/****************************************************************************** * Product: Posterita Ajax UI * * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. 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., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * or via info@posterita.org or http://www.posterita.org/ * *****************************************************************************/ package org.adempiere.webui.apps; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.URI; import java.net.URISyntaxException; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import javax.servlet.ServletRequest; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ISupportMask; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.Window; import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.editor.WTableDirEditor; import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DrillEvent.DrillData; import org.adempiere.webui.info.InfoWindow; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.IServerPushCallback; import org.adempiere.webui.util.ServerPushTemplate; import org.adempiere.webui.window.Dialog; import org.compiere.acct.Doc; import org.compiere.model.GridWindowVO; import org.compiere.model.I_AD_Window; import org.compiere.model.Lookup; import org.compiere.model.MClient; import org.compiere.model.MLanguage; import org.compiere.model.MLookup; import org.compiere.model.MLookupFactory; import org.compiere.model.MQuery; import org.compiere.model.MReference; import org.compiere.model.MRole; import org.compiere.model.MSession; import org.compiere.model.MSysConfig; import org.compiere.model.MTable; import org.compiere.model.MZoomCondition; import org.compiere.model.PO; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.CacheMgt; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Ini; import org.compiere.util.Language; import org.compiere.util.Util; import org.zkoss.web.servlet.Servlets; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Desktop; import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Button; import org.zkoss.zul.impl.InputElement; import com.lowagie.text.DocumentException; /** * Static application environment and utilities methods. * * @author Jorg Janke * @version $Id: AEnv.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ * * Colin Rooney (croo) and kstan_79 RFE#1670185 */ public final class AEnv { /** Environment context attribute for Locale */ public static final String LOCALE = Env.LOCALE; /** * Show window in the center of screen. * @param window Window to position */ public static void showCenterScreen(Window window) { if (SessionManager.getAppDesktop() != null) SessionManager.getAppDesktop().showWindow(window, "center"); else { window.setPosition("center"); window.setPage(getDesktop().getFirstPage()); Object objMode = window.getAttribute(Window.MODE_KEY); final String mode = objMode != null ? objMode.toString() : Window.MODE_HIGHLIGHTED; if (Window.MODE_MODAL.equals(mode)) window.doModal(); else window.doHighlighted(); } } // showCenterScreen /** * Set window position ({@link org.zkoss.zul.Window#setPosition(String)}) and show it. * @param window Window to position * @param position */ public static void showScreen(Window window, String position) { SessionManager.getAppDesktop().showWindow(window, position); } // showScreen /** * Position window in center of the parent window. * @param parent Parent Window * @param window Window to position */ public static void showCenterWindow(Window parent, Window window) { parent.appendChild(window); showScreen(window, "parent,center"); } // showCenterWindow /** * Get Mnemonic character from text. * @param text text with '&' * @return Mnemonic character or 0 */ public static char getMnemonic (String text) { int pos = text.indexOf('&'); if (pos != -1) // We have a nemonic return text.charAt(pos+1); return 0; } // getMnemonic /************************************************************************* * Zoom to AD Window by AD_Table_ID and Record_ID. * @param AD_Table_ID * @param Record_ID */ public static void zoom (int AD_Table_ID, int Record_ID) { int AD_Window_ID = Env.getZoomWindowID(AD_Table_ID, Record_ID); // Nothing to Zoom to if (AD_Window_ID == 0) return; MTable table = MTable.get(Env.getCtx(), AD_Table_ID); MQuery query = MQuery.getEqualQuery(table.getKeyColumns()[0], Record_ID); query.setZoomTableName(table.getTableName()); query.setZoomColumnName(table.getKeyColumns()[0]); query.setZoomValue(Record_ID); zoom(AD_Window_ID, query); } // zoom /************************************************************************* * Zoom to AD Window by AD_Table_ID and Record_UU. * @param AD_Table_ID * @param Record_UU */ public static void zoomUU(int AD_Table_ID, String Record_UU) { int AD_Window_ID = Env.getZoomWindowUU(AD_Table_ID, Record_UU); // Nothing to Zoom to if (AD_Window_ID == 0) return; MTable table = MTable.get(Env.getCtx(), AD_Table_ID); String uuColName = PO.getUUIDColumnName(table.getTableName()); MQuery query = MQuery.getEqualQuery(uuColName, Record_UU); query.setZoomTableName(table.getTableName()); query.setZoomColumnName(uuColName); query.setZoomValue(Record_UU); zoom(AD_Window_ID, query); } // zoom /************************************************************************* * Zoom to AD Window by AD_Table_ID and Record_ID. * @param AD_Table_ID * @param Record_ID * @param query initial query for destination AD Window * @param windowNo */ public static void zoom (int AD_Table_ID, int Record_ID, MQuery query, int windowNo) { int AD_Window_ID = Env.getZoomWindowID(AD_Table_ID, Record_ID, windowNo); // Nothing to Zoom to if (AD_Window_ID == 0) return; zoom(AD_Window_ID, query); } // zoom /************************************************************************* * Zoom to AD Window by AD_Table_ID and Record_UU. * @param AD_Table_ID * @param Record_UU * @param query initial query for destination AD Window * @param windowNo */ public static void zoomUU(int AD_Table_ID, String Record_UU, MQuery query, int windowNo) { int AD_Window_ID = Env.getZoomWindowUU(AD_Table_ID, Record_UU, windowNo); // Nothing to Zoom to if (AD_Window_ID == 0) return; zoom(AD_Window_ID, query); } // zoom /** * Call {@link #zoom(int, int, MQuery, int)} * @param AD_Table_ID * @param Record_ID * @param query */ public static void zoom (int AD_Table_ID, int Record_ID, MQuery query) { zoom (AD_Table_ID, Record_ID, query, 0); } /** * Exit System. * @param status System exit status (usually 0 for no error) */ @Deprecated(forRemoval = true, since = "11") public static void exit (int status) { Env.exitEnv(status); } // exit /** * Logout AD_Session and clear {@link #windowCache}. */ public static void logout() { String sessionID = Env.getContext(Env.getCtx(), Env.AD_SESSION_ID); synchronized (windowCache) { CCache cache = windowCache.get(sessionID); if (cache != null) { cache.clear(); CacheMgt.get().unregister(cache); } } windowCache.remove(sessionID); // End Session int ad_Session_ID = Env.getContextAsInt(Env.getCtx(), Env.AD_SESSION_ID); MSession session = ad_Session_ID > 0 ? new MSession(Env.getCtx(), ad_Session_ID, null) : null; // finish if (session != null) session.logout(); Env.setContext(Env.getCtx(), Env.AD_SESSION_ID, (String)null); } /** * Open Workflow Process Window for AD_Table_ID and Record_ID * @param AD_Table_ID * @param Record_ID */ public static void startWorkflowProcess (int AD_Table_ID, int Record_ID) { if (s_workflow_Window_ID <= 0) { int AD_Window_ID = DB.getSQLValue(null, "SELECT AD_Window_ID FROM AD_Window WHERE Name = 'Workflow Process'"); s_workflow_Window_ID = AD_Window_ID; } if (s_workflow_Window_ID <= 0) return; MQuery query = new MQuery(); query.addRestriction("AD_Table_ID", MQuery.EQUAL, AD_Table_ID); query.addRestriction("Record_ID", MQuery.EQUAL, Record_ID); AEnv.zoom(s_workflow_Window_ID, query); } // startWorkflowProcess /** Cache Workflow Window ID */ private static int s_workflow_Window_ID = 0; /** Logger */ private static final CLogger log = CLogger.getCLogger(AEnv.class); /** Register AD Window Cache */ private static Map> windowCache = new HashMap>(); /** * Get VO for AD_Window * * @param WindowNo Window No * @param AD_Window_ID window * @param AD_Menu_ID menu * @return {@link GridWindowVO} instance for AD_Window_ID */ public static GridWindowVO getMWindowVO (int WindowNo, int AD_Window_ID, int AD_Menu_ID) { if (log.isLoggable(Level.CONFIG)) log.config("Window=" + WindowNo + ", AD_Window_ID=" + AD_Window_ID); GridWindowVO mWindowVO = null; String sessionID = Env.getContext(Env.getCtx(), Env.AD_SESSION_ID); if (AD_Window_ID != 0 && Ini.isCacheWindow()) // try cache { synchronized (windowCache) { CCache cache = windowCache.get(sessionID); if (cache != null) { mWindowVO = cache.get(AD_Window_ID); if (mWindowVO != null) { mWindowVO = mWindowVO.clone(WindowNo); if (log.isLoggable(Level.INFO)) log.info("Cached=" + mWindowVO); } } } } // Create Window Model on Client if (mWindowVO == null) { if (log.isLoggable(Level.CONFIG)) log.config("create local"); mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID, AD_Menu_ID); if (mWindowVO != null && Ini.isCacheWindow()) { synchronized (windowCache) { CCache cache = windowCache.get(sessionID); if (cache == null) { cache = new CCache(I_AD_Window.Table_Name, I_AD_Window.Table_Name+"|GridWindowVO|Session|"+sessionID, 10); windowCache.put(sessionID, cache); } cache.put(AD_Window_ID, mWindowVO); } } } // from Client if (mWindowVO == null) return null; // Check context (Just in case, usually both is ServerContextPropertiesWrapper) if (!mWindowVO.ctx.equals(Env.getCtx())) { // Add Window properties to context Enumeration keyEnum = mWindowVO.ctx.keys(); while (keyEnum.hasMoreElements()) { String key = (String)keyEnum.nextElement(); if (key.startsWith(WindowNo+"|")) { String value = mWindowVO.ctx.getProperty (key); Env.setContext(Env.getCtx(), key, value); } } // Sync Context mWindowVO.setCtx(Env.getCtx()); } return mWindowVO; } // getWindow /** * Post Immediate. * Call {@link Doc#manualPosting(int, int, int, int, boolean)}. * @param WindowNo window * @param AD_Table_ID Table ID of Document * @param AD_Client_ID Client ID of Document * @param Record_ID Record ID of Document * @param force force posting. if false, only post if (Processing='N' OR Processing IS NULL) * @return null if success, otherwise error */ public static String postImmediate (int WindowNo, int AD_Client_ID, int AD_Table_ID, int Record_ID, boolean force) { log.info("Window=" + WindowNo + ", AD_Table_ID=" + AD_Table_ID + "/" + Record_ID + ", Force=" + force); return Doc.manualPosting(WindowNo, AD_Client_ID, AD_Table_ID, Record_ID, force); } // postImmediate /** * Cache Reset * @param tableName table name * @param Record_ID record id */ public static void cacheReset (String tableName, int Record_ID) { if (log.isLoggable(Level.CONFIG)) log.config("TableName=" + tableName + ", Record_ID=" + Record_ID); CacheMgt.get().reset(tableName, Record_ID); } // cacheReset /** * Refresh lookup * @param lookup * @param value * @param mandatory * @param shortList */ public static void actionRefresh(Lookup lookup, Object value, boolean mandatory, boolean shortList) // IDEMPIERE 90 { if (lookup == null) return; lookup.refresh(); if (lookup.isValidated()) lookup.fillComboBox(mandatory, false, false, false, shortList); // IDEMPIERE 90 else lookup.fillComboBox(mandatory, true, false, false, shortList); // IDEMPIERE 90 } /** * zoom to AD Window * @param lookup lookup for zoom destination table * @param value record key */ public static void actionZoom(Lookup lookup, Object value) { if (lookup == null) return; // still null means the field is empty or not selected item if (value == null) value = -1; // MQuery zoomQuery = new MQuery(); // ColumnName might be changed in MTab.validateQuery String column = lookup.getColumnName(); // Check if it is a List Reference if (lookup instanceof MLookup) { int AD_Reference_ID = ((MLookup)lookup).getAD_Reference_Value_ID(); if (AD_Reference_ID > 0) { MReference reference = MReference.get(AD_Reference_ID); if (reference.getValidationType().equals(MReference.VALIDATIONTYPE_ListValidation)) { column = "AD_Ref_List_ID"; value = DB.getSQLValue(null, "SELECT AD_Ref_List_ID FROM AD_Ref_List WHERE AD_Reference_ID=? AND Value=?", AD_Reference_ID, value); } } } //strip off table name, fully qualify name doesn't work when zoom into detail tab if (column.indexOf(".") > 0) { int p = column.indexOf("."); String tableName = column.substring(0, p); column = column.substring(column.indexOf(".")+1); zoomQuery.setZoomTableName(tableName); zoomQuery.setZoomColumnName(column); } else { zoomQuery.setZoomColumnName(column); //remove _ID to get table name zoomQuery.setZoomTableName(column.substring(0, column.length() - 3)); } zoomQuery.setZoomValue(value); zoomQuery.addRestriction(column, MQuery.EQUAL, value); zoomQuery.setRecordCount(1); // guess int windowId = lookup.getZoom(zoomQuery); if (windowId > 0) { zoom(windowId, zoomQuery, lookup.getWindowNo()); } else { int tableId = MTable.getTable_ID(zoomQuery.getZoomTableName()); if (value instanceof Integer && ((Integer) value).intValue() >= 0) { zoom(tableId, ((Integer) value).intValue(), zoomQuery, lookup.getWindowNo()); } else { zoomUU(tableId, value.toString(), zoomQuery, lookup.getWindowNo()); } } } /** * Opens the Drill Assistant * @param data query * @param windowNo */ public static void actionDrill(DrillData data, int windowNo) { actionDrill(data, windowNo, 0); } /** * Opens the Drill Assistant * @param data query * @param windowNo * @param processID Source Report */ public static void actionDrill(DrillData data, int windowNo, int processID) { int AD_Table_ID = MTable.getTable_ID(data.getQuery().getTableName()); if (AD_Table_ID > 0) { if (!MRole.getDefault().isCanReport(AD_Table_ID)) { Dialog.error(windowNo, "AccessCannotReport", data.getQuery().getTableName()); return; } WDrillReport drillReport = new WDrillReport(data, windowNo, processID); Object window = SessionManager.getAppDesktop().findWindow(windowNo); if (window != null && window instanceof Component && window instanceof ISupportMask){ final ISupportMask parent = LayoutUtils.showWindowWithMask(drillReport, (Component)window, LayoutUtils.OVERLAP_PARENT); drillReport.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override public void onEvent(Event event) throws Exception { parent.hideMask(); } }); }else if (window != null && window instanceof Component){ final Mask mask = LayoutUtils.showWindowWithMask(drillReport, (Component)window, null); drillReport.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override public void onEvent(Event event) throws Exception { mask.hideMask(); } }); }else{ drillReport.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); AEnv.showWindow(drillReport); } } else log.warning("No Table found for " + data.getQuery().getWhereClause(true)); } /** * open zoom window with query * @param AD_Window_ID * @param query */ public static void showZoomWindow(int AD_Window_ID, MQuery query) { SessionManager.getAppDesktop().showZoomWindow(AD_Window_ID, query); } /** * Zoom to AD window with the provided window id and filters according to the * query * @param AD_Window_ID Window on which to zoom * @param query Filter to be applied on the records. */ public static void zoom(int AD_Window_ID, MQuery query, int windowNo) { int zoomId = MZoomCondition.findZoomWindowByWindowId(AD_Window_ID, query, windowNo); showZoomWindow(zoomId > 0 ? zoomId : AD_Window_ID, query); } /** * Call {@link #zoom(int, MQuery, int)} * @param AD_Window_ID * @param query */ public static void zoom(int AD_Window_ID, MQuery query) { zoom(AD_Window_ID, query, 0); } /** * Show window in desktop. * Call {@link IDesktop#showWindow(Window)}. * @param win */ public static void showWindow(Window win) { SessionManager.getAppDesktop().showWindow(win); } /** * Zoom to AD Window with details from query * @param query query */ public static void zoom (MQuery query) { if (query == null || query.getTableName() == null || query.getTableName().length() == 0) return; int AD_Window_ID = query.getZoomWindowID(); if (AD_Window_ID <= 0) AD_Window_ID = Env.getZoomWindowID(query); // Nothing to Zoom to if (AD_Window_ID == 0) return; showZoomWindow(AD_Window_ID, query); } /** * Get ImageIcon. * * @param fileNameInImageDir full file name in imgaes folder (e.g. Bean16.png) * @return image {@link URI} */ public static URI getImage(String fileNameInImageDir) { URI uri = null; try { uri = new URI(ThemeManager.getThemeResource("images/" + fileNameInImageDir)); } catch (URISyntaxException exception) { log.log(Level.SEVERE, "Not found: " + fileNameInImageDir); return null; } return uri; } // getImageIcon /** * @return true if client browser is firefox 2+ */ public static boolean isFirefox2() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); if (n instanceof ServletRequest) { String userAgent = Servlets.getUserAgent((ServletRequest) n); return userAgent.indexOf("Firefox/2") >= 0; } else { return false; } } /** * @return boolean * @deprecated See IDEMPIERE-1022 */ public static boolean isBrowserSupported() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); if (n instanceof ServletRequest) { Double version = Servlets.getBrowser((ServletRequest) n, "ff"); if (version != null) { return true; } version = Servlets.getBrowser((ServletRequest) n, "chrome"); if (version != null) { return true; } version = Servlets.getBrowser((ServletRequest) n, "webkit"); if (version != null) { return true; } version = Servlets.getBrowser((ServletRequest) n, "ie"); if (version != null && version.intValue() >= 8) return true; } return false; } /** * @return true if user agent is internet explorer */ public static boolean isInternetExplorer() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); if (n instanceof ServletRequest) { String browser = Servlets.getBrowser((ServletRequest) n); if (browser != null && browser.equals("ie")) return true; else return false; } return false; } /** * @param parent * @param child * @return true if parent == child or parent is ancestor of child. */ public static boolean contains(Component parent, Component child) { if (child == parent) return true; Component c = child.getParent(); while (c != null) { if (c == parent) return true; c = c.getParent(); } return false; } /** * Merge pdfList to outFile * @param pdfList * @param outFile * @throws IOException * @throws DocumentException * @throws FileNotFoundException */ public static void mergePdf(List pdfList, File outFile) throws IOException, DocumentException, FileNotFoundException { Util.mergePdf(pdfList, outFile); } /** * Get window title * @param ctx context * @param WindowNo window * @return Header String */ public static String getWindowHeader(Properties ctx, int WindowNo) { StringBuilder sb = new StringBuilder(); if (WindowNo > 0){ sb.append(Env.getContext(ctx, WindowNo, "_WinInfo_WindowName", false)).append(" "); final String documentNo = Env.getContext(ctx, WindowNo, "DocumentNo", false); final String value = Env.getContext(ctx, WindowNo, "Value", false); final String name = Env.getContext(ctx, WindowNo, "Name", false); if(!"".equals(documentNo)) { sb.append(documentNo).append(" "); } if(!"".equals(value)) { sb.append(value).append(" "); } if(!"".equals(name)) { sb.append(name).append(" "); } } return sb.toString(); } // getHeader /** * @param ctx * @return {@link Language} */ public static Language getLanguage(Properties ctx) { return Env.getLocaleLanguage(ctx); } /** * @param ctx * @return {@link Locale} */ public static Locale getLocale(Properties ctx) { return Env.getLocale(ctx); } /** * Get title for dialog window * @param ctx * @param windowNo * @param prefix * @return dialog header */ public static String getDialogHeader(Properties ctx, int windowNo, String prefix) { StringBuilder sb = new StringBuilder(); if (prefix != null) sb.append(prefix); if (windowNo > 0){ sb.append(Env.getContext(ctx, windowNo, "_WinInfo_WindowName", false)).append(": "); String documentNo = Env.getContext(ctx, windowNo, "DocumentNo", false); if (Util.isEmpty(documentNo)) // try first tab documentNo = Env.getContext(ctx, windowNo, 0, "DocumentNo", false); String value = Env.getContext(ctx, windowNo, "Value", false); if (Util.isEmpty(value)) // try first tab value = Env.getContext(ctx, windowNo, 0, "Value", false); String name = Env.getContext(ctx, windowNo, "Name", false); if (Util.isEmpty(name)) // try first tab name = Env.getContext(ctx, windowNo, 0, "Name", false); if(!"".equals(documentNo)) { sb.append(documentNo).append(" "); } if(!"".equals(value)) { sb.append(value).append(" "); } if(!"".equals(name)) { sb.append(name).append(" "); } } String header = sb.toString().trim(); if (header.length() == 0) header = ThemeManager.getBrowserTitle(); if (header.endsWith(":")) header = header.substring(0, header.length()-1); return header; } /** * Call {@link #getDialogHeader(Properties, int, String)} * @param ctx * @param windowNo * @return dialog header */ public static String getDialogHeader(Properties ctx, int windowNo) { return getDialogHeader(ctx, windowNo, null); } /** * Execute synchronous task in UI thread. * Use {@link Executions#activate(Desktop)} and {@link Executions#deactivate(Desktop)} pair if current thread is not UI/Listener thread. * @param runnable */ public static void executeDesktopTask(final Runnable runnable) { Desktop desktop = getDesktop(); ServerPushTemplate template = new ServerPushTemplate(desktop); template.execute(new IServerPushCallback() { @Override public void updateUI() { runnable.run(); } }); } /** * Execute asynchronous task in UI thread. * @param runnable */ public static void executeAsyncDesktopTask(final Runnable runnable) { Desktop desktop = getDesktop(); ServerPushTemplate template = new ServerPushTemplate(desktop); template.executeAsync(new IServerPushCallback() { @Override public void updateUI() { runnable.run(); } }); } /** * Get current desktop * @return {@link Desktop} */ public static Desktop getDesktop() { boolean inUIThread = Executions.getCurrent() != null; if (inUIThread) { return Executions.getCurrent().getDesktop(); } else { WeakReference ref = DesktopRunnable.getThreadLocalDesktop(); return ref != null ? ref.get() : null; } } /** * @deprecated replace by ClientInfo.isMobile() * @return true if running on a tablet */ @Deprecated(forRemoval = true, since = "11") public static boolean isTablet() { return ClientInfo.isMobile(); } /** * Get AD_Window_ID from windowNo. * @param windowNo * @return AD_Window_ID or {@link Env#adWindowDummyID} (if it is ProcessDialog of InfoWindow) */ public static int getADWindowID (int windowNo){ int adWindowID = 0; Object window = SessionManager.getAppDesktop().findWindow(windowNo); // case show a process dialog, window is below window of process dialog if (window != null && window instanceof ADWindow){ adWindowID = ((ADWindow)window).getAD_Window_ID(); }else if (window != null && (window instanceof ProcessDialog || window instanceof InfoWindow)){ // dummy window is use in case process or infoWindow open in stand-alone window // it help we separate case save preference for all window (windowId = 0, null) and case open in stand-alone (windowId = 200054) adWindowID = Env.adWindowDummyID;// dummy window } return adWindowID; } /** * * @param client * @return {@link WTableDirEditor} for Language if client is with IsMultiLingualDocument=Y * @throws Exception */ public static WTableDirEditor getListDocumentLanguage (MClient client) throws Exception { WTableDirEditor fLanguageType = null; if (client.isMultiLingualDocument()){ Lookup lookupLanguage = MLookupFactory.get (Env.getCtx(), 0, 0, DisplayType.TableDir, Env.getLanguage(Env.getCtx()), MLanguage.COLUMNNAME_AD_Language_ID, 0, false, " IsActive='Y' AND IsLoginLocale = 'Y' "); fLanguageType = new WTableDirEditor(MLanguage.COLUMNNAME_AD_Language_ID, false, false, true, lookupLanguage); } return fLanguageType; } private static String m_ApplicationUrl = null; /** * @return URL to access application from browser */ public static String getApplicationUrl() { String url = MSysConfig.getValue(MSysConfig.APPLICATION_URL, Env.getAD_Client_ID(Env.getCtx())); if (!Util.isEmpty(url) && !url.equals("USE_HARDCODED")) return MSysConfig.getValue(MSysConfig.APPLICATION_URL, Env.getAD_Client_ID(Env.getCtx())); if (m_ApplicationUrl != null) return m_ApplicationUrl; int port = Executions.getCurrent().getServerPort(); String sch = Executions.getCurrent().getScheme(); String sport = null; if ( (sch.equals("http") && port == 80) || (sch.equals("https") && port == 443) ) sport = ""; else sport = ":" + port; m_ApplicationUrl = sch + "://" + Executions.getCurrent().getServerName() + sport + Executions.getCurrent().getContextPath() + Executions.getCurrent().getDesktop().getRequestPath(); return m_ApplicationUrl; } /** * @param po * @return URL link for direct access to the record using AD_Table_ID+Record_UUID */ public static String getZoomUrlTableUU(PO po) { return getApplicationUrl() + "?Action=Zoom&TableName=" + po.get_TableName() + "&Record_UU=" + po.get_UUID(); } /** * @param po * @return URL link for direct access to the record using AD_Table_ID+Record_ID */ public static String getZoomUrlTableID(PO po) { return getApplicationUrl() + "?Action=Zoom&TableName=" + po.get_TableName() + "&Record_ID=" + po.get_ID(); } /** * @param po * @return URL link for direct access to the record using TableName+Record_ID */ public static String getZoomUrlTableName(PO po) { return getApplicationUrl() + "?Action=Zoom&TableName" + po.get_TableName() + "&Record_ID=" + po.get_ID(); } /** * Set attribute value to Boolean.TRUE if attribute doesn't exists in current execution yet. * @param attribute * @return true if attribute have been set for current executions */ public static boolean getOrSetExecutionAttribute(String attribute) { if (Executions.getCurrent() != null) { if (Executions.getCurrent().getAttribute(attribute) != null) return true; Executions.getCurrent().setAttribute(attribute, Boolean.TRUE); } return false; } /** * Workaround for detached HTML input element leak. *
* Detach all InputElement and Button that's the immediate or not immediate child of parent. *
* Note that to remedy the detached HTML element leak issue, we must defer the detach of parent * with {@link Executions#schedule(Desktop, EventListener, Event)}. * @param parent {@link Component} */ public static void detachInputElement(Component parent) { if (parent instanceof InputElement || parent instanceof Button) { parent.detach(); } if (parent.getChildren().size() > 0) { Component[] childs = parent.getChildren().toArray(new Component[0]); for(Component child : childs) { detachInputElement(child); } } } /** * Construct url to open pdfUrl with embedded pdf.js viewer from Mozilla * @param pdfUrl * @return pdf.js viewer url */ public static String toPdfJsUrl(String pdfUrl) { String viewer = Executions.encodeURL("~./js/pdf.js/web/viewer.html?file="); //remove context path int index = viewer.indexOf("/zkau"); if (index >= 0) { viewer = viewer.substring(index+1); } StringBuilder url = new StringBuilder(viewer); url.append(pdfUrl); return url.toString(); } } // AEnv