View Javadoc
1   package fr.ifremer.dali.ui.swing.content.observation.survey;
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.dto.DaliBeans;
27  import fr.ifremer.dali.dto.configuration.programStrategy.PmfmStrategyDTO;
28  import fr.ifremer.dali.dto.configuration.programStrategy.ProgramDTO;
29  import fr.ifremer.dali.dto.data.survey.CampaignDTO;
30  import fr.ifremer.dali.dto.enums.FilterTypeValues;
31  import fr.ifremer.dali.dto.referential.LocationDTO;
32  import fr.ifremer.dali.dto.referential.PersonDTO;
33  import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
34  import fr.ifremer.dali.ui.swing.content.home.map.SurveysMapUI;
35  import fr.ifremer.dali.ui.swing.content.observation.ObservationUIModel;
36  import fr.ifremer.dali.ui.swing.content.observation.survey.history.QualificationHistoryUI;
37  import fr.ifremer.dali.ui.swing.content.observation.survey.history.ValidationHistoryUI;
38  import fr.ifremer.dali.ui.swing.content.observation.survey.measurement.ungrouped.SurveyMeasurementsUngroupedTableUIModel;
39  import fr.ifremer.dali.ui.swing.util.AbstractDaliBeanUIModel;
40  import fr.ifremer.dali.ui.swing.util.AbstractDaliUIHandler;
41  import fr.ifremer.dali.ui.swing.util.map.MapParentUIModel;
42  import fr.ifremer.quadrige3.core.dao.technical.Assert;
43  import jaxx.runtime.SwingUtil;
44  import jaxx.runtime.validator.swing.SwingValidator;
45  import org.nuiton.jaxx.application.swing.tab.TabHandler;
46  
47  import javax.swing.AbstractAction;
48  import javax.swing.JButton;
49  import javax.swing.JFrame;
50  import javax.swing.SwingUtilities;
51  import java.awt.Dimension;
52  import java.awt.event.ActionEvent;
53  import java.util.ArrayList;
54  import java.util.List;
55  import java.util.stream.Collectors;
56  
57  import static org.nuiton.i18n.I18n.t;
58  
59  /**
60   * Controlleur pour l'onglet observation general.
61   */
62  public class SurveyDetailsTabUIHandler extends AbstractDaliUIHandler<SurveyDetailsTabUIModel, SurveyDetailsTabUI> implements TabHandler {
63  
64      /**
65       * Constant <code>OBSERVERS_DOUBLE_LIST="observersDoubleList"</code>
66       */
67      public static final String OBSERVERS_DOUBLE_LIST = "observersDoubleList";
68      /**
69       * Constant <code>OBSERVERS_LIST="observersList"</code>
70       */
71      public static final String OBSERVERS_LIST = "observersList";
72  
73      private AbstractAction unfilterUsersAction;
74  
75      /**
76       * {@inheritDoc}
77       */
78      @Override
79      public void beforeInit(final SurveyDetailsTabUI ui) {
80          super.beforeInit(ui);
81  
82          // create model and register to the JAXX context
83          final SurveyDetailsTabUIModel model = new SurveyDetailsTabUIModel();
84          model.setDateTimePattern(getConfig().getDateTimeFormat());
85          ui.setContextValue(model);
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      @Override
92      public void afterInit(final SurveyDetailsTabUI ui) {
93          initUI(ui);
94  
95          getModel().setUngroupedTableUIModel(ui.getUngroupedTable().getModel());
96  
97          // Initialisation des combobox
98          initComboBox();
99  
100         // Init double list
101         initObserversLists();
102 
103         initListeners();
104 
105         registerValidators(getValidator());
106 
107     }
108 
109     private void initListeners() {
110 
111         // main listener on model
112         getModel().addPropertyChangeListener(evt -> {
113 
114             switch (evt.getPropertyName()) {
115                 case SurveyDetailsTabUIModel.PROPERTY_OBSERVATION_MODEL:
116                     // Listener on parent model
117                     load(getModel().getObservationModel());
118                     break;
119 
120                 case SurveyDetailsTabUIModel.PROPERTY_OBSERVERS:
121 
122                     if (getModel().isAdjusting()) return;
123 
124                     // Reload selected observers
125                     List<PersonDTO> observers = new ArrayList<>(getModel().getObservers());
126                     getUI().getObserversDoubleList().getHandler().setSelected(observers);
127                     getUI().getObserversList().setListData(observers.toArray(new PersonDTO[observers.size()]));
128                     break;
129 
130                 case SurveyDetailsTabUIModel.PROPERTY_PROGRAM:
131                     // reload locations combo
132                     updateLocations(false);
133                     break;
134 
135                 case SurveyDetailsTabUIModel.PROPERTY_LOCATION:
136                     // update coordinate
137                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MIN_LATITUDE_EDITOR_NUMBER_VALUE);
138                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MAX_LATITUDE_EDITOR_NUMBER_VALUE);
139                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MIN_LONGITUDE_EDITOR_NUMBER_VALUE);
140                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MAX_LONGITUDE_EDITOR_NUMBER_VALUE);
141                     // reload program combo
142                     updatePrograms(false);
143                     break;
144 
145                 case SurveyDetailsTabUIModel.PROPERTY_DATE:
146                     // reload program combo
147                     updatePrograms(false);
148                     updateCampaigns(false);
149                     break;
150 
151                 case SurveyDetailsTabUIModel.PROPERTY_COORDINATE:
152                     // update coordinate
153                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LATITUDE_MIN_EDITOR_NUMBER_VALUE);
154                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LATITUDE_MAX_EDITOR_NUMBER_VALUE);
155                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LONGITUDE_MIN_EDITOR_NUMBER_VALUE);
156                     getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LONGITUDE_MAX_EDITOR_NUMBER_VALUE);
157                     break;
158 
159                 case SurveyDetailsTabUIModel.PROPERTY_LATITUDE_MIN:
160                 case SurveyDetailsTabUIModel.PROPERTY_LATITUDE_MAX:
161                 case SurveyDetailsTabUIModel.PROPERTY_LONGITUDE_MIN:
162                 case SurveyDetailsTabUIModel.PROPERTY_LONGITUDE_MAX:
163                     // update positioning when all latitude and longitude are null
164                     if (getModel().getLatitudeMin() == null && getModel().getLatitudeMax() == null
165                             && getModel().getLongitudeMin() == null && getModel().getLongitudeMax() == null) {
166                         getModel().setPositioning(null);
167                     }
168                     break;
169 
170 //                case SurveyDetailsTabUIModel.PROPERTY_TIME:
171 //                    // update time editor
172 //                    getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_TIME_EDITOR_DATE);
173 //                    break;
174 
175                 case SurveyDetailsTabUIModel.PROPERTY_POSITIONING:
176                     // update positioning precision label
177                     getUI().getPositioningPrecisionText().setText(getModel().getPositioningPrecision());
178                     break;
179 
180                 case SurveyDetailsTabUIModel.PROPERTY_DEPARTMENT:
181                     // update department
182                     getUI().getRecorderDepartmentEditor().setText(decorate(getModel().getDepartment()));
183                     break;
184 
185                 case SurveyDetailsTabUIModel.PROPERTY_QUALITY_LEVEL:
186                     // update quality flag
187                     getUI().getQualityFlagEditor().setText(decorate(getModel().getQualityLevel()));
188                     break;
189 
190                 case SurveyDetailsTabUIModel.PROPERTY_EDITABLE:
191                     // select list only if model is not editable
192                     if (getModel().isEditable()) {
193                         getUI().getObserversPanelLayout().setSelected(OBSERVERS_DOUBLE_LIST);
194                     } else {
195                         getUI().getObserversPanelLayout().setSelected(OBSERVERS_LIST);
196                     }
197                     break;
198 
199                 case AbstractDaliBeanUIModel.PROPERTY_LOADING:
200                     // Propagate loading event
201                     getModel().getUngroupedTableUIModel().setLoading((Boolean) evt.getNewValue());
202                     break;
203 
204                 case ObservationUIModel.PROPERTY_PMFM_STRATEGIES:
205                     ObservationUIModel surveyModel = getModel().getObservationModel();
206                     List<PmfmStrategyDTO> pmfmStrategies = DaliBeans.filterCollection(surveyModel.getPmfmStrategies(), input -> input != null && input.isSurvey());
207 
208                     // load pmfms for ungrouped measurements
209                     List<PmfmDTO> pmfms = pmfmStrategies.stream()
210                             .filter(pmfmStrategy -> !pmfmStrategy.isGrouping())
211                             .map(PmfmStrategyDTO::getPmfm)
212                             .collect(Collectors.toList());
213 
214                     // Load other Pmfms in survey
215                     DaliBeans.fillListsEachOther(surveyModel.getPmfms(), pmfms);
216 
217                     // Set model properties
218                     getModel().getUngroupedTableUIModel().setPmfms(pmfms);
219 
220                     break;
221             }
222         });
223 
224         // Add listeners on PROPERTY_ROWS_IN_ERROR to catch modifications and revalidate
225         getModel().getUngroupedTableUIModel().addPropertyChangeListener(SurveyMeasurementsUngroupedTableUIModel.PROPERTY_ROWS_IN_ERROR, evt -> {
226             // re validate
227             getValidator().doValidate();
228         });
229 
230         listenModelModify(getModel().getUngroupedTableUIModel());
231 
232     }
233 
234     /**
235      * Load observation.
236      *
237      * @param surveyModel to load
238      */
239     private void load(final ObservationUIModel surveyModel) {
240 
241         Assert.notNull(surveyModel);
242 
243         // Selected observation
244         getModel().setBean(surveyModel);
245 
246         // Model not modified
247         getModel().setModify(false);
248 
249         // Listen validator
250         listenValidatorValid(getValidator(), getModel());
251 
252     }
253 
254     /**
255      * Initialisation des combobox
256      */
257     private void initComboBox() {
258 
259         // Intialisation des campagnes
260         initBeanFilterableComboBox(
261                 getUI().getCampaignCombo(),
262                 null,
263                 null);
264         getUI().getCampaignCombo().setActionListener(e -> {
265             if (!askBefore(t("dali.common.unfilter"), t("dali.common.unfilter.confirmation"))) {
266                 return;
267             }
268             updateCampaigns(true);
269         });
270         updateCampaigns(false);
271 
272         // Initailisation des programmes
273         initBeanFilterableComboBox(
274                 getUI().getProgramCombo(),
275                 null,
276                 null);
277         getUI().getProgramCombo().setActionListener(e -> {
278             if (!askBefore(t("dali.common.unfilter"), t("dali.common.unfilter.confirmation"))) {
279                 return;
280             }
281             updatePrograms(true);
282         });
283         updatePrograms(false);
284 
285         // Initialisation des lieux
286         initBeanFilterableComboBox(
287                 getUI().getLocationCombo(),
288                 null,
289                 null);
290         getUI().getLocationCombo().setActionListener(e -> {
291             if (!askBefore(t("dali.common.unfilter"), t("dali.common.unfilter.confirmation"))) {
292                 return;
293             }
294             updateLocations(true);
295         });
296         updateLocations(false);
297 
298         // Initialisation des Positionnements
299         initBeanFilterableComboBox(
300                 getUI().getPositioningCombo(),
301                 getContext().getReferentialService().getPositioningSystems(),
302                 null);
303 
304     }
305 
306     @SuppressWarnings("unchecked")
307     private void initObserversLists() {
308 
309         // init list
310         getUI().getObserversList().setCellRenderer(newListCellRender(PersonDTO.class));
311 
312         // init double list
313         initBeanList(
314                 getUI().getObserversDoubleList(),
315                 new ArrayList<>(),
316                 new ArrayList<>(),
317                 300);
318 
319         // add unfilter action
320         unfilterUsersAction = new AbstractAction("", SwingUtil.createActionIcon("unfilter")) {
321             @Override
322             public void actionPerformed(ActionEvent e) {
323                 updateUsers(true);
324             }
325         };
326         JButton unfilterUsersButton = new JButton();
327         unfilterUsersButton.setAction(unfilterUsersAction);
328         unfilterUsersButton.setToolTipText(t("dali.common.unfilter"));
329         getUI().getObserversDoubleList().getFilterFieldLabel().setVisible(false);
330         getUI().getObserversDoubleList().getToolbarLeft().add(unfilterUsersButton, 0);
331         updateUsers(false);
332     }
333 
334     private void updatePrograms(boolean forceNoFilter) {
335 
336         if (getModel().isAdjusting() || !getModel().isEditable()) {
337             return;
338         }
339         getModel().setAdjusting(true);
340 
341         getUI().getProgramCombo().setActionEnabled(!forceNoFilter
342                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.PROGRAM));
343 
344         List<ProgramDTO> programs = getContext().getObservationService().getAvailablePrograms(
345                 getModel().getLocationId(),
346                 getModel().getDate(),
347                 forceNoFilter);
348 
349         // Mantis #0027340 & #0027282 : Avoid Program/Location/Date incompatibility
350         // Mantis #0029591 : Prevent set null when model is loading
351         if (!getModel().isLoading() && getModel().getProgram() != null && !programs.contains(getModel().getProgram())) {
352             getModel().setProgram(null);
353         }
354         getUI().getProgramCombo().setData(programs);
355 
356         getModel().setAdjusting(false);
357     }
358 
359     private void updateCampaigns(boolean forceNoFilter) {
360 
361         if (getModel().isAdjusting() || !getModel().isEditable()) {
362             return;
363         }
364         getModel().setAdjusting(true);
365 
366         getUI().getCampaignCombo().setActionEnabled(!forceNoFilter
367                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.CAMPAIGN));
368 
369         List<CampaignDTO> campaigns = getContext().getObservationService().getAvailableCampaigns(getModel().getDate(), forceNoFilter);
370 
371         // Mantis #0029591 : Prevent set null when model is loading
372         if (!getModel().isLoading() && getModel().getCampaign() != null && !campaigns.contains(getModel().getCampaign())) {
373             getModel().setCampaign(null);
374         }
375         getUI().getCampaignCombo().setData(campaigns);
376 
377         getModel().setAdjusting(false);
378     }
379 
380     private void updateLocations(boolean forceNoFilter) {
381 
382         if (getModel().isAdjusting() || !getModel().isEditable()) {
383             return;
384         }
385         getModel().setAdjusting(true);
386 
387         getUI().getLocationCombo().setActionEnabled(!forceNoFilter
388                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.LOCATION));
389 
390         List<LocationDTO> locations = getContext().getObservationService().getAvailableLocations(
391                 null, //                getModel().getCampaignId(),
392                 getModel().getProgramCode(),
393                 forceNoFilter);
394 
395         // Mantis #0027340 & #0027282 : Avoid Program/Location/Date incompatibility
396         // Mantis #0029591 : Prevent set null when model is loading
397         if (!getModel().isLoading() && getModel().getLocation() != null && !locations.contains(getModel().getLocation())) {
398             getModel().setLocation(null);
399         }
400         getUI().getLocationCombo().setData(locations);
401 
402         getModel().setAdjusting(false);
403     }
404 
405     private void updateUsers(boolean forceNoFilter) {
406 
407         if (getModel().isAdjusting()) {
408             return;
409         }
410         getModel().setAdjusting(true);
411 
412         unfilterUsersAction.setEnabled(!forceNoFilter
413                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.USER));
414 
415         List<PersonDTO> users = getContext().getObservationService().getAvailableUsers(forceNoFilter);
416 
417         getUI().getObserversDoubleList().getHandler().setUniverse(users);
418 
419         getModel().setAdjusting(false);
420     }
421 
422     /**
423      * {@inheritDoc}
424      */
425     @Override
426     public SwingValidator<SurveyDetailsTabUIModel> getValidator() {
427         return getUI().getValidator();
428     }
429 
430     /**
431      * {@inheritDoc}
432      */
433     @Override
434     public boolean onHideTab(int currentIndex, int newIndex) {
435         return true;
436     }
437 
438     /**
439      * {@inheritDoc}
440      */
441     @Override
442     public void onShowTab(int currentIndex, int newIndex) {
443 
444     }
445 
446     /**
447      * {@inheritDoc}
448      */
449     @Override
450     public boolean onRemoveTab() {
451         return false;
452     }
453 
454     /**
455      * <p>saveActualModel.</p>
456      */
457     public void saveActualModel() {
458 
459         getModel().setAdjusting(true);
460 
461         // save observers to parent model
462         getModel().setObservers(getModel().getSelectedObservers());
463 
464         getModel().setAdjusting(false);
465     }
466 
467     public void showValidationHistory() {
468 
469         ValidationHistoryUI ui = new ValidationHistoryUI(getContext());
470         ui.getModel().setBeans(getContext().getObservationService().getValidationHistory(getModel().getId()));
471         openDialog(ui, new Dimension(800, 600));
472     }
473 
474     public void showQualificationHistory() {
475 
476         QualificationHistoryUI ui = new QualificationHistoryUI(getContext());
477         ui.getModel().setBeans(getContext().getObservationService().getQualificationHistory(getModel().getId()));
478         openDialog(ui, new Dimension(800, 600));
479     }
480 
481     private JFrame mapFrame;
482     private SurveysMapUI mapUI;
483 
484     public void showMap() {
485 
486         // if needed
487         closeMap();
488 
489         mapUI = new SurveysMapUI(getUI());
490         getModel().setMapUIModel(mapUI.getModel());
491         mapUI.getModel().setSelectedSurvey(getModel());
492         getModel().addPropertyChangeListener(MapParentUIModel.EVENT_CLOSE_FULLSCREEN, evt -> closeMap());
493         mapUI.getHandler().fullScreen();
494 
495         mapFrame = createFrame(mapUI, t("dali.home.map.title"), null, getUI().getBounds());
496 
497         SwingUtilities.invokeLater(() -> {
498             mapFrame.setExtendedState(mapFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
499             mapFrame.setVisible(true);
500             mapUI.getHandler().openMap();
501         });
502     }
503 
504     private void closeMap() {
505         if (mapUI != null) {
506             mapUI.getHandler().onCloseUI();
507             mapUI = null;
508         }
509         if (mapFrame != null) {
510             mapFrame.dispose();
511         }
512     }
513 
514     @Override
515     public void onCloseUI() {
516         closeMap();
517         super.onCloseUI();
518     }
519 }