View Javadoc
1   package fr.ifremer.dali.ui.swing.content.observation;
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.CoordinateDTO;
27  import fr.ifremer.dali.dto.DaliBeans;
28  import fr.ifremer.dali.dto.data.survey.SurveyDTO;
29  import fr.ifremer.dali.service.DaliTechnicalException;
30  import fr.ifremer.dali.ui.swing.action.GoToObservationAction;
31  import fr.ifremer.dali.ui.swing.action.QuitScreenAction;
32  import fr.ifremer.dali.ui.swing.content.home.survey.SurveysTableRowModel;
33  import fr.ifremer.dali.ui.swing.content.observation.survey.SurveyDetailsTabUI;
34  import fr.ifremer.dali.ui.swing.util.plaf.PlafUtils;
35  import fr.ifremer.dali.ui.swing.util.tab.AbstractDaliTabContainerUIHandler;
36  import fr.ifremer.dali.ui.swing.util.tab.DaliTabIndexes;
37  import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil;
38  import fr.ifremer.quadrige3.ui.swing.table.AbstractTableModel;
39  import fr.ifremer.quadrige3.ui.swing.table.state.SwingTableSessionState;
40  import fr.ifremer.quadrige3.ui.swing.table.state.SwingTableState;
41  import jaxx.runtime.SwingUtil;
42  import jaxx.runtime.swing.session.State;
43  import org.apache.commons.lang3.StringUtils;
44  import org.apache.commons.logging.Log;
45  import org.apache.commons.logging.LogFactory;
46  import org.nuiton.jaxx.application.swing.util.CloseableUI;
47  
48  import javax.swing.BorderFactory;
49  import javax.swing.JTabbedPane;
50  import javax.swing.SwingWorker;
51  import java.awt.Color;
52  import java.util.Map;
53  import java.util.concurrent.ExecutionException;
54  
55  import static org.nuiton.i18n.I18n.t;
56  
57  /**
58   * Controlleur pour observation.
59   */
60  public class ObservationUIHandler extends AbstractDaliTabContainerUIHandler<ObservationUIModel, ObservationUI> implements CloseableUI {
61  
62      /**
63       * Logger.
64       */
65      private static final Log LOG = LogFactory.getLog(ObservationUIHandler.class);
66  
67      /**
68       * {@inheritDoc}
69       */
70      @Override
71      public void beforeInit(final ObservationUI ui) {
72          super.beforeInit(ui);
73  
74          ui.setContextValue(new ObservationUIModel());
75          ui.setContextValue(SwingUtil.createActionIcon("observation"));
76      }
77  
78      /**
79       * {@inheritDoc}
80       */
81      @Override
82      public void afterInit(final ObservationUI ui) {
83  
84          initUI(ui);
85          SwingUtil.setLayerUI(getTabPanel(), ui.getSurveyBlockLayer());
86  
87          // Affect models
88          getModel().setSurveyDetailsTabUIModel(getUI().getSurveyDetailsTabUI().getModel());
89          getModel().setOperationMeasurementsTabUIModel(getUI().getOperationMeasurementsTabUI().getModel());
90          getModel().setPhotosTabUIModel(getUI().getPhotosTabUI().getModel());
91  
92          // Ajout des onglets
93          setCustomTab(DaliTabIndexes.OBSERVATION_GENERAL, getModel().getSurveyDetailsTabUIModel());
94          setCustomTab(DaliTabIndexes.OPERATION_MEASUREMENTS, getModel().getOperationMeasurementsTabUIModel());
95          setCustomTab(DaliTabIndexes.PHOTOS, getModel().getPhotosTabUIModel());
96  
97          // set label colors
98          ApplicationUIUtil.setChildrenLabelForeground(ui, getConfig().getColorThematicLabel());
99          ui.getObservationDescriptionLabel().setForeground(Color.BLACK);
100 
101         // Selection de l onglet actif
102         getTabPanel().setSelectedIndex(getUI().getTabIndex());
103 
104         // Binding save button
105         getUI().applyDataBinding(ObservationUI.BINDING_SAVE_BUTTON_ENABLED);
106 
107         // button border
108         getUI().getNextButton().setBorder(
109                 BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, getConfig().getColorHighlightButtonBorder()), ui.getNextButton().getBorder())
110         );
111 
112         // Listen modify
113         listenModelModify(getModel().getSurveyDetailsTabUIModel());
114         listenModelModify(getModel().getOperationMeasurementsTabUIModel());
115         listenModelModify(getModel().getPhotosTabUIModel());
116 
117         // Listen valid
118         listenModelValid(getModel().getSurveyDetailsTabUIModel());
119         listenModelValid(getModel().getOperationMeasurementsTabUIModel());
120         listenModelValid(getModel().getPhotosTabUIModel());
121 
122         // Register validators
123         registerValidators(
124                 getUI().getSurveyDetailsTabUI().getValidator(),
125                 getUI().getOperationMeasurementsTabUI().getValidator(),
126                 getUI().getPhotosTabUI().getValidator());
127 
128         // listener on properties that updates the title
129         getModel().addPropertyChangeListener(evt -> {
130             if (ObservationUIModel.PROPERTY_LOCATION.equals(evt.getPropertyName())
131                     || ObservationUIModel.PROPERTY_DATE.equals(evt.getPropertyName())
132                     || ObservationUIModel.PROPERTY_TIME.equals(evt.getPropertyName())
133                     || ObservationUIModel.PROPERTY_PROGRAM.equals(evt.getPropertyName())
134                     || ObservationUIModel.PROPERTY_NAME.equals(evt.getPropertyName())
135             ) {
136                 getUI().applyDataBinding(ObservationUI.BINDING_OBSERVATION_DESCRIPTION_LABEL_TEXT);
137             }
138         });
139 
140         // load model
141         loadSurvey();
142 
143     }
144 
145     /**
146      * {@inheritDoc}
147      */
148     @Override
149     public String getTitle() {
150         String contextName;
151         if (getContext().getSelectedContext() == null) {
152             contextName = t("dali.main.title.noContext");
153         } else {
154             contextName = getContext().getSelectedContext().getName();
155         }
156 
157         return String.format("%s [%s]", super.getTitle(), contextName);
158     }
159 
160     private void loadSurvey() {
161 
162         getModel().setLoading(true);
163         SurveyLoader loader = new SurveyLoader();
164         loader.execute();
165 
166     }
167 
168     /**
169      * Select next available tab
170      */
171     public void selectNextTab() {
172 
173         int index = getTabPanel().getSelectedIndex() + 1;
174 
175         if (index >= getTabPanel().getTabCount()) {
176             // if last tab is reached, return to ObservationUI
177             changeScreenAction(GoToObservationAction.class);
178         }
179 
180         while (index < getTabPanel().getTabCount()) {
181             if (getTabPanel().isEnabledAt(index)) {
182                 getTabPanel().setSelectedIndex(index);
183                 return;
184             }
185             index++;
186         }
187     }
188 
189     /**
190      * <p>refreshModels.</p>
191      */
192     public void refreshModels() {
193 
194         // force components to update enabled state if survey is editable or not
195         getModel().getSurveyDetailsTabUIModel().getUngroupedTableUIModel().setSurvey(getModel());
196         getModel().getSurveyDetailsTabUIModel().setEditable(getModel().isEditable());
197         getModel().getOperationMeasurementsTabUIModel().setObservationModel(getModel());
198         getModel().getPhotosTabUIModel().setObservationModel(getModel());
199     }
200 
201     /**
202      * {@inheritDoc}
203      */
204     @Override
205     public JTabbedPane getTabPanel() {
206         return getUI().getObservationTabbedPane();
207     }
208 
209     /**
210      * {@inheritDoc}
211      */
212     @Override
213     public boolean removeTab(int i) {
214         return false;
215     }
216 
217     /**
218      * {@inheritDoc}
219      */
220     @Override
221     @SuppressWarnings("unchecked")
222     public boolean quitUI() {
223         try {
224             QuitScreenAction action = new QuitScreenAction(this, false, SaveAction.class);
225             if (action.prepareAction()) {
226                 return true;
227             }
228         } catch (Exception e) {
229             LOG.error(e.getLocalizedMessage(), e);
230         }
231         return false;
232     }
233 
234     private class SurveyLoader extends SwingWorker<Object, Object> {
235 
236         @Override
237         protected Object doInBackground() {
238 
239             // Observation
240             final SurveyDTO survey = getContext().getObservationService().getSurvey(getContext().getSelectedSurveyId());
241 
242             // run a control
243             getContext().getRulesControlService().controlSurvey(survey, false, false);
244 
245             // Prepare editable state for general tab to speed up some behaviours
246             getModel().setEditable(!DaliBeans.isSurveyValidated(survey));
247             getModel().getSurveyDetailsTabUIModel().setEditable(getModel().isEditable());
248 
249             // load observation into parent model (this)
250             getModel().fromBean(survey);
251 
252             // load preconditioned rules
253             getModel().setPreconditionedRules(getContext().getRuleListService().getPreconditionedControlRulesForSurvey(survey));
254 
255             return null;
256         }
257 
258         @Override
259         protected void done() {
260             try {
261                 try {
262                     get();
263                 } catch (InterruptedException | ExecutionException e) {
264                     throw new DaliTechnicalException(e.getMessage(), e);
265                 }
266 
267                 getUI().applyDataBinding(ObservationUI.BINDING_OBSERVATION_DESCRIPTION_LABEL_TEXT);
268 
269                 // affect other models
270                 refreshModels();
271 
272                 if (getModel().isEditable()) {
273                     updateUnusedEditor();
274                 }
275 
276                 // Reset modify flag
277                 getModel().setModify(false);
278 
279             } finally {
280 
281                 getModel().setLoading(false);
282             }
283         }
284     }
285 
286     /**
287      * Update editors background when unselected in home screen
288      * Set unused background color to each component (not mandatory) without value
289      * <p>
290      * see Mantis #38351
291      */
292     private void updateUnusedEditor() {
293 
294         // get surveys table state
295         SwingTableState surveysTableState = getSurveysTableState();
296         if (surveysTableState == null) return;
297         Color unusedColor = getConfig().getColorUnusedEditorBackground();
298         SurveyDetailsTabUI surveyUI = getUI().getSurveyDetailsTabUI();
299         Map<String, Integer> visibility = surveysTableState.getVisibility();
300 
301         // time
302         if (getModel().getTime() == null && visibility.get(SurveysTableRowModel.PROPERTY_TIME) == -1) {
303             surveyUI.getTimeEditor().setBackground(unusedColor);
304         }
305 
306         // name
307         if (StringUtils.isEmpty(getModel().getName()) && visibility.get(SurveysTableRowModel.PROPERTY_NAME) == -1) {
308             surveyUI.getNameEditor().setBackground(unusedColor);
309         }
310 
311         // bottom depth
312         if (getModel().getBottomDepth() == null && visibility.get(SurveysTableRowModel.PROPERTY_BOTTOM_DEPTH) == -1) {
313             surveyUI.getBottomDepthEditor().getTextField().setBackground(unusedColor);
314         }
315 
316         // campaign
317         if (getModel().getCampaign() == null && visibility.get(SurveysTableRowModel.PROPERTY_CAMPAIGN) == -1) {
318             PlafUtils.changeBackground(surveyUI.getCampaignCombo().getCombobox(), unusedColor);
319         }
320 
321         CoordinateDTO coordinate = getModel().getCoordinate();
322         // latitude start
323         if ((coordinate == null || coordinate.getMinLatitude() == null) && visibility.get(SurveysTableRowModel.PROPERTY_LATITUDE_MIN) == -1) {
324             surveyUI.getSurveyLatitudeMinEditor().getTextField().setBackground(unusedColor);
325         }
326         // latitude end
327         if ((coordinate == null || coordinate.getMaxLatitude() == null) && visibility.get(SurveysTableRowModel.PROPERTY_LATITUDE_MAX) == -1) {
328             surveyUI.getSurveyLatitudeMaxEditor().getTextField().setBackground(unusedColor);
329         }
330         // longitude start
331         if ((coordinate == null || coordinate.getMinLongitude() == null) && visibility.get(SurveysTableRowModel.PROPERTY_LONGITUDE_MIN) == -1) {
332             surveyUI.getSurveyLongitudeMinEditor().getTextField().setBackground(unusedColor);
333         }
334         // longitude end
335         if ((coordinate == null || coordinate.getMaxLongitude() == null) && visibility.get(SurveysTableRowModel.PROPERTY_LONGITUDE_MAX) == -1) {
336             surveyUI.getSurveyLongitudeMaxEditor().getTextField().setBackground(unusedColor);
337         }
338 
339         // positioning
340         if (getModel().getPositioning() == null && visibility.get(SurveysTableRowModel.PROPERTY_POSITIONING) == -1) {
341             PlafUtils.changeBackground(surveyUI.getPositioningCombo().getCombobox(), unusedColor);
342             surveyUI.getPositioningCommentEditor().setBackground(unusedColor);
343         }
344 
345     }
346 
347     private SwingTableState getSurveysTableState() {
348 
349         State state = getContext().getSwingSession().findStateByComponentName("/homeUI.*/surveysTableUI.*/surveysTable");
350 
351         if (state instanceof SwingTableSessionState) {
352             SwingTableSessionState tableSessionState = (SwingTableSessionState) state;
353             if (tableSessionState.getSessionStates() != null) {
354                 return tableSessionState.getSessionStates().get(AbstractTableModel.DEFAULT_STATE_CONTEXT);
355             }
356         }
357 
358         return null;
359     }
360 
361 }