diff --git a/migration/i6.2/oracle/201904251644_IDEMPIERE-3956.sql b/migration/i6.2/oracle/201904251644_IDEMPIERE-3956.sql new file mode 100644 index 0000000000..baad83e6d5 --- /dev/null +++ b/migration/i6.2/oracle/201904251644_IDEMPIERE-3956.sql @@ -0,0 +1,15 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-3956 Add Close Windows to the Left/Right - expanding IDEMPIERE-2335 +-- Apr 25, 2019, 4:43:29 PM 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','Close Windows to the Right',0,0,'Y',TO_DATE('2019-04-25 16:43:29','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-04-25 16:43:29','YYYY-MM-DD HH24:MI:SS'),100,200510,'CloseWindowsToTheRight','D','b90cf739-eb4d-41eb-a8cb-7c1960e7af2a') +; + +-- Apr 25, 2019, 4:44:18 PM 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','Close Windows to the Left',0,0,'Y',TO_DATE('2019-04-25 16:44:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-04-25 16:44:17','YYYY-MM-DD HH24:MI:SS'),100,200511,'CloseWindowsToTheLeft','D','c150a69a-ae19-4403-8d03-0040e7714ef9') +; + +SELECT register_migration_script('201904251644_IDEMPIERE-3956.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201904251644_IDEMPIERE-3956.sql b/migration/i6.2/postgresql/201904251644_IDEMPIERE-3956.sql new file mode 100644 index 0000000000..fae7611d01 --- /dev/null +++ b/migration/i6.2/postgresql/201904251644_IDEMPIERE-3956.sql @@ -0,0 +1,12 @@ +-- IDEMPIERE-3956 Add Close Windows to the Left/Right - expanding IDEMPIERE-2335 +-- Apr 25, 2019, 4:43:29 PM 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','Close Windows to the Right',0,0,'Y',TO_TIMESTAMP('2019-04-25 16:43:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-04-25 16:43:29','YYYY-MM-DD HH24:MI:SS'),100,200510,'CloseWindowsToTheRight','D','b90cf739-eb4d-41eb-a8cb-7c1960e7af2a') +; + +-- Apr 25, 2019, 4:44:18 PM 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','Close Windows to the Left',0,0,'Y',TO_TIMESTAMP('2019-04-25 16:44:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-04-25 16:44:17','YYYY-MM-DD HH24:MI:SS'),100,200511,'CloseWindowsToTheLeft','D','c150a69a-ae19-4403-8d03-0040e7714ef9') +; + +SELECT register_migration_script('201904251644_IDEMPIERE-3956.sql') FROM dual +; + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java index 81d300f0e0..f588936d7a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java @@ -39,6 +39,7 @@ 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.event.KeyEvent; +import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zk.ui.event.SwipeEvent; import org.zkoss.zul.Menuitem; @@ -49,6 +50,12 @@ import org.zkoss.zul.Menuitem; */ public class WindowContainer extends AbstractUIPart implements EventListener { + private static final String OPTION_CLOSE = "Close"; + private static final String OPTION_CLOSE_OTHER_WINDOWS = "CloseOtherWindows"; + private static final String OPTION_CLOSE_WINDOWS_TO_THE_LEFT = "CloseWindowsToTheLeft"; + private static final String OPTION_CLOSE_WINDOWS_TO_THE_RIGHT = "CloseWindowsToTheRight"; + private static final String OPTION_CLOSE_ALL_WINDOWS = "CloseAllWindows"; + public static final String ON_MOBILE_SET_SELECTED_TAB = "onMobileSetSelectedTab"; private static final String ON_AFTER_TAB_CLOSE = "onAfterTabClose"; @@ -279,6 +286,8 @@ public class WindowContainer extends AbstractUIPart implements EventListener() { public void onEvent(Event event) throws Exception { int currentTabIndex = tab.getIndex(); + int focusTabIndex = currentTabIndex; int tabsSizeBeforeClose = tabbox.getTabs().getChildren().size(); - - if ( tabsSizeBeforeClose == currentTabIndex + 1 ) { - currentTabIndex--; - } - if ( tab.getPreviousSibling() != null ) { - tab.onClose(); - // Update the current tab index. - if ( tabsSizeBeforeClose != tabbox.getTabs().getChildren().size() ) - tabbox.setSelectedIndex( currentTabIndex ); - Events.postEvent(ON_AFTER_TAB_CLOSE, tabbox, null); + if (tabsSizeBeforeClose == currentTabIndex + 1) { + focusTabIndex = currentTabIndex - 1; } + closeTabs(tab, currentTabIndex, currentTabIndex, focusTabIndex); } }); - mi = new Menuitem(Msg.getMsg(Env.getCtx(), "CloseOtherWindows")); + mi = new Menuitem(Msg.getMsg(Env.getCtx(), OPTION_CLOSE_OTHER_WINDOWS)); + mi.setAttribute("option", OPTION_CLOSE_OTHER_WINDOWS); popupClose.appendChild(mi); mi.addEventListener(Events.ON_CLICK, new EventListener() { public void onEvent(Event event) throws Exception { + int currentTabIndex = tab.getIndex(); + closeTabs(tab, currentTabIndex + 1, -1, currentTabIndex); // Right int focusTabIndex = 1; - List tabs = tabbox.getTabs().getChildren(); - for ( int i = tabs.size() - 1; i > 0; i-- ) { - if(!((Tab)tabs.get( i )).equals(tab)){ - ((Tab)tabs.get( i )).setSelected(false); + closeTabs(tab, 1, currentTabIndex - 1, focusTabIndex); // Left + } + }); - ((Tab)tabs.get( i )).onClose(); - } - } - tabbox.setSelectedIndex(focusTabIndex); - Events.postEvent(ON_AFTER_TAB_CLOSE, tabbox, null); + mi = new Menuitem(Msg.getMsg(Env.getCtx(), OPTION_CLOSE_WINDOWS_TO_THE_LEFT)); + mi.setAttribute("option", OPTION_CLOSE_WINDOWS_TO_THE_LEFT); + popupClose.appendChild(mi); + mi.addEventListener(Events.ON_CLICK, new EventListener() { + public void onEvent(Event event) throws Exception { + int currentTabIndex = tab.getIndex(); + int focusTabIndex = 1; + closeTabs(tab, 1, currentTabIndex - 1, focusTabIndex); + } + }); + + mi = new Menuitem(Msg.getMsg(Env.getCtx(), OPTION_CLOSE_WINDOWS_TO_THE_RIGHT)); + mi.setAttribute("option", OPTION_CLOSE_WINDOWS_TO_THE_RIGHT); + popupClose.appendChild(mi); + mi.addEventListener(Events.ON_CLICK, new EventListener() { + public void onEvent(Event event) throws Exception { + int currentTabIndex = tab.getIndex(); + closeTabs(tab, currentTabIndex + 1, -1, currentTabIndex); } }); } - mi = new Menuitem(Msg.getMsg(Env.getCtx(), "CloseAllWindows")); - mi.addEventListener(Events.ON_CLICK, new EventListener() { - public void onEvent(Event event) throws Exception { - int focusTabIndex = 0; - List tabs = tabbox.getTabs().getChildren(); - for ( int i = tabs.size() - 1; i > 0; i-- ) { - ((Tab)tabs.get( i )).setSelected(false); - ((Tab)tabs.get( i )).onClose(); - } - tabbox.setSelectedIndex( focusTabIndex ); - Events.postEvent(ON_AFTER_TAB_CLOSE, tabbox, null); - } - }); - popupClose.appendChild(mi); - ZKUpdateUtil.setWidth(popupClose, "auto"); - popupClose.setPage(tab.getPage()); - tab.setContext(popupClose); - + mi = new Menuitem(Msg.getMsg(Env.getCtx(), OPTION_CLOSE_ALL_WINDOWS)); + mi.setAttribute("option", OPTION_CLOSE_ALL_WINDOWS); + popupClose.appendChild(mi); + mi.addEventListener(Events.ON_CLICK, new EventListener() { + public void onEvent(Event event) throws Exception { + int focusTabIndex = 0; + closeTabs(tab, 1, -1, focusTabIndex); + } + }); + + ZKUpdateUtil.setWidth(popupClose, "auto"); + popupClose.setPage(tab.getPage()); + tab.setContext(popupClose); + updateTabListButton(); return tab; } + protected void closeTabs(Tab tab, int start, int end, int focus) { + List tabs = tabbox.getTabs().getChildren(); + if (end == -1) { + end = tabs.size() - 1; + } + for (int i = end; i >= start; i--) { + ((Tab)tabs.get( i )).setSelected(false); + ((Tab)tabs.get( i )).onClose(); + } + tabbox.setSelectedIndex(focus); + Events.postEvent(ON_AFTER_TAB_CLOSE, tabbox, null); + } + private void updateTabListButton() { if (isMobile() && tabListBtn != null) { int cnt = tabbox.getTabs().getChildren().size()-1; @@ -593,6 +621,37 @@ public class WindowContainer extends AbstractUIPart implements EventListener tabs = tabbox.getTabs().getChildren(); + int tabsSize = tabs.size(); + int currentTabIdx = -1; + if (popup.getAttribute("tab") != null) { + Tab currentTab = (Tab) popup.getAttribute("tab"); + for ( int i = tabsSize - 1; i > 0; i-- ) { + Tab tab = ((Tab)tabs.get(i)); + if (currentTab.equals(tab)) { + currentTabIdx = i; + break; + } + } + } + if (currentTabIdx > 0) { + List items = popup.getChildren(); + for (Component item : items) { + if (item instanceof Menuitem) { + String option = (String) item.getAttribute("option"); + boolean visible = + (OPTION_CLOSE.equals(option)) + || (tabsSize > 2 && (OPTION_CLOSE_OTHER_WINDOWS.equals(option) || OPTION_CLOSE_ALL_WINDOWS.equals(option))) + || (currentTabIdx < tabsSize - 1 && OPTION_CLOSE_WINDOWS_TO_THE_RIGHT.equals(option)) + || (currentTabIdx > 1 && OPTION_CLOSE_WINDOWS_TO_THE_LEFT.equals(option)); + item.setVisible(visible); + } + } + } + } }else if (Events.ON_CTRL_KEY.equals(event.getName())) { KeyEvent keyEvent = (KeyEvent) event; if (keyEvent.isAltKey() && keyEvent.getKeyCode() == KeyEvent.PAGE_DOWN