From 7055afe6eedcde5c4fa3bed4b30209afe8dc2972 Mon Sep 17 00:00:00 2001 From: Max Patiiuk Date: Wed, 14 Dec 2022 17:03:17 -0600 Subject: [PATCH 01/29] Don't display trailing zeros for Decimals Fixes #1181 --- src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index eb568ae60..8fa73dad4 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -768,10 +768,9 @@ public Object formatToUI(Object...datas) * using doubleValue() eliminates trailing zeroes but * that leads to conflict with the way big decimals are * displayed in view mode on forms and in query results + * Can be solved by using return String.valueOf(data); */ - //return String.valueOf(((Number )data).doubleValue()); - - return String.valueOf(data); + return String.valueOf(((Number )data).doubleValue()); } else { //fmt = "%d"; From ef7f46c4a128ce993476fc89a6b114eeb225eba1 Mon Sep 17 00:00:00 2001 From: Max Patiiuk Date: Thu, 15 Dec 2022 13:17:14 -0600 Subject: [PATCH 02/29] Remove trailing digits from decimals when readOnly Fixes #1181 --- src/edu/ku/brc/af/ui/forms/FormViewObj.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/FormViewObj.java b/src/edu/ku/brc/af/ui/forms/FormViewObj.java index 92d519222..9707e9d97 100644 --- a/src/edu/ku/brc/af/ui/forms/FormViewObj.java +++ b/src/edu/ku/brc/af/ui/forms/FormViewObj.java @@ -43,6 +43,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; +import java.math.BigDecimal; import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; @@ -5297,7 +5298,7 @@ protected void setDataIntoUI(final boolean doResetAfterFill, } Object[] values = UIHelper.getFieldValues(cellField.getFieldNames(), dataObj, dg); - + setDataIntoUIComp(comp, DataObjFieldFormatMgr.getInstance().format(values[0], dataObjFormatName), defaultValue); } else @@ -5828,6 +5829,7 @@ public void setDataIntoUIComp(final String id, Object data) */ public static void setDataIntoUIComp(final Component comp, final Object data, final String defaultValue) { + log.debug("NAME: " + comp.getClass() + " ||| VALUE: " + data.toString()); if (comp instanceof GetSetValueIFace) { ((GetSetValueIFace)comp).setValue(data, defaultValue); @@ -5839,7 +5841,13 @@ public static void setDataIntoUIComp(final Component comp, final Object data, fi } else if (comp instanceof JTextField) { JTextField tf = (JTextField)comp; - tf.setText(data == null ? "" : data.toString()); + tf.setText( + data == null + ? "" + : data instanceof BigDecimal + ? String.valueOf(((Number )data).doubleValue()) + : data.toString() + ); tf.setCaretPosition(0); } else if (comp instanceof JTextArea) From 3675b14187bad8c825115fc579794563ec1a0c88 Mon Sep 17 00:00:00 2001 From: Max Patiiuk Date: Thu, 15 Dec 2022 13:18:16 -0600 Subject: [PATCH 03/29] Remove extra logging statement Forgot to remove it after doing debugging --- src/edu/ku/brc/af/ui/forms/FormViewObj.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/edu/ku/brc/af/ui/forms/FormViewObj.java b/src/edu/ku/brc/af/ui/forms/FormViewObj.java index 9707e9d97..a560ee35f 100644 --- a/src/edu/ku/brc/af/ui/forms/FormViewObj.java +++ b/src/edu/ku/brc/af/ui/forms/FormViewObj.java @@ -5829,7 +5829,6 @@ public void setDataIntoUIComp(final String id, Object data) */ public static void setDataIntoUIComp(final Component comp, final Object data, final String defaultValue) { - log.debug("NAME: " + comp.getClass() + " ||| VALUE: " + data.toString()); if (comp instanceof GetSetValueIFace) { ((GetSetValueIFace)comp).setValue(data, defaultValue); From b05da6a2cb7d29fe06066645cae264ad4ca75761 Mon Sep 17 00:00:00 2001 From: Max Patiiuk Date: Wed, 14 Dec 2022 16:06:29 -0600 Subject: [PATCH 04/29] Allow decimal fields to be negative Fixes #1180 See https://stackoverflow.com/questions/3884793/why-is-double-min-value-in-not-negative --- src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index eb568ae60..ce40eeae0 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -458,7 +458,7 @@ public Number getMinValue() { if (minValue == null && dataClass == BigDecimal.class) { - minValue = Double.MIN_VALUE; + minValue = -Double.MAX_VALUE; } return minValue; } From 4cdc0ddaef38e9c0abe4171366200fe4b3fb9127 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:49:54 -0600 Subject: [PATCH 05/29] Change CurrencyValidator to BigDecimalValidator for Decimal Fields Fixes #1180 See b05da6a for the other half of this fix --- .../brc/af/ui/forms/validation/ValFormattedTextFieldSingle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextFieldSingle.java b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextFieldSingle.java index e962140e3..c6d905d9d 100644 --- a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextFieldSingle.java +++ b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextFieldSingle.java @@ -818,7 +818,7 @@ protected UIValidatable.ErrorType validateNumeric(final String value) try { if (cls == BigDecimal.class) { if (bdValidator == null) { - bdValidator = CurrencyValidator.getInstance(); + bdValidator = BigDecimalValidator.getInstance(); } Number maxVal = formatter.getMaxValue(); From 3450ca25a69fb9307e43796b05f8907546be6bf8 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Tue, 20 Dec 2022 13:50:24 -0600 Subject: [PATCH 06/29] Truncate BigDecimals in Query Results See #1181 Briefly tested in QueryBuilder, yet this may affect Reports, Labels, and other exports. --- src/edu/ku/brc/dbsupport/JPAQuery.java | 44 ++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/edu/ku/brc/dbsupport/JPAQuery.java b/src/edu/ku/brc/dbsupport/JPAQuery.java index a9be7e545..758841237 100644 --- a/src/edu/ku/brc/dbsupport/JPAQuery.java +++ b/src/edu/ku/brc/dbsupport/JPAQuery.java @@ -19,6 +19,7 @@ */ package edu.ku.brc.dbsupport; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -288,7 +289,7 @@ private boolean runQuery() resultsList = objArray; } else { - resultsList = qry.list(); + resultsList = proccessQuery(qry.list()); } if (doDebug) @@ -348,7 +349,45 @@ private boolean runQuery() return !inError; } - + + /** + * Processes and modifies data from the Query Output of a Hibernate SQL command + * @param queryList -> A query output from Hibernate + * @return newList -> the modified list + */ + public static List proccessQuery(List queryList) + { + /* + * Hibernate returns data from the database to Java from Query.list() in the form of a List. + * If there are multiple results per row, Hibernate instead returns a List of Object Arrays. + * + * See https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html#list() + */ + List newList = (List) queryList; + + for (int row =0 ; row < newList.size(); row++) + { + if (newList.get(row) instanceof Object[]) + { + Object[] cols = (Object[]) newList.get(row); + for (int col=0; col < cols.length; col++) + { + if (cols[col] != null) + { + /* Strip Bigdecimals of their trailing zeros */ + if (cols[col] instanceof BigDecimal) + { + BigDecimal data = ((BigDecimal) cols[col]).stripTrailingZeros(); + cols[col] = data; + newList.set(row, cols); + } + } + } + } + } + return newList; + } + /* (non-Javadoc) * @see edu.ku.brc.dbsupport.CustomQuery#execute(edu.ku.brc.dbsupport.CustomQueryListener) */ @@ -386,6 +425,7 @@ public void execute(final CustomQueryListener cqlArg) ex.printStackTrace(); } } + /** * Dumps the results to the log file. From e9d6065cc0273300d7973a764666ae05dba62cd8 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 21 Dec 2022 10:06:13 -0600 Subject: [PATCH 07/29] Fix case where BigDecimal in exponential form in QueryResults See #1181 --- src/edu/ku/brc/dbsupport/JPAQuery.java | 28 ++++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/edu/ku/brc/dbsupport/JPAQuery.java b/src/edu/ku/brc/dbsupport/JPAQuery.java index 758841237..afe49aa42 100644 --- a/src/edu/ku/brc/dbsupport/JPAQuery.java +++ b/src/edu/ku/brc/dbsupport/JPAQuery.java @@ -289,7 +289,7 @@ private boolean runQuery() resultsList = objArray; } else { - resultsList = proccessQuery(qry.list()); + resultsList = modifyQueryResults(qry.list()); } if (doDebug) @@ -352,24 +352,25 @@ private boolean runQuery() /** * Processes and modifies data from the Query Output of a Hibernate SQL command - * @param queryList -> A query output from Hibernate + * @param rawQueryResults -> A query output from Hibernate * @return newList -> the modified list */ - public static List proccessQuery(List queryList) + public static List modifyQueryResults(List rawQueryResults) { /* - * Hibernate returns data from the database to Java from Query.list() in the form of a List. - * If there are multiple results per row, Hibernate instead returns a List of Object Arrays. + * Hibernate returns data from the database to Java from Query.list() in the form of a List containing the results. + * If there are multiple results per row, Hibernate instead returns a List of Object Arrays, each containing results per row. + * * * See https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html#list() */ - List newList = (List) queryList; + List modifiedQueryResults = (List) rawQueryResults; - for (int row =0 ; row < newList.size(); row++) + for (int row =0 ; row < modifiedQueryResults.size(); row++) { - if (newList.get(row) instanceof Object[]) + if (modifiedQueryResults.get(row) instanceof Object[]) { - Object[] cols = (Object[]) newList.get(row); + Object[] cols = (Object[]) modifiedQueryResults.get(row); for (int col=0; col < cols.length; col++) { if (cols[col] != null) @@ -377,15 +378,16 @@ public static List proccessQuery(List queryList) /* Strip Bigdecimals of their trailing zeros */ if (cols[col] instanceof BigDecimal) { - BigDecimal data = ((BigDecimal) cols[col]).stripTrailingZeros(); - cols[col] = data; - newList.set(row, cols); + BigDecimal rawData = (BigDecimal) cols[col]; + BigDecimal newData = new BigDecimal(rawData.stripTrailingZeros().toPlainString()); + cols[col] = newData; + modifiedQueryResults.set(row, cols); } } } } } - return newList; + return modifiedQueryResults; } /* (non-Javadoc) From 356eabe62fff0523c4579a42182f277365fc7350 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 21 Dec 2022 10:20:05 -0600 Subject: [PATCH 08/29] Ensure consistency between BigDecimal Query Results and Form UI --- src/edu/ku/brc/af/ui/forms/FormViewObj.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edu/ku/brc/af/ui/forms/FormViewObj.java b/src/edu/ku/brc/af/ui/forms/FormViewObj.java index a560ee35f..5925e6c26 100644 --- a/src/edu/ku/brc/af/ui/forms/FormViewObj.java +++ b/src/edu/ku/brc/af/ui/forms/FormViewObj.java @@ -5844,7 +5844,7 @@ public static void setDataIntoUIComp(final Component comp, final Object data, fi data == null ? "" : data instanceof BigDecimal - ? String.valueOf(((Number )data).doubleValue()) + ? ((BigDecimal) data).stripTrailingZeros().toPlainString() : data.toString() ); tf.setCaretPosition(0); From de2a65d829119c186e393f2148a351a15cdbad96 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 21 Dec 2022 11:32:35 -0600 Subject: [PATCH 09/29] Remove casting to double in UI Field Formatter See e9d6065 and 356eabe --- .../brc/af/ui/forms/formatters/UIFieldFormatter.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index 1e0c50490..037b68caa 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -765,12 +765,12 @@ public Object formatToUI(Object...datas) //fmt = "%" + (size-2) + ".2f"; /* - * using doubleValue() eliminates trailing zeroes but - * that leads to conflict with the way big decimals are - * displayed in view mode on forms and in query results - * Can be solved by using return String.valueOf(data); + * This was originally being cast to a double and then converted to string. + * This may cause unwanted issues when displaying certain values. + * (See https://stackoverflow.com/questions/16098046/how-do-i-print-a-double-value-without-scientific-notation-using-java) + * To avoid these issues, the BigDecimal is first stripped of it's trailing zeros and then directly converted to string. */ - return String.valueOf(((Number )data).doubleValue()); + return ((BigDecimal) data).stripTrailingZeros().toPlainString(); } else { //fmt = "%d"; From 11c52fa07c1c41fe1dce2561aac7815dc5383e61 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 26 Dec 2022 14:12:28 -0600 Subject: [PATCH 10/29] Finish adding carry forward support to Citations Fixes # 1179 Adds a clone() implementation to the following Citation Tables: - AccessionCitation - CollectionObjectCitation - DNASequencingRunCitation - TaxonCitation A basic implementation was made for each: these each need to be addressed further to iron out potential problems and solidify which fields should and should not be cloned. --- .../ku/brc/specify/datamodel/AccessionCitation.java | 9 +++++++++ .../specify/datamodel/CollectionObjectCitation.java | 11 ++++++++++- .../specify/datamodel/DNASequencingRunCitation.java | 10 ++++++++++ src/edu/ku/brc/specify/datamodel/TaxonCitation.java | 9 +++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/edu/ku/brc/specify/datamodel/AccessionCitation.java b/src/edu/ku/brc/specify/datamodel/AccessionCitation.java index 704b61be5..2a8b07c12 100644 --- a/src/edu/ku/brc/specify/datamodel/AccessionCitation.java +++ b/src/edu/ku/brc/specify/datamodel/AccessionCitation.java @@ -261,5 +261,14 @@ public static int getClassTableId() { return 156; } + + @Override + public Object clone() throws CloneNotSupportedException + { + AccessionCitation obj = (AccessionCitation) super.clone(); + obj.setAccessionCitationId(null); + obj.setAccession(null); + return obj; + } } diff --git a/src/edu/ku/brc/specify/datamodel/CollectionObjectCitation.java b/src/edu/ku/brc/specify/datamodel/CollectionObjectCitation.java index 9538cd047..8abc6fcf6 100644 --- a/src/edu/ku/brc/specify/datamodel/CollectionObjectCitation.java +++ b/src/edu/ku/brc/specify/datamodel/CollectionObjectCitation.java @@ -43,7 +43,7 @@ { @Index (name="COCITColMemIDX", columnNames={"CollectionMemberID"}) }) -public class CollectionObjectCitation extends CollectionMember implements java.io.Serializable +public class CollectionObjectCitation extends CollectionMember implements java.io.Serializable { // Fields @@ -265,5 +265,14 @@ public static int getClassTableId() { return 29; } + + @Override + public Object clone() throws CloneNotSupportedException + { + CollectionObjectCitation obj = (CollectionObjectCitation) super.clone(); + obj.setCollectionObjectCitationId(null); + obj.setCollectionObject(null); + return obj; + } } diff --git a/src/edu/ku/brc/specify/datamodel/DNASequencingRunCitation.java b/src/edu/ku/brc/specify/datamodel/DNASequencingRunCitation.java index e1b6e04a9..700c9c7e1 100644 --- a/src/edu/ku/brc/specify/datamodel/DNASequencingRunCitation.java +++ b/src/edu/ku/brc/specify/datamodel/DNASequencingRunCitation.java @@ -424,5 +424,15 @@ public String getPageNumber() { public void setPageNumber(String pageNumber) { this.pageNumber = pageNumber; } + + @Override + public Object clone() throws CloneNotSupportedException + { + DNASequencingRunCitation obj = (DNASequencingRunCitation) super.clone(); + obj.setDnaSequencingRunCitationId(null); + obj.setSequencingRun(null); + return obj; + } + } diff --git a/src/edu/ku/brc/specify/datamodel/TaxonCitation.java b/src/edu/ku/brc/specify/datamodel/TaxonCitation.java index b7143c612..89dddb274 100644 --- a/src/edu/ku/brc/specify/datamodel/TaxonCitation.java +++ b/src/edu/ku/brc/specify/datamodel/TaxonCitation.java @@ -348,5 +348,14 @@ public static int getClassTableId() { return 75; } + + @Override + public Object clone() throws CloneNotSupportedException + { + TaxonCitation obj = (TaxonCitation) super.clone(); + obj.setTaxonCitationId(null); + obj.setTaxon(null); + return obj; + } } From 4aa377f9c1b6d5662b61612d56fa8eaa74849a4e Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 26 Dec 2022 14:17:45 -0600 Subject: [PATCH 11/29] Set new LocalityCitationID to null when carry forward Fixes #1188 --- src/edu/ku/brc/specify/datamodel/LocalityCitation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edu/ku/brc/specify/datamodel/LocalityCitation.java b/src/edu/ku/brc/specify/datamodel/LocalityCitation.java index 1188e15e9..07c9545fa 100644 --- a/src/edu/ku/brc/specify/datamodel/LocalityCitation.java +++ b/src/edu/ku/brc/specify/datamodel/LocalityCitation.java @@ -208,7 +208,7 @@ public void setRemarks(String remarks) { public Object clone() throws CloneNotSupportedException { LocalityCitation lc = (LocalityCitation)super.clone(); - localityCitationId = null; + lc.setLocalityCitationId(null); return lc; } From c55dec56f76532ee1a9071dbae581f80044032b2 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:48:50 -0600 Subject: [PATCH 12/29] Do not modify query results for Reports and Exports Adds an isModified flag to the query (default is true). If not modified, the returned results will be straight from the Database. With this change, Reports and Exports will tell the query to not be modified --- src/edu/ku/brc/dbsupport/JPAQuery.java | 19 ++++++++++++++++--- .../ku/brc/specify/tasks/ReportsBaseTask.java | 3 ++- .../tasks/subpane/qb/QBDataSource.java | 1 + src/edu/ku/brc/ui/UIHelper.java | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/edu/ku/brc/dbsupport/JPAQuery.java b/src/edu/ku/brc/dbsupport/JPAQuery.java index afe49aa42..cebb7893f 100644 --- a/src/edu/ku/brc/dbsupport/JPAQuery.java +++ b/src/edu/ku/brc/dbsupport/JPAQuery.java @@ -75,6 +75,7 @@ public class JPAQuery implements CustomQueryIFace protected Query query = null; protected final AtomicBoolean cancelled = new AtomicBoolean(false); + private boolean isModified = true; /** * Constructor. @@ -287,9 +288,12 @@ private boolean runQuery() List objArray = new ArrayList(1); objArray.add(qry.list().size()); resultsList = objArray; - } else + } else if (isModified) { resultsList = modifyQueryResults(qry.list()); + } else + { + resultsList = qry.list(); } if (doDebug) @@ -594,7 +598,16 @@ public void setFirstResult(int firstResult) { this.firstResult = firstResult; } - - + /** + * Tell the query whether it should be modified or not (default is true) + * See modifyQueryResults() to see how the query can be modified + * + * @param isModified + */ + public void setIsModified(boolean isModified) + { + this.isModified = isModified; + } + } diff --git a/src/edu/ku/brc/specify/tasks/ReportsBaseTask.java b/src/edu/ku/brc/specify/tasks/ReportsBaseTask.java index 93ce9b941..c9a1eeafc 100644 --- a/src/edu/ku/brc/specify/tasks/ReportsBaseTask.java +++ b/src/edu/ku/brc/specify/tasks/ReportsBaseTask.java @@ -863,7 +863,7 @@ protected void printReport(final CommandAction cmdAction) } /** - * Processes all Commands of type LABELS. + * Processes all Commands of type REPORTS. * @param cmdAction the command to be processed */ protected void processReportCommands(final CommandAction cmdAction) @@ -885,6 +885,7 @@ protected void processReportCommands(final CommandAction cmdAction) Object data = cmdAction.getData(); UsageTracker.incrUsageCount("RP."+cmdAction.getType()+(data != null ? ("."+data.getClass().getSimpleName()) : "")); + if (cmdAction.isAction(NEWRECORDSET_ACTION)) { if (cmdAction.getData() instanceof GhostActionable) diff --git a/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java b/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java index 9bdd1140e..d86ac76a5 100644 --- a/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java +++ b/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java @@ -545,6 +545,7 @@ public void startDataAcquisition() theQuery.setMaxResults(maxResults.intValue()); } theQuery.setParams(params); + theQuery.setIsModified(false); theQuery.start(); } diff --git a/src/edu/ku/brc/ui/UIHelper.java b/src/edu/ku/brc/ui/UIHelper.java index 6824b879d..ca74220aa 100644 --- a/src/edu/ku/brc/ui/UIHelper.java +++ b/src/edu/ku/brc/ui/UIHelper.java @@ -849,7 +849,7 @@ public static Object convertDataFromString(final String dataStr, final Class } else if (cls == BigDecimal.class) { //System.out.println(BigDecimal.valueOf(Double.parseDouble(dataStr))); - return StringUtils.isNotEmpty(dataStr) ? BigDecimal.valueOf(Double.parseDouble(dataStr)) : null; + return StringUtils.isNotEmpty(dataStr) ? new BigDecimal(dataStr) : null; } else if (cls == Long.class) { From d61c9c49eb76627dfcac9d7797a255be547645dc Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:57:56 -0600 Subject: [PATCH 13/29] Add truncateBigDecimal Scriptlet Formats a BigDecimal to how it would appear in Query Builder Results and on Forms Should hopefully provide enough flexibility for working with BigDecimals' alongside the formatBigDecimal Scriplet in Reports and Labels (NOTE: This and other Scriptlets return a String becuase those are not formatted [have a 'pattern'] by IReport. IReport formats all numeric values by default to only have two places after the decimal unless specified in the JRXML). --- src/edu/ku/brc/specify/config/Scriptlet.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/edu/ku/brc/specify/config/Scriptlet.java b/src/edu/ku/brc/specify/config/Scriptlet.java index 678a91abd..9709c58c5 100644 --- a/src/edu/ku/brc/specify/config/Scriptlet.java +++ b/src/edu/ku/brc/specify/config/Scriptlet.java @@ -414,6 +414,20 @@ public String formatBigDecimal(final BigDecimal value, return String.format("%." + numberOfDecimalPlaces + "f", value); } + /** + * Remove trailing zeroes from a BigDecimal + * + * Returned value is identical to how the value would be formatted + * on Forms and in Query Results in Specify + * + * @param value the BigDecimal value to truncate + * @return returns value with trailing zeroes cut off + */ + public String truncateBigDecimal(final BigDecimal value) + { + return value.stripTrailingZeros().toPlainString(); + } + /** * Formats a String with a float value as a degrees. * @param floatStr From b1ff3f86d5b7d2fca89d6e75f391127bdcc023fd Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:59:26 -0600 Subject: [PATCH 14/29] Add regex support for Field Formatters --- .../formatters/UIFieldFormatterField.java | 35 +++++++- .../formatters/UIFieldFormatterIFace.java | 2 + .../forms/formatters/UIFieldFormatterMgr.java | 4 + .../formatters/UIFormatterEditorDlg.java | 82 +++++++++++++++++-- .../validation/ValFormattedTextField.java | 4 +- 5 files changed, 118 insertions(+), 9 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java index 19d6e872d..f9b6d78d6 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java @@ -25,6 +25,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jfree.util.Log; + /** * @author rods @@ -115,8 +117,8 @@ public UIFieldFormatterField(final FieldType type, this.minSize = minSize; this.value = value; if (type.equals(FieldType.regex)) { - this.regex = value; - this.value = pattern; + this.regex = value; +// this.value = pattern; } this.incrementer = incrementer; this.byYear = byYear; @@ -246,6 +248,25 @@ public String getValue() { return value == null ? "" : value; } + + /** + * Returns a string stripped of its regex value. + * Useful for determining the pattern to display for + * formatters with more than one field that contain a + * regex expression + * (see af.ui.forms.validation.ValFormattedTextField.java) + * + * @return value string stripped of its regex + */ + public String getNoRegexValue() + { + boolean hasRegex = this.regex == null ? false : true; + if (hasRegex) + { + return value == null ? "" : value.replace(regex, ""); + } + return value; + } /** * @return @@ -300,6 +321,12 @@ public String getSample() return value.substring(0, value.length()); } + if (type == FieldType.regex) + { + return ""; + + } + if (sample.length() == 0) { return ""; @@ -332,6 +359,10 @@ public String getRegExp() { return "\\p{Digit}{" + getSize() + "}"; } } + if (type == FieldType.regex) + { + return value; + } if (type == FieldType.year) { return Integer.toString(Calendar.getInstance().get(Calendar.YEAR)); diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterIFace.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterIFace.java index 780eebbe0..57477226e 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterIFace.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterIFace.java @@ -40,6 +40,8 @@ public interface UIFieldFormatterIFace { public enum PartialDateEnum {None, Full, Month, Year, Search} + + // Might need to add regex here as well for separation: currently it is being assigned the 'generic' type public enum FormatterType {generic, date, numeric} // all lower case to follow convention in uiformatters.xml /** diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java index 4a9ede36f..fcbb2e8b9 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java @@ -666,6 +666,10 @@ public UIFieldFormatterIFace createFormatterFromXML(final Element formatElement) { partialDateType = UIFieldFormatter.PartialDateEnum.Full; } + } else if (StringUtils.isNotEmpty(fType) && fType.equals("regex")) + { + type = UIFieldFormatter.FormatterType.regex; + } Class dataClass = null; diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java index 1945b413f..a90a8a0ee 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java @@ -129,7 +129,9 @@ public class UIFormatterEditorDlg extends CustomDialog protected CardLayout cardLayout = new CardLayout(); protected JPanel cardPanel; protected JTextField fieldTxt; + protected JTextField regexExpression; protected JSpinner sizeSpinner; + protected JSpinner regexSizeSpinner; protected JComboBox sepCbx; protected JCheckBox isIncChk; @@ -308,6 +310,17 @@ public int compare(UIFieldFormatterIFace o1, UIFieldFormatterIFace o2) //numPB.add(closeBtn, cc.xy(6, 1)); numPB.add(isIncChk, cc.xy(4, 3)); + + PanelBuilder regexPB = new PanelBuilder(new FormLayout(colDefs, "p,2px,p,2px,p")); + regexExpression = createTextField(); + regexExpression.setDocument(new PlainDocument()); + regexSizeSpinner = new JSpinner(new SpinnerNumberModel(1, 1, fieldInfo.getLength(), 1)); + regexPB.add(createI18NFormLabel("Regex Expression"), cc.xy(2, 1)); + regexPB.add(regexExpression, cc.xy(4, 1)); + regexPB.add(createI18NFormLabel("FFE_LENGTH"), cc.xy(2, 3)); + regexPB.add(regexSizeSpinner, cc.xy(4, 3)); + + sepCbx = new JComboBox(new String[] {"-", ".", "/", "(space)", "_"}); closeBtn = createClose(1); PanelBuilder sepPB = new PanelBuilder(new FormLayout(colDefs, "p,2px,p")); @@ -323,6 +336,7 @@ public int compare(UIFieldFormatterIFace o1, UIFieldFormatterIFace o2) cardPanel = new JPanel(cardLayout); cardPanel.add("size", numPB.getPanel()); cardPanel.add("text", txtPB.getPanel()); + cardPanel.add("regex", regexPB.getPanel()); cardPanel.add("sep", sepPB.getPanel()); cardPanel.add("none", new JLabel(" ")); @@ -440,6 +454,30 @@ public void actionPerformed(ActionEvent e) } }); + regexExpression.getDocument().addDocumentListener(new DocumentAdaptor( ) { + @Override + protected void changed(DocumentEvent e) + { + fieldHasChanged = true; + updateEnabledState(); + hasChanged = true; + updateUIEnabled(); + } + }); + + regexSizeSpinner.addChangeListener(new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent e) + { + fieldHasChanged = true; + updateEnabledState(); + hasChanged = true; + updateUIEnabled(); + + } + }); + fieldTypeCbx.setSelectedIndex(-1); fieldHasChanged = false; updateEnabledState(); @@ -500,8 +538,8 @@ private void typeChanged() FieldType fieldType = (FieldType)fieldTypeCbx.getSelectedItem(); switch (fieldType) { - case alphanumeric : - case alpha : + case alphanumeric : break; + case alpha : break; case anychar : cardKey = "size"; break; @@ -522,6 +560,12 @@ private void typeChanged() case year : cardKey = "none"; break; + + case regex : + cardKey = "regex"; + break; + + default: break; } } cardLayout.show(cardPanel, cardKey); @@ -578,6 +622,8 @@ public void valueChanged(ListSelectionEvent e) isIncChk.setSelected(currentField.isIncrementer()); fieldTxt.setText(currentField.getValue()); sizeSpinner.setValue(Math.max(1, currentField.getSize())); + regexExpression.setText(currentField.getValue()); + regexSizeSpinner.setValue(Math.max(1, currentField.getSize())); enabledEditorUI(true); } else @@ -606,6 +652,8 @@ protected void enabledEditorUI(final boolean enable) fieldTypeLbl.setEnabled(enable); fieldTxt.setEnabled(enable); sizeSpinner.setEnabled(enable); + regexExpression.setEnabled(enable); + regexSizeSpinner.setEnabled(enable); } /** @@ -698,6 +746,11 @@ protected void updateEntry() currentField.setValue("YEAR"); currentField.setSize(4); break; + + case regex : + currentField.setValue(regexExpression.getText()); + currentField.setSize((Integer) regexSizeSpinner.getValue()); + break; } currentField.setByYear(isByYear); @@ -723,6 +776,8 @@ protected void resetUI() fieldTxt.setText(""); sizeSpinner.setValue(1); isIncChk.setSelected(false); + regexExpression.setText(""); + regexSizeSpinner.setValue(1); fieldHasChanged = false; @@ -743,6 +798,7 @@ public void actionPerformed(ActionEvent e) { fieldTypeCbx.setSelectedIndex(-1); fieldTxt.setText(""); // DL attached to this field will set fieldHasChanged to true + // regexExpression.setText(""); fields.remove(fieldsTbl.getSelectedRow()); selectedFormat.resetLength(); @@ -771,6 +827,8 @@ protected void setDataIntoUI() isIncChk.setSelected(currentField.isByYear()); fieldTxt.setText(currentField.getValue()); sizeSpinner.setValue(Math.max(1, currentField.getSize())); + regexExpression.setText(currentField.getValue()); + regexSizeSpinner.setValue(Math.max(1, currentField.getSize())); } } @@ -805,7 +863,9 @@ protected void updateEnabledState() // save Btn if (currentField != null) { - fieldsPanel.getEditBtn().setEnabled(fieldHasChanged && (currentField.getType() == FieldType.constant ? !fieldTxt.getText().isEmpty() : true)); + fieldsPanel.getEditBtn().setEnabled(fieldHasChanged && (currentField.getType() == FieldType.constant + ? !fieldTxt.getText().isEmpty() || !regexExpression.getText().isEmpty() + : true)); } orderUpBtn.setEnabled(inx > 0); @@ -849,7 +909,11 @@ protected void getDataFromUI() if (fields.size() == 1 && fields.get(0).getType() == FieldType.numeric) { //selectedFormat.setType(UIFieldFormatterIFace.FormatterType.numeric); - } else + } else if (fields.size() == 1 && fields.get(0).getType() == FieldType.regex) + { + selectedFormat.setType(UIFieldFormatterIFace.FormatterType.regex); + } + else { selectedFormat.setType(UIFieldFormatterIFace.FormatterType.generic); } @@ -972,7 +1036,7 @@ protected void changed(DocumentEvent e) } /** - * @param txtFld + * @param currLen * @param maxLen * @return */ @@ -984,6 +1048,8 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) { fieldTxt.setBackground(currentTxtBGColor); fieldTxt.repaint(); + regexExpression.setBackground(currentTxtBGColor); + regexExpression.repaint(); currentTxtBGColor = null; } return true; @@ -995,6 +1061,7 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) { currentTxtBGColor = fieldTxt.getBackground(); fieldTxt.setBackground(Color.RED); + regexExpression.setBackground(Color.RED); } Toolkit.getDefaultToolkit().beep(); return false; @@ -1002,6 +1069,7 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) } else if (currentTxtBGColor != null) { fieldTxt.setBackground(currentTxtBGColor); + regexExpression.setBackground(currentTxtBGColor); } return true; } @@ -1086,6 +1154,10 @@ protected void updateUIEnabled() case year : totalLen += 4; break; + + case regex : + totalLen += (Integer)regexSizeSpinner.getValue(); + break; } } } diff --git a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java index eb5db8a58..37bca5d49 100644 --- a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java +++ b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java @@ -76,7 +76,7 @@ /** * A Multiple JTextFields (wrapped inside a JPanel) that provides for "formatted" input. The format "mask" is define in XML - * via the UIFieldFormatterMgr class. This is idea for text fields that have a standard size and a specific format (i.e. Dates) + * via the UIFieldFormatterMgr class. This is ideal for text fields that have a standard size and a specific format (i.e. Dates) * The mask enables the "fields" and separators to be specifically defined. * * NOTE: This impl has multiple Text Field, one for each part of the format. @@ -420,7 +420,7 @@ protected void createUI() } else { - JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.getValue()); + JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.getNoRegexValue()); tfToAdd = tf; if (inx == 0) From 66e85c078127f7d8176af436fe4e8a613ad08ebe Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 2 Jan 2023 14:48:25 -0600 Subject: [PATCH 15/29] Fix invalid enum access --- .../ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java index fcbb2e8b9..4a9ede36f 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterMgr.java @@ -666,10 +666,6 @@ public UIFieldFormatterIFace createFormatterFromXML(final Element formatElement) { partialDateType = UIFieldFormatter.PartialDateEnum.Full; } - } else if (StringUtils.isNotEmpty(fType) && fType.equals("regex")) - { - type = UIFieldFormatter.FormatterType.regex; - } Class dataClass = null; From 5765d963b86da65704f47e7293a02212c111f5fa Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:03:30 -0600 Subject: [PATCH 16/29] Truncate BigDecimals for Data Exports --- .../tasks/subpane/qb/QBDataSource.java | 25 +++++++++++++++++++ .../brc/specify/tools/export/ExportPanel.java | 4 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java b/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java index d86ac76a5..388940e16 100644 --- a/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java +++ b/src/edu/ku/brc/specify/tasks/subpane/qb/QBDataSource.java @@ -528,6 +528,7 @@ public QBDataSource(final String hql, final List> params, f } /** + * Run the query and use the results directly from the database * */ public void startDataAcquisition() @@ -548,6 +549,30 @@ public void startDataAcquisition() theQuery.setIsModified(false); theQuery.start(); } + + /** + * Run the query, but modify the query results. + * See JPAQuery.modifyQueryResults(List rawQueryResults) + * to see how the results get modified + * + */ + public void startModifiedQueryDataAcquistion() + { + firstRow = true; + currentRow = 0; + theQuery = new JPAQuery(hql, this); + + if (firstResult > 0) + { + theQuery.setFirstResult(firstResult.intValue()); + } + if (maxResults > 0) + { + theQuery.setMaxResults(maxResults.intValue()); + } + theQuery.setParams(params); + theQuery.start(); + } /* (non-Javadoc) * @see edu.ku.brc.specify.tasks.subpane.qb.QBJRDataSourceBase#getRecordId() diff --git a/src/edu/ku/brc/specify/tools/export/ExportPanel.java b/src/edu/ku/brc/specify/tools/export/ExportPanel.java index 57acbc283..9dcf3deca 100644 --- a/src/edu/ku/brc/specify/tools/export/ExportPanel.java +++ b/src/edu/ku/brc/specify/tools/export/ExportPanel.java @@ -1819,7 +1819,7 @@ public void run() { src.setFirstResult(rowsExported); src.setMaxResults(ExportPanel.maxExportRowCount); - src.startDataAcquisition(); + src.startModifiedQueryDataAcquistion(); // loading(); // XXX Assuming specimen-based export - 1 for baseTableId. @@ -1987,7 +1987,7 @@ public void run() src.setFirstResult(rowsExported); src.setMaxResults(ExportPanel.maxExportRowCount); - src.startDataAcquisition(); + src.startModifiedQueryDataAcquistion(); loading(); //XXX Assuming specimen-based export - 1 for baseTableId. From e7c98ae6c96d12dffc32a5c9a3bf281f9d30c7c4 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:22:39 -0600 Subject: [PATCH 17/29] Set default UIFieldFormatter type to 'generic' for regex FormatterFields --- .../ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java index a90a8a0ee..be1762724 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFormatterEditorDlg.java @@ -909,9 +909,6 @@ protected void getDataFromUI() if (fields.size() == 1 && fields.get(0).getType() == FieldType.numeric) { //selectedFormat.setType(UIFieldFormatterIFace.FormatterType.numeric); - } else if (fields.size() == 1 && fields.get(0).getType() == FieldType.regex) - { - selectedFormat.setType(UIFieldFormatterIFace.FormatterType.regex); } else { From 269c8f1f0ff87e0dab806bc5e073a18efab64215 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:29:55 -0600 Subject: [PATCH 18/29] Add Pattern option to regex UIFieldFormmaters See #1190 --- .../ui/forms/formatters/UIFieldFormatter.java | 14 ++++++- .../formatters/UIFieldFormatterField.java | 39 ++++++++++++++++--- .../formatters/UIFormatterEditorDlg.java | 35 ++++++++++++++--- .../validation/ValFormattedTextField.java | 19 ++++++--- 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index 037b68caa..664d31262 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -21,6 +21,7 @@ import edu.ku.brc.af.core.db.AutoNumberIFace; import edu.ku.brc.af.prefs.AppPrefsCache; +import edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterField.FieldType; import edu.ku.brc.ui.DateWrapper; import edu.ku.brc.ui.UIRegistry; import edu.ku.brc.util.Pair; @@ -615,7 +616,14 @@ public String toPattern() StringBuilder str = new StringBuilder(); for (UIFieldFormatterField field : fields) { - str.append(field.getValue()); + if (field.getType() == UIFieldFormatterField.FieldType.regex) + { + str.append(field.formatRegexValue()); + } else + { + str.append(field.getValue()); + } + } return str.toString(); } @@ -812,6 +820,10 @@ public String toString() { val = field.getSample(); } + if (field.type == FieldType.regex) + { + val = field.formatRegexValue(); + } str.append(val); } str.append("]"); diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java index f9b6d78d6..7bfadd1e7 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java @@ -25,8 +25,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.jfree.util.Log; - /** * @author rods @@ -51,6 +49,13 @@ public enum FieldType {numeric, alphanumeric, alpha, separator, year, anychar, c protected int minSize; protected String value; protected String regex; + + /* + * customPattern is currently used for regex type FormatterFields + * in the FieldFormatter Editor (see {@code UIFormatterEditorDlg} + * and lets the user define a custom pattern + */ + protected String customPattern; protected boolean incrementer; protected boolean byYear; @@ -118,6 +123,7 @@ public UIFieldFormatterField(final FieldType type, this.value = value; if (type.equals(FieldType.regex)) { this.regex = value; + this.customPattern = pattern; // this.value = pattern; } this.incrementer = incrementer; @@ -260,13 +266,21 @@ public String getValue() */ public String getNoRegexValue() { - boolean hasRegex = this.regex == null ? false : true; - if (hasRegex) + if (type == FieldType.regex) { return value == null ? "" : value.replace(regex, ""); } return value; } + + public String formatRegexValue() + { + if (type == FieldType.regex) + { + return customPattern == null ? (value == null ? "" : value.replace(regex, "")) : customPattern; + } + return value; + } /** * @return @@ -323,7 +337,7 @@ public String getSample() if (type == FieldType.regex) { - return ""; + return customPattern == null ? "" : customPattern; } @@ -385,6 +399,11 @@ public String getRegExpGrp(int idx) { } return result; } + + public String getCustomPattern() + { + return customPattern; + } public boolean isOptional() { return isOptional; @@ -444,6 +463,7 @@ public void toXML(StringBuilder sb) sb.append(" 0); diff --git a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java index 37bca5d49..9c296057a 100644 --- a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java +++ b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java @@ -420,7 +420,7 @@ protected void createUI() } else { - JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.getNoRegexValue()); + JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.formatRegexValue()); tfToAdd = tf; if (inx == 0) @@ -429,7 +429,7 @@ protected void createUI() @Override public void keyPressed(KeyEvent e) { - checkForPaste(e); +// checkForPaste(e); } }); } @@ -482,7 +482,7 @@ protected void changed(DocumentEvent e) cardPanel = new JPanel(cardLayout); cardPanel.add("edit", tf); - viewTF = new BGTextField(f.getSize(), isViewOnly ? "" : f.getValue()); + viewTF = new BGTextField(f.getSize(), isViewOnly ? "" : f.formatRegexValue()); viewTF.setDocument(document); cardPanel.add("view", viewTF); @@ -1186,8 +1186,17 @@ public String getFmtVal(final String strValue, final Object value) { } needsUpdating = (StringUtils.isEmpty(strValue) || strValue.length() != formatter.getLength() || strValue.contains("#")) && formatter.getAutoNumber() != null && formatter.isIncrementer(); - - fmtVal = (String)formatter.formatToUI(strValue); + + /* + * This sets the whole pattern of the format into the textbox + * -not just the transparent placeholder- when a formatter has + * another field beside numeric auto-increment. + * Disabling this will maintain consistency for solo numeric increment + * formatters. + * See () + */ +// fmtVal = (String)formatter.formatToUI(strValue); + fmtVal = strValue; } else { if (value == null) { From de09bbd5cef27df9910f8bb9e9e8db1cee9c5fce Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Tue, 3 Jan 2023 22:25:49 -0600 Subject: [PATCH 19/29] Add a decimal to Bigdecimal integers and zeros in modified results If the value is the equivalent of an integer or zero,format it to #.0 Affects Forms, QueryBuilder Results, and Data Exports This maintains consistency between Specify 6.8.01, where all decimal fields were formatted to one decimal place --- src/edu/ku/brc/af/ui/forms/FormViewObj.java | 9 +++++---- .../brc/af/ui/forms/formatters/UIFieldFormatter.java | 10 +++++++++- .../af/ui/forms/validation/ValFormattedTextField.java | 2 +- src/edu/ku/brc/dbsupport/JPAQuery.java | 9 ++++++++- src/edu/ku/brc/specify/config/Scriptlet.java | 10 +++++++++- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/FormViewObj.java b/src/edu/ku/brc/af/ui/forms/FormViewObj.java index 5925e6c26..a6858f53b 100644 --- a/src/edu/ku/brc/af/ui/forms/FormViewObj.java +++ b/src/edu/ku/brc/af/ui/forms/FormViewObj.java @@ -58,7 +58,6 @@ import java.util.Map; import java.util.Set; import java.util.Vector; - import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; @@ -89,8 +88,6 @@ import javax.swing.SwingUtilities; import edu.ku.brc.specify.datamodel.CollectionObject; -import edu.ku.brc.specify.datamodel.Determination; -import edu.ku.brc.specify.datamodel.Taxon; import edu.ku.brc.ui.*; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; @@ -5843,8 +5840,12 @@ public static void setDataIntoUIComp(final Component comp, final Object data, fi tf.setText( data == null ? "" + // If the BigDecimal is an integer or 0, format it to #.0 + // otherwise, strip the zeros : data instanceof BigDecimal - ? ((BigDecimal) data).stripTrailingZeros().toPlainString() + ? ((((BigDecimal)data).stripTrailingZeros().scale() <= 0 || (((BigDecimal)data).stripTrailingZeros().signum()==0)) + ? ((BigDecimal)data).stripTrailingZeros().setScale(1).toPlainString() + : ((BigDecimal)data).stripTrailingZeros().toPlainString()) : data.toString() ); tf.setCaretPosition(0); diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index 664d31262..cf4728efc 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -778,7 +778,15 @@ public Object formatToUI(Object...datas) * (See https://stackoverflow.com/questions/16098046/how-do-i-print-a-double-value-without-scientific-notation-using-java) * To avoid these issues, the BigDecimal is first stripped of it's trailing zeros and then directly converted to string. */ - return ((BigDecimal) data).stripTrailingZeros().toPlainString(); + BigDecimal strippedDecimal = ((BigDecimal) data).stripTrailingZeros(); + + // If the BigDecimal is an integer or zero + if (strippedDecimal.scale() <= 0 || strippedDecimal.signum() == 0) + { + // Add a decimal place so the format is #.0 + strippedDecimal = strippedDecimal.setScale(1); + } + return strippedDecimal.toPlainString(); } else { //fmt = "%d"; diff --git a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java index 9c296057a..13fd43714 100644 --- a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java +++ b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java @@ -1193,7 +1193,7 @@ public String getFmtVal(final String strValue, final Object value) { * another field beside numeric auto-increment. * Disabling this will maintain consistency for solo numeric increment * formatters. - * See () + * See (https://github.com/specify/specify6/issues/1190) */ // fmtVal = (String)formatter.formatToUI(strValue); fmtVal = strValue; diff --git a/src/edu/ku/brc/dbsupport/JPAQuery.java b/src/edu/ku/brc/dbsupport/JPAQuery.java index cebb7893f..27f7d9854 100644 --- a/src/edu/ku/brc/dbsupport/JPAQuery.java +++ b/src/edu/ku/brc/dbsupport/JPAQuery.java @@ -383,7 +383,14 @@ public static List modifyQueryResults(List rawQueryResults) if (cols[col] instanceof BigDecimal) { BigDecimal rawData = (BigDecimal) cols[col]; - BigDecimal newData = new BigDecimal(rawData.stripTrailingZeros().toPlainString()); + BigDecimal newData = rawData.stripTrailingZeros(); + + // If the stripped BigDecimal is an integer or zero + if (newData.scale() <= 0 || newData.signum() == 0) + { + // Add a decimal place so the format is #.0 + newData = newData.setScale(1); + } cols[col] = newData; modifiedQueryResults.set(row, cols); } diff --git a/src/edu/ku/brc/specify/config/Scriptlet.java b/src/edu/ku/brc/specify/config/Scriptlet.java index 9709c58c5..b72866538 100644 --- a/src/edu/ku/brc/specify/config/Scriptlet.java +++ b/src/edu/ku/brc/specify/config/Scriptlet.java @@ -425,7 +425,15 @@ public String formatBigDecimal(final BigDecimal value, */ public String truncateBigDecimal(final BigDecimal value) { - return value.stripTrailingZeros().toPlainString(); + BigDecimal newValue = value.stripTrailingZeros(); + + // If value stripped of zeroes is an integer or 0 + if (newValue.scale() <= 0 || newValue.signum() == 0) + { + // Add a decimal place so the format is #.0 + newValue = newValue.setScale(1); + } + return newValue.toPlainString(); } /** From d6b3b3d2ea144afa1f3d41014d544aa68845793f Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 9 Jan 2023 09:01:44 -0600 Subject: [PATCH 20/29] Update Specify Version String to 6.8.03 --- .install4j/i4jparams.conf | 8 ++++---- src/resources_en.properties | 2 +- src/resources_pt.properties | 2 +- src/resources_ru.properties | 2 +- src/resources_uk.properties | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.install4j/i4jparams.conf b/.install4j/i4jparams.conf index 77e21d8a3..b4b07a5c3 100644 --- a/.install4j/i4jparams.conf +++ b/.install4j/i4jparams.conf @@ -1,12 +1,12 @@ - + - + @@ -114,7 +114,7 @@ - Specify 6.8.02 includes the following changes: + Specify 6.8.03 includes the following changes: New This Release @@ -207,7 +207,7 @@ - Specify 6.8.02 + Specify 6.8.03 diff --git a/src/resources_en.properties b/src/resources_en.properties index 10d280120..49ce31461 100755 --- a/src/resources_en.properties +++ b/src/resources_en.properties @@ -1,7 +1,7 @@ ################################# # Really common GUI terms ################################# -SPECIFY_VERSION=6.8.02 +SPECIFY_VERSION=6.8.03 APPVER_MISMATCH=The installed version is '%s' and doesn't match the internal version of '%s'.\nThis can be resolved by doing a new full install. true=Yes diff --git a/src/resources_pt.properties b/src/resources_pt.properties index db0a2212e..3b4a2e738 100644 --- a/src/resources_pt.properties +++ b/src/resources_pt.properties @@ -1,7 +1,7 @@ ################################# # Really common GUI terms ################################# -SPECIFY_VERSION=6.8.02 +SPECIFY_VERSION=6.8.03 APPVER_MISMATCH=A versão instalada é a '%s' e não coincide com a versão interna de '%s'.\nIsto pode ser resolvido fazendo uma instalação completa. true=Sim diff --git a/src/resources_ru.properties b/src/resources_ru.properties index 3d9adc044..9cf4a3eb4 100644 --- a/src/resources_ru.properties +++ b/src/resources_ru.properties @@ -1,7 +1,7 @@ ################################# # Really common GUI terms ################################# -SPECIFY_VERSION=6.8.02 +SPECIFY_VERSION=6.8.03 APPVER_MISMATCH=Установленная версия '%s' и не соответствует внутренней версии '%s'.\n Это можно решить, выполнив новую полную установку. true=Да diff --git a/src/resources_uk.properties b/src/resources_uk.properties index 3da529cc2..02c4585be 100755 --- a/src/resources_uk.properties +++ b/src/resources_uk.properties @@ -1,7 +1,7 @@ ################################# # Really common GUI terms ################################# -SPECIFY_VERSION=6.8.02 +SPECIFY_VERSION=6.8.03 APPVER_MISMATCH=Встановлена версія '%s' і не відповідає внутрішній версії '%s'.\nЦе можна вирішити, виконавши нове повне всановлення. true=Так From 1913fc86c0fd54b723b91c52ee1bda9ee5239293 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 11 Jan 2023 12:04:14 -0600 Subject: [PATCH 21/29] Correctly format BigDecimal fields in Data Exports --- .../specify/tools/export/ExportToMySQLDB.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java b/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java index efb3ce3a1..5b179672f 100644 --- a/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java +++ b/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java @@ -1052,6 +1052,24 @@ protected static String getTabDelimLine(ResultSet rows, Connection conn) throws val = val.replace("\t", " "); val = val.replace("\n", " "); val = val.replace("\r", " "); + } + /** + * If the SQL type is Decimal, perform the same operation within Specify + * as seen in Forms and QueryBuilder + * @see JPAQuery#modifyQueryResults(List rawQueryResults) + */ + else if (type == java.sql.Types.DECIMAL) + { + BigDecimal rawData = rows.getBigDecimal(c); + BigDecimal newData = rawData.stripTrailingZeros(); + + // If the stripped BigDecimal is an integer or zero + if (newData.scale() <= 0 || newData.signum() == 0) + { + // Add a decimal place so the format is #.0 + newData = newData.setScale(1); + } + val = newData.toPlainString(); } result.append(val); } @@ -1389,7 +1407,10 @@ protected Object doInBackground() throws Exception stmt = conn.createStatement(); //List flds = BasicSQLUtils.getFieldMetaDataFromSchema(conn, tableName); String sql = getSQLForTabDelimExport(conn, tableName); + ResultSet rows = stmt.executeQuery(sql); + + //no simple way to get record count from ResultSet?? rowCount = BasicSQLUtils.getCount(conn, "select count(*) from `" + tableName + "`").longValue(); for (QBDataSourceListenerIFace listener : listeners) From afe533949ef4076c5da91a87082bd465ced08316 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Fri, 13 Jan 2023 08:18:40 -0600 Subject: [PATCH 22/29] Format BigDecimals in WebPortal exports --- .../tools/webportal/BuildSearchIndex2.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java b/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java index 2a0407781..c2ab819a5 100644 --- a/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java +++ b/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java @@ -54,6 +54,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.math.BigDecimal; import java.nio.file.Files; import java.nio.file.Path; import java.sql.*; @@ -659,7 +660,27 @@ protected void writePortalInstanceJsonToFile(ExportMappingHelper map, Map rawQueryResults) + */ + if (fld.getDataClass() == BigDecimal.class) + { + BigDecimal strippedDecimalValue = (new BigDecimal(value)).stripTrailingZeros(); + + // If the stripped BigDecimal is an integer + if (strippedDecimalValue.scale() <= 0) + { + // Add a decimal place so the format is #.0 + strippedDecimalValue = strippedDecimalValue.setScale(1); + } + value = strippedDecimalValue.toPlainString(); + } + AppPreferences rPrefs = AppPreferences.getRemote(); if (rPrefs.getBoolean(PROCESS_WEBLINKS_PREF_NAME, PROCESS_WEBLINKS_PREF_DEFAULT)) { String wl = fld.getWebLinkName(); From 82004bc3432483eab09d3e8d4d984c3934280b3a Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Fri, 13 Jan 2023 08:25:20 -0600 Subject: [PATCH 23/29] When BigDecimal value is 0, format it to 0 and not 0.0 --- src/edu/ku/brc/af/ui/forms/FormViewObj.java | 4 ++-- src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java | 4 ++-- src/edu/ku/brc/dbsupport/JPAQuery.java | 4 ++-- src/edu/ku/brc/specify/config/Scriptlet.java | 4 ++-- src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java | 4 ++-- src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/FormViewObj.java b/src/edu/ku/brc/af/ui/forms/FormViewObj.java index a6858f53b..04a8c17fa 100644 --- a/src/edu/ku/brc/af/ui/forms/FormViewObj.java +++ b/src/edu/ku/brc/af/ui/forms/FormViewObj.java @@ -5840,10 +5840,10 @@ public static void setDataIntoUIComp(final Component comp, final Object data, fi tf.setText( data == null ? "" - // If the BigDecimal is an integer or 0, format it to #.0 + // If the BigDecimal is an integer and not zero, format it to #.0 // otherwise, strip the zeros : data instanceof BigDecimal - ? ((((BigDecimal)data).stripTrailingZeros().scale() <= 0 || (((BigDecimal)data).stripTrailingZeros().signum()==0)) + ? ((((BigDecimal)data).stripTrailingZeros().scale() <= 0 && ((BigDecimal)data).signum() != 0) ? ((BigDecimal)data).stripTrailingZeros().setScale(1).toPlainString() : ((BigDecimal)data).stripTrailingZeros().toPlainString()) : data.toString() diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index cf4728efc..eff0a4f4e 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -780,8 +780,8 @@ public Object formatToUI(Object...datas) */ BigDecimal strippedDecimal = ((BigDecimal) data).stripTrailingZeros(); - // If the BigDecimal is an integer or zero - if (strippedDecimal.scale() <= 0 || strippedDecimal.signum() == 0) + // If the BigDecimal is an integer and not zero + if (strippedDecimal.scale() <= 0 && strippedDecimal.signum() != 0) { // Add a decimal place so the format is #.0 strippedDecimal = strippedDecimal.setScale(1); diff --git a/src/edu/ku/brc/dbsupport/JPAQuery.java b/src/edu/ku/brc/dbsupport/JPAQuery.java index 27f7d9854..5f8135373 100644 --- a/src/edu/ku/brc/dbsupport/JPAQuery.java +++ b/src/edu/ku/brc/dbsupport/JPAQuery.java @@ -385,8 +385,8 @@ public static List modifyQueryResults(List rawQueryResults) BigDecimal rawData = (BigDecimal) cols[col]; BigDecimal newData = rawData.stripTrailingZeros(); - // If the stripped BigDecimal is an integer or zero - if (newData.scale() <= 0 || newData.signum() == 0) + // If the stripped BigDecimal is an integer and not zero + if (newData.scale() <= 0 && newData.signum() != 0) { // Add a decimal place so the format is #.0 newData = newData.setScale(1); diff --git a/src/edu/ku/brc/specify/config/Scriptlet.java b/src/edu/ku/brc/specify/config/Scriptlet.java index b72866538..08e457b59 100644 --- a/src/edu/ku/brc/specify/config/Scriptlet.java +++ b/src/edu/ku/brc/specify/config/Scriptlet.java @@ -427,8 +427,8 @@ public String truncateBigDecimal(final BigDecimal value) { BigDecimal newValue = value.stripTrailingZeros(); - // If value stripped of zeroes is an integer or 0 - if (newValue.scale() <= 0 || newValue.signum() == 0) + // If value stripped of zeroes is an integer and not 0 + if (newValue.scale() <= 0 && newValue.signum() != 0) { // Add a decimal place so the format is #.0 newValue = newValue.setScale(1); diff --git a/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java b/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java index 5b179672f..0f5bb955c 100644 --- a/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java +++ b/src/edu/ku/brc/specify/tools/export/ExportToMySQLDB.java @@ -1063,8 +1063,8 @@ else if (type == java.sql.Types.DECIMAL) BigDecimal rawData = rows.getBigDecimal(c); BigDecimal newData = rawData.stripTrailingZeros(); - // If the stripped BigDecimal is an integer or zero - if (newData.scale() <= 0 || newData.signum() == 0) + // If the stripped BigDecimal is an integer and not zero + if (newData.scale() <= 0 && newData.signum() != 0) { // Add a decimal place so the format is #.0 newData = newData.setScale(1); diff --git a/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java b/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java index c2ab819a5..5d6b47d3f 100644 --- a/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java +++ b/src/edu/ku/brc/specify/tools/webportal/BuildSearchIndex2.java @@ -672,8 +672,8 @@ protected String processValue(String value, ExportMappingInfo info) { { BigDecimal strippedDecimalValue = (new BigDecimal(value)).stripTrailingZeros(); - // If the stripped BigDecimal is an integer - if (strippedDecimalValue.scale() <= 0) + // If the stripped BigDecimal is an integer and not zero + if (strippedDecimalValue.scale() <= 0 && strippedDecimalValue.signum() != 0) { // Add a decimal place so the format is #.0 strippedDecimalValue = strippedDecimalValue.setScale(1); From 34d66d516437f6b1c2ebdc5ab97ad6ff95b45902 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Mon, 16 Jan 2023 07:12:42 -0600 Subject: [PATCH 24/29] Allow Agents of type Other and Group to have addresses --- .../datamodel/busrules/AgentBusRules.java | 101 +++++++++--------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/src/edu/ku/brc/specify/datamodel/busrules/AgentBusRules.java b/src/edu/ku/brc/specify/datamodel/busrules/AgentBusRules.java index 716c47089..25ed447a6 100644 --- a/src/edu/ku/brc/specify/datamodel/busrules/AgentBusRules.java +++ b/src/edu/ku/brc/specify/datamodel/busrules/AgentBusRules.java @@ -301,6 +301,12 @@ protected void fixUpFormForAgentType(final Agent agent, //{ // agentVarSep.setVisible(useAgentVariant); //} + + Component addrSubView = formViewObj.getCompById("9"); + if (addrSubView != null) + { + addrSubView.setVisible(true); + } Component agentVarSubView = formViewObj.getCompById("10"); if (agentVarSubView != null) @@ -340,24 +346,7 @@ protected void fixUpTypeCBX(final JComboBox cbx) boolean enable = agentType == Agent.ORG; addrSubView.setVisible(enable); - } else - { - if (!isVisible) - { - SwingUtilities.invokeLater(new Runnable() { - public void run() - { - Component topComp = UIHelper.getWindow(addrSubView); - Component topMost = UIRegistry.getTopWindow(); - if (topComp != topMost && topComp != null) - { - ((Window)topComp).pack(); - } - } - }); - } - addrSubView.setVisible(true); - } + } agent.setAgentType(agentType); fixUpFormForAgentType(agent, true); } @@ -421,7 +410,7 @@ public void afterFillForm(final Object dataObjArg) Component addrSubView = formViewObj.getCompById("9"); if (addrSubView != null) { - addrSubView.setVisible(false); + addrSubView.setVisible(true); } } return; @@ -451,27 +440,36 @@ public void afterFillForm(final Object dataObjArg) typeTxt.setText(typeTitles[agentType]); } } - - boolean shouldBeVisible = agentType == Agent.PERSON || agentType == Agent.ORG; + /** + * This logic is in charge of hiding the Address Subview when Agent Type is Other or Group. + * This Business was removed in Specify 7, and is being removed in Specify 6 to maintain consistency + * See https://github.com/specify/specify7/pull/2702#issuecomment-1381057692 for additional information + */ +// boolean shouldBeVisible = agentType == Agent.PERSON || agentType == Agent.ORG; +// final Component addrSubView = formViewObj.getCompById("9"); +// if (addrSubView != null) +// { +// boolean isVisible = addrSubView.isVisible(); +// if (!isVisible != shouldBeVisible) +// { +// SwingUtilities.invokeLater(new Runnable() { +// public void run() +// { +// Component topComp = UIHelper.getWindow(addrSubView); +// Component topMost = UIRegistry.getTopWindow(); +// if (topComp != topMost && topComp != null) +// { +// ((Window)topComp).pack(); +// } +// } +// }); +// } +// addrSubView.setVisible(shouldBeVisible); +// } final Component addrSubView = formViewObj.getCompById("9"); if (addrSubView != null) { - boolean isVisible = addrSubView.isVisible(); - if (!isVisible != shouldBeVisible) - { - SwingUtilities.invokeLater(new Runnable() { - public void run() - { - Component topComp = UIHelper.getWindow(addrSubView); - Component topMost = UIRegistry.getTopWindow(); - if (topComp != topMost && topComp != null) - { - ((Window)topComp).pack(); - } - } - }); - } - addrSubView.setVisible(shouldBeVisible); + addrSubView.setVisible(true); } } @@ -643,18 +641,23 @@ public void beforeMerge(final Object dataObj, final DataProviderSessionIFace ses @Override public boolean beforeSaveCommit(Object dataObj, DataProviderSessionIFace session) throws Exception { - Agent agent = (Agent)dataObj; - byte agentType = agent.getAgentType(); - - if (agent.getAddresses().size() > 0 && - (agentType == Agent.OTHER || agentType == Agent.GROUP)) - { - for (Address addr : new ArrayList
(agent.getAddresses())) - { - agent.removeReference(addr, "addresses"); - session.delete(addr); - } - } + /** + * This logic is in charge of ensuring Addresses for Agent's of type Other or Group do not get saved + * This Business was removed in Specify 7, and is being removed in Specify 6 to maintain consistency + * See https://github.com/specify/specify7/pull/2702#issuecomment-1381057692 for additional information + */ +// Agent agent = (Agent)dataObj; +// byte agentType = agent.getAgentType(); +// +// if (agent.getAddresses().size() > 0 && +// (agentType == Agent.OTHER || agentType == Agent.GROUP)) +// { +// for (Address addr : new ArrayList
(agent.getAddresses())) +// { +// agent.removeReference(addr, "addresses"); +// session.delete(addr); +// } +// } return super.beforeSaveCommit(dataObj, session); } From 8d3e1d9265e13aa1c417646c2daf1d252202f850 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:07:19 -0600 Subject: [PATCH 25/29] Remove WorldWind plugin on MACOS --- src/edu/ku/brc/af/ui/forms/ViewFactory.java | 8 ++++++++ .../ku/brc/specify/plugins/LocalityWorldWindPlugin.java | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/edu/ku/brc/af/ui/forms/ViewFactory.java b/src/edu/ku/brc/af/ui/forms/ViewFactory.java index 8884d7bd2..d2b87f91b 100644 --- a/src/edu/ku/brc/af/ui/forms/ViewFactory.java +++ b/src/edu/ku/brc/af/ui/forms/ViewFactory.java @@ -124,6 +124,7 @@ import edu.ku.brc.af.ui.forms.validation.ValidatedJPanel; import edu.ku.brc.af.ui.weblink.WebLinkButton; import edu.ku.brc.exceptions.ConfigurationException; +import edu.ku.brc.specify.plugins.LocalityWorldWindPlugin; import edu.ku.brc.specify.plugins.SeriesProcCatNumPlugin; import edu.ku.brc.ui.ColorChooser; import edu.ku.brc.ui.ColorWrapper; @@ -1096,6 +1097,13 @@ protected static UIPluginable createPlugin(final MultiView parent, } } } + } else if (uiPlugin instanceof LocalityWorldWindPlugin) + { + if (UIHelper.getOSType().equals(UIHelper.OSTYPE.MacOSX)) + { + log.error("The WorldWind plugin has been deprecated on MACOS and was hidden on the form"); + return null; + } } // This needs to be done before the initialize. diff --git a/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java b/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java index 4571d4255..44c4fabf1 100644 --- a/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java +++ b/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java @@ -49,6 +49,7 @@ import edu.ku.brc.specify.ui.WorldWindPanel; import edu.ku.brc.ui.CustomDialog; import edu.ku.brc.ui.IconManager; +import edu.ku.brc.ui.UIHelper; import edu.ku.brc.ui.UIRegistry; import edu.ku.brc.util.Pair; import edu.ku.brc.util.LatLonConverter.FORMAT; @@ -324,6 +325,11 @@ public String getTitle() @Override public void initialize(final Properties properties, final boolean isViewMode) { + if (UIHelper.getOSType().equals(UIHelper.OSTYPE.MacOSX)) + { + return; + } + this.isViewMode = isViewMode; setIcon(IconManager.getIcon("WorldWind", IconManager.STD_ICON_SIZE.Std16)); From 6de8023fa8231fd13c8482398105f82beacb7697 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:51:50 -0600 Subject: [PATCH 26/29] Remove regex support from field format editor These changes are not compatible with Specify 7, so they will be removed in favor of a future implementation in Specify 7 --- .../ui/forms/formatters/UIFieldFormatter.java | 13 +-- .../formatters/UIFieldFormatterField.java | 64 +------------ .../formatters/UIFieldFormatterIFace.java | 2 - .../formatters/UIFormatterEditorDlg.java | 93 +------------------ .../validation/ValFormattedTextField.java | 18 +--- 5 files changed, 11 insertions(+), 179 deletions(-) diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java index eff0a4f4e..8295e2a2a 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatter.java @@ -616,14 +616,7 @@ public String toPattern() StringBuilder str = new StringBuilder(); for (UIFieldFormatterField field : fields) { - if (field.getType() == UIFieldFormatterField.FieldType.regex) - { - str.append(field.formatRegexValue()); - } else - { - str.append(field.getValue()); - } - + str.append(field.getValue()); } return str.toString(); } @@ -828,10 +821,6 @@ public String toString() { val = field.getSample(); } - if (field.type == FieldType.regex) - { - val = field.formatRegexValue(); - } str.append(val); } str.append("]"); diff --git a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java index 7bfadd1e7..f186da238 100644 --- a/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java +++ b/src/edu/ku/brc/af/ui/forms/formatters/UIFieldFormatterField.java @@ -49,13 +49,6 @@ public enum FieldType {numeric, alphanumeric, alpha, separator, year, anychar, c protected int minSize; protected String value; protected String regex; - - /* - * customPattern is currently used for regex type FormatterFields - * in the FieldFormatter Editor (see {@code UIFormatterEditorDlg} - * and lets the user define a custom pattern - */ - protected String customPattern; protected boolean incrementer; protected boolean byYear; @@ -123,8 +116,7 @@ public UIFieldFormatterField(final FieldType type, this.value = value; if (type.equals(FieldType.regex)) { this.regex = value; - this.customPattern = pattern; -// this.value = pattern; + this.value = pattern; } this.incrementer = incrementer; this.byYear = byYear; @@ -254,33 +246,6 @@ public String getValue() { return value == null ? "" : value; } - - /** - * Returns a string stripped of its regex value. - * Useful for determining the pattern to display for - * formatters with more than one field that contain a - * regex expression - * (see af.ui.forms.validation.ValFormattedTextField.java) - * - * @return value string stripped of its regex - */ - public String getNoRegexValue() - { - if (type == FieldType.regex) - { - return value == null ? "" : value.replace(regex, ""); - } - return value; - } - - public String formatRegexValue() - { - if (type == FieldType.regex) - { - return customPattern == null ? (value == null ? "" : value.replace(regex, "")) : customPattern; - } - return value; - } /** * @return @@ -334,13 +299,7 @@ public String getSample() { return value.substring(0, value.length()); } - - if (type == FieldType.regex) - { - return customPattern == null ? "" : customPattern; - - } - + if (sample.length() == 0) { return ""; @@ -373,10 +332,6 @@ public String getRegExp() { return "\\p{Digit}{" + getSize() + "}"; } } - if (type == FieldType.regex) - { - return value; - } if (type == FieldType.year) { return Integer.toString(Calendar.getInstance().get(Calendar.YEAR)); @@ -400,11 +355,6 @@ public String getRegExpGrp(int idx) { return result; } - public String getCustomPattern() - { - return customPattern; - } - public boolean isOptional() { return isOptional; } @@ -463,7 +413,6 @@ public void toXML(StringBuilder sb) sb.append(" 0); @@ -1068,8 +988,6 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) { fieldTxt.setBackground(currentTxtBGColor); fieldTxt.repaint(); - regexExpression.setBackground(currentTxtBGColor); - regexExpression.repaint(); currentTxtBGColor = null; } return true; @@ -1081,7 +999,6 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) { currentTxtBGColor = fieldTxt.getBackground(); fieldTxt.setBackground(Color.RED); - regexExpression.setBackground(Color.RED); } Toolkit.getDefaultToolkit().beep(); return false; @@ -1089,7 +1006,6 @@ protected boolean checkFieldLen(final int currLen, final int maxLen) } else if (currentTxtBGColor != null) { fieldTxt.setBackground(currentTxtBGColor); - regexExpression.setBackground(currentTxtBGColor); } return true; } @@ -1174,10 +1090,7 @@ protected void updateUIEnabled() case year : totalLen += 4; break; - - case regex : - totalLen += (Integer)regexSizeSpinner.getValue(); - break; + } } } diff --git a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java index 13fd43714..741224005 100644 --- a/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java +++ b/src/edu/ku/brc/af/ui/forms/validation/ValFormattedTextField.java @@ -420,7 +420,7 @@ protected void createUI() } else { - JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.formatRegexValue()); + JTextField tf = new BGTextField(f.getSize(), isViewOnly ? "" : f.getValue()); tfToAdd = tf; if (inx == 0) @@ -429,7 +429,7 @@ protected void createUI() @Override public void keyPressed(KeyEvent e) { -// checkForPaste(e); + checkForPaste(e); } }); } @@ -482,7 +482,7 @@ protected void changed(DocumentEvent e) cardPanel = new JPanel(cardLayout); cardPanel.add("edit", tf); - viewTF = new BGTextField(f.getSize(), isViewOnly ? "" : f.formatRegexValue()); + viewTF = new BGTextField(f.getSize(), isViewOnly ? "" : f.getValue()); viewTF.setDocument(document); cardPanel.add("view", viewTF); @@ -1187,16 +1187,8 @@ public String getFmtVal(final String strValue, final Object value) { needsUpdating = (StringUtils.isEmpty(strValue) || strValue.length() != formatter.getLength() || strValue.contains("#")) && formatter.getAutoNumber() != null && formatter.isIncrementer(); - /* - * This sets the whole pattern of the format into the textbox - * -not just the transparent placeholder- when a formatter has - * another field beside numeric auto-increment. - * Disabling this will maintain consistency for solo numeric increment - * formatters. - * See (https://github.com/specify/specify6/issues/1190) - */ -// fmtVal = (String)formatter.formatToUI(strValue); - fmtVal = strValue; + fmtVal = (String)formatter.formatToUI(strValue); + } else { if (value == null) { From 59cfae5ccc41be7e3830d4cfbb5f81b3c8503940 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Fri, 17 Feb 2023 15:53:15 -0600 Subject: [PATCH 27/29] Allow Taxon to be deleted with TaxonCitations Fixes #1021 --- .../ku/brc/specify/datamodel/busrules/TaxonBusRules.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/edu/ku/brc/specify/datamodel/busrules/TaxonBusRules.java b/src/edu/ku/brc/specify/datamodel/busrules/TaxonBusRules.java index 97884b69e..552e28372 100644 --- a/src/edu/ku/brc/specify/datamodel/busrules/TaxonBusRules.java +++ b/src/edu/ku/brc/specify/datamodel/busrules/TaxonBusRules.java @@ -141,11 +141,7 @@ public boolean okToEnableDelete(Object dataObj) if (dataObj instanceof Taxon) { Taxon taxon = (Taxon)dataObj; - int citCnt = BasicSQLUtils.getCountAsInt("SELECT COUNT(*) FROM taxoncitation WHERE TaxonID = " + taxon.getId()); - if (citCnt < 1) - { - return super.okToDeleteNode(taxon); - } + return super.okToDeleteNode(taxon); } else if (dataObj instanceof TaxonTreeDefItem) { From 3167d01e2bd2b8898339390bc33eb6da7bf58fd2 Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 22 Feb 2023 14:37:03 -0600 Subject: [PATCH 28/29] Ensure WorldWind is not accessed on MacOS --- .../ku/brc/specify/plugins/LocalityWorldWindPlugin.java | 6 ++---- src/edu/ku/brc/specify/ui/WorldWindPanel.java | 9 ++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java b/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java index 44c4fabf1..f7d3f9477 100644 --- a/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java +++ b/src/edu/ku/brc/specify/plugins/LocalityWorldWindPlugin.java @@ -90,7 +90,7 @@ public LocalityWorldWindPlugin() { super(); - if (worldWindEnabled) { + if (worldWindEnabled || !UIHelper.getOSType().equals(UIHelper.OSTYPE.MacOSX)) { wwPanel = new WorldWindPanel(false); wwPanel.setPreferredSize(new Dimension(900, 700)); wwPanel.setZoomInMeters(600000.0); @@ -103,13 +103,11 @@ public LocalityWorldWindPlugin() @Override protected void doButtonAction() { - if (!worldWindEnabled) { + if (!worldWindEnabled || UIHelper.getOSType().equals(UIHelper.OSTYPE.MacOSX)) { UIRegistry.showLocalizedMsg("LocalityWorldWindPlugin.WorldWindDisabled"); return; } - - final List items = new Vector(); Pair llPair = latLonPlugin.getLatLon(); diff --git a/src/edu/ku/brc/specify/ui/WorldWindPanel.java b/src/edu/ku/brc/specify/ui/WorldWindPanel.java index 3d5de3197..2c939e6e5 100644 --- a/src/edu/ku/brc/specify/ui/WorldWindPanel.java +++ b/src/edu/ku/brc/specify/ui/WorldWindPanel.java @@ -20,6 +20,7 @@ package edu.ku.brc.specify.ui; import edu.ku.brc.services.mapping.LatLonPlacemarkIFace; +import edu.ku.brc.ui.UIHelper; import edu.ku.brc.util.Pair; import gov.nasa.worldwind.Model; import gov.nasa.worldwind.View; @@ -116,7 +117,7 @@ public class WorldWindPanel extends JPanel */ public WorldWindPanel() throws HeadlessException { - this(true); + this(true); } /** @@ -124,7 +125,9 @@ public WorldWindPanel() throws HeadlessException */ public WorldWindPanel(final boolean includeGazetter) throws HeadlessException { + super(); + this.includeGazetter = includeGazetter; init(); @@ -135,6 +138,10 @@ public WorldWindPanel(final boolean includeGazetter) throws HeadlessException */ protected void init() { + if (UIHelper.getOSType().equals(UIHelper.OSTYPE.MacOSX)) + { + return; + } if (world == null) { try From cce5ce92961251035116fdaa9cf9d1da6788eebf Mon Sep 17 00:00:00 2001 From: Jason Melton <64045831+melton-jason@users.noreply.github.com> Date: Wed, 1 Mar 2023 15:59:48 -0600 Subject: [PATCH 29/29] Update release notes --- packaging/readme.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/readme.html b/packaging/readme.html index de62bffd3..20694b332 100644 --- a/packaging/readme.html +++ b/packaging/readme.html @@ -6,6 +6,6 @@

Greetings from the Specify Collections Consortium Lab!
-

Release Notes for Specify 6.8.02 are available here.

+

Release Notes for Specify 6.8.03 are available here.