From 19459be87b5b5502d37e2cd468039089ac1b42d7 Mon Sep 17 00:00:00 2001 From: hengsin Date: Thu, 9 Feb 2023 21:39:59 +0800 Subject: [PATCH] IDEMPIERE-5570 Zk: Improve readability of code (#1666) --- .../zk/atmosphere/AtmosphereServerPush.java | 23 ++ .../fi/jawsy/jawwa/zk/atmosphere/Either.java | 41 ++ .../zk/atmosphere/ZkAtmosphereHandler.java | 27 ++ .../org/adempiere/webui/AdempiereWebUI.java | 89 +++- .../src/org/adempiere/webui/ClientInfo.java | 6 +- .../adempiere/webui/DefaultWebAppInit.java | 2 +- .../adempiere/webui/DelegatingServlet.java | 1 + .../src/org/adempiere/webui/Extensions.java | 6 +- .../src/org/adempiere/webui/IWebClient.java | 23 +- .../src/org/adempiere/webui/LayoutUtils.java | 78 ++-- .../webui/LoggedSessionListener.java | 29 +- .../org/adempiere/webui/ShowMaskWrapper.java | 4 +- .../adempiere/webui/UiLifeCycleListener.java | 2 +- .../org/adempiere/webui/ValuePreference.java | 55 +-- .../src/org/adempiere/webui/WArchive.java | 3 +- .../src/org/adempiere/webui/WLogin.java | 23 +- .../src/org/adempiere/webui/WRequest.java | 10 +- .../src/org/adempiere/webui/WZoomAcross.java | 31 +- .../org/adempiere/webui/WebUIActivator.java | 7 +- .../org/adempiere/webui/acct/WAcctViewer.java | 79 ++-- .../adempiere/webui/acct/WAcctViewerData.java | 119 +++--- .../org/adempiere/webui/action/Actions.java | 7 +- .../org/adempiere/webui/action/IAction.java | 2 +- .../adempiere/webui/adwindow/ADSortTab.java | 71 +++- .../adempiere/webui/adwindow/ADTabpanel.java | 210 +++++++--- .../adempiere/webui/adwindow/ADTreePanel.java | 28 +- .../adempiere/webui/adwindow/ADWindow.java | 56 ++- .../webui/adwindow/ADWindowContent.java | 40 +- .../webui/adwindow/ADWindowToolbar.java | 374 ++++++++++++++--- .../webui/adwindow/AbstractADTabbox.java | 71 ++-- .../adwindow/AbstractADWindowContent.java | 383 ++++++++++++++---- .../adempiere/webui/adwindow/BreadCrumb.java | 62 ++- .../webui/adwindow/BreadCrumbLink.java | 9 +- .../webui/adwindow/CompositeADTabbox.java | 88 +++- .../adempiere/webui/adwindow/DetailPane.java | 149 +++++-- .../webui/adwindow/GridTabRowRenderer.java | 111 ++++- .../webui/adwindow/GridTableListModel.java | 13 +- .../adempiere/webui/adwindow/GridView.java | 265 +++++++++--- .../adempiere/webui/adwindow/IADTabbox.java | 65 +-- .../adempiere/webui/adwindow/IADTabpanel.java | 81 ++-- .../webui/adwindow/IFieldEditorContainer.java | 11 +- .../webui/adwindow/ProcessButtonPopup.java | 43 +- .../adwindow/QuickGridTabRowRenderer.java | 79 +++- .../webui/adwindow/QuickGridView.java | 165 +++++++- .../adempiere/webui/adwindow/StatusBar.java | 65 ++- .../webui/adwindow/ToolbarCustomButton.java | 46 +++ .../webui/adwindow/ToolbarProcessButton.java | 36 +- .../adwindow/validator/WindowValidator.java | 34 ++ .../validator/WindowValidatorEvent.java | 40 ++ .../validator/WindowValidatorEventType.java | 36 ++ .../validator/WindowValidatorManager.java | 79 +++- .../org/adempiere/webui/panel/LoginPanel.java | 3 +- .../adempiere/webui/window/LoginWindow.java | 3 +- 53 files changed, 2647 insertions(+), 736 deletions(-) diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java index 3328000923..dfe3f7e6dd 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java @@ -53,11 +53,13 @@ public class AtmosphereServerPush implements ServerPush { private static final String ON_ACTIVATE_DESKTOP = "onActivateDesktop"; + /** default timeout of of 2 minutes **/ public static final int DEFAULT_TIMEOUT = 1000 * 60 * 2; private final AtomicReference desktop = new AtomicReference(); private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** asynchronous request reference as AtmosphereResource **/ private final AtomicReference resource = new AtomicReference(); private final int timeout; @@ -66,6 +68,9 @@ public class AtmosphereServerPush implements ServerPush { private final Object _mutex = new Object(); private List> schedules = new ArrayList<>(); + /** + * default constructor + */ public AtmosphereServerPush() { String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout"); if (timeoutString == null || timeoutString.trim().length() == 0) { @@ -120,10 +125,19 @@ public class AtmosphereServerPush implements ServerPush { return true; } + /** + * release current AtmosphereResource + * @param resource + */ public void clearResource(AtmosphereResource resource) { this.resource.compareAndSet(resource, null); } + /** + * commit/resume response for current AtmosphereResource + * @return true if resource is available + * @throws IOException + */ private boolean commitResponse() throws IOException { AtmosphereResource resource = this.resource.getAndSet(null); if (resource != null) { @@ -224,6 +238,10 @@ public class AtmosphereServerPush implements ServerPush { startClientPush(desktop); } + /** + * start serverpush request at client side + * @param desktop + */ private void startClientPush(Desktop desktop) { Clients.response("jawwa.atmosphere.serverpush", new AuScript(null, "jawwa.atmosphere.startServerPush('" + desktop.getId() + "', " + timeout + ");")); @@ -256,6 +274,10 @@ public class AtmosphereServerPush implements ServerPush { } } + /** + * handle asynchronous server push request (long polling request) + * @param resource + */ public void onRequest(AtmosphereResource resource) { if (log.isTraceEnabled()) { log.trace(resource.transport().name()); @@ -267,6 +289,7 @@ public class AtmosphereServerPush implements ServerPush { return; } + //suspend request for server push event if (!resource.isSuspended()) { //browser default timeout is 2 minutes resource.suspend(5, TimeUnit.MINUTES); diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/Either.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/Either.java index 55260cdcf4..9854b0c7b9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/Either.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/Either.java @@ -1,18 +1,59 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ package fi.jawsy.jawwa.zk.atmosphere; +/** + * class to hold two value, left and right + * @author hengsin + * + * @param + * @param + */ public class Either { private L left; private R right; + /** + * @param l left value + * @param r right value + */ public Either(L l, R r) { left = l; right = r; } + /** + * @return left value + */ public L getLeftValue() { return left; } + /** + * @return right value + */ public R getRightValue() { return right; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java index 25b91f0ff4..5b5bcad140 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java @@ -51,6 +51,12 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { public void destroy() { } + /** + * Get Zk {@link Desktop} instance from session by desktop id + * @param session + * @param dtid desktop id + * @return left as error message and right as {@link Desktop} reference + */ private Either getDesktop(Session session, String dtid) { if (session.getWebApp() instanceof WebAppCtrl) { WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp(); @@ -64,11 +70,21 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { return new Either("Webapp does not implement WebAppCtrl", null); } + /** + * Get Zk {@link Desktop} id from HttpServletRequest parameter (dtid) + * @param request + * @return left as desktop id and right as error message + */ private Either getDesktopId(HttpServletRequest request) { String dtid = request.getParameter("dtid"); return new Either(dtid, DESKTOP_NOT_FOUND); } + /** + * Get {@link AtmosphereServerPush} instance from {@link AtmosphereResource} + * @param resource {@link AtmosphereResource} + * @return left as error message and right as AtmosphereServerPush reference + */ private Either getServerPush(AtmosphereResource resource) { AtmosphereRequest request = resource.getRequest(); @@ -96,6 +112,11 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { } } + /** + * Get {@link AtmosphereServerPush} instance from {@link Desktop} + * @param desktop + * @return left as error message and right as {@link AtmosphereServerPush} reference + */ private Either getServerPush(Desktop desktop) { if (desktop instanceof DesktopCtrl) { DesktopCtrl desktopCtrl = (DesktopCtrl) desktop; @@ -109,6 +130,12 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { return new Either("Desktop does not implement DesktopCtrl", null); } + /** + * Get {@link Session} from request + * @param resource + * @param request + * @return left as error message and right as Session reference + */ private Either getSession(AtmosphereResource resource, HttpServletRequest request) { Session session = WebManager.getSession(resource.getAtmosphereConfig().getServletContext(), request, false); if (session == null) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java index 0d47749945..c0dad29883 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java @@ -90,23 +90,31 @@ import org.zkoss.zul.Window; */ public class AdempiereWebUI extends Window implements EventListener, IWebClient { + /** {@link Session} attribute to hold current login user id value **/ + public static final String CHECK_AD_USER_ID_ATTR = "Check_AD_User_ID"; + + /** Boolean attribute to indicate the HTTP session of a Desktop have been invalidated **/ public static final String DESKTOP_SESSION_INVALIDATED_ATTR = "DesktopSessionInvalidated"; /** - * + * generated serial id */ private static final long serialVersionUID = -6725805283410008847L; + /** {@link Desktop} attribute to hold {@link IDesktop} reference **/ public static final String APPLICATION_DESKTOP_KEY = "application.desktop"; public static String APP_NAME = null; public static final String UID = "1.0.0"; + /** Attribute for widget instance name, use for Selenium test **/ public static final String WIDGET_INSTANCE_NAME = "instanceName"; + /** login and role selection window **/ private WLogin loginDesktop; + /** client info from browser **/ private ClientInfo clientInfo = new ClientInfo(); private String langSession; @@ -119,16 +127,23 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb private static final CLogger logger = CLogger.getCLogger(AdempiereWebUI.class); + @Deprecated(forRemoval = true, since = "11") public static final String EXECUTION_CARRYOVER_SESSION_KEY = "execution.carryover"; + /** Session attribute to hold {@link ClientInfo} reference **/ private static final String CLIENT_INFO = "client.info"; + /** the use of event thread have been deprecated, this should always be false **/ private static boolean eventThreadEnabled = false; private ConcurrentMap m_URLParameters; + /** Login completed event **/ private static final String ON_LOGIN_COMPLETED = "onLoginCompleted"; + /** + * default constructor + */ public AdempiereWebUI() { this.setVisible(false); @@ -140,8 +155,12 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb this.addEventListener(ON_LOGIN_COMPLETED, this); } + /** + * Handle onCreate event from index.zul, don't call this directly. + */ public void onCreate() { + //handle ping request String ping = Executions.getCurrent().getHeader("X-PING"); if (!Util.isEmpty(ping, true)) { @@ -183,6 +202,9 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb eventThreadEnabled = Executions.getCurrent().getDesktop().getWebApp().getConfiguration().isEventThreadEnabled(); } + /** + * perform clean up for ping request + */ private void cleanupForPing() { final Desktop desktop = Executions.getCurrent().getDesktop(); final WebApp wapp = desktop.getWebApp(); @@ -208,10 +230,16 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb }, 1, TimeUnit.SECONDS); } + /** + * Handle onOK (enter key) event + */ public void onOk() { } + /** + * Handle onCancel(escape key) event + */ public void onCancel() { } @@ -219,6 +247,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb /* (non-Javadoc) * @see org.adempiere.webui.IWebClient#loginCompleted() */ + @Override public void loginCompleted() { if (loginDesktop != null) @@ -280,7 +309,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb mSession.saveEx(); } - currSess.setAttribute("Check_AD_User_ID", Env.getAD_User_ID(ctx)); + currSess.setAttribute(CHECK_AD_USER_ID_ATTR, Env.getAD_User_ID(ctx)); //enable full interface, relook into this when doing preference Env.setContext(ctx, Env.SHOW_TRANSLATION, true); @@ -298,14 +327,14 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb keyListener.setCtrlKeys("@a@c@d@e@f@h@l@m@n@o@p@q@r@s@t@w@x@z@#left@#right@#up@#down@#home@#end#enter^u@u@#pgdn@#pgup$#f2^#f2"); keyListener.setAutoBlur(false); - //create new desktop + //create IDesktop instance IDesktop appDesktop = createDesktop(); appDesktop.setClientInfo(clientInfo); appDesktop.createPart(this.getPage()); this.getPage().getDesktop().setAttribute(APPLICATION_DESKTOP_KEY, new WeakReference(appDesktop)); appDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this); - //track browser tab per session + //track browser tab per session, 1 browser tab = 1 zk Desktop SessionContextListener.addDesktopId(mSession.getAD_Session_ID(), getPage().getDesktop().getId()); //ensure server push is on @@ -330,7 +359,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb Env.setContext(ctx, Env.IS_CAN_APPROVE_OWN_DOC, MRole.getDefault().isCanApproveOwnDoc()); Clients.response(new AuScript("zAu.cmd0.clearBusy()")); - //add dynamic style + //add dynamic style for AD tab StringBuilder cssContent = new StringBuilder(); cssContent.append(".adtab-form-borderlayout .z-south-collapsed:before { "); cssContent.append("content: \""); @@ -347,6 +376,9 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb processParameters(); } + /** + * process URL parameters from browser + */ private void processParameters() { String action = getPrmString("Action"); if ("Zoom".equalsIgnoreCase(action)) { @@ -368,6 +400,10 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb m_URLParameters = null; } + /** + * @param prm parameter name + * @return string value for parameter + */ private String getPrmString(String prm) { String retValue = ""; if (m_URLParameters != null) { @@ -378,6 +414,10 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb return retValue; } + /** + * @param prm parameter name + * @return integer value for parameter + */ private int getPrmInt(String prm) { int retValue = 0; String str = getPrmString(prm); @@ -398,6 +438,10 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb return keyListener; } + /** + * Create IDesktop instance. Default is {@link DefaultDesktop} + * @return {@link IDesktop} + */ private IDesktop createDesktop() { IDesktop appDesktop = null; @@ -424,6 +468,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb /* (non-Javadoc) * @see org.adempiere.webui.IWebClient#logout() */ + @Override public void logout() { final Desktop desktop = Executions.getCurrent().getDesktop(); @@ -447,6 +492,10 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb } } + /** + * after logout action for Session + * @param session + */ private void afterLogout(final Session session) { try { ((SessionCtrl)session).onDestroyed(); @@ -457,7 +506,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb } /** - * Perform logout after user close a browser tab without first logging out + * Auto logout after user close browser tab without first logging out */ public void logoutAfterTabDestroyed(){ Desktop desktop = Executions.getCurrent().getDesktop(); @@ -472,7 +521,10 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb afterLogout(session); } - + /** + * Logout current session + * @return {@link Session} + */ protected Session logout0() { Session session = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop().getSession() : null; @@ -502,6 +554,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb /** * @return IDesktop */ + @Override public IDesktop getAppDeskop() { Desktop desktop = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop() : null; @@ -519,6 +572,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb return appDesktop; } + @Override public void onEvent(Event event) { if (event instanceof ClientInfoEvent) { ClientInfoEvent c = (ClientInfoEvent)event; @@ -564,6 +618,11 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb } + /** + * handle change role event + * @param locale + * @param context + */ private void onChangeRole(Locale locale, Properties context) { SessionManager.setSessionApplication(this); loginDesktop = new WLogin(this); @@ -576,6 +635,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb * @param userId * @return UserPreference */ + @Override public UserPreference loadUserPreference(int userId) { userPreference.loadPreference(userId); return userPreference; @@ -584,10 +644,15 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb /** * @return UserPrerence */ + @Override public UserPreference getUserPreference() { return userPreference; } + /** + * Should always return false + * @return true if event thread is enabled + */ public static boolean isEventThreadEnabled() { return eventThreadEnabled; } @@ -635,6 +700,12 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb appDesktop.logout(T -> {if (T) asyncChangeRole(session, locale, properties);}); } + /** + * change role, asynchronous callback from {@link IDesktop#logout(org.adempiere.util.Callback)} + * @param httpSession + * @param locale + * @param properties + */ private void asyncChangeRole(HttpSession httpSession, Locale locale, Properties properties) { //stop key listener if (keyListener != null) { @@ -675,8 +746,8 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb } /** - * @return string for setupload - */ + * @return setting for setUpload call + */ public static String getUploadSetting() { StringBuilder uploadSetting = new StringBuilder("true,native"); int size = MSysConfig.getIntValue(MSysConfig.ZK_MAX_UPLOAD_SIZE, 0); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java index 02e13a380a..b2eeab82bc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java @@ -29,16 +29,17 @@ import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.sys.ComponentCtrl; /** - * + * Model for client info from browser * @author Low Heng Sin * */ public class ClientInfo implements Serializable { /** - * + * generated serial id */ private static final long serialVersionUID = -2686811277627911861L; + //values from browser public int colorDepth; public int desktopWidth; public int desktopHeight; @@ -52,6 +53,7 @@ public class ClientInfo implements Serializable { public boolean tablet; public double devicePixelRatio; + //size constants for responsive layout public static final int LARGE_WIDTH = 1200; public static final int MEDIUM_WIDTH = 1000; public static final int SMALL_WIDTH = 700; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DefaultWebAppInit.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DefaultWebAppInit.java index f9b56fd558..c84745d2b3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DefaultWebAppInit.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DefaultWebAppInit.java @@ -67,7 +67,7 @@ public class DefaultWebAppInit implements WebAppInit { } /** - * Process modle event of table system config + * Process model event of table system config * @author hieplq * */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DelegatingServlet.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DelegatingServlet.java index 9ce7d402db..efbc4b2f44 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DelegatingServlet.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/DelegatingServlet.java @@ -10,6 +10,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; +@Deprecated(forRemoval = true, since = "11") public class DelegatingServlet extends HttpServlet { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java index f9a499fab7..2a62f8cc40 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java @@ -50,7 +50,7 @@ import org.idempiere.ui.zk.media.IMediaViewProvider; import org.zkoss.zk.ui.Component; /** - * + * Entry point to get implementation instance for UI extensions (through OSGI service or Equinox extension). * @author viola * @author hengsin * @@ -372,8 +372,8 @@ public class Extensions { } /** - * @param tabType - * @return {@link IADTabpanel} + * @param tabType build in - FORM or SORT, custom - through IADTabPanelFactory extension + * @return {@link IADTabpanel} */ public static IADTabpanel getADTabPanel(String tabType) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/IWebClient.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/IWebClient.java index 59f783b7ef..6ccf86917e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/IWebClient.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/IWebClient.java @@ -18,56 +18,61 @@ import org.compiere.model.MUser; import org.zkforge.keylistener.Keylistener; /** - * + * Interface for web client * @author hengsin * */ public interface IWebClient { /** - * login completed + * handle login completed */ public void loginCompleted(); /** - * logout + * handle logout */ public void logout(); /** - * logout after browser destroyed + * auto logout after close of browser tab */ public void logoutAfterTabDestroyed(); /** - * + * Get {@link IDesktop} instance * @return IDesktop */ public IDesktop getAppDeskop(); /** - * + * load user preference by user id * @param userId * @return UserPreference */ public UserPreference loadUserPreference(int userId); /** - * + * Get current user preference * @return UserPreference */ public UserPreference getUserPreference(); /** - * change Role + * handle change Role */ public void changeRole(MUser user); /** - * @return keylistener + * Get global key listener + * @return {@link Keylistener} */ public abstract Keylistener getKeylistener(); + /** + * Get current ClientInfo + * @return {@link ClientInfo} + */ default ClientInfo getClientInfo() { return getAppDeskop().getClientInfo(); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java index b32d8b2e0f..c02eeb0a8a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java @@ -44,7 +44,7 @@ import org.zkoss.zul.Window; import org.zkoss.zul.Window.Mode; /** - * + * Some static UI helper methods * @author Low Heng Sin * */ @@ -55,7 +55,7 @@ public final class LayoutUtils { /** * @param layout */ - @Deprecated + @Deprecated(forRemoval = true, since = "11") public static void sendDeferLayoutEvent(org.zkoss.zul.Borderlayout layout, int timeout) { /* this is not required anymore */ // StringBuilder content = new StringBuilder(); @@ -68,7 +68,7 @@ public final class LayoutUtils { } /** - * + * append cls to target's sclass property * @param cls * @param target */ @@ -82,7 +82,7 @@ public final class LayoutUtils { * * @param cls * @param target - * @return boolean + * @return true if target's sclass property contain cls */ public static boolean hasSclass(String cls, HtmlBasedComponent target) { String sclass = target.getSclass(); @@ -93,9 +93,9 @@ public final class LayoutUtils { } /** - * + * create right align label (wrapped in div) * @param label - * @return wrapped label + * @return right align label (wrapped in div) */ public static Component makeRightAlign(Label label) { Div div = new Div(); @@ -105,28 +105,41 @@ public final class LayoutUtils { return div; } + /** + * open popup window overlapping ref component + * @param ref + * @param window + */ public static void openPopupWindow(Component ref, Window window) { openPopupWindow(ref, window, 0); } /** - * open popup window overlapping the ref component + * open popup window overlapping ref component * @param ref * @param window + * @param delayMs */ public static void openPopupWindow(Component ref, Window window, int delayMs) { openPopupWindow(ref, window, "overlap", delayMs); } + /** + * open popup window relative to ref component + * @param ref + * @param window + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- + */ public static void openPopupWindow(Component ref, Window window, String position) { openPopupWindow(ref, window, position, 0); } /** - * open popup window relative to the ref component + * open popup window relative to ref component * @param ref * @param window - * @param position + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- + * @param delayMs */ public static void openPopupWindow(Component ref, Window window, String position, int delayMs) { if (window.getPage() == null) @@ -152,10 +165,10 @@ public final class LayoutUtils { } /** - * open popup window relative to the ref component + * open overlapped window (mode overlapped) relative to ref component * @param ref * @param window - * @param position + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- */ public static void openOverlappedWindow(Component ref, Window window, String position) { if (window.getPage() == null) @@ -173,10 +186,10 @@ public final class LayoutUtils { } /** - * position opened window relative to the ref component + * position opened window relative to ref component * @param ref * @param window - * @param position + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- */ public static void positionWindow(Component ref, Window window, String position) { StringBuilder script = new StringBuilder(); @@ -191,10 +204,10 @@ public final class LayoutUtils { } /** - * open embedded window relative to the ref component + * open embedded window relative to ref component * @param ref * @param window - * @param position + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- */ public static void openEmbeddedWindow(Component ref, Window window, String position) { StringBuilder script = new StringBuilder(); @@ -211,10 +224,10 @@ public final class LayoutUtils { } /** - * open highlighted window relative to the ref component + * open highlighted window relative to ref component * @param ref * @param window - * @param position + * @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map- */ public static void openHighlightedWindow(Component ref, Window window, String position) { StringBuilder script = new StringBuilder(); @@ -230,7 +243,7 @@ public final class LayoutUtils { } /** - * + * Force redraw of component * @param component */ public static void redraw(AbstractComponent component) { @@ -259,6 +272,11 @@ public final class LayoutUtils { return true; } + /** + * Remove cls from target's sclass property + * @param cls + * @param target + */ public static void removeSclass(String cls, HtmlBasedComponent target) { String sclass = target.getSclass(); if (Util.isEmpty(sclass)) @@ -281,13 +299,13 @@ public final class LayoutUtils { /** * show window with a mask below. mask over tabPanel, all window or only over a control, dependency ownModel flag. * when ownModel == {@link #OVERLAP_SELF}, window show overlap childOfOwn, - * when childOfOwn isn't implement {@link ISupportMask} make new {@link Mask} object to make mask layout + * when childOfOwn doesn't implement {@link ISupportMask} make new {@link Mask} object to make mask layout * ownModel == {@link #OVERLAP_ALL_PAGE}, window show overlap all page * ownModel == {@link #OVERLAP_TAB_PANEL}, window show overlap tabPanel * ownModel == {@link #OVERLAP_PARENT}, search near parent of childOfOwn implement {@link ISupportMask} if not exist user as OVERLAP_ALL_PAGE * @param window * @param childOfOwn - * @param ownModel + * @param ownModel OVERLAP_TAB_PANEL, OVERLAP_ALL_PAGE, OVERLAP_PARENT or OVERLAP_SELF * @return when show success return IMask object, it is own window, use {@link ISupportMask#hideMask()} to hidden mask. * other return null. */ @@ -316,7 +334,7 @@ public final class LayoutUtils { } /** - * Show window in center of component + * Show window in center of mask * @param window * @param mask */ @@ -334,7 +352,7 @@ public final class LayoutUtils { } /** - * Show window over ownWindow with a mask, use when ownWindow isn't implement {@link ISupportMask} + * Show window over ownWindow with a mask, use when ownWindow doesn't implement {@link ISupportMask} * @param window * @param ownWindow * @param mask if mask = null, make new and return it @@ -353,11 +371,11 @@ public final class LayoutUtils { } /** - * find parent control of child control, parent must implement {@link ISupportMask} + * find parent of child component, parent must implement {@link ISupportMask} * if parentClass != null, parent class must extends parentClass * @param child * @param parentClass - * @return + * @return {@link ISupportMask} */ public static ISupportMask findMaskParent (Component child, Class parentClass){ Component parent = child; @@ -429,6 +447,11 @@ public final class LayoutUtils { } } + /** + * Expand number of grid column to min (for e.g, to min of 2 column) + * @param grid + * @param min + */ public static void expandTo(Grid grid, int min) { expandTo(grid, min, false); } @@ -488,6 +511,7 @@ public final class LayoutUtils { } } + /** Event listener to add/remove slide from target component's sclass property **/ private static final EventListener addSlideEventListener = (OpenEvent evt) -> { if (evt.isOpen()) LayoutUtils.removeSclass("slide", (HtmlBasedComponent) evt.getTarget()); @@ -504,7 +528,7 @@ public final class LayoutUtils { } /** - * find popup ancestor of comp + * find first popup ancestor of comp * @param comp * @return {@link Popup} if comp or one of its ancestor is Popup */ @@ -519,7 +543,7 @@ public final class LayoutUtils { } /** - * call popup.detach when it is close + * Auto call popup.detach when popup is close * @param popup */ public static void autoDetachOnClose(Popup popup) { @@ -531,7 +555,7 @@ public final class LayoutUtils { } /** - * set target same width as ref using client side script + * Make target same width as ref using client side script * @param target * @param ref */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LoggedSessionListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LoggedSessionListener.java index 7ffb89650e..bb0194f473 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LoggedSessionListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LoggedSessionListener.java @@ -1,3 +1,25 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + **********************************************************************/ package org.adempiere.webui; import java.io.File; @@ -23,6 +45,9 @@ import org.compiere.util.DB; import org.compiere.util.Ini; import org.compiere.util.WebUtil; +/** + * Sync state of {@link HttpSession} and AD_Session + */ public class LoggedSessionListener implements HttpSessionListener, ServletContextListener, ServerStateChangeListener{ private static Hashtable AD_SessionList = new Hashtable(); private static final CLogger logger = CLogger.getCLogger(LoggedSessionListener.class); @@ -83,7 +108,7 @@ public class LoggedSessionListener implements HttpSessionListener, ServletContex */ } - public void DestroyAllSession() { + private void DestroyAllSession() { if (!Adempiere.isStarted()) { Adempiere.addServerStateChangeListener(this); @@ -100,7 +125,7 @@ public class LoggedSessionListener implements HttpSessionListener, ServletContex Adempiere.removeServerStateChangeListener(this); } - public void removeADSession(String sessionID, String serverName) { + private void removeADSession(String sessionID, String serverName) { String sql = "UPDATE AD_Session SET Processed='Y' WHERE WebSession=? AND ServerName=? AND Processed='N'"; int no = DB.executeUpdate(sql, new Object[] {sessionID, serverName}, false, null); if (no < 0) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ShowMaskWrapper.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ShowMaskWrapper.java index a42dc28582..6bbd56071e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ShowMaskWrapper.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ShowMaskWrapper.java @@ -21,7 +21,7 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.util.Clients; /** - * Helper class for any component want implement {@link ISupportMask} + * Helper class for {@link ISupportMask} implementation * Just make a instance of this class and let it do everything * @author hieplq * @@ -39,7 +39,7 @@ public class ShowMaskWrapper implements ISupportMask { private Mask maskObj; /** - * comp is component want implement this interface + * comp is component that implement ISupportMask * @param comp */ public ShowMaskWrapper (Component comp){ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/UiLifeCycleListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/UiLifeCycleListener.java index 67ee6f61b9..8f80602e9f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/UiLifeCycleListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/UiLifeCycleListener.java @@ -20,8 +20,8 @@ import org.zkoss.zk.ui.ShadowElement; import org.zkoss.zk.ui.util.UiLifeCycle; /** + * Utility class for selenium support * @author hengsin - * */ public class UiLifeCycleListener implements UiLifeCycle { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java index eb98f93ec5..287200505e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java @@ -68,12 +68,12 @@ import org.zkoss.zul.Vlayout; public class ValuePreference extends Window implements EventListener { /** - * + * generated serial id */ private static final long serialVersionUID = 7594680475358417813L; /** - * Factory + * Show value preference dialog * @param ref * @param mField field * @param aValue value @@ -89,7 +89,7 @@ public class ValuePreference extends Window implements EventListener } // start /** - * Factory + * Show value preference dialog * @param ref * @param mField field * @param aValue value @@ -127,7 +127,7 @@ public class ValuePreference extends Window implements EventListener int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), WindowNo, "AD_Org_ID"); int AD_User_ID = Env.getAD_User_ID(Env.getCtx()); - // Create Editor + // Create and show value preference dialog @SuppressWarnings("unused") ValuePreference vp = new ValuePreference (WindowNo, AD_Client_ID, AD_Org_ID, AD_User_ID, AD_Window_ID, mField.getAD_Process_ID_Of_Panel(), mField.getAD_InfoWindow_ID_of_Panel(), @@ -135,42 +135,8 @@ public class ValuePreference extends Window implements EventListener displayType, AD_Reference_ID, ref); } // create - /** - * Create the popup menu item to start the ValuePreference editor. - * - * .. add method - * public void setField (MField mField) - * { - * m_mField = mField; - * if (m_mField != null) - * ValuePreference.addMenu (this, m_popupMenu); - * } // setField - * - * .. in actionPerformed add .. - * if (e.getActionCommand().equals(ValuePreference.NAME)) - * { - * ValuePreference.start (m_mField, getValue(), DisplayValue); - * return; - * } - * - * @param l listener - * @param popupMenu menu - * @return JMenuItem - */ - /* - public static CMenuItem addMenu (ActionListener l, JPopupMenu popupMenu) - { - CMenuItem mi = new CMenuItem (Msg.getMsg(Env.getCtx(), NAME), s_icon); - mi.setActionCommand(NAME); - mi.addActionListener(l); - popupMenu.add(mi); - return mi; - }*/ // addMenu - - /** The Name of the Editor */ + /** The Name of the Dialog */ public static final String NAME = "ValuePreference"; - /** The Menu Icon */ - //private static String ICON_URL = "images/VPreference16.png"; /** Logger */ private static final CLogger log = CLogger.getCLogger(ValuePreference.class); private AbstractADWindowContent adwindowContent; @@ -189,7 +155,7 @@ public class ValuePreference extends Window implements EventListener * @param DisplayValue value display * @param displayType display type * @param AD_Reference_ID reference - * @param ref + * @param ref */ public ValuePreference (int WindowNo, int AD_Client_ID, int AD_Org_ID, int AD_User_ID, int AD_Window_ID, int AD_Process_ID_Of_Panel, int AD_Infowindow_ID, @@ -439,7 +405,6 @@ public class ValuePreference extends Window implements EventListener // ActionListener cbClient.setEnabled(false); cbClient.setChecked(true); - // cbClient.addActionListener(this); // Can Change Org if (MRole.PREFERENCETYPE_Client.equals(m_role.getPreferenceType())) @@ -498,7 +463,7 @@ public class ValuePreference extends Window implements EventListener } else setExplanation(); - } // actionPerformed + } private void onCancel() { this.detach(); @@ -557,8 +522,6 @@ public class ValuePreference extends Window implements EventListener */ public int delete() { - log.info(""); - StringBuilder sql = new StringBuilder ("DELETE FROM AD_Preference WHERE "); sql.append("AD_Client_ID=").append(cbClient.isChecked() ? m_AD_Client_ID : 0); sql.append(" AND AD_Org_ID=").append(cbOrg.isChecked() ? m_AD_Org_ID : 0); @@ -654,12 +617,10 @@ public class ValuePreference extends Window implements EventListener } // getContextKey /** - * Save to Disk + * Save to DB */ public void insert() { - log.info(""); - // --- Delete first int no = delete(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WArchive.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WArchive.java index 51e6fb2b67..658e58212a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WArchive.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WArchive.java @@ -143,7 +143,7 @@ public class WArchive implements EventListener } // getZoomTargets /** - * Listner + * Listener * @param e event */ @Override @@ -151,6 +151,7 @@ public class WArchive implements EventListener { if (e.getTarget() instanceof Menuitem) { + //open archive viewer int AD_Form_ID = FORM_ARCHIVEVIEWER; // ArchiveViewer ADForm form = ADForm.openForm(AD_Form_ID); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java index 5ecae731e5..48c0240573 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java @@ -34,7 +34,7 @@ import org.zkoss.zul.West; import org.zkoss.zul.Window; /** - * + * Manage login window for login and role selection * @author Ashley G Ramdass * @author Low Heng Sin * @date Mar 3, 2007 @@ -42,17 +42,28 @@ import org.zkoss.zul.Window; */ public class WLogin extends AbstractUIPart { - + /** IWebClient instance ({@link AdempiereWebUI}) **/ private IWebClient app; + /** Main layout **/ private Borderlayout layout; + @Deprecated(forRemoval = true, since = "11") private Window browserWarningWindow; + /** embedded window for login and role selection **/ private LoginWindow loginWindow; + /** + * + * @param app + */ public WLogin(IWebClient app) { this.app = app; } + /** + * Create UI from login.zul file. The main layout component ("layout") must be instance of {@link Borderlayout}. + */ + @Override protected Component doCreatePart(Component parent) { PageDefinition pageDefintion = Executions.getCurrent().getPageDefinition(ThemeManager.getThemeResource("zul/login/login.zul")); @@ -107,6 +118,9 @@ public class WLogin extends AbstractUIPart return layout; } + /** + * detach/dispose window content + */ public void detach() { layout.detach(); layout = null; @@ -114,12 +128,15 @@ public class WLogin extends AbstractUIPart browserWarningWindow.detach(); } + /** + * @return {@link Component} + */ public Component getComponent() { return layout; } /** - * Show change role window + * Show change role panel in {@link #loginWindow} * @param locale * @param properties env context */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WRequest.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WRequest.java index b6ffe45655..dba54819dc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WRequest.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WRequest.java @@ -36,8 +36,8 @@ import org.zkoss.zul.Menupopup; import org.zkoss.zul.Popup; /** - * Request Button Action. - * Popup Menu + * Handle Request Button Action. + * Show Popup Menu. * * @author Jorg Janke * @version $Id: ARequest.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ @@ -133,6 +133,7 @@ public class WRequest implements EventListener { if (e.getTarget() instanceof Menuitem) { + //open request window MQuery query = null; if (e.getTarget() == m_active) { @@ -171,6 +172,11 @@ public class WRequest implements EventListener } } + /** + * Set initial values for new request record + * @param e + * @param frame + */ private void onNew(Event e, ADWindow frame) { // New - set Table/Record if (e.getTarget() == m_new) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WZoomAcross.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WZoomAcross.java index 25909b6317..7e1fca0ee3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WZoomAcross.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WZoomAcross.java @@ -37,11 +37,10 @@ import org.zkoss.zul.Menupopup; import org.zkoss.zul.Popup; /** - * Application Zoom Across Launcher. - * Called from APanel; Queries available Zoom Targets for Table. + * Handle Zoom Across button action. * - * @author Jorg Janke - * @version $Id: AZoomAcross.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ + * @author Jorg Janke + * @version $Id: AZoomAcross.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ * * @author Teo Sarca, SC ARHIPAC SERVICE SRL - FR [ 1762465 ] * @@ -64,6 +63,12 @@ public class WZoomAcross } + /** + * show zoom across popup menu + * @param invoker + * @param po + * @param windowID + */ public WZoomAcross(Component invoker, PO po, final int windowID) { if (log.isLoggable(Level.CONFIG)) log.config("PO=" + po+", WindowID="+windowID); @@ -104,12 +109,18 @@ public class WZoomAcross m_popup.open(invoker, "after_start"); } - private Menupopup m_popup = new Menupopup(); //"ZoomMenu" + /** popup menu for zoom across targets **/ + private Menupopup m_popup = new Menupopup(); private static final CLogger log = CLogger.getCLogger(WZoomAcross.class); private final List zoomInfos = new ArrayList(); + /** + * find zoom across targets + * @param po + * @param windowID + */ private void mkZoomTargets(final PO po, final int windowID) { for (final ZoomInfoFactory.ZoomInfo zoomInfo : ZoomInfoFactory.retrieveZoomInfos(po, @@ -125,18 +136,18 @@ public class WZoomAcross } /** - * Launch Zoom - * @param pp KeyPair + * Zoom to destination window + * @param zoomInfo */ private void launchZoom (final ZoomInfoFactory.ZoomInfo zoomInfo) { final int AD_Window_ID = zoomInfo.windowId; final MQuery query = zoomInfo.query; - log.info("AD_Window_ID=" + AD_Window_ID - + " - " + query); + if (log.isLoggable(Level.INFO)) + log.info("AD_Window_ID=" + AD_Window_ID + " - " + query); AEnv.zoom(AD_Window_ID, query); } // launchZoom -} // AZoom +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java index b4f64e0b57..3c8bc47e50 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java @@ -18,8 +18,9 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; /** + * {@link BundleActivator} for web UI + * Start {@link WindowValidatorManager} * @author hengsin - * */ public class WebUIActivator implements BundleActivator { @@ -44,6 +45,10 @@ public class WebUIActivator implements BundleActivator { WindowValidatorManager.getInstance().stop(context); } + /** + * + * @return {@link BundleContext} + */ public static BundleContext getBundleContext() { return bundleContext; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java index 23b7c8ec90..e7212091b7 100755 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java @@ -104,11 +104,10 @@ import org.zkoss.zul.Space; * @author Elaine Tan * @author Low Heng Sin */ - public class WAcctViewer extends Window implements EventListener { /** - * + * generated serial id */ private static final long serialVersionUID = 3440375640756094077L; @@ -207,7 +206,6 @@ public class WAcctViewer extends Window implements EventListener /** * Default constructor */ - public WAcctViewer() { this (0, 0, 0); @@ -220,14 +218,13 @@ public class WAcctViewer extends Window implements EventListener * @param AD_Table_ID Table * @param Record_ID Record */ - public WAcctViewer(int AD_Client_ID, int AD_Table_ID, int Record_ID) { super (); - log.info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID); + if (log.isLoggable(Level.INFO)) + log.info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID); - //setDefaultCloseOperation(DISPOSE_ON_CLOSE); m_windowNo = SessionManager.getAppDesktop().registerWindow(this); m_data = new WAcctViewerData (Env.getCtx(), m_windowNo, AD_Client_ID, AD_Table_ID); @@ -242,9 +239,8 @@ public class WAcctViewer extends Window implements EventListener catch(Exception e) { log.log(Level.SEVERE, "", e); - //dispose(); } - } // AcctViewer + } /** * Static Init. @@ -257,7 +253,6 @@ public class WAcctViewer extends Window implements EventListener * * @throws Exception */ - private void init() throws Exception { // Selection Panel @@ -450,8 +445,6 @@ public class WAcctViewer extends Window implements EventListener ZKUpdateUtil.setHflex(sortBy4, "1"); row.appendChild(group4); - //"images/InfoAccount16.png" - Groupbox groupDisplay = new Groupbox(); Caption capDisplay = new Caption(Msg.getMsg(Env.getCtx(), "Display")); groupDisplay.appendChild(capDisplay); @@ -549,11 +542,8 @@ public class WAcctViewer extends Window implements EventListener resultPanel.appendChild(resultCenter); ZKUpdateUtil.setHflex(table, "1"); ZKUpdateUtil.setVflex(table, true); - //ZKUpdateUtil.setHeight(table, "99%"); - //table.setStyle("position: absolute;"); resultCenter.appendChild(table); ZKUpdateUtil.setHflex(table, "1"); - //ZKUpdateUtil.setVflex(table, "1"); table.addEventListener(Events.ON_DOUBLE_CLICK, this); if (ClientInfo.isMobile()) table.setSizedByContent(true); @@ -599,7 +589,7 @@ public class WAcctViewer extends Window implements EventListener layout.setParent(this); ZKUpdateUtil.setHeight(layout, "100%"); ZKUpdateUtil.setWidth(layout, "100%"); - layout.setStyle("background-color: transparent; margin: 0; position: absolute; padding: 0;"); + layout.setStyle("background-color: transparent; margin: 0; position: relative; padding: 0;"); Center center = new Center(); center.setParent(layout); @@ -618,7 +608,7 @@ public class WAcctViewer extends Window implements EventListener this.setTitle(Msg.getMsg(Env.getCtx(), TITLE)); this.setClosable(true); - this.setStyle("position: absolute; width: 100%; height: 100%;"); + this.setStyle("position: relative; width: 100%; height: 100%;"); this.setSizable(true); this.setMaximizable(true); } @@ -629,7 +619,6 @@ public class WAcctViewer extends Window implements EventListener * @param AD_Table_ID table * @param Record_ID record */ - private void dynInit (int AD_Table_ID, int Record_ID) { m_data.validateAcctSchemas(Record_ID); @@ -702,6 +691,12 @@ public class WAcctViewer extends Window implements EventListener stateChanged(); } // dynInit + /** + * set selected table and record id + * @param AD_Table_ID + * @param Record_ID + * @return true if AD_Table_ID is found, false otherwise + */ private boolean setSelectedTable(int AD_Table_ID, int Record_ID) { int cnt = selTable.getItemCount(); @@ -727,9 +722,8 @@ public class WAcctViewer extends Window implements EventListener } /** - * Dispose + * Dispose window */ - public void dispose() { m_data.dispose(); @@ -738,11 +732,10 @@ public class WAcctViewer extends Window implements EventListener } // dispose; /************************************************************************** - * Tab Changed + * After Tab Selection Changed */ public void stateChanged() { - // log.info( "AcctViewer.stateChanged"); boolean visible = m_data.documentQuery && tabResult.isSelected(); bRePost.setVisible(visible); @@ -756,11 +749,8 @@ public class WAcctViewer extends Window implements EventListener * Event Performed (Event Listener) * @param e Event */ - public void onEvent(Event e) throws Exception { - // log.info(e.getActionCommand()); - Object source = e.getTarget(); if (source == tabResult) @@ -802,6 +792,10 @@ public class WAcctViewer extends Window implements EventListener } } // onEvent + /** + * export to excel + * show excel viewer if available + */ private void actionExport() { if (m_rmodel != null && m_rmodel.getRowCount() > 0) { RModelExcelExporter exporter = new RModelExcelExporter(m_rmodel); @@ -835,9 +829,8 @@ public class WAcctViewer extends Window implements EventListener } /** - * New Acct Schema + * Handle Acct Schema selection */ - private void actionAcctSchema() { Listitem listitem = selAcctSchema.getSelectedItem(); @@ -853,7 +846,8 @@ public class WAcctViewer extends Window implements EventListener m_data.C_AcctSchema_ID = kp.getKey(); m_data.ASchema = MAcctSchema.get(Env.getCtx(), m_data.C_AcctSchema_ID); - log.info(m_data.ASchema.toString()); + if (log.isLoggable(Level.INFO)) + log.info(m_data.ASchema.toString()); // Sort Options @@ -916,7 +910,6 @@ public class WAcctViewer extends Window implements EventListener * Add to Sort * @param vn name pair */ - private void sortAddItem(ValueNamePair vn) { sortBy1.appendItem(vn.getName(), vn); @@ -926,9 +919,9 @@ public class WAcctViewer extends Window implements EventListener } // sortAddItem /** - * Query + * Query. + * Delegate to {@link WAcctViewerData#query()} */ - private void actionQuery() { // Parameter Info @@ -1171,7 +1164,6 @@ public class WAcctViewer extends Window implements EventListener /** * Document selection */ - private void actionDocument() { boolean doc = selDocument.isChecked(); @@ -1193,9 +1185,8 @@ public class WAcctViewer extends Window implements EventListener } // actionDocument /** - * Save Table selection (reset Record selection) + * Handle Table selection (reset Record selection) */ - private void actionTable() { Listitem listitem = selTable.getSelectedItem(); @@ -1217,17 +1208,15 @@ public class WAcctViewer extends Window implements EventListener } // actionTable /** - * Action Button + * Handle Info Button action + * Show info window * * @param button pressed button - * @return ID - * @throws Exception + * @throws Exception */ - private void actionButton(final Button button) throws Exception { final String keyColumn = button.getName(); - log.info(keyColumn); String whereClause = "(IsSummary='N' OR IsSummary IS NULL)"; String lookupColumn = keyColumn; @@ -1321,14 +1310,12 @@ public class WAcctViewer extends Window implements EventListener } }); - AEnv.showWindow(info); - + AEnv.showWindow(info); } // actionButton /** * RePost Record */ - private void actionRePost() { if (m_data.documentQuery @@ -1362,7 +1349,9 @@ public class WAcctViewer extends Window implements EventListener } } // actionRePost - // Elaine 2009/07/29 + /** + * zoom to table id + record id + */ private void actionZoom() { int selected = table.getSelectedIndex(); @@ -1380,8 +1369,10 @@ public class WAcctViewer extends Window implements EventListener AEnv.zoom(AD_Table_ID, Record_ID); } } - // - + + /** + * zoom to fact acct window (double click action) + */ private void actionZoomFactAcct() { int selected = table.getSelectedIndex(); if(selected == -1) return; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewerData.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewerData.java index f51e2a079b..2345e339b7 100755 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewerData.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewerData.java @@ -41,6 +41,7 @@ import org.compiere.model.MFactAcct; import org.compiere.model.MJournal; import org.compiere.model.MLookupFactory; import org.compiere.model.MRefList; +import org.compiere.model.SystemIDs; import org.compiere.report.core.RColumn; import org.compiere.report.core.RModel; import org.compiere.util.CLogger; @@ -53,8 +54,7 @@ import org.compiere.util.Msg; import org.compiere.util.ValueNamePair; /** - * Account Viewer State - maintains State information for the Account Viewer - * Based on class AcctViewerData + * State and data access helper for {@link WAcctViewer} * * @author Niraj Sohun * July 27, 2007 @@ -68,68 +68,70 @@ public class WAcctViewerData /** Client */ public int AD_Client_ID; - /** All Acct Schema */ + /** All Accounting Schemas for client */ public MAcctSchema[] ASchemas = null; - /** This Acct Schema */ + /** Selected Accounting Schema */ public MAcctSchema ASchema = null; // Selection Info - /** Document Query */ + /** Document Query - query with {@link #AD_Table_ID} and {@link #Record_ID} */ public boolean documentQuery = false; - /** Acct Schema */ + /** Selected Accounting Schema ID */ public int C_AcctSchema_ID = 0; - /** Posting Type */ + /** Selected Posting Type */ public String PostingType = ""; - /** Organization */ + /** Selected Organization ID */ public int AD_Org_ID = 0; - /** Date From */ + /** Date From, for DateAcct filter */ public Timestamp DateFrom = null; - /** Date To */ + /** Date To, for DateAcct filter */ public Timestamp DateTo = null; // Document Table Selection Info - /** Table ID */ + /** Selected Table ID for {@link #documentQuery} */ public int AD_Table_ID; - /** Record */ + /** Selected Record ID for {@link #documentQuery} */ public int Record_ID; - /** Containing Column and Query */ + /** ColumnName:Filter */ public HashMap whereInfo = new HashMap(); - /** Containing TableName and AD_Table_ID */ + /** TableName:AD_Table_ID */ public HashMap tableInfo = new HashMap(); // Display Info - /** Display Qty */ - boolean displayQty = false; + /** Display Qty Columns */ + protected boolean displayQty = false; - /** Display Source Surrency */ - boolean displaySourceAmt = false; + /** Display Source Amount Columns */ + protected boolean displaySourceAmt = false; /** Display Document info */ - boolean displayDocumentInfo = false; + protected boolean displayDocumentInfo = false; - String sortBy1 = ""; - String sortBy2 = ""; - String sortBy3 = ""; - String sortBy4 = ""; + //order by + protected String sortBy1 = ""; + protected String sortBy2 = ""; + protected String sortBy3 = ""; + protected String sortBy4 = ""; - boolean group1 = false; - boolean group2 = false; - boolean group3 = false; - boolean group4 = false; + //group by + protected boolean group1 = false; + protected boolean group2 = false; + protected boolean group3 = false; + protected boolean group4 = false; - /** Leasing Columns */ + /** Leading Columns. Number of columns shown before Accounted and Source Amount Columns. */ private int m_leadingColumns = 0; /** UserElement1 Reference */ @@ -148,7 +150,6 @@ public class WAcctViewerData * @param ad_Client_ID client * @param ad_Table_ID table */ - public WAcctViewerData (Properties ctx, int windowNo, int ad_Client_ID, int ad_Table_ID) { WindowNo = windowNo; @@ -168,8 +169,7 @@ public class WAcctViewerData /** * Dispose - */ - + */ public void dispose() { ASchemas = null; @@ -182,8 +182,8 @@ public class WAcctViewerData } // dispose /** - * GL Journal only posts in one Accounting Schema - * if the record is a GL Journal, remove the others from the array + * GL Journal only posts in one Accounting Schema. + * If the record is a GL Journal, remove the other accounting schema from {@link #ASchemas} * @param Record_ID */ protected void validateAcctSchemas(int Record_ID) @@ -191,7 +191,7 @@ public class WAcctViewerData if (Record_ID > 0 && AD_Table_ID == MJournal.Table_ID) { MJournal journal = new MJournal(Env.getCtx(), Record_ID, null); - if (journal != null) { + if (journal.getGL_Journal_ID() == Record_ID) { ASchemas = new MAcctSchema[1]; ASchemas[0] = MAcctSchema.get(Env.getCtx(), journal.getC_AcctSchema_ID()); ASchema = ASchemas[0]; @@ -199,11 +199,10 @@ public class WAcctViewerData } } // validateAcctSchemas - /************************************************************************** + /** * Fill Accounting Schema * @param cb Listbox to be filled - */ - + */ protected void fillAcctSchema (Listbox cb) { for (int i = 0; i < ASchemas.length; i++) @@ -214,10 +213,9 @@ public class WAcctViewerData } // fillAcctSchema /** - * Fill Posting Type - * @param cb Listox to be filled - */ - + * Fill Posting Type from {@link SystemIDs#REFERENCE_POSTING_TYPE} list. + * @param cb Listbox to be filled + */ protected void fillPostingType (Listbox cb) { int AD_Reference_ID = REFERENCE_POSTING_TYPE; @@ -230,18 +228,15 @@ public class WAcctViewerData } // fillPostingType /** - * Fill Table with + * Fill Listbox with * ValueNamePair (TableName, translatedKeyColumnName) - * and tableInfo with (TableName, AD_Table_ID) + * and {@link #tableInfo} with (TableName, AD_Table_ID) * and select the entry for AD_Table_ID * * @param cb Listbox to be filled - */ - + */ protected void fillTable (Listbox cb) { - ValueNamePair select = null; - String sql = "SELECT AD_Table_ID, TableName FROM AD_Table t " + "WHERE EXISTS (SELECT * FROM AD_Column c" + " WHERE t.AD_Table_ID=c.AD_Table_ID AND c.ColumnName='Posted')" @@ -261,10 +256,7 @@ public class WAcctViewerData ValueNamePair pp = new ValueNamePair(tableName, name); cb.appendItem(pp.getName(),pp); - tableInfo.put (tableName, Integer.valueOf(id)); - - if (id == AD_Table_ID) - select = pp; + tableInfo.put (tableName, Integer.valueOf(id)); } } catch (SQLException e) @@ -276,18 +268,14 @@ public class WAcctViewerData DB.close(rs, pstmt); rs = null; pstmt = null; - } - - if (select != null) - ;//cb.setSelectedItem(select); + } } // fillTable /** * Fill Org * * @param cb Listbox to be filled - */ - + */ protected void fillOrg (Listbox cb) { KeyNamePair pp = new KeyNamePair(0, ""); @@ -320,7 +308,7 @@ public class WAcctViewerData } // fillOrg /** - * Get Button Text + * Get Info Button Text * * @param tableName table * @param columnName column @@ -362,10 +350,9 @@ public class WAcctViewerData return retValue; } // getButtonText - /************************************************************************** /** - * Create Query and submit - * @return Report Model + * Create query and execute + * @return {@link RModel} query result */ protected RModel query() @@ -502,10 +489,9 @@ public class WAcctViewerData } // query /** - * Create Report Model (Columns) - * @return Report Model - */ - + * Create new Report Model (Setup Columns) instance + * @return {@link RModel} + */ private RModel getRModel() { Properties ctx = Env.getCtx(); @@ -596,10 +582,9 @@ public class WAcctViewerData } // createRModel /** - * Create the key columns in sequence + * Create the list of key/mandatory columns to display in viewer * @return List of Key Columns */ - private ArrayList createKeyColumns() { ArrayList columns = new ArrayList(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java index f0da9f5834..48114dffab 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java @@ -25,7 +25,7 @@ import org.compiere.util.CCache; import org.zkoss.image.AImage; /** - * + * Static methods to get {@link IAction} osgi service instance. * @author hengsin * */ @@ -58,7 +58,10 @@ public class Actions { } /** - * + * Image name: actionId+"24.png". + * Get image from current theme or plugin resource. + * For plugin resource, it will try the path /action/images/{theme}/{image name}, /action/images/default/{image name} and + * /action/images/{image name} * @param actionId * @return {@link AImage} */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/IAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/IAction.java index b6132d8007..9ff12b6755 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/IAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/IAction.java @@ -22,7 +22,7 @@ import org.zkoss.zul.Toolbarbutton; */ public interface IAction { /** - * + * execute action * @param target */ public void execute(Object target); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java index 88d28a790f..773204781c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java @@ -78,10 +78,13 @@ import org.zkoss.zul.event.ListDataEvent; public class ADSortTab extends Panel implements IADTabpanel { /** - * + * generated serial id */ private static final long serialVersionUID = 4302282658814599752L; + /** + * default constructor + */ public ADSortTab() { } @@ -133,7 +136,7 @@ public class ADSortTab extends Panel implements IADTabpanel private Button bUp = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveUp16.png"), null); private Button bDown = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveDown16.png"), null); // - SimpleListModel noModel = new SimpleListModel() { + protected SimpleListModel noModel = new SimpleListModel() { /** * */ @@ -153,12 +156,13 @@ public class ADSortTab extends Panel implements IADTabpanel fireEvent(ListDataEvent.INTERVAL_ADDED, index, index); } }; - SimpleListModel yesModel = new SimpleListModel(); - Listbox noList = new Listbox(); - Listbox yesList = new Listbox(); + protected SimpleListModel yesModel = new SimpleListModel(); + protected Listbox noList = new Listbox(); + protected Listbox yesList = new Listbox(); private GridTab gridTab; private boolean uiCreated; + /** true if tab have been activated **/ private boolean active = false; private boolean isChanged; private boolean detailPaneMode; @@ -277,7 +281,8 @@ public class ADSortTab extends Panel implements IADTabpanel m_IdentifierSql = identifierSql.toString(); // noLabel.setValue(Msg.getMsg(Env.getCtx(), "Available")); - log.fine(m_ColumnSortName); + if (log.isLoggable(Level.FINE)) + log.fine(m_ColumnSortName); } // dynInit /** @@ -520,14 +525,19 @@ public class ADSortTab extends Panel implements IADTabpanel } } + /** + * @return true if tab has changes + */ public boolean isChanged() { return isChanged; } /** + * Move an item between yes and no list. + * Delegate to {@link #migrateLists(Listbox, Listbox, int)} * @param event */ - void migrateValueAcrossLists (Event event) + protected void migrateValueAcrossLists (Event event) { Object source = event.getTarget(); if (source instanceof ListItem) { @@ -544,7 +554,13 @@ public class ADSortTab extends Panel implements IADTabpanel migrateLists (listFrom,listTo,endIndex); } // migrateValueAcrossLists - void migrateLists (Listbox listFrom , Listbox listTo , int endIndex) + /** + * Move an item from listFrom to listTo. + * @param listFrom + * @param listTo + * @param endIndex destination index + */ + protected void migrateLists (Listbox listFrom , Listbox listTo , int endIndex) { int index = 0; SimpleListModel lmFrom = (listFrom == yesList) ? yesModel:noModel; @@ -577,10 +593,10 @@ public class ADSortTab extends Panel implements IADTabpanel } /** - * Move within Yes List + * Move an item within Yes List * @param event event */ - void migrateValueWithinYesList (Event event) + protected void migrateValueWithinYesList (Event event) { Object[] selObjects = yesList.getSelectedItems().toArray(); if (selObjects == null) @@ -643,10 +659,10 @@ public class ADSortTab extends Panel implements IADTabpanel /** - * Move within Yes List with Drag Event and Multiple Choice + * Move items within Yes List with Drag Event and Multiple Choice * @param event event */ - void migrateValueWithinYesList (int endIndex, List selObjects) + protected void migrateValueWithinYesList (int endIndex, List selObjects) { int iniIndex =0; Arrays.sort(selObjects.toArray()); @@ -667,8 +683,9 @@ public class ADSortTab extends Panel implements IADTabpanel setIsChanged(true); } - /* (non-Javadoc) - * @see org.compiere.grid.APanelTab#registerAPanel(APanel) + /** + * Set AD Window content part that own this ADSortTab instance. + * @param panel */ public void registerAPanel (AbstractADWindowContent panel) { @@ -676,14 +693,15 @@ public class ADSortTab extends Panel implements IADTabpanel } // registerAPanel - /** (non-Javadoc) + /** + * Save changes to db. */ public void saveData() { if (!adWindowPanel.getToolbar().isSaveEnable()) return; - log.fine(""); boolean ok = true; + //TODO: should use model instead to enable change log and event handling StringBuilder info = new StringBuilder(); StringBuffer sql = null; // noList - Set SortColumn to null and optional YesNo Column to 'N' @@ -851,6 +869,7 @@ public class ADSortTab extends Panel implements IADTabpanel { } + @Override public void onEvent(Event event) throws Exception { if (event instanceof DropEvent) { @@ -884,6 +903,7 @@ public class ADSortTab extends Panel implements IADTabpanel } } + @Override public void activate(boolean b) { if (b) { if (getAttribute(ATTR_ON_ACTIVATE_POSTED) != null) { @@ -899,6 +919,7 @@ public class ADSortTab extends Panel implements IADTabpanel Events.postEvent(event); } + @Override public void createUI() { if (uiCreated) return; try @@ -913,64 +934,80 @@ public class ADSortTab extends Panel implements IADTabpanel uiCreated = true; } + @Override public void dynamicDisplay(int i) { } + @Deprecated(forRemoval = true, since = "11") public void editRecord(boolean b) { } + @Override public String getDisplayLogic() { return gridTab.getDisplayLogic(); } + @Override public GridTab getGridTab() { return gridTab; } + @Override public int getTabLevel() { return gridTab.getTabLevel(); } + @Override public String getTableName() { return gridTab.getTableName(); } + @Override public int getRecord_ID() { return gridTab.getRecord_ID(); } + @Override public String getTitle() { return gridTab.getName(); } + @Override public boolean isCurrent() { return gridTab != null ? gridTab.isCurrent() : false; } + @Override public void query() { loadData(); } + @Override public void query(boolean currentRows, int currentDays, int i) { loadData(); } + @Override public void refresh() { createUI(); loadData(); } + @Override public void switchRowPresentation() { } + @Override public String get_ValueAsString(String variableName) { return Env.getContext(Env.getCtx(), m_WindowNo, variableName); } + @Override public void afterSave(boolean onSaveEvent) { } + @Override public boolean onEnterKey() { return false; } @@ -991,6 +1028,7 @@ public class ADSortTab extends Panel implements IADTabpanel ZKUpdateUtil.setVflex(this, "true"); } + @Override public boolean isDetailPaneMode() { return this.detailPaneMode; } @@ -1053,6 +1091,7 @@ public class ADSortTab extends Panel implements IADTabpanel noList.setModel(noModel); } + @Override public ADTreePanel getTreePanel() { return null; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java index baa207ec3b..f721052ff7 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java @@ -127,6 +127,7 @@ import org.zkoss.zul.West; import org.zkoss.zul.impl.XulElement; /** + * UI for an AD_Tab content (AD_Tab + AD_Fields). * * This class is based on org.compiere.grid.GridController written by Jorg Janke. * Changes have been brought for UI compatibility. @@ -142,6 +143,7 @@ import org.zkoss.zul.impl.XulElement; public class ADTabpanel extends Div implements Evaluatee, EventListener, DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer { + //css for slide animation private static final String SLIDE_LEFT_IN_CSS = "slide-left-in"; private static final String SLIDE_LEFT_OUT_CSS = "slide-left-out"; @@ -151,19 +153,26 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer private static final String SLIDE_RIGHT_OUT_CSS = "slide-right-out"; /** - * + * generated serial id */ private static final long serialVersionUID = -5335610241895151024L; + /** event to save open/close state of detail pane as user preference for ad window **/ private static final String ON_SAVE_OPEN_PREFERENCE_EVENT = "onSaveOpenPreference"; + /** post init event for tab panel **/ public static final String ON_POST_INIT_EVENT = "onPostInit"; + /** event after tab panel had switch presentation between form and list view **/ public static final String ON_SWITCH_VIEW_EVENT = "onSwitchView"; + /** Event after execution of {@link #dynamicDisplay(int)} **/ public static final String ON_DYNAMIC_DISPLAY_EVENT = "onDynamicDisplay"; + + /** defer event to set selected tree node **/ private static final String ON_DEFER_SET_SELECTED_NODE = "onDeferSetSelectedNode"; + /** ADTabpanel attribute to prevent ON_DEFER_SET_SELECTED_NODE event posted twice within 1 execution **/ private static final String ON_DEFER_SET_SELECTED_NODE_ATTR = "onDeferSetSelectedNode.Event.Posted"; private static final CLogger logger; @@ -177,68 +186,95 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer private GridWindow gridWindow; + /** AD Window content part that own this ADTabpanel instance **/ private AbstractADWindowContent windowPanel; private int windowNo; + /** form view for center of {@link #formContainer} **/ private Grid form; + /** field editors **/ private ArrayList editors = new ArrayList(); + /** components for field editors **/ private ArrayList editorComps = new ArrayList(); + /** editor toolbar buttons**/ private ArrayList toolbarButtonEditors = new ArrayList(); + /** toolbar buttons for AD_ToolBarButton **/ private ArrayList toolbarProcessButtons = new ArrayList(); + /** true if UI have been created for form and list **/ private boolean uiCreated = false; + /** list view for center of {@link #formContainer} **/ private GridView listPanel; + /** content rows for group **/ private Map> fieldGroupContents; + /** header row for group **/ private Map> fieldGroupHeaders; + /** tabs for group (for tab type field group) **/ private Map> fieldGroupTabHeaders; + /** all rows for current group (regardless of field group type) **/ private ArrayList rowList; + /** all collapsible groups **/ protected List allCollapsibleGroups; + /** main layout for header (center), tree (west) and detail pane (south) **/ private Borderlayout formContainer = null; + /** Tree panel for west of {@link #formContainer} **/ private ADTreePanel treePanel = null; + /** Sync field editor changes to GridField **/ private GridTabDataBinder dataBinder; + /** true if tab have been activated **/ protected boolean activated = false; + /** + * current group for collapsible type field group + */ private Group currentGroup; + /** Panel for child tabs, south of {@link #formContainer} **/ private DetailPane detailPane; + /** true if this ADTabpanel instance is own by detail pane **/ private boolean detailPaneMode; + /** tab no within an AD Window (sequence start from 0) **/ private int tabNo; - /** DefaultFocusField */ + /** Default focus field */ private WEditor defaultFocusField = null; + /** number of columns for {@link #form} **/ private int numberOfFormColumns; + /** event to toggle between form and list view **/ public static final String ON_TOGGLE_EVENT = "onToggle"; + /** default width for west tree panel **/ private static final String DEFAULT_PANEL_WIDTH = "300px"; private static CCache quickFormCache = new CCache(null, "QuickForm", 20, false); - /** Tab Box for Tab Field Groups */ + /** Tab Box for Tab Type Field Groups */ private Tabbox tabbox = new Tabbox(); - /** List of Tab Group Grids */ - private List tabForms; - /** Current Tab Group Rows */ - private Rows currentTabRows; + /** List of Grid/Form for tab type field group */ + private List tabGroupForms; + /** Current Rows for tab type field group */ + private Rows currentTabGroupRows; + /** Event for south of {@link #formContainer} **/ private static enum SouthEvent { SLIDE(), OPEN(), @@ -247,11 +283,17 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer private SouthEvent() {} } + /** + * default constructor + */ public ADTabpanel() { init(); } + /** + * init components and event listeners + */ private void init() { initComponents(); @@ -270,6 +312,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer ClientInfo.onClientInfo(this, this::onClientInfo); } + /** + * Create new {@link #form} and {@link #listPanel} instance. + */ private void initComponents() { LayoutUtils.addSclass("adtab-content", this); @@ -282,6 +327,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer form.setVflex(false); form.setSclass("grid-layout adwindow-form"); form.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "form"); + //swipe listener for mobile if (ClientInfo.isMobile()) { form.addEventListener("onSwipeRight", e -> { @@ -313,6 +359,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer listPanel.getListbox().addEventListener(Events.ON_DOUBLE_CLICK, this); } + /** + * Setup client side form swipe listener for mobile. + * Send onSwipeRight and onSwipeLeft event to server. + */ private void setupFormSwipeListener() { String uuid = form.getUuid(); StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('") @@ -344,7 +394,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer public void setDetailPane(DetailPane component) { detailPane = component; - Borderlayout borderLayout = (Borderlayout) formContainer; + Borderlayout borderLayout = formContainer; South south = borderLayout.getSouth(); if (south == null) { south = new South(); @@ -375,7 +425,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer ZKUpdateUtil.setHeight(formContainer.getSouth(), height); } } catch (Exception e) { - // just ignore exception is harmless here, consequence is just not setting height so it will assume the default of theme + // just ignore, exception is harmless here, consequence is just not setting height so it will assume the default of theme } } } @@ -386,7 +436,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * + * init tab panel layout ({@link #formContainer} and listeners * @param winPanel * @param gridTab */ @@ -487,7 +537,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * Create UI components if not already created + * Create UI for AD_Fields */ @Override public void createUI() @@ -496,7 +546,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * + * Create UI for AD_Fields * @param update true if it is update instead of create new */ protected void createUI(boolean update) @@ -515,7 +565,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer fieldGroupHeaders = new HashMap>(); allCollapsibleGroups = new ArrayList(); - tabForms = new ArrayList(); + tabGroupForms = new ArrayList(); fieldGroupTabHeaders = new HashMap>(); int numCols=gridTab.getNumColumns(); @@ -610,8 +660,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer if (numCols - actualxpos + 1 > 0) row.appendCellChild(createSpacer(), numCols - actualxpos + 1); - if(currentTabRows != null) { - currentTabRows.appendChild(row); + if (currentTabGroupRows != null) { + currentTabGroupRows.appendChild(row); } else { row.setGroup(currentGroup); rows.appendChild(row); @@ -641,7 +691,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer rows.appendChild(row); headerRows.add(row); currentGroup = null; - currentTabRows = null; + currentTabGroupRows = null; } else if(X_AD_FieldGroup.FIELDGROUPTYPE_Tab.equals(field.getFieldGroupType())) { // Create New Tab for FieldGroup List headerTabs = new ArrayList(); @@ -658,7 +708,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer headerTabs.add(tab); Grid tabForm = new Grid(); - tabForms.add(tabForm); + tabGroupForms.add(tabForm); ZKUpdateUtil.setHflex(tabForm, "1"); ZKUpdateUtil.setHeight(tabForm, null); tabForm.setVflex(false); @@ -696,7 +746,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer tp.appendChild(tabForm); currentGroup = null; - currentTabRows = tabRows; + currentTabGroupRows = tabRows; } else { @@ -710,7 +760,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer { rowg.setOpen(false); } - currentTabRows = null; + currentTabGroupRows = null; currentGroup = rowg; rows.appendChild(rowg); headerRows.add(rowg); @@ -738,8 +788,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer if (numCols - actualxpos + 1 > 0) row.appendCellChild(createSpacer(), numCols - actualxpos + 1); // Tab Group vs Grid Group - if(currentTabRows != null) { - currentTabRows.appendChild(row); + if (currentTabGroupRows != null) { + currentTabGroupRows.appendChild(row); } else { row.setGroup(currentGroup); rows.appendChild(row); @@ -899,8 +949,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer if (numCols - actualxpos + 1 > 0) row.appendCellChild(createSpacer(), numCols - actualxpos + 1); // Tab Group vs Grid Group - if(currentTabRows != null) { - currentTabRows.appendChild(row); + if (currentTabGroupRows != null) { + currentTabGroupRows.appendChild(row); } else { row.setGroup(currentGroup); rows.appendChild(row); @@ -936,6 +986,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer switchRowPresentation(); } + /** + * @param field + * @return {@link WEditor} or null if not found + */ private WEditor findEditor(GridField field) { for(WEditor editor : editors) { if (editor.getGridField() == field) @@ -944,6 +998,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer return null; } + /** + * load toolbar buttons from AD_ToolBarButton + */ private void loadToolbarButtons() { //get extra toolbar process buttons MToolBarButton[] mToolbarButtons = MToolBarButton.getProcessButtonOfTab(gridTab.getAD_Tab_ID(), null); @@ -976,7 +1033,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * Validate display properties of fields of current row. + * Update state of fields (visibility, style, writable, etc) * @param col */ @Override @@ -987,6 +1044,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer return; } + //css animation for slide if (form.getSclass() != null && form.getSclass().contains(SLIDE_RIGHT_OUT_CSS)) { Executions.schedule(getDesktop(), e -> { LayoutUtils.removeSclass(SLIDE_RIGHT_OUT_CSS, form); @@ -1104,7 +1162,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } //hide row if all editor within the row is invisible in Tabbox grid - for(Grid tabForm: tabForms) { + for(Grid tabForm: tabGroupForms) { List tabrows = tabForm.getRows().getChildren(); for (Component comp : tabrows) { @@ -1217,6 +1275,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer LayoutUtils.removeSclass(SLIDE_RIGHT_IN_CSS, form); } + /** + * echo set selected node event for tree + */ private void echoDeferSetSelectedNodeEvent() { if (getAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR) == null) { setAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR, Boolean.TRUE); @@ -1225,7 +1286,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return String + * @return display logic */ @Override public String getDisplayLogic() @@ -1234,7 +1295,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return String + * @return title of tab */ @Override public String getTitle() @@ -1244,6 +1305,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer /** * @param variableName + * @return value */ @Override public String get_ValueAsString(String variableName) @@ -1270,7 +1332,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return The record ID of this Tabpanel + * @return The record ID of current row */ @Override public int getRecord_ID() @@ -1280,7 +1342,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer /** * Is panel need refresh - * @return boolean + * @return true if GridTab need refresh */ @Override public boolean isCurrent() @@ -1298,7 +1360,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * Retrieve from db + * Retrieve from db. + * Delegate to {@link GridTab#query(boolean)} */ @Override public void query() @@ -1311,9 +1374,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer /** * Retrieve from db - * @param onlyCurrentRows - * @param onlyCurrentDays - * @param maxRows + * @param onlyCurrentRows True to show only unprocessed or the one updated within x days (default is 1 day before today) + * @param onlyCurrentDays if > 0, filter records with created >= current_date - onlyCurrentDays + * @param maxRows if > 0, maximum number of rows to load */ @Override public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows) @@ -1339,7 +1402,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * reset detail data grid for new parent record that's not saved yet + * Reset detail data grid for new parent record that's not saved yet. + * Delegate to {@link GridTab#resetDetailForNewParentRecord()}. */ @Override public void resetDetailForNewParentRecord () @@ -1364,7 +1428,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return TreePanel + * @return ADTreePanel */ public ADTreePanel getTreePanel() { @@ -1372,7 +1436,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return TreePanel + * @return master, detail or both */ public String getTreeDisplayedOn() { @@ -1434,7 +1498,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * + * Delegate to {@link #focusToEditor(WEditor, boolean)} * @param checkCurrent */ public void focusToFirstEditor(boolean checkCurrent) { @@ -1535,6 +1599,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * handle open/close event of south panel (detail pane) + * @param event + */ private void onSouthEvent(SouthEvent event) { if (event == SouthEvent.OPEN || event == SouthEvent.CLOSE) { boolean open = event == SouthEvent.OPEN ? true : false; @@ -1563,6 +1631,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * @return true if detail pane is open/visible + */ private boolean isOpenDetailPane() { if (isMobile()) return false; @@ -1578,6 +1649,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer return open; } + /** + * @return height of detail pane from user preference + */ private String heigthDetailPane() { String height = null; int windowId = getGridTab().getAD_Window_ID(); @@ -1588,6 +1662,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer return height; } + /** + * @return width of tree panel from user preference (or default if no user preference) + */ private String widthTreePanel() { String width = null; int windowId = getGridTab().getAD_Window_ID(); @@ -1597,6 +1674,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer return Util.isEmpty(width) ? DEFAULT_PANEL_WIDTH : width; } + /** + * Navigate to a tree node + * @param value + */ private void navigateTo(DefaultTreeNode value) { MTreeNode treeNode = value.getData(); // We Have a TreeNode @@ -1654,7 +1735,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer Dialog.error(windowNo, msg); } } - //if (col >= 0) + + //update UI state if (!uiCreated) createUI(); dynamicDisplay(col); @@ -1750,6 +1832,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer treePanel.initTree(AD_Tree_ID, windowNo); } } + + //update list view if (listPanel.isVisible()) { listPanel.updateListIndex(); listPanel.dynamicDisplay(col); @@ -1760,6 +1844,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * delete tree node by recordId + * @param recordId + */ private void deleteNode(int recordId) { if (recordId <= 0) return; @@ -1780,6 +1868,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * add new tree node for current row + */ private void addNewNode() { if (gridTab.getRecord_ID() > 0) { String name = (String)gridTab.getValue("Name"); @@ -1817,6 +1908,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * set selected tree node by recordId + * @param recordId + */ private void setSelectedNode(int recordId) { if (recordId <= 0) return; @@ -1921,15 +2016,15 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer static class ZoomListener implements EventListener { - private IZoomableEditor searchEditor; + private IZoomableEditor zoomableEditor; ZoomListener(IZoomableEditor editor) { - searchEditor = editor; + zoomableEditor = editor; } public void onEvent(Event event) throws Exception { if (Events.ON_CLICK.equals(event.getName())) { - searchEditor.actionZoom(); + zoomableEditor.actionZoom(); } } @@ -1980,7 +2075,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * @return boolean + * @return true if list/grid view is visible */ @Override public boolean isGridView() { @@ -1989,7 +2084,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer /** * - * @return GridPanel + * @return {@link GridView} */ @Override public GridView getGridView() { @@ -2015,6 +2110,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * Show detail pane + */ private void attachDetailPane() { if (formContainer.getSouth() != null) { formContainer.getSouth().setVisible(true); @@ -2029,6 +2127,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } + /** + * Hide detail pane + */ private void detachDetailPane() { if (formContainer.getSouth() != null) { formContainer.getSouth().setVisible(false); @@ -2039,8 +2140,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } /** - * Get all visible button editors - * @return List + * Get all visible toolbar button editors + * @return List