IDEMPIERE-5772 - Quick Info Widget Support for Info Window (#1899)
* IDEMPIERE-5772 - Quick Info Widget Support for Info Window - initial commit * IDEMPIERE-5772 - manage context variables in info window Put the following values into the context: - query criteria - values of the selected row * IDEMPIERE-5772 - fixes - info window should not change context if isLookup() = true (popup window mode) - parameter values should be put into context only on re-query - values of KeyNamePair type should use the "key" in context (practically tat means the ID) instead of name (display value) * IDEMPIERE-5772 - add prefix to row variables and Selected_ID to ctx * IDEMPIERE-5772 - rename variable name Selected_ID -> ID_Selection * IDEMPIERE-5772 - patch by Carlos * IDEMPIERE-5772 - fixed reported issues - support ctx variables in info windows without process (no multiselection) - change ctx variable syntax/prefix - fix issue with type IDColumn
This commit is contained in:
parent
407b756cb8
commit
ca98a81671
|
@ -0,0 +1,53 @@
|
|||
-- IDEMPIERE-5772
|
||||
SELECT register_migration_script('202306190914_IDEMPIERE-5772.sql') FROM dual;
|
||||
|
||||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- Jun 19, 2023, 9:14:41 AM CEST
|
||||
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215853,0,'Info Window','Info and search/select Window','The Info window is used to search and select records as well as display information relevant to the selection.',200108,'AD_InfoWindow_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-06-19 09:14:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-06-19 09:14:40','YYYY-MM-DD HH24:MI:SS'),100,3068,'Y','N','D','N','N','N','Y','78d7ed91-8563-461a-ab16-39e62c393e78','Y',0,'N','N','C','N')
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
UPDATE AD_Column SET FKConstraintName='ADInfoWindow_ADStatusLineUsedI', FKConstraintType='C',Updated=TO_TIMESTAMP('2023-06-19 09:14:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215853
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
ALTER TABLE AD_StatusLineUsedIn ADD AD_InfoWindow_ID NUMBER(10) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
ALTER TABLE AD_StatusLineUsedIn ADD CONSTRAINT ADInfoWindow_ADStatusLineUsedI FOREIGN KEY (AD_InfoWindow_ID) REFERENCES ad_infowindow(ad_infowindow_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:15:04 AM CEST
|
||||
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (207654,'Info Window','Info and search/select Window','The Info window is used to search and select records as well as display information relevant to the selection.',200115,215853,'Y',22,110,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-06-19 09:15:03','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-06-19 09:15:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','2ab90c17-a77d-4b89-bc17-17dc3f7b775d','Y',80,2)
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Window_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=40,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202573
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Table_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=60,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202574
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Table_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=70,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202575
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET IsDisplayed='Y', DisplayLogic='@AD_Table_ID@=0 & @AD_Window_ID@=0', SeqNo=80, XPosition=1,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207654
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET SeqNo=100,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202576
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET SeqNo=110,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202578
|
||||
;
|
||||
|
||||
-- Jul 13, 2023, 6:38:30 PM CEST
|
||||
UPDATE AD_Column SET DefaultValue='NULL',Updated=TO_TIMESTAMP('2023-07-13 18:38:30','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215853
|
||||
;
|
|
@ -0,0 +1,50 @@
|
|||
-- IDEMPIERE-5772
|
||||
SELECT register_migration_script('202306190914_IDEMPIERE-5772.sql') FROM dual;
|
||||
|
||||
-- Jun 19, 2023, 9:14:41 AM CEST
|
||||
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215853,0,'Info Window','Info and search/select Window','The Info window is used to search and select records as well as display information relevant to the selection.',200108,'AD_InfoWindow_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-06-19 09:14:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-06-19 09:14:40','YYYY-MM-DD HH24:MI:SS'),100,3068,'Y','N','D','N','N','N','Y','78d7ed91-8563-461a-ab16-39e62c393e78','Y',0,'N','N','C','N')
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
UPDATE AD_Column SET FKConstraintName='ADInfoWindow_ADStatusLineUsedI', FKConstraintType='C',Updated=TO_TIMESTAMP('2023-06-19 09:14:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215853
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
ALTER TABLE AD_StatusLineUsedIn ADD COLUMN AD_InfoWindow_ID NUMERIC(10) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:14:44 AM CEST
|
||||
ALTER TABLE AD_StatusLineUsedIn ADD CONSTRAINT ADInfoWindow_ADStatusLineUsedI FOREIGN KEY (AD_InfoWindow_ID) REFERENCES ad_infowindow(ad_infowindow_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:15:04 AM CEST
|
||||
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (207654,'Info Window','Info and search/select Window','The Info window is used to search and select records as well as display information relevant to the selection.',200115,215853,'Y',22,110,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-06-19 09:15:03','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-06-19 09:15:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','2ab90c17-a77d-4b89-bc17-17dc3f7b775d','Y',80,2)
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Window_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=40,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202573
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Table_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=60,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202574
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET DisplayLogic='@AD_Table_ID@=0 & @AD_InfoWindow_ID@=0', SeqNo=70,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202575
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET IsDisplayed='Y', DisplayLogic='@AD_Table_ID@=0 & @AD_Window_ID@=0', SeqNo=80, XPosition=1,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207654
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET SeqNo=100,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202576
|
||||
;
|
||||
|
||||
-- Jun 19, 2023, 9:22:16 AM CEST
|
||||
UPDATE AD_Field SET SeqNo=110,Updated=TO_TIMESTAMP('2023-06-19 09:22:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202578
|
||||
;
|
||||
|
||||
-- Jul 13, 2023, 6:38:30 PM CEST
|
||||
UPDATE AD_Column SET DefaultValue='NULL',Updated=TO_TIMESTAMP('2023-07-13 18:38:30','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215853
|
||||
;
|
|
@ -49,6 +49,21 @@ public interface I_AD_StatusLineUsedIn
|
|||
*/
|
||||
public int getAD_Client_ID();
|
||||
|
||||
/** Column name AD_InfoWindow_ID */
|
||||
public static final String COLUMNNAME_AD_InfoWindow_ID = "AD_InfoWindow_ID";
|
||||
|
||||
/** Set Info Window.
|
||||
* Info and search/select Window
|
||||
*/
|
||||
public void setAD_InfoWindow_ID (int AD_InfoWindow_ID);
|
||||
|
||||
/** Get Info Window.
|
||||
* Info and search/select Window
|
||||
*/
|
||||
public int getAD_InfoWindow_ID();
|
||||
|
||||
public org.compiere.model.I_AD_InfoWindow getAD_InfoWindow() throws RuntimeException;
|
||||
|
||||
/** Column name AD_Org_ID */
|
||||
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
|
||||
|
||||
|
|
|
@ -189,7 +189,19 @@ public class MStatusLine extends X_AD_StatusLine implements ImmutablePOSupport
|
|||
* @return array of widget lines discovered for table or specific tab or general window
|
||||
*/
|
||||
public static MStatusLine[] getStatusLinesWidget(int window_ID, int tab_ID, int table_ID) {
|
||||
StringBuilder key = new StringBuilder().append(window_ID).append("|").append(tab_ID).append("|").append(table_ID);
|
||||
return getStatusLinesWidget(window_ID, tab_ID, table_ID, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the widget lines defined for the window and tab and table (immutable)
|
||||
* @param window_ID
|
||||
* @param tab_ID
|
||||
* @param table_ID
|
||||
* @param infoWindow_ID
|
||||
* @return array of widget lines discovered for table or specific tab or general window
|
||||
*/
|
||||
public static MStatusLine[] getStatusLinesWidget(int window_ID, int tab_ID, int table_ID, int infoWindow_ID) {
|
||||
StringBuilder key = new StringBuilder().append(window_ID).append("|").append(tab_ID).append("|").append(table_ID).append("|").append(infoWindow_ID);
|
||||
MStatusLine[] retValue = null;
|
||||
if (s_cachew.containsKey(key.toString()))
|
||||
{
|
||||
|
@ -205,9 +217,12 @@ public class MStatusLine extends X_AD_StatusLine implements ImmutablePOSupport
|
|||
+ "WHERE slu.IsActive = 'Y' "
|
||||
+ " AND sl.IsActive = 'Y' "
|
||||
+ " AND slu.IsStatusLine = 'N' "
|
||||
+ " AND (slu.AD_Table_ID = ? OR (slu.AD_Window_ID=? AND slu.AD_Tab_ID=?) OR (slu.AD_Window_ID=? AND slu.AD_Tab_ID IS NULL)) "
|
||||
+ " AND (slu.AD_Table_ID = ? "
|
||||
+ " OR (slu.AD_Window_ID=? AND slu.AD_Tab_ID=?) "
|
||||
+ " OR (slu.AD_Window_ID=? AND slu.AD_Tab_ID IS NULL)"
|
||||
+ " OR slu.AD_InfoWindow_ID=?) "
|
||||
+ "ORDER BY slu.SeqNo";
|
||||
int[] wlids = DB.getIDsEx(null, sql, table_ID, window_ID, tab_ID, window_ID);
|
||||
int[] wlids = DB.getIDsEx(null, sql, table_ID, window_ID, tab_ID, window_ID, infoWindow_ID);
|
||||
if (wlids.length > 0) {
|
||||
ArrayList<MStatusLine> list = new ArrayList<MStatusLine>();
|
||||
for (int wlid : wlids) {
|
||||
|
|
|
@ -71,11 +71,21 @@ public class MStatusLineUsedIn extends X_AD_StatusLineUsedIn
|
|||
if (getAD_Table_ID() > 0) {
|
||||
setAD_Window_ID(0);
|
||||
setAD_Tab_ID(0);
|
||||
} else {
|
||||
if (getAD_Window_ID() <= 0) {
|
||||
log.saveError("SaveError", Msg.parseTranslation(getCtx(), "@FillMandatory@ @AD_Table_ID@ @AD_Window_ID@"));
|
||||
return false;
|
||||
}
|
||||
setAD_InfoWindow_ID(0);
|
||||
}
|
||||
else if (getAD_Window_ID() > 0) {
|
||||
setAD_Table_ID(0);
|
||||
setAD_InfoWindow_ID(0);
|
||||
}
|
||||
else if (getAD_InfoWindow_ID() > 0) {
|
||||
setAD_Table_ID(0);
|
||||
setAD_Window_ID(0);
|
||||
setAD_Tab_ID(0);
|
||||
}
|
||||
else {
|
||||
log.saveError("SaveError", Msg.parseTranslation(getCtx(), "@FillMandatory@ @AD_Table_ID@ @AD_Window_ID@ @AD_InfoWindow_ID@"));
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_StatusLineUsedIn extends PO implements I_AD_StatusLineUsedIn,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20230409L;
|
||||
private static final long serialVersionUID = 20230619L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_StatusLineUsedIn (Properties ctx, int AD_StatusLineUsedIn_ID, String trxName)
|
||||
|
@ -147,6 +147,34 @@ public class X_AD_StatusLineUsedIn extends PO implements I_AD_StatusLineUsedIn,
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
public org.compiere.model.I_AD_InfoWindow getAD_InfoWindow() throws RuntimeException
|
||||
{
|
||||
return (org.compiere.model.I_AD_InfoWindow)MTable.get(getCtx(), org.compiere.model.I_AD_InfoWindow.Table_ID)
|
||||
.getPO(getAD_InfoWindow_ID(), get_TrxName());
|
||||
}
|
||||
|
||||
/** Set Info Window.
|
||||
@param AD_InfoWindow_ID Info and search/select Window
|
||||
*/
|
||||
public void setAD_InfoWindow_ID (int AD_InfoWindow_ID)
|
||||
{
|
||||
if (AD_InfoWindow_ID < 1)
|
||||
set_Value (COLUMNNAME_AD_InfoWindow_ID, null);
|
||||
else
|
||||
set_Value (COLUMNNAME_AD_InfoWindow_ID, Integer.valueOf(AD_InfoWindow_ID));
|
||||
}
|
||||
|
||||
/** Get Info Window.
|
||||
@return Info and search/select Window
|
||||
*/
|
||||
public int getAD_InfoWindow_ID()
|
||||
{
|
||||
Integer ii = (Integer)get_Value(COLUMNNAME_AD_InfoWindow_ID);
|
||||
if (ii == null)
|
||||
return 0;
|
||||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** Set AD_StatusLineUsedIn.
|
||||
@param AD_StatusLineUsedIn_ID AD_StatusLineUsedIn
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.adempiere.webui.panel.ADForm;
|
|||
import org.adempiere.webui.panel.BroadcastMessageWindow;
|
||||
import org.adempiere.webui.panel.HeaderPanel;
|
||||
import org.adempiere.webui.panel.HelpController;
|
||||
import org.adempiere.webui.panel.InfoPanel;
|
||||
import org.adempiere.webui.panel.TimeoutPanel;
|
||||
import org.adempiere.webui.part.ITabOnSelectHandler;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
|
@ -1034,6 +1035,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
|
||||
@Override
|
||||
public void updateHelpContext(String ctxType, int recordId) {
|
||||
this.updateHelpContext(ctxType, recordId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateHelpContext(String ctxType, int recordId, InfoPanel infoPanel) {
|
||||
// don't show context for SetupWizard Form, is managed internally using wf and node ctxhelp
|
||||
if (recordId == SystemIDs.FORM_SETUP_WIZARD && X_AD_CtxHelp.CTXTYPE_Form.equals(ctxType))
|
||||
return;
|
||||
|
@ -1047,7 +1053,10 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
if (adwindow != null) {
|
||||
gridTab = adwindow.getADWindowContent().getActiveGridTab();
|
||||
}
|
||||
updateHelpQuickInfo(gridTab);
|
||||
if(X_AD_CtxHelp.CTXTYPE_Info.equals(ctxType))
|
||||
updateHelpQuickInfo(infoPanel);
|
||||
else
|
||||
updateHelpQuickInfo(gridTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1060,6 +1069,12 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
helpController.renderToolTip(hdr, desc, help, otherContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateHelpQuickInfo(InfoPanel infoPanel) {
|
||||
if (isQuickInfoOpen)
|
||||
helpController.renderQuickInfo(infoPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateHelpQuickInfo(GridTab gridTab) {
|
||||
this.gridTab = gridTab;
|
||||
|
@ -1084,7 +1099,8 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
@Override
|
||||
public void openInfo(int infoId) {
|
||||
super.openInfo(infoId);
|
||||
updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoId);
|
||||
// updateHelpContext is already called in InfoPanel onPageAttached method - IDEMPIERE-5772
|
||||
// updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.adempiere.webui.adwindow.ADWindow;
|
|||
import org.adempiere.webui.apps.ProcessDialog;
|
||||
import org.adempiere.webui.component.Window;
|
||||
import org.adempiere.webui.panel.ADForm;
|
||||
import org.adempiere.webui.panel.InfoPanel;
|
||||
import org.adempiere.webui.part.UIPart;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.GridTab;
|
||||
|
@ -220,6 +221,13 @@ public interface IDesktop extends UIPart {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update help content in help/info panel
|
||||
* @param infoWindowId
|
||||
* @param infoPanel
|
||||
*/
|
||||
public void updateHelpContext(String ctxType, int infoWindowId, InfoPanel infoPanel);
|
||||
|
||||
/**
|
||||
* update help content in help/info panel
|
||||
* @param ctxTypes
|
||||
|
@ -248,6 +256,12 @@ public interface IDesktop extends UIPart {
|
|||
*/
|
||||
public void updateHelpQuickInfo(GridTab gridTab);
|
||||
|
||||
/**
|
||||
* update quick info (status line) in help/info panel
|
||||
* @param infoPanel
|
||||
*/
|
||||
public void updateHelpQuickInfo(InfoPanel infoPanel);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if there are changes not save yet
|
||||
|
|
|
@ -480,7 +480,7 @@ public abstract class WEditor implements EventListener<Event>, PropertyChangeLis
|
|||
* Fire ValueChangeEvent to ValueChangeListener in {@link #listeners}
|
||||
* @param event
|
||||
*/
|
||||
protected void fireValueChange(ValueChangeEvent event)
|
||||
public void fireValueChange(ValueChangeEvent event)
|
||||
{
|
||||
//copy to array to avoid concurrent modification exception
|
||||
ValueChangeListener[] vcl = new ValueChangeListener[listeners.size()];
|
||||
|
|
|
@ -1904,10 +1904,12 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
|
||||
mField.addPropertyChangeListener(editor);
|
||||
mField.setValue(mField.getDefaultForPanel(), true);
|
||||
editor.fireValueChange(new ValueChangeEvent(editor, mField.getColumnName(), mField.getOldValue(), mField.getValue()));
|
||||
|
||||
if(infoColumn.isRange()) {
|
||||
mField2.addPropertyChangeListener(editor2);
|
||||
mField2.setValue(mField2.getDefaultForPanel(), true);
|
||||
editor2.fireValueChange(new ValueChangeEvent(editor2, mField2.getColumnName(), mField2.getOldValue(), mField2.getValue()));
|
||||
}
|
||||
|
||||
} // addSelectionColumn
|
||||
|
@ -2199,15 +2201,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
if (evt.getNewValue() == null) {
|
||||
Env.setContext(infoContext, p_WindowNo, editor.getColumnName(), "");
|
||||
Env.setContext(infoContext, p_WindowNo, Env.TAB_INFO, editor.getColumnName(), "");
|
||||
paraCtxValues.put(editor.getColumnName(), "");
|
||||
} else if (evt.getNewValue() instanceof Boolean) {
|
||||
Env.setContext(infoContext, p_WindowNo, editor.getColumnName(), (Boolean)evt.getNewValue());
|
||||
Env.setContext(infoContext, p_WindowNo, Env.TAB_INFO, editor.getColumnName(), (Boolean)evt.getNewValue());
|
||||
paraCtxValues.put(editor.getColumnName(), (Boolean)evt.getNewValue());
|
||||
} else if (evt.getNewValue() instanceof Timestamp) {
|
||||
Env.setContext(infoContext, p_WindowNo, editor.getColumnName(), (Timestamp)evt.getNewValue());
|
||||
Env.setContext(infoContext, p_WindowNo, Env.TAB_INFO+"|"+editor.getColumnName(), (Timestamp)evt.getNewValue());
|
||||
paraCtxValues.put(editor.getColumnName(), (Timestamp)evt.getNewValue());
|
||||
} else {
|
||||
Env.setContext(infoContext, p_WindowNo, editor.getColumnName(), evt.getNewValue().toString());
|
||||
Env.setContext(infoContext, p_WindowNo, Env.TAB_INFO, editor.getColumnName(), evt.getNewValue().toString());
|
||||
paraCtxValues.put(editor.getColumnName(), evt.getNewValue().toString());
|
||||
}
|
||||
dynamicDisplay(editor);
|
||||
|
||||
|
|
|
@ -662,11 +662,22 @@ public class HelpController
|
|||
}
|
||||
}
|
||||
|
||||
public void renderQuickInfo(GridTab gridTab) {
|
||||
if (gridTab == null) {
|
||||
public void renderQuickInfo(Object obj) {
|
||||
if (obj == null) {
|
||||
pnlQuickInfo.setVisible(false);
|
||||
} else {
|
||||
String widget = gridTab.getStatusLinesWidget();
|
||||
String widget = "";
|
||||
if(obj instanceof GridTab) {
|
||||
widget = ((GridTab)obj).getStatusLinesWidget();
|
||||
}
|
||||
else if(obj instanceof InfoPanel) {
|
||||
widget = ((InfoPanel)obj).getStatusLinesWidget();
|
||||
}
|
||||
else {
|
||||
pnlQuickInfo.setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget == null) {
|
||||
pnlQuickInfo.setVisible(false);
|
||||
} else {
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
@ -73,6 +74,7 @@ import org.adempiere.webui.window.Dialog;
|
|||
import org.compiere.minigrid.ColumnInfo;
|
||||
import org.compiere.minigrid.IDColumn;
|
||||
import org.compiere.minigrid.UUIDColumn;
|
||||
import org.compiere.model.AccessSqlParser.TableInfo;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.InfoColumnVO;
|
||||
import org.compiere.model.InfoRelatedVO;
|
||||
|
@ -82,10 +84,10 @@ import org.compiere.model.MPInstance;
|
|||
import org.compiere.model.MProcess;
|
||||
import org.compiere.model.MRefTable;
|
||||
import org.compiere.model.MRole;
|
||||
import org.compiere.model.MStatusLine;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.X_AD_CtxHelp;
|
||||
import org.compiere.model.AccessSqlParser.TableInfo;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.process.ProcessInfoLog;
|
||||
import org.compiere.process.ProcessInfoUtil;
|
||||
|
@ -141,6 +143,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
protected static final String ON_USER_QUERY_ATTR = "ON_USER_QUERY";
|
||||
protected static final String INFO_QUERY_TIME_OUT_ERROR = "InfoQueryTimeOutError";
|
||||
protected static final String COLUMN_VISIBLE_ORIGINAL = "column.visible.original";
|
||||
protected static final String ROW_CTX_VARIABLE_PREFIX = "_IWInfo_";
|
||||
protected static final String ROW_ID_CTX_VARIABLE_NAME = "_IWInfoIDs_Selected";
|
||||
|
||||
private final static int DEFAULT_PAGE_SIZE = 100;
|
||||
private final static int DEFAULT_PAGE_PRELOAD = 4;
|
||||
|
@ -614,6 +618,19 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
*/
|
||||
private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
|
||||
|
||||
/**
|
||||
* Contains the indexes of selected row, maintains the selection order
|
||||
*/
|
||||
protected ArrayList<Integer> m_rowSelectionOrder = new ArrayList<Integer>();
|
||||
/**
|
||||
* Number of selected rows
|
||||
*/
|
||||
protected int m_selectedCount = 0;
|
||||
/**
|
||||
* Values that will be put into the context on re-query
|
||||
*/
|
||||
protected HashMap<String, Object> paraCtxValues = new HashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* Loaded correctly
|
||||
* @return true if loaded OK
|
||||
|
@ -647,10 +664,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
*/
|
||||
public void setStatusSelected ()
|
||||
{
|
||||
if (!p_multipleSelection)
|
||||
return;
|
||||
|
||||
int selectedCount = recordSelectedData.size();
|
||||
int selectedCount = p_multipleSelection ? recordSelectedData.size() : 0;
|
||||
|
||||
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
|
||||
Object keyCandidate = getColumnValue(rowIndex);
|
||||
|
@ -659,16 +673,20 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
|
||||
|
||||
if (contentPanel.getModel().isSelected(candidateRecord)){
|
||||
if (!recordSelectedData.containsKey(keyCandidate)){
|
||||
if(!p_multipleSelection) {
|
||||
selectedCount++;
|
||||
break;
|
||||
}
|
||||
else if (!recordSelectedData.containsKey(keyCandidate)){
|
||||
selectedCount++;
|
||||
}
|
||||
}else{
|
||||
}else if (p_multipleSelection){
|
||||
if (recordSelectedData.containsKey(keyCandidate)){// unselected record
|
||||
selectedCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_selectedCount = selectedCount;
|
||||
String msg = Msg.getMsg(Env.getCtx(), "IWStatusSelected", new Object [] {String.valueOf(selectedCount)});
|
||||
statusBar.setSelectedRowNumber(msg);
|
||||
btnSelectAll.setEnabled(m_count > 0 && selectedCount != m_count);
|
||||
|
@ -2218,6 +2236,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
}
|
||||
|
||||
enableButtons();
|
||||
if(!isLookup()) {
|
||||
updateRowSelectionOrder();
|
||||
updateContext(false);
|
||||
}
|
||||
|
||||
}else if (event.getTarget() == contentPanel && event.getName().equals("onAfterRender")){
|
||||
//IDEMPIERE-1334 at this event selected item from listBox and model is sync
|
||||
|
@ -2260,6 +2282,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_REFRESH)))
|
||||
{
|
||||
recordSelectedData.clear();
|
||||
setStatusSelected();
|
||||
onUserQuery();
|
||||
}
|
||||
else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_CANCEL)))
|
||||
|
@ -2307,10 +2330,18 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
else if (ON_SELECT_ALL_RECORDS.equals(event.getName()))
|
||||
{
|
||||
selectAllRecords();
|
||||
if(!isLookup()) {
|
||||
updateRowSelectionOrder();
|
||||
updateContext(false);
|
||||
}
|
||||
}
|
||||
else if (event.getTarget().equals(btnDeSelectAll))
|
||||
{
|
||||
deSelectAllRecords();
|
||||
if(!isLookup()) {
|
||||
updateRowSelectionOrder();
|
||||
updateContext(false);
|
||||
}
|
||||
}
|
||||
// IDEMPIERE-1334 handle event click into process button start
|
||||
else if (ON_RUN_PROCESS.equals(event.getName())){
|
||||
|
@ -2380,7 +2411,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
else if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT))
|
||||
{
|
||||
if (infoWindow != null)
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoWindow.getAD_InfoWindow_ID());
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoWindow.getAD_InfoWindow_ID(), this);
|
||||
else
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0);
|
||||
}
|
||||
|
@ -2859,6 +2890,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
isQueryByUser = false;
|
||||
hideBusyDialog();
|
||||
}
|
||||
if(!isLookup()) {
|
||||
updateRowSelectionOrder();
|
||||
updateContext(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3222,11 +3257,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
@Override
|
||||
public void onPageAttached(Page newpage, Page oldpage) {
|
||||
super.onPageAttached(newpage, oldpage);
|
||||
if (newpage != null) {
|
||||
if (newpage != null && !isLookup()) {
|
||||
if (infoWindow != null)
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoWindow.getAD_InfoWindow_ID());
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoWindow.getAD_InfoWindow_ID(), this);
|
||||
else
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0);
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0, this);
|
||||
}
|
||||
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
|
||||
}
|
||||
|
@ -3300,4 +3335,128 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
btnDeSelectAll.setVisible(multipleSelection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Widget support
|
||||
* Depending on Window/Tab returns widget lines info
|
||||
* @return info
|
||||
*/
|
||||
public String getStatusLinesWidget() {
|
||||
if(infoWindow == null)
|
||||
return null;
|
||||
MStatusLine[] wls = MStatusLine.getStatusLinesWidget(0, 0, 0, infoWindow.getAD_InfoWindow_ID());
|
||||
if (wls != null && wls.length > 0)
|
||||
{
|
||||
StringBuilder lines = new StringBuilder();
|
||||
for (MStatusLine wl : wls) {
|
||||
String line = wl.parseLine(getWindowNo());
|
||||
if (line != null) {
|
||||
lines.append(line).append("<br>");
|
||||
}
|
||||
}
|
||||
if (lines.length() > 0)
|
||||
return lines.toString();
|
||||
}
|
||||
return null;
|
||||
} // getWidgetLines
|
||||
|
||||
/**
|
||||
* Update row selection order
|
||||
*/
|
||||
protected void updateRowSelectionOrder() {
|
||||
if(m_selectedCount == m_count) {
|
||||
for(int rowIdx = 0; rowIdx < m_count; rowIdx++) {
|
||||
if(!m_rowSelectionOrder.contains(rowIdx))
|
||||
m_rowSelectionOrder.add((Integer)rowIdx);
|
||||
}
|
||||
}
|
||||
else if(m_selectedCount == 0) {
|
||||
m_rowSelectionOrder.clear();
|
||||
}
|
||||
else {
|
||||
if(!p_multipleSelection) {
|
||||
m_rowSelectionOrder.clear();
|
||||
m_rowSelectionOrder.add(m_lastSelectedIndex);
|
||||
}
|
||||
else {
|
||||
if(m_rowSelectionOrder.contains(m_lastSelectedIndex))
|
||||
m_rowSelectionOrder.remove((Integer)m_lastSelectedIndex);
|
||||
else
|
||||
m_rowSelectionOrder.add(m_lastSelectedIndex);
|
||||
}
|
||||
}
|
||||
} // updateRowSelectionOrder
|
||||
|
||||
/**
|
||||
* Put values from the selected row into the context
|
||||
*/
|
||||
protected void updateContext(boolean checkQueryCriteria) {
|
||||
Map<Object, List<Object>> rowInfo = getSelectedRowInfo();
|
||||
List<Object> lastSelectedRow = m_rowSelectionOrder.size() > 0 ? rowInfo.get(getRowKeyAt(m_rowSelectionOrder.get(m_rowSelectionOrder.size() - 1))) : null;
|
||||
|
||||
if(checkQueryCriteria) {
|
||||
// put parameter values into the context
|
||||
for(Map.Entry<String, Object> e : paraCtxValues.entrySet()) {
|
||||
String columnName = e.getKey();
|
||||
Object value = e.getValue();
|
||||
setContext(columnName, value);
|
||||
}
|
||||
}
|
||||
|
||||
// put the values of the last selected row into the context
|
||||
for(int i = 0; i < p_layout.length; i++) {
|
||||
String columnName = p_layout[i].getColumnName();
|
||||
Object value = lastSelectedRow != null ? lastSelectedRow.get(i) : null;
|
||||
setContext(ROW_CTX_VARIABLE_PREFIX + columnName, value);
|
||||
}
|
||||
// add selected IDs to the context
|
||||
setContext(ROW_ID_CTX_VARIABLE_NAME, getSelectedIDsForCtx());
|
||||
|
||||
// update Quick Info widget
|
||||
if (infoWindow != null)
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Info, infoWindow.getAD_InfoWindow_ID(), this);
|
||||
else
|
||||
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Home, 0, this);
|
||||
} // updateContext
|
||||
|
||||
/**
|
||||
* Set context
|
||||
* @param columnName
|
||||
* @param value
|
||||
*/
|
||||
protected void setContext(String columnName, Object value) {
|
||||
if(value instanceof KeyNamePair)
|
||||
value = ((KeyNamePair)value).getKey();
|
||||
else if(value instanceof IDColumn)
|
||||
value = ((IDColumn)value).getRecord_ID();
|
||||
|
||||
if (value == null) {
|
||||
Env.setContext(Env.getCtx(), p_WindowNo, columnName, "");
|
||||
} else if (value instanceof Boolean) {
|
||||
Env.setContext(Env.getCtx(), p_WindowNo, columnName, (Boolean)value);
|
||||
} else if (value instanceof Timestamp) {
|
||||
Env.setContext(Env.getCtx(), p_WindowNo, columnName, (Timestamp)value);
|
||||
} else {
|
||||
Env.setContext(Env.getCtx(), p_WindowNo, columnName, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a comma-separated string of selected IDs
|
||||
* @return String ctx value
|
||||
*/
|
||||
protected String getSelectedIDsForCtx() {
|
||||
String returnVal = null;
|
||||
|
||||
for(int idx : m_rowSelectionOrder) {
|
||||
String selectedID = Objects.toString(getRowKeyAt(idx));
|
||||
if(returnVal == null)
|
||||
returnVal = selectedID;
|
||||
else
|
||||
returnVal += "," + selectedID;
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
} // Info
|
||||
|
|
Loading…
Reference in New Issue