merge experimental into development
This commit is contained in:
commit
996684885e
|
@ -0,0 +1,63 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- Nov 6, 2014 3:13:05 PM ICT
|
||||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
|
||||
-- Nov 6, 2014 3:13:13 PM ICT
|
||||
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Table_ID,AD_Client_ID,AD_Org_ID,EntityType) VALUES (0,'N',0,211799,'N','N','N',0,'N',1,'N','N','N','Y','4ef802de-84a4-4ebc-a364-8ba9a27a39b5','Y','IsKey','This column is the key in this table','The key column must also be display sequence 0 in the field definition and may be hidden.','Key column','N',TO_DATE('2014-11-06 15:13:12','YYYY-MM-DD HH24:MI:SS'),100,'Y',TO_DATE('2014-11-06 15:13:12','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N',389,20,897,0,0,'D')
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:13:25 PM ICT
|
||||
ALTER TABLE AD_InfoColumn ADD IsKey CHAR(1) DEFAULT NULL CHECK (IsKey IN ('Y','N'))
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:14:19 PM ICT
|
||||
INSERT INTO AD_Field (SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,AD_Org_ID,Created) VALUES (0,'N',844,0,'N','N',260,'Y',203471,'N','The key column must also be display sequence 0 in the field definition and may be hidden.','D','This column is the key in this table','Key column','dd0b953a-d575-4eac-b435-87db841346c6','Y','N',100,100,TO_DATE('2014-11-06 15:14:18','YYYY-MM-DD HH24:MI:SS'),'Y','Y',170,1,'N',0,1,1,'N','N',211799,0,TO_DATE('2014-11-06 15:14:18','YYYY-MM-DD HH24:MI:SS'))
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:17:53 PM ICT
|
||||
UPDATE AD_Field SET Help='In case data of info window come from a view, define a column contain unique value as key to keep selected record', Description='Define this column has unique value, play as key of table', Name='Is View Key',Updated=TO_DATE('2014-11-06 15:17:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203471
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=170, IsDisplayed='Y', XPosition=6,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203471
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=180,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201720
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=190,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201625
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=200,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203048
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=210,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201635
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=220,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201636
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=230,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13603
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=240,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201622
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=250,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201623
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=260,Updated=TO_DATE('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13597
|
||||
;
|
||||
SELECT register_migration_script('201411061604_IDEMPIERE-2230.sql') FROM dual
|
||||
;
|
|
@ -0,0 +1,9 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
-- Aug 2, 2015 3:17:29 AM WITA
|
||||
UPDATE AD_SysConfig SET ConfigurationLevel='C',Updated=TO_DATE('2015-08-02 03:17:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=50018
|
||||
;
|
||||
SELECT register_migration_script('201502081982-IDEMPIERE-2470.sql') FROM dual
|
||||
;
|
|
@ -0,0 +1,15 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- IDEMPIERE-2296/IDEMPIERE-2367
|
||||
-- Aug 19, 2015 4:02:58 PM COT
|
||||
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 (200065,0,0,TO_DATE('2015-08-19 16:02:57','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2015-08-19 16:02:57','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ZK_SEQ_DEFAULT_VALUE_PANEL','63','Define the order to apply defaults on Info Windows - please check wiki for detailed explanation','D','C','bc05e8e6-1a56-4f06-a019-24f42e48d02a')
|
||||
;
|
||||
|
||||
-- Aug 19, 2015 4:05:25 PM COT
|
||||
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 (200066,0,0,TO_DATE('2015-08-19 16:05:25','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2015-08-19 16:05:25','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ZK_INFO_NUM_PAGE_PRELOAD','4','Default of pages preloaded on Info Windows','D','S','f8fee03f-5922-4cf3-bf5a-ce7c5548dcb7')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201508191607_IDEMPIERE-2296.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- IDEMPIERE-2488 Info Window run Query twice
|
||||
-- Aug 9, 2015 11:42:05 PM WITA
|
||||
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (202897,0,0,'Y',TO_DATE('2015-08-09 23:42:05','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-08-09 23:42:05','YYYY-MM-DD HH24:MI:SS'),100,'isLoadPageNum','Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table','Load Page Num','D','9ac2b88f-7ada-4a37-a458-5900f1cdb71b')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:42:50 PM WITA
|
||||
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) VALUES (212224,0,'Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table',895,'isLoadPageNum','Y',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_DATE('2015-08-09 23:42:50','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-08-09 23:42:50','YYYY-MM-DD HH24:MI:SS'),100,202897,'Y','N','D','N','N','N','Y','fd37da5c-6442-425e-9217-fd186c67ff65','Y',0,'N','N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:42:55 PM WITA
|
||||
ALTER TABLE AD_InfoWindow ADD isLoadPageNum CHAR(1) DEFAULT 'Y' CHECK (isLoadPageNum IN ('Y','N'))
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:43:33 PM WITA
|
||||
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 (203856,'Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table',842,212224,'Y',0,220,0,'N','N','N','N',0,0,'Y',TO_DATE('2015-08-09 23:43:33','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-08-09 23:43:33','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','6cc379fd-0f84-45d8-acf7-12f12ce4c753','Y',130,1,1,1,'N','N','N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=100,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13581
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=110,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201621
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=120,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201634
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=130,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13579
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=140,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13580
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=150,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201627
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=160,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201628
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=170, XPosition=5, ColumnSpan=2,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203856
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=190,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201639
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=200,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202198
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=210,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201807
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=220,Updated=TO_DATE('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202196
|
||||
;
|
||||
UPDATE AD_InfoWindow SET isLoadPageNum = 'Y'
|
||||
;
|
||||
SELECT register_migration_script('201509081982-IDEMPIERE-2488.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
-- Aug 14, 2015 6:52:36 AM WITA
|
||||
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','Selected {0} rows',0,0,'Y',TO_DATE('2015-08-14 06:52:36','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-08-14 06:52:36','YYYY-MM-DD HH24:MI:SS'),100,1000000,'IWStatusSelected','D','316251b1-093c-4f33-bf37-4d5af0f000d5')
|
||||
;
|
||||
SELECT register_migration_script('201514081982-IDEMPIERE-2230.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
-- Nov 6, 2014 3:13:05 PM ICT
|
||||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
|
||||
-- Nov 6, 2014 3:13:13 PM ICT
|
||||
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Table_ID,AD_Client_ID,AD_Org_ID,EntityType) VALUES (0,'N',0,211799,'N','N','N',0,'N',1,'N','N','N','Y','4ef802de-84a4-4ebc-a364-8ba9a27a39b5','Y','IsKey','This column is the key in this table','The key column must also be display sequence 0 in the field definition and may be hidden.','Key column','N',TO_TIMESTAMP('2014-11-06 15:13:12','YYYY-MM-DD HH24:MI:SS'),100,'Y',TO_TIMESTAMP('2014-11-06 15:13:12','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N',389,20,897,0,0,'D')
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:13:25 PM ICT
|
||||
ALTER TABLE AD_InfoColumn ADD COLUMN IsKey CHAR(1) DEFAULT NULL CHECK (IsKey IN ('Y','N'))
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:14:19 PM ICT
|
||||
INSERT INTO AD_Field (SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,AD_Org_ID,Created) VALUES (0,'N',844,0,'N','N',260,'Y',203471,'N','The key column must also be display sequence 0 in the field definition and may be hidden.','D','This column is the key in this table','Key column','dd0b953a-d575-4eac-b435-87db841346c6','Y','N',100,100,TO_TIMESTAMP('2014-11-06 15:14:18','YYYY-MM-DD HH24:MI:SS'),'Y','Y',170,1,'N',0,1,1,'N','N',211799,0,TO_TIMESTAMP('2014-11-06 15:14:18','YYYY-MM-DD HH24:MI:SS'))
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:17:53 PM ICT
|
||||
UPDATE AD_Field SET Help='In case data of info window come from a view, define a column contain unique value as key to keep selected record', Description='Define this column has unique value, play as key of table', Name='Is View Key',Updated=TO_TIMESTAMP('2014-11-06 15:17:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203471
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=170, IsDisplayed='Y', XPosition=6,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203471
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=180,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201720
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=190,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201625
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=200,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203048
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=210,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201635
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=220,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201636
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=230,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13603
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=240,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201622
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=250,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201623
|
||||
;
|
||||
|
||||
-- Nov 6, 2014 3:18:15 PM ICT
|
||||
UPDATE AD_Field SET SeqNo=260,Updated=TO_TIMESTAMP('2014-11-06 15:18:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13597
|
||||
;
|
||||
SELECT register_migration_script('201411061604_IDEMPIERE-2230.sql') FROM dual
|
||||
;
|
|
@ -0,0 +1,6 @@
|
|||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
-- Aug 2, 2015 3:17:29 AM WITA
|
||||
UPDATE AD_SysConfig SET ConfigurationLevel='C',Updated=TO_TIMESTAMP('2015-08-02 03:17:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=50018
|
||||
;
|
||||
SELECT register_migration_script('201502081982-IDEMPIERE-2470.sql') FROM dual
|
||||
;
|
|
@ -0,0 +1,12 @@
|
|||
-- IDEMPIERE-2296/IDEMPIERE-2367
|
||||
-- Aug 19, 2015 4:02:58 PM COT
|
||||
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 (200065,0,0,TO_TIMESTAMP('2015-08-19 16:02:57','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2015-08-19 16:02:57','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ZK_SEQ_DEFAULT_VALUE_PANEL','63','Define the order to apply defaults on Info Windows - please check wiki for detailed explanation','D','C','bc05e8e6-1a56-4f06-a019-24f42e48d02a')
|
||||
;
|
||||
|
||||
-- Aug 19, 2015 4:05:25 PM COT
|
||||
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 (200066,0,0,TO_TIMESTAMP('2015-08-19 16:05:25','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2015-08-19 16:05:25','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ZK_INFO_NUM_PAGE_PRELOAD','4','Default of pages preloaded on Info Windows','D','S','f8fee03f-5922-4cf3-bf5a-ce7c5548dcb7')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201508191607_IDEMPIERE-2296.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
-- IDEMPIERE-2488 Info Window run Query twice
|
||||
-- Aug 9, 2015 11:42:05 PM WITA
|
||||
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (202897,0,0,'Y',TO_TIMESTAMP('2015-08-09 23:42:05','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-08-09 23:42:05','YYYY-MM-DD HH24:MI:SS'),100,'isLoadPageNum','Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table','Load Page Num','D','9ac2b88f-7ada-4a37-a458-5900f1cdb71b')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:42:50 PM WITA
|
||||
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) VALUES (212224,0,'Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table',895,'isLoadPageNum','Y',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2015-08-09 23:42:50','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-08-09 23:42:50','YYYY-MM-DD HH24:MI:SS'),100,202897,'Y','N','D','N','N','N','Y','fd37da5c-6442-425e-9217-fd186c67ff65','Y',0,'N','N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:42:55 PM WITA
|
||||
ALTER TABLE AD_InfoWindow ADD COLUMN isLoadPageNum CHAR(1) DEFAULT 'Y' CHECK (isLoadPageNum IN ('Y','N'))
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:43:33 PM WITA
|
||||
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 (203856,'Load Page Num','When load data for info window, also load number of paging','Load number of paging maybe affect to performance when info window is join of many table',842,212224,'Y',0,220,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2015-08-09 23:43:33','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-08-09 23:43:33','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','6cc379fd-0f84-45d8-acf7-12f12ce4c753','Y',130,1,1,1,'N','N','N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=100,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13581
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=110,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201621
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=120,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201634
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=130,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13579
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=140,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13580
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=150,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201627
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=160,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201628
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=170, XPosition=5, ColumnSpan=2,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203856
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=190,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201639
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=200,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202198
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=210,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201807
|
||||
;
|
||||
|
||||
-- Aug 9, 2015 11:45:12 PM WITA
|
||||
UPDATE AD_Field SET SeqNo=220,Updated=TO_TIMESTAMP('2015-08-09 23:45:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202196
|
||||
;
|
||||
UPDATE AD_InfoWindow SET isLoadPageNum = 'Y'
|
||||
;
|
||||
SELECT register_migration_script('201509081982-IDEMPIERE-2488.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
|
||||
-- Aug 14, 2015 6:52:36 AM WITA
|
||||
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','Selected {0} rows',0,0,'Y',TO_TIMESTAMP('2015-08-14 06:52:36','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-08-14 06:52:36','YYYY-MM-DD HH24:MI:SS'),100,1000000,'IWStatusSelected','D','316251b1-093c-4f33-bf37-4d5af0f000d5')
|
||||
;
|
||||
SELECT register_migration_script('201514081982-IDEMPIERE-2230.sql') FROM dual
|
||||
;
|
||||
|
|
@ -37,6 +37,7 @@ import java.util.logging.Level;
|
|||
|
||||
import org.adempiere.base.ILookupFactory;
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
|
@ -45,6 +46,7 @@ import org.compiere.util.Env;
|
|||
import org.compiere.util.Evaluatee;
|
||||
import org.compiere.util.Evaluator;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.util.ParseSeq;
|
||||
|
||||
/**
|
||||
* Grid Field Model.
|
||||
|
@ -78,10 +80,11 @@ import org.compiere.util.Util;
|
|||
public class GridField
|
||||
implements Serializable, Evaluatee, Cloneable
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7859929653710975421L;
|
||||
private static final long serialVersionUID = -7739433012288022819L;
|
||||
|
||||
/**
|
||||
* Field Constructor.
|
||||
|
@ -540,6 +543,8 @@ public class GridField
|
|||
* Don't default from Context => use explicit defaultValue
|
||||
* (would otherwise copy previous record)
|
||||
* </pre>
|
||||
* this method code in mind GirdField lie at standard window, and default is receive when new record.
|
||||
* maybe it will don't suitable for use at other place as info panel parameter,...
|
||||
* @return default value or null
|
||||
*/
|
||||
public Object getDefault()
|
||||
|
@ -547,14 +552,130 @@ public class GridField
|
|||
/**
|
||||
* (a) Key/Parent/IsActive/SystemAccess
|
||||
*/
|
||||
|
||||
// No defaults for these fields
|
||||
if (m_vo.IsKey || m_vo.displayType == DisplayType.RowID
|
||||
|| DisplayType.isLOB(m_vo.displayType)
|
||||
|| "Created".equals(m_vo.ColumnName) // for Created/Updated default is managed on PO, and direct inserts on DB
|
||||
|| "Updated".equals(m_vo.ColumnName))
|
||||
if (isIgnoreDefault())
|
||||
return null;
|
||||
// Set Parent to context if not explicitly set
|
||||
|
||||
String orderGetDefault = "123457";// this value can put to system configuration
|
||||
|
||||
Object defaultValue = null;
|
||||
|
||||
if ((defaultValue = getDefault (orderGetDefault)) != null){
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* No resolution
|
||||
*/
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[NONE] " + m_vo.ColumnName);
|
||||
return null;
|
||||
} // getDefault
|
||||
|
||||
/**
|
||||
* get default of field when field don't lie down at standard window
|
||||
* @return
|
||||
*/
|
||||
public Object getDefaultForPanel (){
|
||||
//default is preference for field > special case > default logic > sql default > data-type default
|
||||
String defaultSeq = "63";
|
||||
return getDefault (MSysConfig.getValue(MSysConfig.ZK_SEQ_DEFAULT_VALUE_PANEL, defaultSeq, Env.getAD_Client_ID(m_vo.ctx)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default value with priority define by seqGetDefaultValueStr
|
||||
* @param seqGetDefaultValueStr
|
||||
* @return
|
||||
*/
|
||||
public Object getDefault(String seqGetDefaultValueStr){
|
||||
ParseSeq seqGetDefaultValue = ParseSeq.getNumberOrder(seqGetDefaultValueStr);
|
||||
|
||||
if (seqGetDefaultValue == null)
|
||||
throw new AdempiereException ("seq define for get default value has wrong value");
|
||||
|
||||
return getDefault (seqGetDefaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default value with priority define by seqGetDefaultValue
|
||||
* @param seqGetDefaultValue
|
||||
* @return
|
||||
*/
|
||||
public Object getDefault(ParseSeq seqGetDefaultValue){
|
||||
Object defaultValue = null;
|
||||
for (Character seqType : seqGetDefaultValue){
|
||||
defaultValue = getDefaultValueByType(seqType);
|
||||
if (defaultValue != null)
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* "1" mean from special case
|
||||
* "2" mean from sql default
|
||||
* "3" mean from default logic
|
||||
* "4" mean user preference
|
||||
* "5" mean from system preference
|
||||
* "6" mean preference for field lie down at panel as process parameter, info parameter,...
|
||||
* "7" mean data-type default
|
||||
* @param initValueType
|
||||
* @return
|
||||
*/
|
||||
protected Object getDefaultValueByType (Character defaultValueType){
|
||||
if (defaultValueType.equals('1')){
|
||||
return defaultForSpecialCase();
|
||||
}else if (defaultValueType.equals('2')){
|
||||
return defaultFromSQLExpression();
|
||||
}else if (defaultValueType.equals('3')){
|
||||
return defaultFromExpression();
|
||||
}else if (defaultValueType.equals('4') || defaultValueType.equals('5')){
|
||||
return defaultFromPreference(defaultValueType);
|
||||
}else if (defaultValueType.equals('6')){
|
||||
return defaultFromPreferenceForPanel();
|
||||
}else if (defaultValueType.equals('7')){
|
||||
return defaultFromDatatype();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isIgnoreDefault (){
|
||||
// No defaults for these fields
|
||||
return (m_vo.IsKey || m_vo.displayType == DisplayType.RowID
|
||||
|| DisplayType.isLOB(m_vo.displayType)
|
||||
|| "Created".equals(m_vo.ColumnName) // for Created/Updated default is managed on PO, and direct inserts on DB
|
||||
|| "Updated".equals(m_vo.ColumnName));
|
||||
}
|
||||
|
||||
/**
|
||||
* When field lie down at standard window, for make new record, some column is fix will special logic
|
||||
* example: reference column at child tab always use parent value
|
||||
* active column always true
|
||||
* in system client always use system for client
|
||||
* @return
|
||||
*/
|
||||
protected Object defaultForSpecialCase (){
|
||||
Object defaultValue = null;
|
||||
// Set Parent to context if not explicitly set
|
||||
if ((defaultValue = defaultFromParent()) != null){
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// is active field then return "Y"
|
||||
if ((defaultValue = defaultForActiveField()) != null){
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// Set Client & Org to System, if System access
|
||||
if ((defaultValue = defaultForClientOrg()) != null){
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultFromParent (){
|
||||
// Set Parent to context if not explicitly set
|
||||
if (isParentValue()
|
||||
&& (m_vo.DefaultValue == null || m_vo.DefaultValue.length() == 0))
|
||||
{
|
||||
|
@ -562,14 +683,22 @@ public class GridField
|
|||
if (log.isLoggable(Level.FINE)) log.fine("[Parent] " + m_vo.ColumnName + "=" + parent);
|
||||
return createDefault(parent);
|
||||
}
|
||||
// Always Active
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultForActiveField (){
|
||||
// Always Active
|
||||
if (m_vo.ColumnName.equals("IsActive"))
|
||||
{
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[IsActive] " + m_vo.ColumnName + "=Y");
|
||||
return "Y";
|
||||
}
|
||||
|
||||
// Set Client & Org to System, if System access
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultForClientOrg (){
|
||||
// Set Client & Org to System, if System access
|
||||
if (X_AD_Table.ACCESSLEVEL_SystemOnly.equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, GridTab.CTX_AccessLevel))
|
||||
&& (m_vo.ColumnName.equals("AD_Client_ID") || m_vo.ColumnName.equals("AD_Org_ID")))
|
||||
{
|
||||
|
@ -584,6 +713,10 @@ public class GridField
|
|||
return new Integer(0);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultFromSQLExpression () {
|
||||
/**
|
||||
* (b) SQL Statement (for data integity & consistency)
|
||||
*/
|
||||
|
@ -631,14 +764,19 @@ public class GridField
|
|||
if (log.isLoggable(Level.FINE)) log.fine("[SQL] " + m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
|
||||
} // SQL Statement
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultFromExpression (){
|
||||
/**
|
||||
* (c) Field DefaultValue === similar code in AStartRPDialog.getDefault ===
|
||||
*/
|
||||
if (m_vo.DefaultValue != null && !m_vo.DefaultValue.equals("") && !m_vo.DefaultValue.startsWith("@SQL="))
|
||||
{
|
||||
defStr = ""; // problem is with texts like 'sss;sss'
|
||||
String defStr = ""; // problem is with texts like 'sss;sss'
|
||||
// It is one or more variables/constants
|
||||
StringTokenizer st = new StringTokenizer(m_vo.DefaultValue, ",;", false);
|
||||
while (st.hasMoreTokens())
|
||||
|
@ -659,79 +797,116 @@ public class GridField
|
|||
} // while more Tokens
|
||||
} // Default value
|
||||
|
||||
if (getAD_Process_ID_Of_Panel() > 0){
|
||||
defStr = Env.getPreference (m_vo.ctx, getAD_Window_ID_Of_Panel(), getAD_Infowindow_ID(), getAD_Process_ID_Of_Panel(), m_vo.ColumnName);
|
||||
return null;
|
||||
}
|
||||
|
||||
// when have no preference set for field, and field lie in process dialog call from infoWindow
|
||||
if (defStr.equals("") && getAD_Infowindow_ID() > 0){
|
||||
// try get preference for current infoWindow but all process
|
||||
defStr = Env.getPreference (m_vo.ctx, Env.adWindowDummyID, getAD_Infowindow_ID(), 0, m_vo.ColumnName);
|
||||
/**
|
||||
* get preference when field don't lie down at standard window
|
||||
* @return
|
||||
*/
|
||||
protected Object defaultFromPreferenceForPanel() {
|
||||
String defStr = "";
|
||||
if (getAD_Process_ID_Of_Panel() > 0) {
|
||||
defStr = Env.getPreference(m_vo.ctx, getAD_Window_ID_Of_Panel(),
|
||||
getAD_Infowindow_ID(), getAD_Process_ID_Of_Panel(),
|
||||
m_vo.ColumnName);
|
||||
|
||||
if (defStr.equals("")){
|
||||
// try get preference for current process but all infoWindow
|
||||
defStr = Env.getPreference (m_vo.ctx, Env.adWindowDummyID, 0, getAD_Process_ID_Of_Panel(), m_vo.ColumnName);
|
||||
// when have no preference set for field, and field lie in process
|
||||
// dialog call from infoWindow
|
||||
if (defStr.equals("") && getAD_Infowindow_ID() > 0) {
|
||||
// try get preference for current infoWindow but all process
|
||||
defStr = Env.getPreference(m_vo.ctx, Env.adWindowDummyID,
|
||||
getAD_Infowindow_ID(), 0, m_vo.ColumnName);
|
||||
|
||||
if (defStr.equals("")) {
|
||||
// try get preference for current process but all infoWindow
|
||||
defStr = Env.getPreference(m_vo.ctx, Env.adWindowDummyID,
|
||||
0, getAD_Process_ID_Of_Panel(), m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (defStr.equals("")) {
|
||||
// try get preference for all infoWindow and all process
|
||||
defStr = Env.getPreference(m_vo.ctx, Env.adWindowDummyID,
|
||||
0, 0, m_vo.ColumnName);
|
||||
}
|
||||
}
|
||||
|
||||
if (defStr.equals("")){
|
||||
// try get preference for all infoWindow and all process
|
||||
defStr = Env.getPreference (m_vo.ctx, Env.adWindowDummyID, 0, 0, m_vo.ColumnName);
|
||||
if (defStr.equals("")) {
|
||||
// try get preference apply for all process and current window
|
||||
defStr = Env.getPreference(m_vo.ctx,
|
||||
getAD_Window_ID_Of_Panel(), 0, 0, m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (defStr.equals("")) {
|
||||
// try get preference apply for all window and this process
|
||||
defStr = Env.getPreference(m_vo.ctx, 0, 0,
|
||||
getAD_Process_ID_Of_Panel(), m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (defStr.equals("")) {
|
||||
// try get preference apply for all process and all window
|
||||
defStr = Env.getPreference(m_vo.ctx, 0, 0, 0, m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (!defStr.equals("")) {
|
||||
if (log.isLoggable(Level.FINE))
|
||||
log.fine("[Process Parameter Preference] "
|
||||
+ m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
// <- End of suggested changes
|
||||
} else if (getAD_Infowindow_ID() > 0) {
|
||||
defStr = Env.getPreference(m_vo.ctx, getAD_Window_ID_Of_Panel(),
|
||||
getAD_Infowindow_ID(), m_vo.ColumnName);
|
||||
if (!defStr.equals("")) {
|
||||
if (log.isLoggable(Level.FINE))
|
||||
log.fine("[Process Parameter Preference] "
|
||||
+ m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param defaultValueType "4" for user preference and "5" for system preference
|
||||
* @return
|
||||
*/
|
||||
protected Object defaultFromPreference(Character defaultValueType) {
|
||||
String defStr = "";
|
||||
if (defaultValueType.equals('4')){
|
||||
/**
|
||||
* (d) Preference (user) - P|
|
||||
*/
|
||||
defStr = Env.getPreference(m_vo.ctx, m_vo.AD_Window_ID,
|
||||
m_vo.ColumnName, false);
|
||||
if (!defStr.equals("")) {
|
||||
if (log.isLoggable(Level.FINE))
|
||||
log.fine("[UserPreference] " + m_vo.ColumnName + "="
|
||||
+ defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
}else if (defaultValueType.equals('5')){
|
||||
/**
|
||||
* (e) Preference (System) - # $
|
||||
*/
|
||||
defStr = Env.getPreference(m_vo.ctx, m_vo.AD_Window_ID,
|
||||
m_vo.ColumnName, true);
|
||||
if (!defStr.equals("")) {
|
||||
if (log.isLoggable(Level.FINE))
|
||||
log.fine("[SystemPreference] " + m_vo.ColumnName + "="
|
||||
+ defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
}
|
||||
|
||||
if (defStr.equals("")){
|
||||
// try get preference apply for all process and current window
|
||||
defStr = Env.getPreference (m_vo.ctx, getAD_Window_ID_Of_Panel(), 0, 0, m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (defStr.equals("")){
|
||||
// try get preference apply for all window and this process
|
||||
defStr = Env.getPreference (m_vo.ctx, 0, 0, getAD_Process_ID_Of_Panel(), m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (defStr.equals("")){
|
||||
// try get preference apply for all process and all window
|
||||
defStr = Env.getPreference (m_vo.ctx, 0, 0, 0, m_vo.ColumnName);
|
||||
}
|
||||
|
||||
if (!defStr.equals("")){
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[Process Parameter Preference] " + m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
// <- End of suggested changes
|
||||
} else if (getAD_Infowindow_ID() > 0){
|
||||
defStr = Env.getPreference (m_vo.ctx, getAD_Window_ID_Of_Panel(), getAD_Infowindow_ID(), m_vo.ColumnName);
|
||||
if (!defStr.equals(""))
|
||||
{
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[Process Parameter Preference] " + m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* (d) Preference (user) - P|
|
||||
*/
|
||||
defStr = Env.getPreference (m_vo.ctx, m_vo.AD_Window_ID, m_vo.ColumnName, false);
|
||||
if (!defStr.equals(""))
|
||||
{
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[UserPreference] " + m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* (e) Preference (System) - # $
|
||||
*/
|
||||
defStr = Env.getPreference (m_vo.ctx, m_vo.AD_Window_ID, m_vo.ColumnName, true);
|
||||
if (!defStr.equals(""))
|
||||
{
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[SystemPreference] " + m_vo.ColumnName + "=" + defStr);
|
||||
return createDefault(defStr);
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object defaultFromDatatype (){
|
||||
/**
|
||||
* (f) DataType defaults
|
||||
*/
|
||||
|
||||
// Button to N
|
||||
if (m_vo.displayType == DisplayType.Button && !m_vo.ColumnName.endsWith("_ID"))
|
||||
{
|
||||
|
@ -762,12 +937,8 @@ public class GridField
|
|||
return createDefault("0");
|
||||
}
|
||||
|
||||
/**
|
||||
* No resolution
|
||||
*/
|
||||
if (log.isLoggable(Level.FINE)) log.fine("[NONE] " + m_vo.ColumnName);
|
||||
return null;
|
||||
} // getDefault
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Default Object type.
|
||||
|
|
|
@ -309,6 +309,19 @@ public interface I_AD_InfoColumn
|
|||
*/
|
||||
public boolean isIdentifier();
|
||||
|
||||
/** Column name IsKey */
|
||||
public static final String COLUMNNAME_IsKey = "IsKey";
|
||||
|
||||
/** Set Key column.
|
||||
* This column is the key in this table
|
||||
*/
|
||||
public void setIsKey (boolean IsKey);
|
||||
|
||||
/** Get Key column.
|
||||
* This column is the key in this table
|
||||
*/
|
||||
public boolean isKey();
|
||||
|
||||
/** Column name IsMandatory */
|
||||
public static final String COLUMNNAME_IsMandatory = "IsMandatory";
|
||||
|
||||
|
|
|
@ -232,6 +232,19 @@ public interface I_AD_InfoWindow
|
|||
*/
|
||||
public boolean isDistinct();
|
||||
|
||||
/** Column name isLoadPageNum */
|
||||
public static final String COLUMNNAME_isLoadPageNum = "isLoadPageNum";
|
||||
|
||||
/** Set Load Page Num.
|
||||
* When load data for info window, also load number of paging
|
||||
*/
|
||||
public void setisLoadPageNum (boolean isLoadPageNum);
|
||||
|
||||
/** Get Load Page Num.
|
||||
* When load data for info window, also load number of paging
|
||||
*/
|
||||
public boolean isLoadPageNum();
|
||||
|
||||
/** Column name IsShowInDashboard */
|
||||
public static final String COLUMNNAME_IsShowInDashboard = "IsShowInDashboard";
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.sql.ResultSet;
|
|||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.model.IInfoColumn;
|
||||
import org.compiere.model.AccessSqlParser.TableInfo;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Evaluatee;
|
||||
|
@ -31,7 +32,7 @@ import org.compiere.util.Evaluator;
|
|||
* @author Jorg Janke
|
||||
* @version $Id: MInfoColumn.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $
|
||||
*/
|
||||
public class MInfoColumn extends X_AD_InfoColumn
|
||||
public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn
|
||||
{
|
||||
/**
|
||||
*
|
||||
|
@ -176,4 +177,14 @@ public class MInfoColumn extends X_AD_InfoColumn
|
|||
getParent().saveEx(get_TrxName());
|
||||
return super.afterDelete(success);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInfoColumnID() {
|
||||
return get_ID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MInfoColumn getAD_InfoColumn() {
|
||||
return this;
|
||||
}
|
||||
} // MInfoColumn
|
||||
|
|
|
@ -42,7 +42,7 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2870394087507976203L;
|
||||
private static final long serialVersionUID = -8766810721578833704L;
|
||||
|
||||
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
|
||||
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
|
||||
|
@ -148,6 +148,7 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
public static final String ZK_FOOTER_SERVER_DATETIME_FORMAT = "ZK_FOOTER_SERVER_DATETIME_FORMAT";
|
||||
public static final String ZK_FOOTER_SERVER_MSG = "ZK_FOOTER_SERVER_MSG";
|
||||
public static final String ZK_GRID_EDIT_MODELESS = "ZK_GRID_EDIT_MODELESS";
|
||||
public static final String ZK_INFO_NUM_PAGE_PRELOAD = "ZK_INFO_NUM_PAGE_PRELOAD";
|
||||
public static final String ZK_LOGIN_ALLOW_REMEMBER_ME = "ZK_LOGIN_ALLOW_REMEMBER_ME";
|
||||
public static final String ZK_LOGO_LARGE = "ZK_LOGO_LARGE";
|
||||
public static final String ZK_LOGO_SMALL = "ZK_LOGO_SMALL";
|
||||
|
@ -157,6 +158,7 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
public static final String ZK_REPORT_JASPER_OUTPUT_TYPE = "ZK_REPORT_JASPER_OUTPUT_TYPE";
|
||||
public static final String ZK_REPORT_TABLE_OUTPUT_TYPE = "ZK_REPORT_TABLE_OUTPUT_TYPE";
|
||||
public static final String ZK_ROOT_FOLDER_BROWSER = "ZK_ROOT_FOLDER_BROWSER";
|
||||
public static final String ZK_SEQ_DEFAULT_VALUE_PANEL = "ZK_SEQ_DEFAULT_VALUE_PANEL";
|
||||
public static final String ZK_SESSION_TIMEOUT_IN_SECONDS = "ZK_SESSION_TIMEOUT_IN_SECONDS";
|
||||
public static final String ZK_THEME = "ZK_THEME";
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_InfoColumn extends PO implements I_AD_InfoColumn, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20141030L;
|
||||
private static final long serialVersionUID = 20141106L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_InfoColumn (Properties ctx, int AD_InfoColumn_ID, String trxName)
|
||||
|
@ -442,6 +442,30 @@ public class X_AD_InfoColumn extends PO implements I_AD_InfoColumn, I_Persistent
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Set Key column.
|
||||
@param IsKey
|
||||
This column is the key in this table
|
||||
*/
|
||||
public void setIsKey (boolean IsKey)
|
||||
{
|
||||
set_Value (COLUMNNAME_IsKey, Boolean.valueOf(IsKey));
|
||||
}
|
||||
|
||||
/** Get Key column.
|
||||
@return This column is the key in this table
|
||||
*/
|
||||
public boolean isKey ()
|
||||
{
|
||||
Object oo = get_Value(COLUMNNAME_IsKey);
|
||||
if (oo != null)
|
||||
{
|
||||
if (oo instanceof Boolean)
|
||||
return ((Boolean)oo).booleanValue();
|
||||
return "Y".equals(oo);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Set Mandatory.
|
||||
@param IsMandatory
|
||||
Data entry is required in this column
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_InfoWindow extends PO implements I_AD_InfoWindow, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20141030L;
|
||||
private static final long serialVersionUID = 20150809L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_InfoWindow (Properties ctx, int AD_InfoWindow_ID, String trxName)
|
||||
|
@ -311,6 +311,30 @@ public class X_AD_InfoWindow extends PO implements I_AD_InfoWindow, I_Persistent
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Set Load Page Num.
|
||||
@param isLoadPageNum
|
||||
When load data for info window, also load number of paging
|
||||
*/
|
||||
public void setisLoadPageNum (boolean isLoadPageNum)
|
||||
{
|
||||
set_Value (COLUMNNAME_isLoadPageNum, Boolean.valueOf(isLoadPageNum));
|
||||
}
|
||||
|
||||
/** Get Load Page Num.
|
||||
@return When load data for info window, also load number of paging
|
||||
*/
|
||||
public boolean isLoadPageNum ()
|
||||
{
|
||||
Object oo = get_Value(COLUMNNAME_isLoadPageNum);
|
||||
if (oo != null)
|
||||
{
|
||||
if (oo instanceof Boolean)
|
||||
return ((Boolean)oo).booleanValue();
|
||||
return "Y".equals(oo);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Set Show in Dashboard.
|
||||
@param IsShowInDashboard
|
||||
Show the dashlet in the dashboard
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2015 iDempiere *
|
||||
* Product: iDempiere ERP & CRM Smart Business Solution *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
|
||||
package org.idempiere.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class help for parse order configuration
|
||||
* example problem in IDEMPIERE-2296. some people wish priority of "default value" is higher than "user value preference"
|
||||
* some other wish reverse.
|
||||
* it's better for define 1 is representative for "default value" and 2 is representative for "user value preference"
|
||||
* in configuration just set 12 or 21 for order configuration.
|
||||
*
|
||||
* this class will help by provide method same in Iterable, it's also provider validate for duplicate value as 221 or 211
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public class ParseSeq implements Iterable<Character> {
|
||||
|
||||
public static String MSG_NOT_NULL = "configuration must is a not null or non empty string";
|
||||
public static String MSG_ONLY_NUNBER = "your value must contain only number character";
|
||||
public static String MSG_CONTAIN_DUP = "your value must contain non duplicate character";
|
||||
/**
|
||||
* init a Order configuration by parse configuration value,
|
||||
* configuration can contain duplicate value or contain only number
|
||||
* when detect wrong configuration value, a {@link IllegalArgumentException} will throw
|
||||
*
|
||||
* @param orderConfiguration configuration value as "5ry76t"
|
||||
* @param allowDupCharacter if false configuration value as "1245648" is wrong value by "4" is duplicate
|
||||
* @param onlyNumber configuration value contain only number
|
||||
*/
|
||||
private ParseSeq (String orderConfiguration, boolean allowDupCharacter, boolean onlyNumber){
|
||||
parseValue(orderConfiguration, allowDupCharacter, onlyNumber);
|
||||
this.orderConfiguration = orderConfiguration;
|
||||
}
|
||||
|
||||
private String orderConfiguration;
|
||||
|
||||
/**
|
||||
* pattern matching a string only number character
|
||||
*/
|
||||
private Pattern regCheckOnlyNumber = Pattern.compile("\\d+");
|
||||
/**
|
||||
* pattern find duplicate character in string
|
||||
*/
|
||||
private Pattern regCheckDupChar = Pattern.compile("(\\w).*\\1");
|
||||
|
||||
/**
|
||||
* validate input string
|
||||
* @param orderConfiguration
|
||||
* @param allowDupCharacter
|
||||
* @param onlyNumber
|
||||
*/
|
||||
protected void parseValue (String orderConfiguration, boolean allowDupCharacter, boolean onlyNumber){
|
||||
if (orderConfiguration == null || orderConfiguration.length() == 0)
|
||||
throw new IllegalArgumentException(MSG_NOT_NULL);
|
||||
|
||||
if (onlyNumber && !regCheckOnlyNumber.matcher(orderConfiguration).matches()){
|
||||
throw new IllegalArgumentException(MSG_ONLY_NUNBER);
|
||||
}
|
||||
|
||||
if (!allowDupCharacter && regCheckDupChar.matcher(orderConfiguration).find()){
|
||||
throw new IllegalArgumentException(MSG_CONTAIN_DUP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Character> iterator() {
|
||||
return new IteratorOrderUtil (orderConfiguration);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor maybe become complicate by add more validate (don't allow space, don't allow special,...)
|
||||
* use get for simple when init this object, don't need add try catch block when use
|
||||
* @param orderConfiguration
|
||||
* @return null when input string isn't suitable
|
||||
*/
|
||||
public static ParseSeq getNumberOrder (String orderConfiguration){
|
||||
ParseSeq numberOrder = null;
|
||||
try{
|
||||
numberOrder = new ParseSeq(orderConfiguration, false, true);
|
||||
}catch (IllegalArgumentException ex){
|
||||
return null;
|
||||
}
|
||||
|
||||
return numberOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* support class for iterator throw start to end of order
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public static class IteratorOrderUtil implements Iterator<Character>{
|
||||
private String orderConfiguration;
|
||||
int currentIndex = -1;
|
||||
public IteratorOrderUtil (String orderConfiguration){
|
||||
this.orderConfiguration = orderConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentIndex < orderConfiguration.length() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character next() {
|
||||
currentIndex++;
|
||||
return orderConfiguration.charAt(currentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* don't support this function
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Don't support this action");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* run test for utility
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
ParseSeq test = null;
|
||||
try{
|
||||
test = new ParseSeq ("e345", true, true);
|
||||
System.out.printf("Test for check only number case has non number:%s", false);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check only number case has non number:%1$s", MSG_ONLY_NUNBER.equals(ex.getMessage()));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("345", true, true);
|
||||
System.out.printf("Test for check only number case normal:%1$s", true);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check only number case normal:%1$s", false);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("3545", true, true);
|
||||
System.out.printf("Test for check dup character case allow:%1$s", true);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check dup character case allow:%1$s", false);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("3afa5", true, false);
|
||||
System.out.printf("Test for check dup character case allow:%1$s", true);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check dup character case allow:%1$s", false);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("3545", false, false);
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", false);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", MSG_CONTAIN_DUP.equals(ex.getMessage()));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("3afa5", false, false);
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", false);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", MSG_CONTAIN_DUP.equals(ex.getMessage()));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
try{
|
||||
test = new ParseSeq ("3sfa5", false, false);
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", true);
|
||||
System.out.println();
|
||||
}catch (IllegalArgumentException ex){
|
||||
System.out.printf("Test for check dup character case disallow:%1$s", false);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
test = ParseSeq.getNumberOrder("4567289");
|
||||
System.out.printf("travel configuration:%1$s", "4567289");
|
||||
System.out.println();
|
||||
|
||||
for (Character ch : test){
|
||||
System.out.print(ch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -331,7 +331,7 @@ public class ProcessParameter extends CDialog
|
|||
// MField => VEditor - New Field value to be updated to editor
|
||||
mField.addPropertyChangeListener(vEditor);
|
||||
// Set Default
|
||||
Object defaultObject = mField.getDefault();
|
||||
Object defaultObject = mField.getDefaultForPanel();
|
||||
mField.setValue (defaultObject, true);
|
||||
//
|
||||
centerPanel.add ((Component)vEditor, gbc);
|
||||
|
@ -360,7 +360,7 @@ public class ProcessParameter extends CDialog
|
|||
// New Field value to be updated to editor
|
||||
mField2.addPropertyChangeListener(vEditor2);
|
||||
// Set Default
|
||||
Object defaultObject2 = mField2.getDefault();
|
||||
Object defaultObject2 = mField2.getDefaultForPanel();
|
||||
mField2.setValue (defaultObject2, true);
|
||||
//
|
||||
centerPanel.add ((Component)vEditor2, gbc);
|
||||
|
|
|
@ -326,7 +326,7 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe
|
|||
centerPanel.add ((Component)vEditor, gbc);
|
||||
m_vEditors.add (vEditor); // add to Editors
|
||||
// Set Default
|
||||
Object defaultObject = mField.getDefault();
|
||||
Object defaultObject = mField.getDefaultForPanel();
|
||||
mField.setValue (defaultObject, true);
|
||||
//
|
||||
if (voF.isRange)
|
||||
|
@ -356,7 +356,7 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe
|
|||
centerPanel.add ((Component)vEditor2, gbc);
|
||||
m_vEditors2.add (vEditor2);
|
||||
// Set Default
|
||||
Object defaultObject2 = mField2.getDefault();
|
||||
Object defaultObject2 = mField2.getDefaultForPanel();
|
||||
mField2.setValue (defaultObject2, true);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.adempiere.webui.adwindow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -35,9 +34,7 @@ import org.compiere.model.MToolBarButton;
|
|||
import org.compiere.model.MToolBarButtonRestrict;
|
||||
import org.compiere.model.MWindow;
|
||||
import org.compiere.model.X_AD_ToolBarButton;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.Env;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
|
||||
/**
|
||||
|
@ -60,8 +57,6 @@ public class ADWindow extends AbstractUIPart
|
|||
private Component windowPanelComponent;
|
||||
private MImage image;
|
||||
|
||||
private static final CCache<Integer, AImage> imageCache = new CCache<Integer, AImage>(null, "WindowImageCache", 5, false);
|
||||
|
||||
private Map<Integer, List<String>> tabToolbarRestricMap = new HashMap<Integer, List<String>>();
|
||||
|
||||
private List<String> windowToolbarRestrictList = null;
|
||||
|
@ -129,23 +124,6 @@ public class ADWindow extends AbstractUIPart
|
|||
return image;
|
||||
}
|
||||
|
||||
public AImage getAImage() throws IOException {
|
||||
MImage image = getMImage();
|
||||
AImage aImage = null;
|
||||
if (image != null) {
|
||||
synchronized (imageCache) {
|
||||
aImage = imageCache.get(image.getAD_Image_ID());
|
||||
}
|
||||
if (aImage == null) {
|
||||
aImage = new AImage(image.getName(), image.getData());
|
||||
synchronized (imageCache) {
|
||||
imageCache.put(image.getAD_Image_ID(), aImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aImage;
|
||||
}
|
||||
|
||||
protected Component doCreatePart(Component parent)
|
||||
{
|
||||
windowPanelComponent = windowContent.createPart(parent);
|
||||
|
|
|
@ -287,7 +287,7 @@ public class ProcessParameterPanel extends Panel implements
|
|||
// MField => VEditor - New Field value to be updated to editor
|
||||
mField.addPropertyChangeListener(editor);
|
||||
// Set Default
|
||||
Object defaultObject = mField.getDefault();
|
||||
Object defaultObject = mField.getDefaultForPanel();
|
||||
mField.setValue(defaultObject, true);
|
||||
// streach component to fill grid cell
|
||||
editor.fillHorizontal();
|
||||
|
@ -349,7 +349,7 @@ public class ProcessParameterPanel extends Panel implements
|
|||
this.appendChild(popupMenu);
|
||||
}
|
||||
// Set Default
|
||||
Object defaultObject2 = mField2.getDefault();
|
||||
Object defaultObject2 = mField2.getDefaultForPanel();
|
||||
mField2.setValue(defaultObject2, true);
|
||||
//
|
||||
m_wEditors2.add(editor2);
|
||||
|
|
|
@ -203,6 +203,7 @@ public class WAllocation extends Allocation
|
|||
row.appendCellChild(bpartnerLabel.rightAlign());
|
||||
bpartnerSearch.getComponent().setHflex("true");
|
||||
row.appendCellChild(bpartnerSearch.getComponent(),2);
|
||||
bpartnerSearch.showMenu();
|
||||
Hbox box = new Hbox();
|
||||
box.appendChild(dateLabel.rightAlign());
|
||||
box.appendChild(dateField.getComponent());
|
||||
|
@ -210,11 +211,13 @@ public class WAllocation extends Allocation
|
|||
row.appendCellChild(organizationLabel.rightAlign());
|
||||
organizationPick.getComponent().setHflex("true");
|
||||
row.appendCellChild(organizationPick.getComponent(),1);
|
||||
organizationPick.showMenu();
|
||||
|
||||
row = rows.newRow();
|
||||
row.appendCellChild(currencyLabel.rightAlign(),1);
|
||||
currencyPick.getComponent().setHflex("true");
|
||||
row.appendCellChild(currencyPick.getComponent(),1);
|
||||
currencyPick.showMenu();
|
||||
row.appendCellChild(multiCurrency,1);
|
||||
row.appendCellChild(autoWriteOff,2);
|
||||
row.appendCellChild(new Space(),1);
|
||||
|
@ -236,8 +239,10 @@ public class WAllocation extends Allocation
|
|||
chargePick.getComponent().setHflex("true");
|
||||
row.appendCellChild(chargePick.getComponent());
|
||||
row.appendCellChild(DocTypeLabel.rightAlign());
|
||||
chargePick.showMenu();
|
||||
DocTypePick.getComponent().setHflex("true");
|
||||
row.appendCellChild(DocTypePick.getComponent());
|
||||
DocTypePick.showMenu();
|
||||
allocateButton.setHflex("true");
|
||||
row.appendCellChild(allocateButton);
|
||||
row.appendCellChild(refreshButton);
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
|
||||
package org.adempiere.webui.component;
|
||||
|
||||
import org.adempiere.webui.adwindow.ADWindow;
|
||||
import org.adempiere.webui.util.ManageImageCache;
|
||||
import org.compiere.model.MImage;
|
||||
import org.compiere.model.MInfoWindow;
|
||||
import org.zkoss.image.Image;
|
||||
import org.zkoss.zul.impl.LabelImageElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||
|
@ -25,10 +32,10 @@ package org.adempiere.webui.component;
|
|||
*/
|
||||
public class Tab extends org.zkoss.zul.Tab
|
||||
{
|
||||
/**
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -550172446768384271L;
|
||||
private static final long serialVersionUID = -5146887728183695020L;
|
||||
|
||||
public Tab(String str)
|
||||
{
|
||||
|
@ -38,6 +45,11 @@ public class Tab extends org.zkoss.zul.Tab
|
|||
public Tab()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void setDecorateInfo (DecorateInfo decorateInfo){
|
||||
if (decorateInfo != null)
|
||||
decorateInfo.decorate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,4 +60,50 @@ public class Tab extends org.zkoss.zul.Tab
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* class contain decorate info
|
||||
* at the moment, has only image info
|
||||
* at the moment, it's use to transfer decorate info from info window, standard window, report, process,... to tab
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public static class DecorateInfo {
|
||||
private String imageKey;
|
||||
private String imageIntenalUrl;
|
||||
|
||||
public void decorate (LabelImageElement comp){
|
||||
if (imageIntenalUrl != null)
|
||||
comp.setImage(imageIntenalUrl);
|
||||
else if (imageKey != null){
|
||||
Image ico = ManageImageCache.instance().getImage(imageKey);
|
||||
if (ico != null)
|
||||
comp.setImageContent(ico);
|
||||
}
|
||||
}
|
||||
|
||||
public DecorateInfo (MImage imageData){
|
||||
imageIntenalUrl = ManageImageCache.getImageInternalUrl(imageData);
|
||||
if (imageIntenalUrl == null)
|
||||
imageKey = ManageImageCache.instance().loadImage(imageData);
|
||||
}
|
||||
|
||||
public DecorateInfo (String imagePath){
|
||||
imageIntenalUrl = ManageImageCache.getImageInternalUrl(imagePath);
|
||||
if (imageIntenalUrl == null)
|
||||
imageKey = imagePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for create decorate info from adWindow info
|
||||
* @param adWindow
|
||||
* @return
|
||||
*/
|
||||
public static DecorateInfo get (ADWindow adWindow){
|
||||
return adWindow == null?null:new DecorateInfo(adWindow.getMImage());
|
||||
}
|
||||
|
||||
public static DecorateInfo get (MInfoWindow mInfo){
|
||||
return mInfo==null?null:new DecorateInfo(mInfo.getImageURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
windowContainer.createPart(windowArea);
|
||||
|
||||
homeTab = new Tabpanel();
|
||||
windowContainer.addWindow(homeTab, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")), false);
|
||||
windowContainer.addWindow(homeTab, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")), false, null);
|
||||
homeTab.getLinkedTab().setSclass("desktop-hometab");
|
||||
homeTab.setSclass("desktop-home-tabpanel");
|
||||
BusyDialog busyDialog = new BusyDialog();
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
*****************************************************************************/
|
||||
package org.adempiere.webui.desktop;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.adempiere.util.Callback;
|
||||
|
@ -22,6 +21,7 @@ import org.adempiere.webui.adwindow.ADWindow;
|
|||
import org.adempiere.webui.apps.ProcessDialog;
|
||||
import org.adempiere.webui.apps.wf.WFPanel;
|
||||
import org.adempiere.webui.component.DesktopTabpanel;
|
||||
import org.adempiere.webui.component.Tab.DecorateInfo;
|
||||
import org.adempiere.webui.component.Tabbox;
|
||||
import org.adempiere.webui.component.Tabpanel;
|
||||
import org.adempiere.webui.component.Window;
|
||||
|
@ -32,11 +32,11 @@ import org.adempiere.webui.panel.InfoPanel;
|
|||
import org.adempiere.webui.part.WindowContainer;
|
||||
import org.adempiere.webui.window.FDialog;
|
||||
import org.adempiere.webui.window.WTask;
|
||||
import org.compiere.model.MInfoWindow;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.model.MTask;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.util.media.AMedia;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
|
@ -73,7 +73,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
String title = pd.getTitle();
|
||||
pd.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, null);
|
||||
Events.postEvent(ProcessDialog.ON_INITIAL_FOCUS_EVENT, pd, null);
|
||||
}
|
||||
return pd;
|
||||
|
@ -93,7 +93,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
//do not show window title when open as tab
|
||||
form.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, form.getFormName(), true);
|
||||
windowContainer.addWindow(tabPanel, form.getFormName(), true, null);
|
||||
form.focus();
|
||||
} else {
|
||||
form.setAttribute(Window.MODE_KEY, form.getWindowMode());
|
||||
|
@ -117,7 +117,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
String title = infoPanel.getTitle();
|
||||
infoPanel.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, DecorateInfo.get(MInfoWindow.get(infoId, null)));
|
||||
infoPanel.focus();
|
||||
} else {
|
||||
FDialog.error(0, "NotValid");
|
||||
|
@ -135,7 +135,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
p.setParent(tabPanel);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, p.getWorkflow().get_Translation(MWorkflow.COLUMNNAME_Name), true);
|
||||
windowContainer.addWindow(tabPanel, p.getWorkflow().get_Translation(MWorkflow.COLUMNNAME_Name), true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,7 +160,8 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
final DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
String id = AdempiereIdGenerator.escapeId(adWindow.getTitle());
|
||||
tabPanel.setId(id+"_"+adWindow.getADWindowContent().getWindowNo());
|
||||
final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true);
|
||||
final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true, DecorateInfo.get(adWindow));
|
||||
|
||||
tab.setClosable(false);
|
||||
final OpenWindowRunnable runnable = new OpenWindowRunnable(adWindow, tab, tabPanel, callback);
|
||||
preOpenNewTab();
|
||||
|
@ -233,7 +234,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
Tabpanel tabPanel = new Tabpanel();
|
||||
window.setParent(tabPanel);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, closeable);
|
||||
windowContainer.addWindow(tabPanel, title, closeable, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +246,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
final ADWindow wnd = new ADWindow(Env.getCtx(), AD_Window_ID, query);
|
||||
|
||||
final DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
final Tab tab = windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true);
|
||||
final Tab tab = windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true, DecorateInfo.get(wnd));
|
||||
tab.setClosable(false);
|
||||
final OpenWindowRunnable runnable = new OpenWindowRunnable(wnd, tab, tabPanel, null);
|
||||
preOpenNewTab();
|
||||
|
@ -277,9 +278,9 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
window.setTitle(null);
|
||||
preOpenNewTab();
|
||||
if (Window.INSERT_NEXT.equals(window.getAttribute(Window.INSERT_POSITION_KEY)))
|
||||
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, title, true, true);
|
||||
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, title, true, true, null);
|
||||
else
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, null);
|
||||
if (window instanceof IHelpContext)
|
||||
Events.sendEvent(new Event(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, window));
|
||||
}
|
||||
|
@ -381,13 +382,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
public void run() {
|
||||
if (adWindow.createPart(tabPanel) != null ) {
|
||||
tab.setClosable(true);
|
||||
if (adWindow.getMImage() != null) {
|
||||
try {
|
||||
AImage aImage = adWindow.getAImage();
|
||||
tab.setImageContent(aImage);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.onCallback(adWindow);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public abstract class WEditor implements EventListener<Event>, PropertyChangeLis
|
|||
this.component.getParent().appendChild(popupMenu);
|
||||
|
||||
// when field have label, add action zoom when click to label, and show menu when right click to label
|
||||
if (!gridField.isFieldOnly())
|
||||
if (!readOnly)
|
||||
{
|
||||
if (popupMenu.isZoomEnabled() && this instanceof IZoomableEditor)
|
||||
{
|
||||
|
|
|
@ -174,19 +174,20 @@ ContextMenuListener, IZoomableEditor
|
|||
refreshList();
|
||||
}
|
||||
|
||||
String tableName_temp = lookup.getColumnName(); // Returns AD_Org.AD_Org_ID
|
||||
int posPoint = tableName_temp.indexOf(".");
|
||||
String tableName = tableName_temp.substring(0, posPoint);
|
||||
|
||||
if (tableName.toUpperCase().equals("C_BPARTNER_LOCATION"))
|
||||
{
|
||||
popupMenu = new WEditorPopupMenu(true, true, isShowPreference(), false, false, true, lookup);
|
||||
} else {
|
||||
popupMenu = new WEditorPopupMenu(zoom, true, isShowPreference(), false, false, false, lookup);
|
||||
}
|
||||
addChangeLogMenu(popupMenu);
|
||||
|
||||
if (gridField != null)
|
||||
{
|
||||
String tableName_temp = lookup.getColumnName(); // Returns AD_Org.AD_Org_ID
|
||||
int posPoint = tableName_temp.indexOf(".");
|
||||
String tableName = tableName_temp.substring(0, posPoint);
|
||||
if (tableName.toUpperCase().equals("C_BPARTNER_LOCATION"))
|
||||
{
|
||||
popupMenu = new WEditorPopupMenu(true, true, isShowPreference(), false, false, true, lookup);
|
||||
} else {
|
||||
popupMenu = new WEditorPopupMenu(zoom, true, isShowPreference(), false, false, false, lookup);
|
||||
}
|
||||
addChangeLogMenu(popupMenu);
|
||||
|
||||
// IDEMPIERE 90
|
||||
boolean isShortListAvailable = false; // Short List available for this lookup
|
||||
if (lookup != null && (lookup.getDisplayType() == DisplayType.TableDir || lookup.getDisplayType() == DisplayType.Table)) // only for Table & TableDir
|
||||
|
|
|
@ -63,7 +63,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -949213040088881469L;
|
||||
private static final long serialVersionUID = 6033101081045706748L;
|
||||
|
||||
public static final String QUICK_ENTRY_MODE = "_QUICK_ENTRY_MODE_";
|
||||
|
||||
|
@ -87,6 +87,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
|
|||
|
||||
private int m_AD_Window_ID;
|
||||
|
||||
private boolean isHasField = false;
|
||||
/**
|
||||
* Constructor.
|
||||
* Requires call loadRecord
|
||||
|
@ -180,7 +181,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
|
|||
if (! quickTabs.contains(gridtab)) {
|
||||
quickTabs.add(gridtab);
|
||||
}
|
||||
|
||||
isHasField = true;
|
||||
newTab = false;
|
||||
}
|
||||
}
|
||||
|
@ -230,6 +231,15 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
|
|||
centerPanel.appendChild(layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* check table is editable in quick entry
|
||||
* user must has write right and has at least a input field
|
||||
* @return
|
||||
*/
|
||||
public boolean isAvailableQuickEdit (){
|
||||
return isHasField && !m_readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Record_ID
|
||||
* @param Record_ID - existing Record or 0 for new
|
||||
|
@ -446,7 +456,7 @@ public class WQuickEntry extends Window implements EventListener<Event>, ValueCh
|
|||
|
||||
public int getRecord_ID()
|
||||
{
|
||||
if (quickPOs.get(0) == null)
|
||||
if (quickPOs.isEmpty() || quickPOs.get(0) == null)
|
||||
return 0;
|
||||
|
||||
return quickPOs.get(0).get_ID();
|
||||
|
|
|
@ -873,5 +873,29 @@ public class InfoProductWindow extends InfoWindow {
|
|||
m_PAttributeButton.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateSubcontent() {
|
||||
super.updateSubcontent();
|
||||
int row = contentPanel.getSelectedRow();
|
||||
if (row < 0){
|
||||
if (warehouseTbl != null && warehouseTbl.getModel() != null)
|
||||
warehouseTbl.getModel().clear();
|
||||
|
||||
if (substituteTbl != null && substituteTbl.getModel() != null)
|
||||
substituteTbl.getModel().clear();
|
||||
|
||||
if (relatedTbl != null && relatedTbl.getModel() != null)
|
||||
relatedTbl.getModel().clear();
|
||||
|
||||
if (m_tableAtp != null && m_tableAtp.getModel() != null)
|
||||
m_tableAtp.getModel().clear();
|
||||
|
||||
if (productpriceTbl != null && productpriceTbl.getModel() != null)
|
||||
productpriceTbl.getModel().clear();
|
||||
|
||||
if (fieldDescription != null)
|
||||
fieldDescription.setText("");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ import org.adempiere.model.IInfoColumn;
|
|||
import org.adempiere.model.MInfoProcess;
|
||||
import org.adempiere.model.MInfoRelated;
|
||||
import org.adempiere.webui.AdempiereWebUI;
|
||||
import org.adempiere.webui.ISupportMask;
|
||||
import org.adempiere.webui.LayoutUtils;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.component.Borderlayout;
|
||||
import org.adempiere.webui.component.Button;
|
||||
|
@ -43,8 +45,10 @@ import org.adempiere.webui.editor.WEditor;
|
|||
import org.adempiere.webui.editor.WSearchEditor;
|
||||
import org.adempiere.webui.editor.WTableDirEditor;
|
||||
import org.adempiere.webui.editor.WebEditorFactory;
|
||||
import org.adempiere.webui.event.DialogEvents;
|
||||
import org.adempiere.webui.event.ValueChangeEvent;
|
||||
import org.adempiere.webui.event.ValueChangeListener;
|
||||
import org.adempiere.webui.grid.WQuickEntry;
|
||||
import org.adempiere.webui.panel.InfoPanel;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.adempiere.webui.theme.ThemeManager;
|
||||
|
@ -56,6 +60,7 @@ import org.compiere.model.AccessSqlParser;
|
|||
import org.compiere.model.AccessSqlParser.TableInfo;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.GridFieldVO;
|
||||
import org.compiere.model.GridWindow;
|
||||
import org.compiere.model.MInfoColumn;
|
||||
import org.compiere.model.MInfoWindow;
|
||||
import org.compiere.model.MLookupFactory;
|
||||
|
@ -71,12 +76,14 @@ import org.compiere.util.KeyNamePair;
|
|||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
import org.compiere.util.ValueNamePair;
|
||||
import org.zkoss.zk.au.out.AuEcho;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
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.SwipeEvent;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
import org.zkoss.zul.Center;
|
||||
import org.zkoss.zul.Checkbox;
|
||||
import org.zkoss.zul.Comboitem;
|
||||
|
@ -97,11 +104,11 @@ import org.zkoss.zul.Vbox;
|
|||
* @contributor xolali IDEMPIERE-1045 Sub-Info Tabs (reviewed by red1)
|
||||
*/
|
||||
public class InfoWindow extends InfoPanel implements ValueChangeListener, EventListener<Event> {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3538308098379400144L;
|
||||
|
||||
private static final long serialVersionUID = 8358292103127594383L;
|
||||
protected Grid parameterGrid;
|
||||
private Borderlayout layout;
|
||||
private Vbox southBody;
|
||||
|
@ -118,14 +125,14 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
public static final int FIELDLENGTH = 20;
|
||||
|
||||
protected ColumnInfo[] columnInfos;
|
||||
protected MInfoWindow infoWindow;
|
||||
protected TableInfo[] tableInfos;
|
||||
protected MInfoColumn[] infoColumns;
|
||||
protected String queryValue;
|
||||
protected WQuickEntry vqe;
|
||||
|
||||
private List<GridField> gridFields;
|
||||
private int AD_InfoWindow_ID;
|
||||
private Checkbox checkAND;
|
||||
|
||||
/**
|
||||
* Menu contail process menu item
|
||||
*/
|
||||
|
@ -167,24 +174,14 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
public InfoWindow(int WindowNo, String tableName, String keyColumn, String queryValue,
|
||||
boolean multipleSelection, String whereClause, int AD_InfoWindow_ID, boolean lookup, GridField field) {
|
||||
super(WindowNo, tableName, keyColumn, multipleSelection, whereClause,
|
||||
lookup);
|
||||
lookup, AD_InfoWindow_ID);
|
||||
this.m_gridfield = field;
|
||||
this.queryValue = queryValue;
|
||||
this.AD_InfoWindow_ID = AD_InfoWindow_ID;
|
||||
|
||||
//Xolali IDEMPIERE-1045
|
||||
contentPanel.addActionListener(new EventListener<Event>() {
|
||||
public void onEvent(Event event) throws Exception {
|
||||
int row = contentPanel.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
for (EmbedWinInfo embed : embeddedWinList) {
|
||||
int indexData = 0;
|
||||
if (columnDataIndex.containsKey(embed.getParentLinkColumnID())){
|
||||
indexData = p_layout.length + columnDataIndex.get(embed.getParentLinkColumnID());
|
||||
}
|
||||
refresh(contentPanel.getValueAt(row,indexData),embed);
|
||||
}// refresh for all
|
||||
}
|
||||
updateSubcontent();
|
||||
}
|
||||
}); //xolali --end-
|
||||
|
||||
|
@ -214,6 +211,30 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
processQueryValue();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void updateSubcontent (){
|
||||
int row = contentPanel.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
for (EmbedWinInfo embed : embeddedWinList) {
|
||||
// default link column is key column
|
||||
int indexData = 0;
|
||||
if (columnDataIndex.containsKey(embed.getParentLinkColumnID())){
|
||||
// get index of link column
|
||||
indexData = p_layout.length + columnDataIndex.get(embed.getParentLinkColumnID());
|
||||
}
|
||||
refresh(contentPanel.getValueAt(row,indexData),embed);
|
||||
}// refresh for all
|
||||
}else{
|
||||
for (EmbedWinInfo embed : embeddedWinList) {
|
||||
refresh(embed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -457,24 +478,29 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
isQueryByUser = false;
|
||||
}
|
||||
|
||||
protected boolean loadInfoDefinition() {
|
||||
String tableName = null;
|
||||
if (AD_InfoWindow_ID > 0) {
|
||||
infoWindow = new MInfoWindow(Env.getCtx(), AD_InfoWindow_ID, null);
|
||||
if (!infoWindow.isValid()) {
|
||||
infoWindow = null;
|
||||
} else {
|
||||
tableName = MTable.getTableName(Env.getCtx(), infoWindow.getAD_Table_ID());
|
||||
if (!tableName.equalsIgnoreCase(p_tableName)) {
|
||||
throw new IllegalArgumentException("AD_InfoWindow.TableName <> TableName argument. ("+tableName + " <> " + p_tableName+")");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@Override
|
||||
protected void loadInfoWindowData (){
|
||||
if (m_infoWindowID > 0) {
|
||||
infoWindow = new MInfoWindow(Env.getCtx(), m_infoWindowID, null);
|
||||
}else {
|
||||
infoWindow = MInfoWindow.get(p_tableName, (String)null);
|
||||
}
|
||||
|
||||
if (infoWindow == null)
|
||||
return;
|
||||
if (!infoWindow.isValid()) {
|
||||
infoWindow = null;
|
||||
} else {
|
||||
String tableName = MTable.getTableName(Env.getCtx(), infoWindow.getAD_Table_ID());
|
||||
if (!tableName.equalsIgnoreCase(p_tableName)) {
|
||||
throw new IllegalArgumentException("AD_InfoWindow.TableName <> TableName argument. ("+tableName + " <> " + p_tableName+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean loadInfoDefinition() {
|
||||
if (infoWindow != null) {
|
||||
if (tableName == null)
|
||||
String tableName = null;
|
||||
tableName = MTable.getTableName(Env.getCtx(), infoWindow.getAD_Table_ID());
|
||||
|
||||
AccessSqlParser sqlParser = new AccessSqlParser("SELECT * FROM " + infoWindow.getFromClause());
|
||||
|
@ -489,7 +515,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
infoColumns = infoWindow.getInfoColumns(tableInfos);
|
||||
|
||||
gridFields = new ArrayList<GridField>();
|
||||
|
||||
for(MInfoColumn infoColumn : infoColumns) {
|
||||
if (infoColumn.isKey())
|
||||
keyColumnOfView = infoColumn;
|
||||
String columnName = infoColumn.getColumnName();
|
||||
/*!m_lookup && infoColumn.isMandatory():apply Mandatory only case open as window and only for criteria field*/
|
||||
boolean isMandatory = !m_lookup && infoColumn.isMandatory() && infoColumn.isQueryCriteria();
|
||||
|
@ -669,10 +698,20 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
columnInfo.setColDescription(infoColumn.get_Translation("Description"));
|
||||
columnInfo.setGridField(gridFields.get(i));
|
||||
list.add(columnInfo);
|
||||
|
||||
if (keyColumnOfView == infoColumn){
|
||||
if (columnInfo.getColClass().equals(IDColumn.class))
|
||||
isIDColumnKeyOfView = true;
|
||||
indexKeyOfView = list.size() - 1;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (keyColumnOfView == null){
|
||||
isIDColumnKeyOfView = true;// because use main key
|
||||
}
|
||||
|
||||
columnInfos = list.toArray(new ColumnInfo[0]);
|
||||
|
||||
prepareTable(columnInfos, infoWindow.getFromClause(), p_whereClause, infoWindow.getOrderByClause());
|
||||
|
@ -956,7 +995,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
}
|
||||
|
||||
addViewIDToQuery();
|
||||
|
||||
addKeyViewToQuery();
|
||||
|
||||
if (m_sqlMain.length() > 0 && infoWindow.isDistinct()) {
|
||||
m_sqlMain = m_sqlMain.substring("SELECT ".length());
|
||||
|
@ -981,6 +1020,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
m_sqlMain = addMoreColumnToQuery (m_sqlMain, infoProcessList);
|
||||
}
|
||||
|
||||
/**
|
||||
* if {@link #keyColumnOfView} not null and not display, add query to query it's value
|
||||
*/
|
||||
protected void addKeyViewToQuery () {
|
||||
if (isNeedAppendKeyViewData()){
|
||||
m_sqlMain = addMoreColumnToQuery (m_sqlMain, new IInfoColumn [] {keyColumnOfView});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNeedAppendKeyViewData() {
|
||||
return (keyColumnOfView != null && !keyColumnOfView.isDisplayed(infoContext, p_WindowNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* because data of infoColumn have isDisplay = false not load,
|
||||
|
@ -1290,10 +1342,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
|
||||
mField.addPropertyChangeListener(editor);
|
||||
|
||||
if (!Util.isEmpty(mField.getVO().DefaultValue, true)) {
|
||||
// set default value
|
||||
mField.setValue(mField.getDefault(), true);
|
||||
}
|
||||
mField.setValue(mField.getDefaultForPanel(), true);
|
||||
|
||||
} // addSelectionColumn
|
||||
|
||||
protected void addSearchParameter(Label label, Component fieldEditor) {
|
||||
|
@ -1547,7 +1597,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
boolean isParameterChange = isParameteChangeValue();
|
||||
// when change parameter, also requery
|
||||
if (isParameterChange){
|
||||
onUserQuery();
|
||||
if (!isQueryByUser)
|
||||
onUserQuery();
|
||||
}else if (m_lookup && contentPanel.getSelectedIndex() >= 0){
|
||||
// do nothing when parameter not change and at window mode, or at dialog mode but select non record
|
||||
onOk();
|
||||
|
@ -1580,7 +1631,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
// just reset to default Field set explicit DefaultValue
|
||||
Object resetValue = null;
|
||||
if (! Util.isEmpty(gField.getVO().DefaultValue, true)) {
|
||||
resetValue = gField.getDefault();
|
||||
resetValue = gField.getDefaultForPanel();
|
||||
}
|
||||
Object oldValue = gField.getValue();
|
||||
gField.setValue(resetValue, true);
|
||||
|
@ -1805,6 +1856,15 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
}
|
||||
} // refresh
|
||||
|
||||
protected void refresh(EmbedWinInfo relatedInfo){
|
||||
if (relatedInfo.getInfoTbl() != null){
|
||||
if (((WListbox)relatedInfo.getInfoTbl()).getModel() != null)
|
||||
((WListbox)relatedInfo.getInfoTbl()).getModel().clear();
|
||||
else
|
||||
((WListbox)relatedInfo.getInfoTbl()).clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author xolali IDEMPIERE-1045
|
||||
* loadEmbedded(ResultSet rs, EmbedWinInfo info)
|
||||
|
@ -1843,7 +1903,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
*/
|
||||
protected GridField getGridField(MInfoColumn infoColumn){
|
||||
String columnName = infoColumn.getColumnName();
|
||||
GridFieldVO vo = GridFieldVO.createParameter(infoContext, p_WindowNo, AEnv.getADWindowID(p_WindowNo), AD_InfoWindow_ID, 0,
|
||||
GridFieldVO vo = GridFieldVO.createParameter(infoContext, p_WindowNo, AEnv.getADWindowID(p_WindowNo), m_infoWindowID, 0,
|
||||
columnName, infoColumn.get_Translation("Name"), infoColumn.getAD_Reference_ID(),
|
||||
infoColumn.getAD_Reference_Value_ID(), false, false);
|
||||
if (infoColumn.getAD_Val_Rule_ID() > 0) {
|
||||
|
@ -1984,4 +2044,57 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasNew() {
|
||||
boolean hasNew = getADWindowID () > 0;
|
||||
if (hasNew && vqe == null && hasRightQuickEntry){
|
||||
GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID());
|
||||
hasRightQuickEntry = gridwindow != null;
|
||||
if (hasRightQuickEntry)
|
||||
vqe = new WQuickEntry (0, getADWindowID());
|
||||
}
|
||||
|
||||
return hasNew && vqe != null && vqe.isAvailableQuickEdit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id of window link with main table of this info window
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
protected int getADWindowID() {
|
||||
if(infoWindow == null)
|
||||
return 0;
|
||||
String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx");
|
||||
if (!isLookup() && Util.isEmpty(isSOTrx)) {
|
||||
isSOTrx = "Y";
|
||||
}
|
||||
|
||||
return super.getAD_Window_ID(MTable.getTableName(Env.getCtx(), infoWindow.getAD_Table_ID()), isSOTrx.equalsIgnoreCase("Y"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void newRecordAction() {
|
||||
// each time close WQuickEntry dialog,
|
||||
// window is un-registry, variable environment of this window as _QUICK_ENTRY_MODE_ is removed
|
||||
// so if reuse WQuickEntry will let some field in child tab init at read only state
|
||||
WQuickEntry vqe = new WQuickEntry (0, getADWindowID());
|
||||
|
||||
vqe.loadRecord (0);
|
||||
|
||||
final ISupportMask parent = LayoutUtils.showWindowWithMask(vqe, this, LayoutUtils.OVERLAP_TAB_PANEL);
|
||||
|
||||
vqe.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
Clients.response(new AuEcho(InfoWindow.this, "onQueryCallback", null));
|
||||
if (parent != null)
|
||||
parent.hideMask();
|
||||
}
|
||||
});
|
||||
|
||||
vqe.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -181,12 +181,12 @@ public abstract class AbstractMenuPanel extends Panel implements EventListener<E
|
|||
}
|
||||
else if (mChildNode.isForm())
|
||||
{
|
||||
link.setImage(ThemeManager.getThemeResource("images/mWindow.png"));
|
||||
link.setImage(ThemeManager.getThemeResource("images/mForm.png"));
|
||||
treeitem.setAttribute("menu.type", "form");
|
||||
}
|
||||
else if (mChildNode.isInfo())
|
||||
{
|
||||
link.setImage(ThemeManager.getThemeResource("images/mWindow.png"));
|
||||
link.setImage(ThemeManager.getThemeResource("images/mInfo.png"));
|
||||
treeitem.setAttribute("menu.type", "info");
|
||||
}
|
||||
else // Window
|
||||
|
|
|
@ -30,9 +30,11 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.model.IInfoColumn;
|
||||
import org.adempiere.model.MInfoProcess;
|
||||
import org.adempiere.model.MInfoRelated;
|
||||
|
@ -94,6 +96,7 @@ import org.zkoss.zul.Listheader;
|
|||
import org.zkoss.zul.Listitem;
|
||||
import org.zkoss.zul.Menuitem;
|
||||
import org.zkoss.zul.Paging;
|
||||
import org.zkoss.zul.event.PagingEvent;
|
||||
import org.zkoss.zul.event.ZulEvents;
|
||||
import org.zkoss.zul.ext.Sortable;
|
||||
|
||||
|
@ -114,18 +117,58 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 965821837109028155L;
|
||||
|
||||
private static final long serialVersionUID = 3761627143274259211L;
|
||||
private final static int DEFAULT_PAGE_SIZE = 100;
|
||||
private final static int DEFAULT_PAGE_PRELOAD = 4;
|
||||
protected List<Button> btProcessList = new ArrayList<Button>();
|
||||
protected Map<String, WEditor> editorMap = new HashMap<String, WEditor>();
|
||||
protected final static String PROCESS_ID_KEY = "processId";
|
||||
protected final static String ON_RUN_PROCESS = "onRunProcess";
|
||||
// attribute key of info process
|
||||
protected final static String ATT_INFO_PROCESS_KEY = "INFO_PROCESS";
|
||||
|
||||
protected int pageSize;
|
||||
protected MInfoRelated[] relatedInfoList;
|
||||
// for test disable load all record when num of record < 1000
|
||||
protected boolean isIgnoreCacheAll = true;
|
||||
// Num of page preload, default is 2 page before current and 2 page after current
|
||||
protected int numPagePreLoad = MSysConfig.getIntValue(MSysConfig.ZK_INFO_NUM_PAGE_PRELOAD, DEFAULT_PAGE_PRELOAD);
|
||||
// max end index is integer.max_value - 1, not integer.max_value.
|
||||
protected int extra_max_row = 1;
|
||||
/**
|
||||
* MInfoColumn has isKey = true, play as key column in case non column has
|
||||
* isKey = true, this column is null and we use {@link #p_keyColumn}
|
||||
*/
|
||||
protected MInfoColumn keyColumnOfView = null;
|
||||
|
||||
/**
|
||||
* index of {@link #keyColumnOfView} in data model, set when prepare listbox
|
||||
*/
|
||||
protected int indexKeyOfView = -1;
|
||||
|
||||
protected boolean isIDColumnKeyOfView = false;
|
||||
protected boolean hasRightQuickEntry = true;
|
||||
protected boolean isHasNextPage = false;
|
||||
/**
|
||||
* store selected record info
|
||||
* key of map is value of column play as keyView
|
||||
* in case has no key coloumn of view, use value of {@link #p_keyColumn}
|
||||
* zk6.x listview don't provide event when click to checkbox select all,
|
||||
* so we can't manage selectedRecord time by time.
|
||||
* each time change page we will update this list with current
|
||||
* selected record of this page by call function
|
||||
* {@link #updateListSelected()} when move to zk7, just enough handle
|
||||
* onclick. because don't direct use recordSelectedData, call
|
||||
* {@link #getSelectedRowInfo()}
|
||||
*/
|
||||
protected Map<Integer, List<Object>> recordSelectedData = new HashMap<Integer, List<Object>>();
|
||||
|
||||
/**
|
||||
* when requery but don't clear selected record (example after run process)
|
||||
* set flag to true to run sync selected record, also
|
||||
* {@link #syncSelectedAfterRequery()}
|
||||
*/
|
||||
protected boolean isRequeryByRunSuccessProcess = false;
|
||||
|
||||
|
||||
public static InfoPanel create (int WindowNo,
|
||||
String tableName, String keyColumn, String value,
|
||||
|
@ -148,6 +191,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
/** Window Width */
|
||||
static final int INFO_WIDTH = 800;
|
||||
protected boolean m_lookup;
|
||||
protected int m_infoWindowID;
|
||||
|
||||
/**************************************************
|
||||
* Detail Constructor
|
||||
|
@ -163,6 +207,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
this(WindowNo, tableName, keyColumn, multipleSelection, whereClause, true);
|
||||
}
|
||||
|
||||
protected InfoPanel (int WindowNo,
|
||||
String tableName, String keyColumn,boolean multipleSelection,
|
||||
String whereClause, boolean lookup){
|
||||
this(WindowNo, tableName, keyColumn, multipleSelection, whereClause,
|
||||
lookup, 0);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Detail Constructor
|
||||
* @param WindowNo WindowNo
|
||||
|
@ -172,7 +223,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
*/
|
||||
protected InfoPanel (int WindowNo,
|
||||
String tableName, String keyColumn,boolean multipleSelection,
|
||||
String whereClause, boolean lookup)
|
||||
String whereClause, boolean lookup, int ADInfoWindowID)
|
||||
{
|
||||
if (WindowNo <= 0) {
|
||||
p_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
|
||||
|
@ -182,11 +233,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
if (log.isLoggable(Level.INFO))
|
||||
log.info("WinNo=" + WindowNo + " " + whereClause);
|
||||
p_tableName = tableName;
|
||||
this.m_infoWindowID = ADInfoWindowID;
|
||||
p_keyColumn = keyColumn;
|
||||
|
||||
p_multipleSelection = multipleSelection;
|
||||
m_lookup = lookup;
|
||||
|
||||
loadInfoWindowData();
|
||||
if (whereClause == null || whereClause.indexOf('@') == -1)
|
||||
p_whereClause = whereClause == null ? "" : whereClause;
|
||||
else
|
||||
|
@ -196,7 +248,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
log.log(Level.SEVERE, "Cannot parse context= " + whereClause);
|
||||
}
|
||||
|
||||
pageSize = MSysConfig.getIntValue(MSysConfig.ZK_PAGING_SIZE, DEFAULT_PAGE_SIZE);
|
||||
pageSize = MSysConfig.getIntValue(MSysConfig.ZK_PAGING_SIZE, DEFAULT_PAGE_SIZE, Env.getAD_Client_ID(Env.getCtx()));
|
||||
|
||||
init();
|
||||
|
||||
|
@ -208,7 +260,6 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "infopanel");
|
||||
|
||||
infoWindow = MInfoWindow.get(p_keyColumn.replace("_ID", ""), null);
|
||||
addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this);
|
||||
addEventListener(ON_RUN_PROCESS, this);
|
||||
addEventListener(Events.ON_CLOSE, this);
|
||||
|
@ -238,6 +289,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
}
|
||||
|
||||
confirmPanel = new ConfirmPanel(true, true, true, true, true, true); // Elaine 2008/12/16
|
||||
confirmPanel.addComponentsLeft(confirmPanel.createButton(ConfirmPanel.A_NEW));
|
||||
confirmPanel.addActionListener(Events.ON_CLICK, this);
|
||||
confirmPanel.setHflex("1");
|
||||
|
||||
|
@ -245,6 +297,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
confirmPanel.getButton(ConfirmPanel.A_CUSTOMIZE).setVisible(hasCustomize());
|
||||
confirmPanel.getButton(ConfirmPanel.A_HISTORY).setVisible(hasHistory());
|
||||
confirmPanel.getButton(ConfirmPanel.A_ZOOM).setVisible(hasZoom());
|
||||
confirmPanel.getButton(ConfirmPanel.A_NEW).setVisible(hasNew());
|
||||
//
|
||||
if (!isLookup())
|
||||
{
|
||||
|
@ -304,7 +357,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
/** PO Zoom Window */
|
||||
private int m_PO_Window_ID = -1;
|
||||
|
||||
private MInfoWindow infoWindow;
|
||||
protected MInfoWindow infoWindow;
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
|
@ -418,6 +471,38 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
statusBar.setStatusDB(text);
|
||||
} // setStatusDB
|
||||
|
||||
/**
|
||||
* Set Status DB
|
||||
* @param text text
|
||||
*/
|
||||
public void setStatusSelected ()
|
||||
{
|
||||
if (!p_multipleSelection)
|
||||
return;
|
||||
|
||||
int selectedCount = recordSelectedData.size();
|
||||
|
||||
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
|
||||
Integer keyCandidate = getColumnValue(rowIndex);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
|
||||
|
||||
if (contentPanel.getModel().isSelected(candidateRecord)){
|
||||
if (!recordSelectedData.containsKey(keyCandidate)){
|
||||
selectedCount++;
|
||||
}
|
||||
}else{
|
||||
if (recordSelectedData.containsKey(keyCandidate)){// unselected record
|
||||
selectedCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String msg = Msg.getMsg(Env.getCtx(), "IWStatusSelected", new Object [] {String.valueOf(selectedCount)});
|
||||
statusBar.setSelectedRowNumber(msg);
|
||||
} // setStatusDB
|
||||
|
||||
protected void prepareTable (ColumnInfo[] layout,
|
||||
String from,
|
||||
String where,
|
||||
|
@ -436,6 +521,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
m_sqlOrder = " ORDER BY " + orderBy;
|
||||
} // prepareTable
|
||||
|
||||
protected boolean isLoadPageNumber(){
|
||||
return infoWindow == null || infoWindow.isLoadPageNum();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Execute Query
|
||||
*/
|
||||
|
@ -444,11 +533,14 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
line = new ArrayList<Object>();
|
||||
setCacheStart(-1);
|
||||
cacheEnd = -1;
|
||||
if (isLoadPageNumber())
|
||||
testCount();
|
||||
else
|
||||
m_count = Integer.MAX_VALUE;
|
||||
|
||||
testCount();
|
||||
if (m_count > 0)
|
||||
{
|
||||
m_useDatabasePaging = (m_count > 1000);
|
||||
m_useDatabasePaging = isIgnoreCacheAll || (m_count > 1000);
|
||||
if (m_useDatabasePaging)
|
||||
{
|
||||
return ;
|
||||
|
@ -538,6 +630,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
appendDataForViewID(rs, data, lsReadedColumn);
|
||||
|
||||
appendDataForParentLink(rs, data, lsReadedColumn);
|
||||
|
||||
appendDataForKeyView (rs, data, lsReadedColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -566,6 +660,20 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
appendInfoColumnData(rs, data, relatedInfoList, listReadedColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* save data of all viewID column in infoProcessList to end of data line
|
||||
* when override {@link #readData(ResultSet)} consider call this method
|
||||
* IDEMPIERE-1970
|
||||
* @param rs record set to read data
|
||||
* @param data data line to append
|
||||
* @param listReadedColumn list column is appended
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected void appendDataForKeyView(ResultSet rs, List<Object> data, List<Integer> listReadedColumn) throws SQLException {
|
||||
if (isNeedAppendKeyViewData())
|
||||
appendInfoColumnData(rs, data, new IInfoColumn [] {keyColumnOfView}, listReadedColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* save data of all infoColumn in listModelHaveInfoColumn to end of data line
|
||||
* @param rs record set to read data
|
||||
|
@ -664,13 +772,17 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
model.setMultiple(p_multipleSelection);
|
||||
contentPanel.setData(model, null);
|
||||
}
|
||||
int no = m_count;
|
||||
setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
|
||||
setStatusDB(Integer.toString(no));
|
||||
|
||||
restoreSelectedInPage();
|
||||
updateStatusBar (m_count);
|
||||
setStatusSelected ();
|
||||
addDoubleClickListener();
|
||||
}
|
||||
|
||||
protected void updateStatusBar (int no){
|
||||
setStatusLine((no == Integer.MAX_VALUE?"?":Integer.toString(no)) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
|
||||
setStatusDB(no == Integer.MAX_VALUE?"?":Integer.toString(no));
|
||||
}
|
||||
|
||||
private List<Object> readLine(int start, int end) {
|
||||
//cacheStart & cacheEnd - 1 based index, start & end - 0 based index
|
||||
if (getCacheStart() >= 1 && cacheEnd > getCacheStart())
|
||||
|
@ -679,7 +791,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
{
|
||||
if (start+1 >= getCacheStart() && end+1 <= cacheEnd)
|
||||
{
|
||||
return end == -1 ? line : line.subList(start-getCacheStart()+1, end-getCacheStart()+2);
|
||||
return end == -1 ? line : getSubList(start-getCacheStart()+1, end-getCacheStart()+1, line);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -688,11 +800,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
{
|
||||
end = cacheEnd;
|
||||
}
|
||||
return line.subList(start, end);
|
||||
return getSubList (start, end, line);
|
||||
}
|
||||
}
|
||||
|
||||
setCacheStart(start + 1 - (pageSize * 4));
|
||||
setCacheStart(getOverIntValue((long)start + 1 - (pageSize * numPagePreLoad)));
|
||||
if (getCacheStart() <= 0)
|
||||
setCacheStart(1);
|
||||
|
||||
|
@ -702,7 +814,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
}
|
||||
else
|
||||
{
|
||||
cacheEnd = end + 1 + (pageSize * 4);
|
||||
cacheEnd = getOverIntValue(end + 1 + (pageSize * numPagePreLoad));
|
||||
if (cacheEnd > m_count)
|
||||
cacheEnd = m_count;
|
||||
}
|
||||
|
@ -717,6 +829,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
//
|
||||
|
||||
dataSql = buildDataSQL(start, end);
|
||||
isHasNextPage = false;
|
||||
if (log.isLoggable(Level.FINER))
|
||||
log.finer(dataSql);
|
||||
try
|
||||
|
@ -754,6 +867,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
//check now of rows loaded, break if we hit the suppose end
|
||||
if (m_useDatabasePaging && rowPointer >= cacheEnd)
|
||||
{
|
||||
isHasNextPage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -769,10 +883,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
DB.close(m_rs, m_pstmt);
|
||||
}
|
||||
|
||||
if (end >= cacheEnd || end <= 0)
|
||||
if (end > cacheEnd || end <= 0)
|
||||
{
|
||||
end = cacheEnd-1;
|
||||
end = cacheEnd;
|
||||
}
|
||||
validateEndPage ();
|
||||
|
||||
if (end == -1)
|
||||
{
|
||||
|
@ -781,13 +896,93 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
else
|
||||
{
|
||||
int fromIndex = start-getCacheStart()+1;
|
||||
int toIndex = end-getCacheStart()+2;
|
||||
if (toIndex > line.size())
|
||||
toIndex = line.size();
|
||||
return line.subList(fromIndex, toIndex);
|
||||
int toIndex = end-getCacheStart()+1;
|
||||
return getSubList(fromIndex, toIndex, line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* after query from database, process validate.
|
||||
* if end page include in cache, process calculate total record
|
||||
* if current page is out of page (no record is query) process query count to detect end page
|
||||
*/
|
||||
protected void validateEndPage (){
|
||||
if (paging == null || isLoadPageNumber())
|
||||
return;
|
||||
|
||||
if (!isHasNextPage){
|
||||
int extraPage = ((line.size() % pageSize > 0)?1:0);
|
||||
int pageInCache = line.size() / pageSize + extraPage;
|
||||
|
||||
if (pageInCache == 0 || pageInCache <= numPagePreLoad){
|
||||
// selected page is out of page
|
||||
testCount();
|
||||
extraPage = ((m_count % pageSize > 0)?1:0);
|
||||
pageInCache = m_count / pageSize + extraPage;
|
||||
// this one will set current page to end page
|
||||
paging.setTotalSize(m_count);
|
||||
Event pagingEvent = new PagingEvent("onPaging", paging, paging.getPageCount() - 1);
|
||||
Events.postEvent(pagingEvent);
|
||||
}else if (pageInCache > numPagePreLoad){
|
||||
// current page isn't end page. but page in cache has end page.
|
||||
int prePage = pageNo - numPagePreLoad;
|
||||
int readTotalRecord = (prePage > 0?prePage:0) * pageSize + line.size();
|
||||
paging.setTotalSize(readTotalRecord);
|
||||
m_count = readTotalRecord;
|
||||
}
|
||||
|
||||
updateStatusBar (m_count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fromIndex and toIndex calculate with assume always query record as {@link #testCount()}
|
||||
* example after testCount we get calculate 6page.
|
||||
* when user navigate to page 4. something change in system (a batch record change become don't match with search query)
|
||||
* let we just get 5 page with current parameter.
|
||||
* so when user navigate to page 6. user will face with index issue. (out of index or start index > end index)
|
||||
* this function is fix for it.
|
||||
* @param fromIndex
|
||||
* @param toIndex
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
protected List<Object> getSubList (int fromIndex, int toIndex, List<Object> line){
|
||||
if (toIndex > line.size())
|
||||
toIndex = line.size();
|
||||
|
||||
if (fromIndex >= line.size())
|
||||
fromIndex = line.size();
|
||||
|
||||
// case line.size = 0
|
||||
if (fromIndex < 0)
|
||||
fromIndex = 0;
|
||||
|
||||
return line.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* when calculator value at bound, sometime value is overflow by data type
|
||||
* this function calculator at high type for avoid it
|
||||
* @param overValue
|
||||
* @return
|
||||
*/
|
||||
protected int getOverIntValue (long overValue){
|
||||
return getOverIntValue (overValue, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* see {@link #getOverIntValue(long)}. when value over max_value set it near max_value.
|
||||
* @param overValue
|
||||
* @param extra
|
||||
* @return
|
||||
*/
|
||||
protected int getOverIntValue (long overValue, int extra){
|
||||
if (overValue >= Integer.MAX_VALUE)
|
||||
overValue = Integer.MAX_VALUE - extra;
|
||||
|
||||
return (int)overValue;
|
||||
}
|
||||
protected String buildDataSQL(int start, int end) {
|
||||
String dataSql;
|
||||
String dynWhere = getSQLWhere();
|
||||
|
@ -943,47 +1138,24 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
/**
|
||||
* Get the keys of selected row/s based on layout defined in prepareTable
|
||||
* @deprecated this function should deprecated and replace with {@link #getListKeyValueOfSelectedRow()} to support view at infoWindow
|
||||
* @return IDs if selection present
|
||||
* @author ashley
|
||||
*/
|
||||
protected ArrayList<Integer> getSelectedRowKeys()
|
||||
{
|
||||
ArrayList<Integer> selectedDataList = new ArrayList<Integer>();
|
||||
|
||||
if (contentPanel.getKeyColumnIndex() == -1)
|
||||
Collection<Integer> lsKeyValueOfSelectedRow = getSelectedRowInfo().keySet();
|
||||
if (lsKeyValueOfSelectedRow.size() == 0)
|
||||
{
|
||||
return selectedDataList;
|
||||
}
|
||||
|
||||
if (p_multipleSelection)
|
||||
{
|
||||
int[] rows = contentPanel.getSelectedIndices();
|
||||
for (int row = 0; row < rows.length; row++)
|
||||
{
|
||||
Object data = contentPanel.getModel().getValueAt(rows[row], contentPanel.getKeyColumnIndex());
|
||||
if (data instanceof IDColumn)
|
||||
{
|
||||
IDColumn dataColumn = (IDColumn)data;
|
||||
selectedDataList.add(dataColumn.getRecord_ID());
|
||||
}
|
||||
else
|
||||
{
|
||||
log.severe("For multiple selection, IDColumn should be key column for selection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedDataList.size() == 0)
|
||||
{
|
||||
int row = contentPanel.getSelectedRow();
|
||||
if (row != -1 && contentPanel.getKeyColumnIndex() != -1)
|
||||
{
|
||||
Object data = contentPanel.getModel().getValueAt(row, contentPanel.getKeyColumnIndex());
|
||||
if (data instanceof IDColumn)
|
||||
selectedDataList.add(((IDColumn)data).getRecord_ID());
|
||||
if (data instanceof Integer)
|
||||
selectedDataList.add((Integer)data);
|
||||
}
|
||||
for (Integer key : lsKeyValueOfSelectedRow){
|
||||
selectedDataList.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
return selectedDataList;
|
||||
|
@ -1012,39 +1184,24 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
if (p_multipleSelection)
|
||||
{
|
||||
int[] rows = contentPanel.getSelectedIndices();
|
||||
Map <Integer, List<Object>> selectedRow = getSelectedRowInfo();
|
||||
|
||||
// this flag to just check key column in first record
|
||||
boolean isCheckedKeyType = false;
|
||||
|
||||
for (int row = 0; row < rows.length; row++)
|
||||
for (Entry<Integer, List<Object>> selectedInfo : selectedRow.entrySet())
|
||||
{
|
||||
// get key data column
|
||||
Object keyData = contentPanel.getModel().getValueAt(rows[row], contentPanel.getKeyColumnIndex());
|
||||
|
||||
// check key data must is IDColumn
|
||||
if (!isCheckedKeyType){
|
||||
if (keyData instanceof IDColumn){
|
||||
isCheckedKeyType = true;
|
||||
}else{
|
||||
log.severe("For multiple selection, IDColumn should be key column for selection");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IDColumn dataColumn = (IDColumn)keyData;
|
||||
Integer keyData = selectedInfo.getKey();
|
||||
|
||||
if (infoCulumnId > 0){
|
||||
// have viewID, get it
|
||||
int dataIndex = columnDataIndex.get(infoCulumnId) + p_layout.length;
|
||||
|
||||
// get row data from model
|
||||
Object viewIDValue = contentPanel.getModel().getDataAt(rows[row], dataIndex);
|
||||
Object viewIDValue = selectedInfo.getValue().get(dataIndex);
|
||||
|
||||
m_viewIDMap.add (new KeyNamePair(dataColumn.getRecord_ID(), viewIDValue == null?null:viewIDValue.toString()));
|
||||
m_viewIDMap.add (new KeyNamePair(keyData, viewIDValue == null?null:viewIDValue.toString()));
|
||||
}else{
|
||||
// hasn't viewID, set viewID value is null
|
||||
m_viewIDMap.add (new KeyNamePair(dataColumn.getRecord_ID(), null));
|
||||
m_viewIDMap.add (new KeyNamePair(keyData, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1057,6 +1214,179 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* need overrider at infoWindow to check isDisplay
|
||||
* @return
|
||||
*/
|
||||
protected boolean isNeedAppendKeyViewData (){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check type of object is IDColumn
|
||||
* @param keyData
|
||||
* @param isCheckNull when true, raise exception when data is null
|
||||
* @return
|
||||
*/
|
||||
protected boolean isIDColumn(Object keyData, boolean isCheckNull){
|
||||
if (isCheckNull && keyData == null){
|
||||
AdempiereException ex = getKeyNullException();
|
||||
log.severe(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (keyData != null && keyData instanceof IDColumn){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* call {@link #isIDColumn(Object, boolean)} without check null value
|
||||
* @param keyData
|
||||
* @return
|
||||
*/
|
||||
protected boolean isIDColumn(Object keyData){
|
||||
return isIDColumn(keyData, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all selected record of current page and update to {@link #recordSelectedData}
|
||||
* remove unselected record and add new selected record
|
||||
* we maintain value of key, and extra value append by {@link #appendInfoColumnData(ResultSet, List, IInfoColumn[], List)}
|
||||
*/
|
||||
protected void updateListSelected (){
|
||||
if (!p_multipleSelection){
|
||||
return;
|
||||
}
|
||||
|
||||
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
|
||||
Integer keyCandidate = getColumnValue(rowIndex);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
|
||||
|
||||
if (contentPanel.getModel().isSelected(candidateRecord)){
|
||||
recordSelectedData.put(keyCandidate, candidateRecord);// add or update selected record info
|
||||
}else{
|
||||
if (recordSelectedData.containsKey(keyCandidate)){// unselected record
|
||||
recordSelectedData.remove(keyCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get data index of keyView
|
||||
* @return
|
||||
*/
|
||||
protected int getIndexKeyColumnOfView (){
|
||||
if (keyColumnOfView == null){
|
||||
return contentPanel.getKeyColumnIndex();
|
||||
}else if (isNeedAppendKeyViewData()){
|
||||
return columnDataIndex.get(keyColumnOfView.getInfoColumnID()) + p_layout.length;
|
||||
}else{
|
||||
return indexKeyOfView;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* go through all data record, in case key value is in {@link #recordSelectedData}, mark it as selected record
|
||||
*/
|
||||
protected void restoreSelectedInPage (){
|
||||
if (!p_multipleSelection)
|
||||
return;
|
||||
|
||||
Collection<Object> lsSelectionRecord = new ArrayList<Object>();
|
||||
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
|
||||
Integer keyViewValue = getColumnValue(rowIndex);
|
||||
if (recordSelectedData.containsKey(keyViewValue)){
|
||||
// TODO: maybe add logic to check value of current record (focus only to viewKeys value) is same as value save in lsSelectedKeyValue
|
||||
// because record can change by other user
|
||||
lsSelectionRecord.add(contentPanel.getModel().get(rowIndex));
|
||||
}
|
||||
}
|
||||
|
||||
contentPanel.getModel().setSelection(lsSelectionRecord);
|
||||
}
|
||||
|
||||
|
||||
protected AdempiereException getKeyNullException (){
|
||||
String errorMessage = String.format("has null value at column %1$s use as key of view in info window %2$s",
|
||||
keyColumnOfView == null ? p_keyColumn : keyColumnOfView, infoWindow.getName());
|
||||
return new AdempiereException(errorMessage);
|
||||
}
|
||||
/**
|
||||
* get keyView value at rowIndex and clumnIndex
|
||||
* also check in case value is null will rise a exception
|
||||
* @param rowIndex
|
||||
* @param columnIndex
|
||||
* @return
|
||||
*/
|
||||
protected Integer getColumnValue (int rowIndex){
|
||||
|
||||
int keyIndex = getIndexKeyColumnOfView();
|
||||
Integer keyValue = null;
|
||||
// get row data from model
|
||||
Object keyColumValue = contentPanel.getModel().getDataAt(rowIndex, keyIndex);
|
||||
// throw exception when value is null
|
||||
if (keyColumValue == null){
|
||||
AdempiereException ex = getKeyNullException();
|
||||
log.severe(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// IDColumn is recreate after change page, because use value of IDColumn
|
||||
if (keyColumValue != null && keyColumValue instanceof IDColumn){
|
||||
keyColumValue = ((IDColumn)keyColumValue).getRecord_ID();
|
||||
}
|
||||
|
||||
if (keyColumValue instanceof Integer){
|
||||
keyValue = (Integer)keyColumValue;
|
||||
}else {
|
||||
String msg = "column play keyView should is integer";
|
||||
AdempiereException ex = new AdempiereException (msg);
|
||||
log.severe(msg);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return (Integer)keyValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* in case requery data, but want store selected record (example when run success a process)
|
||||
* we must sync selected row, because some selected row maybe not at data list (process make it change not map with query)
|
||||
* current 1000 line cache
|
||||
* because in case query get more 1000 record we can't sync or maintain selected record (ever maintain for current page will make user confuse).
|
||||
* just clear selection
|
||||
* in case < 1000 record is ok
|
||||
* TODO:rewrite
|
||||
*/
|
||||
protected void syncSelectedAfterRequery (){
|
||||
if (isRequeryByRunSuccessProcess){
|
||||
isRequeryByRunSuccessProcess = false;
|
||||
//TODO:it's hard to ensure in case use keyViewId we can re-sync. some issue:
|
||||
// + after RunSuccessProcess maybe key of record is change.
|
||||
// + after RunSuccessProcess maybe value of viewID change.
|
||||
// + after RunSuccessProcess maybe some record is out of query result
|
||||
// + when load many page, sync at one time effect to performance
|
||||
// maybe make two list, just sync for first page, old list use for reference,
|
||||
// when user change page will use it for restore selected record, synced record will copy to new list
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update list column key value of selected record and return this list
|
||||
* @return {@link #recordSelectedData} after update
|
||||
*/
|
||||
public Map<Integer, List<Object>> getSelectedRowInfo (){
|
||||
updateListSelected();
|
||||
return recordSelectedData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get selected Keys
|
||||
* @return selected keys (Integers)
|
||||
|
@ -1126,7 +1456,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
return sb.toString();
|
||||
} // getSelectedSQL;
|
||||
|
||||
|
||||
/**
|
||||
* query ADInfoWindow from ADInfoWindowID
|
||||
*/
|
||||
protected void loadInfoWindowData (){}
|
||||
|
||||
/**
|
||||
* Get Table name Synonym
|
||||
|
@ -1156,7 +1489,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
* enable all control button or disable all rely to selected record
|
||||
*/
|
||||
protected void enableButtons (){
|
||||
boolean enable = (contentPanel.getSelectedCount() > 0);
|
||||
boolean enable = (contentPanel.getSelectedCount() > 0 || getSelectedRowInfo().size() > 0);
|
||||
enableButtons(enable);
|
||||
}
|
||||
|
||||
|
@ -1178,7 +1511,6 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
confirmPanel.getButton(ConfirmPanel.A_ZOOM).setEnabled(!enable?enable : (contentPanel.getSelectedCount() == 1) ); //red1 only zoom for single record
|
||||
if (hasProcess())
|
||||
confirmPanel.getButton(ConfirmPanel.A_PROCESS).setEnabled(enable);
|
||||
|
||||
// IDEMPIERE-1334 start
|
||||
for (Button btProcess : btProcessList){
|
||||
btProcess.setEnabled(enable);
|
||||
|
@ -1251,9 +1583,18 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
* @return true if it has zoom (default false)
|
||||
*/
|
||||
protected boolean hasZoom() {return false;}
|
||||
/**
|
||||
* Has new function for create new record (false)
|
||||
* To be overwritten by concrete classes
|
||||
* @return
|
||||
*/
|
||||
protected boolean hasNew() {return false;}
|
||||
/**
|
||||
* Save Selection Details
|
||||
* To be overwritten by concrete classes
|
||||
* this function call when close info window.
|
||||
* default infoWindow will set value of all column of current selected record to environment variable with {@link Env.TAB_INF}
|
||||
* class extends can do more by override it.
|
||||
*/
|
||||
protected void saveSelectionDetail() {}
|
||||
|
||||
|
@ -1312,6 +1653,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
}
|
||||
else if (event.getTarget() == contentPanel && event.getName().equals(Events.ON_SELECT))
|
||||
{
|
||||
setStatusSelected ();
|
||||
m_lastOnSelectItem = null;
|
||||
SelectEvent<?, ?> selectEvent = (SelectEvent<?, ?>) event;
|
||||
if (selectEvent.getReference() != null && selectEvent.getReference() instanceof Listitem)
|
||||
|
@ -1367,6 +1709,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
if (isLookup())
|
||||
this.detach();
|
||||
}
|
||||
}else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_NEW)))
|
||||
{
|
||||
newRecordAction ();
|
||||
}
|
||||
// IDEMPIERE-1334 handle event click into process button start
|
||||
else if (ON_RUN_PROCESS.equals(event.getName())){
|
||||
|
@ -1400,7 +1745,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
// IDEMPIERE-1334 handle event click into process button end
|
||||
else if (event.getTarget() == paging)
|
||||
{
|
||||
updateListSelected();
|
||||
int pgNo = paging.getActivePage();
|
||||
|
||||
if (pageNo != pgNo)
|
||||
{
|
||||
|
||||
|
@ -1408,7 +1755,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
pageNo = pgNo;
|
||||
int start = pageNo * pageSize;
|
||||
int end = start + pageSize;
|
||||
int end = getOverIntValue ((long)start + pageSize, extra_max_row);
|
||||
if (end >= m_count)
|
||||
end = m_count;
|
||||
List<Object> subList = readLine(start, end);
|
||||
|
@ -1417,8 +1764,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
model.addTableModelListener(this);
|
||||
model.setMultiple(p_multipleSelection);
|
||||
contentPanel.setData(model, null);
|
||||
|
||||
restoreSelectedInPage();
|
||||
//contentPanel.setSelectedIndex(0);
|
||||
|
||||
}
|
||||
}
|
||||
else if (event.getName().equals(Events.ON_CHANGE))
|
||||
|
@ -1497,6 +1845,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update relate info when selection in main info change
|
||||
*/
|
||||
protected void updateSubcontent (){};
|
||||
|
||||
/**
|
||||
* Reset parameter to default value or to empty value? implement at
|
||||
* inheritance class when reset parameter maybe need init again parameter,
|
||||
|
@ -1540,6 +1893,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
public void onEvent(Event event) throws Exception {
|
||||
ProcessModalDialog processModalDialog = (ProcessModalDialog)event.getTarget();
|
||||
if (DialogEvents.ON_BEFORE_RUN_PROCESS.equals(event.getName())){
|
||||
updateListSelected();
|
||||
// store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code.
|
||||
DB.createT_SelectionNew(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID())),
|
||||
null);
|
||||
|
@ -1555,7 +1909,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
enableButtons();
|
||||
}else if (!m_pi.isError()){
|
||||
ProcessInfoDialog.showProcessInfo(m_pi, p_WindowNo, InfoPanel.this, true);
|
||||
Clients.response(new AuEcho(InfoPanel.this, "onQueryCallback", m_results));
|
||||
isRequeryByRunSuccessProcess = true;
|
||||
Clients.response(new AuEcho(InfoPanel.this, "onQueryCallback", null));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1610,17 +1965,19 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
executeQuery();
|
||||
renderItems();
|
||||
// IDEMPIERE-1334 after refresh, restore prev selected item start
|
||||
if (event != null && event.getData() != null){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Integer> lsSelectedKey = (List<Integer>)event.getData();
|
||||
contentPanel.setSelectedByKeys(lsSelectedKey);
|
||||
m_results.clear();
|
||||
}
|
||||
// just evaluate display logic of process button when requery by use click requery button
|
||||
if (isQueryByUser){
|
||||
bindInfoProcess();
|
||||
// reset selected list
|
||||
recordSelectedData.clear();
|
||||
isRequeryByRunSuccessProcess = false;
|
||||
}
|
||||
if (isRequeryByRunSuccessProcess){
|
||||
syncSelectedAfterRequery();
|
||||
restoreSelectedInPage();
|
||||
}
|
||||
// IDEMPIERE-1334 after refresh, restore prev selected item end
|
||||
updateSubcontent ();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -1637,7 +1994,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
|
||||
protected void onOk()
|
||||
{
|
||||
if (!contentPanel.getChildren().isEmpty() && contentPanel.getSelectedRowKey()!=null)
|
||||
if (!contentPanel.getChildren().isEmpty() && getSelectedRowInfo().size() > 0)
|
||||
{
|
||||
dispose(true);
|
||||
}
|
||||
|
@ -1689,6 +2046,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* process action when user click to new button
|
||||
*/
|
||||
protected void newRecordAction (){}
|
||||
|
||||
public void addValueChangeListener(ValueChangeListener listener)
|
||||
{
|
||||
if (listener == null)
|
||||
|
@ -1727,6 +2089,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
|
|||
} // dispose
|
||||
|
||||
public void sort(Comparator<Object> cmpr, boolean ascending) {
|
||||
updateListSelected();
|
||||
WListItemRenderer.ColumnComparator lsc = (WListItemRenderer.ColumnComparator) cmpr;
|
||||
if (m_useDatabasePaging)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,7 @@ public class StatusBarPanel extends Panel implements EventListener<Event>, IStat
|
|||
private Label statusDB;
|
||||
private Label infoLine;
|
||||
private Label statusLine;
|
||||
private Label selectedLine;
|
||||
|
||||
private DataStatusEvent m_dse;
|
||||
|
||||
|
@ -107,6 +108,11 @@ public class StatusBarPanel extends Panel implements EventListener<Event>, IStat
|
|||
|
||||
west = new Div();
|
||||
west.setStyle("text-align: left; ");
|
||||
selectedLine = new Label();
|
||||
west.appendChild(selectedLine);
|
||||
selectedLine.setVisible(false);
|
||||
LayoutUtils.addSclass("status-selected", selectedLine);
|
||||
|
||||
west.appendChild(statusLine);
|
||||
Vbox vbox = new Vbox();
|
||||
vbox.setPack("center");
|
||||
|
@ -117,7 +123,8 @@ public class StatusBarPanel extends Panel implements EventListener<Event>, IStat
|
|||
east = new Div();
|
||||
east.setWidth("100%");
|
||||
east.setStyle("text-align: right; ");
|
||||
infoLine = new Label();
|
||||
|
||||
infoLine = new Label();
|
||||
east.appendChild(infoLine);
|
||||
infoLine.setVisible(false);
|
||||
east.appendChild(statusDB);
|
||||
|
@ -298,6 +305,13 @@ public class StatusBarPanel extends Panel implements EventListener<Event>, IStat
|
|||
infoLine.setVisible(true);
|
||||
} // setInfo
|
||||
|
||||
public void setSelectedRowNumber (String rowNum){
|
||||
selectedLine.setVisible(rowNum != null);
|
||||
if (rowNum != null){
|
||||
selectedLine.setValue(rowNum);
|
||||
}
|
||||
}
|
||||
|
||||
public void onEvent(Event event) throws Exception {
|
||||
if (Events.ON_CLICK.equals(event.getName()) && event.getTarget() == statusDB)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||
|
||||
import org.adempiere.webui.component.Menupopup;
|
||||
import org.adempiere.webui.component.Tab;
|
||||
import org.adempiere.webui.component.Tab.DecorateInfo;
|
||||
import org.adempiere.webui.component.Tabbox;
|
||||
import org.adempiere.webui.component.Tabpanel;
|
||||
import org.adempiere.webui.component.Tabpanels;
|
||||
|
@ -101,15 +102,63 @@ public class WindowContainer extends AbstractUIPart
|
|||
return tabbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #addWindow(Component, String, boolean, DecorateInfo)}
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @return
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable){
|
||||
return addWindow(comp, title, closeable, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #addWindow(Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable) {
|
||||
return addWindow(comp, title, closeable, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #insertBefore(Tab, Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param refTab
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable){
|
||||
return insertBefore(refTab, comp, title, closeable, enable, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #insertAfter(Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param refTab
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable){
|
||||
return insertAfter(refTab, comp, title, closeable, enable, null);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable)
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, DecorateInfo decorateInfo)
|
||||
{
|
||||
return addWindow(comp, title, closeable, true);
|
||||
return addWindow(comp, title, closeable, true, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,9 +168,9 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
return insertBefore(null, comp, title, closeable, enable);
|
||||
return insertBefore(null, comp, title, closeable, enable, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,9 +181,10 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
final Tab tab = new Tab();
|
||||
tab.setDecorateInfo(decorateInfo);
|
||||
if (title != null)
|
||||
{
|
||||
setTabTitle(title, tab);
|
||||
|
@ -318,12 +368,12 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
if (refTab == null)
|
||||
return addWindow(comp, title, closeable, enable);
|
||||
return addWindow(comp, title, closeable, enable, decorateInfo);
|
||||
else
|
||||
return insertBefore((Tab)refTab.getNextSibling(), comp, title, closeable, enable);
|
||||
return insertBefore((Tab)refTab.getNextSibling(), comp, title, closeable, enable, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/**********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
**********************************************************************/
|
||||
|
||||
package org.adempiere.webui.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.base.Core;
|
||||
import org.compiere.model.MImage;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Env;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.image.Image;
|
||||
|
||||
/**
|
||||
* Normal image can come from inside system or from outside system.
|
||||
* with image from outside for performance we will cache it.
|
||||
* this class for manage image cache and provide help function relate
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public class ManageImageCache {
|
||||
|
||||
protected static transient CLogger log = CLogger.getCLogger (ManageImageCache.class);
|
||||
/**
|
||||
* this cache is don't expire, if must restart cache when has update image.
|
||||
* better use a timer, example reset cache after 10 minute has update. it help user can change a batch of image and reset one time.
|
||||
*/
|
||||
private final CCache<String, Image> imageCache = new CCache<String, Image>(null, "WindowImageCache", 50, 0, false);
|
||||
|
||||
private static ManageImageCache instance;
|
||||
|
||||
/**
|
||||
* get instance
|
||||
* @return
|
||||
*/
|
||||
public static ManageImageCache instance(){
|
||||
if (instance == null){
|
||||
synchronized (ManageImageCache.class){
|
||||
if (instance == null)
|
||||
instance = new ManageImageCache();
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* investigate image path of MImage, if path is a internal return internal url other return null
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public static String getImageInternalUrl (MImage image){
|
||||
if (image == null)
|
||||
return null;
|
||||
return getImageInternalUrl(image.getImageURL());
|
||||
}
|
||||
|
||||
/**
|
||||
* investigate image path, if path is a internal return internal url other return null
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String getImageInternalUrl (String url){
|
||||
if (url == null || url.trim().length() == 0 || url.indexOf("://") > 0)
|
||||
return null;
|
||||
|
||||
URL urlRsource = Core.getResourceFinder().getResource(url);
|
||||
return urlRsource == null?null:urlRsource.getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load image from url
|
||||
* @param imagePath
|
||||
* @return
|
||||
*/
|
||||
protected static byte [] loadImageData (String imagePath){
|
||||
byte [] data = null;
|
||||
|
||||
URLConnection conn;
|
||||
try {
|
||||
URL url = new URL(imagePath);
|
||||
conn = url.openConnection();
|
||||
|
||||
conn.setUseCaches(false);
|
||||
InputStream is = conn.getInputStream();
|
||||
byte[] buffer = new byte[1024*8]; // 8kB
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
int length = -1;
|
||||
while ((length = is.read(buffer)) != -1)
|
||||
os.write(buffer, 0, length);
|
||||
is.close();
|
||||
data = os.toByteArray();
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
if (log.isLoggable(Level.CONFIG)) log.config (e.toString());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* if image is don't in cache, load it (imagePath can id of MImage)
|
||||
* @param imagePath
|
||||
* @return image load from path. null when has any exception
|
||||
*/
|
||||
public Image getImage(String imagePath){
|
||||
if (imagePath == null || imagePath.trim().length() == 0)
|
||||
return null;
|
||||
|
||||
Image aImage = null;
|
||||
boolean hasCache = false;
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(imagePath);
|
||||
}
|
||||
|
||||
if (!hasCache) {
|
||||
try{
|
||||
int mImageId = Integer.parseInt(imagePath);
|
||||
loadImage(MImage.get(Env.getCtx(), mImageId));
|
||||
}catch (NumberFormatException ex){
|
||||
loadExtend(imagePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
synchronized (imageCache) {
|
||||
aImage = imageCache.get(imagePath);
|
||||
}
|
||||
|
||||
return aImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* if MImage contain extend image or binary image data, load it into cache and return key
|
||||
* other return null
|
||||
* @param mImage
|
||||
* @return
|
||||
*/
|
||||
public String loadImage (MImage mImage){
|
||||
if (mImage == null)
|
||||
return null;
|
||||
|
||||
boolean hasCache = false;
|
||||
String strId = String.valueOf(mImage.get_ID());
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(strId);
|
||||
}
|
||||
|
||||
if(hasCache){
|
||||
return strId;
|
||||
}
|
||||
|
||||
if (mImage.getBinaryData() != null){
|
||||
synchronized (imageCache) {
|
||||
Image loadImage = null;
|
||||
try {
|
||||
loadImage = new AImage (mImage.getName(), mImage.getBinaryData());
|
||||
} catch (IOException e) {
|
||||
// do nothing treat image as null
|
||||
}
|
||||
imageCache.put(String.valueOf(mImage.get_ID()), loadImage);
|
||||
}
|
||||
return strId;
|
||||
}else if (mImage.getImageURL() != null && mImage.getImageURL().trim().length() > 0 && getImageInternalUrl(mImage.getImageURL()) == null){
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(mImage.getImageURL());
|
||||
}
|
||||
if (!hasCache){
|
||||
loadExtend (mImage.getImageURL());
|
||||
}
|
||||
return mImage.getImageURL();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* load extend image into cache
|
||||
* @param imagePath
|
||||
*/
|
||||
protected void loadExtend (String imagePath){
|
||||
byte[] data = loadImageData(imagePath);
|
||||
AImage aImage = null;
|
||||
// when can't load image (by incorrect url or disconnect or any exception, just set image as null
|
||||
if (data != null)
|
||||
try {
|
||||
aImage = new AImage(imagePath, data);
|
||||
} catch (IOException e) {
|
||||
aImage = null;
|
||||
}
|
||||
|
||||
synchronized (imageCache) {
|
||||
imageCache.put(imagePath, aImage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ package org.adempiere.webui.util;
|
|||
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.adempiere.base.IResourceFinder;
|
||||
import org.adempiere.webui.WebUIActivator;
|
||||
|
@ -40,6 +41,7 @@ public class WebUIResourceFinder implements IResourceFinder {
|
|||
return WebUIActivator.getBundleContext().getBundle().findEntries(path, pattern, false);
|
||||
}
|
||||
|
||||
protected Pattern patternOnlyName = Pattern.compile("\\w+\\.\\w+");
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
if ("images/iDempiereHR.png".equals(name) || "images/iDempiere.png".equals(name)) {
|
||||
|
@ -47,6 +49,9 @@ public class WebUIResourceFinder implements IResourceFinder {
|
|||
}
|
||||
Enumeration<URL> e = find(name);
|
||||
URL url = e != null && e.hasMoreElements() ? e.nextElement() : null;
|
||||
if (url == null && patternOnlyName.matcher(name).matches()){
|
||||
name = "images/" + name;
|
||||
}
|
||||
if (url == null && name.startsWith("org/compiere/images")) {
|
||||
String t = name.substring("org/compiere/".length());
|
||||
t = ThemeManager.getThemeResource(t);
|
||||
|
|
|
@ -39,6 +39,37 @@ Copyright (C) 2007 Ashley G Ramdass.
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
zk.afterLoad('zul.mesh', function () {
|
||||
|
||||
zk.override(zul.mesh.Paging.prototype, "bind_", function () {
|
||||
this.$bind_.apply(this, arguments);
|
||||
if (this._totalSize == 0x7fffffff){
|
||||
jq(".z-paging-text", this).text("?");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
zk.override(zul.mesh.Paging.prototype, "infoText_",
|
||||
function () {
|
||||
//this.$infoText_.apply(this, arguments);
|
||||
var acp = this._activePage,
|
||||
psz = this._pageSize,
|
||||
tsz = this._totalSize,
|
||||
|
||||
lastItem = (acp + 1) * psz,
|
||||
dash = '';
|
||||
|
||||
if ('os' != this.getMold())
|
||||
dash = ' - ' + (lastItem > tsz ? tsz : lastItem);
|
||||
|
||||
if (this._totalSize == 0x7fffffff)
|
||||
tsz = "?";
|
||||
|
||||
return '[ ' + (acp * psz + 1) + dash + ' / ' + tsz + ' ]';
|
||||
});
|
||||
});
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<include src="${themePreference}"/>
|
||||
|
|
|
@ -78,6 +78,13 @@
|
|||
padding-right: 10px;
|
||||
border-left: solid 1px #9CBDFF;
|
||||
}
|
||||
|
||||
.status-selected{
|
||||
padding-right: 5px;
|
||||
padding-right: 5px;
|
||||
border-right: solid 1px #9CBDFF;
|
||||
}
|
||||
|
||||
.status-border {
|
||||
border: solid 1px #9CBDFF;
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 993 B |
Loading…
Reference in New Issue