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 <sumerauer@kanzlei-wmv.de>
This commit is contained in:
Andreas Sumerauer 2021-05-22 09:58:02 +02:00 committed by GitHub
parent e8b76e24bb
commit 3919827bc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 264 additions and 24 deletions

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE scr:component>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.webui.factory.DefaultQuickEntryFactory">
<implementation class="org.adempiere.webui.factory.DefaultQuickEntryFactory"/>
<service>
<provide interface="org.adempiere.webui.factory.IQuickEntryFactory"/>
</service>
</scr:component>

View File

@ -2,8 +2,8 @@
* This file is part of Adempiere ERP Bazaar * * This file is part of Adempiere ERP Bazaar *
* http://www.adempiere.org * * http://www.adempiere.org *
* * * *
* Copyright (C) Jorg Viola * * Copyright (C) Jorg Viola *
* Copyright (C) Contributors * * Copyright (C) Contributors *
* * * *
* This program is free software; you can redistribute it and/or modify it * * 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 * * under the terms version 2 of the GNU General Public License as published *
@ -17,6 +17,7 @@
* * * *
* Contributors: * * Contributors: *
* - Heng Sin Low * * - Heng Sin Low *
* - Andreas Sumerauer *
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui; 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.IDashboardGadgetFactory;
import org.adempiere.webui.factory.IFormFactory; import org.adempiere.webui.factory.IFormFactory;
import org.adempiere.webui.factory.IMappedFormFactory; 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.adempiere.webui.panel.ADForm;
import org.compiere.grid.ICreateFrom; import org.compiere.grid.ICreateFrom;
import org.compiere.grid.ICreateFromFactory; import org.compiere.grid.ICreateFromFactory;
@ -254,5 +257,65 @@ public class Extensions {
} }
return formFactoryService; return formFactoryService;
} }
private final static CCache<Integer, IServiceReferenceHolder<IQuickEntryFactory>> 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<IQuickEntryFactory> cache = s_quickEntryFactoryCache.get(AdWindowID);
if (cache != null) {
IQuickEntryFactory service = cache.getService();
if (service != null) {
return service;
}
s_quickEntryFactoryCache.remove(AdWindowID);
}
List<IServiceReferenceHolder<IQuickEntryFactory>> factories = Service.locator().list(IQuickEntryFactory.class).getServiceReferences();
if (factories != null) {
for(IServiceReferenceHolder<IQuickEntryFactory> 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;
}
} }

View File

@ -13,6 +13,9 @@
* For the text or an alternative of this public license, you may reach us * * For the text or an alternative of this public license, you may reach us *
* Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
* or via info@posterita.org or http://www.posterita.org/ * * or via info@posterita.org or http://www.posterita.org/ *
* *
* Contributor: *
* Andreas Sumerauer *
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui.editor; package org.adempiere.webui.editor;
@ -26,6 +29,7 @@ import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener; import javax.swing.event.ListDataListener;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.ValuePreference; import org.adempiere.webui.ValuePreference;
import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.AutoComplete; 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.ContextMenuListener;
import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.event.ValueChangeEvent; 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.theme.ThemeManager;
import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.WFieldRecordInfo; import org.adempiere.webui.window.WFieldRecordInfo;
@ -662,7 +666,7 @@ ContextMenuListener, IZoomableEditor
return; return;
int tabNo = gridField != null && gridField.getGridTab() != null ? gridField.getGridTab().getTabNo() : 0; 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; int Record_ID = 0;
Object value = getValue(); Object value = getValue();

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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<Event>, 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

View File

@ -10,6 +10,9 @@
* You should have received a copy of the GNU General Public License along * * 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., * * with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* *
* Contributor: *
* Andreas Sumerauer *
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui.grid; package org.adempiere.webui.grid;
@ -21,7 +24,6 @@ import java.util.logging.Level;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WEditor;
import org.adempiere.webui.editor.WLocationEditor; import org.adempiere.webui.editor.WLocationEditor;
import org.adempiere.webui.editor.WebEditorFactory; import org.adempiere.webui.editor.WebEditorFactory;
@ -61,7 +63,7 @@ import org.zkoss.zul.Vlayout;
* Author: Carlos Ruiz * Author: Carlos Ruiz
*/ */
public class WQuickEntry extends Window implements EventListener<Event>, ValueChangeListener public class WQuickEntry extends AbstractWQuickEntry implements EventListener<Event>, ValueChangeListener
{ {
/** /**
* *
@ -80,9 +82,9 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
List<GridField> quickFields = new ArrayList<GridField>(); List<GridField> quickFields = new ArrayList<GridField>();
protected List<WEditor> quickEditors = new ArrayList<WEditor>(); protected List<WEditor> quickEditors = new ArrayList<WEditor>();
List<Object> initialValues = new ArrayList<Object>(); protected List<Object> initialValues = new ArrayList<Object>();
List<GridTab> quickTabs = new ArrayList<GridTab>(); protected List<GridTab> quickTabs = new ArrayList<GridTab>();
List<PO> quickPOs = new ArrayList<PO>(); protected List<PO> quickPOs = new ArrayList<PO>();
/** Read Only */ /** Read Only */
private boolean m_readOnly = false; private boolean m_readOnly = false;
@ -116,11 +118,10 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
parent_WindowNo = WindowNo; parent_WindowNo = WindowNo;
parent_TabNo = TabNo; parent_TabNo = TabNo;
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
log.info("R/O=" + m_readOnly);
try try
{ {
jbInit(); initLayout();
} }
catch(Exception ex) catch(Exception ex)
{ {
@ -131,6 +132,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_WINDOW, parent_WindowNo); Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_WINDOW, parent_WindowNo);
Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_TAB, parent_TabNo); Env.setContext(Env.getCtx(), m_WindowNo, QUICK_ENTRY_CALLER_TAB, parent_TabNo);
initPOs(); initPOs();
log.info("R/O=" + isReadOnly());
} // WQuickEntry } // WQuickEntry
@ -141,7 +143,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
m_AD_Window_ID = AD_Window_ID; m_AD_Window_ID = AD_Window_ID;
parent_WindowNo = 0; parent_WindowNo = 0;
m_WindowNo = 0; m_WindowNo = 0;
log.info("R/O=" + m_readOnly); log.info("R/O=" + isReadOnly());
} // WQuickEntry } // WQuickEntry
/** /**
@ -149,7 +151,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
* @throws Exception * @throws Exception
*/ */
private void jbInit() throws Exception protected void initLayout() throws Exception
{ {
if (!ThemeManager.isUseCSSForWindowSize()) { if (!ThemeManager.isUseCSSForWindowSize()) {
ZKUpdateUtil.setWindowWidthX(this, 350); ZKUpdateUtil.setWindowWidthX(this, 350);
@ -217,7 +219,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
if (! isValidQuickEntryType(field.getAD_Reference_ID())) if (! isValidQuickEntryType(field.getAD_Reference_ID()))
continue; continue;
WEditor editor = WebEditorFactory.getEditor(gridfield, false); WEditor editor = WebEditorFactory.getEditor(gridfield, false);
if (m_readOnly) if (isReadOnly())
editor.setReadWrite(false); editor.setReadWrite(false);
if (gridfield.isMandatory(false)) if (gridfield.isMandatory(false))
editor.setMandatory(true); editor.setMandatory(true);
@ -286,7 +288,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
* @return * @return
*/ */
public boolean isAvailableQuickEdit (){ public boolean isAvailableQuickEdit (){
return isHasField && !m_readOnly; return isHasField && !isReadOnly();
} }
/** /**
@ -298,6 +300,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
public boolean loadRecord (int Record_ID) public boolean loadRecord (int Record_ID)
{ {
String parentColumn = null; String parentColumn = null;
quickPOs = new ArrayList<PO>();
for (int idxt = 0; idxt < quickTabs.size(); idxt++) { for (int idxt = 0; idxt < quickTabs.size(); idxt++) {
GridTab gridtab = quickTabs.get(idxt); GridTab gridtab = quickTabs.get(idxt);
int id = 0; int id = 0;
@ -513,7 +516,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
public void onEvent(Event e) throws Exception public void onEvent(Event e) throws Exception
{ {
if (m_readOnly) if (isReadOnly())
this.detach(); this.detach();
// OK pressed // OK pressed
@ -552,10 +555,10 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
// see WLocationEditor firing twice ValueChangeEvent (first with null and then with value) // see WLocationEditor firing twice ValueChangeEvent (first with null and then with value)
} else { } else {
mTable.setValueAt(evt.getNewValue(), row, col); 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); gridTab.processFieldChange(field);
} }
// Refresh the list on dependant fields // Refresh the list on dependent fields
ArrayList<GridField> dependants = gridTab.getDependantFields(columnName); ArrayList<GridField> dependants = gridTab.getDependantFields(columnName);
for (GridField dependentField : dependants) for (GridField dependentField : dependants)
{ {
@ -609,8 +612,23 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
/** /**
* get size quickfields * get size quickfields
*/ */
public int getQuickFields(){ public final int getQuickFields(){
return quickFields.size(); return quickFields.size();
}// size of quickfields }// size of quickfields
/**
* get readOnly
*/
protected final boolean isReadOnly() {
return m_readOnly;
}
/**
* @return the confirmPanel
*/
protected final ConfirmPanel getConfirmPanel() {
return confirmPanel;
}
} // WQuickEntry } // WQuickEntry

View File

@ -24,6 +24,7 @@ import org.adempiere.model.MInfoProcess;
import org.adempiere.model.MInfoRelated; import org.adempiere.model.MInfoRelated;
import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.AdempiereWebUI;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.ISupportMask; import org.adempiere.webui.ISupportMask;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv; 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.ValueChangeListener;
import org.adempiere.webui.event.WTableModelEvent; import org.adempiere.webui.event.WTableModelEvent;
import org.adempiere.webui.factory.ButtonFactory; 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.panel.InfoPanel;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.theme.ThemeManager;
@ -150,7 +151,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
protected TableInfo[] tableInfos; protected TableInfo[] tableInfos;
protected InfoColumnVO[] infoColumns; protected InfoColumnVO[] infoColumns;
protected WQuickEntry vqe; protected AbstractWQuickEntry vqe;
private List<GridField> gridFields; private List<GridField> gridFields;
private TreeMap<Integer, List<Object[]>> parameterTree; private TreeMap<Integer, List<Object[]>> parameterTree;
@ -2181,7 +2182,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID()); GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID());
hasRightQuickEntry = gridwindow != null; hasRightQuickEntry = gridwindow != null;
if (hasRightQuickEntry) if (hasRightQuickEntry)
vqe = new WQuickEntry (0, getADWindowID()); vqe = Extensions.getQuickEntry(0, 0, getADWindowID());
} }
return hasNew && vqe != null && vqe.isAvailableQuickEdit(); return hasNew && vqe != null && vqe.isAvailableQuickEdit();
@ -2208,7 +2209,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
// each time close WQuickEntry dialog, // each time close WQuickEntry dialog,
// window is un-registry, variable environment of this window as _QUICK_ENTRY_MODE_ is removed // 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 // 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); vqe.loadRecord (0);