diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java index be445df53f..cc46b127e1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java @@ -23,6 +23,8 @@ package org.adempiere.webui; import java.util.List; import org.adempiere.base.Service; +import org.adempiere.base.ServiceQuery; +import org.adempiere.webui.apps.IProcessParameterListener; import org.adempiere.webui.factory.IFormFactory; import org.adempiere.webui.panel.ADForm; @@ -50,4 +52,18 @@ public class Extensions { } return null; } + + /** + * + * @param processClass + * @param columnName + * @return list of parameter listener + */ + public static List getProcessParameterListeners(String processClass, String columnName) { + ServiceQuery query = new ServiceQuery(); + query.put("ProcessClass", processClass); + if (columnName != null) + query.put("|ColumnName", columnName+"|"+columnName+",*|"+"*,"+columnName+",*|"+"*,"+columnName); + return Service.locator().list(IProcessParameterListener.class, null, query).getServices(); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java new file mode 100644 index 0000000000..5ebe52790d --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java @@ -0,0 +1,40 @@ +/****************************************************************************** + * Product: iDempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2018 iDempiere.org. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.adempiere.webui.apps; + +import org.adempiere.webui.editor.WEditor; + +/** + * Listener interface for process parameter panel + * @author hengsin + * + */ +public interface IProcessParameterListener { + /** + * on value change of parameter field editor + * @param parameterPanel + * @param columnName + * @param editor + */ + public void onChange(ProcessParameterPanel parameterPanel, String columnName, WEditor editor); + + /** + * validate process parameter form + * @param parameterPanel + * @return error message (if any) + */ + public default String validate(ProcessParameterPanel parameterPanel) { + return null; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java index c92169b069..dadb1f0ec6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java @@ -94,7 +94,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene */ 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"; /** Logger */ private static CLogger log = CLogger.getCLogger(ProcessDialog.class); @@ -138,6 +140,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene querySaved(); addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this); addEventListener(ON_INITIAL_FOCUS_EVENT, this); + addEventListener(ON_OK_ECHO, this); } catch(Exception ex) { @@ -188,10 +191,9 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene } else if (bOK.equals(component)) { super.onEvent(event); - if (isParameterPage) - startProcess(); - else - restart(); + onOk(); + } else if (event.getName().equals(ON_OK_ECHO)) { + onOk(); }else if (bCancel.equals(component)){ super.onEvent(event); cancelProcess(); @@ -228,6 +230,20 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene } } + private void onOk() { + if (isParameterPage) + { + if (getParameterPanel().isWaitingForDialog()) + { + Events.echoEvent(ON_OK_ECHO, this, null); + return; + } + startProcess(); + } + else + restart(); + } + private void onCtrlKeyEvent(KeyEvent keyEvent) { if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X if (m_WindowNo > 0) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java index ddcb1db99a..11c7d1ad18 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java @@ -30,6 +30,7 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; /** * @@ -48,6 +49,9 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi * */ private static final long serialVersionUID = -6227339628038418701L; + + private static final String ON_OK_ECHO = "onOkEcho"; + /** Logger */ private static CLogger log = CLogger.getCLogger(ProcessModalDialog.class); // @@ -112,6 +116,7 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi { log.log(Level.SEVERE, "", ex); } + addEventListener(ON_OK_ECHO, this); } public ProcessModalDialog (int WindowNo, int AD_Process_ID, int tableId, int recordId, boolean autoStart) @@ -199,13 +204,24 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi Component component = event.getTarget(); if (component.equals(bOK)) { super.onEvent(event); - startProcess(); + onOk(); + } else if (event.getName().equals(ON_OK_ECHO)) { + onOk(); } else if (component.equals(bCancel)) { super.onEvent(event); cancelProcess(); }else { super.onEvent(event); } + } + + private void onOk() { + if (getParameterPanel().isWaitingForDialog()) + { + Events.echoEvent(ON_OK_ECHO, this, null); + return; + } + startProcess(); } protected void onClientInfo() { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java index 3f7ef31270..bd6638fc2e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; +import org.adempiere.webui.Extensions; import org.adempiere.webui.component.Column; import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.EditorBox; @@ -36,6 +37,7 @@ import org.adempiere.webui.component.Urlbox; import org.adempiere.webui.editor.IZoomableEditor; import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WEditorPopupMenu; +import org.adempiere.webui.editor.WSearchEditor; import org.adempiere.webui.editor.WebEditorFactory; import org.adempiere.webui.event.ContextMenuListener; import org.adempiere.webui.event.ValueChangeEvent; @@ -50,12 +52,14 @@ import org.compiere.model.MClient; import org.compiere.model.MLookup; import org.compiere.model.MPInstance; import org.compiere.model.MPInstancePara; +import org.compiere.model.MProcess; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.compiere.util.Util; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.event.Event; @@ -99,6 +103,7 @@ public class ProcessParameterPanel extends Panel implements // initComponent(); addEventListener("onDynamicDisplay", this); + addEventListener("onPostEditorValueChange", this); } // ProcessParameterPanel private void initComponent() { @@ -445,6 +450,18 @@ public class ProcessParameterPanel extends Panel implements return false; } + if (m_processInfo.getAD_Process_ID() > 0) { + String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname(); + List listeners = Extensions.getProcessParameterListeners(className, null); + for(IProcessParameterListener listener : listeners) { + String error = listener.validate(this); + if (!Util.isEmpty(error)) { + FDialog.error(m_WindowNo, this, error); + return false; + } + } + } + return true; } // validateParameters @@ -703,6 +720,7 @@ public class ProcessParameterPanel extends Panel implements processDependencies (changedField); // future processCallout (changedField); } + Events.postEvent("onPostEditorValueChange", this, evt.getSource()); } processNewValue(evt.getNewValue(), evt.getPropertyName()); } @@ -731,8 +749,21 @@ public class ProcessParameterPanel extends Panel implements else if (event.getName().equals("onDynamicDisplay")) { dynamicDisplay(); } + else if (event.getName().equals("onPostEditorValueChange")) { + onPostEditorValueChange((WEditor)event.getData()); + } } + private void onPostEditorValueChange(WEditor editor) { + if (m_processInfo.getAD_Process_ID() > 0) { + String className = MProcess.get(Env.getCtx(), m_processInfo.getAD_Process_ID()).getClassname(); + List listeners = Extensions.getProcessParameterListeners(className, editor.getColumnName()); + for(IProcessParameterListener listener : listeners) { + listener.onChange(this, editor.getColumnName(), editor); + } + } + } + /** * Evaluate Dependencies * @param changedField changed field @@ -874,6 +905,54 @@ public class ProcessParameterPanel extends Panel implements ((HtmlBasedComponent)c).focus(); } + /** + * Get parameter field editor by column name + * @param columnName + * @return editor + */ + public WEditor getEditor(String columnName) { + for(int i = 0; i < m_mFields.size(); i++) { + if (m_mFields.get(i).getColumnName().equals(columnName)) { + return m_wEditors.get(i); + } + } + return null; + } + + /** + * Get parameter field value to editor by column name + * @param columnName + * @return editor + */ + public WEditor getEditorTo(String columnName) { + for(int i = 0; i < m_mFields.size(); i++) { + if (m_mFields.get(i).getColumnName().equals(columnName)) { + return m_wEditors2.get(i); + } + } + return null; + } + + /** + * @return true if editor is showing dialog awaiting user action + */ + public boolean isWaitingForDialog() { + for (int i = 0; i < m_mFields.size(); i++) { + // Get Values + WEditor editor = (WEditor) m_wEditors.get(i); + WEditor editor2 = (WEditor) m_wEditors2.get(i); + if (editor != null && editor instanceof WSearchEditor) { + if (((WSearchEditor)editor).isShowingDialog()) + return true; + } else if (editor2 != null && editor2 instanceof WSearchEditor) { + if (((WSearchEditor)editor2).isShowingDialog()) + return true; + } + } + + return false; + } + static class ZoomListener implements EventListener { private IZoomableEditor searchEditor;