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 super OperationMeasurementsGroupedRowModel> 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 extends OperationMeasurementsUngroupedTableModel, ? extends Integer> 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 super R> 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 super R> 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 extends MeasurementAware> 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 extends MeasurementAware> 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