IDEMPIERE-5786 - Refactor ESC/Alt+X Shortcut for Closing Tabs (#1917)

* IDEMPIERE-5786 - ESC Shortcut for Closing Tabs

- remove duplicate registering of on_cancel event on InfoPanel
- register on_cancel event on WindowContainer

* IDEMPIERE-5786 - partially revert ESC Shortcut for Closing Tabs

* IDEMPIERE-5786 - improve closing tabs with shortcut

- info windows
- forms
- workflows
- find window

* IDEMPIERE-5786 - SysConfig to Use Esc For Tab Closing

* IDEMPIERE-5786 - fix MSysConfig order

* IDEMPIERE-5786 - requested changes by Carlos

- implement shortcut on missing forms
- allow Alt+X shortcut also when ESC is allowed with the SysConfig

* IDEMPIERE-5786 - PR1917pr patch by Carlos

- removed unnecessary fix for an old firefox issue
This commit is contained in:
Peter Takács 2023-06-30 11:08:38 +02:00 committed by GitHub
parent d42aec9b39
commit f79dd5f22f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 231 additions and 145 deletions

View File

@ -0,0 +1,10 @@
-- IDEMPIERE-5786
SELECT register_migration_script('202306290925_IDEMPIERE-5786.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Jun 29, 2023, 9:25:49 AM CEST
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200230,0,0,TO_TIMESTAMP('2023-06-29 09:25:48','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-06-29 09:25:48','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','USE_ESC_FOR_TAB_CLOSING','N','Y - use ESC for closing tabs; N - use Alt+X for closing tabs','D','C','a33cec55-070b-41bf-9448-26b797237ee6')
;

View File

@ -0,0 +1,7 @@
-- IDEMPIERE-5786
SELECT register_migration_script('202306290925_IDEMPIERE-5786.sql') FROM dual;
-- Jun 29, 2023, 9:25:49 AM CEST
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200230,0,0,TO_TIMESTAMP('2023-06-29 09:25:48','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-06-29 09:25:48','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','USE_ESC_FOR_TAB_CLOSING','N','Y - use ESC for closing tabs; N - use Alt+X for closing tabs','D','C','a33cec55-070b-41bf-9448-26b797237ee6')
;

View File

@ -44,7 +44,7 @@ public class MSysConfig extends X_AD_SysConfig
/** /**
* *
*/ */
private static final long serialVersionUID = 1700160594551368619L; private static final long serialVersionUID = 4924291305767860669L;
public static final String AD_CHANGELOG_SAVE_UUID = "AD_CHANGELOG_SAVE_UUID"; public static final String AD_CHANGELOG_SAVE_UUID = "AD_CHANGELOG_SAVE_UUID";
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION"; public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
@ -182,6 +182,7 @@ public class MSysConfig extends X_AD_SysConfig
public static final String TWOPACK_COMMIT_DDL = "2PACK_COMMIT_DDL"; public static final String TWOPACK_COMMIT_DDL = "2PACK_COMMIT_DDL";
public static final String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS"; public static final String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS";
public static final String USE_EMAIL_FOR_LOGIN = "USE_EMAIL_FOR_LOGIN"; public static final String USE_EMAIL_FOR_LOGIN = "USE_EMAIL_FOR_LOGIN";
public static final String USE_ESC_FOR_TAB_CLOSING = "USE_ESC_FOR_TAB_CLOSING";
public static final String USER_LOCKING_MAX_ACCOUNT_LOCK_MINUTES = "USER_LOCKING_MAX_ACCOUNT_LOCK_MINUTES"; public static final String USER_LOCKING_MAX_ACCOUNT_LOCK_MINUTES = "USER_LOCKING_MAX_ACCOUNT_LOCK_MINUTES";
public static final String USER_LOCKING_MAX_INACTIVE_PERIOD_DAY = "USER_LOCKING_MAX_INACTIVE_PERIOD_DAY"; public static final String USER_LOCKING_MAX_INACTIVE_PERIOD_DAY = "USER_LOCKING_MAX_INACTIVE_PERIOD_DAY";
public static final String USER_LOCKING_MAX_LOGIN_ATTEMPT = "USER_LOCKING_MAX_LOGIN_ATTEMPT"; public static final String USER_LOCKING_MAX_LOGIN_ATTEMPT = "USER_LOCKING_MAX_LOGIN_ATTEMPT";

View File

@ -29,6 +29,7 @@ import org.adempiere.base.upload.IUploadService;
import org.adempiere.util.Callback; import org.adempiere.util.Callback;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions; import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Checkbox;
@ -50,6 +51,7 @@ import org.adempiere.webui.component.Tabs;
import org.adempiere.webui.component.VerticalBox; import org.adempiere.webui.component.VerticalBox;
import org.adempiere.webui.component.WListItemRenderer; import org.adempiere.webui.component.WListItemRenderer;
import org.adempiere.webui.component.Window; import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.panel.InfoPanel; import org.adempiere.webui.panel.InfoPanel;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
@ -62,6 +64,7 @@ import org.compiere.model.MAuthorizationAccount;
import org.compiere.model.MColumn; import org.compiere.model.MColumn;
import org.compiere.model.MFactAcct; import org.compiere.model.MFactAcct;
import org.compiere.model.MPeriod; import org.compiere.model.MPeriod;
import org.compiere.model.MSysConfig;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.model.X_C_AcctSchema_Element; import org.compiere.model.X_C_AcctSchema_Element;
import org.compiere.report.core.RModel; import org.compiere.report.core.RModel;
@ -81,6 +84,7 @@ import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Caption; import org.zkoss.zul.Caption;
import org.zkoss.zul.Center; import org.zkoss.zul.Center;
@ -199,6 +203,10 @@ public class WAcctViewer extends Window implements EventListener<Event>
private Borderlayout resultPanel; private Borderlayout resultPanel;
private RModel m_rmodel; private RModel m_rmodel;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** Logger */ /** Logger */
private static final CLogger log = CLogger.getCLogger(WAcctViewer.class); private static final CLogger log = CLogger.getCLogger(WAcctViewer.class);
@ -234,6 +242,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
dynInit (AD_Table_ID, Record_ID); dynInit (AD_Table_ID, Record_ID);
setAttribute(MODE_KEY, MODE_EMBEDDED); setAttribute(MODE_KEY, MODE_EMBEDDED);
setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT); setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT);
setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_windowNo); // for closing the window with shortcut
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
AEnv.showWindow(this); AEnv.showWindow(this);
} }
catch(Exception e) catch(Exception e)
@ -790,6 +800,11 @@ public class WAcctViewer extends Window implements EventListener<Event>
else if (Events.ON_DOUBLE_CLICK.equals(e.getName()) && source instanceof Listbox && source == table) { else if (Events.ON_DOUBLE_CLICK.equals(e.getName()) && source instanceof Listbox && source == table) {
actionZoomFactAcct(); actionZoomFactAcct();
} }
else if (e.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) e;
if (LayoutUtils.isReallyVisible(this))
this.onCtrlKeyEvent(keyEvent);
}
} // onEvent } // onEvent
/** /**
@ -1393,4 +1408,18 @@ public class WAcctViewer extends Window implements EventListener<Event>
if (newpage != null) if (newpage != null)
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0); SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0);
} }
/**
* Handle shortcut key event
* @param keyEvent
*/
private void onCtrlKeyEvent(KeyEvent keyEvent) {
if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_windowNo > 0) {
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_windowNo);
}
}
}
} }

View File

@ -90,7 +90,7 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
/** /**
* generated serial id * generated serial id
*/ */
private static final long serialVersionUID = -5151981978053022864L; private static final long serialVersionUID = -2174135931334134570L;
/** /**
* Attribute for {@link #overflowPopup} to store the last close timestamp in ms. * Attribute for {@link #overflowPopup} to store the last close timestamp in ms.
@ -177,13 +177,6 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
private boolean isAllowProductInfo = MRole.getDefault().canAccess_Info_Product(); private boolean isAllowProductInfo = MRole.getDefault().canAccess_Info_Product();
private int windowNo = 0; private int windowNo = 0;
/** previous key event time in ms **/
private long prevKeyEventTime = 0;
/**
* Previous key event.
* Use together with prevKeyEventTime to detect double fire of key event from browser
*/
private KeyEvent prevKeyEvent;
/** /**
* Maintain hierarchical Quick form by its parent-child tab while open leaf * Maintain hierarchical Quick form by its parent-child tab while open leaf
@ -203,6 +196,10 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
private int prevWidth; private int prevWidth;
/** AD Window content part that own this toolbar **/ /** AD Window content part that own this toolbar **/
private AbstractADWindowContent windowContent; private AbstractADWindowContent windowContent;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* default constructor * default constructor
@ -578,22 +575,8 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
if (!(keyEvent.getKeyCode() == KeyEvent.F2) && windowContent != null && windowContent.getOpenQuickFormTabs().size() > 0) if (!(keyEvent.getKeyCode() == KeyEvent.F2) && windowContent != null && windowContent.getOpenQuickFormTabs().size() > 0)
return; return;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
//filter same key event that is too close this.onCtrlKeyEvent(keyEvent);
//firefox fire key event twice when grid is visible
long time = System.currentTimeMillis();
if (prevKeyEvent != null && prevKeyEventTime > 0 &&
prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() &&
prevKeyEvent.getTarget() == keyEvent.getTarget() &&
prevKeyEvent.isAltKey() == keyEvent.isAltKey() &&
prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() &&
prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) {
if ((time - prevKeyEventTime) <= 300) {
return;
}
}
this.onCtrlKeyEvent(keyEvent);
}
} else if (Events.ON_SELECT.equals(eventName)) } else if (Events.ON_SELECT.equals(eventName))
{ {
int index = fQueryName.getSelectedIndex(); int index = fQueryName.getSelectedIndex();
@ -931,21 +914,18 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
ToolBarButton btn = null; ToolBarButton btn = null;
if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
{ {
if (keyEvent.getKeyCode() == VK_X) if ((keyEvent.getKeyCode() == VK_X))
{ {
if (windowNo > 0) closeWindow(keyEvent);
{
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(windowNo);
}
} }
else else
{ {
btn = altKeyMap.get(keyEvent.getKeyCode()); btn = altKeyMap.get(keyEvent.getKeyCode());
} }
} }
else if (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing) { // ESC
closeWindow(keyEvent);
}
else if (!keyEvent.isAltKey() && keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) else if (!keyEvent.isAltKey() && keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
{ {
if (keyEvent.getKeyCode() == KeyEvent.F2) if (keyEvent.getKeyCode() == KeyEvent.F2)
@ -980,6 +960,18 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
fireButtonClickEvent(keyEvent, btn); fireButtonClickEvent(keyEvent, btn);
} }
/**
* Close Window
* @param keyEvent
*/
private void closeWindow(KeyEvent keyEvent) {
if (windowNo > 0)
{
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(windowNo);
}
}
/** /**
* Fire ON_Click event for button, trigger by shortcut key event. * Fire ON_Click event for button, trigger by shortcut key event.
* @param keyEvent source shortcut key event * @param keyEvent source shortcut key event
@ -988,8 +980,6 @@ public class ADWindowToolbar extends ToolBar implements EventListener<Event>
private void fireButtonClickEvent(KeyEvent keyEvent, ToolBarButton btn) private void fireButtonClickEvent(KeyEvent keyEvent, ToolBarButton btn)
{ {
if (btn != null) { if (btn != null) {
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation(); keyEvent.stopPropagation();
if (!btn.isDisabled() && btn.isVisible()) { if (!btn.isDisabled() && btn.isVisible()) {
Events.sendEvent(btn, new Event(Events.ON_CLICK, btn)); Events.sendEvent(btn, new Event(Events.ON_CLICK, btn));

View File

@ -87,11 +87,10 @@ import org.zkoss.zul.Toolbar;
* @author hengsin * @author hengsin
*/ */
public class DetailPane extends Panel implements EventListener<Event>, IdSpace { public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
/** /**
* generated serial id * generated serial id
*/ */
private static final long serialVersionUID = 6251897492168864784L; private static final long serialVersionUID = 3764215603459946930L;
public static final String BTN_PROCESS_ID = "BtnProcess"; public static final String BTN_PROCESS_ID = "BtnProcess";
@ -130,14 +129,6 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
private static final String QUICK_FORM_IMAGE = "images/QuickForm16.png"; private static final String QUICK_FORM_IMAGE = "images/QuickForm16.png";
private static final String TOGGLE_IMAGE = "images/Multi16.png"; private static final String TOGGLE_IMAGE = "images/Multi16.png";
/** Timestamp for previous key event **/
private long prevKeyEventTime = 0;
/**
* Previous KeyEvent reference.
* Use together with {@link #prevKeyEventTime} to detect double firing of key event by browser.
*/
private KeyEvent prevKeyEvent;
/** tabbox for AD_Tabs **/ /** tabbox for AD_Tabs **/
private Tabbox tabbox; private Tabbox tabbox;
@ -800,22 +791,8 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
LayoutUtils.redraw(this); LayoutUtils.redraw(this);
} else if (event.getName().equals(Events.ON_CTRL_KEY)) { } else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
//filter same key event that is too close
//firefox fire key event twice when grid is visible
long time = System.currentTimeMillis();
if (prevKeyEvent != null && prevKeyEventTime > 0 &&
prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() &&
prevKeyEvent.getTarget() == keyEvent.getTarget() &&
prevKeyEvent.isAltKey() == keyEvent.isAltKey() &&
prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() &&
prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) {
if ((time - prevKeyEventTime) <= 300) {
return;
}
}
this.onCtrlKeyEvent(keyEvent); this.onCtrlKeyEvent(keyEvent);
}
} }
} }
@ -1147,8 +1124,6 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
} }
} }
if (btn != null) { if (btn != null) {
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation(); keyEvent.stopPropagation();
if (!btn.isDisabled() && btn.isVisible()) { if (!btn.isDisabled() && btn.isVisible()) {
Events.sendEvent(btn, new Event(Events.ON_CLICK, btn)); Events.sendEvent(btn, new Event(Events.ON_CLICK, btn));
@ -1164,11 +1139,10 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
* Custom {@link org.adempiere.webui.component.Tabpanel} implementation for DetailPane. * Custom {@link org.adempiere.webui.component.Tabpanel} implementation for DetailPane.
*/ */
public static class Tabpanel extends org.adempiere.webui.component.Tabpanel { public static class Tabpanel extends org.adempiere.webui.component.Tabpanel {
/** /**
* generated serial id * generated serial id
*/ */
private static final long serialVersionUID = 8248794614430375822L; private static final long serialVersionUID = -2502140440194514450L;
private ToolBar toolbar; private ToolBar toolbar;
@ -1357,11 +1331,11 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
* *
*/ */
private static class RecordToolbar extends Hlayout { private static class RecordToolbar extends Hlayout {
/** /**
* generated serial id * generated serial id
*/ */
private static final long serialVersionUID = 5024630043211194429L; private static final long serialVersionUID = -3369063577339438823L;
private ToolBarButton btnFirst; private ToolBarButton btnFirst;
private ToolBarButton btnPrevious; private ToolBarButton btnPrevious;
private ToolBarButton btnRecordInfo; private ToolBarButton btnRecordInfo;

View File

@ -43,6 +43,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog; import org.adempiere.webui.window.Dialog;
import org.adempiere.webui.window.SimplePDFViewer; import org.adempiere.webui.window.SimplePDFViewer;
import org.compiere.model.MProcess; import org.compiere.model.MProcess;
import org.compiere.model.MSysConfig;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.print.ReportEngine; import org.compiere.print.ReportEngine;
import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfo;
@ -124,12 +125,10 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
/** Window No */ /** Window No */
private int m_WindowNo = -1; private int m_WindowNo = -1;
/** timestamp of previous key event **/
private long prevKeyEventTime = 0;
/** /**
* Previous key event. use together with {@link #prevKeyEventTime} to detect double firing of key event from browser. * SysConfig USE_ESC_FOR_TAB_CLOSING
*/ */
private KeyEvent prevKeyEvent; private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Dialog to start a process/report * Dialog to start a process/report
@ -236,22 +235,8 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
} }
} else if (event.getName().equals(Events.ON_CTRL_KEY)) { } else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
//filter same key event that is too close
//firefox fire key event twice when grid is visible
long time = System.currentTimeMillis();
if (prevKeyEvent != null && prevKeyEventTime > 0 &&
prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() &&
prevKeyEvent.getTarget() == keyEvent.getTarget() &&
prevKeyEvent.isAltKey() == keyEvent.isAltKey() &&
prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() &&
prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) {
if ((time - prevKeyEventTime) <= 300) {
return;
}
}
this.onCtrlKeyEvent(keyEvent); this.onCtrlKeyEvent(keyEvent);
}
} else { } else {
super.onEvent(event); super.onEvent(event);
} }
@ -279,10 +264,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
* @param keyEvent * @param keyEvent
*/ */
private void onCtrlKeyEvent(KeyEvent keyEvent) { private void onCtrlKeyEvent(KeyEvent keyEvent) {
if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_WindowNo > 0) { if (m_WindowNo > 0) {
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation(); keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_WindowNo); SessionManager.getAppDesktop().closeWindow(m_WindowNo);
} }

View File

@ -678,6 +678,8 @@ public class WBOMDrop extends ADForm implements EventListener<Event>, ValueChang
@Override @Override
public void onEvent (Event e) throws Exception public void onEvent (Event e) throws Exception
{ {
super.onEvent(e);
if (log.isLoggable(Level.CONFIG)) log.config(e.getName()); if (log.isLoggable(Level.CONFIG)) log.config(e.getName());
Object source = e.getTarget(); Object source = e.getTarget();

View File

@ -323,6 +323,8 @@ public class WPluginManager extends ADForm implements EventListener<Event> {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
super.onEvent(event);
if (Events.ON_SELECT.equals(event.getName()) && event.getTarget() == pluginsTable) if (Events.ON_SELECT.equals(event.getName()) && event.getTarget() == pluginsTable)
refreshActionList(); refreshActionList();
else if (Events.ON_CLICK.equals(event.getName()) && event.getTarget() == pluginProcess) else if (Events.ON_CLICK.equals(event.getName()) && event.getTarget() == pluginProcess)

View File

@ -177,6 +177,8 @@ public class WFEditor extends ADForm {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
super.onEvent(event);
if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL))
this.detach(); this.detach();
else if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) else if (event.getTarget().getId().equals(ConfirmPanel.A_OK))

View File

@ -19,12 +19,15 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.panel.IHelpContext; import org.adempiere.webui.panel.IHelpContext;
import org.adempiere.webui.part.WindowContainer; import org.adempiere.webui.part.WindowContainer;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.apps.wf.WFGraphLayout; import org.compiere.apps.wf.WFGraphLayout;
import org.compiere.apps.wf.WFNodeWidget; import org.compiere.apps.wf.WFNodeWidget;
import org.compiere.model.MSysConfig;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
@ -37,11 +40,12 @@ import org.zkoss.zhtml.Tr;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center; import org.zkoss.zul.Center;
import org.zkoss.zul.South;
import org.zkoss.zul.Div; import org.zkoss.zul.Div;
import org.zkoss.zul.Html; import org.zkoss.zul.Html;
import org.zkoss.zul.South;
/** /**
* WorkFlow Panel * WorkFlow Panel
@ -53,8 +57,12 @@ public class WFPanel extends Borderlayout implements EventListener<Event>, IHelp
/** /**
* *
*/ */
private static final long serialVersionUID = 8777798080154603970L; private static final long serialVersionUID = 3748544216557474367L;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Create Workflow Panel * Create Workflow Panel
@ -71,6 +79,8 @@ public class WFPanel extends Borderlayout implements EventListener<Event>, IHelp
log.log(Level.SEVERE, "WFPanel", e); log.log(Level.SEVERE, "WFPanel", e);
} }
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); // for closing the window with shortcut
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
} // WFPanel } // WFPanel
/** Window No */ /** Window No */
@ -274,8 +284,14 @@ public class WFPanel extends Borderlayout implements EventListener<Event>, IHelp
} }
} }
} }
else if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) else if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) {
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Workflow, m_wf.getAD_Workflow_ID()); SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Workflow, m_wf.getAD_Workflow_ID());
}
else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this))
this.onCtrlKeyEvent(keyEvent);
}
} }
private void start(MWFNode wfn) { private void start(MWFNode wfn) {
@ -295,4 +311,17 @@ public class WFPanel extends Borderlayout implements EventListener<Event>, IHelp
} }
} }
/**
* Handle shortcut key event
* @param keyEvent
*/
private void onCtrlKeyEvent(KeyEvent keyEvent) {
if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_WindowNo > 0) {
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_WindowNo);
}
}
}
} // WFPanel } // WFPanel

View File

@ -20,19 +20,24 @@ package org.adempiere.webui.panel;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.webui.Extensions; import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Window; import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.exception.ApplicationException; import org.adempiere.webui.exception.ApplicationException;
import org.adempiere.webui.part.WindowContainer; import org.adempiere.webui.part.WindowContainer;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.GridTab; import org.compiere.model.GridTab;
import org.compiere.model.MForm; import org.compiere.model.MForm;
import org.compiere.model.MSysConfig;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfo;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
/** /**
* Adempiere Web UI custom form. * Adempiere Web UI custom form.
@ -45,7 +50,7 @@ public abstract class ADForm extends Window implements EventListener<Event>, IHe
/** /**
* *
*/ */
private static final long serialVersionUID = -2238655179806815227L; private static final long serialVersionUID = -5381283117636286759L;
/** The class' logging enabler */ /** The class' logging enabler */
protected static final CLogger logger; protected static final CLogger logger;
@ -68,6 +73,11 @@ public abstract class ADForm extends Window implements EventListener<Event>, IHe
private IFormController m_customForm; private IFormController m_customForm;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Constructor * Constructor
*/ */
@ -203,6 +213,8 @@ public abstract class ADForm extends Window implements EventListener<Event>, IHe
Env.setPredefinedVariables(Env.getCtx(), form.getWindowNo(), predefinedContextVariables); Env.setPredefinedVariables(Env.getCtx(), form.getWindowNo(), predefinedContextVariables);
Env.setContext(Env.getCtx(), form.getWindowNo(), "IsSOTrx", isSOTrx); Env.setContext(Env.getCtx(), form.getWindowNo(), "IsSOTrx", isSOTrx);
form.init(adFormID, name); form.init(adFormID, name);
form.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, form.getWindowNo()); // for closing the window with shortcut
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, form);
return form; return form;
} }
else else
@ -220,6 +232,11 @@ public abstract class ADForm extends Window implements EventListener<Event>, IHe
if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) { if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) {
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Form, getAdFormId()); SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Form, getAdFormId());
} }
else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this))
this.onCtrlKeyEvent(keyEvent);
}
} }
/** /**
@ -261,4 +278,18 @@ public abstract class ADForm extends Window implements EventListener<Event>, IHe
{ {
return gridTab; return gridTab;
} }
/**
* Handle shortcut key event
* @param keyEvent
*/
private void onCtrlKeyEvent(KeyEvent keyEvent) {
if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_WindowNo > 0) {
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_WindowNo);
}
}
}
} }

View File

@ -57,6 +57,7 @@ import org.adempiere.webui.component.ProcessInfoDialog;
import org.adempiere.webui.component.WListItemRenderer; import org.adempiere.webui.component.WListItemRenderer;
import org.adempiere.webui.component.WListbox; import org.adempiere.webui.component.WListbox;
import org.adempiere.webui.component.Window; import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WEditor;
import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeEvent;
@ -136,7 +137,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/** /**
* *
*/ */
private static final long serialVersionUID = -3055980415629613992L; private static final long serialVersionUID = 8253708190979803268L;
protected static final String ON_USER_QUERY_ATTR = "ON_USER_QUERY"; protected static final String ON_USER_QUERY_ATTR = "ON_USER_QUERY";
protected static final String INFO_QUERY_TIME_OUT_ERROR = "InfoQueryTimeOutError"; protected static final String INFO_QUERY_TIME_OUT_ERROR = "InfoQueryTimeOutError";
@ -340,7 +341,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
addEventListener(ON_RUN_PROCESS, this); addEventListener(ON_RUN_PROCESS, this);
addEventListener(ON_SELECT_ALL_RECORDS, this); addEventListener(ON_SELECT_ALL_RECORDS, this);
addEventListener(Events.ON_CLOSE, this); addEventListener(Events.ON_CLOSE, this);
addEventListener(Events.ON_CANCEL, e -> onCancel());
setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, p_WindowNo); // for closing the window with shortcut
} // InfoPanel } // InfoPanel
/** /**
@ -605,6 +607,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
protected Button btCbbProcess; protected Button btCbbProcess;
protected Combobox cbbProcess; protected Combobox cbbProcess;
protected Button btMenuProcess; protected Button btMenuProcess;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Loaded correctly * Loaded correctly
* @return true if loaded OK * @return true if loaded OK
@ -2378,9 +2386,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
else if (event.getName().equals(Events.ON_CTRL_KEY)) else if (event.getName().equals(Events.ON_CTRL_KEY))
{ {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
this.onCtrlKeyEvent(keyEvent); this.onCtrlKeyEvent(keyEvent);
}
}else if (event.getName().equals(Events.ON_OK)){// on ok when focus at non parameter component. example grid result }else if (event.getName().equals(Events.ON_OK)){// on ok when focus at non parameter component. example grid result
if (m_lookup && contentPanel.getSelectedIndex() >= 0){ if (m_lookup && contentPanel.getSelectedIndex() >= 0){
// do nothing when parameter not change and at window mode, or at dialog mode but select non record // do nothing when parameter not change and at window mode, or at dialog mode but select non record
@ -2420,6 +2427,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
} }
} else if (keyEvent.getKeyCode() == VK_ENTER) { // Enter } else if (keyEvent.getKeyCode() == VK_ENTER) { // Enter
// do nothing, let on_ok at infoWindo do, at this is too soon to get value from control, it's not bind // do nothing, let on_ok at infoWindo do, at this is too soon to get value from control, it's not bind
} else if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (p_WindowNo > 0) {
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(p_WindowNo);
}
} }
} }

View File

@ -33,6 +33,7 @@ import org.adempiere.webui.component.Listbox;
import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.Window; import org.adempiere.webui.component.Window;
import org.adempiere.webui.component.ZkCssHelper; import org.adempiere.webui.component.ZkCssHelper;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.panel.WSchedule; import org.adempiere.webui.panel.WSchedule;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
@ -40,6 +41,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.MAssignmentSlot; import org.compiere.model.MAssignmentSlot;
import org.compiere.model.MResourceAssignment; import org.compiere.model.MResourceAssignment;
import org.compiere.model.MRole; import org.compiere.model.MRole;
import org.compiere.model.MSysConfig;
import org.compiere.model.ScheduleUtil; import org.compiere.model.ScheduleUtil;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
@ -55,6 +57,7 @@ import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zul.Div; import org.zkoss.zul.Div;
import org.zkoss.zul.Hlayout; import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Space; import org.zkoss.zul.Space;
@ -76,13 +79,24 @@ import org.zkoss.zul.Vbox;
*/ */
public class InfoSchedule extends Window implements EventListener<Event> public class InfoSchedule extends Window implements EventListener<Event>
{ {
/**
*
*/
private static final long serialVersionUID = 3349721592479638482L;
/** /**
* @param mAssignment optional assignment * @param mAssignment optional assignment
* @param createNew if true, allows to create new assignments * @param createNew if true, allows to create new assignments
*/ */
private static final long serialVersionUID = -5948901371276429661L;
private Callback<MResourceAssignment> m_callback; private Callback<MResourceAssignment> m_callback;
private Component m_parent; private Component m_parent;
/** Window No */
private int m_windowNo;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Constructor * Constructor
@ -160,6 +174,11 @@ public class InfoSchedule extends Window implements EventListener<Event>
log.log(Level.SEVERE, "InfoSchedule", ex); log.log(Level.SEVERE, "InfoSchedule", ex);
} }
displayCalendar(); displayCalendar();
m_windowNo = SessionManager.getAppDesktop().registerWindow(this);
setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_windowNo); // for closing the window with shortcut
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
} // InfoSchedule } // InfoSchedule
/** /**
@ -480,6 +499,11 @@ public class InfoSchedule extends Window implements EventListener<Event>
doEdit((CalendarsEvent)event); doEdit((CalendarsEvent)event);
else if (event.getTarget() == fieldResource) else if (event.getTarget() == fieldResource)
displayCalendar(); displayCalendar();
else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this))
this.onCtrlKeyEvent(keyEvent);
}
// //
} }
@ -660,4 +684,18 @@ public class InfoSchedule extends Window implements EventListener<Event>
mask.detach(); mask.detach();
} }
} }
/**
* Handle shortcut key event
* @param keyEvent
*/
private void onCtrlKeyEvent(KeyEvent keyEvent) {
if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_windowNo > 0) {
keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_windowNo);
}
}
}
} // InfoSchedule } // InfoSchedule

View File

@ -93,7 +93,7 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
/** /**
* *
*/ */
private static final long serialVersionUID = -7204858572267608018L; private static final long serialVersionUID = -8782402996207677811L;
private JasperPrint jasperPrint; private JasperPrint jasperPrint;
private java.util.List<JasperPrint> jasperPrintList; private java.util.List<JasperPrint> jasperPrintList;
@ -109,8 +109,6 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
/** Window No */ /** Window No */
private int m_WindowNo = -1; private int m_WindowNo = -1;
private long prevKeyEventTime = 0;
private KeyEvent prevKeyEvent;
private String m_title; // local title - embedded windows clear the title private String m_title; // local title - embedded windows clear the title
Toolbar toolbar = new Toolbar(); Toolbar toolbar = new Toolbar();
@ -130,6 +128,10 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
protected final Map<String, Supplier<AMedia>> mediaSuppliers = new HashMap<String, Supplier<AMedia>>(); protected final Map<String, Supplier<AMedia>> mediaSuppliers = new HashMap<String, Supplier<AMedia>>();
protected Map<MAuthorizationAccount, IUploadService> uploadServicesMap = new HashMap<>(); protected Map<MAuthorizationAccount, IUploadService> uploadServicesMap = new HashMap<>();
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
private final ExportFormat[] exportFormats = new ExportFormat[] { private final ExportFormat[] exportFormats = new ExportFormat[] {
new ExportFormat(PDF_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), PDF_FILE_EXT, PDF_MIME_TYPE), new ExportFormat(PDF_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), PDF_FILE_EXT, PDF_MIME_TYPE),
@ -654,30 +656,15 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
actionPerformed(event); actionPerformed(event);
} else if (event.getName().equals(Events.ON_CTRL_KEY)) { } else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
//filter same key event that is too close
//firefox fire key event twice when grid is visible
long time = System.currentTimeMillis();
if (prevKeyEvent != null && prevKeyEventTime > 0 &&
prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() &&
prevKeyEvent.getTarget() == keyEvent.getTarget() &&
prevKeyEvent.isAltKey() == keyEvent.isAltKey() &&
prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() &&
prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) {
if ((time - prevKeyEventTime) <= 300) {
return;
}
}
this.onCtrlKeyEvent(keyEvent); this.onCtrlKeyEvent(keyEvent);
}
} }
} }
private void onCtrlKeyEvent(KeyEvent keyEvent) { private void onCtrlKeyEvent(KeyEvent keyEvent) {
if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_WindowNo > 0) { if (m_WindowNo > 0) {
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation(); keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_WindowNo); SessionManager.getAppDesktop().closeWindow(m_WindowNo);
} }

View File

@ -149,11 +149,10 @@ import org.zkoss.zul.impl.XulElement;
* @author Low Heng Sin * @author Low Heng Sin
*/ */
public class ZkReportViewer extends Window implements EventListener<Event>, IReportViewerExportSource { public class ZkReportViewer extends Window implements EventListener<Event>, IReportViewerExportSource {
/** /**
* generated serial id *
*/ */
private static final long serialVersionUID = 6307014622485159910L; private static final long serialVersionUID = 3732290698059632847L;
protected static final String CSV_OUTPUT_TYPE = "CSV"; protected static final String CSV_OUTPUT_TYPE = "CSV";
protected static final String HTML_OUTPUT_TYPE = "HTML"; protected static final String HTML_OUTPUT_TYPE = "HTML";
@ -163,8 +162,6 @@ public class ZkReportViewer extends Window implements EventListener<Event>, IRep
/** Window No */ /** Window No */
protected int m_WindowNo = -1; protected int m_WindowNo = -1;
private long prevKeyEventTime = 0;
private KeyEvent prevKeyEvent;
/** Print Context */ /** Print Context */
private Properties m_ctx; private Properties m_ctx;
/** Setting Values */ /** Setting Values */
@ -242,6 +239,11 @@ public class ZkReportViewer extends Window implements EventListener<Event>, IRep
private Center center; private Center center;
private FindWindow find; private FindWindow find;
/**
* SysConfig USE_ESC_FOR_TAB_CLOSING
*/
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
/** /**
* Static Layout * Static Layout
* @throws Exception * @throws Exception
@ -1158,22 +1160,8 @@ public class ZkReportViewer extends Window implements EventListener<Event>, IRep
onRenderReportEvent(); onRenderReportEvent();
} else if (event.getName().equals(Events.ON_CTRL_KEY)) { } else if (event.getName().equals(Events.ON_CTRL_KEY)) {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
if (LayoutUtils.isReallyVisible(this)) { if (LayoutUtils.isReallyVisible(this))
//filter same key event that is too close
//firefox fire key event twice when grid is visible
long time = System.currentTimeMillis();
if (prevKeyEvent != null && prevKeyEventTime > 0 &&
prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() &&
prevKeyEvent.getTarget() == keyEvent.getTarget() &&
prevKeyEvent.isAltKey() == keyEvent.isAltKey() &&
prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() &&
prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) {
if ((time - prevKeyEventTime) <= 300) {
return;
}
}
this.onCtrlKeyEvent(keyEvent); this.onCtrlKeyEvent(keyEvent);
}
} }
else if (event.getTarget() instanceof ProcessModalDialog) else if (event.getTarget() instanceof ProcessModalDialog)
{ {
@ -1201,10 +1189,9 @@ public class ZkReportViewer extends Window implements EventListener<Event>, IRep
} }
private void onCtrlKeyEvent(KeyEvent keyEvent) { private void onCtrlKeyEvent(KeyEvent keyEvent) {
if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X if ((keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) // Alt-X
|| (keyEvent.getKeyCode() == 0x1B && isUseEscForTabClosing)) { // ESC
if (m_WindowNo > 0) { if (m_WindowNo > 0) {
prevKeyEventTime = System.currentTimeMillis();
prevKeyEvent = keyEvent;
keyEvent.stopPropagation(); keyEvent.stopPropagation();
SessionManager.getAppDesktop().closeWindow(m_WindowNo); SessionManager.getAppDesktop().closeWindow(m_WindowNo);
} }