diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d3af45418958bdca7003e7d04786844be9232c4..ed82840733ada3c021707d732dd4446a8aa923ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## Sprint 91 - v3.9.9 + +- Pas de mise à jour de modèle + + ## Sprint 90 - v3.9.8 - Pas de mise à jour de modèle diff --git a/pom.xml b/pom.xml index 686ff01a41b0de6665c4ad4170d88408efcbb6a0..37efac1cb489074950695555f7699025ecad0fc7 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ true - 3.6.13 + 3.6.14-SNAPSHOT 3.0.3 diff --git a/reefdb-core/src/test/java/fr/ifremer/reefdb/dto/ReefDbBeansTest.java b/reefdb-core/src/test/java/fr/ifremer/reefdb/dto/ReefDbBeansTest.java index c53ff90393f0e87468b4c1eacb912909975579ef..8f0f57ab037d17c0204c2faa6c42652bfd504f90 100644 --- a/reefdb-core/src/test/java/fr/ifremer/reefdb/dto/ReefDbBeansTest.java +++ b/reefdb-core/src/test/java/fr/ifremer/reefdb/dto/ReefDbBeansTest.java @@ -24,11 +24,14 @@ package fr.ifremer.reefdb.dto; */ import fr.ifremer.quadrige3.core.dao.referential.UnitId; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; /** * @author ludovic.pecquot@e-is.pro on 13/04/2017. @@ -54,4 +57,38 @@ public class ReefDbBeansTest { Assert.assertEquals(60, result.intValue()); } + + @Test + public void testReduce() { + + List beans = new ArrayList<>(); + { + MeasurementDTO bean = ReefDbBeanFactory.newMeasurementDTO(); + bean.setId(1); + beans.add(bean); + } + { + MeasurementDTO bean = ReefDbBeanFactory.newMeasurementDTO(); + bean.setId(-2); + beans.add(bean); + } + { + MeasurementDTO bean = ReefDbBeanFactory.newMeasurementDTO(); + bean.setId(null); + beans.add(bean); + } + { + MeasurementDTO bean = ReefDbBeanFactory.newMeasurementDTO(); + bean.setId(4); + beans.add(bean); + } + + int minNegativeId = beans.stream() + .filter(measurementDTO -> measurementDTO.getId() != null) + .mapToInt(MeasurementDTO::getId) + .min().orElse(0); + + Assert.assertEquals(-2, minNegativeId); + + } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/SaveAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/SaveAction.java index 5d7b6d1011a2920d5459d568f8474cf0ef96ca3b..afdaffc3f95b1eef8ddf4ec8260a8a28c73cb1cc 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/SaveAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/SaveAction.java @@ -82,10 +82,13 @@ public class SaveAction extends AbstractReefDbSaveAction getModel().setModify(false)); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIHandler.java index 4b8de7aa4bdc2ff1de40f221fc4a3d9b3cf1ad30..dc0e74d22f24f0b22e15d16b9d1b272474d60477 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIHandler.java @@ -23,6 +23,7 @@ package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement; * #L% */ +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; @@ -56,10 +57,7 @@ import org.nuiton.jaxx.application.swing.tab.TabHandler; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.math.BigDecimal; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import static org.nuiton.i18n.I18n.t; @@ -114,16 +112,16 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler { @@ -135,9 +133,9 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler { @@ -180,17 +178,37 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler eventMap = new HashMap<>(ImmutableMap.of( + OperationMeasurementsUngroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, false, + OperationMeasurementsGroupedTableUIModel.EVENT_INDIVIDUAL_MEASUREMENTS_LOADED, false + )); + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (isEventComplete(evt.getPropertyName())) { + // detect if the triplet of PMFM for transition length + detectPmfmForTransitionCalculator(); + detectPitPmfmForGridInitialization(); + resetEventMap(); + } + } + + private boolean isEventComplete(String propertyName) { + if (eventMap.containsKey(propertyName)) + eventMap.put(propertyName, true); + return eventMap.values().stream().allMatch(aBoolean -> aBoolean); + } + + private void resetEventMap() { + eventMap.keySet().forEach(key -> eventMap.put(key, false)); + } + + }; // add listeners on table models - getModel().getUngroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsUngroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, evt -> { - // detect if the triplet of PMFM for transition length - detectPmfmForTransitionCalculator(); - detectPitPmfmForGridInitialization(); - }); - getModel().getGroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsGroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, evt -> { - // detect if the triplet of PMFM for transition length - detectPmfmForTransitionCalculator(); - detectPitPmfmForGridInitialization(); - }); + getModel().getUngroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsUngroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, loadListener); + getModel().getGroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsGroupedTableUIModel.EVENT_INDIVIDUAL_MEASUREMENTS_LOADED, loadListener); // Add listeners on PROPERTY_ROWS_IN_ERROR to catch modifications and revalidate getModel().getUngroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsUngroupedTableUIModel.PROPERTY_ROWS_IN_ERROR, evt -> { @@ -218,7 +236,7 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler taxonGroups = getModel().getObservationUIHandler().getAvailableTaxonGroups(taxon,forceNoFilter); + List taxonGroups = getModel().getObservationUIHandler().getAvailableTaxonGroups(taxon, forceNoFilter); getUI().getSelectionGroupeTaxonCombo().setData(taxonGroups); @@ -287,7 +305,7 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler pmfmStrategies = ReefDbBeans.filterCollection(survey.getPmfmStrategies(), input -> input != null && input.isSampling()); // list available samplings - getUI().getSelectionPrelevementsCombo().setData(getModel().getSamplings()); + getUI().getSelectionPrelevementsCombo().setData(getModel().getSamplingOperations()); // Load ungrouped data (up table) { @@ -301,9 +319,9 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler transitionLengthPmfmTriplets = getConfig().getCalculatedTransitionLengthPmfmTriplets(); - for (Integer[] transitionLengthPmfmTriplet: transitionLengthPmfmTriplets) { + for (Integer[] transitionLengthPmfmTriplet : transitionLengthPmfmTriplets) { int transitionLengthPmfmId = transitionLengthPmfmTriplet[0]; int startPositionPmfmId = transitionLengthPmfmTriplet[1]; @@ -435,7 +453,6 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler startPositionMap; @@ -625,4 +649,25 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandlergetSamplings.

+ *

getSamplingOperations.

* * @return a {@link java.util.List} object. */ - public List getSamplings() { + public List getSamplingOperations() { return observationModel == null ? null : (List) observationModel.getSamplingOperations(); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/OperationMeasurementsGroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/OperationMeasurementsGroupedTableUIHandler.java index 2f82263e21024dfa321f76f27ebbdb4bc11add71..a646097107f882c1a9e66fa4a9e0a7f8ffbfdc58 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/OperationMeasurementsGroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/OperationMeasurementsGroupedTableUIHandler.java @@ -24,7 +24,6 @@ package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.gro */ import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import fr.ifremer.quadrige3.core.dao.technical.AlphanumericComparator; import fr.ifremer.quadrige3.ui.swing.table.ColumnIdentifier; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; @@ -51,8 +50,6 @@ import javax.swing.RowFilter; import javax.swing.border.Border; import java.math.BigDecimal; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -226,23 +223,17 @@ public class OperationMeasurementsGroupedTableUIHandler // remove measurement from old sampling if (oldValue != null) { SamplingOperationDTO oldSamplingOperation = (SamplingOperationDTO) oldValue; - oldSamplingOperation.removeAllIndividualMeasurements(row.getIndividualMeasurements()); - oldSamplingOperation.setDirty(true); - resetIndividualMeasurementIds(row); + setDirty(oldSamplingOperation); } // recalculate individual id if (newValue != null) { // affect new sampling operation now - row.setSamplingOperation((SamplingOperationDTO) newValue); - - // calculate new individual ids - calculateIndividualIds(row); - - // fire event for parent listener - getModel().firePropertyChanged(OperationMeasurementsGroupedTableUIModel.PROPERTY_SAMPLING_OPERATION, null, newValue); + SamplingOperationDTO newSamplingOperation = (SamplingOperationDTO) newValue; + row.setSamplingOperation(newSamplingOperation); + setDirty(newSamplingOperation); } } @@ -250,36 +241,6 @@ public class OperationMeasurementsGroupedTableUIHandler super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue); } - @Override - protected void onDuplicatedRowAdded(OperationMeasurementsGroupedRowModel row) { - // send update event on sampling operation - if (row.getSamplingOperation() != null) { - getModel().firePropertyChanged(OperationMeasurementsGroupedTableUIModel.PROPERTY_SAMPLING_OPERATION, null, row.getSamplingOperation()); - } - } - - @Override - protected void resetIndividualMeasurementIds(OperationMeasurementsGroupedRowModel row) { - - // before, remove those measurements from sampling operation - if (row.getSamplingOperation() != null) { - row.getSamplingOperation().removeAllIndividualMeasurements(row.getIndividualMeasurements()); - } - - super.resetIndividualMeasurementIds(row); - } - - /** - * the predicate test if the row is attached to the bean (=SamplingOperationDTO) - * - * @param bean the bean - * @return the predicate for sampling operation - */ - @Override - protected Predicate getRowForBeanPredicate(MeasurementAware bean) { - return (Predicate) row -> Objects.equals(bean, row.getSamplingOperation()); - } - @Override protected MeasurementAware getMeasurementAwareModelForRow(OperationMeasurementsGroupedRowModel row) { return row.getSamplingOperation(); @@ -381,30 +342,15 @@ public class OperationMeasurementsGroupedTableUIHandler } @Override - protected void removeIndividualMeasurements(List measurementToDelete) { - - // updated sampling operation - Set updatedSamplingOperations = Sets.newHashSet(); - - // Remove from model - for (MeasurementDTO deletedMeasurement : measurementToDelete) { - if (deletedMeasurement.getSamplingOperation() != null) { - deletedMeasurement.getSamplingOperation().removeIndividualMeasurements(deletedMeasurement); - updatedSamplingOperations.add(deletedMeasurement.getSamplingOperation()); - } - } - getModel().setModify(true); - - // final update - for (SamplingOperationDTO updatedSamplingOperation : updatedSamplingOperations) { - updatedSamplingOperation.setDirty(true); - getModel().firePropertyChanged(OperationMeasurementsGroupedTableUIModel.PROPERTY_SAMPLING_OPERATION, null, updatedSamplingOperation); - } + protected boolean isMeasurementNotEmpty(MeasurementDTO measurement) { + return !measurement.getPmfm().getId().equals(getModel().getPitTransitionLengthPmfmId()) && super.isMeasurementNotEmpty(measurement); } @Override - protected boolean isMeasurementNotEmpty(MeasurementDTO measurement) { - return !measurement.getPmfm().getId().equals(getModel().getPitTransitionLengthPmfmId()) && super.isMeasurementNotEmpty(measurement); + protected void setDirty(MeasurementAware bean) { + super.setDirty(bean); + if (bean instanceof SamplingOperationDTO) + getModel().firePropertyChanged(OperationMeasurementsGroupedTableUIModel.PROPERTY_SAMPLING_OPERATION, null, bean); } /** @@ -440,16 +386,11 @@ public class OperationMeasurementsGroupedTableUIHandler List rows = Lists.newArrayList(); for (SamplingOperationDTO samplingOperation : initModel.getResultMap().keySet()) { - AtomicInteger individualId = new AtomicInteger(); for (Integer transition : initModel.getResultMap().get(samplingOperation)) { - // Compute next individual id - incrementNextIndividualId(samplingOperation, individualId); // Initialize the row OperationMeasurementsGroupedRowModel row = createNewRow(false, samplingOperation); - // Set the individualId - row.setIndividualId(individualId.get()); // Affect individual pmfms from parent model row.setIndividualPmfms(new ArrayList<>(getModel().getPmfms())); // Create empty measurements @@ -459,13 +400,12 @@ public class OperationMeasurementsGroupedTableUIHandler if (measurement == null) { throw new ReefDbTechnicalException("No transition measurement found"); } - // Set its value and individualId + // Set its value measurement.setNumericalValue(BigDecimal.valueOf(transition)); - measurement.setIndividualId(individualId.get()); row.setValid(true); rows.add(row); } - samplingOperation.setDirty(true); + setDirty(samplingOperation); } resetCellEditors(); @@ -474,6 +414,20 @@ public class OperationMeasurementsGroupedTableUIHandler } } + @Override + protected boolean isRowToSave(OperationMeasurementsGroupedRowModel row) { + boolean toSave = super.isRowToSave(row); + + if (toSave && getModel().getPitTransitionLengthPmfmId() != null) { + // If this row has been initialized but nothing else has been set, it can be ignored + Set pmfmIds = ReefDbBeans.getPmfmIdsOfNonEmptyIndividualMeasurements(row); + pmfmIds.remove(getModel().getPitTransitionLengthPmfmId()); + toSave = !pmfmIds.isEmpty() || row.hasTaxonInformation(); + } + + return toSave; + } + public void editSelectedMeasurements() { OperationMeasurementsMultiEditUI editUI = new OperationMeasurementsMultiEditUI(getUI()); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java index 5428fb86287da3734530f7845d73021cd9e2a56b..0dfe0cec51e1536c4bd78afeb098c57c5a4d7e4f 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java @@ -31,6 +31,7 @@ import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO; import fr.ifremer.reefdb.dto.enums.FilterTypeValues; import fr.ifremer.reefdb.dto.referential.DepartmentDTO; +import fr.ifremer.reefdb.service.ReefDbTechnicalException; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler; import jaxx.runtime.SwingUtil; import org.apache.commons.collections4.CollectionUtils; @@ -38,6 +39,8 @@ import org.jdesktop.swingx.table.TableColumnExt; import javax.swing.RowFilter; import javax.swing.SwingUtilities; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import static org.nuiton.i18n.I18n.t; @@ -115,7 +118,7 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb private void updateDepartmentCellEditor(boolean forceNoFilter) { departmentCellEditor.getCombo().setActionEnabled(!forceNoFilter - && getContext().getDataContext().isContextFiltered(FilterTypeValues.DEPARTMENT)); + && getContext().getDataContext().isContextFiltered(FilterTypeValues.DEPARTMENT)); departmentCellEditor.getCombo().setData(getContext().getObservationService().getAvailableDepartments(forceNoFilter)); } @@ -141,16 +144,16 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb uninstallSaveTableStateListener(); addPmfmColumns( - getModel().getPmfms(), - SamplingOperationDTO.PROPERTY_PMFMS, - DecoratorService.NAME_WITH_UNIT); // insert at the end + getModel().getPmfms(), + SamplingOperationDTO.PROPERTY_PMFMS, + DecoratorService.NAME_WITH_UNIT); // insert at the end boolean notEmpty = CollectionUtils.isNotEmpty(getModel().getPmfms()); // tell the table model is editable or not getTableModel().setReadOnly(!getModel().getSurvey().isEditable()); - getModel().setBeans(getModel().getSamplings()); + getModel().setBeans(getModel().getSamplingOperations()); if (notEmpty) { for (OperationMeasurementsUngroupedRowModel row : getModel().getRows()) { // set analyst from first non null measurement @@ -159,8 +162,8 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb row.setAnalyst(measurementFound.get().getAnalyst()); } else { row.setAnalyst(getContext().getProgramStrategyService().getAnalysisDepartmentOfAppliedStrategyBySurvey( - getModel().getSurvey(), - getModel().getPmfms() + getModel().getSurvey(), + getModel().getPmfms() )); } } @@ -197,7 +200,7 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb @Override public boolean include(Entry entry) { return getModel().getSamplingFilter() == null - || getModel().getSamplingFilter().getName().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsUngroupedTableModel.NAME).getModelIndex())); + || getModel().getSamplingFilter().getName().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsUngroupedTableModel.NAME).getModelIndex())); } }); } @@ -216,21 +219,26 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue); - // save modifications to parent model - // be careful, table beans can be filtered, so use detection to save measurements - for (SamplingOperationDTO samplingOperationToSave : getModel().getSurvey().getSamplingOperations()) { + row.setDirty(true); - // use QuadrigeBean comparator - if (samplingOperationToSave.getId().equals(row.getId())) { + } - // update all measurements - row.getMeasurements().forEach(measurement -> measurement.setAnalyst(row.getAnalyst())); + public void save() { - samplingOperationToSave.setMeasurements(row.getMeasurements()); - samplingOperationToSave.setDirty(true); - break; - } - } + Map rowById = new HashMap<>(); + getModel().getRows().forEach(row -> rowById.put(row.getId(), row)); + + getModel().getSamplingOperations().forEach(samplingOperation -> { + OperationMeasurementsUngroupedRowModel row = rowById.get(samplingOperation.getId()); + if (row == null) + throw new ReefDbTechnicalException("Unable to find the row for sampling operation id=" + samplingOperation.getId()); + + // update all measurements + row.getMeasurements().forEach(measurement -> measurement.setAnalyst(row.getAnalyst())); + + // affect measurements + samplingOperation.setMeasurements(row.getMeasurements()); + }); } @@ -246,8 +254,8 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb if (row.getAnalyst() == null && row.getMeasurements().stream().anyMatch(measurement -> !ReefDbBeans.isMeasurementEmpty(measurement))) { ReefDbBeans.addError(row, - t("reefdb.validator.error.analyst.required"), - OperationMeasurementsUngroupedRowModel.PROPERTY_ANALYST); + t("reefdb.validator.error.analyst.required"), + OperationMeasurementsUngroupedRowModel.PROPERTY_ANALYST); return false; } return true; @@ -260,16 +268,16 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb // Colonne mnemonique final TableColumnExt colMnemonic = addColumn( - OperationMeasurementsUngroupedTableModel.NAME); + OperationMeasurementsUngroupedTableModel.NAME); colMnemonic.setSortable(true); colMnemonic.setEditable(false); setDefaultColumnMinWidth(colMnemonic); // Add analyst column (Mantis #42619) TableColumnExt analystColumn = addColumn( - departmentCellEditor, - newTableCellRender(OperationMeasurementsUngroupedTableModel.ANALYST), - OperationMeasurementsUngroupedTableModel.ANALYST + departmentCellEditor, + newTableCellRender(OperationMeasurementsUngroupedTableModel.ANALYST), + OperationMeasurementsUngroupedTableModel.ANALYST ); analystColumn.setMinWidth(100); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java index 6e830aba2ebdc61c5b69771ddc8a8df6e8b08d34..073fe62742d806dbbb928ea7e9222bf259c7ae5c 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java @@ -71,11 +71,11 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa } /** - *

getSamplings.

+ *

getSamplingOperations.

* * @return a {@link java.util.List} object. */ - public List getSamplings() { + public List getSamplingOperations() { return survey == null ? null : (List) survey.getSamplingOperations(); } @@ -106,8 +106,8 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa */ public List getAllMeasurements() { List measurements = Lists.newArrayList(); - if (getSamplings() != null) { - for (SamplingOperationDTO samplingOperation : getSamplings()) { + if (getSamplingOperations() != null) { + for (SamplingOperationDTO samplingOperation : getSamplingOperations()) { measurements.addAll(samplingOperation.getMeasurements()); } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/PhotosTabUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/PhotosTabUIHandler.java index 75c400e0489e775d23a62d21bf05b0d70cb39b07..f270aa82bee0fe106aa42635f15341ee56e381e8 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/PhotosTabUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/PhotosTabUIHandler.java @@ -412,9 +412,9 @@ public class PhotosTabUIHandler extends AbstractReefDbTableUIHandlersaveActualModel.

+ *

save.

*/ - public void saveActualModel() { + public void save() { getModel().setModelAdjusting(true); getModel().getObservationModel().setPhotos(getModel().getBeans()); getModel().setModelAdjusting(false); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java index 3227c3e215f981abc964a225f61eba194febd306..8db3b60ed49e1b2977990a47726f372817eedeed 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java @@ -319,6 +319,15 @@ public abstract class AbstractMeasurementsGroupedRowModel !ReefDbBeans.isMeasurementEmpty(measurement)); + } + + /** * Return a unique hashCode for the row * diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java index a35bc881318a01a9191a87ed6e3c3095d093bdab..d13074ab3f85f51a28af664bc52b875d45893196 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java @@ -24,14 +24,13 @@ package fr.ifremer.reefdb.ui.swing.content.observation.shared; */ import com.google.common.base.Joiner; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import fr.ifremer.quadrige3.core.dao.technical.Assert; import fr.ifremer.quadrige3.core.dao.technical.factorization.pmfm.AllowedQualitativeValuesMap; import fr.ifremer.quadrige3.ui.core.dto.DirtyAware; -import fr.ifremer.quadrige3.ui.swing.table.AbstractTableUIModel; -import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.quadrige3.ui.swing.table.editor.ExtendedComboBoxCellEditor; import fr.ifremer.reefdb.decorator.DecoratorService; import fr.ifremer.reefdb.dto.ErrorDTO; @@ -51,8 +50,8 @@ import fr.ifremer.reefdb.dto.referential.TaxonDTO; import fr.ifremer.reefdb.dto.referential.TaxonGroupDTO; import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; import fr.ifremer.reefdb.dto.referential.pmfm.QualitativeValueDTO; +import fr.ifremer.reefdb.service.ReefDbTechnicalException; import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedRowModel; -import fr.ifremer.reefdb.ui.swing.util.OneShotListener; import fr.ifremer.reefdb.ui.swing.util.ReefDbUI; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler; import fr.ifremer.reefdb.ui.swing.util.table.PmfmTableColumn; @@ -71,7 +70,6 @@ import java.awt.Dimension; import java.awt.Insets; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import java.util.stream.Collectors; import static org.nuiton.i18n.I18n.t; @@ -235,7 +233,7 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< loadMeasurements(); break; - case AbstractMeasurementsGroupedTableUIModel.EVENT_MEASUREMENTS_LOADED: + case AbstractMeasurementsGroupedTableUIModel.EVENT_INDIVIDUAL_MEASUREMENTS_LOADED: detectPreconditionedPmfms(); detectGroupedIdentifiers(); @@ -453,14 +451,6 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< // set default analyst from pmfm strategies (Mantis #42619) setDefaultAnalyst(newRow); - // now calculate individual id after table is sorted - if (getTable().getRowSorter().getSortKeys().isEmpty()) { - // Also use a OneShotListener (Mantis #51586) - OneShotListener.create(getModel(), AbstractTableUIModel.PROPERTY_ROWS, propertyChangeEvent -> calculateIndividualIds(newRow)); - } else { - OneShotListener.create(getTable(), SwingTable.PROPERTY_SORTED, propertyChangeEvent -> calculateIndividualIds(newRow)); - } - // reset the cell editors resetCellEditors(); @@ -493,59 +483,6 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< rows.forEach(row -> row.setAnalyst(analyst)); } - protected void calculateIndividualIds(R rowToUpdate) { - - calculateIndividualIds(getMeasurementAwareModelForRow(rowToUpdate)); - } - - protected void calculateIndividualIds(MeasurementAware bean) { - - if (bean == null) return; - - Predicate predicate = getRowForBeanPredicate(bean); - AtomicInteger individualId = new AtomicInteger(); - - // iterate over sorted rows and set incremental individualId (see Mantis #51520) - for (int i = 0; i < getTable().getRowCount(); i++) { - R row = getTableModel().getEntry(getTable().convertRowIndexToModel(i)); - if (predicate.test(row)) { - // increment and set row individual id - row.setIndividualId(individualId.incrementAndGet()); - // update all individual measurements - row.getIndividualMeasurements().forEach(measurement -> measurement.setIndividualId(individualId.get())); - } - } - - setDirty(bean); - } - - /** - * Increment the nextIndividualId to next unused individual id in rows - * - * @param bean the current bean - * @param nextIndividualId the counter to increment - */ - protected void incrementNextIndividualId(MeasurementAware bean, AtomicInteger nextIndividualId) { - - do { - nextIndividualId.incrementAndGet(); - } while (getModel().getRows().stream() - .filter(getRowForBeanPredicate(bean)) - .anyMatch(row -> Objects.equals(nextIndividualId.get(), row.getIndividualId()))); - - Assert.isTrue(nextIndividualId.get() > 0, "the next individual id must be > 0"); - } - - /** - * return a predicate to tell if the row is associated to the bean (true by default) - * - * @param bean the bean - * @return a predicate - */ - protected Predicate getRowForBeanPredicate(MeasurementAware bean) { - return (Predicate) r -> true; - } - protected void initAddedRow(R row) { if (getModel().getTaxonGroupFilter() != null) { row.setTaxonGroup(getModel().getTaxonGroupFilter()); @@ -604,7 +541,7 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< if (oldValue != newValue) { // save modifications ot the row to bean - saveMeasurementsInModel(row); +// saveMeasurementsInModel(row); // also recompute valid state on all rows recomputeRowsValidState(); @@ -614,54 +551,11 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< protected void resetIndividualMeasurementIds(R row) { if (row != null && CollectionUtils.isNotEmpty(row.getIndividualMeasurements())) { - for (MeasurementDTO individualMeasurement : row.getIndividualMeasurements()) { - individualMeasurement.setId(null); - } + row.getIndividualMeasurements().forEach(measurement -> measurement.setId(null)); } } - public void saveMeasurementsInModel(R row) { - Assert.notNull(row); - - if (!row.isValid()) return; - - MeasurementAware bean = getMeasurementAwareModelForRow(row); - Assert.notNull(bean); - - // existing measurements in bean (for this individualId) - List remainingMeasurements = ReefDbBeans.filterCollection(bean.getIndividualMeasurements(), - input -> input != null && input.getId() != null && Objects.equals(row.getIndividualId(), input.getIndividualId())); - - // get stored individual measurement by id - List existingIndividualMeasurementIds = ReefDbBeans.collectIds(bean.getIndividualMeasurements()); - // get the minimum negative measurement id - int minNegativeId = CollectionUtils.isEmpty(existingIndividualMeasurementIds) ? 0 : Math.min(Collections.min(existingIndividualMeasurementIds), 0); - - // iterate individual measurement in row - for (MeasurementDTO individualMeasurement : row.getIndividualMeasurements()) { - - if (individualMeasurement.getId() == null) { - // this measurement was not in bean, so add it with next negative id - individualMeasurement.setId(--minNegativeId); - // add to bean - bean.getIndividualMeasurements().add(individualMeasurement); - } - - // update this measurement - updateMeasurementFromRow(individualMeasurement, row); - - // remove if existing - remainingMeasurements.remove(individualMeasurement); - } - - // Remove remaining - bean.getIndividualMeasurements().removeAll(remainingMeasurements); - - setDirty(bean); - - } - - private void setDirty(Object bean) { + protected void setDirty(MeasurementAware bean) { if (bean instanceof DirtyAware) ((DirtyAware) bean).setDirty(true); } @@ -678,18 +572,10 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< public void removeIndividualMeasurements() { if (getModel().getSelectedRows().isEmpty()) { - LOG.warn("Aucune mesure de selectionnee"); + LOG.warn("Can't remove rows: no row selected"); return; } - // Selected measurement - List measurementToDelete = Lists.newArrayList(); - for (final R row : getModel().getSelectedRows()) { - if (CollectionUtils.isNotEmpty(row.getIndividualMeasurements())) { - measurementToDelete.addAll(row.getIndividualMeasurements()); - } - } - if (askBeforeDelete(t("reefdb.action.delete.survey.measurement.titre"), t("reefdb.action.delete.survey.measurement.message"))) { // Get distinct models to update after rows removed @@ -700,25 +586,20 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< // Remove from table getModel().deleteSelectedRows(); - // Remove from model - removeIndividualMeasurements(measurementToDelete); - - // Recalculate individual ids - modelsToUpdate.forEach(this::calculateIndividualIds); - + modelsToUpdate.forEach(this::setDirty); + getModel().setModify(true); recomputeRowsValidState(); } } - protected abstract void removeIndividualMeasurements(List measurementToDelete); - public void duplicateSelectedRow() { if (getModel().getSelectedRows().size() == 1 && getModel().getSingleSelectedRow() != null) { R rowToDuplicate = getModel().getSingleSelectedRow(); - R row = createNewRow(false, getMeasurementAwareModelForRow(rowToDuplicate)); + MeasurementAware bean = getMeasurementAwareModelForRow(rowToDuplicate); + R row = createNewRow(false, bean); row.setTaxonGroup(rowToDuplicate.getTaxonGroup()); row.setTaxon(rowToDuplicate.getTaxon()); row.setInputTaxonId(rowToDuplicate.getInputTaxonId()); @@ -732,21 +613,14 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< // Add duplicate measurement to table getModel().insertRowAfterSelected(row); - // save directly to sampling operation - saveMeasurementsInModel(row); - - onDuplicatedRowAdded(row); + setDirty(bean); recomputeRowsValidState(); getModel().setModify(true); setFocusOnCell(row); } } - protected void onDuplicatedRowAdded(R row) { - // nothing by default - } - /* validation section */ /** @@ -823,59 +697,6 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< AbstractMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_PMFMS)); })); - // old algo (too long with many rows) -// for (R row : getModel().getRows()) { -// for (R otherRow : getModel().getRows()) { -// if (otherRow == row /*|| (otherRow.getTaxonGroup() == null && otherRow.getTaxon() == null)*/) continue; -// -// if (row.isSameRow(otherRow) -// // Both measurements must have same non empty measurements (Mantis #42170) -// && ReefDbBeans.haveSameMeasurements(row.getIndividualMeasurements(), otherRow.getIndividualMeasurements()) -// ) { -// // if rows equals, check all measurement values -// boolean allValuesEquals = true; -// Set notNullMeasurementPmfmIds = Sets.newHashSet(); -// for (MeasurementDTO measurement : row.getIndividualMeasurements()) { -// -// // find the measurement with same pmfm in the other row -// MeasurementDTO otherMeasurement = ReefDbBeans.getIndividualMeasurementByPmfmId(otherRow, measurement.getPmfm().getId()); -// -// if (otherMeasurement != null) { -// if (measurement.getPmfm().getParameter().isQualitative()) { -// if (!Objects.equals(measurement.getQualitativeValue(), otherMeasurement.getQualitativeValue())) { -// allValuesEquals = false; -// break; -// } -// } else { -// if (!Objects.equals(measurement.getNumericalValue(), otherMeasurement.getNumericalValue())) { -// allValuesEquals = false; -// break; -// } -// } -// } -// -// // collect pmfm ids -// if (!ReefDbBeans.isMeasurementEmpty(measurement)) { -// notNullMeasurementPmfmIds.add(measurement.getPmfm().getId()); -// } -// } -// if (allValuesEquals) { -// -// // Mantis #0026890 The check for perfect duplicates is now a warning -// ReefDbBeans.addWarning(row, -// t("reefdb.measurement.grouped.duplicates"), row.getDefaultProperties().toArray(new String[0])); -// -// for (Integer pmfmId : notNullMeasurementPmfmIds) { -// ReefDbBeans.addWarning(row, -// t("reefdb.measurement.grouped.duplicates"), -// pmfmId, -// AbstractMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_PMFMS); -// } -// return; -// } -// } -// } -// } } protected boolean hasNoUnicityDuplicates(R row) { @@ -998,6 +819,14 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< for (Map.Entry> identifierByGroup : getModel().getIdentifiersByGroupedRuleMap().get(groupedRule)) { RuleGroupDTO group = identifierByGroup.getKey(); ReefDbColumnIdentifier identifier = identifierByGroup.getValue(); + + if (row.getMultipleValuesOnIdentifier().contains(identifier) + || (identifier instanceof ReefDbPmfmColumnIdentifier && row.getMultipleValuesOnPmfmIds().contains(((ReefDbPmfmColumnIdentifier) identifier).getPmfmId())) + ) { + groupResult = true; + break; + } + // For now, assume logical operator is always OR Assert.isTrue(group.isIsOr()); groupResult |= getContext().getControlRuleService().controlUniqueObject(group.getRule(), identifier.getValue(row)); @@ -1287,8 +1116,6 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } } - // save modifications - saveMeasurementsInModel(row); } // done @@ -1297,4 +1124,99 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } } + /** + * Save grouped measurements on parent model(s) + * This replace inline save (see Mantis #51725) + */ + public void save() { + + // Get all existing measurements in beans + List beansToSave = getMeasurementAwareModels(); + List existingMeasurements = beansToSave.stream() + .flatMap(bean -> bean.getIndividualMeasurements().stream()) + .collect(Collectors.toList()); + + // get the minimum negative measurement id + AtomicInteger minNegativeId = new AtomicInteger( + Math.min( + 0, + existingMeasurements.stream() + .filter(measurement -> measurement != null && measurement.getId() != null) + .mapToInt(MeasurementDTO::getId) + .min() + .orElse(0) + ) + ); + + Multimap rowsByBean = ArrayListMultimap.create(); + + // Get ordered rows by bean + for (int i = 0; i < getTable().getRowCount(); i++) { + R row = getTableModel().getEntry(getTable().convertRowIndexToModel(i)); + MeasurementAware bean = getMeasurementAwareModelForRow(row); + if (bean == null) { + throw new ReefDbTechnicalException("The parent bean is null for a grouped measurements row"); + } + rowsByBean.put(bean, row); + } + + rowsByBean.keySet().forEach(bean -> { + + AtomicInteger individualId = new AtomicInteger(); + List beanMeasurements = new ArrayList<>(); + + // Iterate over each row + rowsByBean.get(bean).forEach(row -> { + + // Test is this row is to save or not + if (isRowToSave(row)) { + + // Affect row individual ids according this order + row.setIndividualId(individualId.incrementAndGet()); + + // Iterate over row's measurements + row.getIndividualMeasurements().forEach(measurement -> { + if (measurement.getId() == null) { + // this measurement was not in bean, so add it with next negative id + measurement.setId(minNegativeId.decrementAndGet()); + } + // update this measurement + updateMeasurementFromRow(measurement, row); + // Add to new list + beanMeasurements.add(measurement); + }); + + } + }); + + // Affect new list of measurements + bean.getIndividualMeasurements().clear(); + bean.getIndividualMeasurements().addAll(beanMeasurements); + + setDirty(bean); + // Remove this bean from the list + beansToSave.remove(bean); + }); + + // Clean remaining beans + beansToSave.forEach(bean -> { + // If a bean still in this map, it means there is no row of this bean, so remove all + bean.getIndividualMeasurements().clear(); + setDirty(bean); + }); + } + + /** + * Determine if this row is to be saved + * + * @param row to test + * @return true if to save (default) + */ + protected boolean isRowToSave(R row) { + return + // The row must exists + row != null + // and contains at least 1 non empty individual measurement or a taxon group or a taxon + && (row.hasTaxonInformation() || row.hasNonEmptyMeasurements()); + } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java index f8fbca9d4b3a9cae849d5dbefedaacebb6fe2154..cd574f4f2b3b96edeb4256d896ff8aab22bfbe7d 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java @@ -53,7 +53,7 @@ public abstract class AbstractMeasurementsGroupedTableUIModel< public static final String PROPERTY_SURVEY = "survey"; public static final String PROPERTY_MEASUREMENT_FILTER = "measurementFilter"; - public static final String EVENT_MEASUREMENTS_LOADED = "measurementsLoaded"; + public static final String EVENT_INDIVIDUAL_MEASUREMENTS_LOADED = "individualMeasurementsLoaded"; // the survey model private ObservationUIModel survey; @@ -189,6 +189,6 @@ public abstract class AbstractMeasurementsGroupedTableUIModel< } public void fireMeasurementsLoaded() { - firePropertyChange(EVENT_MEASUREMENTS_LOADED, null, null); + firePropertyChange(EVENT_INDIVIDUAL_MEASUREMENTS_LOADED, null, null); } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java index ca251614895e28b17960dc3d31fb7a153e9fd631..dc1cd283c7762094d88eaf23b4e7836932c37ef8 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java @@ -197,12 +197,6 @@ public abstract class AbstractMeasurementsMultiEditUIHandler< // super.onRowsAdded(addedRows); } - @Override - public void saveMeasurementsInModel(R row) { - // Don't call super method; the selected rows will be saved after multi-line validation -// super.saveMeasurementsInModel(row); - } - @Override protected List getMeasurementAwareModels() { // nothing to return, this handler don't save model @@ -219,10 +213,6 @@ public abstract class AbstractMeasurementsMultiEditUIHandler< protected void filterMeasurements() { } - @Override - protected void removeIndividualMeasurements(List measurementToDelete) { - } - public void valid() { if (getModel().isValid()) { closeDialog(); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jaxx b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jaxx index 8de94ffbf9b7055af5637c15a170528510e06468..a7a92a500d5784ddc7e4acaf1cee3ac6c76a0a4b 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jaxx +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jaxx @@ -9,297 +9,302 @@ Affero General Public License along with this program. If not, see . #L% --> - - fr.ifremer.reefdb.ui.swing.ReefDbHelpBroker - fr.ifremer.reefdb.ui.swing.ReefDbUIContext - fr.ifremer.reefdb.ui.swing.util.ReefDbUI - fr.ifremer.quadrige3.ui.swing.ApplicationUI - fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil - fr.ifremer.quadrige3.ui.swing.component.coordinate.CoordinateEditor - fr.ifremer.quadrige3.ui.swing.component.coordinate.CoordinateEditor.CoordinateType - fr.ifremer.quadrige3.ui.swing.component.bean.ExtendedComboBox - fr.ifremer.quadrige3.ui.swing.component.bean.ExtendedBeanDoubleList + implements='fr.ifremer.reefdb.ui.swing.util.ReefDbUI<SurveyDetailsTabUIModel, SurveyDetailsTabUIHandler>'> + + fr.ifremer.reefdb.ui.swing.ReefDbHelpBroker + fr.ifremer.reefdb.ui.swing.ReefDbUIContext + fr.ifremer.reefdb.ui.swing.util.ReefDbUI + fr.ifremer.quadrige3.ui.swing.ApplicationUI + fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil + fr.ifremer.quadrige3.ui.swing.component.coordinate.CoordinateEditor + fr.ifremer.quadrige3.ui.swing.component.coordinate.CoordinateEditor.CoordinateType + fr.ifremer.quadrige3.ui.swing.component.bean.ExtendedComboBox + fr.ifremer.quadrige3.ui.swing.component.bean.ExtendedBeanDoubleList + fr.ifremer.quadrige3.ui.swing.plaf.WaitBlockingLayerUI - fr.ifremer.reefdb.dto.data.survey.CampaignDTO - fr.ifremer.reefdb.dto.configuration.programStrategy.ProgramDTO - fr.ifremer.reefdb.dto.referential.DepthDTO - fr.ifremer.reefdb.dto.referential.LocationDTO - fr.ifremer.reefdb.dto.referential.PositioningSystemDTO - fr.ifremer.reefdb.dto.referential.PersonDTO + fr.ifremer.reefdb.dto.data.survey.CampaignDTO + fr.ifremer.reefdb.dto.configuration.programStrategy.ProgramDTO + fr.ifremer.reefdb.dto.referential.DepthDTO + fr.ifremer.reefdb.dto.referential.LocationDTO + fr.ifremer.reefdb.dto.referential.PositioningSystemDTO + fr.ifremer.reefdb.dto.referential.PersonDTO - static org.nuiton.i18n.I18n.* + static org.nuiton.i18n.I18n.* - fr.ifremer.quadrige3.ui.swing.component.date.JDatePicker - fr.ifremer.quadrige3.ui.swing.component.date.JLocalDatePicker - fr.ifremer.quadrige3.ui.swing.component.time.LocalTimeEditor + fr.ifremer.quadrige3.ui.swing.component.date.JDatePicker + fr.ifremer.quadrige3.ui.swing.component.date.JLocalDatePicker + fr.ifremer.quadrige3.ui.swing.component.time.LocalTimeEditor - javax.swing.BoxLayout - javax.swing.JList + javax.swing.BoxLayout + javax.swing.JList - jaxx.runtime.swing.CardLayout2Ext + jaxx.runtime.swing.CardLayout2Ext - org.nuiton.jaxx.widgets.number.NumberEditor - + org.nuiton.jaxx.widgets.number.NumberEditor + - - + + - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + - - + - - - - - - - - - - - - - - - - - + +
- - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + -
+ + + + + + + + + + - + - - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + +
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-
+
+
+ +
\ No newline at end of file diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jcss b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jcss index 581dfcf760251b4fe7d20e1c42ae9e0b9bc66dc2..b7e21580738d244f254dd3c33bd0b3720b0cdcc6 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jcss +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUI.jcss @@ -43,6 +43,11 @@ NumberEditor { _selectOnFocus: {true}; } +#surveyDetailsBlockLayer { + blockingColor: {handler.getConfig().getColorBlockingLayer()}; + block:{model.isLoading()}; +} + #surveyDetailsTabUI { _panelType: {ReefDbUI.EDITION_PANEL_TYPE}; } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUIHandler.java index 1f74acacdd1564dc37ae44fd35ebdca3f074a5f4..8be8865595a69f6e29fe38f72966b4d800427590 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/SurveyDetailsTabUIHandler.java @@ -75,6 +75,7 @@ public class SurveyDetailsTabUIHandler extends AbstractReefDbUIHandlersaveActualModel.

+ *

save.

*/ - public void saveActualModel() { + public void save() { getModel().setAdjusting(true); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java index 08e6cf1ba56a0d0957bac24fb04b33c83abb81bd..2c5b793d9caa591e8c52af70857c967c6e35e5e1 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java @@ -336,4 +336,24 @@ public class SurveyMeasurementsTabUIHandler extends AbstractReefDbUIHandler measurementToDelete) { - - // Remove from model - getModel().getSurvey().removeAllIndividualMeasurements(measurementToDelete); - - getModel().getSurvey().setDirty(true); - getModel().setModify(true); - - } - public void editSelectedMeasurements() { editSelectedMeasurements(new SurveyMeasurementsMultiEditUI(getUI())); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java index 0524789f44ccfbf2876e5881bd0f8872b6c71a9f..d3adf1d743bccb6a1951a52531bfb9394b29e34c 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java @@ -31,6 +31,7 @@ import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import fr.ifremer.reefdb.dto.data.survey.SurveyDTO; import fr.ifremer.reefdb.dto.enums.FilterTypeValues; import fr.ifremer.reefdb.dto.referential.DepartmentDTO; +import fr.ifremer.reefdb.service.ReefDbTechnicalException; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler; import jaxx.runtime.SwingUtil; import org.apache.commons.collections4.CollectionUtils; @@ -148,13 +149,12 @@ public class SurveyMeasurementsUngroupedTableUIHandler // tell the table model is editable or not getTableModel().setReadOnly(!getModel().getSurvey().isEditable()); -// getModel().setBean(getModel().getSurvey()); getModel().setRows(null); if (notEmpty) { // affect row - SurveyMeasurementsUngroupedRowModel row = getModel().addNewRow(getModel().getSurvey()); //getModel().getRows().get(0); + SurveyMeasurementsUngroupedRowModel row = getModel().addNewRow(getModel().getSurvey()); // set analyst from first non null measurement Optional measurementFound = getModel().getSurvey().getMeasurements().stream().filter(measurement -> measurement.getAnalyst() != null).findFirst(); @@ -199,12 +199,25 @@ public class SurveyMeasurementsUngroupedTableUIHandler super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue); + getModel().getSurvey().setDirty(true); + + } + + public void save() { + + if (getModel().getRowCount() == 0) + return; + + if (getModel().getRowCount() > 1) + throw new ReefDbTechnicalException("Should be only 1 row of survey ungrouped measurements"); + + SurveyMeasurementsUngroupedRowModel row = getModel().getRows().get(0); + // update all measurements row.getMeasurements().forEach(measurement -> measurement.setAnalyst(row.getAnalyst())); // save modifications to parent model getModel().getSurvey().setMeasurements(row.getMeasurements()); - getModel().getSurvey().setDirty(true); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/OneShotListener.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/OneShotListener.java deleted file mode 100644 index 6c4c77990a8e35cdf64ea3507eccf66b844e2b57..0000000000000000000000000000000000000000 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/OneShotListener.java +++ /dev/null @@ -1,92 +0,0 @@ -package fr.ifremer.reefdb.ui.swing.util; - -/*- - * #%L - * Reef DB :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 - 2020 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 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 Affero General Public License - * along with this program. If not, see . - * #L% - */ - -import org.jdesktop.beans.AbstractBean; - -import javax.annotation.Nonnull; -import java.awt.Component; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.function.Consumer; - -/** - * a PropertyChangeListener that auto remove after fired - * - * @author peck7 on 20/03/2020. - */ -public class OneShotListener implements PropertyChangeListener { - - private final Component parentComponent; - private final AbstractBean parentBean; - private final String propertyName; - private final Consumer consumer; - - /** - * Create and add to parent object - * - * @param parent the component on which this listener will be added - * @param propertyName the property to listen to - * @param consumer the consumer function - */ - public static void create(@Nonnull Component parent, @Nonnull String propertyName, @Nonnull Consumer consumer) { - OneShotListener listener = new OneShotListener(parent, propertyName, consumer); - parent.addPropertyChangeListener(propertyName, listener); - } - - /** - * Create and add to parent object - * - * @param parent the bean on which this listener will be added - * @param propertyName the property to listen to - * @param consumer the consumer function - */ - public static void create(@Nonnull AbstractBean parent, @Nonnull String propertyName, @Nonnull Consumer consumer) { - OneShotListener listener = new OneShotListener(parent, propertyName, consumer); - parent.addPropertyChangeListener(propertyName, listener); - } - - private OneShotListener(Component parentComponent, String propertyName, Consumer consumer) { - this.parentComponent = parentComponent; - this.parentBean = null; - this.propertyName = propertyName; - this.consumer = consumer; - } - - private OneShotListener(AbstractBean parentBean, String propertyName, Consumer consumer) { - this.parentComponent = null; - this.parentBean = parentBean; - this.propertyName = propertyName; - this.consumer = consumer; - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - consumer.accept(evt); - if (parentComponent != null) - parentComponent.removePropertyChangeListener(propertyName, this); - if (parentBean != null) - parentBean.removePropertyChangeListener(propertyName, this); - } -} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java index 951a01d2d3ae5b6dfcd2d963b112898455063035..f5943e43d3ae29cf15aced5ab627b13f8b94003b 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java @@ -529,6 +529,7 @@ public abstract class AbstractReefDbTableUIHandler + + + Grouped measurements: automatic calculation and saving into parent beans has been replaced by unique function executed at observation saving + + + PIT protocol: section calculation fixed + + + Upgrade quadrige3-core to version 3.6.14 + + + Regression of #51520: Postpone calculation also if no row sorting