From 434cbaf110f824398ab9423cecb81149303cfdbc Mon Sep 17 00:00:00 2001 From: Deepak Pansheriya Date: Wed, 26 Feb 2020 16:03:16 +0530 Subject: [PATCH] IDEMPIERE-4157: Quick Form for fast data entry with keyboard --- db/ddlutils/oracle/views/AD_FIELD_V.sql | 2 +- db/ddlutils/oracle/views/AD_FIELD_VT.sql | 2 +- db/ddlutils/postgresql/views/AD_FIELD_V.sql | 2 +- db/ddlutils/postgresql/views/AD_FIELD_VT.sql | 2 +- .../oracle/201710311730_IDEMPIERE-4157.sql | 206 +++ .../201710311730_IDEMPIERE-4157.sql | 218 +++ .../adempiere/model/MTabCustomization.java | 55 +- .../src/org/compiere/model/GridField.java | 7 + .../src/org/compiere/model/GridFieldVO.java | 10 +- .../src/org/compiere/model/GridTab.java | 9 + .../src/org/compiere/model/GridTable.java | 17 +- .../src/org/compiere/model/I_AD_Field.java | 13 + .../model/I_AD_Tab_Customization.java | 13 + .../src/org/compiere/model/MSysConfig.java | 1 + .../src/org/compiere/model/X_AD_Field.java | 28 +- .../model/X_AD_Tab_Customization.java | 26 +- .../org/adempiere/webui/AdempiereWebUI.java | 2 +- .../adempiere/webui/adwindow/ADSortTab.java | 6 + .../adempiere/webui/adwindow/ADTabpanel.java | 28 + .../webui/adwindow/ADWindowToolbar.java | 67 +- .../adwindow/AbstractADWindowContent.java | 269 ++- .../webui/adwindow/CompositeADTabbox.java | 20 + .../adempiere/webui/adwindow/DetailPane.java | 28 +- .../adempiere/webui/adwindow/GridView.java | 4 +- .../adempiere/webui/adwindow/IADTabpanel.java | 4 + .../adwindow/QuickGridTabRowRenderer.java | 1021 +++++++++++ .../webui/adwindow/QuickGridView.java | 1552 +++++++++++++++++ .../adempiere/webui/adwindow/StatusBar.java | 5 +- .../adempiere/webui/apps/form/WQuickForm.java | 445 +++++ .../adempiere/webui/editor/WSearchEditor.java | 13 +- .../webui/panel/CustomizeGridViewPanel.java | 32 +- .../panel/QuickCustomizeGridViewPanel.java | 555 ++++++ .../webui/session/SessionManager.java | 43 + .../webui/window/CustomizeGridViewDialog.java | 78 +- org.adempiere.ui.zk/index.zul | 2 +- .../default/css/fragment/font-icons.css.dsp | 6 + .../theme/default/css/fragment/window.css.dsp | 16 + .../theme/default/images/QuickForm16.png | Bin 0 -> 991 bytes .../theme/default/images/QuickForm24.png | Bin 0 -> 1104 bytes .../theme/default/images/UnSort16.png | Bin 0 -> 396 bytes .../theme/default/images/UnSort24.png | Bin 0 -> 481 bytes 41 files changed, 4715 insertions(+), 92 deletions(-) create mode 100644 migration/i7.1z/oracle/201710311730_IDEMPIERE-4157.sql create mode 100644 migration/i7.1z/postgresql/201710311730_IDEMPIERE-4157.sql create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridTabRowRenderer.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridView.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WQuickForm.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/QuickCustomizeGridViewPanel.java create mode 100644 org.adempiere.ui.zk/theme/default/images/QuickForm16.png create mode 100644 org.adempiere.ui.zk/theme/default/images/QuickForm24.png create mode 100644 org.adempiere.ui.zk/theme/default/images/UnSort16.png create mode 100644 org.adempiere.ui.zk/theme/default/images/UnSort24.png diff --git a/db/ddlutils/oracle/views/AD_FIELD_V.sql b/db/ddlutils/oracle/views/AD_FIELD_V.sql index 75a5b5d7c6..4a42f638ba 100644 --- a/db/ddlutils/oracle/views/AD_FIELD_V.sql +++ b/db/ddlutils/oracle/views/AD_FIELD_V.sql @@ -1,5 +1,5 @@ CREATE OR REPLACE VIEW ad_field_v AS - SELECT t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, f.name, f.description, f.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fg.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml + SELECT t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, f.name, f.description, f.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fg.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml, f.isquickform FROM ad_field f JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id diff --git a/db/ddlutils/oracle/views/AD_FIELD_VT.sql b/db/ddlutils/oracle/views/AD_FIELD_VT.sql index 9ad9c01890..71876c8586 100644 --- a/db/ddlutils/oracle/views/AD_FIELD_VT.sql +++ b/db/ddlutils/oracle/views/AD_FIELD_VT.sql @@ -1,5 +1,5 @@ CREATE OR REPLACE VIEW ad_field_vt AS - SELECT trl.ad_language, t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, trl.name, trl.description, trl.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fgt.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml + SELECT trl.ad_language, t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, trl.name, trl.description, trl.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fgt.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml, f.isquickform FROM ad_field f JOIN ad_field_trl trl ON f.ad_field_id = trl.ad_field_id JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id diff --git a/db/ddlutils/postgresql/views/AD_FIELD_V.sql b/db/ddlutils/postgresql/views/AD_FIELD_V.sql index 7070237bc8..3928a6f177 100644 --- a/db/ddlutils/postgresql/views/AD_FIELD_V.sql +++ b/db/ddlutils/postgresql/views/AD_FIELD_V.sql @@ -7,7 +7,7 @@ COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandator c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fg.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, -c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml +c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml, f.isquickform FROM ad_field f JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id diff --git a/db/ddlutils/postgresql/views/AD_FIELD_VT.sql b/db/ddlutils/postgresql/views/AD_FIELD_VT.sql index 3b452fa86e..e056a7cfc4 100644 --- a/db/ddlutils/postgresql/views/AD_FIELD_VT.sql +++ b/db/ddlutils/postgresql/views/AD_FIELD_VT.sql @@ -6,7 +6,7 @@ CREATE OR REPLACE VIEW ad_field_vt AS c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fgt.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, - f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml + f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml, f.isquickform FROM ad_field f JOIN ad_field_trl trl ON f.ad_field_id = trl.ad_field_id JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id diff --git a/migration/i7.1z/oracle/201710311730_IDEMPIERE-4157.sql b/migration/i7.1z/oracle/201710311730_IDEMPIERE-4157.sql new file mode 100644 index 0000000000..4aed374555 --- /dev/null +++ b/migration/i7.1z/oracle/201710311730_IDEMPIERE-4157.sql @@ -0,0 +1,206 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-4157 Quick Form enhancement +-- Oct 31, 2017 5:12:27 PM IST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203142,0,0,'Y',TO_DATE('2017-10-31 17:12:26','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-10-31 17:12:26','YYYY-MM-DD HH24:MI:SS'),100,'IsQuickForm','Quick Form','Quick Form','D','3367c970-b5a2-47c8-86ad-efc08fd0a9f6') +; + +-- Oct 31, 2017 5:13:45 PM IST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,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) VALUES (213257,0,'Quick Form',107,'IsQuickForm','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2017-10-31 17:13:44','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-10-31 17:13:44','YYYY-MM-DD HH24:MI:SS'),100,203142,'Y','N','D','N','N','N','Y','882bd1cb-1777-4824-9ace-f434d00e1722','Y',0,'N','N') +; + +-- Oct 31, 2017 5:13:51 PM IST +ALTER TABLE AD_Field ADD IsQuickForm CHAR(1) DEFAULT 'N' CHECK (IsQuickForm IN ('Y','N')) NOT NULL +; + +-- Oct 31, 2017 5:26:16 PM IST +UPDATE AD_Element SET Description='Display in Quick Form', Help='The field will be displayed in Quick Form for easy entry.',Updated=TO_DATE('2017-10-31 17:26:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203142 +; + +-- Oct 31, 2017 5:26:16 PM IST +UPDATE AD_Column SET ColumnName='IsQuickForm', Name='Quick Form', Description='Display in Quick Form', Help='The field will be displayed in Quick Form for easy entry.' WHERE AD_Element_ID=203142 +; + +-- Oct 31, 2017 5:28:18 PM IST +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (205244,'Quick Form','Display in Quick Form','The field will be displayed in Quick Form for easy entry.',107,213257,'Y',0,440,0,'N','N','N','N',0,0,'Y',TO_DATE('2017-10-31 17:28:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-10-31 17:28:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','ada991db-87ad-45a3-8fd7-b8fefd16e50a','Y',420,1,1,1,'N','N','N') +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=160, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=2, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205244 +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET SeqNo=170, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=133 +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET SeqNo=180, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=137 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=190, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200274 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=200, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=138 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=210, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202362 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=220, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=142 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=230, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8343 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=240, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=140 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=250, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202341 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=260, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=141 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=270, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200350 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=280, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200348 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=290, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200349 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=300, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204213 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=310, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204214 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=320, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13425 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=330, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200837 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=340, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=54402 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=350, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=54401 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=360, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200838 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=370, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200834 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=380, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13424 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=390, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=62468 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=400, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=53280 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=410, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200836 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=420, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203500 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=430, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200835 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=440, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=136 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=450, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=139 +; + +INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_ToolBarButton_UU,Action,SeqNo,IsAdvancedButton,IsAddSeparator) VALUES (0,0,TO_DATE('2017-11-01 09:47:25','YYYY-MM-DD HH24:MI:SS'),100,'QuickForm','Y',200094,'Window -QuickForm',TO_DATE('2017-11-01 09:47:25','YYYY-MM-DD HH24:MI:SS'),100,'N',0,0,'73c01d0e-ff1b-4bbb-b3c7-e6c650adbed8','W',280,'N','Y') +; + +CREATE OR REPLACE VIEW ad_field_v AS + SELECT t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, f.name, f.description, f.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fg.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml, f.isquickform + FROM ad_field f + JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id + LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id + LEFT JOIN ad_column c ON f.ad_column_id = c.ad_column_id + JOIN ad_table tbl ON c.ad_table_id = tbl.ad_table_id + LEFT JOIN ad_val_rule vr ON vr.ad_val_rule_id = COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) + WHERE f.isactive = 'Y' AND c.isactive = 'Y' +; + +CREATE OR REPLACE VIEW ad_field_vt AS + SELECT trl.ad_language, t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, trl.name, trl.description, trl.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fgt.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml, f.isquickform + FROM ad_field f + JOIN ad_field_trl trl ON f.ad_field_id = trl.ad_field_id + JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id + LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id + LEFT JOIN ad_fieldgroup_trl fgt ON f.ad_fieldgroup_id = fgt.ad_fieldgroup_id AND trl.ad_language = fgt.ad_language + LEFT JOIN ad_column c ON f.ad_column_id = c.ad_column_id + LEFT JOIN ad_column_trl ct ON f.ad_column_id = ct.ad_column_id AND trl.ad_language = ct.ad_language + JOIN ad_table tbl ON c.ad_table_id = tbl.ad_table_id + LEFT JOIN ad_val_rule vr ON vr.ad_val_rule_id = COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) + WHERE f.isactive = 'Y' AND c.isactive = 'Y' +; + + +-- Nov 8, 2017 10:56:03 AM IST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,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) VALUES (213259,0,'Quick Form','Display in Quick Form','The field will be displayed in Quick Form for easy encoding.',200008,'IsQuickForm','N',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_DATE('2017-11-08 10:56:02','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-11-08 10:56:02','YYYY-MM-DD HH24:MI:SS'),100,203142,'Y','N','D','N','N','N','Y','c52262c8-322a-4607-a50d-745a7f063706','Y',0,'N','N','N') +; + +-- Nov 8, 2017 10:56:08 AM IST +ALTER TABLE AD_Tab_Customization ADD IsQuickForm CHAR(1) DEFAULT 'N' CHECK (IsQuickForm IN ('Y','N')) +; + +-- Nov 9, 2017 10:55:12 AM IST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Quick Form',0,0,'Y',TO_DATE('2017-11-09 10:55:11','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-11-09 10:55:11','YYYY-MM-DD HH24:MI:SS'),100,200440,'QuickForm','D','0fadb3eb-413b-41c2-b41c-d0ae3a1d5c27') +; + + +-- Nov 21, 2017 11:39:03 AM IST +INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200112,0,0,TO_DATE('2017-11-21 11:39:02','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2017-11-21 11:39:02','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','QUICKFORM_PAGE_SIZE','25','Default paging size for Quick Form in zk webui','D','C','2ae2e737-285e-4cda-82a6-bbe7efce2cb8') +; + +-- Quick Form enhancement +-- Nov 22, 2017 12:48:12 PM IST +INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_ToolBarButton_UU,Action,SeqNo,IsAdvancedButton,IsAddSeparator) VALUES (0,0,TO_DATE('2017-11-22 12:48:11','YYYY-MM-DD HH24:MI:SS'),100,'QuickForm','Y',200095,'Detail - QuickForm',TO_DATE('2017-11-22 12:48:11','YYYY-MM-DD HH24:MI:SS'),100,'N',0,0,'93a9a483-ea2f-49b7-8737-a4113b2aa8de','D',50,'N','N') +; + +-- Quick Form read only +-- Feb 18, 2020, 6:13:37 PM IST +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, ReadOnlyLogic='@AD_Column_ID.AD_Reference_ID@=200122 | @AD_Column_ID.AD_Reference_ID@=200127 | @AD_Column_ID.AD_Reference_ID@=200128 | @AD_Column_ID.AD_Reference_ID@=200161 | @AD_Column_ID.AD_Reference_ID@=200162 | @AD_Column_ID.AD_Reference_ID@=200163', IsToolbarButton=NULL,Updated=TO_DATE('2020-02-18 18:13:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205244 +; + +SELECT register_migration_script('201710311730_IDEMPIERE-4157.sql') FROM dual +; diff --git a/migration/i7.1z/postgresql/201710311730_IDEMPIERE-4157.sql b/migration/i7.1z/postgresql/201710311730_IDEMPIERE-4157.sql new file mode 100644 index 0000000000..c7d0d312c7 --- /dev/null +++ b/migration/i7.1z/postgresql/201710311730_IDEMPIERE-4157.sql @@ -0,0 +1,218 @@ +-- IDEMPIERE-4157 Quick Form enhancement +-- Oct 31, 2017 5:12:27 PM IST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203142,0,0,'Y',TO_TIMESTAMP('2017-10-31 17:12:26','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-10-31 17:12:26','YYYY-MM-DD HH24:MI:SS'),100,'IsQuickForm','Quick Form','Quick Form','D','3367c970-b5a2-47c8-86ad-efc08fd0a9f6') +; + +-- Oct 31, 2017 5:13:45 PM IST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,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) VALUES (213257,0,'Quick Form',107,'IsQuickForm','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2017-10-31 17:13:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-10-31 17:13:44','YYYY-MM-DD HH24:MI:SS'),100,203142,'Y','N','D','N','N','N','Y','882bd1cb-1777-4824-9ace-f434d00e1722','Y',0,'N','N') +; + +-- Oct 31, 2017 5:13:51 PM IST +ALTER TABLE AD_Field ADD COLUMN IsQuickForm CHAR(1) DEFAULT 'N' CHECK (IsQuickForm IN ('Y','N')) NOT NULL +; + +-- Oct 31, 2017 5:26:16 PM IST +UPDATE AD_Element SET Description='Display in Quick Form', Help='The field will be displayed in Quick Form for easy entry.',Updated=TO_TIMESTAMP('2017-10-31 17:26:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203142 +; + +-- Oct 31, 2017 5:26:16 PM IST +UPDATE AD_Column SET ColumnName='IsQuickForm', Name='Quick Form', Description='Display in Quick Form', Help='The field will be displayed in Quick Form for easy entry.' WHERE AD_Element_ID=203142 +; + +-- Oct 31, 2017 5:28:18 PM IST +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (205244,'Quick Form','Display in Quick Form','The field will be displayed in Quick Form for easy entry.',107,213257,'Y',0,440,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-10-31 17:28:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-10-31 17:28:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','ada991db-87ad-45a3-8fd7-b8fefd16e50a','Y',420,1,1,1,'N','N','N') +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=160, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=2, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205244 +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET SeqNo=170, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=133 +; + +-- Oct 31, 2017 5:29:05 PM IST +UPDATE AD_Field SET SeqNo=180, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=137 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=190, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200274 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=200, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=138 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=210, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202362 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=220, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=142 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=230, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8343 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=240, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=140 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=250, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202341 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=260, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=141 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=270, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200350 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=280, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200348 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=290, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200349 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=300, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204213 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=310, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204214 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=320, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13425 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=330, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200837 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=340, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=54402 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=350, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=54401 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=360, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200838 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=370, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200834 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=380, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13424 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=390, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=62468 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=400, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=53280 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=410, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200836 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=420, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203500 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=430, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200835 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=440, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=136 +; + +-- Oct 31, 2017 5:29:06 PM IST +UPDATE AD_Field SET SeqNo=450, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-31 17:29:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=139 +; + +INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_ToolBarButton_UU,"action",SeqNo,IsAdvancedButton,IsAddSeparator) VALUES (0,0,TO_TIMESTAMP('2017-11-01 09:47:25','YYYY-MM-DD HH24:MI:SS'),100,'QuickForm','Y',200094,'Window -QuickForm',TO_TIMESTAMP('2017-11-01 09:47:25','YYYY-MM-DD HH24:MI:SS'),100,'N',0,0,'73c01d0e-ff1b-4bbb-b3c7-e6c650adbed8','W',280,'N','Y') +; + +CREATE OR REPLACE VIEW ad_field_v AS + SELECT t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, f.name, f.description, f.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, f.sortno, f.issameline, +f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, +c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, +c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, c.isalwaysupdateable) AS isalwaysupdateable, +COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, +c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fg.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, +fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, +f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, +c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(f.placeholder, c.placeholder) AS placeholder, c.ishtml, f.isquickform + FROM ad_field f + JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id + LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id + LEFT JOIN ad_column c ON f.ad_column_id = c.ad_column_id + JOIN ad_table tbl ON c.ad_table_id = tbl.ad_table_id + LEFT JOIN ad_val_rule vr ON vr.ad_val_rule_id = COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) + WHERE f.isactive = 'Y' AND c.isactive = 'Y' +; + +CREATE OR REPLACE VIEW ad_field_vt AS + SELECT trl.ad_language, t.ad_window_id, f.ad_tab_id, f.ad_field_id, tbl.ad_table_id, f.ad_column_id, trl.name, trl.description, trl.help, f.isdisplayed, f.displaylogic, f.displaylength, f.seqno, + f.sortno, f.issameline, f.isheading, f.isfieldonly, f.isreadonly, f.isencrypted AS isencryptedfield, f.obscuretype, c.columnname, c.columnsql, c.fieldlength, COALESCE(f.VFormat, c.VFormat) AS VFormat, COALESCE(f.defaultvalue, c.defaultvalue) AS defaultvalue, + c.iskey, c.isparent, COALESCE(f.ismandatory, c.ismandatory) AS ismandatory, c.isidentifier, c.istranslated, COALESCE(f.ad_reference_value_id, c.ad_reference_value_id) AS ad_reference_value_id, + c.callout, COALESCE(f.ad_reference_id, c.ad_reference_id) AS ad_reference_id, COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) AS ad_val_rule_id, c.ad_process_id, COALESCE(f.isalwaysupdateable, + c.isalwaysupdateable) AS isalwaysupdateable, COALESCE(f.readonlylogic, c.readonlylogic) AS readonlylogic, COALESCE(f.mandatorylogic, c.mandatorylogic) AS mandatorylogic, COALESCE(f.isupdateable, c.isupdateable) AS isupdateable, + c.isencrypted AS isencryptedcolumn, c.isselectioncolumn, tbl.tablename, c.valuemin, c.valuemax, fgt.name AS fieldgroup, vr.code AS validationcode, f.included_tab_id, fg.fieldgrouptype, + fg.iscollapsedbydefault, COALESCE(f.infofactoryclass, c.infofactoryclass) AS infofactoryclass, c.isautocomplete, COALESCE(f.isallowcopy, c.isallowcopy) AS isallowcopy, f.isdisplayedgrid, + f.seqnogrid, c.seqnoselection, f.xposition, f.columnspan, f.numlines, COALESCE(f.istoolbarbutton, c.istoolbarbutton) AS istoolbarbutton, c.formatpattern, f.isadvancedfield, f.isdefaultfocus, c.ad_chart_id, f.ad_labelstyle_id, f.ad_fieldstyle_id, c.pa_dashboardcontent_id, COALESCE(trl.placeholder, ct.placeholder) AS placeholder, c.ishtml, f.isquickform + FROM ad_field f + JOIN ad_field_trl trl ON f.ad_field_id = trl.ad_field_id + JOIN ad_tab t ON f.ad_tab_id = t.ad_tab_id + LEFT JOIN ad_fieldgroup fg ON f.ad_fieldgroup_id = fg.ad_fieldgroup_id + LEFT JOIN ad_fieldgroup_trl fgt ON f.ad_fieldgroup_id = fgt.ad_fieldgroup_id AND trl.ad_language::text = fgt.ad_language::text + LEFT JOIN ad_column c ON f.ad_column_id = c.ad_column_id + LEFT JOIN ad_column_trl ct ON f.ad_column_id = ct.ad_column_id AND trl.ad_language::text = ct.ad_language::text + JOIN ad_table tbl ON c.ad_table_id = tbl.ad_table_id + LEFT JOIN ad_val_rule vr ON vr.ad_val_rule_id = COALESCE(f.ad_val_rule_id, c.ad_val_rule_id) + WHERE f.isactive = 'Y' AND c.isactive = 'Y' +; + + +-- Nov 8, 2017 10:56:03 AM IST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,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) VALUES (213259,0,'Quick Form','Display in Quick Form','The field will be displayed in Quick Form for easy encoding.',200008,'IsQuickForm','N',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2017-11-08 10:56:02','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-11-08 10:56:02','YYYY-MM-DD HH24:MI:SS'),100,203142,'Y','N','D','N','N','N','Y','c52262c8-322a-4607-a50d-745a7f063706','Y',0,'N','N','N') +; + +-- Nov 8, 2017 10:56:08 AM IST +ALTER TABLE AD_Tab_Customization ADD COLUMN IsQuickForm CHAR(1) DEFAULT 'N' CHECK (IsQuickForm IN ('Y','N')) +; + +-- Nov 9, 2017 10:55:12 AM IST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Quick Form',0,0,'Y',TO_TIMESTAMP('2017-11-09 10:55:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-11-09 10:55:11','YYYY-MM-DD HH24:MI:SS'),100,200440,'QuickForm','D','0fadb3eb-413b-41c2-b41c-d0ae3a1d5c27') +; + + +-- Nov 21, 2017 11:39:03 AM IST +INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200112,0,0,TO_TIMESTAMP('2017-11-21 11:39:02','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2017-11-21 11:39:02','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','QUICKFORM_PAGE_SIZE','25','Default paging size for Quick Form in zk webui','D','C','2ae2e737-285e-4cda-82a6-bbe7efce2cb8') +; + +-- Quick Form enhancement +-- Nov 22, 2017 12:48:12 PM IST +INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_ToolBarButton_UU,"action",SeqNo,IsAdvancedButton,IsAddSeparator) VALUES (0,0,TO_TIMESTAMP('2017-11-22 12:48:11','YYYY-MM-DD HH24:MI:SS'),100,'QuickForm','Y',200095,'Detail - QuickForm',TO_TIMESTAMP('2017-11-22 12:48:11','YYYY-MM-DD HH24:MI:SS'),100,'N',0,0,'93a9a483-ea2f-49b7-8737-a4113b2aa8de','D',50,'N','N') +; + +-- Quick Form read only +-- Feb 18, 2020, 6:13:37 PM IST +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, ReadOnlyLogic='@AD_Column_ID.AD_Reference_ID@=200122 | @AD_Column_ID.AD_Reference_ID@=200127 | @AD_Column_ID.AD_Reference_ID@=200128 | @AD_Column_ID.AD_Reference_ID@=200161 | @AD_Column_ID.AD_Reference_ID@=200162 | @AD_Column_ID.AD_Reference_ID@=200163', IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-02-18 18:13:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205244 +; + +SELECT register_migration_script('201710311730_IDEMPIERE-4157.sql') FROM dual +; diff --git a/org.adempiere.base/src/org/adempiere/model/MTabCustomization.java b/org.adempiere.base/src/org/adempiere/model/MTabCustomization.java index 54110e13c1..36c6fd4dbf 100644 --- a/org.adempiere.base/src/org/adempiere/model/MTabCustomization.java +++ b/org.adempiere.base/src/org/adempiere/model/MTabCustomization.java @@ -5,6 +5,7 @@ import java.util.Properties; import org.compiere.model.Query; import org.compiere.model.X_AD_Tab_Customization; +import org.compiere.util.Util; public class MTabCustomization extends X_AD_Tab_Customization { /** @@ -28,10 +29,60 @@ public class MTabCustomization extends X_AD_Tab_Customization { /** * * @param ctx + * @param AD_User_ID * @param AD_Tab_ID + * @param trxName */ public static MTabCustomization get(Properties ctx, int AD_User_ID, int AD_Tab_ID, String trxName) { - Query query = new Query(ctx, Table_Name, "AD_User_ID=? AND AD_Tab_ID=?", trxName); - return query.setClient_ID().setParameters(new Object[]{AD_User_ID, AD_Tab_ID}).first(); + return get(ctx, AD_User_ID, AD_Tab_ID, trxName, false); } + + /** + * @param ctx + * @param AD_User_ID + * @param AD_Tab_ID + * @param trxName + * @param isQuickForm + * @return + */ + public static MTabCustomization get(Properties ctx, int AD_User_ID, int AD_Tab_ID, String trxName, boolean isQuickForm) { + Query query = new Query(ctx, Table_Name, "AD_User_ID=? AND AD_Tab_ID=? AND IsQuickForm=?", trxName); + return query.setClient_ID().setParameters(new Object[] { AD_User_ID, AD_Tab_ID, (isQuickForm ? "Y" : "N") }).first(); + } + + /** + * Save Tab Customization Data + * + * @param ctx - Context + * @param AD_Tab_ID - Tab ID + * @param AD_User_ID - User ID + * @param Custom - Customized Field IDs with it's Size + * @param DisplayedGrid - Default preference of Grid view + * @param trxName - Transaction + * @param isQuickForm - Is Quick Form + * @return True if save successfully + */ + public static boolean saveData(Properties ctx, int AD_Tab_ID, int AD_User_ID, String Custom, String DisplayedGrid, String trxName, boolean isQuickForm) { + MTabCustomization tabCust = get(ctx, AD_User_ID, AD_Tab_ID, trxName, isQuickForm); + + if (tabCust != null && tabCust.getAD_Tab_Customization_ID() > 0) + { + tabCust.setCustom(Custom); + tabCust.setIsDisplayedGrid(DisplayedGrid); + } + else + { + tabCust = new MTabCustomization(ctx, 0, trxName); + tabCust.setAD_Tab_ID(AD_Tab_ID); + tabCust.setAD_User_ID(AD_User_ID); + tabCust.setCustom(Custom); + tabCust.setIsDisplayedGrid(DisplayedGrid); + tabCust.setIsQuickForm(isQuickForm); + } + + if (Util.isEmpty(tabCust.getCustom(), true)) + return tabCust.delete(true); + return tabCust.save(); + } // saveTabCustomization + } diff --git a/org.adempiere.base/src/org/compiere/model/GridField.java b/org.adempiere.base/src/org/compiere/model/GridField.java index 20c50863c0..e02d1d2682 100644 --- a/org.adempiere.base/src/org/compiere/model/GridField.java +++ b/org.adempiere.base/src/org/compiere/model/GridField.java @@ -2595,6 +2595,13 @@ public class GridField { return m_lookupEditorSettingValue; } + /** + * Is Quick Form + * @return true if displayed in Quick Form + */ + public boolean isQuickForm() { + return m_vo.IsQuickForm; + } public void processUIVirtualColumn() { String sql = m_vo.ColumnSQL.substring(5); diff --git a/org.adempiere.base/src/org/compiere/model/GridFieldVO.java b/org.adempiere.base/src/org/compiere/model/GridFieldVO.java index a6e56c6dbc..22531c4f72 100644 --- a/org.adempiere.base/src/org/compiere/model/GridFieldVO.java +++ b/org.adempiere.base/src/org/compiere/model/GridFieldVO.java @@ -200,6 +200,8 @@ public class GridFieldVO implements Serializable vo.AD_Reference_Value_ID = rs.getInt(i); else if (columnName.equalsIgnoreCase("ValidationCode")) vo.ValidationCode = rs.getString(i); + else if (columnName.equalsIgnoreCase("IsQuickForm")) + vo.IsQuickForm = "Y".equals(rs.getString (i)); else if (columnName.equalsIgnoreCase("ColumnSQL")) { vo.ColumnSQL = rs.getString(i); if (vo.ColumnSQL != null && !vo.ColumnSQL.startsWith("@SQL=") && !vo.ColumnSQL.startsWith("@SQLFIND=") && vo.ColumnSQL.contains("@")) { @@ -739,10 +741,15 @@ public class GridFieldVO implements Serializable public int PA_DashboardContent_ID = 0; public String Placeholder = ""; + public String Placeholder2 = ""; + /* Is HTML String */ public boolean IsHtml = false; - + + /* Allow to show field in Quick Form */ + public boolean IsQuickForm = false; + /** * Set Context including contained elements * @param newCtx new context @@ -879,6 +886,7 @@ public class GridFieldVO implements Serializable clone.PA_DashboardContent_ID = PA_DashboardContent_ID; clone.Placeholder = Placeholder; clone.IsHtml = IsHtml; + clone.IsQuickForm = IsQuickForm; // Lookup clone.ValidationCode = ValidationCode; diff --git a/org.adempiere.base/src/org/compiere/model/GridTab.java b/org.adempiere.base/src/org/compiere/model/GridTab.java index 84c740844f..0c1b57f451 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTab.java +++ b/org.adempiere.base/src/org/compiere/model/GridTab.java @@ -214,6 +214,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable //Contains currently selected rows private ArrayList selection = null; + public boolean isQuickForm = false; // Context property names: public static final String CTX_KeyColumnName = "_TabInfo_KeyColumnName"; @@ -3375,6 +3376,14 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable selection.clear(); } + public boolean isQuickForm() { + return isQuickForm; + } + + public void setQuickForm(boolean isQuickForm) { + this.isQuickForm = isQuickForm; + } + public GridWindow getGridWindow() { return this.m_window; diff --git a/org.adempiere.base/src/org/compiere/model/GridTable.java b/org.adempiere.base/src/org/compiere/model/GridTable.java index fe0c68f45b..18b02a2345 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTable.java +++ b/org.adempiere.base/src/org/compiere/model/GridTable.java @@ -904,7 +904,13 @@ public class GridTable extends AbstractTableModel } if (getRowCount() == 0) return; - + + GridField field = getField(col); + + // Ignoring new record while sorting + if (field.getGridTab().isQuickForm()) + dataIgnore(); + boolean isSameSortEntries = (col == m_lastSortColumnIndex && ascending == m_lastSortedAscending); if (!isSameSortEntries) { @@ -915,7 +921,6 @@ public class GridTable extends AbstractTableModel //cache changed row Object[] changedRow = m_rowChanged >= 0 ? getDataAtRow(m_rowChanged) : null; - GridField field = getField (col); // RowIDs are not sorted if (field.getDisplayType() == DisplayType.RowID) return; @@ -3976,4 +3981,12 @@ public class GridTable extends AbstractTableModel public int getKeyColumnIndex() { return m_indexKeyColumn; } + + /** + * Index of updated row's + */ + public int getRowChanged() + { + return m_rowChanged; + } } diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Field.java b/org.adempiere.base/src/org/compiere/model/I_AD_Field.java index ac3d6d1bc2..6bdcbff312 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Field.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Field.java @@ -483,6 +483,19 @@ public interface I_AD_Field /** Get Quick Entry */ public boolean isQuickEntry(); + /** Column name IsQuickForm */ + public static final String COLUMNNAME_IsQuickForm = "IsQuickForm"; + + /** Set Quick Form. + * Display in Quick Form + */ + public void setIsQuickForm (boolean IsQuickForm); + + /** Get Quick Form. + * Display in Quick Form + */ + public boolean isQuickForm(); + /** Column name IsReadOnly */ public static final String COLUMNNAME_IsReadOnly = "IsReadOnly"; diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Tab_Customization.java b/org.adempiere.base/src/org/compiere/model/I_AD_Tab_Customization.java index 97784f15da..a884f2ec39 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Tab_Customization.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Tab_Customization.java @@ -157,6 +157,19 @@ public interface I_AD_Tab_Customization /** Get Show in Grid */ public String getIsDisplayedGrid(); + /** Column name IsQuickForm */ + public static final String COLUMNNAME_IsQuickForm = "IsQuickForm"; + + /** Set Quick Form. + * Display in Quick Form + */ + public void setIsQuickForm (boolean IsQuickForm); + + /** Get Quick Form. + * Display in Quick Form + */ + public boolean isQuickForm(); + /** Column name Updated */ public static final String COLUMNNAME_Updated = "Updated"; diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 327bee7dc1..a75f67d289 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -194,6 +194,7 @@ public class MSysConfig extends X_AD_SysConfig public static final String ZK_THEME_USE_FONT_ICON_FOR_IMAGE = "ZK_THEME_USE_FONT_ICON_FOR_IMAGE"; public static final String ZK_THEME = "ZK_THEME"; public static final String ZOOM_ACROSS_QUERY_TIMEOUT = "ZOOM_ACROSS_QUERY_TIMEOUT"; + public static final String QUICKFORM_PAGE_SIZE = "QUICKFORM_PAGE_SIZE"; /** * Standard Constructor diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Field.java b/org.adempiere.base/src/org/compiere/model/X_AD_Field.java index 06bfa179df..2f3e4afe0d 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Field.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Field.java @@ -32,7 +32,7 @@ public class X_AD_Field extends PO implements I_AD_Field, I_Persistent /** * */ - private static final long serialVersionUID = 20191121L; + private static final long serialVersionUID = 20200225L; /** Standard Constructor */ public X_AD_Field (Properties ctx, int AD_Field_ID, String trxName) @@ -55,6 +55,8 @@ public class X_AD_Field extends PO implements I_AD_Field, I_Persistent setIsFieldOnly (false); setIsHeading (false); setIsQuickEntry (false); +// N + setIsQuickForm (false); // N setIsReadOnly (false); setIsSameLine (false); @@ -783,6 +785,30 @@ public class X_AD_Field extends PO implements I_AD_Field, I_Persistent return false; } + /** Set Quick Form. + @param IsQuickForm + Display in Quick Form + */ + public void setIsQuickForm (boolean IsQuickForm) + { + set_Value (COLUMNNAME_IsQuickForm, Boolean.valueOf(IsQuickForm)); + } + + /** Get Quick Form. + @return Display in Quick Form + */ + public boolean isQuickForm () + { + Object oo = get_Value(COLUMNNAME_IsQuickForm); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } + /** Set Read Only. @param IsReadOnly Field is read only diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Tab_Customization.java b/org.adempiere.base/src/org/compiere/model/X_AD_Tab_Customization.java index 89a302b51a..0739a56f79 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Tab_Customization.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Tab_Customization.java @@ -29,7 +29,7 @@ public class X_AD_Tab_Customization extends PO implements I_AD_Tab_Customization /** * */ - private static final long serialVersionUID = 20191121L; + private static final long serialVersionUID = 20200225L; /** Standard Constructor */ public X_AD_Tab_Customization (Properties ctx, int AD_Tab_Customization_ID, String trxName) @@ -194,4 +194,28 @@ public class X_AD_Tab_Customization extends PO implements I_AD_Tab_Customization { return (String)get_Value(COLUMNNAME_IsDisplayedGrid); } + + /** Set Quick Form. + @param IsQuickForm + Display in Quick Form + */ + public void setIsQuickForm (boolean IsQuickForm) + { + set_Value (COLUMNNAME_IsQuickForm, Boolean.valueOf(IsQuickForm)); + } + + /** Get Quick Form. + @return Display in Quick Form + */ + public boolean isQuickForm () + { + Object oo = get_Value(COLUMNNAME_IsQuickForm); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } } \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java index 91f311fdd6..445d2cd17a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java @@ -250,7 +250,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb keyListener = new Keylistener(); keyListener.setPage(this.getPage()); - keyListener.setCtrlKeys("@a@c@d@e@f@h@m@n@o@p@r@s@t@z@x@#left@#right@#up@#down@#home@#end#enter^u@u@#pgdn@#pgup"); + keyListener.setCtrlKeys("@a@c@d@e@f@h@l@m@n@o@p@r@s@t@z@x@#left@#right@#up@#down@#home@#end#enter^u@u@#pgdn@#pgup$#f2^#f2"); keyListener.setAutoBlur(false); //create new desktop diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java index e5d5c4601c..487cdda347 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java @@ -1036,5 +1036,11 @@ public class ADSortTab extends Panel implements IADTabpanel public ADTreePanel getTreePanel() { return null; } + + @Override + public boolean isEnableQuickFormButton() + { + return false; + } } //ADSortTab diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java index c3ae8236d8..e365bbc8f2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java @@ -84,6 +84,7 @@ import org.compiere.model.PO; import org.compiere.model.Query; import org.compiere.model.X_AD_FieldGroup; import org.compiere.model.X_AD_ToolBarButton; +import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DisplayType; import org.compiere.util.Env; @@ -214,6 +215,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer private static final String DEFAULT_PANEL_WIDTH = "300px"; + private static CCache quickFormCache = new CCache(null, "QuickForm", 20, false); + private static enum SouthEvent { SLIDE(), OPEN(), @@ -2009,4 +2012,29 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } + @Override + public boolean isEnableQuickFormButton() + { + boolean hasQuickForm = false; + int tabID = getGridTab().getAD_Tab_ID(); + + if (quickFormCache.containsKey(tabID)) + { + hasQuickForm = quickFormCache.get(tabID); + } + else if (getGridTab() != null) + { + for (GridField field : getGridTab().getFields()) + { + if (field.isQuickForm()) + { + hasQuickForm = true; + break; + } + } + quickFormCache.put(tabID, hasQuickForm); + } + + return hasQuickForm; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java index d6b4aeab27..08e18f848e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java @@ -119,6 +119,8 @@ public class ADWindowToolbar extends FToolbar implements EventListener private ToolBarButton btnProcess; + private ToolBarButton btnQuickForm; + private ToolBarButton btnShowMore; private Menupopup menupopup; @@ -148,6 +150,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener private long prevKeyEventTime = 0; private KeyEvent prevKeyEvent; + + // Maintain hierarchical Quick form by its parent-child tab while open leaf + // tab once & dispose and doing same action + private int quickFormTabHrchyLevel = 0; private A overflowButton; @@ -235,6 +241,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener btnProcess.setTooltiptext(btnProcess.getTooltiptext()+ " Alt+O"); btnProcess.setDisabled(false); + btnQuickForm = createButton("QuickForm", "QuickForm", "QuickForm"); + btnQuickForm.setDisabled(false); + // Help and Exit should always be enabled btnHelp.setDisabled(false); btnGridToggle.setDisabled(false); @@ -440,6 +449,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener altKeyMap.put(VK_R, btnReport); altKeyMap.put(VK_P, btnPrint); altKeyMap.put(VK_O, btnProcess); + altKeyMap.put(VK_L, btnCustomize); } protected void addSeparator() @@ -476,6 +486,8 @@ public class ADWindowToolbar extends FToolbar implements EventListener } else if (eventName.equals(Events.ON_CTRL_KEY)) { KeyEvent keyEvent = (KeyEvent) event; + if (SessionManager.getOpenQuickFormTabs().size() > 0 && !(keyEvent.getKeyCode() == KeyEvent.F2)) + return; if (LayoutUtils.isReallyVisible(this)) { //filter same key event that is too close //firefox fire key event twice when grid is visible @@ -672,6 +684,12 @@ public class ADWindowToolbar extends FToolbar implements EventListener menuItems.get(button).setDisabled(!enabled); } + public void enableQuickForm(boolean enabled) + { + btnQuickForm.setDisabled(!enabled); + enableMenuitem(btnQuickForm, enabled); + } + public void lock(boolean locked) { setPressed("Lock", locked); @@ -734,10 +752,41 @@ public class ADWindowToolbar extends FToolbar implements EventListener } } else if (!keyEvent.isAltKey() && keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) - btn = ctrlKeyMap.get(keyEvent.getKeyCode()); + { + if (keyEvent.getKeyCode() == KeyEvent.F2) + { + quickFormTabHrchyLevel = quickFormTabHrchyLevel + 1; + fireButtonClickEvent(keyEvent, btnDetailRecord); + if (!btnQuickForm.isDisabled() && btnQuickForm.isVisible()) + { + fireButtonClickEvent(keyEvent, btnQuickForm); + } + else if (!btnParentRecord.isDisabled() && btnParentRecord.isVisible()) + { + fireButtonClickEvent(keyEvent, btnParentRecord); + quickFormTabHrchyLevel = quickFormTabHrchyLevel - 1; + } + return; + } + else + { + btn = ctrlKeyMap.get(keyEvent.getKeyCode()); + } + } else if (!keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) btn = keyMap.get(keyEvent.getKeyCode()); + else if (!keyEvent.isAltKey() && !keyEvent.isCtrlKey() && keyEvent.isShiftKey()) + { + if (keyEvent.getKeyCode() == KeyEvent.F2) + { + btn = btnQuickForm; + } + } + fireButtonClickEvent(keyEvent, btn); + } + private void fireButtonClickEvent(KeyEvent keyEvent, ToolBarButton btn) + { if (btn != null) { prevKeyEventTime = System.currentTimeMillis(); prevKeyEvent = keyEvent; @@ -1107,4 +1156,20 @@ public class ADWindowToolbar extends FToolbar implements EventListener } } } + + /** + * @return + */ + public int getQuickFormTabHrchyLevel() + { + return quickFormTabHrchyLevel; + } + + /** + * @param quickFormHrchyTabLevel + */ + public void setQuickFormTabHrchyLevel(int quickFormHrchyTabLevel) + { + this.quickFormTabHrchyLevel = quickFormHrchyTabLevel; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index d8b5d1c96e..b004f9fa57 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -49,6 +49,7 @@ import org.adempiere.webui.apps.HelpWindow; import org.adempiere.webui.apps.ProcessModalDialog; import org.adempiere.webui.apps.form.WCreateFromFactory; import org.adempiere.webui.apps.form.WCreateFromWindow; +import org.adempiere.webui.apps.form.WQuickForm; import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.ProcessInfoDialog; import org.adempiere.webui.component.Window; @@ -198,6 +199,11 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements private MImage image; + /** + * Quick Form Status bar + */ + protected StatusBar statusBarQF; + /** * Constructor * @param ctx @@ -1100,6 +1106,42 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } + /** + * Invoke when quick form is click + */ + public void onQuickForm() + { + logger.log(Level.FINE, "Invoke Quick Form"); + // Prevent to open Quick Form if already opened. + if (!SessionManager.registerQuickFormTab(getADTab().getSelectedGridTab().getAD_Tab_ID())) + { + logger.fine("TabID=" + getActiveGridTab().getAD_Tab_ID() + " is already open."); + return; + } + int table_ID = adTabbox.getSelectedGridTab().getAD_Table_ID(); + if (table_ID == -1) + return; + + statusBarQF = new StatusBar(); + // Remove Key-listener of parent Quick Form + int tabLevel = getToolbar().getQuickFormTabHrchyLevel(); + if (tabLevel > 0 && getCurrQGV() != null) + { + SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, getCurrQGV()); + } + + WQuickForm form = new WQuickForm(this, m_onlyCurrentRows, m_onlyCurrentDays); + form.setTitle(this.getADTab().getSelectedGridTab().getName()); + form.setVisible(true); + form.setSizable(true); + form.setMaximizable(true); + form.setMaximized(true); + form.setPosition("center"); + ZkCssHelper.appendStyle(form, "min-width: 500px; min-height: 400px; width: 900px; height:550px; z-index: 900;"); + + AEnv.showWindow(form); + } // onQuickForm + /** * @param event * @see EventListener#onEvent(Event) @@ -1149,11 +1191,30 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements hideBusyMask(); ProcessModalDialog dialog = (ProcessModalDialog) event.getTarget(); onModalClose(dialog.getProcessInfo()); - String s = statusBar.getStatusLine(); - boolean b = statusBar.getStatusError(); - ProcessInfoLog[] logs = statusBar.getPLogs(); - onRefresh(true, false); - statusBar.setStatusLine(s, b, logs); + String s = null; + boolean b = false; + ProcessInfoLog[] logs = null; + if (getActiveGridTab().isQuickForm) + { + s = statusBarQF.getStatusLine(); + b = statusBarQF.getStatusError(); + logs = statusBarQF.getPLogs(); + } + else + { + s = statusBar.getStatusLine(); + b = statusBar.getStatusError(); + logs = statusBar.getPLogs(); + } + onRefresh(true, false); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(s, b, logs); + } + else + { + statusBar.setStatusLine(s, b, logs); + } } else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName())) { @@ -1351,6 +1412,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted() && !adTabbox.getSelectedGridTab().isNew()); + toolbar.enableQuickForm(adTabbox.getSelectedTabpanel().isEnableQuickFormButton() && !adTabbox.getSelectedGridTab().isReadOnly()); + boolean isNewRow = adTabbox.getSelectedGridTab().getRowCount() == 0 || adTabbox.getSelectedGridTab().isNew(); //Deepak-Enabling customize button IDEMPIERE-364 if(adTabbox.getSelectedTabpanel() instanceof ADSortTab){//consistent with dataStatusChanged @@ -1466,9 +1529,16 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements if (detailTab) { String msg = e.getTotalRows() + " " + Msg.getMsg(Env.getCtx(), "Records"); adTabbox.setDetailPaneStatusMessage(msg, false); - } else { - statusBar.setStatusLine ("", false); - } + } else { + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine("", false); + } + else + { + statusBar.setStatusLine("", false); + } + } } else { @@ -1541,7 +1611,14 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements if (detailTab) { adTabbox.setDetailPaneStatusMessage(sb.toString (), e.isError ()); } else { - statusBar.setStatusLine (sb.toString (), e.isError ()); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(sb.toString(), e.isError()); + } + else + { + statusBar.setStatusLine(sb.toString(), e.isError()); + } } } } @@ -2192,14 +2269,28 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { if (result) { - String statusLine = statusBar.getStatusLine(); - adTabbox.getSelectedGridTab().dataRefreshAll(true, true); - adTabbox.getSelectedGridTab().refreshParentTabs(); - statusBar.setStatusLine(statusLine); - if( adTabbox.getSelectedDetailADTabpanel() != null && - adTabbox.getSelectedDetailADTabpanel().getGridTab() != null ) - adTabbox.getSelectedDetailADTabpanel().getGridTab().dataRefreshAll(true, true); - } + String statusLine = null; + if (getActiveGridTab().isQuickForm) + { + statusLine = statusBarQF.getStatusLine(); + } + else + { + statusLine = statusBar.getStatusLine(); + } + adTabbox.getSelectedGridTab().dataRefreshAll(true, true); + adTabbox.getSelectedGridTab().refreshParentTabs(); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(statusLine); + } + else + { + statusBar.setStatusLine(statusLine); + } + if (adTabbox.getSelectedDetailADTabpanel() != null && adTabbox.getSelectedDetailADTabpanel().getGridTab() != null) + adTabbox.getSelectedDetailADTabpanel().getGridTab().dataRefreshAll(true, true); + } if (dirtyTabpanel != null) { if (dirtyTabpanel == adTabbox.getSelectedDetailADTabpanel()) Clients.scrollIntoView(dirtyTabpanel); @@ -2207,6 +2298,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } else { focusToActivePanel(); } + + if(adTabbox.getSelectedGridTab().isQuickForm()) + onRefresh(true, true); } }); } @@ -2317,9 +2411,16 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } else if (dirtyTabpanel instanceof ADSortTab) { ADSortTab sortTab = (ADSortTab) dirtyTabpanel; if (!sortTab.isChanged()) { - if (sortTab == adTabbox.getSelectedTabpanel()) { - statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Saved")); - } else { + if (sortTab == adTabbox.getSelectedTabpanel()) { + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(Msg.getMsg(Env.getCtx(), "Saved")); + } + else + { + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Saved")); + } + } else { adTabbox.setDetailPaneStatusMessage(Msg.getMsg(Env.getCtx(), "Saved"), false); } } @@ -2382,7 +2483,14 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements String msg = CLogger.retrieveErrorString(null); if (msg != null) { - statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), msg), true); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(Msg.getMsg(Env.getCtx(), msg), true); + } + else + { + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), msg), true); + } } //other error will be catch in the dataStatusChanged event } @@ -2526,14 +2634,28 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements adTabbox.getSelectedGridTab().refreshParentTabs(); adTabbox.getSelectedTabpanel().dynamicDisplay(0); - statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Deleted")+": "+count, false); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(Msg.getMsg(Env.getCtx(), "Deleted") + ": " + count, false); + } + else + { + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Deleted") + ": " + count, false); + } } if (postCallback != null) postCallback.onCallback(result); } }); } else { - statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Selected")+": 0", false); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(Msg.getMsg(Env.getCtx(), "Selected") + ": 0", false); + } + else + { + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Selected") + ": 0", false); + } if (postCallback != null) postCallback.onCallback(false); } @@ -2824,7 +2946,16 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements */ private void actionButton0 (String col, final IProcessButton wButton) { - final IADTabpanel adtabPanel = findADTabpanel(wButton); + //To perform button action (adtabPanel is null in QuickForm) + IADTabpanel adtabPanel = null; + if (adTabbox.getSelectedGridTab().isQuickForm()) + { + adtabPanel=this.getADTab().getSelectedTabpanel(); + } + else + { + adtabPanel = findADTabpanel(wButton); + } boolean startWOasking = false; if (adtabPanel == null) { return; @@ -2986,7 +3117,16 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements onRefresh(true, false); if (error != null) - statusBar.setStatusLine(error, true); + { + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(error, true); + } + else + { + statusBar.setStatusLine(error, true); + } + } } } }); @@ -3077,7 +3217,15 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements ProcessInfo pi = new ProcessInfo (title, wButton.getProcess_ID(), table_ID, record_ID); pi.setAD_User_ID (Env.getAD_User_ID(ctx)); pi.setAD_Client_ID (Env.getAD_Client_ID(ctx)); - final IADTabpanel adtabPanel = findADTabpanel(wButton); + IADTabpanel adtabPanel = null; + if (adTabbox.getSelectedGridTab().isQuickForm()) + { + adtabPanel=this.getADTab().getSelectedTabpanel(); + } + else + { + adtabPanel = findADTabpanel(wButton); + } GridTab gridTab = null; if (adtabPanel != null) gridTab = adtabPanel.getGridTab(); @@ -3105,7 +3253,11 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } else { - final IADTabpanel adtabPanel = findADTabpanel(wButton); + IADTabpanel adtabPanel = null; + if (adTabbox.getSelectedGridTab().isQuickForm()) + adtabPanel = this.getADTab().getSelectedTabpanel(); + else + adtabPanel = findADTabpanel(wButton); ProcessInfo pi = new ProcessInfo("", wButton.getProcess_ID(), table_ID, record_ID); if (adtabPanel != null && adtabPanel.isGridView() && adtabPanel.getGridTab() != null) @@ -3144,6 +3296,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } dialog.focus(); } + if (adTabbox.getSelectedGridTab().isQuickForm()) { + adTabbox.getSelectedGridTab().dataRefreshAll(false, false); + } else { onRefresh(true, false); @@ -3162,7 +3317,14 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements String error = processButtonCallout((IProcessButton) event.getSource()); if (error != null && error.trim().length() > 0) { - statusBar.setStatusLine(error, true); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(error, true); + } + else + { + statusBar.setStatusLine(error, true); + } return; } actionButton((IProcessButton) event.getSource()); @@ -3187,7 +3349,15 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements */ private String processButtonCallout (IProcessButton button) { - IADTabpanel adtab = findADTabpanel(button); + IADTabpanel adtab = null; + if (adTabbox.getSelectedGridTab().isQuickForm()) + { + adtab=this.getADTab().getSelectedTabpanel(); + } + else + { + adtab = findADTabpanel(button); + } if (adtab != null) { GridField field = adtab.getGridTab().getField(button.getColumnName()); if (field != null) @@ -3280,7 +3450,15 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements // Get Log Info ProcessInfoUtil.setLogFromDB(pi); ProcessInfoLog m_logs[] = pi.getLogs(); - statusBar.setStatusLine(pi.getSummary(), pi.isError(),m_logs); + if (getActiveGridTab().isQuickForm) + { + statusBarQF.setStatusLine(pi.getSummary(), pi.isError(), m_logs); + } + else + { + statusBar.setStatusLine(pi.getSummary(), pi.isError(), m_logs); + } + if (m_logs != null && m_logs.length > 0) { ProcessInfoDialog.showProcessInfo(pi, curWindowNo, getComponent(), false); @@ -3332,7 +3510,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements gridFieldIds.add(fields[i].getAD_Field_ID()); } - CustomizeGridViewDialog.showCustomize(0, adTabbox.getSelectedGridTab().getAD_Tab_ID(), columnsWidth,gridFieldIds,tabPanel.getGridView()); + CustomizeGridViewDialog.showCustomize(0, adTabbox.getSelectedGridTab().getAD_Tab_ID(), columnsWidth,gridFieldIds,tabPanel.getGridView(), null, false); } /** @@ -3405,5 +3583,34 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements Env.setContext(ctx, curWindowNo, "Name", ""); } } + + /** + * @return Quick Form StatusBar + */ + public StatusBar getStatusBarQF() + { + return statusBarQF; + } + + /** + * Implementation to work key listener for the current open Quick Form. + */ + QuickGridView currQGV = null; + /** + * @return + */ + public QuickGridView getCurrQGV() + { + return currQGV; + } + + /** + * @param currQGV + */ + public void setCurrQGV(QuickGridView currQGV) + { + this.currQGV = currQGV; + } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/CompositeADTabbox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/CompositeADTabbox.java index aee6b86eaf..9cc527d8ad 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/CompositeADTabbox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/CompositeADTabbox.java @@ -156,6 +156,26 @@ public class CompositeADTabbox extends AbstractADTabbox else if (DetailPane.ON_DELETE_EVENT.equals(event.getName())) { onDelete(); } + else if (DetailPane.ON_QUICK_FORM_EVENT.equals(event.getName())) + { + if (headerTab.getGridTab().isNew() && !headerTab.needSave(true, false)) + return; + + final int row = getSelectedDetailADTabpanel() != null ? getSelectedDetailADTabpanel().getGridTab().getCurrentRow() : 0; + final boolean formView = event.getData() != null ? (Boolean) event.getData() : true; + + adWindowPanel.saveAndNavigate(new Callback () { + @Override + public void onCallback(Boolean result) + { + if (result) + { + onEditDetail(row, formView); + adWindowPanel.onQuickForm(); + } + } + }); + } } private void onDelete() { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/DetailPane.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/DetailPane.java index cab2439adc..0bc02c1070 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/DetailPane.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/DetailPane.java @@ -69,6 +69,8 @@ public class DetailPane extends Panel implements EventListener, IdSpace { private static final String BTN_NEW_ID = "BtnNew"; private static final String BTN_SAVE_ID = "BtnSave"; + + private static final String BTN_QUICK_FORM_ID = "BtnQuickForm"; private static final String TABBOX_ONSELECT_ATTRIBUTE = "detailpane.tabbox.onselect"; @@ -83,6 +85,7 @@ public class DetailPane extends Panel implements EventListener, IdSpace { private static final String NEW_IMAGE = "images/New16.png"; private static final String PROCESS_IMAGE = "images/Process16.png"; private static final String SAVE_IMAGE = "images/Save16.png"; + private static final String QUICK_FORM_IMAGE = "images/QuickForm16.png"; private ToolBarButton btnNew; @@ -111,6 +114,8 @@ public class DetailPane extends Panel implements EventListener, IdSpace { public static final String ON_SAVE_EVENT = "onSave"; + public static final String ON_QUICK_FORM_EVENT = "onQuickForm"; + private HashMap buttons = new HashMap(); private List toolbarCustomButtons = new ArrayList(); @@ -355,6 +360,24 @@ public class DetailPane extends Panel implements EventListener, IdSpace { buttons.put(BTN_PROCESS_ID.substring(3, BTN_PROCESS_ID.length()), button); } + // ADD Quick Form Button + button = new ToolBarButton(); + if (ThemeManager.isUseFontIconForImage()) + button.setIconSclass("z-icon-QuickForm"); + else + button.setImage(ThemeManager.getThemeResource(QUICK_FORM_IMAGE)); + button.setId(BTN_QUICK_FORM_ID); + button.addEventListener(Events.ON_CLICK, new EventListener() { + @Override + public void onEvent(Event event) throws Exception + { + Event openEvent = new Event(ON_QUICK_FORM_EVENT, DetailPane.this); + eventListener.onEvent(openEvent); + } + }); + button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "QuickForm"))); + buttons.put(BTN_QUICK_FORM_ID.substring(3, BTN_QUICK_FORM_ID.length()), button); + MToolBarButton[] officialButtons = MToolBarButton.getToolbarButtons("D", null); for (MToolBarButton toolbarButton : officialButtons) { if ( !toolbarButton.isActive() ) { @@ -711,7 +734,10 @@ public class DetailPane extends Panel implements EventListener, IdSpace { btn.setDisabled(false); } else if (BTN_SAVE_ID.equals(btn.getId())) { btn.setDisabled(!adtab.needSave(true, false)); - } + } + else if (BTN_QUICK_FORM_ID.equals(btn.getId())) { + btn.setDisabled(!(adtab.isEnableQuickFormButton() && !adtab.getGridTab().isReadOnly())); + } if (windowRestrictList.contains(btn.getId())) { btn.setVisible(false); } else if (tabRestrictList.contains(btn.getId())) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java index 658176a51b..6c58dabeee 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java @@ -84,7 +84,7 @@ public class GridView extends Vlayout implements EventListener, IdSpace, private static final int DEFAULT_DETAIL_PAGE_SIZE = 10; - private static final int DEFAULT_MOBILE_PAGE_SIZE = 20; + public static final int DEFAULT_MOBILE_PAGE_SIZE = 20; private static final int DEFAULT_PAGE_SIZE = 20; @@ -163,7 +163,7 @@ public class GridView extends Vlayout implements EventListener, IdSpace, //default paging size if (ClientInfo.isMobile()) { - //Shoud be <= 20 on mobile + //Should be <= 20 on mobile pageSize = MSysConfig.getIntValue(MSysConfig.ZK_MOBILE_PAGING_SIZE, DEFAULT_MOBILE_PAGE_SIZE, Env.getAD_Client_ID(Env.getCtx())); String limit = Library.getProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT); if (limit == null || !(limit.equals(Integer.toString(pageSize)))) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/IADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/IADTabpanel.java index e94d78b302..7d1911ab04 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/IADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/IADTabpanel.java @@ -191,4 +191,8 @@ public interface IADTabpanel extends Component, Evaluatee { */ public abstract ADTreePanel getTreePanel(); + /** + * @return Quick Form Button Enabled/Disabled + */ + public abstract boolean isEnableQuickFormButton(); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridTabRowRenderer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridTabRowRenderer.java new file mode 100644 index 0000000000..6468e36b32 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridTabRowRenderer.java @@ -0,0 +1,1021 @@ +/****************************************************************************** + * Copyright (C) 2016 Logilite Technologies LLP * + * 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.adwindow; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.adempiere.util.GridRowCtx; +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.Combinationbox; +import org.adempiere.webui.component.Combobox; +import org.adempiere.webui.component.Datebox; +import org.adempiere.webui.component.DatetimeBox; +import org.adempiere.webui.component.EditorBox; +import org.adempiere.webui.component.FilenameBox; +import org.adempiere.webui.component.Locationbox; +import org.adempiere.webui.component.NumberBox; +import org.adempiere.webui.component.PAttributebox; +import org.adempiere.webui.component.Paymentbox; +import org.adempiere.webui.component.Searchbox; +import org.adempiere.webui.component.Textbox; +import org.adempiere.webui.component.Urlbox; +import org.adempiere.webui.editor.WButtonEditor; +import org.adempiere.webui.editor.WEditor; +import org.adempiere.webui.editor.WNumberEditor; +import org.adempiere.webui.editor.WPAttributeEditor; +import org.adempiere.webui.editor.WSearchEditor; +import org.adempiere.webui.editor.WebEditorFactory; +import org.adempiere.webui.event.ActionEvent; +import org.adempiere.webui.event.ActionListener; +import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.util.GridTabDataBinder; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.model.GridField; +import org.compiere.model.GridTab; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.zkoss.zk.au.out.AuScript; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +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; +import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Cell; +import org.zkoss.zul.Column; +import org.zkoss.zul.Grid; +import org.zkoss.zul.Paging; +import org.zkoss.zul.RendererCtrl; +import org.zkoss.zul.Row; +import org.zkoss.zul.RowRenderer; +import org.zkoss.zul.RowRendererExt; +import org.zkoss.zul.Timebox; + +/** + * Row renderer for Quick GridTab grid. + * + * @author Logilite Technologies + * @since Nov 03, 2017 + */ +public class QuickGridTabRowRenderer + implements RowRenderer, RowRendererExt, RendererCtrl, EventListener { + + public static final String IS_QUICK_FORM_COMPONENT = "IS_QUICK_FORM_COMPONENT"; + public static final String GRID_ROW_INDEX_ATTR = "grid.row.index"; + private static final String CELL_DIV_STYLE = "height: 100%; cursor: pointer; "; + private static final String CELL_DIV_STYLE_ALIGN_CENTER = CELL_DIV_STYLE + "text-align:center; "; + private static final String CELL_DIV_STYLE_ALIGN_RIGHT = CELL_DIV_STYLE + "text-align:right; "; + public static final String CURRENT_ROW_STYLE = "border-top: 2px solid #6f97d2; border-bottom: 2px solid #6f97d2"; + // CSS for Disabled component to visible text properly. + public static final String CSS_READ_ONLY_COMPONENT = "quickform-readonly "; + + private GridTab gridTab; + private int windowNo; + private GridTabDataBinder dataBinder; + private Paging paging; + + private RowListener rowListener; + + private Grid grid = null; + private QuickGridView gridPanel = null; + private Row currentRow; + private Object[] currentValues; + private boolean editing = false; + public int currentRowIndex = -1; + private AbstractADWindowContent m_windowPanel; + private ActionListener buttonListener; + // Row-wise Editors Map + public Map> editorsListMap = new LinkedHashMap>(); + // Row-wise read-only Editors Map + public Map> readOnlyEditorsListMap = new LinkedHashMap>(); + /** + * Flag detect this view has customized column or not + * value is set at {@link #render(Row, Object[], int)} + */ + private boolean isGridViewCustomized = false; + // Keep track of shorted column in Quick form. + private Column sortedColumn = null; + // Keep track of sorting order of column in Quick form. for e.g Ascending, Descending and Natural + private String sortOrder; + + /** + * + * @param gridTab + * @param windowNo + */ + public QuickGridTabRowRenderer(GridTab gridTab, int windowNo) { + this.gridTab = gridTab; + this.windowNo = windowNo; + this.dataBinder = new GridTabDataBinder(gridTab); + } + + private WEditor getEditorCell(GridField gridField, Object object) { + WEditor editor = WebEditorFactory.getEditor(gridField, true); + if (editor != null) { + prepareFieldEditor(gridField, editor); + editor.setValue(object); + } + return editor; + } + + private void prepareFieldEditor(GridField gridField, WEditor editor) { + if (editor instanceof WButtonEditor) + { + if (buttonListener != null) + { + ((WButtonEditor)editor).addActionListener(buttonListener); + } + else + { + Object window = SessionManager.getAppDesktop().findWindow(windowNo); + if (window != null && window instanceof ADWindow) + { + AbstractADWindowContent windowPanel = ((ADWindow)window).getADWindowContent(); + ((WButtonEditor)editor).addActionListener(windowPanel); + } + } + } + + //Stretch component to fill grid cell + if (editor.getComponent() instanceof HtmlBasedComponent) { + editor.fillHorizontal(); + } + } + + public int getColumnIndex(GridField field) { + GridField[] fields = gridPanel.getFields(); + for(int i = 0; i < fields.length; i++) { + if (fields[i] == field) + return i; + } + return 0; + } + + /** + * @param paging + */ + public void setPaging(Paging paging) { + this.paging = paging; + } + + /** + * @param row + * @param data + * @see RowRenderer#render(Row, Object) + */ + @Override + public void render(Row row, Object[] data, int index) throws Exception { + //don't render if not visible + int columnCount = 0; + GridField[] gridPanelFields = null; + GridField[] gridTabFields = null; + + if (gridPanel != null) { + if (!gridPanel.isVisible()) { + return; + } + else{ + gridPanelFields = gridPanel.getFields(); + columnCount = gridPanelFields.length; + gridTabFields = gridTab.getFields(); + isGridViewCustomized = gridTabFields.length != gridPanelFields.length; + } + } + + if (grid == null) + grid = (Grid) row.getParent().getParent(); + + if (rowListener == null) + rowListener = new RowListener((Grid)row.getParent().getParent()); + + if (!isGridViewCustomized) { + for(int i = 0; i < gridTabFields.length; i++) { + if (gridPanelFields[i].getAD_Field_ID() != gridTabFields[i].getAD_Field_ID()) { + isGridViewCustomized = true; + break; + } + } + } + if (!isGridViewCustomized) { + currentValues = data; + } else { + List dataList = new ArrayList(); + for(GridField gridField : gridPanelFields) { + for(int i = 0; i < gridTabFields.length; i++) { + gridTabFields[i].setValue(data[i], !gridPanel.isNewLineSaved); + if (gridField.getAD_Field_ID() == gridTabFields[i].getAD_Field_ID()) { + // Update value of gridField for Context Parsing. + gridField.setValue(data[i], !gridPanel.isNewLineSaved); + dataList.add(data[i]); + break; + } + } + } + currentValues = dataList.toArray(new Object[0]); + } + + + Grid grid = (Grid) row.getParent().getParent(); + org.zkoss.zul.Columns columns = grid.getColumns(); + + int rowIndex = index; + if (paging != null && paging.getPageSize() > 0) { + rowIndex = (paging.getActivePage() * paging.getPageSize()) + rowIndex; + } + + Cell cell = new Cell(); + cell.setTooltiptext(Msg.getMsg(Env.getCtx(), "Select")); + Checkbox selection = new Checkbox(); + selection.setAttribute(GRID_ROW_INDEX_ATTR, rowIndex); + selection.setChecked(gridTab.isSelected(rowIndex)); + cell.setStyle("border: none;"); + selection.addEventListener(Events.ON_CHECK, this); + + if (!selection.isChecked()) { + if (gridPanel.selectAll.isChecked()) { + gridPanel.selectAll.setChecked(false); + } + } + + cell.appendChild(selection); + row.appendChild(cell); + + Boolean isActive = null; + int colIndex = -1; + // Editors List of Current Rendered Row + ArrayList editorsList = new ArrayList(); + // Read-only editors List of Current Rendered Row + ArrayList readOnlyEditorsList = new ArrayList(); + for (int i = 0; i < columnCount; i++) { + if (!gridPanelFields[i].isQuickForm()){ + continue; + } + + if ("IsActive".equals(gridPanelFields[i].getColumnName())) { + isActive = Boolean.FALSE; + if (currentValues[i] != null) { + if ("true".equalsIgnoreCase(currentValues[i].toString())) { + isActive = Boolean.TRUE; + } + } + } + + // IDEMPIERE-2148: when has tab customize, ignore check properties isDisplayedGrid + if ((!isGridViewCustomized && gridPanelFields[i].isDisplayedGrid()) || gridPanelFields[i].isToolbarOnlyButton()) { + continue; + } + colIndex ++; + + Cell div = new Cell(); + String divStyle = CELL_DIV_STYLE; + org.zkoss.zul.Column column = (org.zkoss.zul.Column) columns.getChildren().get(colIndex); + if (column.isVisible()) { + WEditor componentEditor = getEditorCell(gridPanelFields[i], currentValues[i]); + editorsList.add(componentEditor); + componentEditor.getComponent().addEventListener(Events.ON_FOCUS, gridPanel); + Component component = componentEditor.getComponent(); + component.setAttribute(IS_QUICK_FORM_COMPONENT, true); + div.appendChild(component); + div.setAttribute("display.component", component); + if (componentEditor instanceof WPAttributeEditor) + { + ((WPAttributeEditor) componentEditor).getComponent().getButton().addEventListener(Events.ON_FOCUS, gridPanel); + } + else if (componentEditor instanceof WSearchEditor) + { + ((WSearchEditor) componentEditor).getComponent().getButton().addEventListener(Events.ON_FOCUS, gridPanel); + } + else if (componentEditor instanceof WNumberEditor) + { + ((WNumberEditor) componentEditor).getComponent().getButton().addEventListener(Events.ON_FOCUS, gridPanel); + } + if (gridPanelFields[i].isHeading()) { + component.setVisible(false); + } + + if (DisplayType.YesNo == gridPanelFields[i].getDisplayType() || DisplayType.Image == gridPanelFields[i].getDisplayType()) + { + divStyle = CELL_DIV_STYLE_ALIGN_CENTER; + } + else if (DisplayType.isNumeric(gridPanelFields[i].getDisplayType())) + { + divStyle = CELL_DIV_STYLE_ALIGN_RIGHT; + } + if (isDisableReadonlyComponent(component, true)) + { + readOnlyEditorsList.add(componentEditor); + } + + GridRowCtx ctx = new GridRowCtx(Env.getCtx(), gridTab, rowIndex); + // Enable or Disable Component + componentEditor.setReadWrite(gridPanelFields[i].isEditable(ctx, true, false)); + if (!gridPanelFields[i].isDisplayed(ctx, true)){ + // IDEMPIERE-2253 + component.setVisible(false); + } + } + div.setStyle(divStyle); + ZKUpdateUtil.setWidth(div, "100%"); + div.setAttribute("columnName", gridPanelFields[i].getColumnName()); + div.addEventListener(Events.ON_CLICK, rowListener); + div.addEventListener(Events.ON_DOUBLE_CLICK, rowListener); + editing = true; + GridTableListModel model = (GridTableListModel) grid.getModel(); + model.setEditing(true); + row.appendChild(div); + } + + editorsListMap.put(row, editorsList); + readOnlyEditorsListMap.put(row, readOnlyEditorsList); + + if (rowIndex == gridTab.getCurrentRow()) { + setCurrentRow(row); + } + + row.setStyle("cursor:pointer"); + row.addEventListener(Events.ON_CLICK, rowListener); + row.addEventListener(Events.ON_OK, rowListener); + row.setTooltiptext("Row " + (rowIndex+1)); + + if (isActive == null) { + Object isActiveValue = gridTab.getValue(rowIndex, "IsActive"); + if (isActiveValue != null) { + if ("true".equalsIgnoreCase(isActiveValue.toString())) { + isActive = Boolean.TRUE; + } else { + isActive = Boolean.FALSE; + } + } + } + if (isActive != null && !isActive.booleanValue()) { + LayoutUtils.addSclass("grid-inactive-row", row); + } + if (gridTab.isNew()) + gridPanel.isNewLineSaved = false; + // Set focus to first editable cell of the last record if multiple + // records inserted + if (gridPanel.paging.getTotalSize() != gridTab.getRowCount()) + { + gridPanel.updateListIndex(); + if (!gridPanel.isNewLineSaved) + { + gridPanel.isNewLineSaved = true; + paging.setActivePage( + paging.getActivePage() + (paging.getActivePage() == (paging.getPageCount() - 1) ? 0 : 1)); + gridPanel.listModel.setPage(paging.getActivePage()); + gridPanel.updateModelIndex(0); + setCurrentCell(gridTab.getRowCount() - 1 % paging.getPageSize() + - (paging.getActivePage() * paging.getPageSize()), 1, KeyEvent.RIGHT); + } + Events.echoEvent(QuickGridView.EVENT_ON_SET_FOCUS_TO_FIRST_CELL, gridPanel, null); + } + + // When shorting is done all rows are rendered and focus is lost. + // If record are shorting then set focus to the first row of the current page. + Column column = gridPanel.findCurrentSortColumn(); + if (column != null && gridPanel.isNewLineSaved && (sortedColumn == null || sortedColumn != column + || (sortedColumn == column && sortOrder != column.getSortDirection()))) + { + sortedColumn = column; + sortOrder = column.getSortDirection(); + Events.echoEvent(QuickGridView.EVENT_ON_PAGE_NAVIGATE, gridPanel, null); + } + } + + /** + * Disable Read-only components for while pressing tab button focus goes to + * read-only component. + * Enable Read-only component before display Logic update. + * Add/Remove CSS Class from read-only component + * + * @param component + * @param isDisable + * @return + */ + public boolean isDisableReadonlyComponent(Component component, boolean isDisable) + { + boolean isReadonly = false; + if (component instanceof NumberBox) + { + NumberBox comp = ((NumberBox) component); + if (comp.getDecimalbox().isReadonly()) + { + comp.getDecimalbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Textbox) + { + Textbox comp = ((Textbox) component); + if (comp.isReadonly()) + { + comp.setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Datebox) + { + Datebox comp = ((Datebox) component); + if (comp.isReadonly()) + { + comp.setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof DatetimeBox) + { + DatetimeBox comp = ((DatetimeBox) component); + if (comp.getTimebox().isReadonly()) + { + comp.getTimebox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + if (comp.getDatebox().isReadonly()) + { + comp.getDatebox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Searchbox) + { + Searchbox comp = ((Searchbox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Combinationbox) + { + Combinationbox comp = ((Combinationbox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof EditorBox) + { + EditorBox comp = ((EditorBox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Urlbox) + { + Urlbox comp = ((Urlbox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof FilenameBox) + { + FilenameBox comp = ((FilenameBox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Timebox) + { + Timebox comp = ((Timebox) component); + if (comp.isReadonly()) + { + comp.setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof Paymentbox) + { + Paymentbox comp = ((Paymentbox) component); + if (comp.getCombobox().isReadonly()) + { + comp.getCombobox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + else if (component instanceof PAttributebox) + { + PAttributebox comp = ((PAttributebox) component); + if (comp.getTextbox().isReadonly()) + { + comp.getTextbox().setDisabled(isDisable); + comp.setZclass(addOrRemoveCssClass(comp.getZclass(), isDisable)); + isReadonly = true; + } + } + return isReadonly; + } + + /** + * Add/Remove CSS class from Read-only Component + * + * @param zclass + * @param isDisable + * @return + */ + private String addOrRemoveCssClass(String zclass, boolean isDisable) + { + if (zclass == null) + zclass = ""; + if (isDisable) + { + zclass += CSS_READ_ONLY_COMPONENT; + } + else + { + if (zclass.contains(CSS_READ_ONLY_COMPONENT)) + zclass.replaceAll(CSS_READ_ONLY_COMPONENT, ""); + } + return zclass; + } + + private Cell currentCell = null; + + public Cell getCurrentCell() { + return currentCell; + } + + public void setCurrentCell(Cell currentCell) { + this.currentCell = currentCell; + } + + public void setCurrentCell(int row, int col, int code) { + if (col < 0 || row < 0) + return; + int currentCol = col; + boolean isLastCell = false; + while (!isEditable(row, col)) + { + if (!(code == KeyEvent.RIGHT || code == KeyEvent.LEFT || code == KeyEvent.DOWN || code == KeyEvent.UP + || code == QuickGridView.NAVIGATE_CODE)) + { + break; + } + else if (code == KeyEvent.RIGHT || code == QuickGridView.NAVIGATE_CODE) + { + ++col; + } + else if (code == KeyEvent.LEFT) + { + --col; + } + // on UP/DOWN go to next editable field if move field is not + // editable + else if (code == KeyEvent.DOWN || code == KeyEvent.UP) + { + if (isLastCell) + { + col--; + + } + else + { + col++; + if (col > gridPanel.getGridField().length) + { + col = currentCol; + isLastCell = true; + } + + } + } + + if (col < 0 && !isLastCell) + { + setFocusOnCurrentCell(); + return; + } + } + if (isAddRemoveListener(code)) + { + // Remove current row property change listener + addRemovePropertyChangeListener(false, col); + } + + int pgIndex = row >= 0 ? row % paging.getPageSize() : 0; + if (row != currentRowIndex || pgIndex != currentRowIndex) { + if (currentRow != null) + currentRow.setStyle(null); + if (grid.getRows().getChildren().size() <= 0) { + currentCell = null; + return; + } + gridTab.setCurrentRow(pgIndex + paging.getActivePage() * paging.getPageSize()); + currentRow = ((Row) grid.getRows().getChildren().get(pgIndex)); + currentRowIndex = gridTab.getCurrentRow(); + currentRow.setStyle(CURRENT_ROW_STYLE); + } + + setCurrentRow(currentRow); + + if (isAddRemoveListener(code)) + { + // Add property change listener to new current row + addRemovePropertyChangeListener(true, col); + } + + if (grid.getCell(pgIndex, col) instanceof Cell) { + currentCell = (Cell) grid.getCell(pgIndex, col); + } + if (currentCell != null && code != QuickGridView.FOCUS_CODE) { + setFocusOnCurrentCell(); + } + } + + /** + * Set Property change listener of editor field + * + * @param editorsList + */ + private void addEditorPropertyChangeListener(ArrayList editorsList) + { + GridField[] fields = gridPanel.getFields(); + for (int i = 0; i < editorsList.size(); i++) + { + editorsList.get(i).addValueChangeListener(dataBinder); + fields[i].removePropertyChangeListener(editorsList.get(i)); + fields[i].addPropertyChangeListener(editorsList.get(i)); + } + } + + /** + * Remove Property change listener of editor field + * + * @param editorsList + */ + private void removeEditorPropertyChangeListener(ArrayList editorsList) + { + GridField[] fields = gridPanel.getFields(); + for (int i = 0; i < editorsList.size(); i++) + { + fields[i].removePropertyChangeListener(editorsList.get(i)); + editorsList.get(i).removeValuechangeListener(dataBinder); + } + } + + /** + * If true add Property Change Listener, a false Remove Property Change Listener + * + * @param isAddListener + * @param col + */ + public void addRemovePropertyChangeListener(boolean isAddListener, int col) + { + ArrayList editorsList = editorsListMap.get(getCurrentRow()); + if (editorsList != null) + { + if (isAddListener) + { + addEditorPropertyChangeListener(editorsList); + gridPanel.dynamicDisplay(col); + } + else + { + removeEditorPropertyChangeListener(editorsList); + } + } + } // addRemovePropertyChangeListener + + /** + * @param code + * @return + */ + public Boolean isAddRemoveListener(int code) + { + if (code == KeyEvent.DOWN || code == KeyEvent.UP || code == QuickGridView.FOCUS_CODE + || code == QuickGridView.NAVIGATE_CODE || code == KeyEvent.HOME) + return true; + return false; + } // isAddRemoveListener + + /** + * @param row + */ + public void setRowTo(int row) + { + int pgIndex = row >= 0 ? row % paging.getPageSize() : 0; + currentRow = ((Row) grid.getRows().getChildren().get(pgIndex)); + currentRow.setStyle(QuickGridTabRowRenderer.CURRENT_ROW_STYLE); + setCurrentRow(currentRow); + } + + private boolean isEditable(int row, int col) + { + Cell cell = null; + + if (col > getCurrentRow().getChildren().size()) + return true; + + if (grid.getCell(row, col) instanceof Cell) + cell = (Cell) grid.getCell(row, col); + else + return true; + + if (cell == null) + return true; + if (cell.getChildren().size() <= 0) + return false; + // get component of cell + Component component = cell.getChildren().get(0); + if (component instanceof NumberBox && (!((NumberBox) component).getDecimalbox().isDisabled() && !((NumberBox) component).getDecimalbox().isReadonly() && ((NumberBox) component).getDecimalbox().isVisible())) + return true; + else if (component instanceof Checkbox && (((Checkbox) component).isEnabled() && ((Checkbox) component).isVisible())) + return true; + else if (component instanceof Combobox && (!((Combobox) component).isReadonly() && ((Combobox) component).isEnabled() && ((Combobox) component).isVisible())) + return true; + else if (component instanceof Textbox && (!((Textbox) component).isDisabled() && !((Textbox) component).isReadonly() && ((Textbox) component).isVisible())) + return true; + else if (component instanceof Datebox && (!((Datebox) component).isReadonly() && ((Datebox) component).isEnabled() && ((Datebox) component).isVisible())) + return true; + else if (component instanceof DatetimeBox && (((DatetimeBox) component).isEnabled() && ((DatetimeBox) component).isVisible())) + return true; + else if (component instanceof Locationbox && (((Locationbox) component).isEnabled() && ((Locationbox) component).isVisible())) + return true; + else if (component instanceof Searchbox && (!((Searchbox) component).getTextbox().isDisabled() && !((Searchbox) component).getTextbox().isReadonly() && ((Searchbox) component).getTextbox().isVisible())) + return true; + else if (component instanceof Button && (((Button) component).isEnabled() && ((Button) component).isVisible())) + return true; + else if (component instanceof Combinationbox && (!((Combinationbox) component).getTextbox().isReadonly() && ((Combinationbox) component).isEnabled() && ((Combinationbox) component).isVisible())) + return true; + else if (component instanceof EditorBox && (!((EditorBox) component).getTextbox().isReadonly() && ((EditorBox) component).isEnabled() && ((EditorBox) component).isVisible())) + return true; + else if (component instanceof Urlbox && (((Urlbox) component).isEnabled() && ((Urlbox) component).isVisible())) + return true; + else if (component instanceof FilenameBox && (!((FilenameBox) component).getTextbox().isReadonly() && ((FilenameBox) component).isEnabled() && ((FilenameBox) component).isVisible())) + return true; + else if (component instanceof Timebox && !((Timebox) component).isReadonly() && ((Timebox) component).isVisible()) + return true; + else if (component instanceof Paymentbox && (((Paymentbox) component).isEnabled() && ((Paymentbox) component).isVisible())) + return true; + else if (component instanceof PAttributebox && !((PAttributebox) component).getTextbox().isReadonly() && (((PAttributebox) component).isEnabled() && ((PAttributebox) component).isVisible())) + return true; + else + return false; + } + + public void setFocusOnCurrentCell() { + if (currentCell == null || currentCell.getChildren().size() <= 0) { + return; + } + + Component component = currentCell.getChildren().get(0); + if (component instanceof NumberBox) + { + ((NumberBox) component).focus(); + ((NumberBox) component).getDecimalbox().select(); + } + else if (component instanceof Checkbox) + ((Checkbox) component).focus(); + else if (component instanceof Combobox) + ((Combobox) component).focus(); + else if (component instanceof Textbox) + { + ((Textbox) component).focus(); + ((Textbox) component).select(); + } + else if (component instanceof Datebox) + ((Datebox) component).focus(); + else if (component instanceof DatetimeBox) + ((DatetimeBox) component).focus(); + else if (component instanceof Locationbox) + ((Locationbox) component).focus(); + else if (component instanceof Combinationbox) + { + ((Combinationbox) component).getTextbox().focus(); + ((Combinationbox) component).getTextbox().select(); + } + else if (component instanceof Searchbox) + { + ((Searchbox) component).getTextbox().focus(); + ((Searchbox) component).getTextbox().select(); + } + else if (component instanceof Button) + ((Button) component).focus(); + else if (component instanceof EditorBox) + ((EditorBox) component).focus(); + else if (component instanceof Urlbox) + ((Urlbox) component).focus(); + else if (component instanceof FilenameBox) + ((FilenameBox) component).focus(); + else if (component instanceof Timebox) + ((Timebox) component).focus(); + else if (component instanceof Paymentbox) + ((Paymentbox) component).focus(); + else if (component instanceof PAttributebox) + ((PAttributebox) component).focus(); + else + ((HtmlBasedComponent) currentCell).focus(); + } // setFocusOnCurrentCell + + /** + * @param row + */ + public void setCurrentRow(Row row) + { + currentRow = row; + + String script = "jq('#" + row.getUuid() + "').addClass('highlight').siblings().removeClass('highlight')"; + + if (!gridTab.getValueAsBoolean("IsActive")) + { + script = "jq('#" + row.getUuid() + "').addClass('grid-inactive-row').siblings().removeClass('highlight')"; + } + + Clients.response(new AuScript(script)); + } + + /** + * @return Row + */ + public Row getCurrentRow() { + return currentRow; + } + + /** + * @return current row index ( absolute ) + */ + public int getCurrentRowIndex() { + return currentRowIndex; + } + + /** + * Enter edit mode + */ + public void editCurrentRow() { + if (currentRow != null && currentRow.getParent() != null && currentRow.isVisible() && grid != null + && grid.isVisible() && grid.getParent() != null && grid.getParent().isVisible()) { + + editing = true; + + GridTableListModel model = (GridTableListModel) grid.getModel(); + model.setEditing(true); + } + } + + /** + * @see RowRendererExt#getControls() + */ + public int getControls() { + return DETACH_ON_RENDER; + } + + /** + * @see RowRendererExt#newCell(Row) + */ + public Component newCell(Row row) { + return null; + } + + /** + * @see RowRendererExt#newRow(Grid) + */ + public Row newRow(Grid grid) { + return null; + } + + /** + * @see RendererCtrl#doCatch(Throwable) + */ + public void doCatch(Throwable ex) throws Throwable { + } + + /** + * @see RendererCtrl#doFinally() + */ + public void doFinally() { + } + + /** + * @see RendererCtrl#doTry() + */ + public void doTry() { + } + + /** + * + * @param gridPanel + */ + public void setGridPanel(QuickGridView gridPanel) { + this.gridPanel = gridPanel; + } + + static class RowListener implements EventListener { + + private Grid _grid; + + public RowListener(Grid grid) { + _grid = grid; + } + + public void onEvent(Event event) throws Exception { + if (Events.ON_CLICK.equals(event.getName())) { + if (Executions.getCurrent().getAttribute("gridView.onSelectRow") != null) + return; + Event evt = new Event(Events.ON_CLICK, _grid, event.getTarget()); + Events.sendEvent(_grid, evt); + evt.stopPropagation(); + } + else if (Events.ON_DOUBLE_CLICK.equals(event.getName())) { + Event evt = new Event(Events.ON_DOUBLE_CLICK, _grid, _grid); + Events.sendEvent(_grid, evt); + } + else if (Events.ON_OK.equals(event.getName())) { + Event evt = new Event(Events.ON_OK, _grid, _grid); + Events.sendEvent(_grid, evt); + } + } + } + + /** + * @return boolean + */ + public boolean isEditing() { + return editing; + } + + /** + * @param windowPanel + */ + public void setADWindowPanel(AbstractADWindowContent windowPanel) { + if (this.m_windowPanel == windowPanel) + return; + + this.m_windowPanel = windowPanel; + + buttonListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + WButtonEditor editor = (WButtonEditor) event.getSource(); + Integer rowIndex = (Integer) editor.getComponent().getAttribute(GRID_ROW_INDEX_ATTR); + if (rowIndex != null) { + int newRowIndex = gridTab.navigate(rowIndex); + if (newRowIndex == rowIndex) { + m_windowPanel.actionPerformed(event); + } + } else { + m_windowPanel.actionPerformed(event); + } + } + }; + } + + @Override + public void onEvent(Event event) throws Exception { + if (event.getTarget() instanceof Cell) { + Cell cell = (Cell) event.getTarget(); + if (cell.getSclass() != null && cell.getSclass().indexOf("row-indicator-selected") >= 0) + Events.sendEvent(gridPanel, new Event(DetailPane.ON_EDIT_EVENT, gridPanel)); + else + Events.sendEvent(event.getTarget().getParent(), event); + } else if (event.getTarget() instanceof Checkbox) { + Executions.getCurrent().setAttribute("gridView.onSelectRow", Boolean.TRUE); + Checkbox checkBox = (Checkbox) event.getTarget(); + Events.sendEvent(gridPanel, new Event("onSelectRow", gridPanel, checkBox)); + } + } + + /** + * Clear editorsListmap on page change and dispose. + */ + public void clearMaps() + { + editorsListMap.clear(); + readOnlyEditorsListMap.clear(); + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridView.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridView.java new file mode 100644 index 0000000000..9fc699847d --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/QuickGridView.java @@ -0,0 +1,1552 @@ +/****************************************************************************** + * Copyright (C) 2016 Logilite Technologies LLP * + * 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.adwindow; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +import javax.swing.table.AbstractTableModel; + +import org.adempiere.base.Core; +import org.adempiere.model.MTabCustomization; +import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.apps.form.WQuickForm; +import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.Columns; +import org.adempiere.webui.component.Combobox; +import org.adempiere.webui.component.Grid; +import org.adempiere.webui.component.Rows; +import org.adempiere.webui.component.Searchbox; +import org.adempiere.webui.editor.WEditor; +import org.adempiere.webui.editor.WSearchEditor; +import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.util.SortComparator; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.model.GridField; +import org.compiere.model.GridTab; +import org.compiere.model.GridTable; +import org.compiere.model.MSysConfig; +import org.compiere.model.StateChangeEvent; +import org.compiere.model.StateChangeListener; +import org.compiere.util.CLogger; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Util; +import org.zkforge.keylistener.Keylistener; +import org.zkoss.lang.Library; +import org.zkoss.zk.au.out.AuScript; +import org.zkoss.zk.ui.AbstractComponent; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.IdSpace; +import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Cell; +import org.zkoss.zul.Column; +import org.zkoss.zul.Div; +import org.zkoss.zul.Frozen; +import org.zkoss.zul.Paging; +import org.zkoss.zul.Row; +import org.zkoss.zul.Vbox; +import org.zkoss.zul.event.ZulEvents; +import org.zkoss.zul.impl.CustomGridDataLoader; + +/** + * Quick Grid view implemented using the Grid component. + * + * @author Logilite Technologies + * @since Nov 03, 2017 + */ +public class QuickGridView extends Vbox + implements EventListener, IdSpace, IFieldEditorContainer, StateChangeListener { + /** + * + */ + private static final long serialVersionUID = -2966799998482667434L; + + static CLogger log = CLogger.getCLogger(QuickGridView.class); + + private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;"; + + private static final int DEFAULT_PAGE_SIZE = 20; + + private static final int MIN_COLUMN_WIDTH = 100; + + private static final int MAX_COLUMN_WIDTH = 300; + + private static final int MIN_COMBOBOX_WIDTH = 160; + + private static final int MIN_NUMERIC_COL_WIDTH = 120; + + public static final int SALES_ORDER_LINE_TAB_ID = 187; + + private static final String ATTR_ON_POST_SELECTED_ROW_CHANGED = "org.adempiere.webui.adwindow.GridView.onPostSelectedRowChanged"; + + public static final String CNTRL_KEYS = "#left#right#up#down#home@k@r"; + + // Event Listeners + public static final String EVENT_ON_SELECT_ROW = "onSelectRow"; + public static final String EVENT_ON_CUSTOMIZE_GRID = "onCustomizeGrid"; + public static final String EVENT_ON_PAGE_NAVIGATE = "onPageNavigate"; + public static final String EVENT_ON_CLICK_TO_NAVIGATE = "onClickToNavigate"; + public static final String EVENT_ON_SET_FOCUS_TO_FIRST_CELL = "onSetFocusToFirstCell"; + public static final String EVENT_ON_AFTER_SAVE = "onAfterSave"; + public static final String EVENT_ONFOCUS_AFTER_SAVE = "onFocusAfterSave"; + + // Code for navigation to setcurrentcell + public static final int NAVIGATE_CODE = 1; + public static final int FOCUS_CODE = 0; + + private Grid listbox = null; + + private int pageSize = DEFAULT_PAGE_SIZE; + + /** + * list field display in grid mode, in case user customize grid + * this list container only customize list. + */ + private GridField[] gridFields; + private AbstractTableModel tableModel; + + private int numColumns = 5; + + private int windowNo; + + private GridTab gridTab; + + private boolean init; + + public GridTableListModel listModel; + + public Paging paging; + + private QuickGridTabRowRenderer renderer; + + private Div gridFooter; + + private boolean modeless = true; + + private AbstractADWindowContent windowPanel; + + private boolean refreshing; + + private Map columnWidthMap; + + protected Checkbox selectAll; + + boolean isHasCustomizeData = false; + + Keylistener keyListener; + + public boolean isNewLineSaved = true; + + // Prevent focus change until render is complete + private boolean isOnFocusAfterSave = false; + // To prevent 'onFocus' event fire twice on same component. + private Component preEventComponent; + + // 'Alt + K' for Save and Close + private static final int KEYBOARD_KEY_K = 75; + // 'Alt + S' for Save + private static final int KEYBOARD_KEY_S = 83; + // 'Alt + Z' for Ignore + private static final int KEYBOARD_KEY_Z = 90; + // 'Alt + E' for Refresh + private static final int KEYBOARD_KEY_E = 69; + // 'Enter' Work as Down key + private static final int KEYBOARD_KEY_ENTER = 13; + // 'Alt + D' for Delete + private static final int KEYBOARD_KEY_D = 68; + // 'Alt + X' for Close + private static final int KEYBOARD_KEY_X = 88; + // 'Alt + L' for opening Customize grid panel + private static final int KEYBOARD_KEY_L = 76; + // 'Alt + R' for UnSort + private static final int KEYBOARD_KEY_R = 82; + + public WQuickForm quickForm; + + public GridField[] getGridField() { + return gridFields; + } + + public void setGridField(GridField[] gridField) { + this.gridFields = gridField; + } + + public QuickGridTabRowRenderer getRenderer() { + return renderer; + } + + /** + * @param windowNo + */ + public QuickGridView(int windowNo) + { + this.windowNo = windowNo; + setId("quickGridView"); + createListbox(); + + ZKUpdateUtil.setHflex(this, "1"); + + gridFooter = new Div(); + ZKUpdateUtil.setVflex(gridFooter, "0"); + + //default paging size + if (ClientInfo.isMobile()) + { + //Should be <= 20 on mobile + pageSize = MSysConfig.getIntValue(MSysConfig.ZK_MOBILE_PAGING_SIZE, GridView.DEFAULT_MOBILE_PAGE_SIZE, Env.getAD_Client_ID(Env.getCtx())); + String limit = Library.getProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT); + if (limit == null || !(limit.equals(Integer.toString(pageSize)))) { + Library.setProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT, Integer.toString(pageSize)); + } + } + else + { + pageSize = MSysConfig.getIntValue(MSysConfig.QUICKFORM_PAGE_SIZE, DEFAULT_PAGE_SIZE, Env.getAD_Client_ID(Env.getCtx())); + String limit = Library.getProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT); + if (limit == null || !(limit.equals(Integer.toString(pageSize)))) { + Library.setProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT, Integer.toString(pageSize)); + } + } + //default true for better UI experience + if (ClientInfo.isMobile()) + modeless = MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_MOBILE_EDIT_MODELESS, false); + else + modeless = MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_EDIT_MODELESS, true); + + appendChild(listbox); + appendChild(gridFooter); + ZKUpdateUtil.setVflex(this, "true"); + + setStyle(HEADER_GRID_STYLE); + gridFooter.setStyle(HEADER_GRID_STYLE); + + addEventListener(EVENT_ON_SELECT_ROW, this); + addEventListener(EVENT_ON_CUSTOMIZE_GRID, this); + addEventListener(EVENT_ON_PAGE_NAVIGATE, this); + addEventListener(EVENT_ON_CLICK_TO_NAVIGATE, this); + addEventListener(EVENT_ON_SET_FOCUS_TO_FIRST_CELL, this); + addEventListener(EVENT_ON_AFTER_SAVE, this); + addEventListener(EVENT_ONFOCUS_AFTER_SAVE, this); + } + + public QuickGridView(AbstractADWindowContent abstractADWindowContent, GridTab gridTab, WQuickForm wQuickForm) + { + this(abstractADWindowContent.getWindowNo()); + setADWindowPanel(abstractADWindowContent); + this.quickForm = wQuickForm; + init(gridTab); + } + + protected void createListbox() + { + listbox = new Grid(); + listbox.setSizedByContent(false); + ZKUpdateUtil.setVflex(listbox, "1"); + ZKUpdateUtil.setHflex(listbox, "1"); + listbox.setSclass("adtab-grid"); + listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Processing"))); + } + + /** + * + * @param gridTab + */ + public void init(GridTab gridTab) + { + if (init) return; + + if (this.gridTab != null) + this.gridTab.removeStateChangeListener(this); + + setupFields(gridTab); + + setupColumns(); + render(); + + updateListIndex(); + + this.init = true; + } + + private void setupFields(GridTab gridTab) { + this.gridTab = gridTab; + gridTab.addStateChangeListener(this); + + tableModel = gridTab.getTableModel(); + columnWidthMap = new HashMap(); + GridField[] modelFields = ((GridTable)tableModel).getFields(); + MTabCustomization tabCustomization = MTabCustomization.get(Env.getCtx(), Env.getAD_User_ID(Env.getCtx()), gridTab.getAD_Tab_ID(), null, true); + isHasCustomizeData = tabCustomization != null && tabCustomization.getAD_Tab_Customization_ID() > 0 + && tabCustomization.getCustom() != null && tabCustomization.getCustom().trim().length() > 0; + if (isHasCustomizeData) { + String custom = tabCustomization.getCustom().trim(); + String[] customComponent = custom.split(";"); + String[] fieldIds = customComponent[0].split("[,]"); + List gridFieldsList = new ArrayList(); + for(String fieldId : fieldIds) { + fieldId = fieldId.trim(); + int AD_Field_ID=0; + if (fieldId.length() == 0) continue; + try + { + AD_Field_ID = Integer.parseInt(fieldId); + } + catch (NumberFormatException e) + { + log.log(Level.SEVERE, "", e); + continue; + } + for(GridField gridField : modelFields) { + if (gridField.getAD_Field_ID() == AD_Field_ID) { + // IDEMPIERE-2204 add field in tabCustomization list to + // display list event this field have showInGrid = false + // if ((gridField.isDisplayedGrid() || + // gridField.isDisplayed()) + // && !gridField.isToolbarOnlyButton()) + + // add field in tabCustomization list to display list + // event this field have showInGrid = false + if (gridField.isQuickForm()) + gridFieldsList.add(gridField); + + break; + } + } + } + gridFields = gridFieldsList.toArray(new GridField[0]); + // if any new column added for quick form. + for (GridField field : modelFields) { + if (field.isQuickForm()) { + boolean isFieldAvailable = false; + for (GridField gField : gridFields) { + if (gField.getAD_Field_ID() == field.getAD_Field_ID()) { + isFieldAvailable = true; + break; + } + } + if (!isFieldAvailable) + gridFieldsList.add(field); + } + } + gridFields = gridFieldsList.toArray(new GridField[0]); + if (customComponent.length == 2) { + String[] widths = customComponent[1].split("[,]"); + for(int i = 0; i< gridFields.length && i gridFieldsList = new ArrayList(); + + for(GridField field:modelFields){ + if (field.isQuickForm()) + { + gridFieldsList.add(field); + } + } + + Collections.sort(gridFieldsList, new Comparator() { + @Override + public int compare(GridField o1, GridField o2) { + return o1.getSeqNoGrid()-o2.getSeqNoGrid(); + } + }); + + gridFields = new GridField[gridFieldsList.size()]; + gridFieldsList.toArray(gridFields); + } + numColumns = gridFields.length; + } + + /** + * + * @return boolean + */ + public boolean isInit() { + return init; + } + + /** + * refresh after switching from form view + * @param gridTab + */ + public void refresh(GridTab gridTab) { + if (this.gridTab != gridTab || !isInit()) + { + init = false; + init(gridTab); + } + else + { + refreshing = true; + listbox.setModel(listModel); + updateListIndex(); + refreshing = false; + if (gridTab.getRowCount() == 0 && selectAll.isChecked()) + selectAll.setChecked(false); + } + } + + public boolean isRefreshing() { + return refreshing; + } + + /** + * Update current row from model + */ + public void updateListIndex() { + if (gridTab == null || !gridTab.isOpen()) return; + + updateEmptyMessage(); + + int rowIndex = gridTab.getCurrentRow(); + if (pageSize > 0) { + if (paging.getTotalSize() != gridTab.getRowCount()) + paging.setTotalSize(gridTab.getRowCount()); + if (paging.getPageCount() > 1 && !gridFooter.isVisible()) { + showPagingControl(); + } + int pgIndex = rowIndex >= 0 ? rowIndex % pageSize : 0; + int pgNo = rowIndex >= 0 ? (rowIndex - pgIndex) / pageSize : 0; + if (listModel.getPage() != pgNo) { + listModel.setPage(pgNo); + } else if (rowIndex == renderer.getCurrentRowIndex()){ + if (modeless && !renderer.isEditing()) + echoOnPostSelectedRowChanged(); + return; + } else { + if (renderer.isEditing()) { + int editingRow = renderer.getCurrentRowIndex(); + if (editingRow >= 0) { + int editingPgIndex = editingRow % pageSize; + int editingPgNo = (editingRow - editingPgIndex) / pageSize; + if (editingPgNo == pgNo) { + listModel.updateComponent(renderer.getCurrentRowIndex() % pageSize); + } + } + } + } + if (paging.getActivePage() != pgNo) { + paging.setActivePage(pgNo); + } + // Fire event for first record. + if (rowIndex >= 0 && pgIndex >= 0 && isNewLineSaved || rowIndex == 0 && pgIndex == 0 && !isNewLineSaved) + { + echoOnPostSelectedRowChanged(); + } + } else { + if (rowIndex >= 0 && isNewLineSaved) { + echoOnPostSelectedRowChanged(); + } + } + } + + private void hidePagingControl() { + if (gridFooter.isVisible()) + gridFooter.setVisible(false); + } + + private void showPagingControl() { + if (!gridFooter.isVisible()) + gridFooter.setVisible(true); + } + + /** + * + */ + protected void echoOnPostSelectedRowChanged() { + if (getAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED) == null) { + setAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED, Boolean.TRUE); + Events.echoEvent("onPostSelectedRowChanged", this, null); + } + } + + /** + * set paging size + * @param pageSize + */ + public void setPageSize(int pageSize) + { + this.pageSize = pageSize; + } + + public void clear() + { + this.getChildren().clear(); + } + + private void setupColumns() + { + if (init) return; + + Columns columns = new Columns(); + + //frozen not working well on tablet devices yet + if (!ClientInfo.isMobile()) + { + Frozen frozen = new Frozen(); + //freeze selection and indicator column + frozen.setColumns(1); + listbox.appendChild(frozen); + } + + org.zkoss.zul.Column selection = new Column(); + ZKUpdateUtil.setWidth(selection, "22px"); + try{ + selection.setSort("none"); + } catch (Exception e) {} + selection.setStyle("border-right: none"); + selectAll = new Checkbox(); + selection.appendChild(selectAll); + selectAll.setId("selectAll"); + selectAll.addEventListener(Events.ON_CHECK, this); + columns.appendChild(selection); + + listbox.appendChild(columns); + columns.setSizable(true); + columns.setMenupopup("none"); + columns.setColumnsgroup(false); + + Map colnames = new HashMap(); + int index = 0; + + for (int i = 0; i < numColumns; i++) + { + // IDEMPIERE-2148: when has tab customize, ignore check properties isDisplayedGrid + if (gridFields[i].isQuickForm()) + { + colnames.put(index, gridFields[i].getHeader()); + index++; + org.zkoss.zul.Column column = new Column(); + int colindex =tableModel.findColumn(gridFields[i].getColumnName()); + column.setSortAscending(new SortComparator(colindex, true, Env.getLanguage(Env.getCtx()))); + column.setSortDescending(new SortComparator(colindex, false, Env.getLanguage(Env.getCtx()))); + column.addEventListener(Events.ON_SORT, this); + //IDEMPIERE-2898 - UX: Field only showing title at header on grid + if( gridFields[i].isFieldOnly() ) + column.setLabel(""); + else { + column.setLabel(gridFields[i].getHeader()); + column.setTooltiptext(gridFields[i].getDescription()); + } + if (columnWidthMap != null && columnWidthMap.get(gridFields[i].getAD_Field_ID()) != null && !columnWidthMap.get(gridFields[i].getAD_Field_ID()).equals("")) { + ZKUpdateUtil.setWidth(column, columnWidthMap.get(gridFields[i].getAD_Field_ID())); + } else { + if (gridFields[i].getDisplayType()==DisplayType.YesNo) { + if (i > 0) { + ZKUpdateUtil.setHflex(column, "min"); + } else { + int estimatedWidth=60; + int headerWidth = (gridFields[i].getHeader().length()+2) * 8; + if (headerWidth > estimatedWidth) + estimatedWidth = headerWidth; + ZKUpdateUtil.setWidth(column, estimatedWidth + "px"); + } + } else if (DisplayType.isNumeric(gridFields[i].getDisplayType()) && "Line".equals(gridFields[i].getColumnName())) { + //special treatment for line + if (i > 0) + ZKUpdateUtil.setHflex(column, "min"); + else + ZKUpdateUtil.setWidth(column, "60px"); + } else { + int estimatedWidth = 0; + if (DisplayType.isNumeric(gridFields[i].getDisplayType())) + estimatedWidth = MIN_NUMERIC_COL_WIDTH; + else if (DisplayType.isLookup(gridFields[i].getDisplayType())) + estimatedWidth = MIN_COMBOBOX_WIDTH; + else if (DisplayType.isText(gridFields[i].getDisplayType())) + estimatedWidth = gridFields[i].getDisplayLength() * 8; + else + estimatedWidth = MIN_COLUMN_WIDTH; + + int headerWidth = (gridFields[i].getHeader().length() + 2) * 8; + if (headerWidth > estimatedWidth) + estimatedWidth = headerWidth; + + //hflex=min for first column not working well + if (i > 0) + { + if (DisplayType.isLookup(gridFields[i].getDisplayType())) + { + if (headerWidth > MIN_COMBOBOX_WIDTH) + ZKUpdateUtil.setHflex(column, "min"); + } + else if (DisplayType.isNumeric(gridFields[i].getDisplayType())) + { + if (headerWidth > MIN_NUMERIC_COL_WIDTH) + ZKUpdateUtil.setHflex(column, "min"); + } + else if (!DisplayType.isText(gridFields[i].getDisplayType())) + { + if (headerWidth > MIN_COLUMN_WIDTH) + ZKUpdateUtil.setHflex(column, "min"); + } + } + + //set estimated width if not using hflex=min + if (!"min".equals(column.getHflex())) { + if (estimatedWidth > MAX_COLUMN_WIDTH) + estimatedWidth = MAX_COLUMN_WIDTH; + else if (estimatedWidth < MIN_COLUMN_WIDTH) + estimatedWidth = MIN_COLUMN_WIDTH; + ZKUpdateUtil.setWidth(column, Integer.toString(estimatedWidth) + "px"); + } + } + } + columns.appendChild(column); + } + } + } + + private void render() + { + updateEmptyMessage(); + + listbox.addEventListener(Events.ON_CLICK, this); + + updateModel(); + + if (pageSize > 0) + { + paging = new Paging(); + paging.setPageSize(pageSize); + paging.setTotalSize(tableModel.getRowCount()); + paging.setDetailed(true); + paging.setId("paging"); + gridFooter.appendChild(paging); + paging.addEventListener(ZulEvents.ON_PAGING, this); + renderer.setPaging(paging); + showPagingControl(); + positionPagingControl(); + } + else + { + hidePagingControl(); + } + } + + private void updateEmptyMessage() { + if (gridTab.getRowCount() == 0) + { + listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "FindZeroRecords"))); + } + else + { + listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Processing"))); + } + } + + private void updateModel() { + if (listModel != null) + ((GridTable)tableModel).removeTableModelListener(listModel); + listModel = new GridTableListModel((GridTable)tableModel, windowNo); + listModel.setPageSize(pageSize); + renderer = new QuickGridTabRowRenderer(gridTab, windowNo); + renderer.setGridPanel(this); + renderer.setADWindowPanel(windowPanel); + if (pageSize > 0 && paging != null) + renderer.setPaging(paging); + + listbox.setModel(listModel); + if (listbox.getRows() == null) + listbox.appendChild(new Rows()); + listbox.setRowRenderer(renderer); + } + + @SuppressWarnings("unchecked") + public void onEvent(Event event) throws Exception + { + if (event == null) + return; + else if (event.getTarget() == listbox && Events.ON_CLICK.equals(event.getName())) + { + Object data = event.getData(); + org.zkoss.zul.Row row = null; + if (data != null && data instanceof Component) + { + if (data instanceof org.zkoss.zul.Row) + row = (org.zkoss.zul.Row) data; + else + { + AbstractComponent cmp = (AbstractComponent) data; + if (cmp.getParent() instanceof org.zkoss.zul.Row) + { + row = (Row) cmp.getParent(); + } + } + } + if (row != null) + { + // click on selected row to enter edit mode + if (row != renderer.getCurrentRow()) + { + int index = listbox.getRows().getChildren().indexOf(row); + if (index >= 0 && !isOnFocusAfterSave) + { + onSelectedRowChange(index); + } + } + } + } + else if (event.getTarget() == paging) + { + isNewLineSaved = true; + int pgNo = paging.getActivePage(); + if (pgNo != listModel.getPage()) + { + listModel.setPage(pgNo); + onSelectedRowChange(0); + gridTab.clearSelection(); + // Clear Map on page change. + renderer.clearMaps(); + Clients.resize(listbox); + Events.postEvent(new Event(EVENT_ON_PAGE_NAVIGATE, this, null)); + } + } + else if (event.getTarget() == selectAll) + { + toggleSelectionForAll(selectAll.isChecked()); + } + else if (event.getName().equals(EVENT_ON_SELECT_ROW)) + { + Checkbox checkbox = (Checkbox) event.getData(); + int rowIndex = (Integer) checkbox.getAttribute(GridTabRowRenderer.GRID_ROW_INDEX_ATTR); + if ((gridTab.getRowCount() - 1) == rowIndex && !isNewLineSaved) + { + checkbox.setChecked(false); + return; + } + if (checkbox.isChecked()) + { + gridTab.addToSelection(rowIndex); + if (!selectAll.isChecked() && isAllSelected()) + { + selectAll.setChecked(true); + } + } + else + { + gridTab.removeFromSelection(rowIndex); + if (selectAll.isChecked()) + selectAll.setChecked(false); + } + onSelectedRowChange(rowIndex % paging.getPageSize()); + isNewLineSaved = true; + } + else if (event.getName().equals(EVENT_ON_CUSTOMIZE_GRID)) + { + reInit(); + } + else if (event.getName().equals(Events.ON_CTRL_KEY) || event.getName().equals(EVENT_ON_AFTER_SAVE)) + { + KeyEvent keyEvent; + ArrayList dataEvent = null; + + if (event.getName().equals(EVENT_ON_AFTER_SAVE)) + { + dataEvent = (ArrayList) event.getData(); + keyEvent = (KeyEvent) dataEvent.get(0); + } + else + keyEvent = (KeyEvent) event; + + int code = keyEvent.getKeyCode(); + boolean isAlt = keyEvent.isAltKey(); + boolean isCtrl = keyEvent.isCtrlKey(); + boolean isShift = keyEvent.isShiftKey(); + + int row = renderer.getCurrentRowIndex() % paging.getPageSize(); + int col = 0; + if (renderer.getCurrentCell() != null) + col = renderer.getCurrentRow().getChildren().indexOf(renderer.getCurrentCell()); + int totalRow = gridTab.getRowCount(); + + if (event.getName().equals(EVENT_ON_AFTER_SAVE) && col == -1) + col = (int) dataEvent.get(1); + + // Not focus on specific component through mouse + if (col == -1 && (code == KeyEvent.LEFT || code == KeyEvent.RIGHT)) + col = (code == KeyEvent.LEFT ? 3 : 0); + + // Navigate in item selection popup then no action + if ((code == KeyEvent.DOWN || code == KeyEvent.UP) && renderer.getCurrentCell() != null + && renderer.getCurrentCell().getChildren().get(0) instanceof Combobox) + { + return; + } + + if (code == KEYBOARD_KEY_ENTER && !isCtrl && !isAlt && !isShift) + { + // If Search text is empty on ENTER key event then as default behavior to open Search Dialog otherwise move to down. + Cell cell = renderer.getCurrentCell(); + if (cell != null && cell.getChildren().get(0) instanceof Searchbox + && !((Searchbox) cell.getChildren().get(0)).getText().isEmpty() + && (Boolean) ((Searchbox) cell.getChildren().get(0)).getAttribute(WSearchEditor.ATTRIBUTE_IS_INFO_PANEL_OPEN)) + { + event.stopPropagation(); + return; + } + code = KeyEvent.DOWN; + } + + + int currentRow = row % paging.getPageSize() + (paging.getActivePage() * paging.getPageSize()); + if (code == KeyEvent.DOWN || code == KeyEvent.UP || code == KeyEvent.HOME || code == KeyEvent.END) + { + int rowChangedIndex = gridTab.getTableModel().getRowChanged(); + // update index of pagination if multiple records created + // (e.g select multiple products) + if (paging.getTotalSize() != gridTab.getRowCount()) + { + updateListIndex(); + isNewLineSaved = true; + } + if (rowChangedIndex == currentRow) + { + if (!save(code, row, col)) + { + event.stopPropagation(); + return; + } + else + { + // If a row is removed after filtering, update the rowIndex. + if (totalRow != gridTab.getRowCount()) + { + if (code == KeyEvent.DOWN) + { + row -= 1; + totalRow = gridTab.getRowCount(); + gridTab.setCurrentRow((row >= 0 ? row % paging.getPageSize() : 0) + + paging.getActivePage() * paging.getPageSize()); + renderer.currentRowIndex = gridTab.getCurrentRow(); + } + } + // fire event for stopping duplicate row data + ArrayList eData = new ArrayList(); + eData.add(keyEvent); + eData.add(col); + + Events.echoEvent(EVENT_ON_AFTER_SAVE, this, eData); + return; + } + } + } + if (code == KeyEvent.DOWN && !isCtrl && !isAlt && !isShift) + { + row += 1; + currentRow = row % paging.getPageSize() + (paging.getActivePage() * paging.getPageSize()); + if (((currentRow == totalRow) + || (row % paging.getPageSize() == 0 && paging.getActivePage() == (paging.getPageCount() - 1))) + && isNewLineSaved) + { + createNewLine(); + updateListIndex(); + toggleSelectionForAll(false); + if (!(row % paging.getPageSize() == 0)) + { + Events.echoEvent(EVENT_ON_SET_FOCUS_TO_FIRST_CELL, this, null); + event.stopPropagation(); + } + } + // stop from creating new record if new record blank or not save + else if (((currentRow == totalRow) + || (row % paging.getPageSize() == 0 && paging.getActivePage() == (paging.getPageCount() - 1)))) + { + event.stopPropagation(); + return; + } + + if (row % paging.getPageSize() == 0) + { + // Clear Map on page change. + renderer.clearMaps(); + updateListIndex(); + paging.setActivePage( + paging.getActivePage() + (paging.getActivePage() == (paging.getPageCount() - 1) ? 0 : 1)); + listModel.setPage(paging.getActivePage()); + updateModelIndex(0); + // on page change set focus to first editable cell of row + Events.echoEvent(EVENT_ON_SET_FOCUS_TO_FIRST_CELL, this, null); + row = 0; + } + } + else if (code == KeyEvent.LEFT && !isCtrl && !isAlt && !isShift) + { + col -= 1; + } + else if (code == KeyEvent.RIGHT && !isCtrl && !isAlt && !isShift) + { + col += 1; + } + else if (code == KeyEvent.UP && !isCtrl && !isAlt && !isShift) + { + // remove new record if blank + currentRow = gridTab.getCurrentRow(); + // Ignore all blank record except first blank record. + if (totalRow > 1 && (totalRow - 1) == currentRow && !isNewLineSaved) + { + gridTab.dataIgnore(); + if (gridTab.getRowCount() <= 0) + createNewLine(); + gridTab.setCurrentRow(currentRow); + } + + row -= 1; + if (paging.getActivePage() > 0 && (row + 1) % paging.getPageSize() == 0) + { + // Clear Map on page change. + renderer.clearMaps(); + paging.setActivePage(paging.getActivePage() - 1); + listModel.setPage(paging.getActivePage()); + updateModelIndex(paging.getPageSize() - 1); + // on page change set focus to first editable cell of row + Events.echoEvent(EVENT_ON_SET_FOCUS_TO_FIRST_CELL, this, null); + return; + } + + // check is new record is ignore + // update page index after remove new record + if (currentRow != gridTab.getCurrentRow() && !isNewLineSaved) + { + updateListIndex(); + isNewLineSaved = true; + } + + if (row < 0) + { + row = 0; + } + } + else if (code == KeyEvent.HOME) + { + row = 0; + } + else if (!isCtrl && isAlt && !isShift) + { + if (code == KEYBOARD_KEY_K) + { + quickForm.onSave(); + quickForm.dispose(); + } + else if (code == KEYBOARD_KEY_S) + { + quickForm.onSave(); + } + else if (code == KEYBOARD_KEY_D) + { + quickForm.onDelete(); + } + else if (code == KEYBOARD_KEY_Z) + { + quickForm.onIgnore(); + } + else if (code == KEYBOARD_KEY_E) + { + quickForm.onRefresh(); + } + else if (code == KEYBOARD_KEY_X) + { + quickForm.onCancel(); + } + else if (code == KEYBOARD_KEY_L) + { + quickForm.onCustomize(); + } + else if (code == KEYBOARD_KEY_R) + { + quickForm.onUnSort(); + } + + event.stopPropagation(); + return; + } + else + { + renderer.setCurrentCell(row, col, code); + event.stopPropagation(); + return; + } + + if (row < 0 || row >= gridTab.getTableModel().getRowCount() || col < 0 + || col >= gridTab.getTableModel().getColumnCount()) + { + renderer.setFocusOnCurrentCell(); + event.stopPropagation(); + return; + } + + Component source = listbox.getCell(row, col); + if (source == null) + { + listbox.renderAll(); + source = listbox.getCell(row, col); + } + + while (source != null && !(source.getClass() == Cell.class)) + { + source = source.getParent(); + } + renderer.setCurrentCell(row, col, code); + } + else if (event.getName().equals(Events.ON_FOCUS) || event.getName().equals(EVENT_ONFOCUS_AFTER_SAVE)) + { + isOnFocusAfterSave = event.getName().equals(EVENT_ONFOCUS_AFTER_SAVE); + Component eventComponent; + if (isOnFocusAfterSave) + eventComponent = (Component) event.getData(); + else + eventComponent = event.getTarget(); + + // update index of pagination if multiple records created if user use mouse to select record + // (e.g select multiple products) + if (paging.getTotalSize() != gridTab.getRowCount()) + { + updateListIndex(); + } + int totalRow = gridTab.getRowCount(); + int currentRow = gridTab.getCurrentRow(); + if ((totalRow - 1) != currentRow && !isNewLineSaved) + { + updateListIndex(); + isNewLineSaved = true; + gridTab.dataIgnore(); + gridTab.setCurrentRow(currentRow); + } + if (!isOnFocusAfterSave) + { + // Prevent to fire event again on same component + if (eventComponent == preEventComponent) + return; + + preEventComponent = eventComponent; + } + + Component source = event.getTarget(); + if (isOnFocusAfterSave) + source = (Component) event.getData(); + + while (source != null && !(source.getClass() == Cell.class)) + { + source = source.getParent(); + } + if (renderer.getCurrentCell() != null && !renderer.getCurrentCell().equals(source)) + { + int row = renderer.getCurrentRowIndex(); + int col = renderer.getCurrentRow().getChildren().indexOf(renderer.getCurrentCell()); + int focusedRowIndex = getFocusedRowIndex(source); + + if (focusedRowIndex != row % pageSize) + { + // remove all pop-up dialog list box + String script = "$('.z-combobox-open').remove()"; + Clients.response(new AuScript(script)); + + int rowChangedIndex = gridTab.getTableModel().getRowChanged(); + if (rowChangedIndex == row) + { + if (save(KeyEvent.RIGHT, row, col)) + { + isOnFocusAfterSave = true; + Events.echoEvent(EVENT_ONFOCUS_AFTER_SAVE, this, event.getTarget()); + } + else + { + event.stopPropagation(); + } + return; + } + } + + setFocusOnDiv(source); + } + } + else if (event.getName().equals(EVENT_ON_PAGE_NAVIGATE)) + { + renderer.setCurrentCell(null); + renderer.setCurrentCell(0, 1, NAVIGATE_CODE); + renderer.getCurrentRow().setStyle(QuickGridTabRowRenderer.CURRENT_ROW_STYLE); + } + else if (event.getName().equals(EVENT_ON_CLICK_TO_NAVIGATE)) + { + int row = renderer.getCurrentRowIndex(); + int col = (int) event.getData(); + + renderer.setCurrentCell(row, col, NAVIGATE_CODE); + + Row currntRow = renderer.getCurrentRow(); + currntRow.setStyle(QuickGridTabRowRenderer.CURRENT_ROW_STYLE); + } + else if (event.getName().equals(EVENT_ON_SET_FOCUS_TO_FIRST_CELL)) + { + int row = renderer.getCurrentRowIndex() % paging.getPageSize(); + row = row < 0 ? 0 : row; + + renderer.setCurrentCell(row, 1, NAVIGATE_CODE); + + // on sort current index remain same but rows get sorted so set current index row as current row. + // remove property change listener to new current row + renderer.addRemovePropertyChangeListener(false, 1); + // set focus to row. + renderer.setRowTo(row); + // Add property change listener to new current row + renderer.addRemovePropertyChangeListener(true, 1); + } + else if (Events.ON_SORT.equals(event.getName())) + { + int row = renderer.getCurrentRowIndex(); + int col = renderer.getCurrentRow().getChildren().indexOf(renderer.getCurrentCell()); + int rowChangedIndex = gridTab.getTableModel().getRowChanged(); + if (rowChangedIndex == row) + { + if (!save(KeyEvent.RIGHT, row, col)) + { + event.stopPropagation(); + return; + } + } + else if (gridTab.getRowCount() <= 1 && !isNewLineSaved) + { + event.stopPropagation(); + setStatusLine("NO record to Sort", false); + return; + } + renderer.clearMaps(); + Events.echoEvent(EVENT_ON_PAGE_NAVIGATE, this, null); + return; + } + event.stopPropagation(); + } + + private void setFocusOnDiv(Component source) { + int rowCount = gridTab.getTableModel().getRowCount(); + int colCount = renderer.getCurrentRow().getChildren().size(); + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < colCount; j++) { + if (listbox.getCell(i, j) != null && listbox.getCell(i, j).equals(source)) { + renderer.setCurrentCell(i, j, FOCUS_CODE); + return; + } + } + } + } + + public boolean isAllSelected() { + org.zkoss.zul.Rows rows = listbox.getRows(); + List childs = rows.getChildren(); + boolean all = false; + for (Component comp : childs) { + org.zkoss.zul.Row row = (org.zkoss.zul.Row) comp; + Component firstChild = row.getFirstChild(); + if (firstChild instanceof Cell) { + firstChild = firstChild.getFirstChild(); + } + if (firstChild instanceof Checkbox) { + Checkbox checkbox = (Checkbox) firstChild; + if (!checkbox.isChecked()) + return false; + else + all = true; + } + } + return all; + } + + public void toggleSelectionForAll(boolean b) { + org.zkoss.zul.Rows rows = listbox.getRows(); + List childs = rows.getChildren(); + for (Component comp : childs) { + org.zkoss.zul.Row row = (org.zkoss.zul.Row) comp; + Component firstChild = row.getFirstChild(); + if (firstChild instanceof Cell) { + firstChild = firstChild.getFirstChild(); + } + if (firstChild instanceof Checkbox) { + Checkbox checkbox = (Checkbox) firstChild; + checkbox.setChecked(b); + int rowIndex = (Integer) checkbox.getAttribute(GridTabRowRenderer.GRID_ROW_INDEX_ATTR); + if ((gridTab.getRowCount() - 1) == rowIndex && !isNewLineSaved) + { + checkbox.setChecked(false); + continue; + } + if (b) + gridTab.addToSelection(rowIndex); + else + gridTab.removeFromSelection(rowIndex); + } + } + } + + private void onSelectedRowChange(int index) { + if (updateModelIndex(index)) { + updateListIndex(); + } + } + + /** + * Event after the current selected row change + */ + private boolean save(int code, int row, int col) + { + boolean isSave = dataSave(code); + if (isSave) + { + listModel.updateComponent(row % pageSize); + } + else + { + renderer.setCurrentCell(row, col, code); + } + return isSave; + } + + public void onPostSelectedRowChanged() { + removeAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED); + if (listbox.getRows() == null || listbox.getRows().getChildren().isEmpty()) + return; + + int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1; + if (rowIndex >= 0 && pageSize > 0) { + int pgIndex = rowIndex >= 0 ? rowIndex % pageSize : 0; + org.zkoss.zul.Row row = (org.zkoss.zul.Row) listbox.getRows().getChildren().get(pgIndex); + if (!isRowRendered(row, pgIndex)) { + listbox.renderRow(row); + } else { + renderer.setCurrentRow(row); + renderer.setCurrentCell(rowIndex, 1, NAVIGATE_CODE); + } + } else if (rowIndex >= 0) { + org.zkoss.zul.Row row = (org.zkoss.zul.Row) listbox.getRows().getChildren().get(rowIndex); + if (!isRowRendered(row, rowIndex)) { + listbox.renderRow(row); + } else { + renderer.setCurrentRow(row); + renderer.setCurrentCell(rowIndex, 1, NAVIGATE_CODE); + } + } + } + + /** + * scroll grid to the current focus row + */ + public void scrollToCurrentRow() { + onPostSelectedRowChanged(); + } + + private boolean isRowRendered(org.zkoss.zul.Row row, int index) { + if (row.getChildren().size() == 0) { + return false; + } else if (row.getChildren().size() == 1) { + if (!(row.getChildren().get(0) instanceof Cell)) { + return false; + } + } + return true; + } + + public boolean updateModelIndex(int rowIndex) { + if (pageSize > 0) { + int start = listModel.getPage() * listModel.getPageSize(); + rowIndex = start + rowIndex; + } + + if (gridTab.getCurrentRow() != rowIndex) { + gridTab.navigate(rowIndex); + return true; + } + return false; + } + + /** + * @return Grid + */ + public Grid getListbox() { + return listbox; + } + + /** + * Validate display properties of fields of current row + * @param col + */ + public void dynamicDisplay(int col) { + if (gridTab == null || !gridTab.isOpen()) + { + return; + } + + // Selective + if (col > 0) + { + GridField changedField = gridTab.getField(col); + String columnName = changedField.getColumnName(); + ArrayList dependants = gridTab.getDependantFields(columnName); + if ( ! ( dependants.size() > 0 + || changedField.getCallout().length() > 0 + || Core.findCallout(gridTab.getTableName(), columnName).size() > 0)) { + return; + } + } + + boolean noData = gridTab.getRowCount() == 0; + // Get editors list of Current Row + List list = renderer.editorsListMap.get(renderer.getCurrentRow()); + if (list != null) + dynamicDisplayEditors(noData, list); // all components + + if (gridTab.getRowCount() == 0 && selectAll.isChecked()) + selectAll.setChecked(false); + } + + /** + * Change display properties of current row + * + * @param noData + * @param list + */ + private void dynamicDisplayEditors(boolean noData, List list) { + // Get read-only editors list of Current Row + ArrayList readOnlyEditorsList = renderer.readOnlyEditorsListMap.get(renderer.getCurrentRow()); + for (WEditor comp : list) + { + GridField mField = comp.getGridField(); + if (mField != null) + { + if (noData) + { + comp.setReadWrite(false); + } + else + { + // Enable read-only Component to get proper value of read & + // write logic. + if (readOnlyEditorsList != null && readOnlyEditorsList.contains(comp)) + { + renderer.isDisableReadonlyComponent(comp.getComponent(), false); + readOnlyEditorsList.remove(comp); + } + // r/w - check Context + boolean rw = mField.isEditable(true); + // IDEMPIERE-3421 - if it was read-only the list can contain + // direct values + if (rw && !comp.isReadWrite()) + mField.refreshLookup(); + comp.setReadWrite(rw); + comp.setMandatory(mField.isMandatory(true)); + comp.dynamicDisplay(); + // Disable read-only Component for while pressing tab button + // focus goes to read-only component. + if (readOnlyEditorsList != null && renderer.isDisableReadonlyComponent(comp.getComponent(), true)) + { + readOnlyEditorsList.add(comp); + } + } + comp.setVisible((isHasCustomizeData || mField.isDisplayedGrid()) + && mField.isDisplayed(mField.getVO().ctx, true)); + } + } + renderer.readOnlyEditorsListMap.put(renderer.getCurrentRow(), readOnlyEditorsList); + } + + /** + * + * @param windowNo + */ + public void setWindowNo(int windowNo) { + this.windowNo = windowNo; + } + + /** + * @param winPanel + */ + public void setADWindowPanel(AbstractADWindowContent winPanel) { + windowPanel = winPanel; + if (renderer != null) + renderer.setADWindowPanel(windowPanel); + } + + public void reInit() { + listbox.getChildren().clear(); + listbox.detach(); + + if (paging != null) { + paging.detach(); + paging = null; + } + + renderer = null; + init = false; + + Grid tmp = listbox; + createListbox(); + tmp.copyEventListeners(listbox); + insertBefore(listbox, gridFooter); + + refresh(gridTab); + scrollToCurrentRow(); + Clients.resize(listbox); + } + + /** + * list field display in grid mode, in case user customize grid + * this list container only customize list. + */ + public GridField[] getFields() { + return gridFields; + } + + @Override + public void focusToFirstEditor() { + } + + @Override + public void focusToNextEditor(WEditor ref) { + } + + @Override + public void stateChange(StateChangeEvent event) { + switch(event.getEventType()) { + case StateChangeEvent.DATA_NEW: + case StateChangeEvent.DATA_QUERY: + case StateChangeEvent.DATA_REFRESH_ALL: + if (selectAll.isChecked()) + selectAll.setChecked(false); + break; + case StateChangeEvent.DATA_DELETE: + case StateChangeEvent.DATA_IGNORE: + if (!selectAll.isChecked() && isAllSelected()) + selectAll.setChecked(true); + break; + } + } + + protected void onADTabPanelParentChanged() { + positionPagingControl(); + } + + private void positionPagingControl() + { + if (gridFooter.getParent() != this) + { + ZKUpdateUtil.setHflex(gridFooter, "1"); + gridFooter.setSclass("adtab-grid-south"); + appendChild(gridFooter); + } + if (paging != null) + paging.setDetailed(true); + } + + public void setStatusLine(String text, boolean error) + { + windowPanel.getStatusBarQF().setStatusLine(text, error); + } + + public void createNewLine() { + isNewLineSaved = false; + gridTab.dataNew(false); + } + + /** + * @param code + */ + public boolean dataSave(int code) { + boolean isSave = false; + //save only if new record modify + isSave = gridTab.dataSave(false); + if (isSave) { + isNewLineSaved = true; + } + + int row = renderer.getCurrentRowIndex(); + int col = renderer.getCurrentRow().getChildren().indexOf(renderer.getCurrentCell()); + if (code != KeyEvent.DOWN && code != KeyEvent.UP) { + renderer.setCurrentCell(row, col, code); + } + return isSave; + } + + @Override + public void onPageAttached(Page newpage, Page oldpage) + { + super.onPageAttached(newpage, oldpage); + + if (newpage != null) + { + keyListener = SessionManager.getSessionApplication().getKeylistener(); + keyListener.setCtrlKeys(keyListener.getCtrlKeys() + CNTRL_KEYS); + keyListener.addEventListener(Events.ON_CTRL_KEY, this); + } + } + + @Override + public void onPageDetached(Page page) + { + super.onPageDetached(page); + keyListener.setCtrlKeys(keyListener.getCtrlKeys().replaceAll(CNTRL_KEYS, "")); + keyListener.removeEventListener(Events.ON_CTRL_KEY, this); + } + + @Override + public void editorTraverse(Callback editorTaverseCallback) { + + } + + private int getFocusedRowIndex(Component source) + { + int rowCount = gridTab.getTableModel().getRowCount(); + int colCount = renderer.getCurrentRow().getChildren().size(); + for (int i = 0; i < rowCount; i++) + { + for (int j = 0; j < colCount; j++) + { + if (listbox.getCell(i, j) != null && listbox.getCell(i, j).equals(source)) + return i; + } + } + return 0; + } // getFocusedRowIndex + + public Column findCurrentSortColumn() + { + if (listbox.getColumns() != null) + { + List list = listbox.getColumns().getChildren(); + for (int i = 0; i < list.size(); i++) + { + Component comp = (Component) list.get(i); + if (comp instanceof Column) + { + Column column = (Column) comp; + if (!column.getSortDirection().equals("natural")) + return column; + } + } + } + return null; + } // findCurrentSortColumn + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/StatusBar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/StatusBar.java index 04219148de..dfbb41559f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/StatusBar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/StatusBar.java @@ -18,6 +18,7 @@ package org.adempiere.webui.adwindow; import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.apps.form.WQuickForm; import org.adempiere.webui.component.DocumentLink; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Panel; @@ -243,7 +244,9 @@ public class StatusBar extends Panel implements EventListener while (parent != null) { if (parent instanceof Tabpanel) return parent; - + else if (parent instanceof WQuickForm) + return parent; + parent = parent.getParent(); } return null; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WQuickForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WQuickForm.java new file mode 100644 index 0000000000..4d739c4a71 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WQuickForm.java @@ -0,0 +1,445 @@ +/****************************************************************************** + * Copyright (C) 2016 Logilite Technologies LLP * + * 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.form; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.adempiere.util.Callback; +import org.adempiere.webui.adwindow.AbstractADWindowContent; +import org.adempiere.webui.adwindow.QuickGridView; +import org.adempiere.webui.component.Borderlayout; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Panel; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.component.ZkCssHelper; +import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.adempiere.webui.window.CustomizeGridViewDialog; +import org.adempiere.webui.window.FDialog; +import org.compiere.model.DataStatusEvent; +import org.compiere.model.DataStatusListener; +import org.compiere.model.GridField; +import org.compiere.model.GridTab; +import org.compiere.model.MRole; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.zkforge.keylistener.Keylistener; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.Column; +import org.zkoss.zul.Columns; + +/** + * Quick entry form + * + * @author Logilite Technologies + * @since Nov 03, 2017 + */ +public class WQuickForm extends Window implements EventListener , DataStatusListener +{ + + /** + * + */ + private static final long serialVersionUID = -5095168843989540551L; + + public Trx trx = null; + + private Borderlayout mainLayout = new Borderlayout(); + private AbstractADWindowContent adWinContent = null; + private QuickGridView quickGridView = null; + private GridTab gridTab; + + private ConfirmPanel confirmPanel = new ConfirmPanel(true, true, false, false, false, false); + + private Button bDelete = confirmPanel.createButton(ConfirmPanel.A_DELETE); + private Button bSave = confirmPanel.createButton("Save"); + private Button bIgnore = confirmPanel.createButton("Ignore"); + private Button bCustomize = confirmPanel.createButton("Customize"); + private Button bUnSort = confirmPanel.createButton("UnSort"); + + private boolean onlyCurrentRows = false; + + private int onlyCurrentDays = 0; + + QuickGridView prevQGV = null; + + private int windowNo; + + public WQuickForm(AbstractADWindowContent winContent, boolean m_onlyCurrentRows, int m_onlyCurrentDays) + { + super(); + + this.setMode(Mode.POPUP); + windowNo = SessionManager.getAppDesktop().registerWindow(this); + adWinContent = winContent; + onlyCurrentRows = m_onlyCurrentRows; + onlyCurrentDays = m_onlyCurrentDays; + this.gridTab = adWinContent.getADTab().getSelectedGridTab(); + this.quickGridView = new QuickGridView(adWinContent, gridTab, this); + this.quickGridView.setVisible(true); + initForm(); + gridTab.isQuickForm = true; + + gridTab.addDataStatusListener(this); + + // To maintain parent-child Quick Form + prevQGV = adWinContent.getCurrQGV(); + adWinContent.setCurrQGV(quickGridView); + } + + protected void initForm( ) + { + initZk(); + createNewRow(); + quickGridView.refresh(gridTab); + } + + private void initZk( ) + { + // Center + Panel Center = new Panel(); + Center.appendChild(quickGridView); + ZkCssHelper.appendStyle(Center, "border: none; width: 100%; height:99%; background: gainsboro;"); + + // South + Panel south = new Panel(); + + // Adding statusBar for Quick Form + south.appendChild(adWinContent.getStatusBarQF()); + ZkCssHelper.appendStyle(adWinContent.getStatusBarQF(), "height: 20px; padding-bottom: 3px background: white"); + south.appendChild(confirmPanel); + ZkCssHelper.appendStyle(confirmPanel, "height: 50px; padding-top: 9px; background: #9c9c9c;"); + + bSave.setEnabled(!gridTab.isReadOnly()); + bDelete.setEnabled(!gridTab.isReadOnly()); + bIgnore.setEnabled(!gridTab.isReadOnly()); + bUnSort.setEnabled(!gridTab.isReadOnly()); + + bSave.addEventListener(Events.ON_CLICK, this); + bDelete.addEventListener(Events.ON_CLICK, this); + bIgnore.addEventListener(Events.ON_CLICK, this); + bCustomize.addEventListener(Events.ON_CLICK, this); + bUnSort.addEventListener(Events.ON_CLICK, this); + + // Add Shortcut Key info in tool-tip + bSave.setTooltiptext(bSave.getTooltiptext() + " (Alt+S) Save current record if modified"); + bIgnore.setTooltiptext(bIgnore.getTooltiptext() + " (Alt+Z) Ignore un-save changes of current record"); + bDelete.setTooltiptext(bDelete.getTooltiptext() + " (Alt+D) Delete selected or current record"); + bCustomize.setTooltiptext(bCustomize.getTooltiptext() + " (Alt+L) Customize panel as per user"); + + Button bRefresh = confirmPanel.getButton(ConfirmPanel.A_REFRESH); + bRefresh.setTooltiptext(bRefresh.getTooltiptext() + " (Alt+E) ReQuery all record"); + + Button bCancle = confirmPanel.getButton(ConfirmPanel.A_CANCEL); + bCancle.setTooltiptext(bCancle.getTooltiptext() + " (Alt+X) Close quick form"); + + Button bok = confirmPanel.getButton(ConfirmPanel.A_OK); + bok.setTooltiptext(bok.getTooltiptext() + " (Alt+K) Save and Close quick form"); + + Button bunSort = confirmPanel.getButton("UnSort"); + bunSort.setTooltiptext(bunSort.getTooltiptext() + " (Alt + R) Restore sorting to natural if column sorted"); + + confirmPanel.addComponentsLeft(bSave); + confirmPanel.addComponentsLeft(bDelete); + confirmPanel.addComponentsLeft(bIgnore); + confirmPanel.addComponentsLeft(bCustomize); + confirmPanel.addComponentsLeft(bUnSort); + confirmPanel.addActionListener(this); + + mainLayout.appendCenter(Center); + mainLayout.appendSouth(south); + + this.appendChild(mainLayout); + } // initZk + + @Override + public void onEvent(Event event) throws Exception + { + if (event.getTarget() == confirmPanel.getButton(ConfirmPanel.A_CANCEL)) + { + onCancel(); + } + else if (event.getTarget() == confirmPanel.getButton(ConfirmPanel.A_REFRESH)) + { + quickGridView.getRenderer().setCurrentCell(null); + onRefresh(); + } + if (event.getTarget() == confirmPanel.getButton(ConfirmPanel.A_OK)) + { + onSave(); + dispose(); + } + else if (event.getTarget() == confirmPanel.getButton("Save")) + { + quickGridView.getRenderer().setCurrentCell(null); + onSave(); + } + else if (event.getTarget() == confirmPanel.getButton(ConfirmPanel.A_DELETE)) + { + quickGridView.getRenderer().setCurrentCell(null); + onDelete(); + } + else if (event.getTarget() == confirmPanel.getButton("Ignore")) + { + quickGridView.getRenderer().setCurrentCell(null); + onIgnore(); + } + else if (event.getTarget() == confirmPanel.getButton("Customize")) + { + onCustomize(); + } + else if (event.getTarget() == confirmPanel.getButton("UnSort")) + { + onUnSort(); + } + event.stopPropagation(); + } // onEvent + + public void onCancel( ) + { + if (gridTab.getTableModel().getRowChanged() > -1) + { + FDialog.ask(windowNo, this, "SaveChanges?", new Callback () { + + @Override + public void onCallback(Boolean result) + { + if (result) + onSave(); + dispose(); + } + }); + } + else + { + dispose(); + } + } // onCancel + + public void onUnSort( ) + { + adWinContent.getActiveGridTab().getTableModel().resetCacheSortState(); + Column sortColumn = quickGridView.findCurrentSortColumn(); + + onRefresh(); + + if (sortColumn != null) + sortColumn.setSortDirection("natural"); + + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "UnSort"), false); + } // onUnSort + + public void onCustomize( ) + { + onSave(); + // + Columns columns = quickGridView.getListbox().getColumns(); + List columnList = columns.getChildren(); + GridField[] fields = quickGridView.getGridField(); + Map columnsWidth = new HashMap (); + ArrayList gridFieldIds = new ArrayList (); + + for (int i = 0; i < fields.length; i++) + { + Column column = (Column) columnList.get(i + 1); + String width = column.getWidth(); + columnsWidth.put(fields[i].getAD_Field_ID(), width); + gridFieldIds.add(fields[i].getAD_Field_ID()); + } + + ZKUpdateUtil.setWidth(quickGridView, getWidth()); + ZKUpdateUtil.setHeight(quickGridView, getHeight()); + + CustomizeGridViewDialog.showCustomize(0, gridTab.getAD_Tab_ID(), columnsWidth, gridFieldIds, null, quickGridView, true); + } // onCustomize + + public void onIgnore( ) + { + gridTab.dataIgnore(); + gridTab.dataRefreshAll(); + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "Ignored"), false); + quickGridView.isNewLineSaved = true; + // Create new record if no record present. + if (gridTab.getRowCount() <= 0) + createNewRow(); + quickGridView.updateListIndex(); + Events.echoEvent(QuickGridView.EVENT_ON_SET_FOCUS_TO_FIRST_CELL, quickGridView, null); + } // onIgnore + + public void onDelete( ) + { + if (gridTab == null || !quickGridView.isNewLineSaved) + return; + + // if no any row selected then delete current record + if (gridTab.getSelection().length == 0) + gridTab.addToSelection(quickGridView.getRenderer().getCurrentRowIndex()); + + final int[] indices = gridTab.getSelection(); + if (indices.length > 0) + { + FDialog.ask(windowNo, this, "DeleteRecord?", new Callback () { + + @Override + public void onCallback(Boolean result) + { + if (result) + { + boolean isAllSelected = quickGridView.isAllSelected(); + quickGridView.isNewLineSaved = true; + gridTab.clearSelection(); + quickGridView.toggleSelectionForAll(false); + Arrays.sort(indices); + int count = 0; + for (int i = 0, offset = 0; i < indices.length; i++) + { + gridTab.navigate(indices[i] - offset); + if (gridTab.dataDelete()) + { + offset++; + count++; + } + else + { + break; + } + } + + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "Deleted") + ": " + count + " / " + indices.length, false); + + // if all records is deleted then it will show default with new record. + if (gridTab.getRowCount() <= 0) + quickGridView.createNewLine(); + quickGridView.updateListIndex(); + + // Set focus on the first row if all Row's are selected. + if (isAllSelected) + Events.echoEvent(QuickGridView.EVENT_ON_PAGE_NAVIGATE, quickGridView, null); + else + Events.echoEvent(QuickGridView.EVENT_ON_SET_FOCUS_TO_FIRST_CELL, quickGridView, null); + } + else + { + gridTab.clearSelection(); + quickGridView.toggleSelectionForAll(false); + } + } + }); + } + } // onDelete + + public void onSave( ) + { + if (gridTab.getTableModel().getRowChanged() == gridTab.getCurrentRow()) + { + if (quickGridView.dataSave(0)) + { + gridTab.dataRefreshAll(); + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "Saved"), false); + Events.echoEvent(QuickGridView.EVENT_ON_SET_FOCUS_TO_FIRST_CELL, quickGridView, null); + } + } + else + { + onIgnore(); + } + } // onSave + + public void onRefresh( ) + { + gridTab.dataRefreshAll(); + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "Refresh"), false); + quickGridView.isNewLineSaved = true; + quickGridView.updateListIndex(); + Events.echoEvent(QuickGridView.EVENT_ON_SET_FOCUS_TO_FIRST_CELL, quickGridView, null); + // Create new record if no record present. + if (gridTab.getRowCount() <= 0) + createNewRow(); + } // onRefresh + + @Override + public void dispose( ) + { + super.dispose(); + + gridTab.setQuickForm(false); + onIgnore(); + gridTab.removeDataStatusListener(this); + SessionManager.closeQuickFormTab(gridTab.getAD_Tab_ID()); + quickGridView.getRenderer().clearMaps(); + int tabLevel = adWinContent.getToolbar().getQuickFormTabHrchyLevel(); + if (tabLevel > 0) + { + adWinContent.getToolbar().setQuickFormTabHrchyLevel(tabLevel - 1); + Keylistener keyListener = SessionManager.getSessionApplication().getKeylistener(); + keyListener.setCtrlKeys(keyListener.getCtrlKeys() + QuickGridView.CNTRL_KEYS); + + // Add Key-listener of parent Quick Form + if (prevQGV != null) + { + adWinContent.onParentRecord(); + SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, prevQGV); + // TODO need to set focus on last focused row of parent Form. + Events.echoEvent(QuickGridView.EVENT_ON_PAGE_NAVIGATE, prevQGV, null); + } + adWinContent.setCurrQGV(prevQGV); + } + else + { + adWinContent.setCurrQGV(null); + } + adWinContent.getADTab().getSelectedTabpanel().query(onlyCurrentRows, onlyCurrentDays, MRole.getDefault().getMaxQueryRecords()); // autoSize + } // dispose + + private void createNewRow( ) + { + int row = gridTab.getRowCount(); + // creating the first record from the parent tab first record is duplicated on KEY DOWN. + // If a grid does not have a record or blank record then create a new row. + if (row <= 0 || (gridTab.isNew() && row == 1)) + { + gridTab.dataIgnore(); + if (gridTab.isInsertRecord()) + { + quickGridView.createNewLine(); + } + else + { + adWinContent.getStatusBarQF().setStatusLine(Msg.getMsg(Env.getCtx(), "NewError"), true); + } + } + } // createNewRow + + @Override + public void dataStatusChanged(DataStatusEvent e) + { + // ignore background event + if (Executions.getCurrent() == null || e.isInitEdit()) + return; + + // update Dynamic display on data Status change. + int col = e.getChangedColumn(); + quickGridView.dynamicDisplay(col); + } // dataStatusChanged +} \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java index ff6b9d087b..c000a36dae 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java @@ -29,6 +29,7 @@ import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.ValuePreference; import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.adwindow.ADWindowContent; +import org.adempiere.webui.adwindow.QuickGridTabRowRenderer; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Searchbox; import org.adempiere.webui.event.ContextMenuEvent; @@ -73,6 +74,7 @@ import org.zkoss.zk.ui.util.Clients; public class WSearchEditor extends WEditor implements ContextMenuListener, ValueChangeListener, IZoomableEditor { private static final String[] LISTENER_EVENTS = {Events.ON_CLICK, Events.ON_CHANGE, Events.ON_OK}; + public static final String ATTRIBUTE_IS_INFO_PANEL_OPEN = "ATTRIBUTE_IS_INFO_PANEL_OPEN"; private Lookup lookup; private String m_tableName = null; private String m_keyColumnName = null; @@ -97,6 +99,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value columnName = lookup.getColumnName(); init(); + getComponent().setAttribute(ATTRIBUTE_IS_INFO_PANEL_OPEN, false); } @@ -253,7 +256,13 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value actionText(getComponent().getText()); } else if ((Events.ON_OK.equals(e.getName()))) { - if (getComponent().getText() == null || getComponent().getText().length() == 0) { + // Do not allow to open info panel if component text is empty & belongs to quick form. + boolean isQuickFormComp = false; + if (getComponent().getAttribute(QuickGridTabRowRenderer.IS_QUICK_FORM_COMPONENT) != null) + isQuickFormComp = (boolean) getComponent().getAttribute(QuickGridTabRowRenderer.IS_QUICK_FORM_COMPONENT); + + if ((getComponent().getText() == null || getComponent().getText().length() == 0) && !isQuickFormComp) + { // open Info window similar to swing client if (infoPanel != null) { @@ -567,6 +576,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value ip.setClosable(true); ip.addValueChangeListener(this); infoPanel = ip; + getComponent().setAttribute(ATTRIBUTE_IS_INFO_PANEL_OPEN, true); ip.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override @@ -610,6 +620,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value { if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - Result = null (not cancelled)"); getComponent().getTextbox().focus(); + getComponent().setAttribute(ATTRIBUTE_IS_INFO_PANEL_OPEN, false); } } }); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java index 8d397f8449..d1f5324ab9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java @@ -51,7 +51,6 @@ import org.compiere.model.MTab; import org.compiere.model.Query; import org.compiere.model.X_AD_Tab_Customization; import org.compiere.util.CLogger; -import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.NamePair; @@ -556,34 +555,9 @@ public class CustomizeGridViewPanel extends Panel String gridview = null; if (lstGridMode.getSelectedItem() != null && lstGridMode.getSelectedItem().toString().length() > 0) gridview = lstGridMode.getSelectedItem().toString(); - if (m_tabcust != null && m_tabcust.getAD_Tab_Customization_ID() > 0) { - m_tabcust.setCustom(custom.toString()); - m_tabcust.setIsDisplayedGrid(gridview); - } else { - m_tabcust = new MTabCustomization(Env.getCtx(), 0, null); - m_tabcust.setAD_Tab_ID(m_AD_Tab_ID); - m_tabcust.set_ValueOfColumn("AD_User_ID", m_AD_User_ID); - m_tabcust.setCustom(custom.toString()); - m_tabcust.setIsDisplayedGrid(gridview); - } - if (m_tabcust.getCustom() == null || m_tabcust.getCustom().trim().length() == 0) - { - if (m_tabcust.is_new()) - { - //no action needed - getParent().detach(); - return; - } - else - { - ok = m_tabcust.delete(true); - } - } - else - { - ok = m_tabcust.save(); - } - // + final String dView = gridview; + + ok = MTabCustomization.saveData(Env.getCtx(), m_AD_Tab_ID, m_AD_User_ID, custom.toString(), dView, null, false); if(ok) { m_saved = true; // FDialog.info(m_WindowNo, null, "Saved"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/QuickCustomizeGridViewPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/QuickCustomizeGridViewPanel.java new file mode 100644 index 0000000000..65fbec0282 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/QuickCustomizeGridViewPanel.java @@ -0,0 +1,555 @@ +/****************************************************************************** + * Copyright (C) 2016 Logilite Technologies LLP * + * 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.panel; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; + +import org.adempiere.exceptions.DBException; +import org.adempiere.model.MTabCustomization; +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.adwindow.QuickGridView; +import org.adempiere.webui.component.Borderlayout; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListHead; +import org.adempiere.webui.component.ListHeader; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Panel; +import org.adempiere.webui.component.SimpleListModel; +import org.adempiere.webui.factory.ButtonFactory; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.adempiere.webui.window.FDialog; +import org.compiere.model.I_AD_Field; +import org.compiere.model.MField; +import org.compiere.model.MRole; +import org.compiere.model.MTab; +import org.compiere.model.Query; +import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.NamePair; +import org.zkoss.zhtml.Span; +import org.zkoss.zk.au.out.AuFocus; +import org.zkoss.zk.ui.event.DropEvent; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Hbox; +import org.zkoss.zul.North; +import org.zkoss.zul.Separator; +import org.zkoss.zul.South; +import org.zkoss.zul.Vbox; + +/** + * Customize grid panel for quick form + * + * @author Logilite Technologies + * @since Nov 08, 2017 + */ +public class QuickCustomizeGridViewPanel extends Panel { + + /** + * + */ + private static final long serialVersionUID = 721233085611663253L; + + static CLogger log = CLogger.getCLogger(QuickCustomizeGridViewPanel.class); + + private Map m_columnsWidth; + ArrayList tableSeqs; + QuickGridView gridview = null; + + private int m_WindowNo; + private int m_AD_Tab_ID; + private int m_AD_User_ID; + + // UI variables + private Label yesLabel = new Label(); + + private Button bDown = ButtonFactory.createNamedButton("MoveDown"); + private Button bUp = ButtonFactory.createNamedButton("MoveUp"); + + private Checkbox chkSaveWidth = new Checkbox(); + + SimpleListModel yesModel = new SimpleListModel(); + Listbox yesList = new Listbox(); + + private boolean uiCreated; + private boolean m_saved = false; + private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, true, false, false, false); + + /** + * Sort Tab Constructor + * + * @param WindowNo + * Window No + * @param columnsWidth + * @param GridTab + */ + public QuickCustomizeGridViewPanel(int WindowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth, ArrayList gridFieldIds) + { + m_WindowNo = WindowNo; + m_AD_Tab_ID = AD_Tab_ID; + m_AD_User_ID = AD_User_ID; + m_columnsWidth = columnsWidth; + tableSeqs = gridFieldIds; + this.setStyle("position: relative; height: 100%; width: 100%; margin: none; border: none; padding: none;"); + } + + /** + * Static Layout + * + * @throws Exception + */ + private void init() throws Exception { + Borderlayout layout = new Borderlayout(); + layout.setStyle("height: 100%; width: 100%; border: none; margin: none; padding: 2px;"); + + yesLabel.setValue(Msg.getMsg(Env.getCtx(), "Selected")); + ZKUpdateUtil.setVflex(yesList, true); + ZKUpdateUtil.setHeight(yesList, "300px"); + yesList.setSeltype("multiple"); + + EventListener crossListMouseListener = new DragListener(); + yesList.addOnDropListener(crossListMouseListener); + yesList.setItemDraggable(true); + + EventListener actionListener = new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + migrateValueWithinYesList(event); + } + }; + + bUp.addEventListener(Events.ON_CLICK, actionListener); + bDown.addEventListener(Events.ON_CLICK, actionListener); + + Panel northPanel = new Panel(); + + ListHead listHead = new ListHead(); + listHead.setParent(yesList); + ListHeader listHeader = new ListHeader(); + listHeader.appendChild(yesLabel); + listHeader.setParent(listHead); + + Span span = new Span(); + span.setParent(northPanel); + span.setStyle("height: 99%; display: inline-block; width: 86%; float: left;"); + span.appendChild(yesList); + + Vbox vbox = new Vbox(); + vbox.appendChild(bUp); + vbox.appendChild(bDown); + + span = new Span(); + span.setParent(northPanel); + span.setStyle("height: 99%; display: inline-block; width: 60px; float: left;"); + span.appendChild(vbox); + + North north = new North(); + north.setStyle("border: none; margin: 0; padding: 0; "); + north.appendChild(northPanel); + layout.appendChild(north); + + South south = new South(); + south.setStyle("border: none; margin: 0; padding: 0; "); + + Separator sep = new Separator(); + sep.setSpacing("2px"); + + Panel southPanel = new Panel(); + southPanel.appendChild(sep); + + chkSaveWidth.setLabel(Msg.getMsg(Env.getCtx(), "SaveColumnWidth")); + + vbox = new Vbox(); + + Hbox hbox = new Hbox(); + hbox.appendChild(chkSaveWidth); + vbox.appendChild(hbox); + vbox.appendChild(sep); + + hbox = new Hbox(); + vbox.appendChild(hbox); + + southPanel.appendChild(vbox); + southPanel.appendChild(sep); + + LayoutUtils.addSclass("dialog-footer", confirmPanel); + EventListener onClickListener = new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_OK))) { + saveData(); + } else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_CANCEL))) { + if (gridview != null) { + Events.postEvent("onCustomizeGrid", gridview, null); + } + getParent().detach(); + } else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_RESET))) { + MTabCustomization tabCust = MTabCustomization.get(Env.getCtx(), m_AD_User_ID, m_AD_Tab_ID, null,true); + if (tabCust != null && tabCust.getAD_Tab_Customization_ID() > 0) + tabCust.deleteEx(true); + } + } + }; + + confirmPanel.addActionListener(onClickListener); + southPanel.appendChild(confirmPanel); + south.appendChild(southPanel); + layout.appendChild(south); + + this.appendChild(layout); + + } // init + + public void loadData() { + MTabCustomization tabCust = MTabCustomization.get(Env.getCtx(), m_AD_User_ID, m_AD_Tab_ID, null,true); + boolean baseLanguage = Env.isBaseLanguage(Env.getCtx(), "AD_Field"); + yesModel.removeAllElements(); + Query query = null; + query = new Query(Env.getCtx(), I_AD_Field.Table_Name, + "AD_Tab_ID=? AND (IsDisplayed='Y' OR IsDisplayedGrid='Y') AND IsActive='Y' AND IsQuickForm='Y'", null); + query.setOrderBy("SeqNoGrid, Name, SeqNo"); + query.setParameters(new Object[] { m_AD_Tab_ID }); + query.setApplyAccessFilter(true); + + try { + List lsFieldsOfGrid = query.list(); + HashMap curTabSel = new HashMap(); + MTab tab = new MTab(Env.getCtx(), m_AD_Tab_ID, null); + + for (MField field : lsFieldsOfGrid) { + if (!MRole.getDefault(Env.getCtx(), false).isColumnAccess(tab.getAD_Table_ID(), field.getAD_Column_ID(), + true)) + continue; + + int key = field.get_ID(); + String name = null; + if (baseLanguage) + name = field.getName(); + else + name = field.get_Translation(I_AD_Field.COLUMNNAME_Name); + + ListElement pp = new ListElement(key, name); + if (tableSeqs != null && tableSeqs.size() > 0) { + if (tableSeqs.contains(key)) { + curTabSel.put(key, pp); + } + } + } + if (tableSeqs != null) { + for (int key : tableSeqs) { + if (curTabSel.get(key) != null) { + yesModel.addElement(curTabSel.get(key)); + } + } + } + } catch (DBException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + + bUp.setEnabled(true); + bDown.setEnabled(true); + yesList.setEnabled(true); + + yesList.setItemRenderer(yesModel); + yesList.setModel(yesModel); + + if ((tabCust != null && tabCust.getCustom().indexOf("px") > 0)) + chkSaveWidth.setChecked(true); + } // loadData + + void migrateLists(Listbox listFrom, Listbox listTo, int endIndex) { + int index = 0; + SimpleListModel lmFrom = (SimpleListModel) listFrom.getModel(); + SimpleListModel lmTo = (SimpleListModel) listTo.getModel(); + Set selectedItems = listFrom.getSelectedItems(); + List selObjects = new ArrayList(); + for (Object obj : selectedItems) { + ListItem listItem = (ListItem) obj; + index = listFrom.getIndexOfItem(listItem); + ListElement selObject = (ListElement) lmFrom.getElementAt(index); + selObjects.add(selObject); + } + for (ListElement selObject : selObjects) { + if (selObject == null || !selObject.isUpdateable()) + continue; + + lmFrom.removeElement(selObject); + lmTo.add(endIndex, selObject); + endIndex++; + index = lmTo.indexOf(selObject); + listTo.setSelectedIndex(index); + } + } + + /** + * Move within Yes List with Drag Event and Multiple Choice + * + * @param event event + */ + void migrateValueWithinYesList(int endIndex, List selObjects) { + int iniIndex = 0; + Arrays.sort(selObjects.toArray()); + ListElement endObject = (ListElement) yesModel.getElementAt(endIndex); + for (ListElement selected : selObjects) { + iniIndex = yesModel.indexOf(selected); + ListElement selObject = (ListElement) yesModel.getElementAt(iniIndex); + yesModel.removeElement(selObject); + endIndex = yesModel.indexOf(endObject); + yesModel.add(endIndex, selObject); + } + } + + /** + * Move within Yes List + * + * @param event event + */ + void migrateValueWithinYesList(Event event) { + Object[] selObjects = yesList.getSelectedItems().toArray(); + + if (selObjects == null) + return; + int length = selObjects.length; + if (length == 0) + return; + // + int[] indices = yesList.getSelectedIndices(); + Arrays.sort(indices); + // + boolean change = false; + // + Object source = event.getTarget(); + if (source == bUp) { + for (int i = 0; i < length; i++) { + int index = indices[i]; + if (index == 0) + break; + ListElement selObject = (ListElement) yesModel.getElementAt(index); + ListElement newObject = (ListElement) yesModel.getElementAt(index - 1); + if (!selObject.isUpdateable() || !newObject.isUpdateable()) + break; + yesModel.setElementAt(newObject, index); + yesModel.setElementAt(selObject, index - 1); + indices[i] = index - 1; + change = true; + } + } // up + + else if (source == bDown) { + for (int i = length - 1; i >= 0; i--) { + int index = indices[i]; + if (index >= yesModel.getSize() - 1) + break; + ListElement selObject = (ListElement) yesModel.getElementAt(index); + ListElement newObject = (ListElement) yesModel.getElementAt(index + 1); + if (!selObject.isUpdateable() || !newObject.isUpdateable()) + break; + yesModel.setElementAt(newObject, index); + yesModel.setElementAt(selObject, index + 1); + yesList.setSelectedIndex(index + 1); + indices[i] = index + 1; + change = true; + } + } // down + + // + if (change) { + yesList.setSelectedIndices(indices); + if (yesList.getSelectedItem() != null) { + AuFocus focus = new AuFocus(yesList.getSelectedItem()); + Clients.response(focus); + } + } + } // migrateValueWithinYesList + + public void saveData() { + // yesList + // int index = 0; + boolean ok = true; + final StringBuilder custom = new StringBuilder(); + for (int i = 0; i < yesModel.getSize(); i++) { + ListElement pp = (ListElement) yesModel.getElementAt(i); + if (!pp.isUpdateable()) + continue; + + if (i > 0) + custom.append(","); + custom.append(pp.getKey()); + } + + if (chkSaveWidth.isSelected() && m_columnsWidth != null && !m_columnsWidth.isEmpty()) { + for (int i = 0; i < yesModel.getSize(); i++) { + if (i > 0) + custom.append(","); + else + custom.append(";"); + + ListElement pp = (ListElement) yesModel.getElementAt(i); + int fieldId = pp.getKey(); + String width = m_columnsWidth.get(fieldId); + if (width == null) + width = ""; + custom.append(width); + } + } + // save Window width and height + ok = MTabCustomization.saveData(Env.getCtx(), m_AD_Tab_ID, m_AD_User_ID, custom.toString(), null, null,true); + if (ok) { + m_saved = true; + gridview.setStatusLine("Customize Preference Saved.", false); + if (gridview != null) { + Events.postEvent("onCustomizeGrid", gridview, null); + } + getParent().detach(); + } else { + FDialog.error(m_WindowNo, null, "SaveError", custom.toString()); + } + } // saveData + + public void activate(boolean b) { + if (b && !uiCreated) + createUI(); + } + + public void createUI() { + if (uiCreated) + return; + try { + init(); + } catch (Exception e) { + log.log(Level.SEVERE, "", e); + } + uiCreated = true; + } + + public boolean isSaved() { + return m_saved; + } + + public void setGridPanel(QuickGridView quickGridView) { + this.gridview = quickGridView; + } + + /** + * ListElement Item + */ + private static class ListElement extends NamePair { + + /** + * + */ + private static final long serialVersionUID = 884539656654102968L; + + private int m_key; + + private boolean m_updateable; + + public ListElement(int key, String name) { + super(name); + this.m_key = key; + this.m_updateable = true; + } + + public int getKey() { + return m_key; + } + + public boolean isUpdateable() { + return m_updateable; + } + + @Override + public String getID() { + return m_key != -1 ? String.valueOf(m_key) : null; + } + + @Override + public int hashCode() { + return m_key; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ListElement) { + ListElement li = (ListElement) obj; + return li.getKey() == m_key && li.getName() != null && li.getName().equals(getName()); + } + return false; + } // equals + + @Override + public String toString() { + String s = super.toString(); + if (s == null || s.trim().length() == 0) + s = "<" + getKey() + ">"; + return s; + } + } // ListElement Class + + /** + * DragListener Class + */ + private class DragListener implements EventListener { + /** + * Creates a ADSortTab.DragListener. + */ + public DragListener() { + } + + @Override + public void onEvent(Event event) throws Exception { + if (event instanceof DropEvent) { + int endIndex = 0; + DropEvent me = (DropEvent) event; + ListItem endItem = (ListItem) me.getTarget(); + ListItem startItem = (ListItem) me.getDragged(); + + if (!startItem.isSelected()) + startItem.setSelected(true); + + if (!(startItem.getListbox() == endItem.getListbox())) { + Listbox listFrom = (Listbox) startItem.getListbox(); + Listbox listTo = (Listbox) endItem.getListbox(); + endIndex = yesList.getIndexOfItem(endItem); + migrateLists(listFrom, listTo, endIndex); + } else if (startItem.getListbox() == endItem.getListbox() && startItem.getListbox() == yesList) { + List selObjects = new ArrayList(); + endIndex = yesList.getIndexOfItem(endItem); + for (Object obj : yesList.getSelectedItems()) { + ListItem listItem = (ListItem) obj; + int index = yesList.getIndexOfItem(listItem); + ListElement selObject = (ListElement) yesModel.getElementAt(index); + selObjects.add(selObject); + } + migrateValueWithinYesList(endIndex, selObjects); + yesList.clearSelection(); + } + } + } + } // DragListener Class + +} // QuickCustomizeGridPanel Class \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionManager.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionManager.java index 6d04638d2e..0fd0cfb4c7 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionManager.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionManager.java @@ -18,6 +18,7 @@ package org.adempiere.webui.session; import java.lang.ref.WeakReference; +import java.util.LinkedList; import java.util.Properties; import org.adempiere.webui.IWebClient; @@ -26,6 +27,8 @@ import org.adempiere.webui.desktop.IDesktop; import org.compiere.model.MUser; import org.compiere.util.Env; import org.zkoss.zk.ui.Desktop; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.Session; /** * @@ -36,6 +39,8 @@ import org.zkoss.zk.ui.Desktop; public class SessionManager { public static final String SESSION_APPLICATION = "SessionApplication"; + // Keep track of open Quick Form + public static final String SESSION_QUICKFORM = "SessionQuickForm"; public static boolean isUserLoggedIn(Properties ctx) { @@ -94,4 +99,42 @@ public class SessionManager app.changeRole(user); } + public static boolean registerQuickFormTab(Integer AD_Tab_ID) + { + LinkedList openTabs = getOpenQuickFormTabs(); + + if (openTabs.contains(AD_Tab_ID)) + { + return false; + } + + openTabs.add(AD_Tab_ID); + getSession().setAttribute(SESSION_QUICKFORM, openTabs); + + return true; + } + + @SuppressWarnings("unchecked") + public static LinkedList getOpenQuickFormTabs() + { + LinkedList tabs = (LinkedList) getSession().getAttribute(SESSION_QUICKFORM); + + if (tabs == null) + { + tabs = new LinkedList(); + } + return tabs; + } + + public static void closeQuickFormTab(Integer AD_Tab_ID) + { + LinkedList openTabs = getOpenQuickFormTabs(); + openTabs.remove(AD_Tab_ID); + getSession().setAttribute(SESSION_QUICKFORM, openTabs); + } + + private static Session getSession() + { + return Executions.getCurrent().getDesktop().getSession(); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java index 81eb1ef549..98501919e6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java @@ -4,11 +4,13 @@ import java.util.ArrayList; import java.util.Map; import org.adempiere.webui.adwindow.GridView; +import org.adempiere.webui.adwindow.QuickGridView; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; import org.adempiere.webui.panel.CustomizeGridViewPanel; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; +import org.adempiere.webui.panel.QuickCustomizeGridViewPanel; import org.compiere.util.Env; import org.compiere.util.Msg; @@ -20,6 +22,8 @@ public class CustomizeGridViewDialog extends Window { private static final long serialVersionUID = -4093048147438176240L; private CustomizeGridViewPanel customizePanel; + private QuickCustomizeGridViewPanel quickCustomizePanel; + private boolean isQuickForm = false; /** * Standard Constructor @@ -27,16 +31,26 @@ public class CustomizeGridViewDialog extends Window { * @param AD_Tab_ID tab * @param AD_User_ID user * @param columnsWidth + * @param isQuickForm */ - public CustomizeGridViewDialog(int windowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth,ArrayList gridFieldIds) - { + public CustomizeGridViewDialog(int windowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth, + ArrayList gridFieldIds, boolean isQuickForm) { setClosable(true); setTitle(Msg.getMsg(Env.getCtx(), "Customize")); - initComponent(windowNo,AD_Tab_ID, AD_User_ID, columnsWidth,gridFieldIds); + this.isQuickForm = isQuickForm; + initComponent(windowNo, AD_Tab_ID, AD_User_ID, columnsWidth, gridFieldIds); } - private void initComponent(int windowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth,ArrayList gridFieldIds) { - customizePanel = new CustomizeGridViewPanel(windowNo, AD_Tab_ID, AD_User_ID, columnsWidth,gridFieldIds); + private void initComponent(int windowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth, ArrayList gridFieldIds) { + if (isQuickForm) + { + quickCustomizePanel = new QuickCustomizeGridViewPanel(windowNo, AD_Tab_ID, AD_User_ID, columnsWidth, + gridFieldIds); + } + else + { + customizePanel = new CustomizeGridViewPanel(windowNo, AD_Tab_ID, AD_User_ID, columnsWidth, gridFieldIds); + } this.setStyle("position : relative;"); if (!ThemeManager.isUseCSSForWindowSize()) { ZKUpdateUtil.setWindowWidthX(this, 600); @@ -49,16 +63,34 @@ public class CustomizeGridViewDialog extends Window { } this.setBorder("normal"); this.setSclass("popup-dialog customize-grid-view-dialog"); - appendChild(customizePanel); - customizePanel.createUI(); - customizePanel.query(); + + if (isQuickForm) + { + ZKUpdateUtil.setWidth(this, "500px"); + ZKUpdateUtil.setHeight(this, "410px"); + quickCustomizePanel.createUI(); + quickCustomizePanel.loadData(); + appendChild(quickCustomizePanel); + } + else + { + ZKUpdateUtil.setWidth(this, "600px"); + ZKUpdateUtil.setHeight(this, "500px"); + + appendChild(customizePanel); + customizePanel.createUI(); + customizePanel.query(); + } } /** * @return whether change have been successfully save to db */ public boolean isSaved() { - return customizePanel.isSaved(); + if (isQuickForm) + return quickCustomizePanel.isSaved(); + else + return customizePanel.isSaved(); } public void setGridPanel(GridView gridPanel){ @@ -72,12 +104,32 @@ public class CustomizeGridViewDialog extends Window { * @param columnsWidth * @param gridFieldIds list fieldId current display in gridview * @param gridPanel + * @param isQuickForm + * @param quickGridView */ - public static boolean showCustomize (int WindowNo, int AD_Tab_ID, Map columnsWidth,ArrayList gridFieldIds,GridView gridPanel) + public static boolean showCustomize(int WindowNo, int AD_Tab_ID, Map columnsWidth, ArrayList gridFieldIds, GridView gridPanel, + QuickGridView quickGridView, boolean isQuickForm) { - CustomizeGridViewDialog customizeWindow = new CustomizeGridViewDialog(WindowNo, AD_Tab_ID, Env.getAD_User_ID(Env.getCtx()), columnsWidth,gridFieldIds); - customizeWindow.setGridPanel(gridPanel); + CustomizeGridViewDialog customizeWindow = new CustomizeGridViewDialog(WindowNo, AD_Tab_ID, Env.getAD_User_ID(Env.getCtx()), columnsWidth, gridFieldIds, + isQuickForm); + if (isQuickForm) + { + customizeWindow.setquickGridView(quickGridView); + } + else + { + customizeWindow.setGridPanel(gridPanel); + } AEnv.showWindow(customizeWindow); return customizeWindow.isSaved(); - } // showProduct + } // showCustomize + + /** + * @param QuickGridView + */ + private void setquickGridView(QuickGridView quickGridView) + { + quickCustomizePanel.setGridPanel(quickGridView); + } + } diff --git a/org.adempiere.ui.zk/index.zul b/org.adempiere.ui.zk/index.zul index e45f08f2d3..dcdf4c13a2 100644 --- a/org.adempiere.ui.zk/index.zul +++ b/org.adempiere.ui.zk/index.zul @@ -46,7 +46,7 @@ Copyright (C) 2007 Ashley G Ramdass. id.zk.Extend = zk.$extends(zk.Object, {}, { fakeOnchange: function (wgt) { // just sent fake event when control is textfield and value is not yet sync to server - if (wgt.$instanceof(zul.inp.Textbox) && wgt.$n().value != wgt.getText()) + if ((wgt.$instanceof(zul.inp.Textbox) || wgt.$instanceof(zul.inp.Decimalbox)) && wgt.$n().value != wgt.getText()) zAu.send(new zk.Event(zk.Widget.$(wgt), 'onChange',{"value":wgt.$n().value})); else if (zk.$import("ckez.CKeditor") != undefined && wgt.$instanceof(ckez.CKeditor)){//https://www.zkoss.org/javadoc/latest/jsdoc/_global_/zk.html#$import(_global_.String) diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/font-icons.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/font-icons.css.dsp index 2e44114c3c..198f0a555f 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/font-icons.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/font-icons.css.dsp @@ -286,3 +286,9 @@ .z-icon-Share:before { content: "\f0ac"; } +.z-icon-QuickForm:before { + content: "\f0ae"; +} +.z-icon-UnSort:before { + content: "\f074"; +} \ No newline at end of file diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/window.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/window.css.dsp index 931835a7a8..fd63881fd2 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/window.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/window.css.dsp @@ -117,3 +117,19 @@ div.wc-modal, div.wc-modal-none, div.wc-highlighted, div.wc-highlighted-none { .z-notification { padding: 3px !important; } + +input[type="checkbox"]:focus +{ + outline: #0000ff auto 1px; + -moz-outline-radius: 3px; +} + +<%-- Quick Form Read-only Component --%> +.quickform-readonly .z-textbox-readonly, .quickform-readonly .z-intbox-readonly, .quickform-readonly .z-longbox-readonly, .quickform-readonly .z-doublebox-readonly, +.quickform-readonly .z-decimalbox-readonly, .quickform-readonly .z-datebox-readonly, .quickform-readonly .z-timebox-readonly, .quickform-readonly .editor-input-disd, +.quickform-readonly .z-textbox[readonly], .quickform-readonly .z-intbox[readonly], .quickform-readonly .z-longbox[readonly], .quickform-readonly .z-doublebox[readonly], +.quickform-readonly .z-decimalbox[readonly], .quickform-readonly .z-datebox[readonly], .quickform-readonly .z-timebox[readonly] +{ + color: #252525 !important; + opacity: .8; +} \ No newline at end of file diff --git a/org.adempiere.ui.zk/theme/default/images/QuickForm16.png b/org.adempiere.ui.zk/theme/default/images/QuickForm16.png new file mode 100644 index 0000000000000000000000000000000000000000..ba36f891df011accbc0c218223d26d7490faf9e8 GIT binary patch literal 991 zcmV<510ei~P) zSad^gZEa<4bO2OuZ){>=axHUddSzrFX=8703OzkNJv}`=Jv}`=JqijaV<{jqFfcP9 zN?~htVjw4KX>Dy`V<#X}bY*F7WpXSa3TSk6a5^t9YH4k4VPh_Bb#rNBXklz@E@OHM z3S)9*VRU6=Aa`kWXdrZGWgtgMO;9WfXmoUNIxjDGcXuvlX>D*WZ*pfA^S=}T00PfR zL_t(I%WaZPXjE4e$A9;}_d1g|Z)nvKL%~`t2??>f5EntT9|{!;Ev`zeLYKO0{0N9v ztlcOfC{3*dtY9gLBQ0sMwWbkG3em<$6RI(4VjQEB%-E!fCU4@*WbWyrHl49Ka2EF- z&hPy1|6BzS-HG$snv$nx#@~zx+VL92WDevqk6Z2F!m~)OH9d9zK)_qte7kMn^$+VY zb-{<9pIx*T+WL9NQUX zx7z>d-jcW8c>7LvCPdh?0C+U&vtXV}C=}pfd>q$(f%z{L(be?_xtq0A)qKt`4SR`Q zzfx|SoROj;mz5=@hzMG1%F7f0BEqXnUO{Wku|8)Z+J!i&tM0xW_mB!9D({UUkk;v>>E5+pG z6NWAwWb^(eE}p6*{vgh-D3K#oT2(h0(fI(&vT$7&*LCr{5HnVo_WE~Nwf=p6J@*q2 z27A$^TL7qTG6GNlNT<`p<8g+Ehq={vla|jasQTnIznyF5&%U48P}6~B6^Ld|1;JpD ztF4W!+j^J_r)n9W_>0xsT1X7_kkg%+S>jn@A=SLqb&{KJi8LxpYmhP-+y=1 zvaCfSqD4?31&vCne^zE`BRRPPOwZPyrOu=3IfhGKW{Zm#nM5K9z~6KfHkgNMlbZkl N002ovPDHLkV1hUzxlsTB literal 0 HcmV?d00001 diff --git a/org.adempiere.ui.zk/theme/default/images/QuickForm24.png b/org.adempiere.ui.zk/theme/default/images/QuickForm24.png new file mode 100644 index 0000000000000000000000000000000000000000..cf82dcf1b72b9540704324e2a74363461d99a429 GIT binary patch literal 1104 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fY)RhkE=Z06Ge{Kf4?WhlA0l# z@h(BaqeFPti&F|&hn^^_Sv6=ktEuGmPF7S@P~4Hx!`0aMp@%QSL&Yx2N>S;P(b1wx zj-@x+xAg99ymx-#-sw!NjhpAZpHuU5?tjbs%$v?!?z8B#zhLv0L$Sr8@BGopo12eZ zD!AouZ$0U}(aD$_3{q0Bt=a33G3zeJU4l`t?b66O&u6|E{+) zTq%{D6uNNX#<)8>%DOjhG?d|Ee^?-~`|i0@r?^(F66$o((9?6fY!VWhnw!fT8p_Gm z+|%FxI3{P&va5%ic2DoGT?;bd?38yURx4MmU^rmFBjUPn&mI}iNdii?$2M&;N{KvX zz{AiYU?Dzx$M2MurT%k$&a7F^a8!!bAu&;L*E;3}8eZp^%|3T665wF@@$b_ovn%3C zHh0(0SiIrDraiTNvzEzLG+(=ZedgO0Ks%eiEo{DclA-XvboM^$12@Bhf;Q=wl$MrC z|Jv7_U%daj!*|yA%WnkTn$+f}@6vIOXTkh>mRP-i+~<}81s^5eyLY3BCrw`N543C()5{E}(o{rC1Z7SS68n94u1u9B}mW`5<^nWQN% z-Y`sE$I0NdFyP!q*%c8Sj{g4qvp=~m+Y=`i_D^80?1P-M(M<;xoH&A3UU_(M*`pAx z)?Ihbe2CJ#TU$Hj)Z#fiZ+a_DRFLZr4heBFnt4ZD=e=LntTq9r*y}4_8)fXYJ$~X@ zso(V2r*jT7HXMHFaJ}@kXqtta*$)@JqfQ(x0%51ijbvx6_n)M)ZQHg2tGPe6N=TlI z_o!cNwm>0VdyKHa^pZl9zWgVh8k73rD&%0itFzE)YTN)5(b8fTfV0cavd_@X?R#YPied6 znY0S#L@0ndXRc`8Kj^+Cq%=R3uy)E~_ z>;2Nhua+7Lh5sl?OjREn8pjt$CDJ zN`3mL4~$)|I%b^fejfljNDt(oO*R{C-C|^V u-E6}KBLfBor;Dsw5+7V;VLEg3Q!>*kiPc$kV$&m_P6kg`KbLh*2~7ZQBj{!T literal 0 HcmV?d00001 diff --git a/org.adempiere.ui.zk/theme/default/images/UnSort16.png b/org.adempiere.ui.zk/theme/default/images/UnSort16.png new file mode 100644 index 0000000000000000000000000000000000000000..7f3dad1871a893d93b5532e2a2d140e72dd88116 GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4T_#Fjv*HQ$r3UT?(?uMuD>k#@6Y^$ALdK& zg#4FY!oEtD$u8X3qIPB4kDpuH9@^XS1ThD3Uv1;scf~*@@p4O#W7dLG8<`g@Dl75z z*de=$$Nb0n0|z)to)wjxRWO_&6CzpnVgJ0w*VWvIkIk3mIqo2FgsszYX(#i6h)6E} zQUz%(9~%er2m3b~z7AKv+;jfivf_pv4_8laH3`uyYe+gEa_njRoU?sQAL}j3jDCN( zdDBUJm5i{0^atbUUn*T`7G`%@L;E-<@cs~6S@+aE`)z&7hwAry8?+akGGsi#kWf_1 zx8(7Gy1p;J|1VxC)VKesN)yix9-xkYzR4ec+Rt}nIPxzmUyZrsowZI}2fMZ!TTPki oMaEk@q@Uz0c&06ImWPKyD@ZviEdIq@UPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0d`45K~zXf?UcVu z!%z^%PY3@42XS?E>q}RgIH^?!H&=0XR9Ywne<6ZH2b;a4e}ZUd{{<)4j>!w9t>$@` z9GK`e#y-KtFMOfAyYJ_cg2b+KuWQwfv