/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.widget.form; import java.util.List; import com.extjs.gxt.ui.client.GXT; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.Style.Orientation; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.dnd.ListViewDragSource; import com.extjs.gxt.ui.client.dnd.ListViewDropTarget; import com.extjs.gxt.ui.client.dnd.DND.Feedback; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.widget.VerticalPanel; import com.extjs.gxt.ui.client.widget.button.IconButton; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; /** * Combines two list fields and allows selections to be moved between fields * either using buttons or by dragging and dropping selections. * * @param <D> the model type */ public class DualListField<D extends ModelData> extends MultiField<Field<?>> { /** * The dual list field messages. */ public class DualListFieldMessages extends FieldMessages { private String moveUp; private String moveDown; private String addAll; private String addSelected; private String removeSelected; private String removeAll; /** * Returns the add all tooltip. * * @return the add all tooltip */ public String getAddAll() { return addAll; } /** * Returns the add selected tooltip. * * @return the add selected tooltip */ public String getAddSelected() { return addSelected; } /** * Returns the move down tooltip. * * @return the move down tooltip */ public String getMoveDown() { return moveDown; } /** * Sets the move up tooltip. * * @return the move up tooltip */ public String getMoveUp() { return moveUp; } /** * Returns the remove all tooltip. * * @return the remove all tooltip */ public String getRemoveAll() { return removeAll; } /** * Returns the remove selected tooltip. * * @return the remove selected tooltip */ public String getRemoveSelected() { return removeSelected; } /** * Sets the add all tooltip (defaults to 'Add all'). * * @param addAll the add all tooltip */ public void setAddAll(String addAll) { this.addAll = addAll; } /** * Sets the add selected tooltip (defaults to 'Add selected'). * * @param addSelected the add selected tooltip */ public void setAddSelected(String addSelected) { this.addSelected = addSelected; } /** * Sets the move selected down tooltip (defaults to 'Move selected down'). * * @param moveDown the move down tootip */ public void setMoveDown(String moveDown) { this.moveDown = moveDown; } /** * Sets the move selected up tooltip (defaults to 'Move selected up'). * * @param moveUp */ public void setMoveUp(String moveUp) { this.moveUp = moveUp; } /** * Sets the remove all tooltip (defaults to 'Remove all'). * * @param removeAll the remove all tooltip */ public void setRemoveAll(String removeAll) { this.removeAll = removeAll; } /** * Sets the remove selected tooltip (defaults to 'Remove selected'). * * @param removeSelected the remove selected tooltip */ public void setRemoveSelected(String removeSelected) { this.removeSelected = removeSelected; } } public enum Mode { APPEND, INSERT; } protected ListField<D> fromField; protected ListField<D> toField; protected AdapterField buttonAdapter; protected VerticalPanel buttonBar; protected Mode mode = Mode.APPEND; private String dndGroup; private boolean enableDND = true; public DualListField() { fromField = new ListField<D>(); toField = new ListField<D>(); messages = new DualListFieldMessages(); buttonBar = new VerticalPanel(); buttonBar.setStyleAttribute("margin", "7px"); buttonBar.setHorizontalAlign(HorizontalAlignment.CENTER); buttonAdapter = new AdapterField(buttonBar); add(fromField); add(buttonAdapter); add(toField); } public String getDNDGroup() { return dndGroup; } /** * Returns the from list field. * * @return the field */ public ListField<D> getFromList() { return fromField; } @Override public DualListFieldMessages getMessages() { return (DualListFieldMessages) messages; } /** * Returns the list field's mode. * * @return the mode */ public Mode getMode() { return mode; } /** * Returns the to list field. * * @return the field */ public ListField<D> getToList() { return toField; } /** * Returns true if drag and drop is enabled. * * @return true if drag and drop is enabled */ public boolean isEnableDND() { return enableDND; } /** * Sets the drag and drop group name. A group name will be generated if none * is specified. * * @param group the group name */ public void setDNDGroup(String group) { this.dndGroup = group; } /** * True to allow selections to be dragged and dropped between lists (defaults * to true). * * @param enableDND true to enable drag and drop */ public void setEnableDND(boolean enableDND) { this.enableDND = enableDND; } /** * Specifies if selections are either inserted or appended when moving between * lists. * * @param mode the mode */ public void setMode(Mode mode) { this.mode = mode; } protected void initButtons() { if (mode == Mode.INSERT) { String tip = ""; if (getMessages().getMoveUp() == null) { tip = GXT.MESSAGES.listField_moveSelectedUp(); } else { tip = getMessages().getMoveUp(); } IconButton up = new IconButton("arrow-up"); up.setHeight(18); up.setToolTip(tip); up.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { toField.getListView().moveSelectedUp(); } }); buttonBar.add(up); } String tip = ""; if (getMessages().getAddAll() == null) { tip = GXT.MESSAGES.listField_addAll(); } else { tip = getMessages().getAddAll(); } IconButton allRight = new IconButton("arrow-double-right"); allRight.setHeight(18); allRight.setToolTip(tip); allRight.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { List<D> sel = fromField.getStore().getModels(); toField.getStore().add(sel); fromField.getStore().removeAll(); } }); buttonBar.add(allRight); tip = ""; if (getMessages().getAddSelected() == null) { tip = GXT.MESSAGES.listField_addSelected(); } else { tip = getMessages().getAddSelected(); } IconButton right = new IconButton("arrow-right"); right.setHeight(18); right.setToolTip(tip); right.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { List<D> sel = fromField.getSelection(); for (D model : sel) { fromField.getStore().remove(model); } toField.getStore().add(sel); select(toField, sel); } }); tip = ""; if (getMessages().getRemoveSelected() == null) { tip = GXT.MESSAGES.listField_removeSelected(); } else { tip = getMessages().getRemoveSelected(); } IconButton left = new IconButton("arrow-left"); left.setHeight(18); left.setToolTip(tip); left.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { List<D> sel = toField.getSelection(); for (D model : sel) { toField.getStore().remove(model); } fromField.getStore().add(sel); select(fromField, sel); } }); buttonBar.add(right); buttonBar.add(left); tip = ""; if (getMessages().getRemoveAll() == null) { tip = GXT.MESSAGES.listField_removeAll(); } else { tip = getMessages().getRemoveAll(); } IconButton allLeft = new IconButton("arrow-double-left"); allLeft.setHeight(18); allLeft.setToolTip(tip); allLeft.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { List<D> sel = toField.getStore().getModels(); fromField.getStore().add(sel); toField.getStore().removeAll(); } }); buttonBar.add(allLeft); if (mode == Mode.INSERT) { tip = ""; if (getMessages().getMoveDown() == null) { tip = GXT.MESSAGES.listField_moveSelectedDown(); } else { tip = getMessages().getMoveDown(); } IconButton down = new IconButton("arrow-down"); down.setHeight(18); down.setToolTip(tip); down.addListener(Events.Select, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { toField.getListView().moveSelectedDown(); } }); buttonBar.add(down); } } protected void initDND() { if (dndGroup == null) { dndGroup = getId() + "-group"; } ListViewDragSource source1 = new ListViewDragSource(fromField.getListView()); ListViewDragSource source2 = new ListViewDragSource(toField.getListView()); source1.setGroup(dndGroup); source2.setGroup(dndGroup); ListViewDropTarget target1 = new ListViewDropTarget(fromField.getListView()); target1.setAutoSelect(true); ListViewDropTarget target2 = new ListViewDropTarget(toField.getListView()); target2.setAutoSelect(true); target1.setGroup(dndGroup); target2.setGroup(dndGroup); if (mode == Mode.INSERT) { target1.setFeedback(Feedback.INSERT); target2.setFeedback(Feedback.INSERT); } } protected void initLists() { fromField.setHeight(125); toField.setHeight(125); } @Override protected void onRender(Element target, int index) { initLists(); initButtons(); super.onRender(target, index); if (enableDND) { initDND(); } } @Override protected void onResize(int width, int height) { super.onResize(width, height); if (orientation == Orientation.HORIZONTAL) { int w = (width - buttonAdapter.el().getParent().getWidth()) / 2; w -= (fields.size() * spacing); fromField.setWidth(w); toField.setWidth(w); } else { for (Field<?> f : fields) { f.setWidth(width); } } } @SuppressWarnings("unchecked") private void select(final ListField<?> field, final List list) { DeferredCommand.addCommand(new Command() { public void execute() { field.getListView().getSelectionModel().select(list, false); } }); } }