View Javadoc
1   package fr.ifremer.dali.ui.swing.content.observation.survey.measurement.ungrouped;
2   
3   /*
4    * #%L
5    * Dali :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   *
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   *
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import fr.ifremer.dali.decorator.DecoratorService;
27  import fr.ifremer.dali.dto.DaliBeans;
28  import fr.ifremer.dali.dto.data.measurement.MeasurementDTO;
29  import fr.ifremer.dali.dto.data.survey.SurveyDTO;
30  import fr.ifremer.dali.dto.enums.FilterTypeValues;
31  import fr.ifremer.dali.dto.referential.DepartmentDTO;
32  import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableUIHandler;
33  import fr.ifremer.dali.ui.swing.util.table.PmfmTableColumn;
34  import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
35  import fr.ifremer.quadrige3.ui.swing.table.editor.ExtendedComboBoxCellEditor;
36  import jaxx.runtime.SwingUtil;
37  import org.apache.commons.collections4.CollectionUtils;
38  import org.jdesktop.swingx.table.TableColumnExt;
39  
40  import javax.swing.SwingUtilities;
41  import java.util.HashSet;
42  import java.util.Optional;
43  import java.util.Set;
44  import java.util.stream.Collectors;
45  
46  import static org.nuiton.i18n.I18n.t;
47  
48  /**
49   * Controleur pour le tableau du haut (Psfm) pour l onglet des mesures de l'observation.
50   */
51  public class SurveyMeasurementsUngroupedTableUIHandler
52          extends AbstractDaliTableUIHandler<SurveyMeasurementsUngroupedRowModel, SurveyMeasurementsUngroupedTableUIModel, SurveyMeasurementsUngroupedTableUI> {
53  
54      private static final int ROW_COUNT = 1;
55  
56      // editor for analyst column
57      private ExtendedComboBoxCellEditor<DepartmentDTO> departmentCellEditor;
58  
59  
60      /**
61       * <p>Constructor for SurveyMeasurementsUngroupedTableUIHandler.</p>
62       */
63      public SurveyMeasurementsUngroupedTableUIHandler() {
64          super(SurveyMeasurementsUngroupedRowModel.PROPERTY_PMFMS);
65      }
66  
67      /**
68       * {@inheritDoc}
69       */
70      @Override
71      public SurveyMeasurementsUngroupedTableModel getTableModel() {
72          return (SurveyMeasurementsUngroupedTableModel) getTable().getModel();
73      }
74  
75      /**
76       * {@inheritDoc}
77       */
78      @Override
79      public void beforeInit(final SurveyMeasurementsUngroupedTableUI ui) {
80          super.beforeInit(ui);
81          // create model and register to the JAXX context
82          ui.setContextValue(new SurveyMeasurementsUngroupedTableUIModel());
83      }
84  
85      /**
86       * {@inheritDoc}
87       */
88      @Override
89      public void afterInit(final SurveyMeasurementsUngroupedTableUI ui) {
90  
91          // Initialiser l UI
92          initUI(ui);
93          createDepartmentCellEditor();
94          updateDepartmentCellEditor(false);
95  
96          initTable();
97          getTable().setVisibleRowCount(ROW_COUNT);
98  
99          SwingUtil.setLayerUI(ui.getTableScrollPane(), ui.getTableBlockLayer());
100         // TODO mettre cette ligne si la scrollbar doit etre visible (et retirer setVisibleRowCount)
101 //        DaliUIs.forceComponentSize(ui.getTableauHautScrollPane(), 500, 70);
102 
103         // Initialiser listeners
104         initListeners();
105     }
106 
107     private void createDepartmentCellEditor() {
108 
109         departmentCellEditor = newExtendedComboBoxCellEditor(null, DepartmentDTO.class, false);
110 
111         departmentCellEditor.setAction("unfilter", "dali.common.unfilter", e -> {
112             if (!askBefore(t("dali.common.unfilter"), t("dali.common.unfilter.confirmation"))) {
113                 return;
114             }
115             // unfilter location
116             updateDepartmentCellEditor(true);
117         });
118 
119     }
120 
121     private void updateDepartmentCellEditor(boolean forceNoFilter) {
122 
123         departmentCellEditor.getCombo().setActionEnabled(!forceNoFilter
124                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.DEPARTMENT));
125 
126         departmentCellEditor.getCombo().setData(getContext().getObservationService().getAvailableDepartments(forceNoFilter));
127     }
128 
129     /**
130      * Initialiser les listeners
131      */
132     private void initListeners() {
133 
134         getModel().addPropertyChangeListener(SurveyMeasurementsUngroupedTableUIModel.PROPERTY_SURVEY, evt -> loadSurvey());
135 
136         getModel().addPropertyChangeListener(SurveyMeasurementsUngroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, evt -> {
137             // Detect read only measurement
138             detectRealOnlyMeasurements();
139         });
140 
141     }
142 
143     private void detectRealOnlyMeasurements() {
144 
145         Set<Integer> readOnlyPmfmIds = new HashSet<>();
146 
147         // Add Calculated length
148         readOnlyPmfmIds.add(getConfig().getSurveyCalculatedLengthPmfmId());
149 
150         // Add calculated area (first pmfm id of each triplets)
151         readOnlyPmfmIds.addAll(getConfig().getCalculatedTrawlAreaPmfmTriplets().stream().map(integers -> integers[0]).collect(Collectors.toList()));
152 
153         if (CollectionUtils.isNotEmpty(readOnlyPmfmIds)) {
154             for (PmfmTableColumn column : getModel().getPmfmColumns()) {
155                 if (readOnlyPmfmIds.contains(column.getPmfmId())) {
156                     column.setEditable(false);
157                     column.getPmfmIdentifier().setNotMandatory(); // by precaution
158                 }
159             }
160         }
161 
162     }
163 
164     /**
165      * Load survey.
166      */
167     private void loadSurvey() {
168 
169         SwingUtilities.invokeLater(() -> {
170 
171             // Uninstall save state listener
172             uninstallSaveTableStateListener();
173 
174             addPmfmColumns(
175                     getModel().getPmfms(),
176                     SurveyDTO.PROPERTY_PMFMS,
177                     DecoratorService.NAME_WITH_UNIT); // insert at the end
178 
179             boolean notEmpty = CollectionUtils.isNotEmpty(getModel().getPmfms());
180 
181             // tell the table model is editable or not
182             getTableModel().setReadOnly(!getModel().getSurvey().isEditable());
183 
184             // Enable the table if pmfms non empty (Mantis #40984)
185             getUI().getTableScrollPane().getParent().setVisible(notEmpty);
186             getModel().setRows(null);
187 
188             if (notEmpty) {
189 
190                 // affect row
191                 SurveyMeasurementsUngroupedRowModel row = getModel().addNewRow(getModel().getSurvey());
192 
193                 // set analyst from first non null measurement
194                 Optional<MeasurementDTO> measurementFound = getModel().getSurvey().getMeasurements().stream().filter(measurement -> measurement.getAnalyst() != null).findFirst();
195                 if (measurementFound.isPresent()) {
196                     row.setAnalyst(measurementFound.get().getAnalyst());
197                 } else {
198                     // todo attention si on charge des mesures sans analyst (en base) on affiche qd meme l'analyste de la stratégie
199                     row.setAnalyst(getContext().getProgramStrategyService().getAnalysisDepartmentOfAppliedStrategyBySurvey(getModel().getSurvey()));
200                 }
201 
202             }
203 
204             recomputeRowsValidState();
205 
206             // restore table from swing session
207             restoreTableState();
208 
209             // hide analyst if no pmfm
210 //            forceColumnVisibleAtLastPosition(SurveyMeasurementsUngroupedTableModel.ANALYST, notEmpty);
211             // Don't force position (Mantis #49939)
212             forceColumnVisible(SurveyMeasurementsUngroupedTableModel.ANALYST, notEmpty);
213 
214             getModel().fireMeasurementsLoaded();
215 
216             // Install save state listener
217             SwingUtilities.invokeLater(this::installSaveTableStateListener);
218         });
219     }
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     protected void onRowModified(int rowIndex, SurveyMeasurementsUngroupedRowModel row, String propertyName, Integer propertyIndex, Object oldValue, Object newValue) {
226 
227         // no need to tell the table is modified if no pmfms (measurement) changes
228         if (SurveyMeasurementsUngroupedRowModel.PROPERTY_PMFMS.equals(propertyName) && oldValue == newValue) {
229             return;
230         }
231 
232         super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue);
233 
234         // update all measurements
235         row.getMeasurements().forEach(measurement -> measurement.setAnalyst(row.getAnalyst()));
236 
237         // save modifications to parent model
238         getModel().getSurvey().setMeasurements(row.getMeasurements());
239         getModel().getSurvey().setDirty(true);
240 
241     }
242 
243     /**
244      * {@inheritDoc}
245      */
246     @Override
247     protected boolean isRowValid(SurveyMeasurementsUngroupedRowModel row) {
248         return super.isRowValid(row) && isMeasurementRowValid(row);
249     }
250 
251     private boolean isMeasurementRowValid(SurveyMeasurementsUngroupedRowModel row) {
252 
253         if (row.getAnalyst() == null && row.getMeasurements().stream().anyMatch(measurement -> !DaliBeans.isMeasurementEmpty(measurement))) {
254             DaliBeans.addError(row,
255                     t("dali.validator.error.analyst.required"),
256                     SurveyMeasurementsUngroupedRowModel.PROPERTY_ANALYST);
257             return false;
258         }
259         return true;
260     }
261 
262     /**
263      * Initialisation du tableau.
264      */
265     private void initTable() {
266 
267         // La table des mesures
268         final SwingTable table = getTable();
269 
270         // Add analyst column (Mantis #42617)
271         TableColumnExt analystColumn = addColumn(
272                 departmentCellEditor,
273                 newTableCellRender(SurveyMeasurementsUngroupedTableModel.ANALYST),
274                 SurveyMeasurementsUngroupedTableModel.ANALYST
275         );
276         analystColumn.setMinWidth(100);
277 
278         // Modele de la table
279         SurveyMeasurementsUngroupedTableModel tableModel = new SurveyMeasurementsUngroupedTableModel(getTable().getColumnModel());
280         tableModel.setNoneEditableCols();
281         table.setModel(tableModel);
282 
283         // Initialisation de la table
284         initTable(table, true);
285 
286         // border
287         addEditionPanelBorder();
288     }
289 
290     /**
291      * {@inheritDoc}
292      */
293     @Override
294     public SwingTable getTable() {
295         return ui.getSurveyUngroupedMeasurementTable();
296     }
297 }