View Javadoc
1   package fr.ifremer.reefdb.ui.swing.content.observation.survey;
2   
3   /*
4    * #%L
5    * Reef DB :: 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.reefdb.dto.configuration.programStrategy.ProgramDTO;
27  import fr.ifremer.reefdb.dto.data.survey.CampaignDTO;
28  import fr.ifremer.reefdb.dto.data.survey.SurveyDTO;
29  import fr.ifremer.reefdb.dto.enums.FilterTypeValues;
30  import fr.ifremer.reefdb.dto.referential.LocationDTO;
31  import fr.ifremer.reefdb.dto.referential.PersonDTO;
32  import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbUIHandler;
33  import jaxx.runtime.SwingUtil;
34  import jaxx.runtime.validator.swing.SwingValidator;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.nuiton.jaxx.application.swing.tab.TabHandler;
38  
39  import javax.swing.AbstractAction;
40  import javax.swing.JButton;
41  import java.awt.event.ActionEvent;
42  import java.util.ArrayList;
43  import java.util.List;
44  
45  import static org.nuiton.i18n.I18n.t;
46  
47  /**
48   * Controlleur pour l'onglet observation general.
49   */
50  public class SurveyDetailsTabUIHandler extends AbstractReefDbUIHandler<SurveyDetailsTabUIModel, SurveyDetailsTabUI> implements TabHandler {
51  
52      /**
53       * Logger.
54       */
55      private static final Log LOG = LogFactory.getLog(SurveyDetailsTabUIHandler.class);
56  
57      /** Constant <code>OBSERVERS_DOUBLE_LIST="observersDoubleList"</code> */
58      public static final String OBSERVERS_DOUBLE_LIST = "observersDoubleList";
59      /** Constant <code>OBSERVERS_LIST="observersList"</code> */
60      public static final String OBSERVERS_LIST = "observersList";
61  
62      private AbstractAction unfilterUsersAction;
63  
64      /** {@inheritDoc} */
65      @Override
66      public void beforeInit(final SurveyDetailsTabUI ui) {
67          super.beforeInit(ui);
68  
69          // create model and register to the JAXX context
70          final SurveyDetailsTabUIModel model = new SurveyDetailsTabUIModel();
71          ui.setContextValue(model);
72      }
73  
74      /** {@inheritDoc} */
75      @Override
76      public void afterInit(final SurveyDetailsTabUI ui) {
77          initUI(ui);
78          SwingUtil.setLayerUI(ui.getDetailsPanel(), ui.getSurveyDetailsBlockLayer());
79  
80          // Initialisation des combobox
81          initComboBox();
82  
83          // Init double list
84          initObserversLists();
85  
86          initListeners();
87  
88          // Listen validator
89          listenValidatorValid(getValidator(), getModel());
90      }
91  
92      private void initListeners() {
93  
94          // main listener on model
95          getModel().addPropertyChangeListener(evt -> {
96  
97              if (SurveyDetailsTabUIModel.PROPERTY_OBSERVATION_MODEL.equals(evt.getPropertyName())) {
98                  // Listener on parent model
99                  load(getModel().getObservationModel());
100 
101             } else if (SurveyDetailsTabUIModel.PROPERTY_OBSERVERS.equals(evt.getPropertyName())) {
102 
103                 if (getModel().isAdjusting()) return;
104 
105                 // Reload selected observers
106                 List<PersonDTO> observers = new ArrayList<>(getModel().getObservers());
107 //                    getModel().setSelectedObservers(observers);
108                 getUI().getObserversDoubleList().getHandler().setSelected(observers);
109                 getUI().getObserversList().setListData(observers.toArray(new PersonDTO[observers.size()]));
110 
111             } else if (SurveyDetailsTabUIModel.PROPERTY_PROGRAM.equals(evt.getPropertyName())) {
112                 // reload locations combo
113                 updateLocations(false);
114 
115             } else if (SurveyDetailsTabUIModel.PROPERTY_LOCATION.equals(evt.getPropertyName())) {
116                 // update coordinate
117                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MIN_LATITUDE_EDITOR_NUMBER_VALUE);
118                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MAX_LATITUDE_EDITOR_NUMBER_VALUE);
119                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MIN_LONGITUDE_EDITOR_NUMBER_VALUE);
120                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_LOCATION_MAX_LONGITUDE_EDITOR_NUMBER_VALUE);
121                 // reload program combo
122                 updatePrograms(false);
123 
124             } else if (SurveyDetailsTabUIModel.PROPERTY_DATE.equals(evt.getPropertyName())) {
125                 // reload program combo
126                 updatePrograms(false);
127                 updateCampaigns(false);
128 
129             } else if (SurveyDetailsTabUIModel.PROPERTY_COORDINATE.equals(evt.getPropertyName())) {
130                 // update coordinate
131                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LATITUDE_EDITOR_NUMBER_VALUE);
132                 getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_SURVEY_LONGITUDE_EDITOR_NUMBER_VALUE);
133 
134 
135             } else if (SurveyDetailsTabUIModel.PROPERTY_LATITUDE.equals(evt.getPropertyName())
136                     || SurveyDetailsTabUIModel.PROPERTY_LONGITUDE.equals(evt.getPropertyName())) {
137                 // update positioning when both latitude and longitude are null
138                 if (getModel().getLatitude() == null && getModel().getLongitude() == null) {
139                     getModel().setPositioning(null);
140                 }
141 
142 //            } else if (SurveyDetailsTabUIModel.PROPERTY_TIME.equals(evt.getPropertyName())) {
143                 // update time editor
144 //                getUI().applyDataBinding(SurveyDetailsTabUI.BINDING_TIME_EDITOR_DATE);
145 
146             } else if (SurveyDetailsTabUIModel.PROPERTY_POSITIONING.equals(evt.getPropertyName())) {
147                 // update positioning precision label
148                 getUI().getSelectionPrecisionLabel().setText(getModel().getPositioningPrecision());
149 
150             } else if (SurveyDetailsTabUIModel.PROPERTY_RECORDER_DEPARTMENT.equals(evt.getPropertyName())) {
151                 // update department
152                 getUI().getInputSaisisseur().setText(decorate(getModel().getRecorderDepartment()));
153 
154             } else if (SurveyDetailsTabUIModel.PROPERTY_EDITABLE.equals(evt.getPropertyName())) {
155                 // select list only if model is not editable
156                 if (getModel().isEditable()) {
157                     getUI().getObserversPanelLayout().setSelected(OBSERVERS_DOUBLE_LIST);
158                 } else {
159                     getUI().getObserversPanelLayout().setSelected(OBSERVERS_LIST);
160                 }
161 
162             }
163         });
164 
165     }
166 
167     /**
168      * Load observation.
169      *
170      * @param survey to load
171      */
172     private void load(final SurveyDTO survey) {
173 
174         // Selected observation
175         getModel().setBean(survey);
176 
177         // Model not modified
178         getModel().setModify(false);
179     }
180 
181     /**
182      * Initialisation des combobox
183      */
184     private void initComboBox() {
185 
186         // Intialisation des campagnes
187         initBeanFilterableComboBox(
188                 getUI().getCampaignCombo(),
189                 null,
190                 null);
191         getUI().getCampaignCombo().setActionListener(e -> {
192             if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
193                 return;
194             }
195             updateCampaigns(true);
196         });
197         updateCampaigns(false);
198 
199         // Initailisation des programmes
200         initBeanFilterableComboBox(
201                 getUI().getProgramCombo(),
202                 null, //getContext().getObservationService().getAvailablePrograms(null, null, null, false),
203                 null);
204         getUI().getProgramCombo().setActionListener(e -> {
205             if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
206                 return;
207             }
208             updatePrograms(true);
209         });
210         updatePrograms(false);
211 
212         // Initialisation des lieux
213         initBeanFilterableComboBox(
214                 getUI().getLocationCombo(),
215                 null, //getContext().getObservationService().getAvailableLocations(false),
216                 null);
217         getUI().getLocationCombo().setActionListener(e -> {
218             if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
219                 return;
220             }
221             updateLocations(true);
222         });
223         updateLocations(false);
224 
225         // Initialisation des Positionnements
226         initBeanFilterableComboBox(
227                 getUI().getSelectionPositionnementCombo(),
228                 getContext().getReferentialService().getPositioningSystems(),
229                 null);
230 
231         // Initialisation des Profondeurs
232         initBeanFilterableComboBox(
233                 getUI().getProfondeurEditor(),
234                 getContext().getReferentialService().getDepths(),
235                 null);
236 
237     }
238 
239     @SuppressWarnings("unchecked")
240     private void initObserversLists() {
241 
242         // init list
243         getUI().getObserversList().setCellRenderer(newListCellRender(PersonDTO.class));
244 
245         // init double list
246         initBeanList(
247                 getUI().getObserversDoubleList(),
248                 new ArrayList<>(),
249                 new ArrayList<>(),
250                 300);
251 
252         // add unfilter action
253         unfilterUsersAction = new AbstractAction("", SwingUtil.createActionIcon("unfilter")){
254             @Override
255             public void actionPerformed(ActionEvent e) {
256                 updateUsers(true);
257             }
258         };
259         JButton unfilterUsersButton = new JButton();
260         unfilterUsersButton.setAction(unfilterUsersAction);
261         unfilterUsersButton.setToolTipText(t("reefdb.common.unfilter"));
262         getUI().getObserversDoubleList().getFilterFieldLabel().setVisible(false);
263         getUI().getObserversDoubleList().getToolbarLeft().add(unfilterUsersButton, 0);
264         updateUsers(false);
265     }
266 
267     private void updatePrograms(boolean forceNoFilter) {
268 
269         if (getModel().isAdjusting() || !getModel().isEditable()) {
270             return;
271         }
272         getModel().setAdjusting(true);
273 
274         getUI().getProgramCombo().setActionEnabled(!forceNoFilter
275                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.PROGRAM));
276 
277         List<ProgramDTO> programs = getContext().getObservationService().getAvailablePrograms(
278                 null,  // no campaign filter getModel().getCampaignId(),
279                 getModel().getLocationId(),
280                 getModel().getDate(),
281                 forceNoFilter);
282 
283         // Mantis #0027340 & #0027282 : Avoid Program/Location/Date incompatibility
284         // Mantis #0029591 : Prevent set null when model is loading
285         if (!getModel().isLoading() && getModel().getProgram() != null && !programs.contains(getModel().getProgram())) {
286             getModel().setProgram(null);
287         }
288         getUI().getProgramCombo().setData(programs);
289 
290         getModel().setAdjusting(false);
291     }
292 
293     private void updateCampaigns(boolean forceNoFilter) {
294 
295         if (getModel().isAdjusting() || !getModel().isEditable()) {
296             return;
297         }
298         getModel().setAdjusting(true);
299 
300         getUI().getCampaignCombo().setActionEnabled(!forceNoFilter
301                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.CAMPAIGN));
302 
303         List<CampaignDTO> campaigns = getContext().getObservationService().getAvailableCampaigns(getModel().getDate(), forceNoFilter);
304 
305         // Mantis #0029591 : Prevent set null when model is loading
306         if (!getModel().isLoading() && getModel().getCampaign() != null && !campaigns.contains(getModel().getCampaign())) {
307             getModel().setCampaign(null);
308         }
309         getUI().getCampaignCombo().setData(campaigns);
310 
311         getModel().setAdjusting(false);
312     }
313 
314     private void updateLocations(boolean forceNoFilter) {
315 
316         if (getModel().isAdjusting() || !getModel().isEditable()) {
317             return;
318         }
319         getModel().setAdjusting(true);
320 
321         getUI().getLocationCombo().setActionEnabled(!forceNoFilter
322                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.LOCATION));
323 
324         List<LocationDTO> locations = getContext().getObservationService().getAvailableLocations(
325                 null, // pas de filtrage sur les campagne getModel().getCampaignId(),
326                 getModel().getProgramCode(),
327                 forceNoFilter);
328 
329         // Mantis #0027340 & #0027282 : Avoid Program/Location/Date incompatibility
330         // Mantis #0029591 : Prevent set null when model is loading
331         if (!getModel().isLoading() && getModel().getLocation() != null && !locations.contains(getModel().getLocation())) {
332             getModel().setLocation(null);
333         }
334         getUI().getLocationCombo().setData(locations);
335 
336         getModel().setAdjusting(false);
337     }
338 
339     private void updateUsers(boolean forceNoFilter) {
340 
341         if (getModel().isAdjusting()) {
342             return;
343         }
344         getModel().setAdjusting(true);
345 
346         unfilterUsersAction.setEnabled(!forceNoFilter
347                 && getContext().getDataContext().isContextFiltered(FilterTypeValues.USER));
348 
349         List<PersonDTO> users = getContext().getObservationService().getAvailableUsers(forceNoFilter);
350 
351         getUI().getObserversDoubleList().getModel().setUniverse(users);
352         getUI().getObserversDoubleList().getHandler().sortData();
353 
354         getModel().setAdjusting(false);
355     }
356 
357     /** {@inheritDoc} */
358     @Override
359     public SwingValidator<SurveyDetailsTabUIModel> getValidator() {
360         return getUI().getValidator();
361     }
362 
363     /** {@inheritDoc} */
364     @Override
365     public boolean onHideTab(int currentIndex, int newIndex) {
366         return true;
367     }
368 
369     /** {@inheritDoc} */
370     @Override
371     public void onShowTab(int currentIndex, int newIndex) {
372 
373     }
374 
375     /** {@inheritDoc} */
376     @Override
377     public boolean onRemoveTab() {
378         return false;
379     }
380 
381     /**
382      * <p>save.</p>
383      */
384     public void save() {
385 
386         getModel().setAdjusting(true);
387 
388         // save observers to parent model
389         getModel().setObservers(getModel().getSelectedObservers());
390 
391         getModel().setAdjusting(false);
392     }
393 }