From 3919827bc5b5698b8b843668b6ed4062627f8473 Mon Sep 17 00:00:00 2001 From: Andreas Sumerauer Date: Sat, 22 May 2021 09:58:02 +0200 Subject: [PATCH] IDempiere-4794 (#694) * IDEMPIERE-4794 IQuickEntry OSGI Service * Interface IQuickeEntry replaced with abstract class AbstractWQuickEntry, Refactorings * QuickEntry Service used in InfoWindow. Redundant method removed. Co-authored-by: Andreas --- .../OSGI-INF/defaultquickentryfactory.xml | 8 +++ .../src/org/adempiere/webui/Extensions.java | 69 ++++++++++++++++++- .../webui/editor/WTableDirEditor.java | 8 ++- .../factory/DefaultQuickEntryFactory.java | 37 ++++++++++ .../webui/factory/IQuickEntryFactory.java | 41 +++++++++++ .../webui/grid/AbstractWQuickEntry.java | 68 ++++++++++++++++++ .../org/adempiere/webui/grid/WQuickEntry.java | 48 +++++++++---- .../org/adempiere/webui/info/InfoWindow.java | 9 +-- 8 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 org.adempiere.ui.zk/OSGI-INF/defaultquickentryfactory.xml create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultQuickEntryFactory.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IQuickEntryFactory.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/AbstractWQuickEntry.java diff --git a/org.adempiere.ui.zk/OSGI-INF/defaultquickentryfactory.xml b/org.adempiere.ui.zk/OSGI-INF/defaultquickentryfactory.xml new file mode 100644 index 0000000000..d164765d7d --- /dev/null +++ b/org.adempiere.ui.zk/OSGI-INF/defaultquickentryfactory.xml @@ -0,0 +1,8 @@ + + + + + + + + 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 d3e0bf418e..f11559e697 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 @@ -2,8 +2,8 @@ * This file is part of Adempiere ERP Bazaar * * http://www.adempiere.org * * * - * Copyright (C) Jorg Viola * - * Copyright (C) Contributors * + * Copyright (C) Jorg Viola * + * Copyright (C) Contributors * * * * 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 * @@ -17,6 +17,7 @@ * * * Contributors: * * - Heng Sin Low * + * - Andreas Sumerauer * *****************************************************************************/ package org.adempiere.webui; @@ -32,6 +33,8 @@ import org.adempiere.webui.apps.graph.IChartRendererService; import org.adempiere.webui.factory.IDashboardGadgetFactory; import org.adempiere.webui.factory.IFormFactory; import org.adempiere.webui.factory.IMappedFormFactory; +import org.adempiere.webui.factory.IQuickEntryFactory; +import org.adempiere.webui.grid.AbstractWQuickEntry; import org.adempiere.webui.panel.ADForm; import org.compiere.grid.ICreateFrom; import org.compiere.grid.ICreateFromFactory; @@ -254,5 +257,65 @@ public class Extensions { } return formFactoryService; } - + + private final static CCache> s_quickEntryFactoryCache = new CCache<>(null, "IQuickEntryFactory", 100, false); + + /** + * + * @param AD_Window_ID + * @return IQuickEntryFactory instance or null if AD_Window_ID not found + */ + private static IQuickEntryFactory getQuickEntryService(Integer AdWindowID) { + IServiceReferenceHolder cache = s_quickEntryFactoryCache.get(AdWindowID); + if (cache != null) { + IQuickEntryFactory service = cache.getService(); + if (service != null) { + return service; + } + s_quickEntryFactoryCache.remove(AdWindowID); + } + List> factories = Service.locator().list(IQuickEntryFactory.class).getServiceReferences(); + if (factories != null) { + for(IServiceReferenceHolder factory : factories) { + IQuickEntryFactory service = factory.getService(); + if (service != null) { + s_quickEntryFactoryCache.put(AdWindowID, factory); + return service; + } + } + } + return null; + } + + /** + * + * @param AD_Window_ID + * @return IQuickEntry instance or null if AD_Window_ID not found + */ + public static AbstractWQuickEntry getQuickEntry(int AD_Window_ID) { + IQuickEntryFactory service = getQuickEntryService(AD_Window_ID); + if (service != null) { + AbstractWQuickEntry quickEntry = service.newQuickEntryInstance(AD_Window_ID); + if (quickEntry != null) + return quickEntry; + } + return null; + } + + /** + * + * @param WindowNo + * @param AD_Window_ID + * @param TabNo + * @return IQuickEntry instance or null if AD_Window_ID not found + */ + public static AbstractWQuickEntry getQuickEntry(int WindowNo, int TabNo, int AD_Window_ID) { + IQuickEntryFactory service = getQuickEntryService(AD_Window_ID); + if (service != null) { + AbstractWQuickEntry quickEntry = service.newQuickEntryInstance(WindowNo, TabNo, AD_Window_ID); + if (quickEntry != null) + return quickEntry; + } + return null; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java index 12b35135fe..948ebf6023 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java @@ -13,6 +13,9 @@ * For the text or an alternative of this public license, you may reach us * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * or via info@posterita.org or http://www.posterita.org/ * + * * + * Contributor: * + * Andreas Sumerauer * *****************************************************************************/ package org.adempiere.webui.editor; @@ -26,6 +29,7 @@ import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.ValuePreference; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.AutoComplete; @@ -34,7 +38,7 @@ import org.adempiere.webui.event.ContextMenuEvent; import org.adempiere.webui.event.ContextMenuListener; import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.ValueChangeEvent; -import org.adempiere.webui.grid.WQuickEntry; +import org.adempiere.webui.grid.AbstractWQuickEntry; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.WFieldRecordInfo; @@ -662,7 +666,7 @@ ContextMenuListener, IZoomableEditor return; int tabNo = gridField != null && gridField.getGridTab() != null ? gridField.getGridTab().getTabNo() : 0; - final WQuickEntry vqe = new WQuickEntry(lookup.getWindowNo(), tabNo, lookup.getZoom()); + final AbstractWQuickEntry vqe = Extensions.getQuickEntry(lookup.getWindowNo(), tabNo, lookup.getZoom()); int Record_ID = 0; Object value = getValue(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultQuickEntryFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultQuickEntryFactory.java new file mode 100644 index 0000000000..6b4398095f --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultQuickEntryFactory.java @@ -0,0 +1,37 @@ +/****************************************************************************** + * Copyright (C) Contributors * + * Product: iDempiere ERP & CRM Smart Business Solution * + * 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. * + * Contributors: * + * Andreas Sumerauer * + *****************************************************************************/ + +package org.adempiere.webui.factory; + +import org.adempiere.webui.grid.AbstractWQuickEntry; +import org.adempiere.webui.grid.WQuickEntry; + + +/** + * @author Andreas Sumerauer + */ +public class DefaultQuickEntryFactory implements IQuickEntryFactory { + + @Override + public AbstractWQuickEntry newQuickEntryInstance(int WindowNo, int TabNo, int AD_Window_ID) { + return new WQuickEntry(WindowNo, TabNo, AD_Window_ID); + } + + @Override + public AbstractWQuickEntry newQuickEntryInstance(int AD_Window_ID) { + return new WQuickEntry(AD_Window_ID); + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IQuickEntryFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IQuickEntryFactory.java new file mode 100644 index 0000000000..c7152f95f7 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IQuickEntryFactory.java @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright (C) Contributors * + * 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. * + * Contributors: * + * Andreas Sumerauer * + *****************************************************************************/ + +package org.adempiere.webui.factory; + +import org.adempiere.webui.grid.AbstractWQuickEntry; + +/** + * + * @author Andreas Sumerauer + * + */ +public interface IQuickEntryFactory { + + /** + * @param WindowNo + * @param TabNo + * @param AD_Window_ID + * @return new QuickEntry instance + */ + public AbstractWQuickEntry newQuickEntryInstance(int WindowNo, int TabNo, int AD_Window_ID); + + /** + * @param AD_Window_ID + * @return new QuickEntry instance + */ + public AbstractWQuickEntry newQuickEntryInstance(int AD_Window_ID); + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/AbstractWQuickEntry.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/AbstractWQuickEntry.java new file mode 100644 index 0000000000..a303f8afd1 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/AbstractWQuickEntry.java @@ -0,0 +1,68 @@ +/****************************************************************************** + * Copyright (C) Contributors * + * Product: iDempiere ERP & CRM Smart Business Solution * + * 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. * + * Contributors: * + * Andreas Sumerauer * + *****************************************************************************/ + +package org.adempiere.webui.grid; + +import org.adempiere.webui.ISupportMask; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.event.ValueChangeListener; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; + +/** + * Quick Entry Window + * Interface based on class WQuickEntry by Carlos Ruiz + * @Author Andreas Sumerauer + */ +public abstract class AbstractWQuickEntry extends Window implements Component, ISupportMask, EventListener, ValueChangeListener +{ + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * check table is editable in quick entry + * user must have write right and table has at least one input field + * @return + */ + public abstract boolean isAvailableQuickEdit (); + + /** + * Load Record_ID + * @param Record_ID - existing Record or 0 for new + * @return true if loaded + */ + public abstract boolean loadRecord (int Record_ID); + + /** + * Returns Record_ID + * @return Record_ID (0 = not saved) + */ + public abstract int getRecord_ID(); + + /** + * refresh all fields + */ + public abstract void dynamicDisplay(); + + /** + * get size quickfields + */ + public abstract int getQuickFields(); + +} // AbstractWQuickEntry diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java index 13c5c7fdc3..d36db4734e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java @@ -10,6 +10,9 @@ * 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. * + * * + * Contributor: * + * Andreas Sumerauer * *****************************************************************************/ package org.adempiere.webui.grid; @@ -21,7 +24,6 @@ import java.util.logging.Level; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; -import org.adempiere.webui.component.Window; import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WLocationEditor; import org.adempiere.webui.editor.WebEditorFactory; @@ -61,7 +63,7 @@ import org.zkoss.zul.Vlayout; * Author: Carlos Ruiz */ -public class WQuickEntry extends Window implements EventListener, ValueChangeListener +public class WQuickEntry extends AbstractWQuickEntry implements EventListener, ValueChangeListener { /** * @@ -80,9 +82,9 @@ public class WQuickEntry extends Window implements EventListener, ValueCh List quickFields = new ArrayList(); protected List quickEditors = new ArrayList(); - List initialValues = new ArrayList(); - List quickTabs = new ArrayList(); - List quickPOs = new ArrayList(); + protected List initialValues = new ArrayList(); + protected List quickTabs = new ArrayList(); + protected List quickPOs = new ArrayList(); /** Read Only */ private boolean m_readOnly = false; @@ -116,11 +118,10 @@ public class WQuickEntry extends Window implements EventListener, ValueCh parent_WindowNo = WindowNo; parent_TabNo = TabNo; m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); - log.info("R/O=" + m_readOnly); try { - jbInit(); + initLayout(); } catch(Exception ex) { @@ -131,6 +132,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_WINDOW, parent_WindowNo); Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_TAB, parent_TabNo); initPOs(); + log.info("R/O=" + isReadOnly()); } // WQuickEntry @@ -141,7 +143,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh m_AD_Window_ID = AD_Window_ID; parent_WindowNo = 0; m_WindowNo = 0; - log.info("R/O=" + m_readOnly); + log.info("R/O=" + isReadOnly()); } // WQuickEntry /** @@ -149,7 +151,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh * @throws Exception */ - private void jbInit() throws Exception + protected void initLayout() throws Exception { if (!ThemeManager.isUseCSSForWindowSize()) { ZKUpdateUtil.setWindowWidthX(this, 350); @@ -217,7 +219,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh if (! isValidQuickEntryType(field.getAD_Reference_ID())) continue; WEditor editor = WebEditorFactory.getEditor(gridfield, false); - if (m_readOnly) + if (isReadOnly()) editor.setReadWrite(false); if (gridfield.isMandatory(false)) editor.setMandatory(true); @@ -286,7 +288,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh * @return */ public boolean isAvailableQuickEdit (){ - return isHasField && !m_readOnly; + return isHasField && !isReadOnly(); } /** @@ -298,6 +300,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh public boolean loadRecord (int Record_ID) { String parentColumn = null; + quickPOs = new ArrayList(); for (int idxt = 0; idxt < quickTabs.size(); idxt++) { GridTab gridtab = quickTabs.get(idxt); int id = 0; @@ -513,7 +516,7 @@ public class WQuickEntry extends Window implements EventListener, ValueCh public void onEvent(Event e) throws Exception { - if (m_readOnly) + if (isReadOnly()) this.detach(); // OK pressed @@ -552,10 +555,10 @@ public class WQuickEntry extends Window implements EventListener, ValueCh // see WLocationEditor firing twice ValueChangeEvent (first with null and then with value) } else { mTable.setValueAt(evt.getNewValue(), row, col); - field.setValue(evt.getNewValue(), field.getGridTab().getTableModel().isInserting()); + // field.setValue(evt.getNewValue(), field.getGridTab().getTableModel().isInserting()); gridTab.processFieldChange(field); } - // Refresh the list on dependant fields + // Refresh the list on dependent fields ArrayList dependants = gridTab.getDependantFields(columnName); for (GridField dependentField : dependants) { @@ -609,8 +612,23 @@ public class WQuickEntry extends Window implements EventListener, ValueCh /** * get size quickfields */ - public int getQuickFields(){ + public final int getQuickFields(){ return quickFields.size(); }// size of quickfields + /** + * get readOnly + */ + protected final boolean isReadOnly() { + return m_readOnly; + } + + /** + * @return the confirmPanel + */ + protected final ConfirmPanel getConfirmPanel() { + return confirmPanel; + } + } // WQuickEntry + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index b35ebb330e..3f10c5c1ad 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -24,6 +24,7 @@ import org.adempiere.model.MInfoProcess; import org.adempiere.model.MInfoRelated; import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.ISupportMask; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; @@ -57,7 +58,7 @@ import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeListener; import org.adempiere.webui.event.WTableModelEvent; import org.adempiere.webui.factory.ButtonFactory; -import org.adempiere.webui.grid.WQuickEntry; +import org.adempiere.webui.grid.AbstractWQuickEntry; import org.adempiere.webui.panel.InfoPanel; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; @@ -150,7 +151,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL protected TableInfo[] tableInfos; protected InfoColumnVO[] infoColumns; - protected WQuickEntry vqe; + protected AbstractWQuickEntry vqe; private List gridFields; private TreeMap> parameterTree; @@ -2181,7 +2182,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID()); hasRightQuickEntry = gridwindow != null; if (hasRightQuickEntry) - vqe = new WQuickEntry (0, getADWindowID()); + vqe = Extensions.getQuickEntry(0, 0, getADWindowID()); } return hasNew && vqe != null && vqe.isAvailableQuickEdit(); @@ -2208,7 +2209,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL // each time close WQuickEntry dialog, // window is un-registry, variable environment of this window as _QUICK_ENTRY_MODE_ is removed // so if reuse WQuickEntry will let some field in child tab init at read only state - WQuickEntry vqe = new WQuickEntry (0, getADWindowID()); + AbstractWQuickEntry vqe = Extensions.getQuickEntry(0, 0, getADWindowID()); vqe.loadRecord (0);