From 5476274f59fb7f4e8a0e1ca405d7bb9f7012ddd1 Mon Sep 17 00:00:00 2001 From: Nicolas Micoud <58596990+nmicoud@users.noreply.github.com> Date: Thu, 28 Apr 2022 13:48:47 +0200 Subject: [PATCH] IDEMPIERE-5265 : Wizard for Chosen Multiple Selection List editor (#1289) * IDEMPIERE-5265 : Wizard for Chosen Multiple Selection List editor Co-Authored-By: hengsin <152246+hengsin@users.noreply.github.com> --- .../i9/oracle/202204151102_IDEMPIERE-5265.sql | 14 + .../202204151102_IDEMPIERE-5265.sql | 11 + .../src/org/compiere/model/MRefList.java | 19 +- .../WEB-INF/src/metainfo/zk/lang-addon.xml | 2 +- .../webui/editor/WChosenboxListEditor.java | 497 +++++++++++++++++- .../webui/editor/WEditorPopupMenu.java | 1 + .../org/zkoss/addon/chosenbox/Chosenbox.java | 6 + .../default/css/fragment/window-size.css.dsp | 14 + .../src/web/theme/default/images/Wizard16.png | Bin 0 -> 886 bytes 9 files changed, 543 insertions(+), 21 deletions(-) create mode 100644 migration/i9/oracle/202204151102_IDEMPIERE-5265.sql create mode 100644 migration/i9/postgresql/202204151102_IDEMPIERE-5265.sql create mode 100644 org.adempiere.ui.zk/WEB-INF/src/web/theme/default/images/Wizard16.png diff --git a/migration/i9/oracle/202204151102_IDEMPIERE-5265.sql b/migration/i9/oracle/202204151102_IDEMPIERE-5265.sql new file mode 100644 index 0000000000..a43bb8e570 --- /dev/null +++ b/migration/i9/oracle/202204151102_IDEMPIERE-5265.sql @@ -0,0 +1,14 @@ +-- IDEMPIERE-5265 +SELECT register_migration_script('202204151102_IDEMPIERE-5265.sql') FROM dual; + +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Apr 15, 2022, 11:02:38 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Assistant',0,0,'Y',TO_TIMESTAMP('2022-04-15 11:02:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-04-15 11:02:38','YYYY-MM-DD HH24:MI:SS'),100,200740,'Assistant','D','9a4df9bc-2c84-4bd2-9ca6-ca89794e901d') +; + +-- Apr 15, 2022, 11:03:28 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Selected Items',0,0,'Y',TO_TIMESTAMP('2022-04-15 11:03:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-04-15 11:03:28','YYYY-MM-DD HH24:MI:SS'),100,200741,'SelectedItems','D','219fc977-68a7-459c-aaab-a3f32a32fd2b') +; + diff --git a/migration/i9/postgresql/202204151102_IDEMPIERE-5265.sql b/migration/i9/postgresql/202204151102_IDEMPIERE-5265.sql new file mode 100644 index 0000000000..c65d558133 --- /dev/null +++ b/migration/i9/postgresql/202204151102_IDEMPIERE-5265.sql @@ -0,0 +1,11 @@ +-- IDEMPIERE-5265 +SELECT register_migration_script('202204151102_IDEMPIERE-5265.sql') FROM dual; + +-- Apr 15, 2022, 11:02:38 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Assistant',0,0,'Y',TO_TIMESTAMP('2022-04-15 11:02:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-04-15 11:02:38','YYYY-MM-DD HH24:MI:SS'),100,200740,'Assistant','D','9a4df9bc-2c84-4bd2-9ca6-ca89794e901d') +; + +-- Apr 15, 2022, 11:03:28 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Selected Items',0,0,'Y',TO_TIMESTAMP('2022-04-15 11:03:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-04-15 11:03:28','YYYY-MM-DD HH24:MI:SS'),100,200741,'SelectedItems','D','219fc977-68a7-459c-aaab-a3f32a32fd2b') +; + diff --git a/org.adempiere.base/src/org/compiere/model/MRefList.java b/org.adempiere.base/src/org/compiere/model/MRefList.java index 596a2fe582..b878380143 100644 --- a/org.adempiere.base/src/org/compiere/model/MRefList.java +++ b/org.adempiere.base/src/org/compiere/model/MRefList.java @@ -46,8 +46,7 @@ public class MRefList extends X_AD_Ref_List implements ImmutablePOSupport /** * */ - private static final long serialVersionUID = 2342762307330992884L; - + private static final long serialVersionUID = -2704284822855131148L; /** RefList Value Cache */ private static ImmutablePOCache s_ref_value_cache = new ImmutablePOCache(Table_Name, 40); @@ -262,6 +261,19 @@ public class MRefList extends X_AD_Ref_List implements ImmutablePOSupport * @return List or null */ public static ValueNamePair[] getList (Properties ctx, int AD_Reference_ID, boolean optional, String orderBy) { + return getList(ctx, AD_Reference_ID, optional, "", orderBy); + } + + /** + * Get Reference List (translated) + * @param ctx context + * @param AD_Reference_ID reference + * @param optional if true add "","" + * @param additionalWhereClause + * @param orderBy N-Name, V-Value, D-Default (IsOrderByValue) + * @return List or null + */ + public static ValueNamePair[] getList (Properties ctx, int AD_Reference_ID, boolean optional, String additionalWhereClause, String orderBy) { String language = Env.getAD_Language(ctx); boolean orderByValue = MReference.get(AD_Reference_ID).isOrderByValue(); @@ -294,6 +306,9 @@ public class MRefList extends X_AD_Ref_List implements ImmutablePOSupport .append(language).append("')"); sql.append(" WHERE AD_Ref_List.AD_Reference_ID=").append(AD_Reference_ID); + if (!Util.isEmpty(additionalWhereClause, true)) + sql.append(" AND (").append(additionalWhereClause).append(")"); + sql.append(AspFilter.toString()); if (orderByValue) sql.append(" ORDER BY 1"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml index 508a60977f..3a371fa6dd 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml +++ b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml @@ -56,5 +56,5 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI). - + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChosenboxListEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChosenboxListEditor.java index 8ba56ab659..9b3ab7897e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChosenboxListEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChosenboxListEditor.java @@ -15,37 +15,66 @@ package org.adempiere.webui.editor; import java.beans.PropertyChangeEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Properties; import java.util.Set; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.ValuePreference; +import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ChosenSearchBox; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListHead; +import org.adempiere.webui.component.ListHeader; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Panel; +import org.adempiere.webui.component.SimpleListModel; +import org.adempiere.webui.component.Window; import org.adempiere.webui.event.ContextMenuEvent; import org.adempiere.webui.event.ContextMenuListener; +import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.ValueChangeEvent; +import org.adempiere.webui.factory.ButtonFactory; import org.adempiere.webui.theme.ThemeManager; +import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.WFieldRecordInfo; import org.compiere.model.GridField; import org.compiere.model.Lookup; +import org.compiere.model.MColumn; import org.compiere.model.MLookup; +import org.compiere.model.MRefList; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.CacheMgt; +import org.compiere.util.Env; import org.compiere.util.KeyNamePair; +import org.compiere.util.Msg; import org.compiere.util.Util; import org.compiere.util.ValueNamePair; import org.zkoss.addon.chosenbox.Chosenbox; +import org.zkoss.zk.au.out.AuFocus; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Desktop; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.DropEvent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; import org.zkoss.zk.ui.util.DesktopCleanup; +import org.zkoss.zul.Borderlayout; +import org.zkoss.zul.Center; +import org.zkoss.zul.Hlayout; import org.zkoss.zul.ListModelList; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.Menuitem; +import org.zkoss.zul.South; /** * @@ -225,6 +254,16 @@ public class WChosenboxListEditor extends WEditor implements ContextMenuListener { popupMenu = new WEditorPopupMenu(false, true, isShowPreference(), false, false, false, lookup); addChangeLogMenu(popupMenu); + + Menuitem editor = new Menuitem(); + editor.setAttribute("EVENT", WEditorPopupMenu.ASSISTANT_EVENT); + editor.setLabel(Msg.getMsg(Env.getCtx(), "Assistant")); + if (ThemeManager.isUseFontIconForImage()) + editor.setIconSclass("z-icon-Wizard"); + else + editor.setImage(ThemeManager.getThemeResource("images/Wizard16.png")); + editor.addEventListener(Events.ON_CLICK, popupMenu); + popupMenu.appendChild(editor); } } @@ -416,26 +455,30 @@ public class WChosenboxListEditor extends WEditor implements ContextMenuListener { if (Events.ON_SELECT.equalsIgnoreCase(event.getName())) { - try { - onselecting = true; - Object newValue = getValueFromComponent(); - if (isValueChange(newValue)) { - try { - if (gridField != null) - gridField.setLookupEditorSettingValue(true); - ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue); - super.fireValueChange(changeEvent); - oldValue = newValue; - } finally { - if (gridField != null) - gridField.setLookupEditorSettingValue(false); - } - } - } finally { - onselecting = false; - } + updateValue(getValueFromComponent()); } } + + private void updateValue(Object newValue) { + try { + onselecting = true; + + if (isValueChange(newValue)) { + try { + if (gridField != null) + gridField.setLookupEditorSettingValue(true); + ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue); + super.fireValueChange(changeEvent); + oldValue = newValue; + } finally { + if (gridField != null) + gridField.setLookupEditorSettingValue(false); + } + } + } finally { + onselecting = false; + } + } private boolean isValueChange(Object newValue) { return (oldValue == null && newValue != null) || (oldValue != null && newValue == null) @@ -494,6 +537,20 @@ public class WChosenboxListEditor extends WEditor implements ContextMenuListener { WFieldRecordInfo.start(gridField); } + else if (WEditorPopupMenu.ASSISTANT_EVENT.equals(evt.getContextEvent())) { + + final WChosenboxListAssistant wdc = new WChosenboxListAssistant(); + wdc.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { + public void onEvent(Event event) throws Exception { + + Object newValue = wdc.getNewValue(); + updateValue(newValue); + setValue(newValue.toString()); + } + }); + + AEnv.showWindow(wdc); + } } @Override @@ -622,4 +679,408 @@ public class WChosenboxListEditor extends WEditor implements ContextMenuListener } } } + + private class WChosenboxListAssistant extends Window implements EventListener { + private static final long serialVersionUID = 1223690858387209211L; + private Button bAdd, bRemove, bUp, bDown; + private SimpleListModel availableModel = new SimpleListModel(); + private SimpleListModel selectedModel = new SimpleListModel(); + private Listbox availableList = new Listbox(); + private Listbox selectedList = new Listbox(); + private Hlayout hlayout; + private Button bOk = ButtonFactory.createNamedButton(ConfirmPanel.A_OK, false, true); + private int refID = 0; + private String m_newValue = ""; + + public WChosenboxListAssistant() { + super(); + refID = MColumn.get(Env.getCtx(), gridTab.getTableName(), gridField.getColumnName()).getAD_Reference_Value_ID(); + setTitle(gridField.getHeader() + " " + Msg.getMsg(Env.getCtx(), "Assistant")); + init(); + load(); + setClosable(true); + setBorder("normal"); + setShadow(true); + setMaximizable(true); + setSizable(true); + + if (!ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setWindowHeightX(this, 600); + ZKUpdateUtil.setWindowWidthX(this, 700); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + setSclass("chosenbox-assistant-dialog"); + + addCallback(AFTER_PAGE_DETACHED, t -> { + WChosenboxListEditor.this.getComponent().getChosenbox().focus(); + }); + } + + private void init() { + m_newValue = getValue() != null ? getValue().toString() : ""; + + Borderlayout mainLayout = new Borderlayout(); + appendChild(mainLayout); + + Center center = new Center(); + mainLayout.appendChild(center); + center.setAutoscroll(true); + + EventListener actionListener = new EventListener() { + public void onEvent(Event event) throws Exception { + migrateValueAcrossLists(event); + } + }; + + EventListener actionListener2 = new EventListener() { + public void onEvent(Event event) throws Exception { + migrateValueWithinSelectedList(event); + } + }; + + EventListener mouseListener = new EventListener() { + public void onEvent(Event event) throws Exception { + if (Events.ON_DOUBLE_CLICK.equals(event.getName())) { + migrateValueAcrossLists(event); + } + } + }; + + EventListener crossListMouseListener = new DragListener(); + + bUp = createButton("MoveUp16", actionListener2); + bDown = createButton("MoveDown16", actionListener2); + bAdd = createButton("MoveRight16", actionListener); + bRemove = createButton("MoveLeft16", actionListener); + bOk.addEventListener(Events.ON_CLICK, this); + + Hlayout yesButtonLayout = createHlayoutBtn(new Button[] {bUp, bDown}); + Hlayout noButtonLayout = createHlayoutBtn(new Button[] {bRemove, bAdd}); + + initListboxAndModel(selectedList, selectedModel, mouseListener, crossListMouseListener, true, Msg.getMsg(Env.getCtx(), "SelectedItems"), yesButtonLayout); + initListboxAndModel(availableList, availableModel, mouseListener, crossListMouseListener, true, Msg.getMsg(Env.getCtx(), "Available"), noButtonLayout); + + hlayout = createHlayoutLine(new Component[] {availableList, selectedList}); + center.appendChild(hlayout); + + Panel confirmPanel = new Panel(); + confirmPanel.setSclass("confirm-panel-right"); + confirmPanel.appendChild(bOk); + + South south = new South(); + south.setSclass("dialog-footer"); + mainLayout.appendChild(south); + south.appendChild(confirmPanel); + } + + private void load() { + selectedModel.removeAllElements(); + availableModel.removeAllElements(); + + // selected + Object values = getValue(); + ArrayList listSelected = new ArrayList(); + if (values != null && !Util.isEmpty((String) values)) { + for (String value : ((String) values).split(",")) { + selectedModel.addElement(new ValueNamePair (value, MRefList.getListName(Env.getCtx(), refID, value))); + listSelected.add(value); + } + } + + // available (data - available) + String validationCode = gridField.getVO().ValidationCode; + if (!Util.isEmpty(validationCode)) { + validationCode = Env.parseContext(Env.getCtx(), gridField.getWindowNo(), gridField.getVO().TabNo, validationCode, false); + if (Util.isEmpty(validationCode, true)) { + //not validated, ensure list is empty + validationCode = "1=2"; + } + } + + for (ValueNamePair vnp : MRefList.getList(Env.getCtx(), refID, false, validationCode, "")) { + + if (listSelected.contains(vnp.getValue())) + continue; + + availableModel.addElement(new ValueNamePair (vnp.getValue(), MRefList.getListName(Env.getCtx(), refID, vnp.getValue()))); + listSelected.add(vnp.getValue()); + } + } + + public void onEvent(Event event) throws Exception { + if (event.getTarget() == bOk) { + + StringBuilder value = new StringBuilder(""); + + for (Listitem le : selectedList.getItems()) { + int index = selectedList.getIndexOfItem(le); + ValueNamePair selObject = (ValueNamePair ) selectedModel.getElementAt(index); + value.append(selObject.getID()).append(","); + } + + if (value.length() > 0) + value = value.deleteCharAt(value.length() - 1); + m_newValue = value.toString(); + this.detach(); + } + } + + private Button createButton(String image, EventListener actionListener) { + Button btn = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/" + image + ".png"), null); + LayoutUtils.addSclass("btn-small", btn); + LayoutUtils.addSclass("btn-sorttab small-img-btn", btn); + btn.addEventListener(Events.ON_CLICK, actionListener); + return btn; + } + + private void initListboxAndModel(Listbox lb, SimpleListModel model, EventListener mouseListener, EventListener crossListMouseListener, boolean isItemDraggable, String headerLabel, Hlayout buttonsLayout) { + lb.addEventListener(Events.ON_RIGHT_CLICK, this); + ZKUpdateUtil.setHflex(lb, "1"); + ZKUpdateUtil.setVflex(lb, true); + + if (mouseListener != null) + lb.addDoubleClickListener(mouseListener); + if (crossListMouseListener != null) + lb.addOnDropListener(crossListMouseListener); + lb.setItemDraggable(isItemDraggable); + lb.setItemRenderer(model); + lb.setModel(model); + model.setMultiple(true); + + ListHead listHead = new ListHead(); + listHead.setParent(lb); + ListHeader listHeader = new ListHeader(); + listHeader.appendChild(new Label(headerLabel)); + listHeader.setParent(listHead); + listHeader.appendChild(buttonsLayout); + } + + private Hlayout createHlayoutBtn(Button[] btns) { + Hlayout hl = new Hlayout(); + for (Button btn : btns) + hl.appendChild(btn); + hl.setStyle("display: inline-block; float: right;"); + return hl; + } + + private Hlayout createHlayoutLine(Component[] comps) { + + Hlayout hl = new Hlayout(); + hl.setValign("middle"); + for (Component comp : comps) + hl.appendChild(comp); + hl.setVflex("1"); + hl.setStyle("margin-bottom: 5px;"); + return hl; + } + + private Listbox getListboxFrom(Object source) { + Listbox retValue = null; + if (source == bAdd || source == availableList) + retValue = availableList; + else if (source == bRemove || source == selectedList) + retValue = selectedList; + + return retValue; + } + + private Listbox getListboxTo(Object source) { + Listbox retValue = null; + if (source == bAdd || source == availableList) + retValue = selectedList; + else if (source == bRemove || source == selectedList) + retValue = availableList; + return retValue; + } + + private SimpleListModel getModel(Listbox listbox) { + + SimpleListModel retValue = null; + + if (listbox == selectedList) + retValue = selectedModel; + else if (listbox == availableList) + retValue = availableModel; + + return retValue; + } + + private SimpleListModel getModel(SimpleListModel model) { + + SimpleListModel retValue = null; + + if (model == availableModel) + retValue = selectedModel; + else if (model == selectedModel) + retValue = availableModel; + + return retValue; + } + + private void migrateValueAcrossLists (Event event) { + Object source = event.getTarget(); + if (source instanceof ListItem) + source = ((ListItem)source).getListbox(); + Listbox listFrom = getListboxFrom(source); + Listbox listTo = getListboxTo(source); + int endIndex = selectedList.getIndexOfItem(listTo.getSelectedItem()); + + //Listto is empty. + if (endIndex < 0) + endIndex=0; + + migrateLists (listFrom, listTo, endIndex); + } // migrateValueAcrossLists + + private void migrateLists (final Listbox listFrom, final Listbox listTo, final int endIndex) { + int index = 0; + final SimpleListModel lmFrom = getModel(listFrom); + final SimpleListModel lmTo = getModel(lmFrom); + Set selectedItems = listFrom.getSelectedItems(); + List selObjects = new ArrayList(); + + for (Object obj : selectedItems) { + ListItem listItem = (ListItem) obj; + index = listFrom.getIndexOfItem(listItem); + ValueNamePair selObject = (ValueNamePair )lmFrom.getElementAt(index); + selObjects.add(selObject); + } + + doTransfer(index, selObjects, lmFrom, lmTo, listFrom, listTo, endIndex); + } + + private void doTransfer(int index, List selObjects, SimpleListModel lmFrom, SimpleListModel lmTo, Listbox listFrom , Listbox listTo , int endIndex) { + + index = 0; + Arrays.sort(selObjects.toArray()); + for (ValueNamePair selObject : selObjects) { + lmFrom.removeElement(selObject); + lmTo.add(endIndex, selObject); + } + + if (listTo.getSelectedItem() != null) { + AuFocus focus = new AuFocus(listTo.getSelectedItem()); + Clients.response(focus); + } + } + + private class DragListener implements EventListener { + public DragListener() { + } + + public void onEvent(Event event) throws Exception { + if (event instanceof DropEvent) { + int endIndex = 0; + DropEvent me = (DropEvent) event; + ListItem endItem = (ListItem) me.getTarget(); + ListItem startItem = (ListItem) me.getDragged(); + + if (!startItem.isSelected()) + startItem.setSelected(true); + + Listbox selListbox = selectedList; + SimpleListModel selModel = getModel(selListbox); + + if (!(startItem.getListbox() == endItem.getListbox())) { + Listbox listFrom = (Listbox) startItem.getListbox(); + Listbox listTo = (Listbox) endItem.getListbox(); + endIndex = selListbox.getIndexOfItem(endItem); + migrateLists (listFrom, listTo, endIndex); + } else if (startItem.getListbox() == endItem.getListbox() && startItem.getListbox() == selListbox) { + List selObjects = new ArrayList(); + endIndex = selListbox.getIndexOfItem(endItem); + for (Object obj : selListbox.getSelectedItems()) { + ListItem listItem = (ListItem) obj; + int index = selListbox.getIndexOfItem(listItem); + ValueNamePair selObject = (ValueNamePair ) selModel.getElementAt(index); + selObjects.add(selObject); + } + migrateValueWithinSelectedList (selModel, selListbox, endIndex, selObjects); + } + } + } + } + + private void migrateValueWithinSelectedList (SimpleListModel selModel, Listbox selListbox, int endIndex, List selObjects) { + int iniIndex =0; + Arrays.sort(selObjects.toArray()); + ValueNamePair selObject= null; + ValueNamePair endObject = (ValueNamePair ) selModel.getElementAt(endIndex); + for (ValueNamePair selected : selObjects) { + iniIndex = selModel.indexOf(selected); + selObject = (ValueNamePair ) selModel.getElementAt(iniIndex); + selModel.removeElement(selObject); + endIndex = selModel.indexOf(endObject); + selModel.add(endIndex, selObject); + } + + selListbox.removeAllItems(); + for(int i=0 ; i= 0; i--) { + int index = indices[i]; + if (index >= selectedModel.getSize() - 1) + break; + ValueNamePair selObject = (ValueNamePair ) selectedModel.getElementAt(index); + ValueNamePair newObject = (ValueNamePair ) selectedModel.getElementAt(index + 1); + selectedModel.setElementAt(newObject, index); + selectedModel.setElementAt(selObject, index + 1); + selectedList.setSelectedIndex(index + 1); + indices[i] = index + 1; + change = true; + } + } // down + + // + if (change) { + selectedList.setSelectedIndices(indices); + if ( selectedList.getSelectedItem() != null) { + AuFocus focus = new AuFocus(selectedList.getSelectedItem()); + Clients.response(focus); + } + } + } + + private String getNewValue() { + return m_newValue; + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java index 232a2d5219..86532ba6b4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java @@ -63,6 +63,7 @@ public class WEditorPopupMenu extends Menupopup implements EventListener public static final String CHANGE_LOG_EVENT = "CHANGE_LOG"; public static final String EDITOR_EVENT = "EDITOR"; public static final String RESET_EVENT = "RESET"; + public static final String ASSISTANT_EVENT = "ASSISTANT"; private boolean newEnabled = true; private boolean updateEnabled = true; // Elaine 2009/02/16 - update record diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/zkoss/addon/chosenbox/Chosenbox.java b/org.adempiere.ui.zk/WEB-INF/src/org/zkoss/addon/chosenbox/Chosenbox.java index dc928e988d..ca9a73f78e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/zkoss/addon/chosenbox/Chosenbox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/zkoss/addon/chosenbox/Chosenbox.java @@ -32,6 +32,7 @@ import java.util.logging.Logger; import org.apache.commons.text.StringEscapeUtils; import org.zkoss.lang.Objects; import org.zkoss.xel.VariableResolver; +import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.au.out.AuSetAttribute; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; @@ -842,6 +843,11 @@ public class Chosenbox extends HtmlBasedComponent { this._subListModel = _subListModel; } + @Override + public void focus() { + response(new AuScript("$('#"+getUuid()+"-inp').focus();")); + } + private final ItemRenderer _defRend = new ItemRenderer() { public String render(final Component owner, final T data, final int index) { final Chosenbox self = (Chosenbox) owner; diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/window-size.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/window-size.css.dsp index d8f978615e..f68ae929d6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/window-size.css.dsp +++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/window-size.css.dsp @@ -386,3 +386,17 @@ } } +.chosenbox-assistant-dialog { + height: 600px; + width: 700px; +} +@media screen and (max-width: 500px) { + .chosenbox-assistant-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .chosenbox-assistant-dialog { + height: 100%; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/images/Wizard16.png b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/images/Wizard16.png new file mode 100644 index 0000000000000000000000000000000000000000..0e0cc7ca43babbcdff6f8b43755638fe7cb4f6c7 GIT binary patch literal 886 zcmV-+1Bv{JP)#1YX_S#CQ~5_NEqWSu(8rD zvI!AmLR^e|Au)XMv*8c$gQEB{kr_f*9azQ2A^5TnkWe9Pc82MO&aJ2mlw+ctHSU0W4D`%$v6Dl8MqL)3yeK z8=Mk5B(hFiUjV>M`wx{*muOp^##`$3r?W--pW(ZO;^q}jROz(o;KrI2^Rs4j-*<_b zA8zJpNr6Ow#lX(x8nR^;BgrD2YV*H;$F%=8z`cLo%KY|5u;H!pOm?@2dAF=OzJ(?W zsRF=&PzYjbp^T53si+uE*+DL<&t3m?o4`MPt#g-Cs)OPdHEf0Vs+Oc|H|f`JNIVl zWdNiK;v0d-p8fDfUU(Gp>|L(;hGz<+vJi)^%@(GK?PPfJ65f9I@b~WKmbRhTD9%M= zBl(gw2ThRVR|VoN-q#Bqwdrho&D_LxZ)nXj6@GvkR;|HvOpy+2@yW*n@#zFI z)4vZWceiNlS?y4fvN*G@MoD_w?x@YiPt7m60g#wPjb z$*&?if}KvM%MDG_m!1!K(MsJu6$k26`SQlvy0%)k`f-2cLe8}L=dmgN;Isa|)}1dn zI=WsW5<(CWP;s~bAPE8hYHr$qnp&R{J~J?wsWA7Q`DRCZr|Ti+iU1pc00CgOg+xb> zhX&h&f!05!{=${3!=cC*pC52&nwiUG1(*|yAH@vdUz~$lMvd3FdH?_b M07*qoM6N<$g2Yg(m;e9( literal 0 HcmV?d00001