IDEMPIERE-5570 Zk: Improve readability of code (#1675)
* IDEMPIERE-5570 Zk: Improve readability of code * IDEMPIERE-5570 Zk: Improve readability of code - Improve readability for org.adempiere.webui.apps package.
This commit is contained in:
parent
17f1957d70
commit
dff85c45de
|
@ -33,7 +33,7 @@ import org.compiere.util.Evaluator;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract model and controller for AD_Tab+AD_Field. UI part is implemented in sub class.
|
* Abstract base class for header+details AD_Tabs UI for AD_Window.
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
||||||
* @date Feb 25, 2007
|
* @date Feb 25, 2007
|
||||||
|
@ -41,12 +41,12 @@ import org.compiere.util.Util;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabbox
|
public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabbox
|
||||||
{
|
{
|
||||||
/** Logger */
|
/** Logger **/
|
||||||
private static final CLogger log = CLogger.getCLogger (AbstractADTabbox.class);
|
private static final CLogger log = CLogger.getCLogger (AbstractADTabbox.class);
|
||||||
/** List of dependent Variables */
|
/** List of variables/columnName that's reference by one or more gridTab logic expression **/
|
||||||
private ArrayList<String> m_dependents = new ArrayList<String>();
|
private ArrayList<String> m_dependents = new ArrayList<String>();
|
||||||
|
|
||||||
/** AD tab panels associated to this tab box */
|
/** List of {@link IADTabpanel} instance manage by this AbstractADTabbox instance **/
|
||||||
protected List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
protected List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
||||||
/** Parent part, the content part of AD Window **/
|
/** Parent part, the content part of AD Window **/
|
||||||
protected AbstractADWindowContent adWindowPanel;
|
protected AbstractADWindowContent adWindowPanel;
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.adempiere.webui.LayoutUtils;
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
import org.adempiere.webui.adwindow.ADWindow;
|
||||||
import org.adempiere.webui.component.Mask;
|
import org.adempiere.webui.component.Mask;
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
|
import org.adempiere.webui.desktop.IDesktop;
|
||||||
import org.adempiere.webui.editor.WTableDirEditor;
|
import org.adempiere.webui.editor.WTableDirEditor;
|
||||||
import org.adempiere.webui.event.DialogEvents;
|
import org.adempiere.webui.event.DialogEvents;
|
||||||
import org.adempiere.webui.event.DrillEvent.DrillData;
|
import org.adempiere.webui.event.DrillEvent.DrillData;
|
||||||
|
@ -86,7 +87,7 @@ import org.zkoss.zul.impl.InputElement;
|
||||||
import com.lowagie.text.DocumentException;
|
import com.lowagie.text.DocumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ZK Application Environment and utilities
|
* Static application environment and utilities methods.
|
||||||
*
|
*
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
* @version $Id: AEnv.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
* @version $Id: AEnv.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
||||||
|
@ -95,11 +96,11 @@ import com.lowagie.text.DocumentException;
|
||||||
*/
|
*/
|
||||||
public final class AEnv
|
public final class AEnv
|
||||||
{
|
{
|
||||||
|
/** Environment context attribute for Locale **/
|
||||||
public static final String LOCALE = Env.LOCALE;
|
public static final String LOCALE = Env.LOCALE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show in the center of the screen.
|
* Show window in the center of screen.
|
||||||
* (pack, set location and set visibility)
|
|
||||||
* @param window Window to position
|
* @param window Window to position
|
||||||
*/
|
*/
|
||||||
public static void showCenterScreen(Window window)
|
public static void showCenterScreen(Window window)
|
||||||
|
@ -120,8 +121,7 @@ public final class AEnv
|
||||||
} // showCenterScreen
|
} // showCenterScreen
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show in the center of the screen.
|
* Set window position ({@link org.zkoss.zul.Window#setPosition(String)}) and show it.
|
||||||
* (pack, set location and set visibility)
|
|
||||||
* @param window Window to position
|
* @param window Window to position
|
||||||
* @param position
|
* @param position
|
||||||
*/
|
*/
|
||||||
|
@ -131,8 +131,7 @@ public final class AEnv
|
||||||
} // showScreen
|
} // showScreen
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Position in center of the parent window.
|
* Position window in center of the parent window.
|
||||||
* (pack, set location and set visibility)
|
|
||||||
* @param parent Parent Window
|
* @param parent Parent Window
|
||||||
* @param window Window to position
|
* @param window Window to position
|
||||||
*/
|
*/
|
||||||
|
@ -145,7 +144,7 @@ public final class AEnv
|
||||||
/**
|
/**
|
||||||
* Get Mnemonic character from text.
|
* Get Mnemonic character from text.
|
||||||
* @param text text with '&'
|
* @param text text with '&'
|
||||||
* @return Mnemonic or 0
|
* @return Mnemonic character or 0
|
||||||
*/
|
*/
|
||||||
public static char getMnemonic (String text)
|
public static char getMnemonic (String text)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +158,7 @@ public final class AEnv
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Zoom
|
* Zoom to AD Window by AD_Table_ID and Record_ID.
|
||||||
* @param AD_Table_ID
|
* @param AD_Table_ID
|
||||||
* @param Record_ID
|
* @param Record_ID
|
||||||
*/
|
*/
|
||||||
|
@ -178,10 +177,11 @@ public final class AEnv
|
||||||
} // zoom
|
} // zoom
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Zoom
|
* Zoom to AD Window by AD_Table_ID and Record_ID.
|
||||||
* @param AD_Table_ID
|
* @param AD_Table_ID
|
||||||
* @param Record_ID
|
* @param Record_ID
|
||||||
* @param query
|
* @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)
|
public static void zoom (int AD_Table_ID, int Record_ID, MQuery query, int windowNo)
|
||||||
{
|
{
|
||||||
|
@ -192,21 +192,28 @@ public final class AEnv
|
||||||
zoom(AD_Window_ID, query);
|
zoom(AD_Window_ID, query);
|
||||||
} // zoom
|
} // 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) {
|
public static void zoom (int AD_Table_ID, int Record_ID, MQuery query) {
|
||||||
zoom (AD_Table_ID, Record_ID, query, 0);
|
zoom (AD_Table_ID, Record_ID, query, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit System
|
* Exit System.
|
||||||
* @param status System exit status (usually 0 for no error)
|
* @param status System exit status (usually 0 for no error)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public static void exit (int status)
|
public static void exit (int status)
|
||||||
{
|
{
|
||||||
Env.exitEnv(status);
|
Env.exitEnv(status);
|
||||||
} // exit
|
} // exit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* logout AD_Session
|
* Logout AD_Session and clear {@link #windowCache}.
|
||||||
*/
|
*/
|
||||||
public static void logout()
|
public static void logout()
|
||||||
{
|
{
|
||||||
|
@ -228,13 +235,12 @@ public final class AEnv
|
||||||
session.logout();
|
session.logout();
|
||||||
|
|
||||||
Env.setContext(Env.getCtx(), Env.AD_SESSION_ID, (String)null);
|
Env.setContext(Env.getCtx(), Env.AD_SESSION_ID, (String)null);
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start Workflow Process Window
|
* Open Workflow Process Window for AD_Table_ID and Record_ID
|
||||||
* @param AD_Table_ID optional table
|
* @param AD_Table_ID
|
||||||
* @param Record_ID optional record
|
* @param Record_ID
|
||||||
*/
|
*/
|
||||||
public static void startWorkflowProcess (int AD_Table_ID, int Record_ID)
|
public static void startWorkflowProcess (int AD_Table_ID, int Record_ID)
|
||||||
{
|
{
|
||||||
|
@ -253,28 +259,24 @@ public final class AEnv
|
||||||
AEnv.zoom(s_workflow_Window_ID, query);
|
AEnv.zoom(s_workflow_Window_ID, query);
|
||||||
} // startWorkflowProcess
|
} // startWorkflowProcess
|
||||||
|
|
||||||
|
/** Cache Workflow Window ID **/
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
/** Workflow Window */
|
|
||||||
private static int s_workflow_Window_ID = 0;
|
private static int s_workflow_Window_ID = 0;
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger(AEnv.class);
|
private static final CLogger log = CLogger.getCLogger(AEnv.class);
|
||||||
|
|
||||||
/** Window Cache */
|
/** Register AD Window Cache **/
|
||||||
private static Map<String, CCache<Integer,GridWindowVO>> windowCache = new HashMap<String, CCache<Integer,GridWindowVO>>();
|
private static Map<String, CCache<Integer,GridWindowVO>> windowCache = new HashMap<String, CCache<Integer,GridWindowVO>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Window Model
|
* Get VO for AD_Window
|
||||||
*
|
*
|
||||||
* @param WindowNo Window No
|
* @param WindowNo Window No
|
||||||
* @param AD_Window_ID window
|
* @param AD_Window_ID window
|
||||||
* @param AD_Menu_ID menu
|
* @param AD_Menu_ID menu
|
||||||
* @return Model Window Value Obkect
|
* @return {@link GridWindowVO} instance for AD_Window_ID
|
||||||
*/
|
*/
|
||||||
public static GridWindowVO getMWindowVO (int WindowNo, int AD_Window_ID, int AD_Menu_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);
|
if (log.isLoggable(Level.CONFIG)) log.config("Window=" + WindowNo + ", AD_Window_ID=" + AD_Window_ID);
|
||||||
GridWindowVO mWindowVO = null;
|
GridWindowVO mWindowVO = null;
|
||||||
String sessionID = Env.getContext(Env.getCtx(), Env.AD_SESSION_ID);
|
String sessionID = Env.getContext(Env.getCtx(), Env.AD_SESSION_ID);
|
||||||
|
@ -299,7 +301,8 @@ public final class AEnv
|
||||||
// Create Window Model on Client
|
// Create Window Model on Client
|
||||||
if (mWindowVO == null)
|
if (mWindowVO == null)
|
||||||
{
|
{
|
||||||
log.config("create local");
|
if (log.isLoggable(Level.CONFIG))
|
||||||
|
log.config("create local");
|
||||||
mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID, AD_Menu_ID);
|
mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID, AD_Menu_ID);
|
||||||
if (mWindowVO != null && Ini.isCacheWindow())
|
if (mWindowVO != null && Ini.isCacheWindow())
|
||||||
{
|
{
|
||||||
|
@ -318,10 +321,9 @@ public final class AEnv
|
||||||
if (mWindowVO == null)
|
if (mWindowVO == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Check (remote) context
|
// Check context
|
||||||
if (!mWindowVO.ctx.equals(Env.getCtx()))
|
if (!mWindowVO.ctx.equals(Env.getCtx()))
|
||||||
{
|
{
|
||||||
// Remote Context is called by value, not reference
|
|
||||||
// Add Window properties to context
|
// Add Window properties to context
|
||||||
Enumeration<Object> keyEnum = mWindowVO.ctx.keys();
|
Enumeration<Object> keyEnum = mWindowVO.ctx.keys();
|
||||||
while (keyEnum.hasMoreElements())
|
while (keyEnum.hasMoreElements())
|
||||||
|
@ -341,12 +343,13 @@ public final class AEnv
|
||||||
} // getWindow
|
} // getWindow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post Immediate
|
* Post Immediate.
|
||||||
|
* Call {@link Doc#manualPosting(int, int, int, int, boolean)}.
|
||||||
* @param WindowNo window
|
* @param WindowNo window
|
||||||
* @param AD_Table_ID Table ID of Document
|
* @param AD_Table_ID Table ID of Document
|
||||||
* @param AD_Client_ID Client ID of Document
|
* @param AD_Client_ID Client ID of Document
|
||||||
* @param Record_ID Record ID of this document
|
* @param Record_ID Record ID of Document
|
||||||
* @param force force posting
|
* @param force force posting. if false, only post if (Processing='N' OR Processing IS NULL)
|
||||||
* @return null if success, otherwise error
|
* @return null if success, otherwise error
|
||||||
*/
|
*/
|
||||||
public static String postImmediate (int WindowNo, int AD_Client_ID,
|
public static String postImmediate (int WindowNo, int AD_Client_ID,
|
||||||
|
@ -373,6 +376,13 @@ public final class AEnv
|
||||||
CacheMgt.get().reset(tableName, Record_ID);
|
CacheMgt.get().reset(tableName, Record_ID);
|
||||||
} // cacheReset
|
} // 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
|
public static void actionRefresh(Lookup lookup, Object value, boolean mandatory, boolean shortList) // IDEMPIERE 90
|
||||||
{
|
{
|
||||||
if (lookup == null)
|
if (lookup == null)
|
||||||
|
@ -385,9 +395,9 @@ public final class AEnv
|
||||||
lookup.fillComboBox(mandatory, true, false, false, shortList); // IDEMPIERE 90
|
lookup.fillComboBox(mandatory, true, false, false, shortList); // IDEMPIERE 90
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
* zoom to AD Window
|
||||||
* @param lookup
|
* @param lookup lookup for zoom destination table
|
||||||
* @param value
|
* @param value record key
|
||||||
*/
|
*/
|
||||||
public static void actionZoom(Lookup lookup, Object value)
|
public static void actionZoom(Lookup lookup, Object value)
|
||||||
{
|
{
|
||||||
|
@ -492,7 +502,7 @@ public final class AEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zoom to a window with the provided window id and filters according to the
|
* Zoom to AD window with the provided window id and filters according to the
|
||||||
* query
|
* query
|
||||||
* @param AD_Window_ID Window on which to zoom
|
* @param AD_Window_ID Window on which to zoom
|
||||||
* @param query Filter to be applied on the records.
|
* @param query Filter to be applied on the records.
|
||||||
|
@ -503,17 +513,27 @@ public final class AEnv
|
||||||
showZoomWindow(zoomId > 0 ? zoomId : AD_Window_ID, query);
|
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) {
|
public static void zoom(int AD_Window_ID, MQuery query) {
|
||||||
zoom(AD_Window_ID, query, 0);
|
zoom(AD_Window_ID, query, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show window in desktop.
|
||||||
|
* Call {@link IDesktop#showWindow(Window)}.
|
||||||
|
* @param win
|
||||||
|
*/
|
||||||
public static void showWindow(Window win)
|
public static void showWindow(Window win)
|
||||||
{
|
{
|
||||||
SessionManager.getAppDesktop().showWindow(win);
|
SessionManager.getAppDesktop().showWindow(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zoom
|
* Zoom to AD Window with details from query
|
||||||
* @param query query
|
* @param query query
|
||||||
*/
|
*/
|
||||||
public static void zoom (MQuery query)
|
public static void zoom (MQuery query)
|
||||||
|
@ -537,7 +557,7 @@ public final class AEnv
|
||||||
* Get ImageIcon.
|
* Get ImageIcon.
|
||||||
*
|
*
|
||||||
* @param fileNameInImageDir full file name in imgaes folder (e.g. Bean16.png)
|
* @param fileNameInImageDir full file name in imgaes folder (e.g. Bean16.png)
|
||||||
* @return image
|
* @return image {@link URI}
|
||||||
*/
|
*/
|
||||||
public static URI getImage(String fileNameInImageDir)
|
public static URI getImage(String fileNameInImageDir)
|
||||||
{
|
{
|
||||||
|
@ -555,8 +575,7 @@ public final class AEnv
|
||||||
} // getImageIcon
|
} // getImageIcon
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return true if client browser is firefox 2+
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static boolean isFirefox2() {
|
public static boolean isFirefox2() {
|
||||||
Execution execution = Executions.getCurrent();
|
Execution execution = Executions.getCurrent();
|
||||||
|
@ -626,10 +645,9 @@ public final class AEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param child
|
* @param child
|
||||||
* @return boolean
|
* @return true if parent == child or parent is ancestor of child.
|
||||||
*/
|
*/
|
||||||
public static boolean contains(Component parent, Component child) {
|
public static boolean contains(Component parent, Component child) {
|
||||||
if (child == parent)
|
if (child == parent)
|
||||||
|
@ -646,7 +664,7 @@ public final class AEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Merge pdfList to outFile
|
||||||
* @param pdfList
|
* @param pdfList
|
||||||
* @param outFile
|
* @param outFile
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
@ -687,7 +705,7 @@ public final class AEnv
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ctx
|
* @param ctx
|
||||||
* @return Language
|
* @return {@link Language}
|
||||||
*/
|
*/
|
||||||
public static Language getLanguage(Properties ctx) {
|
public static Language getLanguage(Properties ctx) {
|
||||||
return Env.getLocaleLanguage(ctx);
|
return Env.getLocaleLanguage(ctx);
|
||||||
|
@ -695,7 +713,7 @@ public final class AEnv
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ctx
|
* @param ctx
|
||||||
* @return Locale
|
* @return {@link Locale}
|
||||||
*/
|
*/
|
||||||
public static Locale getLocale(Properties ctx) {
|
public static Locale getLocale(Properties ctx) {
|
||||||
return Env.getLocale(ctx);
|
return Env.getLocale(ctx);
|
||||||
|
@ -741,12 +759,19 @@ public final class AEnv
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link #getDialogHeader(Properties, int, String)}
|
||||||
|
* @param ctx
|
||||||
|
* @param windowNo
|
||||||
|
* @return dialog header
|
||||||
|
*/
|
||||||
public static String getDialogHeader(Properties ctx, int windowNo) {
|
public static String getDialogHeader(Properties ctx, int windowNo) {
|
||||||
return getDialogHeader(ctx, windowNo, null);
|
return getDialogHeader(ctx, windowNo, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute synchronous task in UI thread.
|
* 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
|
* @param runnable
|
||||||
*/
|
*/
|
||||||
public static void executeDesktopTask(final Runnable runnable) {
|
public static void executeDesktopTask(final Runnable runnable) {
|
||||||
|
@ -777,7 +802,7 @@ public final class AEnv
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current desktop
|
* Get current desktop
|
||||||
* @return Desktop
|
* @return {@link Desktop}
|
||||||
*/
|
*/
|
||||||
public static Desktop getDesktop() {
|
public static Desktop getDesktop() {
|
||||||
boolean inUIThread = Executions.getCurrent() != null;
|
boolean inUIThread = Executions.getCurrent() != null;
|
||||||
|
@ -793,6 +818,7 @@ public final class AEnv
|
||||||
* @deprecated replace by ClientInfo.isMobile()
|
* @deprecated replace by ClientInfo.isMobile()
|
||||||
* @return true if running on a tablet
|
* @return true if running on a tablet
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public static boolean isTablet() {
|
public static boolean isTablet() {
|
||||||
return ClientInfo.isMobile();
|
return ClientInfo.isMobile();
|
||||||
}
|
}
|
||||||
|
@ -822,6 +848,12 @@ public final class AEnv
|
||||||
return adWindowID;
|
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 {
|
public static WTableDirEditor getListDocumentLanguage (MClient client) throws Exception {
|
||||||
WTableDirEditor fLanguageType = null;
|
WTableDirEditor fLanguageType = null;
|
||||||
if (client.isMultiLingualDocument()){
|
if (client.isMultiLingualDocument()){
|
||||||
|
@ -834,6 +866,10 @@ public final class AEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String m_ApplicationUrl = null;
|
private static String m_ApplicationUrl = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return URL to access application from browser
|
||||||
|
*/
|
||||||
public static String getApplicationUrl() {
|
public static String getApplicationUrl() {
|
||||||
String url = MSysConfig.getValue(MSysConfig.APPLICATION_URL, Env.getAD_Client_ID(Env.getCtx()));
|
String url = MSysConfig.getValue(MSysConfig.APPLICATION_URL, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
if (!Util.isEmpty(url) && !url.equals("USE_HARDCODED"))
|
if (!Util.isEmpty(url) && !url.equals("USE_HARDCODED"))
|
||||||
|
@ -851,20 +887,26 @@ public final class AEnv
|
||||||
return m_ApplicationUrl;
|
return m_ApplicationUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the link for direct access to the record using tableID */
|
/**
|
||||||
|
* @param po
|
||||||
|
* @return URL link for direct access to the record using AD_Table_ID+Record_ID
|
||||||
|
*/
|
||||||
public static String getZoomUrlTableID(PO po)
|
public static String getZoomUrlTableID(PO po)
|
||||||
{
|
{
|
||||||
return getApplicationUrl() + "?Action=Zoom&AD_Table_ID=" + po.get_Table_ID() + "&Record_ID=" + po.get_ID();
|
return getApplicationUrl() + "?Action=Zoom&AD_Table_ID=" + po.get_Table_ID() + "&Record_ID=" + po.get_ID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the link for direct access to the record using tablename */
|
/**
|
||||||
|
* @param po
|
||||||
|
* @return URL link for direct access to the record using TableName+Record_ID
|
||||||
|
*/
|
||||||
public static String getZoomUrlTableName(PO po)
|
public static String getZoomUrlTableName(PO po)
|
||||||
{
|
{
|
||||||
return getApplicationUrl() + "?Action=Zoom&TableName" + po.get_TableName() + "&Record_ID=" + po.get_ID();
|
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
|
* @param attribute
|
||||||
* @return true if attribute have been set for current executions
|
* @return true if attribute have been set for current executions
|
||||||
*/
|
*/
|
||||||
|
@ -878,17 +920,22 @@ public final class AEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workaround for detached HTML input element leak
|
* Workaround for detached HTML input element leak.
|
||||||
* @param c
|
* <br/>
|
||||||
|
* Detach all InputElement and Button that's the immediate or not immediate child of parent.
|
||||||
|
* <br/>
|
||||||
|
* 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 c) {
|
public static void detachInputElement(Component parent) {
|
||||||
if (c instanceof InputElement || c instanceof Button) {
|
if (parent instanceof InputElement || parent instanceof Button) {
|
||||||
c.detach();
|
parent.detach();
|
||||||
}
|
}
|
||||||
if (c.getChildren().size() > 0) {
|
if (parent.getChildren().size() > 0) {
|
||||||
Component[] childs = c.getChildren().toArray(new Component[0]);
|
Component[] childs = parent.getChildren().toArray(new Component[0]);
|
||||||
for(Component c1 : childs) {
|
for(Component child : childs) {
|
||||||
detachInputElement(c1);
|
detachInputElement(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ import org.compiere.model.MUser;
|
||||||
import org.compiere.model.MUserDefProc;
|
import org.compiere.model.MUserDefProc;
|
||||||
import org.compiere.model.Query;
|
import org.compiere.model.Query;
|
||||||
import org.compiere.model.SystemIDs;
|
import org.compiere.model.SystemIDs;
|
||||||
|
import org.compiere.model.X_AD_PInstance;
|
||||||
import org.compiere.print.MPrintFormat;
|
import org.compiere.print.MPrintFormat;
|
||||||
import org.compiere.process.ProcessInfo;
|
import org.compiere.process.ProcessInfo;
|
||||||
import org.compiere.process.ProcessInfoUtil;
|
import org.compiere.process.ProcessInfoUtil;
|
||||||
|
@ -101,15 +102,22 @@ import org.zkoss.zul.Html;
|
||||||
import org.zkoss.zul.Space;
|
import org.zkoss.zul.Space;
|
||||||
import org.zkoss.zul.Vlayout;
|
import org.zkoss.zul.Vlayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract dialog base class for execution of process/report.
|
||||||
|
* @see ProcessModalDialog
|
||||||
|
* @see ProcessDialog
|
||||||
|
*/
|
||||||
public abstract class AbstractProcessDialog extends Window implements IProcessUI, EventListener<Event>
|
public abstract class AbstractProcessDialog extends Window implements IProcessUI, EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 484056046177205235L;
|
private static final long serialVersionUID = 484056046177205235L;
|
||||||
|
|
||||||
private static final String ON_COMPLETE = "onComplete";
|
/** Event to fire on complete of execution of process/report **/
|
||||||
private static final String ON_STATUS_UPDATE = "onStatusUpdate";
|
private static final String ON_COMPLETE_EVENT = "onComplete";
|
||||||
|
/** Event to update status text of process dialog. Event data: status text message. **/
|
||||||
|
private static final String ON_STATUS_UPDATE_EVENT = "onStatusUpdate";
|
||||||
|
|
||||||
private static final CLogger log = CLogger.getCLogger(AbstractProcessDialog.class);
|
private static final CLogger log = CLogger.getCLogger(AbstractProcessDialog.class);
|
||||||
|
|
||||||
|
@ -118,29 +126,47 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
private Properties m_ctx;
|
private Properties m_ctx;
|
||||||
private int m_AD_Process_ID;
|
private int m_AD_Process_ID;
|
||||||
private ProcessInfo m_pi = null;
|
private ProcessInfo m_pi = null;
|
||||||
|
/** if true, auto call {@link #dispose()} in {@link #ON_COMPLETE_EVENT} handler. **/
|
||||||
private boolean m_disposeOnComplete;
|
private boolean m_disposeOnComplete;
|
||||||
|
/** Panel for process paramters **/
|
||||||
private ProcessParameterPanel parameterPanel = null;
|
private ProcessParameterPanel parameterPanel = null;
|
||||||
|
/** Checkbox to toggle running process/report as background job **/
|
||||||
private Checkbox runAsJobField = null;
|
private Checkbox runAsJobField = null;
|
||||||
private Label notificationTypeLabel = null;
|
private Label notificationTypeLabel = null;
|
||||||
|
/**
|
||||||
|
* Drop down editor for {@link X_AD_PInstance#NOTIFICATIONTYPE_AD_Reference_ID} list.
|
||||||
|
* For background job notification when {@link #runAsJobField} is checked.
|
||||||
|
*/
|
||||||
private WTableDirEditor notificationTypeField = null;
|
private WTableDirEditor notificationTypeField = null;
|
||||||
|
|
||||||
private BusyDialog progressWindow;
|
private BusyDialog progressWindow;
|
||||||
|
|
||||||
|
/** translated process name */
|
||||||
private String m_Name = null;
|
private String m_Name = null;
|
||||||
|
/** translated process description */
|
||||||
private String m_Description = null;
|
private String m_Description = null;
|
||||||
|
/** translated process help */
|
||||||
private String m_Help = null;
|
private String m_Help = null;
|
||||||
private String m_ShowHelp = null; // Determine if a Help Process Window is shown
|
/** Determine if a Help Process Window is shown **/
|
||||||
|
private String m_ShowHelp = null;
|
||||||
|
/** initial panel header message **/
|
||||||
private String initialMessage;
|
private String initialMessage;
|
||||||
|
/** true if dialog is still valid, i.e not dispose yet **/
|
||||||
private boolean m_valid = true;
|
private boolean m_valid = true;
|
||||||
|
/** true if dialog have been cancelled by user **/
|
||||||
private boolean m_cancel = false;
|
private boolean m_cancel = false;
|
||||||
|
|
||||||
|
/** Reference to process thread/task **/
|
||||||
private Future<?> future;
|
private Future<?> future;
|
||||||
|
/** files for download by user **/
|
||||||
private List<File> downloadFiles;
|
private List<File> downloadFiles;
|
||||||
|
/** true when UI have been locked, i.e busy **/
|
||||||
private boolean m_locked = false;
|
private boolean m_locked = false;
|
||||||
private String m_AD_Process_UU = "";
|
private String m_AD_Process_UU = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
protected AbstractProcessDialog()
|
protected AbstractProcessDialog()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
@ -163,7 +189,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* layout as below
|
* layout dialog
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx
|
||||||
* @param WindowNo
|
* @param WindowNo
|
||||||
|
@ -172,7 +198,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
* @param pi
|
* @param pi
|
||||||
* @param autoStart
|
* @param autoStart
|
||||||
* @param isDisposeOnComplete
|
* @param isDisposeOnComplete
|
||||||
* @return
|
* @return true if init is ok.
|
||||||
*/
|
*/
|
||||||
protected boolean init(Properties ctx, int WindowNo, int TabNo, int AD_Process_ID, ProcessInfo pi, boolean autoStart, boolean isDisposeOnComplete)
|
protected boolean init(Properties ctx, int WindowNo, int TabNo, int AD_Process_ID, ProcessInfo pi, boolean autoStart, boolean isDisposeOnComplete)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +209,8 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
setProcessInfo(pi);
|
setProcessInfo(pi);
|
||||||
m_disposeOnComplete = isDisposeOnComplete;
|
m_disposeOnComplete = isDisposeOnComplete;
|
||||||
|
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG))
|
||||||
|
log.config("");
|
||||||
//
|
//
|
||||||
StringBuilder buildMsg = new StringBuilder();
|
StringBuilder buildMsg = new StringBuilder();
|
||||||
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
|
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
|
||||||
|
@ -222,7 +249,6 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
//
|
//
|
||||||
this.setTitle(m_Name);
|
this.setTitle(m_Name);
|
||||||
|
|
||||||
// Move from APanel.actionButton
|
|
||||||
if (m_pi == null) {
|
if (m_pi == null) {
|
||||||
m_pi = new WProcessInfo(m_Name, AD_Process_ID);
|
m_pi = new WProcessInfo(m_Name, AD_Process_ID);
|
||||||
// Set Replace Tab Content
|
// Set Replace Tab Content
|
||||||
|
@ -233,8 +259,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
m_pi.setTitle(m_Name);
|
m_pi.setTitle(m_Name);
|
||||||
m_pi.setAD_Process_UU(m_AD_Process_UU);
|
m_pi.setAD_Process_UU(m_AD_Process_UU);
|
||||||
|
|
||||||
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_TabNo, m_pi);
|
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_TabNo, m_pi);
|
||||||
if ( !parameterPanel.init() ) {
|
if ( !parameterPanel.init() ) {
|
||||||
|
//auto start if no parameters and DonTShowHelp.
|
||||||
if (m_ShowHelp != null && MProcess.SHOWHELP_DonTShowHelp.equals(m_ShowHelp))
|
if (m_ShowHelp != null && MProcess.SHOWHELP_DonTShowHelp.equals(m_ShowHelp))
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|
||||||
|
@ -263,21 +290,33 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** top part of {@link #mainParameterLayout} **/
|
||||||
protected HtmlBasedComponent topParameterLayout;
|
protected HtmlBasedComponent topParameterLayout;
|
||||||
|
/** bottom part of {@link #mainParameterLayout} **/
|
||||||
protected HtmlBasedComponent bottomParameterLayout;
|
protected HtmlBasedComponent bottomParameterLayout;
|
||||||
|
/** main content layout **/
|
||||||
protected HtmlBasedComponent mainParameterLayout;
|
protected HtmlBasedComponent mainParameterLayout;
|
||||||
protected WTableDirEditor fPrintFormat;
|
protected WTableDirEditor fPrintFormat;
|
||||||
private WEditor fLanguageType;
|
private WEditor fLanguageType;
|
||||||
protected Listbox freportType;
|
protected Listbox freportType;
|
||||||
private Checkbox chbIsSummary;
|
private Checkbox chbIsSummary;
|
||||||
|
/** ok button to run process/report **/
|
||||||
protected Button bOK;
|
protected Button bOK;
|
||||||
|
/** cancel button to dismiss dialog **/
|
||||||
protected Button bCancel;
|
protected Button bCancel;
|
||||||
|
/** List of name/label for save process parameters **/
|
||||||
protected Combobox fSavedName=new Combobox();
|
protected Combobox fSavedName=new Combobox();
|
||||||
|
/** button to save process parameters **/
|
||||||
private Button bSave=ButtonFactory.createNamedButton("Save");
|
private Button bSave=ButtonFactory.createNamedButton("Save");
|
||||||
|
/** button to delete saved process parameters **/
|
||||||
private Button bDelete=ButtonFactory.createNamedButton("Delete");
|
private Button bDelete=ButtonFactory.createNamedButton("Delete");
|
||||||
|
/** List of save parameters **/
|
||||||
private List<MPInstance> savedParams;
|
private List<MPInstance> savedParams;
|
||||||
private Label lSaved;
|
private Label lSaved;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* layout dialog
|
||||||
|
*/
|
||||||
protected void layout(){
|
protected void layout(){
|
||||||
overalLayout();
|
overalLayout();
|
||||||
topLayout(topParameterLayout);
|
topLayout(topParameterLayout);
|
||||||
|
@ -285,6 +324,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout {@link #mainParameterLayout}, {@link #topParameterLayout} and {@link #bottomParameterLayout}.
|
||||||
|
*/
|
||||||
protected void overalLayout(){
|
protected void overalLayout(){
|
||||||
mainParameterLayout = new Div();
|
mainParameterLayout = new Div();
|
||||||
mainParameterLayout.setSclass("main-parameter-layout");
|
mainParameterLayout.setSclass("main-parameter-layout");
|
||||||
|
@ -300,6 +342,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
mainParameterLayout.appendChild(bottomParameterLayout);
|
mainParameterLayout.appendChild(bottomParameterLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout content of {@link #topParameterLayout}
|
||||||
|
* @param topParameterLayout
|
||||||
|
*/
|
||||||
protected void topLayout(HtmlBasedComponent topParameterLayout) {
|
protected void topLayout(HtmlBasedComponent topParameterLayout) {
|
||||||
// message
|
// message
|
||||||
setHeadMessage (topParameterLayout, initialMessage);
|
setHeadMessage (topParameterLayout, initialMessage);
|
||||||
|
@ -313,6 +359,12 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
inputParameterLayout(inputParameterLayout);
|
inputParameterLayout(inputParameterLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create header message of {@link #topParameterLayout}
|
||||||
|
* @param parent
|
||||||
|
* @param contentMsg
|
||||||
|
* @return content component for contentMsg
|
||||||
|
*/
|
||||||
protected HtmlBasedComponent setHeadMessage (HtmlBasedComponent parent, String contentMsg){
|
protected HtmlBasedComponent setHeadMessage (HtmlBasedComponent parent, String contentMsg){
|
||||||
// message
|
// message
|
||||||
HtmlBasedComponent messageParameterLayout = new Vlayout();
|
HtmlBasedComponent messageParameterLayout = new Vlayout();
|
||||||
|
@ -332,6 +384,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout parameter part of {@link #topParameterLayout}.
|
||||||
|
* {@link #parameterPanel}, {@link #runAsJobField} and {@link #notificationTypeField}.
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
protected void inputParameterLayout (HtmlBasedComponent parent) {
|
protected void inputParameterLayout (HtmlBasedComponent parent) {
|
||||||
parent.appendChild(parameterPanel);
|
parent.appendChild(parameterPanel);
|
||||||
|
|
||||||
|
@ -403,6 +460,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout content of {@link #bottomParameterLayout}.
|
||||||
|
* Report option, save parameter and action buttons.
|
||||||
|
* @param bottomParameterLayout
|
||||||
|
*/
|
||||||
protected void bottomLayout(HtmlBasedComponent bottomParameterLayout) {
|
protected void bottomLayout(HtmlBasedComponent bottomParameterLayout) {
|
||||||
reportOptionLayout(bottomParameterLayout);
|
reportOptionLayout(bottomParameterLayout);
|
||||||
|
|
||||||
|
@ -418,6 +480,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
buttonLayout (bottomContainer);
|
buttonLayout (bottomContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render report option part of {@link #bottomParameterLayout}.
|
||||||
|
* @param bottomParameterLayout
|
||||||
|
*/
|
||||||
protected void reportOptionLayout(HtmlBasedComponent bottomParameterLayout) {
|
protected void reportOptionLayout(HtmlBasedComponent bottomParameterLayout) {
|
||||||
if (!isReport() && !isJasperReport())
|
if (!isReport() && !isJasperReport())
|
||||||
return;//if not a report not need show this pannel
|
return;//if not a report not need show this pannel
|
||||||
|
@ -428,6 +494,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
reportOptionLayout.setValign("middle");
|
reportOptionLayout.setValign("middle");
|
||||||
bottomParameterLayout.appendChild(reportOptionLayout);
|
bottomParameterLayout.appendChild(reportOptionLayout);
|
||||||
|
|
||||||
|
//output type: html, pdf, etc
|
||||||
Label lreportType = new Label(Msg.translate(Env.getCtx(), "view.report"));
|
Label lreportType = new Label(Msg.translate(Env.getCtx(), "view.report"));
|
||||||
lreportType.setSclass("option-input-parameter view-report-label");
|
lreportType.setSclass("option-input-parameter view-report-label");
|
||||||
freportType = new Listbox();
|
freportType = new Listbox();
|
||||||
|
@ -440,6 +507,8 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
|
|
||||||
if (!isReport())
|
if (!isReport())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//summary option
|
||||||
chbIsSummary = new Checkbox();
|
chbIsSummary = new Checkbox();
|
||||||
chbIsSummary.setSclass("option-input-parameter");
|
chbIsSummary.setSclass("option-input-parameter");
|
||||||
Label lPrintFormat = new Label(Msg.translate(Env.getCtx(), "AD_PrintFormat_ID"));
|
Label lPrintFormat = new Label(Msg.translate(Env.getCtx(), "AD_PrintFormat_ID"));
|
||||||
|
@ -447,11 +516,13 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
Label lIsSummary = new Label(Msg.translate(Env.getCtx(), "Summary"));
|
Label lIsSummary = new Label(Msg.translate(Env.getCtx(), "Summary"));
|
||||||
lIsSummary.setSclass("option-input-parameter");
|
lIsSummary.setSclass("option-input-parameter");
|
||||||
|
|
||||||
|
//print formats
|
||||||
MClient client = MClient.get(m_ctx);
|
MClient client = MClient.get(m_ctx);
|
||||||
listPrintFormat(client);
|
listPrintFormat(client);
|
||||||
|
|
||||||
reportOptionLayout.appendChild(lPrintFormat);
|
reportOptionLayout.appendChild(lPrintFormat);
|
||||||
reportOptionLayout.appendChild(fPrintFormat.getComponent());
|
reportOptionLayout.appendChild(fPrintFormat.getComponent());
|
||||||
|
//selection of language
|
||||||
if (client.isMultiLingualDocument()){
|
if (client.isMultiLingualDocument()){
|
||||||
Label lLanguageType = new Label(Msg.translate(Env.getCtx(), MLanguage.COLUMNNAME_AD_Language_ID));
|
Label lLanguageType = new Label(Msg.translate(Env.getCtx(), MLanguage.COLUMNNAME_AD_Language_ID));
|
||||||
reportOptionLayout.appendChild(lLanguageType);
|
reportOptionLayout.appendChild(lLanguageType);
|
||||||
|
@ -464,16 +535,26 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
reportOptionLayout.appendChild(chbIsSummary);
|
reportOptionLayout.appendChild(chbIsSummary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if current process is with IsReport=Y AND JasperReport Is NULL.
|
||||||
|
*/
|
||||||
protected boolean isReport () {
|
protected boolean isReport () {
|
||||||
MProcess pr = MProcess.get(m_ctx, m_AD_Process_ID);
|
MProcess pr = MProcess.get(m_ctx, m_AD_Process_ID);
|
||||||
return pr.isReport() && pr.getJasperReport() == null;
|
return pr.isReport() && pr.getJasperReport() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if current process is with IsReport=Y AND JasperReport Is Not NULL.
|
||||||
|
*/
|
||||||
protected boolean isJasperReport () {
|
protected boolean isJasperReport () {
|
||||||
MProcess pr = MProcess.get(m_ctx, m_AD_Process_ID);
|
MProcess pr = MProcess.get(m_ctx, m_AD_Process_ID);
|
||||||
return pr.isReport() && pr.getJasperReport() != null;
|
return pr.isReport() && pr.getJasperReport() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout UI to load/save process parameters
|
||||||
|
* @param bottomParameterLayout
|
||||||
|
*/
|
||||||
protected void savePrameterLayout(HtmlBasedComponent bottomParameterLayout) {
|
protected void savePrameterLayout(HtmlBasedComponent bottomParameterLayout) {
|
||||||
Hlayout savePrameterLayout = new Hlayout();
|
Hlayout savePrameterLayout = new Hlayout();
|
||||||
savePrameterLayout.setSclass("save-parameter-container");
|
savePrameterLayout.setSclass("save-parameter-container");
|
||||||
|
@ -503,6 +584,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
querySaved();
|
querySaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load saved process parameters
|
||||||
|
*/
|
||||||
protected void querySaved()
|
protected void querySaved()
|
||||||
{
|
{
|
||||||
//user query
|
//user query
|
||||||
|
@ -517,6 +601,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
fSavedName.setValue("");
|
fSavedName.setValue("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action buttons for dialog
|
||||||
|
* @param bottomParameterLayout
|
||||||
|
*/
|
||||||
protected void buttonLayout (HtmlBasedComponent bottomParameterLayout) {
|
protected void buttonLayout (HtmlBasedComponent bottomParameterLayout) {
|
||||||
HtmlBasedComponent confParaPanel =new Div();
|
HtmlBasedComponent confParaPanel =new Div();
|
||||||
confParaPanel.setSclass("button-container");
|
confParaPanel.setSclass("button-container");
|
||||||
|
@ -536,6 +624,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill {@link #fPrintFormat}
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
private void listPrintFormat(MClient client)
|
private void listPrintFormat(MClient client)
|
||||||
{
|
{
|
||||||
int AD_Column_ID = 0;
|
int AD_Column_ID = 0;
|
||||||
|
@ -590,6 +682,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
setReportTypeAndPrintFormat(getLastRun());
|
setReportTypeAndPrintFormat(getLastRun());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill {@link #freportType} for Jasper Report.
|
||||||
|
*/
|
||||||
private void listReportTypeJasper()
|
private void listReportTypeJasper()
|
||||||
{
|
{
|
||||||
boolean m_isCanExport = MRole.getDefault().isCanExport();
|
boolean m_isCanExport = MRole.getDefault().isCanExport();
|
||||||
|
@ -598,6 +693,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
setReportTypeAndPrintFormat(getLastRun());
|
setReportTypeAndPrintFormat(getLastRun());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last run {@link MPInstance} record for current logged in user.
|
||||||
|
*/
|
||||||
protected MPInstance getLastRun() {
|
protected MPInstance getLastRun() {
|
||||||
final String where = "AD_Process_ID = ? AND AD_User_ID = ? AND Name IS NULL ";
|
final String where = "AD_Process_ID = ? AND AD_User_ID = ? AND Name IS NULL ";
|
||||||
return new Query(Env.getCtx(), MPInstance.Table_Name, where, null)
|
return new Query(Env.getCtx(), MPInstance.Table_Name, where, null)
|
||||||
|
@ -607,6 +705,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
.first();
|
.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill {@link #freportType}
|
||||||
|
* @param m_isCanExport true to include excel and csv.
|
||||||
|
*/
|
||||||
private void fillReportType(boolean m_isCanExport) {
|
private void fillReportType(boolean m_isCanExport) {
|
||||||
freportType.removeAllItems();
|
freportType.removeAllItems();
|
||||||
freportType.setMold("select");
|
freportType.setMold("select");
|
||||||
|
@ -623,6 +725,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
freportType.setSelectedIndex(-1);
|
freportType.setSelectedIndex(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value for {@link #fPrintFormat}, {@link #fLanguageType}, {@link #freportType} and {@link #chbIsSummary} from instance.
|
||||||
|
* @param instance
|
||||||
|
*/
|
||||||
private void setReportTypeAndPrintFormat(MPInstance instance)
|
private void setReportTypeAndPrintFormat(MPInstance instance)
|
||||||
{
|
{
|
||||||
if (fPrintFormat != null && instance != null
|
if (fPrintFormat != null && instance != null
|
||||||
|
@ -645,6 +751,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
chbIsSummary.setSelected(instance.isSummary());
|
chbIsSummary.setSelected(instance.isSummary());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update process info ({@link ProcessInfo}) with selected report options ({@link #freportType},
|
||||||
|
* {@link #fPrintFormat}, {@link #fLanguageType} and {@link #chbIsSummary}).
|
||||||
|
*/
|
||||||
protected void saveReportOption (){
|
protected void saveReportOption (){
|
||||||
if (!isReport() && !isJasperReport()){
|
if (!isReport() && !isJasperReport()){
|
||||||
return;
|
return;
|
||||||
|
@ -669,11 +779,16 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
getProcessInfo().setLanguageID(MLanguage.get(getCtx(), Env.getLanguage(getCtx())).getAD_Language_ID());
|
getProcessInfo().setLanguageID(MLanguage.get(getCtx(), Env.getLanguage(getCtx())).getAD_Language_ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto start process upon instantiation of process dialog.
|
||||||
|
* Delegate to {@link #startProcess0()}.
|
||||||
|
*/
|
||||||
protected void autoStart()
|
protected void autoStart()
|
||||||
{
|
{
|
||||||
startProcess0();
|
startProcess0();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event)
|
public void onEvent(Event event)
|
||||||
{
|
{
|
||||||
Component component = event.getTarget();
|
Component component = event.getTarget();
|
||||||
|
@ -683,9 +798,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
mainParameterLayout.invalidate();
|
mainParameterLayout.invalidate();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (event.getName().equals(ON_COMPLETE))
|
else if (event.getName().equals(ON_COMPLETE_EVENT))
|
||||||
onComplete();
|
onComplete();
|
||||||
else if (event.getName().equals(ON_STATUS_UPDATE))
|
else if (event.getName().equals(ON_STATUS_UPDATE_EVENT))
|
||||||
onStatusUpdate(event);
|
onStatusUpdate(event);
|
||||||
else if (event.getTarget().equals(bSave) || event.getTarget().equals(bDelete) || event.getTarget().equals(fSavedName)){
|
else if (event.getTarget().equals(bSave) || event.getTarget().equals(bDelete) || event.getTarget().equals(fSavedName)){
|
||||||
String saveName = null;
|
String saveName = null;
|
||||||
|
@ -708,52 +823,62 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save process parameters and report options.
|
||||||
|
* Set MPInstance.Name = saveName.
|
||||||
|
* @param saveName
|
||||||
|
*/
|
||||||
protected void updateSaveParameter(String saveName) {
|
protected void updateSaveParameter(String saveName) {
|
||||||
// Update existing
|
// Update existing
|
||||||
if (fSavedName.getSelectedIndex() > -1 && savedParams != null) {
|
if (fSavedName.getSelectedIndex() > -1 && savedParams != null) {
|
||||||
for (int i = 0; i < savedParams.size(); i++) {
|
for (int i = 0; i < savedParams.size(); i++) {
|
||||||
if (savedParams.get(i).getName().equals(saveName)) {
|
if (savedParams.get(i).getName().equals(saveName)) {
|
||||||
getProcessInfo().setAD_PInstance_ID(savedParams.get(i)
|
getProcessInfo().setAD_PInstance_ID(savedParams.get(i)
|
||||||
.getAD_PInstance_ID());
|
.getAD_PInstance_ID());
|
||||||
for (MPInstancePara para : savedParams.get(i)
|
for (MPInstancePara para : savedParams.get(i)
|
||||||
.getParameters()) {
|
.getParameters()) {
|
||||||
para.deleteEx(true);
|
para.deleteEx(true);
|
||||||
}
|
|
||||||
getParameterPanel().saveParameters();
|
|
||||||
|
|
||||||
saveReportOptionToInstance(savedParams.get(i));
|
|
||||||
|
|
||||||
savedParams.get(i).saveEx();
|
|
||||||
|
|
||||||
getProcessInfo().setAD_PInstance_ID(0);
|
|
||||||
}
|
}
|
||||||
|
getParameterPanel().saveParameters();
|
||||||
|
|
||||||
|
saveReportOptionToInstance(savedParams.get(i));
|
||||||
|
|
||||||
|
savedParams.get(i).saveEx();
|
||||||
|
|
||||||
|
getProcessInfo().setAD_PInstance_ID(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create new
|
}
|
||||||
else {
|
// create new
|
||||||
MPInstance instance = null;
|
else {
|
||||||
try {
|
MPInstance instance = null;
|
||||||
instance = new MPInstance(Env.getCtx(),
|
try {
|
||||||
getProcessInfo().getAD_Process_ID(), getProcessInfo().getRecord_ID());
|
instance = new MPInstance(Env.getCtx(),
|
||||||
instance.setName(saveName);
|
getProcessInfo().getAD_Process_ID(), getProcessInfo().getRecord_ID());
|
||||||
saveReportOptionToInstance(instance);
|
instance.setName(saveName);
|
||||||
instance.saveEx();
|
saveReportOptionToInstance(instance);
|
||||||
getProcessInfo().setAD_PInstance_ID(instance.getAD_PInstance_ID());
|
instance.saveEx();
|
||||||
// Get Parameters
|
getProcessInfo().setAD_PInstance_ID(instance.getAD_PInstance_ID());
|
||||||
if (getParameterPanel() != null) {
|
// Get Parameters
|
||||||
if (!getParameterPanel().saveParameters()) {
|
if (getParameterPanel() != null) {
|
||||||
throw new AdempiereSystemError(Msg.getMsg(
|
if (!getParameterPanel().saveParameters()) {
|
||||||
Env.getCtx(), "SaveParameterError"));
|
throw new AdempiereSystemError(Msg.getMsg(
|
||||||
}
|
Env.getCtx(), "SaveParameterError"));
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
|
||||||
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
||||||
}
|
}
|
||||||
querySaved();
|
}
|
||||||
fSavedName.setSelectedItem(getComboItem(saveName));
|
//reload fSavedName
|
||||||
|
querySaved();
|
||||||
|
fSavedName.setSelectedItem(getComboItem(saveName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save report options (output type, print format, language and IsSummary) to instance.
|
||||||
|
* @param instance {@link MPInstance}
|
||||||
|
*/
|
||||||
protected void saveReportOptionToInstance (MPInstance instance){
|
protected void saveReportOptionToInstance (MPInstance instance){
|
||||||
if (!isReport() && !isJasperReport())
|
if (!isReport() && !isJasperReport())
|
||||||
return;
|
return;
|
||||||
|
@ -782,6 +907,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
instance.setIsSummary(chbIsSummary.isSelected());
|
instance.setIsSummary(chbIsSummary.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find {@link #fSavedName} item for value.
|
||||||
|
* @param value
|
||||||
|
* @return {@link Comboitem} found.
|
||||||
|
*/
|
||||||
public Comboitem getComboItem( String value) {
|
public Comboitem getComboItem( String value) {
|
||||||
Comboitem item = null;
|
Comboitem item = null;
|
||||||
for (int i = 0; i < fSavedName.getItems().size(); i++) {
|
for (int i = 0; i < fSavedName.getItems().size(); i++) {
|
||||||
|
@ -794,7 +924,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete saved MPInstance by saveName.
|
||||||
|
* @param saveName
|
||||||
|
*/
|
||||||
protected void deleteSaveParameter(String saveName) {
|
protected void deleteSaveParameter(String saveName) {
|
||||||
Object o = fSavedName.getSelectedItem();
|
Object o = fSavedName.getSelectedItem();
|
||||||
if (savedParams != null && o != null) {
|
if (savedParams != null && o != null) {
|
||||||
|
@ -808,6 +942,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
querySaved();
|
querySaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load MPInstance by saveName.
|
||||||
|
* @param saveName
|
||||||
|
* @param lastRun
|
||||||
|
*/
|
||||||
protected void chooseSaveParameter(String saveName, boolean lastRun) {
|
protected void chooseSaveParameter(String saveName, boolean lastRun) {
|
||||||
if (savedParams != null && saveName != null) {
|
if (savedParams != null && saveName != null) {
|
||||||
for (int i = 0; i < savedParams.size(); i++) {
|
for (int i = 0; i < savedParams.size(); i++) {
|
||||||
|
@ -819,15 +958,22 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
boolean enabled = !Util.isEmpty(saveName);
|
boolean enabled = !Util.isEmpty(saveName);
|
||||||
bSave.setEnabled(enabled && !lastRun);
|
bSave.setEnabled(enabled && !lastRun);
|
||||||
bDelete.setEnabled(enabled && fSavedName.getSelectedIndex() > -1
|
bDelete.setEnabled(enabled && fSavedName.getSelectedIndex() > -1
|
||||||
&& !lastRun);
|
&& !lastRun);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load parameter values and report options from instance.
|
||||||
|
* @param instance {@link MPInstance}
|
||||||
|
*/
|
||||||
protected void loadSavedParams(MPInstance instance) {
|
protected void loadSavedParams(MPInstance instance) {
|
||||||
getParameterPanel().loadParameters(instance);
|
getParameterPanel().loadParameters(instance);
|
||||||
setReportTypeAndPrintFormat(instance);
|
setReportTypeAndPrintFormat(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run process.
|
||||||
|
* Delegate to {@link #startProcess0()}.
|
||||||
|
*/
|
||||||
protected void startProcess()
|
protected void startProcess()
|
||||||
{
|
{
|
||||||
if (!parameterPanel.validateParameters())
|
if (!parameterPanel.validateParameters())
|
||||||
|
@ -842,12 +988,19 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
startProcess0();
|
startProcess0();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel/dismiss process dialog.
|
||||||
|
*/
|
||||||
protected void cancelProcess()
|
protected void cancelProcess()
|
||||||
{
|
{
|
||||||
m_cancel = true;
|
m_cancel = true;
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new {@link #progressWindow}.
|
||||||
|
* @return {@link BusyDialog}
|
||||||
|
*/
|
||||||
protected BusyDialog createBusyDialog()
|
protected BusyDialog createBusyDialog()
|
||||||
{
|
{
|
||||||
progressWindow = new BusyDialog();
|
progressWindow = new BusyDialog();
|
||||||
|
@ -855,6 +1008,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
return progressWindow;
|
return progressWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close {@link #progressWindow}.
|
||||||
|
*/
|
||||||
protected void closeBusyDialog()
|
protected void closeBusyDialog()
|
||||||
{
|
{
|
||||||
if (progressWindow != null) {
|
if (progressWindow != null) {
|
||||||
|
@ -869,6 +1025,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
} // dispose
|
} // dispose
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run process.
|
||||||
|
*/
|
||||||
private void startProcess0()
|
private void startProcess0()
|
||||||
{
|
{
|
||||||
if (!isBackgroundJob())
|
if (!isBackgroundJob())
|
||||||
|
@ -882,12 +1041,20 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
Clients.response(new AuEcho(this, isBackgroundJob() ? "runBackgroundJob" : "runProcess", this));
|
Clients.response(new AuEcho(this, isBackgroundJob() ? "runBackgroundJob" : "runProcess", this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run process. Echo event from {@link #startProcess0()}.
|
||||||
|
*/
|
||||||
public void runProcess()
|
public void runProcess()
|
||||||
{
|
{
|
||||||
Events.sendEvent(DialogEvents.ON_BEFORE_RUN_PROCESS, this, null);
|
Events.sendEvent(DialogEvents.ON_BEFORE_RUN_PROCESS, this, null);
|
||||||
future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new ProcessDialogRunnable(null), getDesktop()));
|
future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new ProcessDialogRunnable(null), getDesktop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run process as background job (runBackgroundJob event echo from {@link #startProcess0()}).
|
||||||
|
* <br/>
|
||||||
|
* The different with {@link #runProcess()} is this method doesn't wait for completion of process.
|
||||||
|
*/
|
||||||
public void runBackgroundJob()
|
public void runBackgroundJob()
|
||||||
{
|
{
|
||||||
Properties m_ctx = getCtx();
|
Properties m_ctx = getCtx();
|
||||||
|
@ -959,6 +1126,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle {@link #ON_COMPLETE_EVENT}
|
||||||
|
*/
|
||||||
private void onComplete()
|
private void onComplete()
|
||||||
{
|
{
|
||||||
ProcessInfo m_pi = getProcessInfo();
|
ProcessInfo m_pi = getProcessInfo();
|
||||||
|
@ -986,6 +1156,10 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle {@link #ON_STATUS_UPDATE_EVENT}
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
private void onStatusUpdate(Event event)
|
private void onStatusUpdate(Event event)
|
||||||
{
|
{
|
||||||
String message = (String) event.getData();
|
String message = (String) event.getData();
|
||||||
|
@ -993,6 +1167,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
progressWindow.statusUpdate(message);
|
progressWindow.statusUpdate(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock UI by showing of busy dialog ({@link #progressWindow}).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void lockUI(ProcessInfo pi) {
|
public void lockUI(ProcessInfo pi) {
|
||||||
if (m_locked || Executions.getCurrent() == null)
|
if (m_locked || Executions.getCurrent() == null)
|
||||||
|
@ -1001,8 +1178,14 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
showBusyDialog();
|
showBusyDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show process in progress dialog.
|
||||||
|
*/
|
||||||
public abstract void showBusyDialog();
|
public abstract void showBusyDialog();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock dialog upon completion of process (or upon submission of job if process is running as background job).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void unlockUI(ProcessInfo pi) {
|
public void unlockUI(ProcessInfo pi) {
|
||||||
if (!m_locked)
|
if (!m_locked)
|
||||||
|
@ -1026,14 +1209,23 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close process in progress dialog and update UI with the result of process execution.
|
||||||
|
*/
|
||||||
private void doUnlockUI()
|
private void doUnlockUI()
|
||||||
{
|
{
|
||||||
hideBusyDialog();
|
hideBusyDialog();
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close process in progress dialog.
|
||||||
|
*/
|
||||||
public abstract void hideBusyDialog();
|
public abstract void hideBusyDialog();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update UI with the result of process execution.
|
||||||
|
*/
|
||||||
public abstract void updateUI();
|
public abstract void updateUI();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1045,7 +1237,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
public void statusUpdate(String message) {
|
public void statusUpdate(String message) {
|
||||||
Desktop desktop = getDesktop();
|
Desktop desktop = getDesktop();
|
||||||
if (desktop != null && desktop.isAlive())
|
if (desktop != null && desktop.isAlive())
|
||||||
Executions.schedule(desktop, this, new Event(ON_STATUS_UPDATE, this, message));
|
Executions.schedule(desktop, this, new Event(ON_STATUS_UPDATE_EVENT, this, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1064,20 +1256,21 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return {@link ProcessInfo}
|
||||||
* @return ProcessInfo
|
|
||||||
*/
|
*/
|
||||||
public ProcessInfo getProcessInfo() {
|
public ProcessInfo getProcessInfo() {
|
||||||
return m_pi;
|
return m_pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pi
|
||||||
|
*/
|
||||||
public void setProcessInfo(ProcessInfo pi) {
|
public void setProcessInfo(ProcessInfo pi) {
|
||||||
m_pi = pi;
|
m_pi = pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is dialog still valid
|
* @return true if dialog is still valid (i.e not completed and not cancel).
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public boolean isValid()
|
public boolean isValid()
|
||||||
{
|
{
|
||||||
|
@ -1092,60 +1285,97 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
return m_cancel;
|
return m_cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return cache environment context reference
|
||||||
|
*/
|
||||||
public Properties getCtx()
|
public Properties getCtx()
|
||||||
{
|
{
|
||||||
return m_ctx;
|
return m_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return register window number.
|
||||||
|
*/
|
||||||
public int getWindowNo()
|
public int getWindowNo()
|
||||||
{
|
{
|
||||||
return m_WindowNo;
|
return m_WindowNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AD_Process_ID
|
||||||
|
*/
|
||||||
public int getAD_Process_ID()
|
public int getAD_Process_ID()
|
||||||
{
|
{
|
||||||
return m_AD_Process_ID;
|
return m_AD_Process_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ProcessParameterPanel} instance
|
||||||
|
*/
|
||||||
public ProcessParameterPanel getParameterPanel()
|
public ProcessParameterPanel getParameterPanel()
|
||||||
{
|
{
|
||||||
return parameterPanel;
|
return parameterPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return translated process name
|
||||||
|
*/
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return m_Name;
|
return m_Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DonTShowHelp, ShowHelp or Silent.
|
||||||
|
*/
|
||||||
public String getShowHelp()
|
public String getShowHelp()
|
||||||
{
|
{
|
||||||
return m_ShowHelp;
|
return m_ShowHelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return initial panel header message
|
||||||
|
*/
|
||||||
public String getInitialMessage()
|
public String getInitialMessage()
|
||||||
{
|
{
|
||||||
return initialMessage;
|
return initialMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if run process as background job.
|
||||||
|
*/
|
||||||
public boolean isBackgroundJob()
|
public boolean isBackgroundJob()
|
||||||
{
|
{
|
||||||
return runAsJobField != null && runAsJobField.isChecked();
|
return runAsJobField != null && runAsJobField.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Notification type - None, Email, Notice or Email+Notice.
|
||||||
|
*/
|
||||||
public String getNotificationType()
|
public String getNotificationType()
|
||||||
{
|
{
|
||||||
return (String) notificationTypeField.getValue();
|
return (String) notificationTypeField.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of files for user download
|
||||||
|
*/
|
||||||
public List<File> getDownloadFiles()
|
public List<File> getDownloadFiles()
|
||||||
{
|
{
|
||||||
return downloadFiles;
|
return downloadFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runnable to run process in background thread.
|
||||||
|
* Notify process dialog with {@link AbstractProcessDialog#ON_COMPLETE_EVENT} event.
|
||||||
|
*/
|
||||||
private class ProcessDialogRunnable extends ZkContextRunnable
|
private class ProcessDialogRunnable extends ZkContextRunnable
|
||||||
{
|
{
|
||||||
private Trx m_trx;
|
private Trx m_trx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param trx
|
||||||
|
*/
|
||||||
private ProcessDialogRunnable(Trx trx)
|
private ProcessDialogRunnable(Trx trx)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
@ -1164,11 +1394,15 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
m_pi.setSummary(ex.getLocalizedMessage());
|
m_pi.setSummary(ex.getLocalizedMessage());
|
||||||
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
Executions.schedule(getDesktop(), AbstractProcessDialog.this, new Event(ON_COMPLETE, AbstractProcessDialog.this, null));
|
Executions.schedule(getDesktop(), AbstractProcessDialog.this, new Event(ON_COMPLETE_EVENT, AbstractProcessDialog.this, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runnable to run process as background job.
|
||||||
|
* Send email or notice notification to user upon completion of job.
|
||||||
|
*/
|
||||||
private class BackgroundJobRunnable implements Runnable
|
private class BackgroundJobRunnable implements Runnable
|
||||||
{
|
{
|
||||||
private Properties m_ctx;
|
private Properties m_ctx;
|
||||||
|
@ -1313,6 +1547,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
|
||||||
Dialog.askForInput(message, lookup, editorType, callback, getDesktop(), m_WindowNo);
|
Dialog.askForInput(message, lookup, editorType, callback, getDesktop(), m_WindowNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge pdfList and show with {@link SimplePDFViewer}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void showReports(List<File> pdfList) {
|
public void showReports(List<File> pdfList) {
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,24 @@ import org.zkoss.zul.Div;
|
||||||
import org.zkoss.zul.Span;
|
import org.zkoss.zul.Span;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Blocking in progress dialog.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BusyDialog extends Window {
|
public class BusyDialog extends Window {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
private static final long serialVersionUID = -779475945298887887L;
|
private static final long serialVersionUID = -779475945298887887L;
|
||||||
|
/**
|
||||||
|
* Label component to display in progress message (default is Processing...).
|
||||||
|
*/
|
||||||
private Label label;
|
private Label label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
public BusyDialog() {
|
public BusyDialog() {
|
||||||
super();
|
super();
|
||||||
LayoutUtils.addSclass("busy-dialog", this);
|
LayoutUtils.addSclass("busy-dialog", this);
|
||||||
|
@ -55,6 +64,10 @@ public class BusyDialog extends Window {
|
||||||
setShadow(true);
|
setShadow(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update in progress message.
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
public void statusUpdate(String message) {
|
public void statusUpdate(String message) {
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
label.setText(message);
|
label.setText(message);
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* 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 *
|
||||||
|
* - Richard Morales *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.apps;
|
package org.adempiere.webui.apps;
|
||||||
|
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
|
@ -5,18 +30,31 @@ import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
import org.zkoss.zk.ui.event.Events;
|
import org.zkoss.zk.ui.event.Events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show {@link BusyDialog} and invoke {@link Runnable} task.
|
||||||
|
* <br/>
|
||||||
|
* Usage: new BusyDialogTemplate(runnable).run(); or with Lambda,new BusyDialogTemplate(() -> {your code}).run();
|
||||||
|
*/
|
||||||
public class BusyDialogTemplate implements Runnable, EventListener<Event> {
|
public class BusyDialogTemplate implements Runnable, EventListener<Event> {
|
||||||
|
|
||||||
|
/** Event to call {@link #runnable} **/
|
||||||
private static final String EVENT_NAME = "onRun";
|
private static final String EVENT_NAME = "onRun";
|
||||||
|
|
||||||
|
/** Task to be invoked **/
|
||||||
private Runnable runnable;
|
private Runnable runnable;
|
||||||
|
|
||||||
private BusyDialog busyDialog;
|
private BusyDialog busyDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param runnable
|
||||||
|
*/
|
||||||
public BusyDialogTemplate(Runnable runnable) {
|
public BusyDialogTemplate(Runnable runnable) {
|
||||||
this.runnable = runnable;
|
this.runnable = runnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide/dispose busy dialog
|
||||||
|
*/
|
||||||
private void hideBusyDialog() {
|
private void hideBusyDialog() {
|
||||||
if (busyDialog != null)
|
if (busyDialog != null)
|
||||||
{
|
{
|
||||||
|
@ -25,12 +63,19 @@ public class BusyDialogTemplate implements Runnable, EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show busy dialog in highlighted mode.
|
||||||
|
*/
|
||||||
private void showBusyDialog() {
|
private void showBusyDialog() {
|
||||||
busyDialog = new BusyDialog();
|
busyDialog = new BusyDialog();
|
||||||
busyDialog.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
|
busyDialog.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
|
||||||
AEnv.showCenterScreen(busyDialog);
|
AEnv.showCenterScreen(busyDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link #runnable} and close busy dialog.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
try {
|
try {
|
||||||
if (event.getName().equals(EVENT_NAME)) {
|
if (event.getName().equals(EVENT_NAME)) {
|
||||||
|
@ -41,6 +86,9 @@ public class BusyDialogTemplate implements Runnable, EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show busy dialog and echo {@link #EVENT_NAME} to call {@link #runnable}
|
||||||
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
showBusyDialog();
|
showBusyDialog();
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.compiere.model.MLookup;
|
||||||
import org.zkoss.zk.ui.Desktop;
|
import org.zkoss.zk.ui.Desktop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callout Dialog used for Ask For Input
|
* Callout Dialog used to ask for input from user.
|
||||||
*
|
*
|
||||||
* @author Murilo H. Torquato (devCoffee, http://devcoffee.com.br)
|
* @author Murilo H. Torquato (devCoffee, http://devcoffee.com.br)
|
||||||
*
|
*
|
||||||
|
@ -31,6 +31,10 @@ public class CalloutDialog implements ICalloutUI {
|
||||||
private Desktop desktop;
|
private Desktop desktop;
|
||||||
private int m_windowNo;
|
private int m_windowNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param desktop
|
||||||
|
* @param windowNo
|
||||||
|
*/
|
||||||
public CalloutDialog(Desktop desktop, int windowNo) {
|
public CalloutDialog(Desktop desktop, int windowNo) {
|
||||||
this.desktop = desktop;
|
this.desktop = desktop;
|
||||||
this.m_windowNo = windowNo;
|
this.m_windowNo = windowNo;
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
/**
|
/***********************************************************************
|
||||||
*
|
* 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 org.adempiere.webui.apps;
|
package org.adempiere.webui.apps;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
@ -14,10 +35,12 @@ import org.zkoss.zk.ui.Desktop;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DesktopRunnable implements Runnable {
|
public class DesktopRunnable implements Runnable {
|
||||||
|
/** wrapped runnable **/
|
||||||
private Runnable runnable;
|
private Runnable runnable;
|
||||||
|
/** weak reference to Desktop **/
|
||||||
private WeakReference<Desktop> desktopWeakRef;
|
private WeakReference<Desktop> desktopWeakRef;
|
||||||
|
|
||||||
|
/** ThreadLocal weak reference to Desktop **/
|
||||||
private static ThreadLocal<WeakReference<Desktop>> threadLocalDesktop = new ThreadLocal<WeakReference<Desktop>>() {
|
private static ThreadLocal<WeakReference<Desktop>> threadLocalDesktop = new ThreadLocal<WeakReference<Desktop>>() {
|
||||||
protected WeakReference<Desktop> initialValue()
|
protected WeakReference<Desktop> initialValue()
|
||||||
{
|
{
|
||||||
|
@ -25,13 +48,17 @@ public class DesktopRunnable implements Runnable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param runnable
|
||||||
|
* @param desktop
|
||||||
|
*/
|
||||||
public DesktopRunnable(Runnable runnable, Desktop desktop) {
|
public DesktopRunnable(Runnable runnable, Desktop desktop) {
|
||||||
this.runnable = runnable;
|
this.runnable = runnable;
|
||||||
this.desktopWeakRef = new WeakReference<Desktop>(desktop);
|
this.desktopWeakRef = new WeakReference<Desktop>(desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/**
|
||||||
* @see java.lang.Runnable#run()
|
* Set thread local Desktop reference and call {@link #runnable}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -53,20 +53,29 @@ import org.zkoss.zul.Vlayout;
|
||||||
*/
|
*/
|
||||||
public class DocumentSearchController implements EventListener<Event>{
|
public class DocumentSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
|
/** {@link A} component attribute to hold reference to corresponding {@link #SEARCH_RESULT} **/
|
||||||
private static final String SEARCH_RESULT = "search.result";
|
private static final String SEARCH_RESULT = "search.result";
|
||||||
private static final String ON_SEARCH_DOCUMENTS = "onSearchDocuments";
|
/** onSearchDocuments event **/
|
||||||
|
private static final String ON_SEARCH_DOCUMENTS_EVENT = "onSearchDocuments";
|
||||||
private int MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER = 3;
|
private int MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER = 3;
|
||||||
|
/** layout to show links ({@link A}) for each {@link #SEARCH_RESULT} in {@link #list} **/
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
|
/** results from execution of search **/
|
||||||
private ArrayList<SearchResult> list;
|
private ArrayList<SearchResult> list;
|
||||||
|
/** Current selected index of {@link #list} **/
|
||||||
private int selected = -1;
|
private int selected = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* default constructor
|
||||||
*/
|
*/
|
||||||
public DocumentSearchController() {
|
public DocumentSearchController() {
|
||||||
MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER = MSysConfig.getIntValue(MSysConfig.MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER, 3, Env.getAD_Client_ID(Env.getCtx()));
|
MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER = MSysConfig.getIntValue(MSysConfig.MAX_RESULTS_PER_SEARCH_IN_DOCUMENT_CONTROLLER, 3, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create {@link #layout} for search result
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
public void create(Component parent) {
|
public void create(Component parent) {
|
||||||
layout = new Vlayout();
|
layout = new Vlayout();
|
||||||
layout.setStyle("padding: 3px; overflow:auto;");
|
layout.setStyle("padding: 3px; overflow:auto;");
|
||||||
|
@ -75,14 +84,23 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
parent.appendChild(layout);
|
parent.appendChild(layout);
|
||||||
|
|
||||||
layout.addEventListener(ON_SEARCH_DOCUMENTS, this);
|
layout.addEventListener(ON_SEARCH_DOCUMENTS_EVENT, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo {@link #ON_SEARCH_DOCUMENTS_EVENT} with value as event data.
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
public void search(String value) {
|
public void search(String value) {
|
||||||
layout.getChildren().clear();
|
layout.getChildren().clear();
|
||||||
Events.echoEvent(ON_SEARCH_DOCUMENTS, layout, value);
|
Events.echoEvent(ON_SEARCH_DOCUMENTS_EVENT, layout, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle {@link #ON_SEARCH_DOCUMENTS_EVENT} event.
|
||||||
|
* Delegate execution of search to {@link #doSearch(String)}.
|
||||||
|
* @param searchString
|
||||||
|
*/
|
||||||
private void onSearchDocuments(String searchString) {
|
private void onSearchDocuments(String searchString) {
|
||||||
list = new ArrayList<SearchResult>();
|
list = new ArrayList<SearchResult>();
|
||||||
if (Util.isEmpty(searchString)) {
|
if (Util.isEmpty(searchString)) {
|
||||||
|
@ -119,6 +137,11 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform search with searchString using definition from AD_SearchDefinition.
|
||||||
|
* @param searchString
|
||||||
|
* @return List of {@link SearchResult}
|
||||||
|
*/
|
||||||
private List<SearchResult> doSearch(String searchString) {
|
private List<SearchResult> doSearch(String searchString) {
|
||||||
final MRole role = MRole.get(Env.getCtx(), Env.getAD_Role_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()), true);
|
final MRole role = MRole.get(Env.getCtx(), Env.getAD_Role_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()), true);
|
||||||
|
|
||||||
|
@ -199,6 +222,17 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute query and output result to list.
|
||||||
|
* @param msd
|
||||||
|
* @param builder
|
||||||
|
* @param params
|
||||||
|
* @param lookup
|
||||||
|
* @param window
|
||||||
|
* @param tableName
|
||||||
|
* @param extraWhereClase
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
private void doRetrieval(MSearchDefinition msd, StringBuilder builder, List<Object> params, MLookup lookup, MWindow window, String tableName,
|
private void doRetrieval(MSearchDefinition msd, StringBuilder builder, List<Object> params, MLookup lookup, MWindow window, String tableName,
|
||||||
String extraWhereClase, List<SearchResult> list) {
|
String extraWhereClase, List<SearchResult> list) {
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
|
@ -250,17 +284,24 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
SearchResult result = (SearchResult) event.getTarget().getAttribute(SEARCH_RESULT);
|
SearchResult result = (SearchResult) event.getTarget().getAttribute(SEARCH_RESULT);
|
||||||
doZoom(result);
|
doZoom(result);
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(ON_SEARCH_DOCUMENTS)) {
|
} else if (event.getName().equals(ON_SEARCH_DOCUMENTS_EVENT)) {
|
||||||
onSearchDocuments((String)event.getData());
|
onSearchDocuments((String)event.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zoom to AD Window
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
private void doZoom(SearchResult result) {
|
private void doZoom(SearchResult result) {
|
||||||
MQuery query = new MQuery();
|
MQuery query = new MQuery();
|
||||||
query.addRestriction(result.getTableName()+"_ID", "=", result.getRecordId());
|
query.addRestriction(result.getTableName()+"_ID", "=", result.getRecordId());
|
||||||
AEnv.zoom(result.getWindowId(), query);
|
AEnv.zoom(result.getWindowId(), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value class to hold search result
|
||||||
|
*/
|
||||||
public static class SearchResult {
|
public static class SearchResult {
|
||||||
private String windowName;
|
private String windowName;
|
||||||
private int windowId;
|
private int windowId;
|
||||||
|
@ -344,6 +385,13 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find {@link SearchResult} link from {@link #layout} that matches text from textbox.
|
||||||
|
* <br/>
|
||||||
|
* Call {@link #doZoom(SearchResult)} if a match is found.
|
||||||
|
* @param textbox
|
||||||
|
* @return true if a match is found
|
||||||
|
*/
|
||||||
public boolean onOk(Textbox textbox) {
|
public boolean onOk(Textbox textbox) {
|
||||||
String text = textbox.getText();
|
String text = textbox.getText();
|
||||||
if (Util.isEmpty(text))
|
if (Util.isEmpty(text))
|
||||||
|
@ -374,11 +422,16 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
result = (SearchResult) firstStart.getAttribute(SEARCH_RESULT);
|
result = (SearchResult) firstStart.getAttribute(SEARCH_RESULT);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
doZoom(result);
|
doZoom(result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select and return {@link SearchResult} that comes before the current selected {@link SearchResult} link in {@link #layout}.
|
||||||
|
* @return {@link SearchResult}
|
||||||
|
*/
|
||||||
public SearchResult selectPrior() {
|
public SearchResult selectPrior() {
|
||||||
if (selected > 0) {
|
if (selected > 0) {
|
||||||
selected--;
|
selected--;
|
||||||
|
@ -399,6 +452,10 @@ public class DocumentSearchController implements EventListener<Event>{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select and return {@link SearchResult} that comes after the current selected {@link SearchResult} link in {@link #layout}.
|
||||||
|
* @return {@link SearchResult}
|
||||||
|
*/
|
||||||
public SearchResult selectNext() {
|
public SearchResult selectNext() {
|
||||||
if (selected < (list.size()-1)) {
|
if (selected < (list.size()-1)) {
|
||||||
selected++;
|
selected++;
|
||||||
|
|
|
@ -64,7 +64,7 @@ import org.zkoss.zul.Div;
|
||||||
import org.zkoss.zul.South;
|
import org.zkoss.zul.South;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Window to capture feedback request from user.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -77,13 +77,19 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
|
|
||||||
private static final CLogger log = CLogger.getCLogger(FeedbackRequestWindow.class);
|
private static final CLogger log = CLogger.getCLogger(FeedbackRequestWindow.class);
|
||||||
|
|
||||||
|
/** Fields for {@link MRequest} **/
|
||||||
protected WTableDirEditor requestTypeField, priorityField, salesRepField;
|
protected WTableDirEditor requestTypeField, priorityField, salesRepField;
|
||||||
protected Textbox txtSummary;
|
protected Textbox txtSummary;
|
||||||
protected ConfirmPanel confirmPanel;
|
protected ConfirmPanel confirmPanel;
|
||||||
|
|
||||||
|
/** attachments uploaded by user **/
|
||||||
protected List<DataSource> attachments = new ArrayList<DataSource>();
|
protected List<DataSource> attachments = new ArrayList<DataSource>();
|
||||||
|
/** Div to host list of {@link AttachmentItem} **/
|
||||||
protected Div attachmentBox;
|
protected Div attachmentBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
public FeedbackRequestWindow() {
|
public FeedbackRequestWindow() {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
|
@ -114,6 +120,7 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
throw new RuntimeException(Msg.getMsg(Env.getCtx(), "AccessTableNoUpdate"));
|
throw new RuntimeException(Msg.getMsg(Env.getCtx(), "AccessTableNoUpdate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//layout window
|
||||||
Label lblRequestType = new Label(Msg.getElement(Env.getCtx(), "R_RequestType_ID"));
|
Label lblRequestType = new Label(Msg.getElement(Env.getCtx(), "R_RequestType_ID"));
|
||||||
Label lblPriority = new Label(Msg.getElement(Env.getCtx(), "Priority"));
|
Label lblPriority = new Label(Msg.getElement(Env.getCtx(), "Priority"));
|
||||||
Label lblSummary = new Label(Msg.getElement(Env.getCtx(), "Summary"));
|
Label lblSummary = new Label(Msg.getElement(Env.getCtx(), "Summary"));
|
||||||
|
@ -236,6 +243,7 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
addAttachment(FeedbackManager.getLogAttachment(false), false);
|
addAttachment(FeedbackManager.getLogAttachment(false), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event e) throws Exception {
|
public void onEvent(Event e) throws Exception {
|
||||||
if (e.getTarget() == confirmPanel.getButton(ConfirmPanel.A_OK)) {
|
if (e.getTarget() == confirmPanel.getButton(ConfirmPanel.A_OK)) {
|
||||||
Clients.clearBusy();
|
Clients.clearBusy();
|
||||||
|
@ -271,6 +279,10 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save request
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
protected void saveRequest() throws IOException {
|
protected void saveRequest() throws IOException {
|
||||||
Trx trx = Trx.get(Trx.createTrxName("SaveNewRequest"), true);
|
Trx trx = Trx.get(Trx.createTrxName("SaveNewRequest"), true);
|
||||||
trx.setDisplayName(getClass().getName()+"_saveRequest");
|
trx.setDisplayName(getClass().getName()+"_saveRequest");
|
||||||
|
@ -315,6 +327,11 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new MRequest record.
|
||||||
|
* @param trx
|
||||||
|
* @return {@link MRequest}
|
||||||
|
*/
|
||||||
protected MRequest createMRequest(Trx trx) {
|
protected MRequest createMRequest(Trx trx) {
|
||||||
MRequest request = new MRequest(Env.getCtx(), 0, trx.getTrxName());
|
MRequest request = new MRequest(Env.getCtx(), 0, trx.getTrxName());
|
||||||
request.setAD_Org_ID(Env.getAD_Org_ID(Env.getCtx()));
|
request.setAD_Org_ID(Env.getAD_Org_ID(Env.getCtx()));
|
||||||
|
@ -325,6 +342,11 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add attachment from user.
|
||||||
|
* @param dataSource
|
||||||
|
* @param removable
|
||||||
|
*/
|
||||||
public void addAttachment(DataSource dataSource, boolean removable) {
|
public void addAttachment(DataSource dataSource, boolean removable) {
|
||||||
attachments.add(dataSource);
|
attachments.add(dataSource);
|
||||||
AttachmentItem item = new AttachmentItem(dataSource, attachments, removable);
|
AttachmentItem item = new AttachmentItem(dataSource, attachments, removable);
|
||||||
|
@ -332,6 +354,11 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
getFirstChild().invalidate();
|
getFirstChild().invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get byte[] from media.
|
||||||
|
* @param media
|
||||||
|
* @return byte[]
|
||||||
|
*/
|
||||||
private byte[] getMediaData(Media media) {
|
private byte[] getMediaData(Media media) {
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
|
|
||||||
|
@ -358,6 +385,11 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get character set from contentType (i.e from charset=).
|
||||||
|
* @param contentType
|
||||||
|
* @return character set (default is UTF-8)
|
||||||
|
*/
|
||||||
private String getCharset(String contentType) {
|
private String getCharset(String contentType) {
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
int j = contentType.indexOf("charset=");
|
int j = contentType.indexOf("charset=");
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.adempiere.webui.component.Tabpanels;
|
||||||
import org.adempiere.webui.component.Tabs;
|
import org.adempiere.webui.component.Tabs;
|
||||||
import org.adempiere.webui.util.DocumentSearch;
|
import org.adempiere.webui.util.DocumentSearch;
|
||||||
import org.adempiere.webui.util.ZKUpdateUtil;
|
import org.adempiere.webui.util.ZKUpdateUtil;
|
||||||
|
import org.compiere.model.MSearchDefinition;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
|
@ -37,19 +38,27 @@ import org.zkoss.zul.Bandpopup;
|
||||||
import org.zkoss.zul.Div;
|
import org.zkoss.zul.Div;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Global search component at desktop header.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GlobalSearch extends Div implements EventListener<Event> {
|
public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
|
|
||||||
private static final String ON_ENTER_KEY = "onEnterKey";
|
/** {@link #bandbox} attribute to store value from last {@link Events#ON_CHANGING} event **/
|
||||||
|
private static final String LAST_ONCHANGING_ATTR = "last.onchanging";
|
||||||
|
|
||||||
private static final String ON_POST_ENTER_KEY = "onPostEnterKey";
|
/** Event send from client side upon keyDown of enter key **/
|
||||||
|
private static final String ON_ENTER_KEY_EVENT = "onEnterKey";
|
||||||
|
|
||||||
private static final String ON_CREATE_ECHO = "onCreateEcho";
|
/** Event echo from ON_ENTER_KEY_EVENT to allow showing of in progress dialog before execution of search **/
|
||||||
|
private static final String ON_POST_ENTER_KEY_EVENT = "onPostEnterKey";
|
||||||
|
|
||||||
private static final String ON_SEARCH = "onSearch";
|
/** Event echo from {@link #onPageAttached(Page, Page)} **/
|
||||||
|
private static final String ON_CREATE_ECHO_EVENT = "onCreateEcho";
|
||||||
|
|
||||||
|
/** Event to execute search. **/
|
||||||
|
private static final String ON_SEARCH_EVENT = "onSearch";
|
||||||
|
|
||||||
|
/** Prefix to start document search using definition from {@link MSearchDefinition} **/
|
||||||
private static final String PREFIX_DOCUMENT_SEARCH = "/";
|
private static final String PREFIX_DOCUMENT_SEARCH = "/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,15 +66,20 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -8793878697269469837L;
|
private static final long serialVersionUID = -8793878697269469837L;
|
||||||
|
|
||||||
|
/** Bandbox to capture search text from user and display result in popup **/
|
||||||
private Bandbox bandbox;
|
private Bandbox bandbox;
|
||||||
|
|
||||||
|
/** controller to search AD_Menu **/
|
||||||
private MenuSearchController menuController;
|
private MenuSearchController menuController;
|
||||||
|
|
||||||
|
/** controller to search tables **/
|
||||||
private DocumentSearchController docController;
|
private DocumentSearchController docController;
|
||||||
|
|
||||||
|
/** tabbox to host menu and document search tab **/
|
||||||
private Tabbox tabbox;
|
private Tabbox tabbox;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param menuController
|
||||||
*/
|
*/
|
||||||
public GlobalSearch(MenuSearchController menuController) {
|
public GlobalSearch(MenuSearchController menuController) {
|
||||||
this.menuController = menuController;
|
this.menuController = menuController;
|
||||||
|
@ -73,11 +87,13 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout UI and setup listeners
|
||||||
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
bandbox = new Bandbox();
|
bandbox = new Bandbox();
|
||||||
bandbox.setSclass("global-search-box");
|
bandbox.setSclass("global-search-box");
|
||||||
appendChild(bandbox);
|
appendChild(bandbox);
|
||||||
// ZKUpdateUtil.setWidth(bandbox, "100%");
|
|
||||||
bandbox.setAutodrop(true);
|
bandbox.setAutodrop(true);
|
||||||
bandbox.setId("globalSearchBox");
|
bandbox.setId("globalSearchBox");
|
||||||
bandbox.addEventListener(Events.ON_CHANGING, this);
|
bandbox.addEventListener(Events.ON_CHANGING, this);
|
||||||
|
@ -114,22 +130,24 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
tabPanels.appendChild(tabPanel);
|
tabPanels.appendChild(tabPanel);
|
||||||
docController.create(tabPanel);
|
docController.create(tabPanel);
|
||||||
|
|
||||||
addEventListener(ON_SEARCH, this);
|
addEventListener(ON_SEARCH_EVENT, this);
|
||||||
addEventListener(ON_CREATE_ECHO, this);
|
addEventListener(ON_CREATE_ECHO_EVENT, this);
|
||||||
bandbox.addEventListener(ON_ENTER_KEY, this);
|
bandbox.addEventListener(ON_ENTER_KEY_EVENT, this);
|
||||||
addEventListener(ON_POST_ENTER_KEY, this);
|
addEventListener(ON_POST_ENTER_KEY_EVENT, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (Events.ON_CHANGING.equals(event.getName())) {
|
if (Events.ON_CHANGING.equals(event.getName())) {
|
||||||
|
//post ON_SEARCH_EVENT for ON_CHANGING from bandbox
|
||||||
InputEvent inputEvent = (InputEvent) event;
|
InputEvent inputEvent = (InputEvent) event;
|
||||||
String value = inputEvent.getValue();
|
String value = inputEvent.getValue();
|
||||||
bandbox.setAttribute("last.onchanging", value);
|
bandbox.setAttribute(LAST_ONCHANGING_ATTR, value);
|
||||||
Events.postEvent(ON_SEARCH, this, value);
|
Events.postEvent(ON_SEARCH_EVENT, this, value);
|
||||||
} else if (Events.ON_CHANGE.equals(event.getName())) {
|
} else if (Events.ON_CHANGE.equals(event.getName())) {
|
||||||
bandbox.removeAttribute("last.onchanging");
|
bandbox.removeAttribute(LAST_ONCHANGING_ATTR);
|
||||||
} else if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
} else if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
||||||
|
//handle keyboard navigation for bandbox items
|
||||||
KeyEvent ke = (KeyEvent) event;
|
KeyEvent ke = (KeyEvent) event;
|
||||||
if (ke.getKeyCode() == KeyEvent.UP) {
|
if (ke.getKeyCode() == KeyEvent.UP) {
|
||||||
if (bandbox.getFirstChild().isVisible()) {
|
if (bandbox.getFirstChild().isVisible()) {
|
||||||
|
@ -160,28 +178,30 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(ON_SEARCH)) {
|
} else if (event.getName().equals(ON_SEARCH_EVENT)) {
|
||||||
String value = (String) event.getData();
|
String value = (String) event.getData();
|
||||||
if (tabbox.getSelectedIndex()==0)
|
if (tabbox.getSelectedIndex()==0)
|
||||||
menuController.search(value);
|
menuController.search(value);
|
||||||
else
|
else
|
||||||
docController.search(value);
|
docController.search(value);
|
||||||
bandbox.focus();
|
bandbox.focus();
|
||||||
} else if (event.getName().equals(ON_CREATE_ECHO)) {
|
} else if (event.getName().equals(ON_CREATE_ECHO_EVENT)) {
|
||||||
|
//setup client side listener for enter key
|
||||||
StringBuilder script = new StringBuilder("jq('#")
|
StringBuilder script = new StringBuilder("jq('#")
|
||||||
.append(bandbox.getUuid())
|
.append(bandbox.getUuid())
|
||||||
.append("').bind('keydown', function(e) {let code=e.keyCode||e.which;if(code==13){")
|
.append("').bind('keydown', function(e) {let code=e.keyCode||e.which;if(code==13){")
|
||||||
.append("let widget=zk.Widget.$(this);")
|
.append("let widget=zk.Widget.$(this);")
|
||||||
.append("let event=new zk.Event(widget,'")
|
.append("let event=new zk.Event(widget,'")
|
||||||
.append(ON_ENTER_KEY)
|
.append(ON_ENTER_KEY_EVENT)
|
||||||
.append("',{},{toServer:true});")
|
.append("',{},{toServer:true});")
|
||||||
.append("zAu.send(event);")
|
.append("zAu.send(event);")
|
||||||
.append("}});");
|
.append("}});");
|
||||||
Clients.evalJavaScript(script.toString());
|
Clients.evalJavaScript(script.toString());
|
||||||
} else if (event.getName().equals(ON_ENTER_KEY)) {
|
} else if (event.getName().equals(ON_ENTER_KEY_EVENT)) {
|
||||||
Clients.showBusy(bandbox, null);
|
Clients.showBusy(bandbox, null);
|
||||||
Events.echoEvent(ON_POST_ENTER_KEY, this, null);
|
Events.echoEvent(ON_POST_ENTER_KEY_EVENT, this, null);
|
||||||
} else if (event.getName().equals(ON_POST_ENTER_KEY)) {
|
} else if (event.getName().equals(ON_POST_ENTER_KEY_EVENT)) {
|
||||||
|
//execute search trigger by press of enter key
|
||||||
Clients.clearBusy(bandbox);
|
Clients.clearBusy(bandbox);
|
||||||
if (bandbox.getValue() != null && bandbox.getValue().startsWith(PREFIX_DOCUMENT_SEARCH)) {
|
if (bandbox.getValue() != null && bandbox.getValue().startsWith(PREFIX_DOCUMENT_SEARCH)) {
|
||||||
DocumentSearch search = new DocumentSearch();
|
DocumentSearch search = new DocumentSearch();
|
||||||
|
@ -195,11 +215,11 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(Events.ON_SELECT)) {
|
} else if (event.getName().equals(Events.ON_SELECT)) {
|
||||||
String value = (String) bandbox.getAttribute("last.onchanging");
|
String value = (String) bandbox.getAttribute(LAST_ONCHANGING_ATTR);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = bandbox.getValue();
|
value = bandbox.getValue();
|
||||||
}
|
}
|
||||||
Events.postEvent(ON_SEARCH, this, value);
|
Events.postEvent(ON_SEARCH_EVENT, this, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,15 +229,21 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
@Override
|
@Override
|
||||||
public void onPageAttached(Page newpage, Page oldpage) {
|
public void onPageAttached(Page newpage, Page oldpage) {
|
||||||
super.onPageAttached(newpage, oldpage);
|
super.onPageAttached(newpage, oldpage);
|
||||||
Events.echoEvent(ON_CREATE_ECHO, this, null);
|
Events.echoEvent(ON_CREATE_ECHO_EVENT, this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close {@link #bandbox} popup.
|
||||||
|
*/
|
||||||
public void closePopup() {
|
public void closePopup() {
|
||||||
if (bandbox != null) {
|
if (bandbox != null) {
|
||||||
bandbox.close();
|
bandbox.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle client info event from browser.
|
||||||
|
*/
|
||||||
public void onClientInfo() {
|
public void onClientInfo() {
|
||||||
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50);
|
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,15 +38,21 @@ import org.zkoss.zul.Center;
|
||||||
import org.zkoss.zul.Div;
|
import org.zkoss.zul.Div;
|
||||||
import org.zkoss.zul.Html;
|
import org.zkoss.zul.Html;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help for AD Window with contents generated from AD definition.
|
||||||
|
*/
|
||||||
public class HelpWindow extends Window {
|
public class HelpWindow extends Window {
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -7353411576541612026L;
|
private static final long serialVersionUID = -7353411576541612026L;
|
||||||
|
|
||||||
private GridWindow gridWindow;
|
private GridWindow gridWindow;
|
||||||
private String winpref;
|
private String winpref;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gridWindow
|
||||||
|
*/
|
||||||
public HelpWindow(GridWindow gridWindow)
|
public HelpWindow(GridWindow gridWindow)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
@ -95,6 +101,9 @@ public class HelpWindow extends Window {
|
||||||
html.setContent(doc.toString());
|
html.setContent(doc.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return header {@link table}
|
||||||
|
*/
|
||||||
private table getHeader()
|
private table getHeader()
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -180,6 +189,9 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return content {@link table}
|
||||||
|
*/
|
||||||
private table getContent()
|
private table getContent()
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -202,6 +214,9 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return content {@link table} for left pane
|
||||||
|
*/
|
||||||
private table getLeftContent()
|
private table getLeftContent()
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -223,6 +238,9 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return content {@link table} for right pane
|
||||||
|
*/
|
||||||
private table getRightContent()
|
private table getRightContent()
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -273,6 +291,12 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name, description and help text for AD_Tab
|
||||||
|
* @param tab
|
||||||
|
* @param tabIndex
|
||||||
|
* @return {@link table} with name, description and help text
|
||||||
|
*/
|
||||||
private table getTabBox(GridTab tab, int tabIndex)
|
private table getTabBox(GridTab tab, int tabIndex)
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -326,6 +350,12 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links for all display field
|
||||||
|
* @param tab
|
||||||
|
* @param tabIndex
|
||||||
|
* @return {@link table} with link for all display fields
|
||||||
|
*/
|
||||||
private table getFieldsBox(GridTab tab, int tabIndex)
|
private table getFieldsBox(GridTab tab, int tabIndex)
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
@ -383,6 +413,13 @@ public class HelpWindow extends Window {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* header/label, description and help text for a field.
|
||||||
|
* @param field
|
||||||
|
* @param tabIndex
|
||||||
|
* @param fieldIndex
|
||||||
|
* @return {@link table} with header/label, description and help text
|
||||||
|
*/
|
||||||
private table getFieldBox(GridField field, int tabIndex, int fieldIndex)
|
private table getFieldBox(GridField field, int tabIndex, int fieldIndex)
|
||||||
{
|
{
|
||||||
table table = new table("0", "0", "0", "100%", null);
|
table table = new table("0", "0", "0", "100%", null);
|
||||||
|
|
|
@ -17,7 +17,7 @@ import org.adempiere.webui.editor.WEditor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener interface for process parameter panel.
|
* Listener interface for process parameter panel.
|
||||||
* Implementation must be thread safe
|
* Implementation must be thread safe.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,16 +42,29 @@ import org.zkoss.zk.ui.util.Clients;
|
||||||
import org.zkoss.zul.Bandpopup;
|
import org.zkoss.zul.Bandpopup;
|
||||||
import org.zkoss.zul.Div;
|
import org.zkoss.zul.Div;
|
||||||
|
|
||||||
public class LabelsSearch extends Div implements EventListener<Event> {
|
/**
|
||||||
|
* Component to search AD_Label* records.
|
||||||
|
*/
|
||||||
|
public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
private static final long serialVersionUID = -8793878697269469837L;
|
private static final long serialVersionUID = -8793878697269469837L;
|
||||||
private static final String ON_ENTER_KEY = "onEnterKey";
|
/** Event send from client side upon keyDown of enter key **/
|
||||||
private static final String ON_CREATE_ECHO = "onCreateEcho";
|
private static final String ON_ENTER_KEY_EVENT = "onEnterKey";
|
||||||
private static final String ON_SEARCH = "onSearch";
|
/** Event echo from {@link #onPageAttached(Page, Page)} **/
|
||||||
private Bandbox bandbox;
|
private static final String ON_CREATE_ECHO_EVENT = "onCreateEcho";
|
||||||
|
/** Event to execute search. **/
|
||||||
|
private static final String ON_SEARCH_EVENT = "onSearch";
|
||||||
|
/** {@link #bandbox} attribute to store value from last {@link Events#ON_CHANGING} event **/
|
||||||
|
private static final String LAST_ONCHANGING_ATTR = "last.onchanging";
|
||||||
|
/** Bandbox to capture search text from user and display result in popup **/
|
||||||
|
private Bandbox bandbox;
|
||||||
|
/** Controller to perform search on AD_Label* records **/
|
||||||
private LabelsSearchController controller;
|
private LabelsSearchController controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard constructot
|
* Standard constructor
|
||||||
* @param controller
|
* @param controller
|
||||||
*/
|
*/
|
||||||
public LabelsSearch(LabelsSearchController controller) {
|
public LabelsSearch(LabelsSearchController controller) {
|
||||||
|
@ -59,6 +72,9 @@ public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout UI and setup listeners
|
||||||
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
bandbox = new Bandbox();
|
bandbox = new Bandbox();
|
||||||
appendChild(bandbox);
|
appendChild(bandbox);
|
||||||
|
@ -77,22 +93,24 @@ public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
bandbox.appendChild(popup);
|
bandbox.appendChild(popup);
|
||||||
controller.create(popup);
|
controller.create(popup);
|
||||||
|
|
||||||
addEventListener(ON_SEARCH, this);
|
addEventListener(ON_SEARCH_EVENT, this);
|
||||||
addEventListener(ON_CREATE_ECHO, this);
|
addEventListener(ON_CREATE_ECHO_EVENT, this);
|
||||||
addEventListener(LabelsSearchController.ON_POST_SELECT_LABELITEM_EVENT, this);
|
addEventListener(LabelsSearchController.ON_POST_SELECT_LABELITEM_EVENT, this);
|
||||||
bandbox.addEventListener(ON_ENTER_KEY, this);
|
bandbox.addEventListener(ON_ENTER_KEY_EVENT, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (Events.ON_CHANGING.equals(event.getName())) {
|
if (Events.ON_CHANGING.equals(event.getName())) {
|
||||||
|
//post ON_SEARCH_EVENT for ON_CHANGING event from bandbox
|
||||||
InputEvent inputEvent = (InputEvent) event;
|
InputEvent inputEvent = (InputEvent) event;
|
||||||
String value = inputEvent.getValue();
|
String value = inputEvent.getValue();
|
||||||
bandbox.setAttribute("last.onchanging", value);
|
bandbox.setAttribute(LAST_ONCHANGING_ATTR, value);
|
||||||
Events.postEvent(ON_SEARCH, this, value);
|
Events.postEvent(ON_SEARCH_EVENT, this, value);
|
||||||
} else if (Events.ON_CHANGE.equals(event.getName())) {
|
} else if (Events.ON_CHANGE.equals(event.getName())) {
|
||||||
bandbox.removeAttribute("last.onchanging");
|
bandbox.removeAttribute(LAST_ONCHANGING_ATTR);
|
||||||
} else if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
} else if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
||||||
|
//handle keyboard navigation for bandbox items
|
||||||
KeyEvent ke = (KeyEvent) event;
|
KeyEvent ke = (KeyEvent) event;
|
||||||
if (ke.getKeyCode() == KeyEvent.UP) {
|
if (ke.getKeyCode() == KeyEvent.UP) {
|
||||||
if (bandbox.getFirstChild().isVisible()) {
|
if (bandbox.getFirstChild().isVisible()) {
|
||||||
|
@ -111,32 +129,33 @@ public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(ON_SEARCH)) {
|
} else if (event.getName().equals(ON_SEARCH_EVENT)) {
|
||||||
String value = (String) event.getData();
|
String value = (String) event.getData();
|
||||||
controller.search(value);
|
controller.search(value);
|
||||||
bandbox.focus();
|
bandbox.focus();
|
||||||
} else if (event.getName().equals(ON_CREATE_ECHO)) {
|
} else if (event.getName().equals(ON_CREATE_ECHO_EVENT)) {
|
||||||
|
//setup client side keyDown listener for enter key
|
||||||
StringBuilder script = new StringBuilder("jq('#")
|
StringBuilder script = new StringBuilder("jq('#")
|
||||||
.append(bandbox.getUuid())
|
.append(bandbox.getUuid())
|
||||||
.append("').bind('keydown', function(e) {var code=e.keyCode||e.which;if(code==13){")
|
.append("').bind('keydown', function(e) {var code=e.keyCode||e.which;if(code==13){")
|
||||||
.append("var widget=zk.Widget.$(this);")
|
.append("var widget=zk.Widget.$(this);")
|
||||||
.append("var event=new zk.Event(widget,'")
|
.append("var event=new zk.Event(widget,'")
|
||||||
.append(ON_ENTER_KEY)
|
.append(ON_ENTER_KEY_EVENT)
|
||||||
.append("',{},{toServer:true});")
|
.append("',{},{toServer:true});")
|
||||||
.append("zAu.send(event);")
|
.append("zAu.send(event);")
|
||||||
.append("}});");
|
.append("}});");
|
||||||
Clients.evalJavaScript(script.toString());
|
Clients.evalJavaScript(script.toString());
|
||||||
} else if (event.getName().equals(ON_ENTER_KEY)) {
|
} else if (event.getName().equals(ON_ENTER_KEY_EVENT)) {
|
||||||
if (event.getTarget() instanceof Bandbox) {
|
if (event.getTarget() instanceof Bandbox) {
|
||||||
controller.onSelect(controller.getSelectedItem());
|
controller.onSelect(controller.getSelectedItem());
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(Events.ON_SELECT)) {
|
} else if (event.getName().equals(Events.ON_SELECT)) {
|
||||||
String value = (String) bandbox.getAttribute("last.onchanging");
|
String value = (String) bandbox.getAttribute(LAST_ONCHANGING_ATTR);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = bandbox.getValue();
|
value = bandbox.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.postEvent(ON_SEARCH, this, value);
|
Events.postEvent(ON_SEARCH_EVENT, this, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getName().equals(LabelsSearchController.ON_POST_SELECT_LABELITEM_EVENT)) {
|
if (event.getName().equals(LabelsSearchController.ON_POST_SELECT_LABELITEM_EVENT)) {
|
||||||
|
@ -150,11 +169,11 @@ public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
@Override
|
@Override
|
||||||
public void onPageAttached(Page newpage, Page oldpage) {
|
public void onPageAttached(Page newpage, Page oldpage) {
|
||||||
super.onPageAttached(newpage, oldpage);
|
super.onPageAttached(newpage, oldpage);
|
||||||
Events.echoEvent(ON_CREATE_ECHO, this, null);
|
Events.echoEvent(ON_CREATE_ECHO_EVENT, this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the search dropdown
|
* Close {@link #bandbox} popup
|
||||||
*/
|
*/
|
||||||
public void closePopup() {
|
public void closePopup() {
|
||||||
if (bandbox != null) {
|
if (bandbox != null) {
|
||||||
|
@ -163,7 +182,7 @@ public class LabelsSearch extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set height of the search dropdown
|
* Set height {@link #bandbox} dropdown
|
||||||
*/
|
*/
|
||||||
public void onClientInfo() {
|
public void onClientInfo() {
|
||||||
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50);
|
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50);
|
||||||
|
|
|
@ -56,14 +56,25 @@ import org.zkoss.zul.ListitemRenderer;
|
||||||
import org.zkoss.zul.ListitemRendererExt;
|
import org.zkoss.zul.ListitemRendererExt;
|
||||||
import org.zkoss.zul.Vlayout;
|
import org.zkoss.zul.Vlayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for search on AD_Label* records.
|
||||||
|
*/
|
||||||
public class LabelsSearchController implements EventListener<Event>{
|
public class LabelsSearchController implements EventListener<Event>{
|
||||||
|
/** Event echo from {@link #onSelect(LabelItem)} **/
|
||||||
public static final String ON_POST_SELECT_LABELITEM_EVENT = "onPostSelectLabelitem";
|
public static final String ON_POST_SELECT_LABELITEM_EVENT = "onPostSelectLabelitem";
|
||||||
private static final String ON_SEARCH_ECHO = "onSearchEcho";
|
/** Event echo to initiate search for a given input text **/
|
||||||
private static final String ON_LOAD_MORE = "onLoadMore";
|
private static final String ON_SEARCH_ECHO_EVENT = "onSearchEcho";
|
||||||
|
/** TODO: not used, candidate for removal **/
|
||||||
|
private static final String ON_LOAD_MORE_EVENT = "onLoadMore";
|
||||||
|
/** parent of {@link #layout} **/
|
||||||
private Component parent;
|
private Component parent;
|
||||||
|
/** Listbox to display search result **/
|
||||||
private Listbox listbox;
|
private Listbox listbox;
|
||||||
|
/** model for {@link #listbox} **/
|
||||||
private ListModelList<LabelItem> model;
|
private ListModelList<LabelItem> model;
|
||||||
|
/** main layout **/
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
|
/** label window panel, provider for AD_Table_ID and Record_ID **/
|
||||||
private LabelsPanel labelsPanel;
|
private LabelsPanel labelsPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,13 +114,13 @@ public class LabelsSearchController implements EventListener<Event>{
|
||||||
ZKUpdateUtil.setWidth(listheader, "30px");
|
ZKUpdateUtil.setWidth(listheader, "30px");
|
||||||
listhead.appendChild(listheader);
|
listhead.appendChild(listheader);
|
||||||
|
|
||||||
layout.addEventListener(ON_SEARCH_ECHO, this);
|
layout.addEventListener(ON_SEARCH_ECHO_EVENT, this);
|
||||||
layout.addEventListener(ON_LOAD_MORE, this);
|
layout.addEventListener(ON_LOAD_MORE_EVENT, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (event.getName().equals(ON_SEARCH_ECHO)) {
|
if (event.getName().equals(ON_SEARCH_ECHO_EVENT)) {
|
||||||
onSearchEcho((String) event.getData());
|
onSearchEcho((String) event.getData());
|
||||||
} else if (Events.ON_CLICK.equals(event.getName())) {
|
} else if (Events.ON_CLICK.equals(event.getName())) {
|
||||||
if (event.getTarget() instanceof ListItem) {
|
if (event.getTarget() instanceof ListItem) {
|
||||||
|
@ -121,16 +132,16 @@ public class LabelsSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for a given text
|
* Echo {@link #ON_SEARCH_ECHO_EVENT} to initiate search for value
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
public void search(String value) {
|
public void search(String value) {
|
||||||
listbox.setModel((ListModel<?>)null);
|
listbox.setModel((ListModel<?>)null);
|
||||||
Events.echoEvent(ON_SEARCH_ECHO, layout, value);
|
Events.echoEvent(ON_SEARCH_ECHO_EVENT, layout, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for a given text
|
* Handle {@link #ON_SEARCH_ECHO_EVENT} to execute search for a given text
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
public void onSearchEcho(String value) {
|
public void onSearchEcho(String value) {
|
||||||
|
|
|
@ -1,22 +1,50 @@
|
||||||
/**
|
/***********************************************************************
|
||||||
*
|
* 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 org.adempiere.webui.apps;
|
package org.adempiere.webui.apps;
|
||||||
|
|
||||||
|
import org.zkoss.zul.DefaultTreeNode;
|
||||||
|
import org.zkoss.zul.Treeitem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Value object for AD_Menu.
|
||||||
|
* <br/>
|
||||||
|
* Use by {@link GlobalSearch} and {@link MenuSearchController}.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class MenuItem {
|
public class MenuItem {
|
||||||
|
|
||||||
private String label;
|
private String label;
|
||||||
private String description;
|
private String description;
|
||||||
private String image;
|
private String image;
|
||||||
|
/** report, process, workflow, form, info or window **/
|
||||||
private String type;
|
private String type;
|
||||||
|
/** Corresponding {@link Treeitem} or {@link DefaultTreeNode} **/
|
||||||
private Object data;
|
private Object data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* default constructor
|
||||||
*/
|
*/
|
||||||
public MenuItem() {
|
public MenuItem() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,41 +55,60 @@ import org.zkoss.zul.Textbox;
|
||||||
import org.zkoss.zul.Tree;
|
import org.zkoss.zul.Tree;
|
||||||
import org.zkoss.zul.Treechildren;
|
import org.zkoss.zul.Treechildren;
|
||||||
import org.zkoss.zul.Treeitem;
|
import org.zkoss.zul.Treeitem;
|
||||||
|
import org.zkoss.zul.Treerow;
|
||||||
import org.zkoss.zul.Vlayout;
|
import org.zkoss.zul.Vlayout;
|
||||||
import org.zkoss.zul.impl.LabelElement;
|
import org.zkoss.zul.impl.LabelElement;
|
||||||
import org.zkoss.zul.impl.LabelImageElement;
|
import org.zkoss.zul.impl.LabelImageElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Controller for search on AD_Menu records.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class MenuSearchController implements EventListener<Event>{
|
public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
|
/** Component attribute to hold reference of {@link MTreeNode} **/
|
||||||
public static final String M_TREE_NODE_ATTR = "MTreeNode";
|
public static final String M_TREE_NODE_ATTR = "MTreeNode";
|
||||||
|
|
||||||
|
/** font icon sclass for already added to favourite menu item **/
|
||||||
private static final String Z_ICON_STAR_O = "z-icon-star-o";
|
private static final String Z_ICON_STAR_O = "z-icon-star-o";
|
||||||
|
/** font icon sclass for not yet added to favourite menu item **/
|
||||||
private static final String Z_ICON_STAR = "z-icon-star";
|
private static final String Z_ICON_STAR = "z-icon-star";
|
||||||
private static final String ON_SEARCH_ECHO = "onSearchEcho";
|
/** Event echo from {@link #search(String)} to initiate search action **/
|
||||||
private static final String ON_LOAD_MORE = "onLoadMore";
|
private static final String ON_SEARCH_ECHO_EVENT = "onSearchEcho";
|
||||||
private static final String ONSELECT_TIMESTAMP = "onselect.timestamp";
|
/** Event to load all menu items into {@link #listbox}. Default is to load the first 50 only. **/
|
||||||
|
private static final String ON_LOAD_MORE_EVENT = "onLoadMore";
|
||||||
|
/** {@link Listitem} attribute to store the last timestamp of ON_CLICK or ON_SELECT event **/
|
||||||
|
private static final String ONSELECT_TIMESTAMP_ATTR = "onselect.timestamp";
|
||||||
|
/** name of star button **/
|
||||||
private static final String STAR_BUTTON_NAME = "Star";
|
private static final String STAR_BUTTON_NAME = "Star";
|
||||||
|
/** name of new button **/
|
||||||
private static final String NEW_BUTTON_NAME = "New";
|
private static final String NEW_BUTTON_NAME = "New";
|
||||||
|
/** tree for AD_Menu **/
|
||||||
private Tree tree;
|
private Tree tree;
|
||||||
|
/** list box for menu items **/
|
||||||
private Listbox listbox;
|
private Listbox listbox;
|
||||||
|
/** model for all menu items **/
|
||||||
private ListModelList<MenuItem> model;
|
private ListModelList<MenuItem> model;
|
||||||
|
/** main layout component. parent of {@link #listbox}. **/
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
|
/** model for all menu items **/
|
||||||
private ListModelList<MenuItem> fullModel;
|
private ListModelList<MenuItem> fullModel;
|
||||||
|
/** true when controller is handling event from Star/Favourite button **/
|
||||||
private boolean inStarEvent;
|
private boolean inStarEvent;
|
||||||
|
|
||||||
|
/** Event post from {@link #selectTreeitem(Object, Boolean)} **/
|
||||||
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param tree
|
||||||
*/
|
*/
|
||||||
public MenuSearchController(Tree tree) {
|
public MenuSearchController(Tree tree) {
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate {@link #model} from {@link #tree}
|
||||||
|
*/
|
||||||
public void refreshModel() {
|
public void refreshModel() {
|
||||||
final List<MenuItem> list = new ArrayList<MenuItem>();
|
final List<MenuItem> list = new ArrayList<MenuItem>();
|
||||||
if (tree.getModel() == null) {
|
if (tree.getModel() == null) {
|
||||||
|
@ -116,6 +135,11 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add treeNode to list
|
||||||
|
* @param list
|
||||||
|
* @param treeNode
|
||||||
|
*/
|
||||||
private void addTreeItem(List<MenuItem> list, DefaultTreeNode<?> treeNode) {
|
private void addTreeItem(List<MenuItem> list, DefaultTreeNode<?> treeNode) {
|
||||||
MTreeNode mNode = (MTreeNode) treeNode.getData();
|
MTreeNode mNode = (MTreeNode) treeNode.getData();
|
||||||
if (!mNode.isLeaf())
|
if (!mNode.isLeaf())
|
||||||
|
@ -129,6 +153,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
list.add(item);
|
list.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param treeItem
|
||||||
|
* @return true if treeItem is a folder
|
||||||
|
*/
|
||||||
private boolean isFolder(Treeitem treeItem) {
|
private boolean isFolder(Treeitem treeItem) {
|
||||||
List<Component> list = treeItem.getChildren();
|
List<Component> list = treeItem.getChildren();
|
||||||
for (Component c : list) {
|
for (Component c : list) {
|
||||||
|
@ -139,6 +167,11 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add treeItem to list
|
||||||
|
* @param list
|
||||||
|
* @param treeItem
|
||||||
|
*/
|
||||||
private void addTreeItem(List<MenuItem> list, Treeitem treeItem) {
|
private void addTreeItem(List<MenuItem> list, Treeitem treeItem) {
|
||||||
if (isFolder(treeItem))
|
if (isFolder(treeItem))
|
||||||
return;
|
return;
|
||||||
|
@ -158,6 +191,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
item.setType((String) treeItem.getAttribute(AbstractMenuPanel.MENU_TYPE_ATTRIBUTE));
|
item.setType((String) treeItem.getAttribute(AbstractMenuPanel.MENU_TYPE_ATTRIBUTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param treeItem
|
||||||
|
* @return label for treeItem
|
||||||
|
*/
|
||||||
private String getLabel(Treeitem treeItem) {
|
private String getLabel(Treeitem treeItem) {
|
||||||
String label = treeItem.getLabel();
|
String label = treeItem.getLabel();
|
||||||
if (label == null || label.trim().length() == 0)
|
if (label == null || label.trim().length() == 0)
|
||||||
|
@ -172,6 +209,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param treeItem
|
||||||
|
* @return image url or font icon sclass (start with z-icon)
|
||||||
|
*/
|
||||||
private String getImage(Treeitem treeItem) {
|
private String getImage(Treeitem treeItem) {
|
||||||
String image = treeItem.getImage();
|
String image = treeItem.getImage();
|
||||||
if (image == null || image.trim().length() == 0)
|
if (image == null || image.trim().length() == 0)
|
||||||
|
@ -189,6 +230,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return image != null ? image.intern() : null;
|
return image != null ? image.intern() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link #refreshModel()} and layout UI.
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
public void create(Component parent) {
|
public void create(Component parent) {
|
||||||
refreshModel();
|
refreshModel();
|
||||||
|
|
||||||
|
@ -220,8 +265,8 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
ZKUpdateUtil.setWidth(listheader, "28px");
|
ZKUpdateUtil.setWidth(listheader, "28px");
|
||||||
listhead.appendChild(listheader);
|
listhead.appendChild(listheader);
|
||||||
|
|
||||||
layout.addEventListener(ON_SEARCH_ECHO, this);
|
layout.addEventListener(ON_SEARCH_ECHO_EVENT, this);
|
||||||
layout.addEventListener(ON_LOAD_MORE, this);
|
layout.addEventListener(ON_LOAD_MORE_EVENT, this);
|
||||||
updateListboxModel(model);
|
updateListboxModel(model);
|
||||||
|
|
||||||
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
@ -240,7 +285,7 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
} else if (Events.ON_CLICK.equals(event.getName())) {
|
} else if (Events.ON_CLICK.equals(event.getName())) {
|
||||||
if (event.getTarget() instanceof ListItem) {
|
if (event.getTarget() instanceof ListItem) {
|
||||||
ListItem item = (ListItem) event.getTarget();
|
ListItem item = (ListItem) event.getTarget();
|
||||||
Long onSelect = (Long) item.getAttribute(ONSELECT_TIMESTAMP);
|
Long onSelect = (Long) item.getAttribute(ONSELECT_TIMESTAMP_ATTR);
|
||||||
if (onSelect == null) {
|
if (onSelect == null) {
|
||||||
onSelect(item, Boolean.FALSE);
|
onSelect(item, Boolean.FALSE);
|
||||||
} else if (System.currentTimeMillis() - onSelect.longValue() > 1000) {
|
} else if (System.currentTimeMillis() - onSelect.longValue() > 1000) {
|
||||||
|
@ -276,9 +321,9 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
inStarEvent = false;
|
inStarEvent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(ON_SEARCH_ECHO)) {
|
} else if (event.getName().equals(ON_SEARCH_ECHO_EVENT)) {
|
||||||
onSearchEcho((String) event.getData());
|
onSearchEcho((String) event.getData());
|
||||||
} else if (event.getName().equals(ON_LOAD_MORE)) {
|
} else if (event.getName().equals(ON_LOAD_MORE_EVENT)) {
|
||||||
loadMore();
|
loadMore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,13 +342,19 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
listbox.setModel(t);
|
listbox.setModel(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo {@link #ON_LOAD_MORE_EVENT} if selected is of type "...".
|
||||||
|
* Otherwise delegate to {@link #selectTreeitem(Object, Boolean)}.
|
||||||
|
* @param selected
|
||||||
|
* @param newRecord true if event is originated from new record button
|
||||||
|
*/
|
||||||
private void onSelect(ListItem selected, Boolean newRecord) {
|
private void onSelect(ListItem selected, Boolean newRecord) {
|
||||||
MenuItem item = selected.getValue();
|
MenuItem item = selected.getValue();
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
if ("...".equals(item.getType())) {
|
if ("...".equals(item.getType())) {
|
||||||
selected.setAttribute(ONSELECT_TIMESTAMP, System.currentTimeMillis());
|
selected.setAttribute(ONSELECT_TIMESTAMP_ATTR, System.currentTimeMillis());
|
||||||
Clients.showBusy(selected, null);
|
Clients.showBusy(selected, null);
|
||||||
Events.echoEvent(ON_LOAD_MORE, layout, null);
|
Events.echoEvent(ON_LOAD_MORE_EVENT, layout, null);
|
||||||
} else {
|
} else {
|
||||||
if (newRecord) {
|
if (newRecord) {
|
||||||
Treeitem ti = (Treeitem)item.getData();
|
Treeitem ti = (Treeitem)item.getData();
|
||||||
|
@ -312,10 +363,14 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
newRecord = false;
|
newRecord = false;
|
||||||
}
|
}
|
||||||
selectTreeitem(item.getData(), newRecord);
|
selectTreeitem(item.getData(), newRecord);
|
||||||
selected.setAttribute(ONSELECT_TIMESTAMP, System.currentTimeMillis());
|
selected.setAttribute(ONSELECT_TIMESTAMP_ATTR, System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load {@link #fullModel} to {@link #listbox}.
|
||||||
|
* Only first 50 loaded to {@link #listbox} initially.
|
||||||
|
*/
|
||||||
private void loadMore() {
|
private void loadMore() {
|
||||||
ListModel<MenuItem> listModel = listbox.getModel();
|
ListModel<MenuItem> listModel = listbox.getModel();
|
||||||
ListModelList<MenuItem> lml = (ListModelList<MenuItem>) listModel;
|
ListModelList<MenuItem> lml = (ListModelList<MenuItem>) listModel;
|
||||||
|
@ -327,6 +382,11 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
Clients.scrollIntoView(listbox.getSelectedItem());
|
Clients.scrollIntoView(listbox.getSelectedItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link #select(Treeitem)} and post {@link #ON_POST_SELECT_TREEITEM_EVENT} event.
|
||||||
|
* @param node {@link Treeitem} or {@link DefaultTreeNode}
|
||||||
|
* @param newRecord
|
||||||
|
*/
|
||||||
private void selectTreeitem(Object node, Boolean newRecord) {
|
private void selectTreeitem(Object node, Boolean newRecord) {
|
||||||
if (Executions.getCurrent().getAttribute(listbox.getUuid()+".selectTreeitem") != null)
|
if (Executions.getCurrent().getAttribute(listbox.getUuid()+".selectTreeitem") != null)
|
||||||
return;
|
return;
|
||||||
|
@ -350,6 +410,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure all parent node is open and ensure tree selected item is selectedItem
|
||||||
|
* @param selectedItem
|
||||||
|
*/
|
||||||
private void select(Treeitem selectedItem) {
|
private void select(Treeitem selectedItem) {
|
||||||
Treeitem parent = selectedItem.getParentItem();
|
Treeitem parent = selectedItem.getParentItem();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -361,6 +425,11 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
selectedItem.getTree().setSelectedItem(selectedItem);
|
selectedItem.getTree().setSelectedItem(selectedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle {@link #ON_POST_SELECT_TREEITEM_EVENT} event.
|
||||||
|
* Post ON_CLICK event to link ({@link A} or {@link Treerow}).
|
||||||
|
* @param newRecord
|
||||||
|
*/
|
||||||
private void onPostSelectTreeitem(Boolean newRecord) {
|
private void onPostSelectTreeitem(Boolean newRecord) {
|
||||||
Event event = null;
|
Event event = null;
|
||||||
if (tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild() instanceof A)
|
if (tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild() instanceof A)
|
||||||
|
@ -374,11 +443,19 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
Events.postEvent(event);
|
Events.postEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo {@link #ON_SEARCH_ECHO_EVENT} to initial search with value.
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
public void search(String value) {
|
public void search(String value) {
|
||||||
listbox.setModel((ListModel<?>)null);
|
listbox.setModel((ListModel<?>)null);
|
||||||
Events.echoEvent(ON_SEARCH_ECHO, layout, value);
|
Events.echoEvent(ON_SEARCH_ECHO_EVENT, layout, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle {@link #ON_SEARCH_ECHO_EVENT} event.
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
public void onSearchEcho(String value) {
|
public void onSearchEcho(String value) {
|
||||||
ListModelList<MenuItem> newModel = null;
|
ListModelList<MenuItem> newModel = null;
|
||||||
if (Util.isEmpty(value)) {
|
if (Util.isEmpty(value)) {
|
||||||
|
@ -391,6 +468,12 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
updateListboxModel(newModel);
|
updateListboxModel(newModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update {@link #listbox} with newModel.
|
||||||
|
* If newModel has > 50 items, only first 50 is loaded into {@link #listbox}.
|
||||||
|
* User has to click the load more link (...) to load the rest of the items into {@link #listbox}.
|
||||||
|
* @param newModel
|
||||||
|
*/
|
||||||
private void updateListboxModel(ListModelList<MenuItem> newModel) {
|
private void updateListboxModel(ListModelList<MenuItem> newModel) {
|
||||||
fullModel = null;
|
fullModel = null;
|
||||||
if (newModel.size() > 50) {
|
if (newModel.size() > 50) {
|
||||||
|
@ -406,10 +489,20 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
listbox.setModel(newModel);
|
listbox.setModel(newModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparator to help filter menu items with a filter value.
|
||||||
|
*/
|
||||||
private class MenuListComparator implements Comparator<MenuItem> {
|
private class MenuListComparator implements Comparator<MenuItem> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text to filter menu items by label.
|
||||||
|
* Use startsWith if length of compare is < 3, otherwise use contains for filter.
|
||||||
|
*/
|
||||||
private String compare;
|
private String compare;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param compare filter text
|
||||||
|
*/
|
||||||
private MenuListComparator(String compare) {
|
private MenuListComparator(String compare) {
|
||||||
this.compare = Util.deleteAccents(compare.toLowerCase().trim());
|
this.compare = Util.deleteAccents(compare.toLowerCase().trim());
|
||||||
}
|
}
|
||||||
|
@ -431,6 +524,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* select ListItem that comes before the current selected ListItem.
|
||||||
|
* @return new selected {@link MenuItem}
|
||||||
|
*/
|
||||||
public MenuItem selectPrior() {
|
public MenuItem selectPrior() {
|
||||||
int i = listbox.getSelectedIndex();
|
int i = listbox.getSelectedIndex();
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
@ -444,6 +541,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* select ListItem that comes after the current selected ListItem.
|
||||||
|
* @return new selected {@link MenuItem}
|
||||||
|
*/
|
||||||
public MenuItem selectNext() {
|
public MenuItem selectNext() {
|
||||||
int i = listbox.getSelectedIndex();
|
int i = listbox.getSelectedIndex();
|
||||||
if (i < 0 && listbox.getItemCount() > 0) {
|
if (i < 0 && listbox.getItemCount() > 0) {
|
||||||
|
@ -467,6 +568,11 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_OK event
|
||||||
|
* @param textbox
|
||||||
|
* @return true if there's partial or exact match for textbox value
|
||||||
|
*/
|
||||||
public boolean onOk(Textbox textbox) {
|
public boolean onOk(Textbox textbox) {
|
||||||
String text = textbox.getText();
|
String text = textbox.getText();
|
||||||
if (Util.isEmpty(text))
|
if (Util.isEmpty(text))
|
||||||
|
@ -498,6 +604,9 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ListitemRenderer} for {@link #listbox}
|
||||||
|
*/
|
||||||
private class MenuItemRenderer implements ListitemRenderer<MenuItem>, ListitemRendererExt {
|
private class MenuItemRenderer implements ListitemRenderer<MenuItem>, ListitemRendererExt {
|
||||||
private static final String REMOVE_FROM_FAVOURITES_MSG = "RemoveFromFavourites";
|
private static final String REMOVE_FROM_FAVOURITES_MSG = "RemoveFromFavourites";
|
||||||
private static final String ADD_TO_FAVOURITES_MSG = "AddToFavourites";
|
private static final String ADD_TO_FAVOURITES_MSG = "AddToFavourites";
|
||||||
|
|
|
@ -78,7 +78,7 @@ import com.lowagie.text.pdf.PdfReader;
|
||||||
import com.lowagie.text.pdf.PdfWriter;
|
import com.lowagie.text.pdf.PdfWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog to Start process or report.
|
* Embedded Dialog to Start process or report.
|
||||||
* Displays information about the process
|
* Displays information about the process
|
||||||
* and lets the user decide to start it
|
* and lets the user decide to start it
|
||||||
* and displays results (optionally print them).
|
* and displays results (optionally print them).
|
||||||
|
@ -90,30 +90,42 @@ import com.lowagie.text.pdf.PdfWriter;
|
||||||
public class ProcessDialog extends AbstractProcessDialog implements EventListener<Event>, IHelpContext
|
public class ProcessDialog extends AbstractProcessDialog implements EventListener<Event>, IHelpContext
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -6728929130788829223L;
|
private static final long serialVersionUID = -6728929130788829223L;
|
||||||
|
|
||||||
public static final String ON_INITIAL_FOCUS_EVENT = "onInitialFocus";
|
public static final String ON_INITIAL_FOCUS_EVENT = "onInitialFocus";
|
||||||
|
|
||||||
private static final String ON_OK_ECHO = "onOkEcho";
|
/**
|
||||||
|
* Event echo form {@link #onOk()} to defer execution of {@link #onOk()}.
|
||||||
|
* Execution is defer to happens after the dismiss of modal dialog (usually info window) blocking parameter panel.
|
||||||
|
*/
|
||||||
|
private static final String ON_OK_ECHO_EVENT = "onOkEcho";
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger(ProcessDialog.class);
|
private static final CLogger log = CLogger.getCLogger(ProcessDialog.class);
|
||||||
//
|
//
|
||||||
|
/** message from {@link ProcessInfoLog} **/
|
||||||
private Table logMessageTable;
|
private Table logMessageTable;
|
||||||
private int[] m_ids = null;
|
/** record ids from {@link ProcessInfo} **/
|
||||||
|
private int[] m_ids = null;
|
||||||
|
/** true if dialog is showing process parameters **/
|
||||||
private boolean isParameterPage = true;
|
private boolean isParameterPage = true;
|
||||||
private Mask mask;
|
private Mask mask;
|
||||||
|
/** layout for process execution result **/
|
||||||
private HtmlBasedComponent resultPanelLayout;
|
private HtmlBasedComponent resultPanelLayout;
|
||||||
|
/** process message content of {@link #resultPanelLayout} **/
|
||||||
private HtmlBasedComponent messageResultContent;
|
private HtmlBasedComponent messageResultContent;
|
||||||
|
/** process log content of {@link #resultPanelLayout}, host {@link #logMessageTable} **/
|
||||||
private HtmlBasedComponent infoResultContent;
|
private HtmlBasedComponent infoResultContent;
|
||||||
|
|
||||||
/** Window No */
|
/** Window No */
|
||||||
private int m_WindowNo = -1;
|
private int m_WindowNo = -1;
|
||||||
|
/** timestamp of previous key event **/
|
||||||
private long prevKeyEventTime = 0;
|
private long prevKeyEventTime = 0;
|
||||||
|
/**
|
||||||
|
* Previous key event. use together with {@link #prevKeyEventTime} to detect double firing of key event from browser.
|
||||||
|
*/
|
||||||
private KeyEvent prevKeyEvent;
|
private KeyEvent prevKeyEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,7 +146,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
*/
|
*/
|
||||||
public ProcessDialog (int AD_Process_ID, boolean isSOTrx, String predefinedContextVariables)
|
public ProcessDialog (int AD_Process_ID, boolean isSOTrx, String predefinedContextVariables)
|
||||||
{
|
{
|
||||||
log.info("Process=" + AD_Process_ID );
|
if (log.isLoggable(Level.INFO)) log.info("Process=" + AD_Process_ID );
|
||||||
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
|
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
|
||||||
this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo);
|
this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo);
|
||||||
Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N");
|
Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N");
|
||||||
|
@ -145,7 +157,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
querySaved();
|
querySaved();
|
||||||
addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this);
|
addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this);
|
||||||
addEventListener(ON_INITIAL_FOCUS_EVENT, this);
|
addEventListener(ON_INITIAL_FOCUS_EVENT, this);
|
||||||
addEventListener(ON_OK_ECHO, this);
|
addEventListener(ON_OK_ECHO_EVENT, this);
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -188,7 +200,8 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
super.dispose();
|
super.dispose();
|
||||||
SessionManager.getAppDesktop().closeWindow(getWindowNo());
|
SessionManager.getAppDesktop().closeWindow(getWindowNo());
|
||||||
}// dispose
|
}// dispose
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
Component component = event.getTarget();
|
Component component = event.getTarget();
|
||||||
|
|
||||||
|
@ -198,7 +211,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
super.onEvent(event);
|
super.onEvent(event);
|
||||||
|
|
||||||
onOk();
|
onOk();
|
||||||
} else if (event.getName().equals(ON_OK_ECHO)) {
|
} else if (event.getName().equals(ON_OK_ECHO_EVENT)) {
|
||||||
onOk();
|
onOk();
|
||||||
}else if (bCancel.equals(component)){
|
}else if (bCancel.equals(component)){
|
||||||
super.onEvent(event);
|
super.onEvent(event);
|
||||||
|
@ -236,12 +249,15 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_Click event from {@link #bOK}
|
||||||
|
*/
|
||||||
private void onOk() {
|
private void onOk() {
|
||||||
if (isParameterPage)
|
if (isParameterPage)
|
||||||
{
|
{
|
||||||
if (getParameterPanel().isWaitingForDialog())
|
if (getParameterPanel().isWaitingForDialog())
|
||||||
{
|
{
|
||||||
Events.echoEvent(ON_OK_ECHO, this, null);
|
Events.echoEvent(ON_OK_ECHO_EVENT, this, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
startProcess();
|
startProcess();
|
||||||
|
@ -250,6 +266,10 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
restart();
|
restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle shortcut key event
|
||||||
|
* @param keyEvent
|
||||||
|
*/
|
||||||
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
||||||
if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X
|
if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X
|
||||||
if (m_WindowNo > 0) {
|
if (m_WindowNo > 0) {
|
||||||
|
@ -261,6 +281,10 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle on click event for record link.
|
||||||
|
* @param btn
|
||||||
|
*/
|
||||||
private void doOnClick(A btn) {
|
private void doOnClick(A btn) {
|
||||||
int Record_ID = 0;
|
int Record_ID = 0;
|
||||||
int AD_Table_ID =0;
|
int AD_Table_ID =0;
|
||||||
|
@ -272,8 +296,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Record_ID > 0 && AD_Table_ID > 0) {
|
if (Record_ID > 0 && AD_Table_ID > 0) {
|
||||||
|
|
||||||
AEnv.zoom(AD_Table_ID, Record_ID);
|
AEnv.zoom(AD_Table_ID, Record_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,6 +309,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
LayoutUtils.openOverlappedWindow(this, progressWindow, "middle_center");
|
LayoutUtils.openOverlappedWindow(this, progressWindow, "middle_center");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return in progress mask
|
||||||
|
*/
|
||||||
private Div getMask() {
|
private Div getMask() {
|
||||||
if (mask == null) {
|
if (mask == null) {
|
||||||
mask = new Mask();
|
mask = new Mask();
|
||||||
|
@ -293,9 +319,14 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show in progress mask
|
||||||
|
* @param window
|
||||||
|
*/
|
||||||
private void showBusyMask(Window window) {
|
private void showBusyMask(Window window) {
|
||||||
if (getParent() != null) {
|
if (getParent() != null) {
|
||||||
getParent().appendChild(getMask());
|
getParent().appendChild(getMask());
|
||||||
|
//to prevent focus to components beneath the in progress mask (see canActivate in web/js/org/idempiere/commons/window.js)
|
||||||
StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('#");
|
StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('#");
|
||||||
script.append(getParent().getUuid()).append("');");
|
script.append(getParent().getUuid()).append("');");
|
||||||
if (window != null) {
|
if (window != null) {
|
||||||
|
@ -308,6 +339,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close in progress mask
|
||||||
|
*/
|
||||||
private void hideBusyMask()
|
private void hideBusyMask()
|
||||||
{
|
{
|
||||||
if (mask != null && mask.getParent() != null) {
|
if (mask != null && mask.getParent() != null) {
|
||||||
|
@ -333,6 +367,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
swithToFinishScreen();
|
swithToFinishScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch to process execution result panel.
|
||||||
|
*/
|
||||||
protected void swithToFinishScreen() {
|
protected void swithToFinishScreen() {
|
||||||
ProcessInfo pi = getProcessInfo();
|
ProcessInfo pi = getProcessInfo();
|
||||||
ProcessInfoUtil.setLogFromDB(pi);
|
ProcessInfoUtil.setLogFromDB(pi);
|
||||||
|
@ -375,6 +412,10 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
Clients.response(new AuEcho(this, "onAfterProcess", null));
|
Clients.response(new AuEcho(this, "onAfterProcess", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* layout process execution result panel
|
||||||
|
* @param topParameterLayout
|
||||||
|
*/
|
||||||
private void layoutResultPanel (HtmlBasedComponent topParameterLayout){
|
private void layoutResultPanel (HtmlBasedComponent topParameterLayout){
|
||||||
if (resultPanelLayout == null){
|
if (resultPanelLayout == null){
|
||||||
resultPanelLayout = new Vlayout();
|
resultPanelLayout = new Vlayout();
|
||||||
|
@ -388,11 +429,21 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace oldComponent with newComponent
|
||||||
|
* @param newComponent
|
||||||
|
* @param oldComponent
|
||||||
|
*/
|
||||||
protected void replaceComponent(HtmlBasedComponent newComponent, HtmlBasedComponent oldComponent) {
|
protected void replaceComponent(HtmlBasedComponent newComponent, HtmlBasedComponent oldComponent) {
|
||||||
oldComponent.getParent().insertBefore(newComponent, oldComponent);
|
oldComponent.getParent().insertBefore(newComponent, oldComponent);
|
||||||
oldComponent.detach();
|
oldComponent.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append m_logs content to {@link #logMessageTable}
|
||||||
|
* @param m_logs
|
||||||
|
* @param infoResultContent
|
||||||
|
*/
|
||||||
private void appendRecordLogInfo(ProcessInfoLog[] m_logs, HtmlBasedComponent infoResultContent) {
|
private void appendRecordLogInfo(ProcessInfoLog[] m_logs, HtmlBasedComponent infoResultContent) {
|
||||||
if (m_logs == null)
|
if (m_logs == null)
|
||||||
return;
|
return;
|
||||||
|
@ -466,9 +517,11 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//messageDiv.appendChild(logMessageTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move back from process execution result panel to process parameter panel
|
||||||
|
*/
|
||||||
private void restart() {
|
private void restart() {
|
||||||
replaceComponent (topParameterLayout, resultPanelLayout);
|
replaceComponent (topParameterLayout, resultPanelLayout);
|
||||||
|
|
||||||
|
@ -500,6 +553,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onAfterProcess event echo from {@link #swithToFinishScreen()}
|
||||||
|
*/
|
||||||
public void onAfterProcess()
|
public void onAfterProcess()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -510,15 +566,15 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**
|
||||||
* Optional Processing Task
|
* Optional after/post process execution task
|
||||||
*/
|
*/
|
||||||
private boolean afterProcessTask()
|
private boolean afterProcessTask()
|
||||||
{
|
{
|
||||||
// something to do?
|
// something to do?
|
||||||
if (m_ids != null && m_ids.length > 0)
|
if (m_ids != null && m_ids.length > 0)
|
||||||
{
|
{
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
// Print invoices
|
// Print invoices
|
||||||
if (getAD_Process_ID() == PROCESS_C_INVOICE_GENERATE)
|
if (getAD_Process_ID() == PROCESS_C_INVOICE_GENERATE)
|
||||||
{
|
{
|
||||||
|
@ -538,8 +594,8 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
return false;
|
return false;
|
||||||
} // afterProcessTask
|
} // afterProcessTask
|
||||||
|
|
||||||
/**************************************************************************
|
/**
|
||||||
* Print Shipments
|
* Print Shipments
|
||||||
*/
|
*/
|
||||||
private void printShipments()
|
private void printShipments()
|
||||||
{
|
{
|
||||||
|
@ -557,8 +613,11 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} // printInvoices
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onPrintShipments event echo by {@link #printShipments()}
|
||||||
|
*/
|
||||||
public void onPrintShipments()
|
public void onPrintShipments()
|
||||||
{
|
{
|
||||||
// Loop through all items
|
// Loop through all items
|
||||||
|
@ -629,7 +688,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print Invoices
|
* Print Invoices
|
||||||
*/
|
*/
|
||||||
private void printInvoices()
|
private void printInvoices()
|
||||||
{
|
{
|
||||||
|
@ -649,8 +708,11 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} // printInvoices
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onPrintInvoices event echo by {@link #printInvoices()}
|
||||||
|
*/
|
||||||
public void onPrintInvoices()
|
public void onPrintInvoices()
|
||||||
{
|
{
|
||||||
// Loop through all items
|
// Loop through all items
|
||||||
|
|
|
@ -48,15 +48,22 @@ import org.zkoss.zk.ui.event.Events;
|
||||||
public class ProcessModalDialog extends AbstractProcessDialog implements EventListener<Event>, DialogEvents
|
public class ProcessModalDialog extends AbstractProcessDialog implements EventListener<Event>, DialogEvents
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -6227339628038418701L;
|
private static final long serialVersionUID = -6227339628038418701L;
|
||||||
|
|
||||||
private static final String ON_OK_ECHO = "onOkEcho";
|
/**
|
||||||
|
* Event echo form {@link #onOk()} to defer execution of {@link #onOk()}.
|
||||||
|
* Execution is defer to happens after the dismiss of modal dialog (usually info window) blocking parameter panel.
|
||||||
|
*/
|
||||||
|
private static final String ON_OK_ECHO_EVENT = "onOkEcho";
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger(ProcessModalDialog.class);
|
private static final CLogger log = CLogger.getCLogger(ProcessModalDialog.class);
|
||||||
//
|
/**
|
||||||
|
* Store screen orientation from last onClientInfo event.
|
||||||
|
* Use to detect change of screen orientation and adapt layout accordingly.
|
||||||
|
*/
|
||||||
private String orientation;
|
private String orientation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,10 +179,17 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
|
||||||
{
|
{
|
||||||
log.log(Level.SEVERE, "", ex);
|
log.log(Level.SEVERE, "", ex);
|
||||||
}
|
}
|
||||||
addEventListener(ON_OK_ECHO, this);
|
addEventListener(ON_OK_ECHO_EVENT, this);
|
||||||
addEventListener(Events.ON_CANCEL, e -> onCancel());
|
addEventListener(Events.ON_CANCEL, e -> onCancel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WindowNo
|
||||||
|
* @param AD_Process_ID
|
||||||
|
* @param tableId
|
||||||
|
* @param recordId
|
||||||
|
* @param autoStart
|
||||||
|
*/
|
||||||
public ProcessModalDialog (int WindowNo, int AD_Process_ID, int tableId, int recordId, boolean autoStart)
|
public ProcessModalDialog (int WindowNo, int AD_Process_ID, int tableId, int recordId, boolean autoStart)
|
||||||
{
|
{
|
||||||
this(null, WindowNo, AD_Process_ID, tableId, recordId, autoStart);
|
this(null, WindowNo, AD_Process_ID, tableId, recordId, autoStart);
|
||||||
|
@ -265,12 +279,13 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
|
||||||
/**
|
/**
|
||||||
* handle events
|
* handle events
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
Component component = event.getTarget();
|
Component component = event.getTarget();
|
||||||
if (component.equals(bOK)) {
|
if (component.equals(bOK)) {
|
||||||
super.onEvent(event);
|
super.onEvent(event);
|
||||||
onOk();
|
onOk();
|
||||||
} else if (event.getName().equals(ON_OK_ECHO)) {
|
} else if (event.getName().equals(ON_OK_ECHO_EVENT)) {
|
||||||
onOk();
|
onOk();
|
||||||
} else if (component.equals(bCancel)) {
|
} else if (component.equals(bCancel)) {
|
||||||
super.onEvent(event);
|
super.onEvent(event);
|
||||||
|
@ -280,14 +295,20 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_Click event from {@link #bCancel}
|
||||||
|
*/
|
||||||
private void onCancel() {
|
private void onCancel() {
|
||||||
cancelProcess();
|
cancelProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_Click event from {@link #bOK}
|
||||||
|
*/
|
||||||
private void onOk() {
|
private void onOk() {
|
||||||
if (getParameterPanel().isWaitingForDialog())
|
if (getParameterPanel().isWaitingForDialog())
|
||||||
{
|
{
|
||||||
Events.echoEvent(ON_OK_ECHO, this, null);
|
Events.echoEvent(ON_OK_ECHO_EVENT, this, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(fPrintFormat != null && fPrintFormat.getValue() != null) {
|
if(fPrintFormat != null && fPrintFormat.getValue() != null) {
|
||||||
|
@ -302,6 +323,9 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
|
||||||
startProcess();
|
startProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle client info event from browser
|
||||||
|
*/
|
||||||
protected void onClientInfo() {
|
protected void onClientInfo() {
|
||||||
if (getPage() != null) {
|
if (getPage() != null) {
|
||||||
String newOrientation = ClientInfo.get().orientation;
|
String newOrientation = ClientInfo.get().orientation;
|
||||||
|
|
|
@ -84,9 +84,9 @@ import org.zkoss.zul.impl.InputElement;
|
||||||
import org.zkoss.zul.impl.XulElement;
|
import org.zkoss.zul.impl.XulElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process Parameter Panel, based on existing ProcessParameter dialog. -
|
* Process Parameter Panel.
|
||||||
* Embedded in ProcessDialog - checks, if parameters exist and inquires and
|
* Embedded in {@link ProcessDialog} and {@link ProcessModalDialog}.
|
||||||
* saves them
|
* Capture parameters input, validate and save to DB.
|
||||||
*
|
*
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
* @version 2006-12-01
|
* @version 2006-12-01
|
||||||
|
@ -94,17 +94,18 @@ import org.zkoss.zul.impl.XulElement;
|
||||||
public class ProcessParameterPanel extends Panel implements
|
public class ProcessParameterPanel extends Panel implements
|
||||||
ValueChangeListener, IProcessParameter, EventListener<Event> {
|
ValueChangeListener, IProcessParameter, EventListener<Event> {
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -6099317911368929787L;
|
private static final long serialVersionUID = -6099317911368929787L;
|
||||||
|
|
||||||
|
/** Event post from {@link #valueChange(ValueChangeEvent)} **/
|
||||||
|
private static final String ON_POST_EDITOR_VALUE_CHANGE_EVENT = "onPostEditorValueChange";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamic generated Parameter panel.
|
* Dynamic generated Parameter panel.
|
||||||
*
|
*
|
||||||
* @param WindowNo
|
* @param WindowNo register window number
|
||||||
* window
|
* @param pi process info
|
||||||
* @param pi
|
|
||||||
* process info
|
|
||||||
*/
|
*/
|
||||||
public ProcessParameterPanel(int WindowNo, ProcessInfo pi) {
|
public ProcessParameterPanel(int WindowNo, ProcessInfo pi) {
|
||||||
this(WindowNo, 0, pi);
|
this(WindowNo, 0, pi);
|
||||||
|
@ -113,12 +114,9 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
/**
|
/**
|
||||||
* Dynamic generated Parameter panel.
|
* Dynamic generated Parameter panel.
|
||||||
*
|
*
|
||||||
* @param WindowNo
|
* @param WindowNo register window number
|
||||||
* window
|
* @param tabNo tabNo
|
||||||
* @param tabNo
|
* @param pi process info
|
||||||
* tabNo
|
|
||||||
* @param pi
|
|
||||||
* process info
|
|
||||||
*/
|
*/
|
||||||
public ProcessParameterPanel(int WindowNo,int tabNo, ProcessInfo pi) {
|
public ProcessParameterPanel(int WindowNo,int tabNo, ProcessInfo pi) {
|
||||||
//
|
//
|
||||||
|
@ -130,9 +128,12 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
//
|
//
|
||||||
initComponent();
|
initComponent();
|
||||||
addEventListener("onDynamicDisplay", this);
|
addEventListener("onDynamicDisplay", this);
|
||||||
addEventListener("onPostEditorValueChange", this);
|
addEventListener(ON_POST_EDITOR_VALUE_CHANGE_EVENT, this);
|
||||||
} // ProcessParameterPanel
|
} // ProcessParameterPanel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout UI
|
||||||
|
*/
|
||||||
private void initComponent() {
|
private void initComponent() {
|
||||||
centerPanel = GridFactory.newGridLayout();
|
centerPanel = GridFactory.newGridLayout();
|
||||||
this.appendChild(centerPanel);
|
this.appendChild(centerPanel);
|
||||||
|
@ -151,27 +152,36 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
private int m_WindowNo;
|
private int m_WindowNo;
|
||||||
private int m_TabNo;
|
private int m_TabNo;
|
||||||
private ProcessInfo m_processInfo;
|
private ProcessInfo m_processInfo;
|
||||||
// AD_Window of window below this dialog in case show parameter dialog panel
|
/** AD_Window_ID if process dialog is launch by AD_Window **/
|
||||||
private int m_AD_Window_ID = 0;
|
private int m_AD_Window_ID = 0;
|
||||||
// infoWindowID of infoWindow below this dialog in case call process from infoWindow
|
/** Info_Window_ID if process dialog is launch by Info Window **/
|
||||||
private int m_InfoWindowID = 0;
|
private int m_InfoWindowID = 0;
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger
|
private static final CLogger log = CLogger
|
||||||
.getCLogger(ProcessParameterPanel.class);
|
.getCLogger(ProcessParameterPanel.class);
|
||||||
|
|
||||||
//
|
/** parameter editor list **/
|
||||||
private ArrayList<WEditor> m_wEditors = new ArrayList<WEditor>();
|
private ArrayList<WEditor> m_wEditors = new ArrayList<WEditor>();
|
||||||
private ArrayList<WEditor> m_wEditors2 = new ArrayList<WEditor>(); // for ranges
|
/** to parameter editor list for range parameter **/
|
||||||
|
private ArrayList<WEditor> m_wEditors2 = new ArrayList<WEditor>();
|
||||||
|
/** parameter field list **/
|
||||||
private ArrayList<GridField> m_mFields = new ArrayList<GridField>();
|
private ArrayList<GridField> m_mFields = new ArrayList<GridField>();
|
||||||
|
/** to parameter field list for range parameter **/
|
||||||
private ArrayList<GridField> m_mFields2 = new ArrayList<GridField>();
|
private ArrayList<GridField> m_mFields2 = new ArrayList<GridField>();
|
||||||
private ArrayList<Space> m_separators = new ArrayList<Space>();
|
private ArrayList<Space> m_separators = new ArrayList<Space>();
|
||||||
|
/** all rows of {@link #centerPanel} **/
|
||||||
private ArrayList<Row> m_Rows = new ArrayList<Row>();
|
private ArrayList<Row> m_Rows = new ArrayList<Row>();
|
||||||
//
|
/** layout grid for parameter fields **/
|
||||||
private Grid centerPanel = null;
|
private Grid centerPanel = null;
|
||||||
|
/** Group Name:Rows for parameter field **/
|
||||||
private Map<String, List<Row>> fieldGroupContents = new HashMap<String, List<Row>>();
|
private Map<String, List<Row>> fieldGroupContents = new HashMap<String, List<Row>>();
|
||||||
|
/** Group Name:Rows for group header **/
|
||||||
private Map<String, List<org.zkoss.zul.Row>> fieldGroupHeaders = new HashMap<String, List<org.zkoss.zul.Row>>();
|
private Map<String, List<org.zkoss.zul.Row>> fieldGroupHeaders = new HashMap<String, List<org.zkoss.zul.Row>>();
|
||||||
|
/** rows of current rendering group **/
|
||||||
private ArrayList<Row> rowList;
|
private ArrayList<Row> rowList;
|
||||||
|
/** all groups of field type collapsible or tab **/
|
||||||
private List<Group> allCollapsibleGroups = new ArrayList<Group>();
|
private List<Group> allCollapsibleGroups = new ArrayList<Group>();
|
||||||
|
/** current rendering group **/
|
||||||
private Group currentGroup;
|
private Group currentGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,12 +196,12 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
} // dispose
|
} // dispose
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read Fields to display
|
* Render all visible fields
|
||||||
*
|
*
|
||||||
* @return true if loaded OK
|
* @return true if loaded OK
|
||||||
*/
|
*/
|
||||||
public boolean init() {
|
public boolean init() {
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
// ASP
|
// ASP
|
||||||
MClient client = MClient.get(Env.getCtx());
|
MClient client = MClient.get(Env.getCtx());
|
||||||
|
@ -385,12 +395,13 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
} // initDialog
|
} // initDialog
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Field. - creates Fields and adds it to m_mFields list - creates
|
* Create editor and adds it to {@link #m_wEditors}.
|
||||||
* Editor and adds it to m_vEditors list Handeles Ranges by adding
|
* <br/>
|
||||||
* additional mField/vEditor.
|
* For range type field, create the to field and add it to {@link #m_mFields2} and
|
||||||
|
* create the to editor and adds it to {@link #m_wEditors2}.
|
||||||
* <p>
|
* <p>
|
||||||
* mFields are used for default value and mandatory checking; vEditors are
|
* mField is used for default value and mandatory checking and editor is
|
||||||
* used to retrieve the value (no data binding)
|
* used to capture input value from user (no data binding).
|
||||||
*
|
*
|
||||||
* @param voF GridFieldVO
|
* @param voF GridFieldVO
|
||||||
* @param mField
|
* @param mField
|
||||||
|
@ -403,7 +414,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
editor.getComponent().addEventListener(Events.ON_FOCUS, this);
|
editor.getComponent().addEventListener(Events.ON_FOCUS, this);
|
||||||
editor.addValueChangeListener(this);
|
editor.addValueChangeListener(this);
|
||||||
editor.dynamicDisplay();
|
editor.dynamicDisplay();
|
||||||
// MField => VEditor - New Field value to be updated to editor
|
// MField => editor - New Field value to be updated to editor
|
||||||
mField.addPropertyChangeListener(editor);
|
mField.addPropertyChangeListener(editor);
|
||||||
// Set Default
|
// Set Default
|
||||||
Object defaultObject = mField.getDefaultForPanel();
|
Object defaultObject = mField.getDefaultForPanel();
|
||||||
|
@ -446,6 +457,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
Div box = new Div();
|
Div box = new Div();
|
||||||
box.setStyle("display: flex; align-items: center;");
|
box.setStyle("display: flex; align-items: center;");
|
||||||
ZKUpdateUtil.setWidth(box, "100%");
|
ZKUpdateUtil.setWidth(box, "100%");
|
||||||
|
//create to field and editor
|
||||||
if (voF.isRange) {
|
if (voF.isRange) {
|
||||||
box.appendChild(editor.getComponent());
|
box.appendChild(editor.getComponent());
|
||||||
ZKUpdateUtil.setWidth((HtmlBasedComponent) editor.getComponent(), "49%");
|
ZKUpdateUtil.setWidth((HtmlBasedComponent) editor.getComponent(), "49%");
|
||||||
|
@ -492,6 +504,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
m_mFields2.add(null);
|
m_mFields2.add(null);
|
||||||
m_wEditors2.add(null);
|
m_wEditors2.add(null);
|
||||||
m_separators.add(null);
|
m_separators.add(null);
|
||||||
|
//add not in support for multi selection field
|
||||||
if(DisplayType.isChosenMultipleSelection(mField.getDisplayType())) {
|
if(DisplayType.isChosenMultipleSelection(mField.getDisplayType())) {
|
||||||
Button bNegate = ButtonFactory.createButton("", null, null);
|
Button bNegate = ButtonFactory.createButton("", null, null);
|
||||||
bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
|
bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
|
||||||
|
@ -507,6 +520,11 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
row.appendChild(box);
|
row.appendChild(box);
|
||||||
} // createField
|
} // createField
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set place holder message
|
||||||
|
* @param editor
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
private void setEditorPlaceHolder(WEditor editor, String msg) {
|
private void setEditorPlaceHolder(WEditor editor, String msg) {
|
||||||
Component c = editor.getComponent();
|
Component c = editor.getComponent();
|
||||||
if (c instanceof InputElement) {
|
if (c instanceof InputElement) {
|
||||||
|
@ -528,17 +546,15 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
* @return true if parameters are valid
|
* @return true if parameters are valid
|
||||||
*/
|
*/
|
||||||
public boolean validateParameters() {
|
public boolean validateParameters() {
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
/**
|
//mandatory fields validation
|
||||||
* Mandatory fields see - MTable.getMandatory
|
|
||||||
*/
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
int size = m_mFields.size();
|
int size = m_mFields.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
GridField field = (GridField) m_mFields.get(i);
|
GridField field = (GridField) m_mFields.get(i);
|
||||||
if (field.isMandatory(true)) // check context
|
if (field.isMandatory(true)) // check context
|
||||||
{
|
{
|
||||||
WEditor wEditor = (WEditor) m_wEditors.get(i);
|
WEditor wEditor = (WEditor) m_wEditors.get(i);
|
||||||
Object data = wEditor.getValue();
|
Object data = wEditor.getValue();
|
||||||
if (data == null || data.toString().length() == 0) {
|
if (data == null || data.toString().length() == 0) {
|
||||||
|
@ -577,6 +593,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** call {@link IProcessParameterListener} validate(ProcessParameterPanel) **/
|
||||||
if (m_processInfo.getAD_Process_ID() > 0) {
|
if (m_processInfo.getAD_Process_ID() > 0) {
|
||||||
String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname();
|
String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname();
|
||||||
List<IProcessParameterListener> listeners = Extensions.getProcessParameterListeners(className, null);
|
List<IProcessParameterListener> listeners = Extensions.getProcessParameterListeners(className, null);
|
||||||
|
@ -592,12 +609,13 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
return true;
|
return true;
|
||||||
} // validateParameters
|
} // validateParameters
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* load parameters from saved instance
|
* load parameters from saved instance
|
||||||
|
* @param instance
|
||||||
*/
|
*/
|
||||||
public boolean loadParameters(MPInstance instance)
|
public boolean loadParameters(MPInstance instance)
|
||||||
{
|
{
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
MPInstancePara[] params = instance.getParameters();
|
MPInstancePara[] params = instance.getParameters();
|
||||||
for (int j = 0; j < m_mFields.size(); j++)
|
for (int j = 0; j < m_mFields.size(); j++)
|
||||||
|
@ -688,12 +706,13 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
return true;
|
return true;
|
||||||
} // loadParameters
|
} // loadParameters
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Load parameters from Process Info
|
* Load parameters from Process Info
|
||||||
|
* @param pi
|
||||||
*/
|
*/
|
||||||
public boolean loadParametersFromProcessInfo(ProcessInfo pi)
|
public boolean loadParametersFromProcessInfo(ProcessInfo pi)
|
||||||
{
|
{
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
ProcessInfoParameter[] params = pi.getParameter();
|
ProcessInfoParameter[] params = pi.getParameter();
|
||||||
for (int j = 0; j < m_mFields.size(); j++)
|
for (int j = 0; j < m_mFields.size(); j++)
|
||||||
|
@ -742,12 +761,12 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
} // loadParameters
|
} // loadParameters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Parameter values
|
* Save parameter values to {@link MPInstancePara}.
|
||||||
*
|
*
|
||||||
* @return true if parameters saved
|
* @return true if parameters saved
|
||||||
*/
|
*/
|
||||||
public boolean saveParameters() {
|
public boolean saveParameters() {
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
if (!validateParameters())
|
if (!validateParameters())
|
||||||
return false;
|
return false;
|
||||||
|
@ -839,21 +858,19 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
} // saveParameters
|
} // saveParameters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Parameter values without saving
|
* Get parameter values from editors without saving to DB.
|
||||||
*
|
*
|
||||||
* @return list of parameter values
|
* @return MPInstancePara[], list of parameter values.
|
||||||
*/
|
*/
|
||||||
public MPInstancePara[] getParameters() {
|
public MPInstancePara[] getParameters() {
|
||||||
log.config("");
|
if (log.isLoggable(Level.CONFIG)) log.config("");
|
||||||
|
|
||||||
if (!validateParameters())
|
if (!validateParameters())
|
||||||
return new MPInstancePara[0];
|
return new MPInstancePara[0];
|
||||||
|
|
||||||
List<MPInstancePara> paras = new ArrayList<MPInstancePara>();
|
List<MPInstancePara> paras = new ArrayList<MPInstancePara>();
|
||||||
|
|
||||||
/**********************************************************************
|
/** create MPInstancePara from editors and add to paras (without saving MPInstancePara to DB) **/
|
||||||
* Save Now
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < m_mFields.size(); i++) {
|
for (int i = 0; i < m_mFields.size(); i++) {
|
||||||
// Get Values
|
// Get Values
|
||||||
WEditor editor = (WEditor) m_wEditors.get(i);
|
WEditor editor = (WEditor) m_wEditors.get(i);
|
||||||
|
@ -928,12 +945,10 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor Listener
|
* Editor value change listener.
|
||||||
*
|
*
|
||||||
* @param evt
|
* @param evt ValueChangeEvent
|
||||||
* ValueChangeEvent
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void valueChange(ValueChangeEvent evt) {
|
public void valueChange(ValueChangeEvent evt) {
|
||||||
String propName = evt.getPropertyName();
|
String propName = evt.getPropertyName();
|
||||||
if (evt.getSource() instanceof WEditor) {
|
if (evt.getSource() instanceof WEditor) {
|
||||||
|
@ -947,7 +962,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
processDependencies (changedField);
|
processDependencies (changedField);
|
||||||
// future processCallout (changedField);
|
// future processCallout (changedField);
|
||||||
}
|
}
|
||||||
Events.postEvent("onPostEditorValueChange", this, evt.getSource());
|
Events.postEvent(ON_POST_EDITOR_VALUE_CHANGE_EVENT, this, evt.getSource());
|
||||||
}
|
}
|
||||||
processNewValue(evt.getNewValue(), propName);
|
processNewValue(evt.getNewValue(), propName);
|
||||||
}
|
}
|
||||||
|
@ -955,6 +970,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (event.getName().equals(Events.ON_FOCUS)) {
|
if (event.getName().equals(Events.ON_FOCUS)) {
|
||||||
|
//update tooltip text inside desktop help panel.
|
||||||
for (WEditor editor : m_wEditors)
|
for (WEditor editor : m_wEditors)
|
||||||
{
|
{
|
||||||
if (editor.isComponentOfEditor(event.getTarget()))
|
if (editor.isComponentOfEditor(event.getTarget()))
|
||||||
|
@ -976,7 +992,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
else if (event.getName().equals("onDynamicDisplay")) {
|
else if (event.getName().equals("onDynamicDisplay")) {
|
||||||
dynamicDisplay();
|
dynamicDisplay();
|
||||||
}
|
}
|
||||||
else if (event.getName().equals("onPostEditorValueChange")) {
|
else if (event.getName().equals(ON_POST_EDITOR_VALUE_CHANGE_EVENT)) {
|
||||||
WEditor editor = (WEditor)event.getData();
|
WEditor editor = (WEditor)event.getData();
|
||||||
onPostEditorValueChange(editor);
|
onPostEditorValueChange(editor);
|
||||||
if(editor.getComponent() != null) {
|
if(editor.getComponent() != null) {
|
||||||
|
@ -996,6 +1012,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
else if (event.getName().equals(Events.ON_CLICK)) {
|
else if (event.getName().equals(Events.ON_CLICK)) {
|
||||||
if(event.getTarget() instanceof Button) {
|
if(event.getTarget() instanceof Button) {
|
||||||
|
//from not in button of multi selection field
|
||||||
Button bNegate = (Button)event.getTarget();
|
Button bNegate = (Button)event.getTarget();
|
||||||
boolean isSelected = !(boolean)bNegate.getAttribute("isSelected");
|
boolean isSelected = !(boolean)bNegate.getAttribute("isSelected");
|
||||||
if(isSelected) {
|
if(isSelected) {
|
||||||
|
@ -1013,6 +1030,12 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_POST_EDITOR_VALUE_CHANGE_EVENT event.
|
||||||
|
* <br/>
|
||||||
|
* Call {@link IProcessParameterListener#validate(ProcessParameterPanel)}.
|
||||||
|
* @param editor
|
||||||
|
*/
|
||||||
private void onPostEditorValueChange(WEditor editor) {
|
private void onPostEditorValueChange(WEditor editor) {
|
||||||
if (m_processInfo.getAD_Process_ID() > 0) {
|
if (m_processInfo.getAD_Process_ID() > 0) {
|
||||||
String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname();
|
String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname();
|
||||||
|
@ -1029,7 +1052,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate Dependencies
|
* Notify dependent fields.
|
||||||
* @param changedField changed field
|
* @param changedField changed field
|
||||||
*/
|
*/
|
||||||
private void processDependencies (GridField changedField)
|
private void processDependencies (GridField changedField)
|
||||||
|
@ -1048,6 +1071,11 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
} // processDependencies
|
} // processDependencies
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset field value to null if field depends on columnName.
|
||||||
|
* @param field
|
||||||
|
* @param columnName column name of changed field
|
||||||
|
*/
|
||||||
private void verifyChangedField(GridField field, String columnName) {
|
private void verifyChangedField(GridField field, String columnName) {
|
||||||
ArrayList<String> list = field.getDependentOn();
|
ArrayList<String> list = field.getDependentOn();
|
||||||
if (list.contains(columnName)) {
|
if (list.contains(columnName)) {
|
||||||
|
@ -1066,6 +1094,11 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process new value from {@link #valueChange(ValueChangeEvent)}.
|
||||||
|
* @param value
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
private void processNewValue(Object value, String name) {
|
private void processNewValue(Object value, String name) {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
value = new String("");
|
value = new String("");
|
||||||
|
@ -1086,6 +1119,9 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
Events.postEvent("onDynamicDisplay", this, (Object)null);
|
Events.postEvent("onDynamicDisplay", this, (Object)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic update the UI state and properties of all fields.
|
||||||
|
*/
|
||||||
private void dynamicDisplay() {
|
private void dynamicDisplay() {
|
||||||
for (int i = 0; i < m_wEditors.size(); i++) {
|
for (int i = 0; i < m_wEditors.size(); i++) {
|
||||||
WEditor editor = m_wEditors.get(i);
|
WEditor editor = m_wEditors.get(i);
|
||||||
|
@ -1172,6 +1208,10 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
m_processInfo = processInfo;
|
m_processInfo = processInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* focus to first visible field editor.
|
||||||
|
* @return true if there is at least one visible field editor.
|
||||||
|
*/
|
||||||
public boolean focusToFirstEditor() {
|
public boolean focusToFirstEditor() {
|
||||||
if (m_wEditors.isEmpty())
|
if (m_wEditors.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1184,6 +1224,9 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param toFocus
|
||||||
|
*/
|
||||||
private void focusToEditor(WEditor toFocus) {
|
private void focusToEditor(WEditor toFocus) {
|
||||||
Component c = toFocus.getComponent();
|
Component c = toFocus.getComponent();
|
||||||
if (c instanceof EditorBox) {
|
if (c instanceof EditorBox) {
|
||||||
|
@ -1211,7 +1254,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get parameter field value to editor by column name
|
* Get parameter field to editor by column name
|
||||||
* @param columnName
|
* @param columnName
|
||||||
* @return editor
|
* @return editor
|
||||||
*/
|
*/
|
||||||
|
@ -1225,7 +1268,7 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if editor is showing dialog awaiting user action
|
* @return true if editor is showing dialog awaiting user action (usually info window).
|
||||||
*/
|
*/
|
||||||
public boolean isWaitingForDialog() {
|
public boolean isWaitingForDialog() {
|
||||||
for (int i = 0; i < m_mFields.size(); i++) {
|
for (int i = 0; i < m_mFields.size(); i++) {
|
||||||
|
@ -1244,6 +1287,9 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field label ON_CLICK listener for {@link IZoomableEditor}.
|
||||||
|
*/
|
||||||
static class ZoomListener implements EventListener<Event> {
|
static class ZoomListener implements EventListener<Event> {
|
||||||
|
|
||||||
private IZoomableEditor searchEditor;
|
private IZoomableEditor searchEditor;
|
||||||
|
@ -1261,6 +1307,9 @@ public class ProcessParameterPanel extends Panel implements
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return register window number.
|
||||||
|
*/
|
||||||
public int getWindowNo() {
|
public int getWindowNo() {
|
||||||
return m_WindowNo;
|
return m_WindowNo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,14 +70,14 @@ import org.zkoss.zul.Center;
|
||||||
import org.zkoss.zul.Div;
|
import org.zkoss.zul.Div;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Drill assistant dialog
|
||||||
* @author Igor Pojzl, Cloudempiere
|
* @author Igor Pojzl, Cloudempiere
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class WDrillReport extends Window implements EventListener<Event> {
|
public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 5143424676962140799L;
|
private static final long serialVersionUID = 5143424676962140799L;
|
||||||
|
|
||||||
|
@ -88,10 +88,14 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
private static final String DRILL_REPORT_TABLE_NAME = "TableName";
|
private static final String DRILL_REPORT_TABLE_NAME = "TableName";
|
||||||
|
|
||||||
private DrillReportCtl drillReportCtl;
|
private DrillReportCtl drillReportCtl;
|
||||||
|
/** generated unique window name prefix **/
|
||||||
private String winpref;
|
private String winpref;
|
||||||
|
|
||||||
|
/** tabpanel for related table drill **/
|
||||||
private Tabpanel tabPanel;
|
private Tabpanel tabPanel;
|
||||||
|
/** tab for related table drill **/
|
||||||
private Tab tableTab;
|
private Tab tableTab;
|
||||||
|
/** true if {@link #tabPanel} loaded **/
|
||||||
private boolean tablesLoaded = false;
|
private boolean tablesLoaded = false;
|
||||||
|
|
||||||
private int windowNo = 0;
|
private int windowNo = 0;
|
||||||
|
@ -150,6 +154,10 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
td.appendChild(getContent());
|
td.appendChild(getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header text
|
||||||
|
* @return {@link Table}
|
||||||
|
*/
|
||||||
private Table getHeader()
|
private Table getHeader()
|
||||||
{
|
{
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
|
@ -202,6 +210,10 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabbox with Drill Rules and Related Tables tab.
|
||||||
|
* @return {@link Tabbox}
|
||||||
|
*/
|
||||||
private Tabbox getContent()
|
private Tabbox getContent()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -236,6 +248,14 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return tabbox;
|
return tabbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table with links for all process and nested table for print formats for each process.
|
||||||
|
* @param tabIndex
|
||||||
|
* @param drillTables [AD_Process_ID,Process Name]
|
||||||
|
* @param drillPrintFormatMap AD_Process_ID:[AD_Process_DrillRule_ID,Name]
|
||||||
|
* @param isDrillProcessRule true for drill rules, false for related tables
|
||||||
|
* @return {@link Table}
|
||||||
|
*/
|
||||||
private Table getTabContent(int tabIndex, KeyNamePair[] drillTables, HashMap<Integer, KeyNamePair[]> drillPrintFormatMap, boolean isDrillProcessRule)
|
private Table getTabContent(int tabIndex, KeyNamePair[] drillTables, HashMap<Integer, KeyNamePair[]> drillPrintFormatMap, boolean isDrillProcessRule)
|
||||||
{
|
{
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
|
@ -276,7 +296,6 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
td.appendChild(getTablesBox(tabIndex, drillTables));
|
td.appendChild(getTablesBox(tabIndex, drillTables));
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
KeyNamePair drillTable = drillTables[i];
|
KeyNamePair drillTable = drillTables[i];
|
||||||
|
|
||||||
// tab
|
// tab
|
||||||
|
@ -292,6 +311,15 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table with process name and print formats
|
||||||
|
* @param drillTable [AD_Process_ID,Process Name]
|
||||||
|
* @param tabIndex
|
||||||
|
* @param groupIndex
|
||||||
|
* @param drillPrintFormatMap AD_Process_ID:[AD_Process_DrillRule_ID,Name]
|
||||||
|
* @param isDrillProcessRule
|
||||||
|
* @return {@link Table}
|
||||||
|
*/
|
||||||
private Table getDrillTableBox(KeyNamePair drillTable, int tabIndex, int groupIndex, HashMap<Integer, KeyNamePair[]> drillPrintFormatMap, boolean isDrillProcessRule)
|
private Table getDrillTableBox(KeyNamePair drillTable, int tabIndex, int groupIndex, HashMap<Integer, KeyNamePair[]> drillPrintFormatMap, boolean isDrillProcessRule)
|
||||||
{
|
{
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
|
@ -325,11 +353,14 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
a.appendChild(new Text(".."));
|
a.appendChild(new Text(".."));
|
||||||
header.appendChild(a);
|
header.appendChild(a);
|
||||||
|
|
||||||
|
//[AD_Process_DrillRule_ID,Name]
|
||||||
KeyNamePair[] drillRules = drillPrintFormatMap != null ? drillPrintFormatMap.get(drillTable.getKey()) : new KeyNamePair[]{findTablePrintFormat(drillTable)};
|
KeyNamePair[] drillRules = drillPrintFormatMap != null ? drillPrintFormatMap.get(drillTable.getKey()) : new KeyNamePair[]{findTablePrintFormat(drillTable)};
|
||||||
for (int j = 0; j < drillRules.length; j++)
|
for (int j = 0; j < drillRules.length; j++)
|
||||||
{
|
{
|
||||||
|
//(AD_Process_DrillRule_ID,Name) or (AD_PrintFormat_ID,Name)
|
||||||
KeyNamePair drillRule = drillRules[j];
|
KeyNamePair drillRule = drillRules[j];
|
||||||
|
|
||||||
|
//[AD_PrintFormat_ID,Name]
|
||||||
KeyNamePair[] printFormats = isDrillProcessRule ? drillReportCtl.getDrillProcessRulesPrintFormatMap(drillRule.getKey()) : new KeyNamePair[] {drillRule} ;
|
KeyNamePair[] printFormats = isDrillProcessRule ? drillReportCtl.getDrillProcessRulesPrintFormatMap(drillRule.getKey()) : new KeyNamePair[] {drillRule} ;
|
||||||
|
|
||||||
// create new Print Format
|
// create new Print Format
|
||||||
|
@ -376,7 +407,10 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param drillTable KeyNamePair(AD_Process_ID,Process Name)
|
||||||
|
* @return KeyNamePair(AD_PrintFormat_ID,Name)
|
||||||
|
*/
|
||||||
private KeyNamePair findTablePrintFormat(KeyNamePair drillTable) {
|
private KeyNamePair findTablePrintFormat(KeyNamePair drillTable) {
|
||||||
|
|
||||||
Integer printFormatID = new Query(Env.getCtx(), MPrintFormat.Table_Name, " AD_Table_ID = ? AND AD_Client_ID IN (0,?) ", null)
|
Integer printFormatID = new Query(Env.getCtx(), MPrintFormat.Table_Name, " AD_Table_ID = ? AND AD_Client_ID IN (0,?) ", null)
|
||||||
|
@ -385,7 +419,12 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return new KeyNamePair((printFormatID != null && printFormatID > 0) ? printFormatID : 0, drillTable.getName());
|
return new KeyNamePair((printFormatID != null && printFormatID > 0) ? printFormatID : 0, drillTable.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link for process in drillTables
|
||||||
|
* @param tabIndex
|
||||||
|
* @param drillTables [AD_Process_ID,Process Name]
|
||||||
|
* @return {@link Table}
|
||||||
|
*/
|
||||||
private Table getTablesBox(int tabIndex, KeyNamePair[] drillTables)
|
private Table getTablesBox(int tabIndex, KeyNamePair[] drillTables)
|
||||||
{
|
{
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
|
@ -436,6 +475,17 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link and description for print format.
|
||||||
|
* @param drillPrintFormat KeyNamePair(AD_PrintFormat_ID,Name)
|
||||||
|
* @param reportIndex
|
||||||
|
* @param formatIndex
|
||||||
|
* @param groupIndex
|
||||||
|
* @param drillTable KeyNamePair(AD_Process_ID,Name)
|
||||||
|
* @param drillRule KeyNamePair(AD_Process_DrillRule_ID,Name)
|
||||||
|
* @param isSinglePrintFormat
|
||||||
|
* @return {@link Tr}
|
||||||
|
*/
|
||||||
private Tr getPrintFormatBox(KeyNamePair drillPrintFormat, int reportIndex, int formatIndex, int groupIndex, KeyNamePair drillTable, KeyNamePair drillRule, boolean isSinglePrintFormat)
|
private Tr getPrintFormatBox(KeyNamePair drillPrintFormat, int reportIndex, int formatIndex, int groupIndex, KeyNamePair drillTable, KeyNamePair drillRule, boolean isSinglePrintFormat)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -451,7 +501,6 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
H4 h4 = new H4();
|
H4 h4 = new H4();
|
||||||
h4.appendChild(new Text(drillPrintFormat.getName()));
|
h4.appendChild(new Text(drillPrintFormat.getName()));
|
||||||
|
|
||||||
|
|
||||||
td.appendChild(h4);
|
td.appendChild(h4);
|
||||||
a = new A();
|
a = new A();
|
||||||
a.setHref("#"+winpref+"Rep"+reportIndex+"-"+groupIndex);
|
a.setHref("#"+winpref+"Rep"+reportIndex+"-"+groupIndex);
|
||||||
|
@ -459,8 +508,6 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
a.appendChild(new Text(".."));
|
a.appendChild(new Text(".."));
|
||||||
td.appendChild(a);
|
td.appendChild(a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
td = new Td();
|
td = new Td();
|
||||||
td.setStyle("width: 10%");
|
td.setStyle("width: 10%");
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
|
@ -495,7 +542,6 @@ public class WDrillReport extends Window implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
td = new Td();
|
td = new Td();
|
||||||
td.setStyle("width: 60");
|
td.setStyle("width: 60");
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
|
|
|
@ -40,7 +40,8 @@ import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ported from org.compiere.apps.ProcessCtl
|
* Zk client controller for execution of process.
|
||||||
|
*
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
* @contributor red1 IDEMPIERE-1711 with final review by Hengsin
|
* @contributor red1 IDEMPIERE-1711 with final review by Hengsin
|
||||||
*
|
*
|
||||||
|
@ -50,25 +51,28 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger(WProcessCtl.class);
|
private static final CLogger log = CLogger.getCLogger(WProcessCtl.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link #process(int, ProcessInfo, Trx, EventListener)}
|
||||||
|
* @param WindowNo
|
||||||
|
* @param pi
|
||||||
|
* @param trx
|
||||||
|
*/
|
||||||
public static void process (int WindowNo, ProcessInfo pi, Trx trx)
|
public static void process (int WindowNo, ProcessInfo pi, Trx trx)
|
||||||
{
|
{
|
||||||
process(WindowNo, pi, trx, null);
|
process(WindowNo, pi, trx, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process Control
|
* Open ProcessModalDialog to run process.
|
||||||
* <code>
|
* <pre>
|
||||||
* - Get Instance ID
|
* - Create and save {@link MPInstance} if no pi.AD_PInstance_ID.
|
||||||
* - Get Parameters
|
* - Use {@link ProcessModalDialog} to capture process parameters and run process.
|
||||||
* - execute (lock - start process - unlock)
|
* </pre>
|
||||||
* </code>
|
*
|
||||||
* Creates a ProcessCtl instance, which calls
|
* @param WindowNo window no
|
||||||
* lockUI and unlockUI if parent is a ASyncProcess
|
* @param pi ProcessInfo process info
|
||||||
* <br>
|
* @param trx Transaction
|
||||||
*
|
* @param listener listener for {@link ProcessModalDialog}
|
||||||
* @param WindowNo window no
|
|
||||||
* @param pi ProcessInfo process info
|
|
||||||
* @param trx Transaction
|
|
||||||
*/
|
*/
|
||||||
public static void process (int WindowNo, ProcessInfo pi, Trx trx, EventListener<Event> listener)
|
public static void process (int WindowNo, ProcessInfo pi, Trx trx, EventListener<Event> listener)
|
||||||
{
|
{
|
||||||
|
@ -104,7 +108,6 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
ProcessModalDialog para = new ProcessModalDialog(listener, WindowNo, pi, false);
|
ProcessModalDialog para = new ProcessModalDialog(listener, WindowNo, pi, false);
|
||||||
if (para.isValid())
|
if (para.isValid())
|
||||||
{
|
{
|
||||||
//para.setWidth("500px");
|
|
||||||
para.setVisible(true);
|
para.setVisible(true);
|
||||||
|
|
||||||
Object window = SessionManager.getAppDesktop().findWindow(WindowNo);
|
Object window = SessionManager.getAppDesktop().findWindow(WindowNo);
|
||||||
|
@ -116,7 +119,7 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
parent.hideMask();
|
parent.hideMask();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else if (window != null && window instanceof Component){
|
} else if (window != null && window instanceof Component){
|
||||||
final Mask mask = LayoutUtils.showWindowWithMask(para, (Component)window, null);
|
final Mask mask = LayoutUtils.showWindowWithMask(para, (Component)window, null);
|
||||||
para.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
|
para.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,7 +127,7 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
mask.hideMask();
|
mask.hideMask();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
para.setPosition("center");
|
para.setPosition("center");
|
||||||
para.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
|
para.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
|
||||||
AEnv.showWindow(para);
|
AEnv.showWindow(para);
|
||||||
|
@ -134,57 +137,54 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
} // execute
|
} // execute
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async Process - Do it all.
|
* Save parameters and execute process.
|
||||||
* <code>
|
* <pre>
|
||||||
* - Get Instance ID
|
* - Create and save {@link MPInstance} if no pi.AD_PInstance_ID.
|
||||||
* - Get Parameters
|
* - Call parameter.saveParameters ({@link IProcessParameter#saveParameters()}) to save process parameters.
|
||||||
* - execute (lock - start process - unlock)
|
* - Save pi.getRecord_IDs() to T_Selections ({@link DB#createT_Selection(int, java.util.Collection, String)}).
|
||||||
* </code>
|
* - Call {@link WProcessCtl#run()} to execute process.
|
||||||
* Creates a ProcessCtl instance, which calls
|
* </pre>
|
||||||
* lockUI and unlockUI if parent is a ASyncProcess
|
|
||||||
* <br>
|
|
||||||
* Called from ProcessDialog.actionPerformed
|
|
||||||
*
|
*
|
||||||
* @param aProcessUI ASyncProcess and Container
|
* @param aProcessUI {@link IProcessUI}
|
||||||
* @param WindowNo window no
|
* @param WindowNo window no
|
||||||
* @param parameter Process Parameter Panel
|
* @param parameter Process Parameter Panel
|
||||||
* @param pi ProcessInfo process info
|
* @param pi {@link ProcessInfo}
|
||||||
* @param trx Transaction
|
* @param trx Transaction
|
||||||
*/
|
*/
|
||||||
public static void process(IProcessUI aProcessUI, int WindowNo, IProcessParameter parameter, ProcessInfo pi, Trx trx)
|
public static void process(IProcessUI aProcessUI, int WindowNo, IProcessParameter parameter, ProcessInfo pi, Trx trx)
|
||||||
{
|
{
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("WindowNo=" + WindowNo + " - " + pi);
|
if (log.isLoggable(Level.FINE)) log.fine("WindowNo=" + WindowNo + " - " + pi);
|
||||||
|
|
||||||
MPInstance instance = null;
|
MPInstance instance = null;
|
||||||
if (pi.getAD_PInstance_ID() < 1) { //red1 bypass if PInstance exists
|
if (pi.getAD_PInstance_ID() < 1) { //red1 bypass if PInstance exists
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
instance = new MPInstance(Env.getCtx(), pi.getAD_Process_ID(), pi.getRecord_ID());
|
instance = new MPInstance(Env.getCtx(), pi.getAD_Process_ID(), pi.getRecord_ID());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pi.setSummary (e.getLocalizedMessage());
|
||||||
|
pi.setError (true);
|
||||||
|
log.warning(pi.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Error e)
|
||||||
|
{
|
||||||
|
pi.setSummary (e.getLocalizedMessage());
|
||||||
|
pi.setError (true);
|
||||||
|
log.warning(pi.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!instance.save())
|
||||||
|
{
|
||||||
|
pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
|
||||||
|
pi.setError (true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
|
||||||
|
} else {
|
||||||
|
instance = new MPInstance(Env.getCtx(), pi.getAD_PInstance_ID(), null);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
pi.setSummary (e.getLocalizedMessage());
|
|
||||||
pi.setError (true);
|
|
||||||
log.warning(pi.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (Error e)
|
|
||||||
{
|
|
||||||
pi.setSummary (e.getLocalizedMessage());
|
|
||||||
pi.setError (true);
|
|
||||||
log.warning(pi.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!instance.save())
|
|
||||||
{
|
|
||||||
pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
|
|
||||||
pi.setError (true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
|
|
||||||
} else {
|
|
||||||
instance = new MPInstance(Env.getCtx(), pi.getAD_PInstance_ID(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Parameters
|
// Get Parameters
|
||||||
if (parameter != null) {
|
if (parameter != null) {
|
||||||
|
|
|
@ -40,15 +40,15 @@ import org.zkoss.zul.Menuitem;
|
||||||
import org.zkoss.zul.Menupopup;
|
import org.zkoss.zul.Menupopup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base on org.compiere.print.AReport
|
* Launch report for table (immediate or through popup menu, depends on number of print format discover
|
||||||
|
* for AD_Table_ID and AD_Window_ID).
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class WReport implements EventListener<Event> {
|
public class WReport implements EventListener<Event> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Call {@link #WReport(int, MQuery, Component, int)}
|
||||||
*
|
|
||||||
* @param AD_Table_ID table
|
* @param AD_Table_ID table
|
||||||
* @param query query
|
* @param query query
|
||||||
*/
|
*/
|
||||||
|
@ -58,11 +58,10 @@ public class WReport implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Call {@link #WReport(int, MQuery, Component, int, String)}
|
||||||
*
|
|
||||||
* @param AD_Table_ID table
|
* @param AD_Table_ID table
|
||||||
* @param query query
|
* @param query query
|
||||||
* @param parent The invoking parent window
|
* @param parent The invoking parent component
|
||||||
* @param WindowNo The invoking parent window number
|
* @param WindowNo The invoking parent window number
|
||||||
*/
|
*/
|
||||||
public WReport (int AD_Table_ID, MQuery query, Component parent,
|
public WReport (int AD_Table_ID, MQuery query, Component parent,
|
||||||
|
@ -72,7 +71,8 @@ public class WReport implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Launch report immediately (if only one print format found) or show menu popup
|
||||||
|
* for the list of print formats discover for AD_Table_ID and AD_Window_ID (from WindowNo).
|
||||||
*
|
*
|
||||||
* @param AD_Table_ID table
|
* @param AD_Table_ID table
|
||||||
* @param query query
|
* @param query query
|
||||||
|
@ -103,25 +103,26 @@ public class WReport implements EventListener<Event> {
|
||||||
getPrintFormats (AD_Table_ID, AD_Window_ID);
|
getPrintFormats (AD_Table_ID, AD_Window_ID);
|
||||||
} // AReport
|
} // AReport
|
||||||
|
|
||||||
/** The Query */
|
/** Query parameter **/
|
||||||
private MQuery m_query;
|
private MQuery m_query;
|
||||||
|
/** menu popup to show the list of print formats discover **/
|
||||||
private Menupopup m_popup;
|
private Menupopup m_popup;
|
||||||
/** The Option List */
|
/** List of KeyNamePair(AD_PrintFormat_ID,Name) **/
|
||||||
private List<KeyNamePair> m_list = new ArrayList<KeyNamePair>();
|
private List<KeyNamePair> m_list = new ArrayList<KeyNamePair>();
|
||||||
/** Logger */
|
/** Logger **/
|
||||||
private static final CLogger log = CLogger.getCLogger(WReport.class);
|
private static final CLogger log = CLogger.getCLogger(WReport.class);
|
||||||
/** The parent window for locking/unlocking during process execution */
|
/** The invoking parent component **/
|
||||||
Component parent;
|
protected Component parent;
|
||||||
/** The parent window number */
|
/** The parent window number **/
|
||||||
int WindowNo;
|
protected int WindowNo;
|
||||||
/** The filter to apply to this report */
|
/** The filter to apply to this report **/
|
||||||
private String whereExtended;
|
private String whereExtended;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Print Formats for the table.
|
* Get Print Formats for table and window.
|
||||||
* Fill the list and the popup menu
|
* If there's only 1 print format found, call {@link #launchReport(KeyNamePair)}, otherwise call {@link #showPopup()}.
|
||||||
* @param AD_Table_ID table
|
* @param AD_Table_ID table
|
||||||
* @param invoker component to display popup (optional)
|
* @param AD_Window_ID
|
||||||
*/
|
*/
|
||||||
private void getPrintFormats (int AD_Table_ID, int AD_Window_ID)
|
private void getPrintFormats (int AD_Table_ID, int AD_Window_ID)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +135,9 @@ public class WReport implements EventListener<Event> {
|
||||||
showPopup(); // below button
|
showPopup(); // below button
|
||||||
} // getPrintFormats
|
} // getPrintFormats
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show popup menu for the list of print formats found.
|
||||||
|
*/
|
||||||
private void showPopup() {
|
private void showPopup() {
|
||||||
m_popup = new Menupopup();
|
m_popup = new Menupopup();
|
||||||
for(int i = 0; i < m_list.size(); i++)
|
for(int i = 0; i < m_list.size(); i++)
|
||||||
|
@ -150,7 +154,7 @@ public class WReport implements EventListener<Event> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch Report
|
* Launch Report
|
||||||
* @param pp Key=AD_PrintFormat_ID
|
* @param pp KeyNamePair(AD_PrintFormat_ID,Name)
|
||||||
*/
|
*/
|
||||||
private void launchReport (KeyNamePair pp)
|
private void launchReport (KeyNamePair pp)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +206,7 @@ public class WReport implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
} // launchReport
|
} // launchReport
|
||||||
|
|
||||||
/**************************************************************************
|
/**
|
||||||
* Get AD_Table_ID for Table Name
|
* Get AD_Table_ID for Table Name
|
||||||
* @param tableName table name
|
* @param tableName table name
|
||||||
* @return AD_Table_ID or 0
|
* @return AD_Table_ID or 0
|
||||||
|
@ -212,9 +216,11 @@ public class WReport implements EventListener<Event> {
|
||||||
return MTable.getTable_ID(tableName);
|
return MTable.getTable_ID(tableName);
|
||||||
} // getAD_Table_ID
|
} // getAD_Table_ID
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
if(event.getTarget() instanceof Menuitem)
|
if(event.getTarget() instanceof Menuitem)
|
||||||
{
|
{
|
||||||
|
//ON_CLICK event from showPopup() menu item.
|
||||||
Menuitem mi = (Menuitem) event.getTarget();
|
Menuitem mi = (Menuitem) event.getTarget();
|
||||||
launchReport(m_list.get(Integer.parseInt(mi.getValue().toString())));
|
launchReport(m_list.get(Integer.parseInt(mi.getValue().toString())));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue