View Javadoc
1   package fr.ifremer.tutti.ui.swing.content.operation.catches;
2   
3   /*
4    * #%L
5    * Tutti :: UI
6    * %%
7    * Copyright (C) 2012 - 2014 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.collect.Sets;
26  import fr.ifremer.tutti.persistence.entities.referential.Species;
27  import fr.ifremer.tutti.type.WeightUnit;
28  import fr.ifremer.tutti.ui.swing.content.operation.catches.species.BenthosBatchUISupportImpl;
29  import fr.ifremer.tutti.ui.swing.content.operation.catches.species.EditSpeciesBatchPanelUI;
30  import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesOrBenthosBatchUISupport;
31  import fr.ifremer.tutti.ui.swing.util.AbstractTuttiTabContainerUIHandler;
32  import fr.ifremer.tutti.ui.swing.util.TuttiBeanMonitor;
33  import jaxx.runtime.swing.CardLayout2Ext;
34  import jaxx.runtime.validator.swing.SwingValidator;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.jdesktop.swingx.JXTitledPanel;
38  import org.nuiton.jaxx.application.swing.tab.TabContentModel;
39  import org.nuiton.jaxx.application.swing.tab.TabHandler;
40  
41  import javax.swing.JComponent;
42  import javax.swing.JOptionPane;
43  import javax.swing.JPanel;
44  import javax.swing.JTabbedPane;
45  import java.awt.Component;
46  import java.beans.PropertyChangeEvent;
47  import java.beans.PropertyChangeListener;
48  import java.util.Set;
49  
50  import static org.nuiton.i18n.I18n.n;
51  import static org.nuiton.i18n.I18n.t;
52  
53  /**
54   * @author Tony Chemit - chemit@codelutin.com
55   * @since 0.3
56   */
57  public class EditCatchesUIHandler extends AbstractTuttiTabContainerUIHandler<EditCatchesUIModel, EditCatchesUI>
58          implements TabHandler {
59  
60      public static final String MAIN_CARD = "main";
61  
62      public static final String CREATE_BATCH_CARD = "createBatch";
63  
64      public static final String EDIT_CARACTERISTICS_CARD = "caracteristicsCard";
65  
66      /** Logger. */
67      private static final Log log = LogFactory.getLog(EditCatchesUIHandler.class);
68  
69      /**
70       * To monitor changes on the incoming fishing operation.
71       *
72       * @since 0.3
73       */
74      private TuttiBeanMonitor<EditCatchesUIModel> catchBatchMonitor;
75  
76      /**
77       * To remove {@code 0} value of total rejected weight.
78       *
79       * @since 3.5
80       */
81      private final PropertyChangeListener totalWeightRejectedListener = new PropertyChangeListener() {
82  
83          public void propertyChange(PropertyChangeEvent evt) {
84  
85              EditCatchesUIModel source = (EditCatchesUIModel) evt.getSource();
86  
87              Float totalWeight = (Float) evt.getNewValue();
88  
89              if (totalWeight != null && WeightUnit.KG.isZero(totalWeight)) {
90  
91                  // remove the totalWeight (see https://forge.codelutin.com/issues/5144)
92                  source.setCatchTotalRejectedWeight(null);
93  
94              }
95          }
96      };
97  
98      /**
99       * To handle the svg canvas.
100      *
101      * @since 3.13
102      */
103     private EditCatchesSvgHandler editCatchesSvgHandler;
104 
105     //------------------------------------------------------------------------//
106     //-- AbstractTuttiUIHandler methods                                     --//
107     //------------------------------------------------------------------------//
108 
109     @Override
110     public void beforeInit(EditCatchesUI ui) {
111         super.beforeInit(ui);
112 
113         this.catchBatchMonitor = new TuttiBeanMonitor<EditCatchesUIModel>(
114                 EditCatchesUIModel.PROPERTY_MARINE_LITTER_TOTAL_WEIGHT,
115                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_SORTED_WEIGHT,
116                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_INERT_WEIGHT,
117                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_LIVING_NOT_ITEMIZED_WEIGHT,
118                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_SORTED_WEIGHT,
119                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_INERT_WEIGHT,
120                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_LIVING_NOT_ITEMIZED_WEIGHT);
121 
122         EditCatchesUIModel model = ui.getContextValue(EditCatchesUIModel.class);
123 
124         model.setValidationContext(getContext().getValidationContext());
125 
126         listModelIsModify(model);
127 
128         catchBatchMonitor.setBean(model);
129 
130         editCatchesSvgHandler = new EditCatchesSvgHandler(getContext(), ui, model);
131 
132     }
133 
134     @Override
135     public void afterInit(EditCatchesUI ui) {
136 
137         initUI(ui);
138 
139         EditCatchesUIModel model = getModel();
140 
141         changeValidatorContext(model.getValidationContext(), getValidator());
142         listenValidationTableHasNoFatalError(getValidator(), model);
143 
144         setCustomTab2(0, model,
145                       Sets.newHashSet(EditCatchesUIModel.PROPERTY_CATCH_TOTAL_WEIGHT,
146                                       EditCatchesUIModel.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT,
147                                       EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_SORTED_WEIGHT,
148                                       EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_INERT_WEIGHT,
149                                       EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_LIVING_NOT_ITEMIZED_WEIGHT,
150                                       EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_SORTED_WEIGHT,
151                                       EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_INERT_WEIGHT,
152                                       EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_LIVING_NOT_ITEMIZED_WEIGHT,
153                                       EditCatchesUIModel.PROPERTY_MARINE_LITTER_TOTAL_WEIGHT));
154 
155         setCustomTab(1, ui.getSpeciesTabPanel().getEditBatchesUI().getModel());
156         setCustomTab(2, ui.getBenthosTabPanel().getEditBatchesUI().getModel());
157         setCustomTab(3, ui.getMarineLitterTabContent().getModel());
158         setCustomTab(4, ui.getAccidentalTabContent().getModel());
159 
160         getTabPanel().setSelectedIndex(1);
161         // when internal tab change, close any attachments popup
162         getTabPanel().addChangeListener(e -> closeAttachments());
163 
164     }
165 
166     public void setCustomTab2(int index, TabContentModel model, Set<String> modifyPropertyNames) {
167 
168         JTabbedPane tabPanel = getTabPanel();
169         tabPanel.setTabComponentAt(index, CatchCustomTab.newCustomTab(model, this, modifyPropertyNames));
170 
171     }
172 
173     public void closeAttachments() {
174         ui.getCatchesCaracteristicsAttachmentsButton().onCloseUI();
175         ui.getSpeciesTabPanel().getEditBatchesUI().getSpeciesBatchAttachmentsButton().onCloseUI();
176         ui.getBenthosTabPanel().getEditBatchesUI().getSpeciesBatchAttachmentsButton().onCloseUI();
177         ui.getMarineLitterTabContent().getMarineLitterBatchAttachmentsButton().onCloseUI();
178         ui.getAccidentalTabContent().getAccidentalBatchAttachmentsButton().onCloseUI();
179     }
180 
181     @Override
182     protected JComponent getComponentToFocus() {
183         return null;
184     }
185 
186     @Override
187     public void onCloseUI() {
188 
189         if (log.isDebugEnabled()) {
190             log.debug("closing: " + ui);
191         }
192         ui.getCatchesCaracteristicsAttachmentsButton().onCloseUI();
193         editCatchesSvgHandler.clearSVG();
194 
195         // close batches tabs, then general tab
196         closeUI(ui.getSpeciesTabPanel());
197         closeUI(ui.getBenthosTabPanel());
198         closeUI(ui.getMarineLitterTabContent());
199         closeUI(ui.getAccidentalTabContent());
200     }
201 
202     @Override
203     public SwingValidator<EditCatchesUIModel> getValidator() {
204         return ui.getValidator();
205     }
206 
207     @Override
208     protected Set<String> getPropertiesToIgnore() {
209         Set<String> result = super.getPropertiesToIgnore();
210         result.addAll(Sets.newHashSet(
211                 EditCatchesUIModel.PROPERTY_CATCH_TOTAL_COMPUTED_WEIGHT,
212                 EditCatchesUIModel.PROPERTY_CATCH_TOTAL_UNSORTED_COMPUTED_WEIGHT,
213                 EditCatchesUIModel.PROPERTY_CATCH_TOTAL_SORTED_COMPUTED_WEIGHT,
214                 EditCatchesUIModel.PROPERTY_CATCH_TOTAL_SORTED_SORTED_COMPUTED_WEIGHT,
215                 EditCatchesUIModel.PROPERTY_CATCH_TOTAL_REJECTED_COMPUTED_WEIGHT,
216                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_COMPUTED_WEIGHT,
217                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_SORTED_COMPUTED_WEIGHT,
218                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_UNSORTED_COMPUTED_WEIGHT,
219                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT,
220                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_INERT_COMPUTED_WEIGHT,
221                 EditCatchesUIModel.PROPERTY_SPECIES_TOTAL_LIVING_NOT_ITEMIZED_COMPUTED_WEIGHT,
222                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_COMPUTED_WEIGHT,
223                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_SORTED_COMPUTED_WEIGHT,
224                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_UNSORTED_COMPUTED_WEIGHT,
225                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT,
226                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_INERT_COMPUTED_WEIGHT,
227                 EditCatchesUIModel.PROPERTY_BENTHOS_TOTAL_LIVING_NOT_ITEMIZED_COMPUTED_WEIGHT,
228                 EditCatchesUIModel.PROPERTY_SPECIES_DISTINCT_SORTED_SPECIES_COUNT,
229                 EditCatchesUIModel.PROPERTY_BENTHOS_DISTINCT_SORTED_SPECIES_COUNT,
230                 EditCatchesUIModel.PROPERTY_SPECIES_DISTINCT_UNSORTED_SPECIES_COUNT,
231                 EditCatchesUIModel.PROPERTY_BENTHOS_DISTINCT_UNSORTED_SPECIES_COUNT,
232                 EditCatchesUIModel.PROPERTY_MARINE_LITTER_TOTAL_COMPUTED_WEIGHT,
233                 EditCatchesUIModel.PROPERTY_ATTACHMENT
234         ));
235         return result;
236     }
237 
238     @Override
239     public JTabbedPane getTabPanel() {
240         return ui.getTabPane();
241     }
242 
243     @Override
244     public boolean onTabChanged(int currentIndex, int newIndex) {
245 
246         ui.getCatchesCaracteristicsAttachmentsButton().onCloseUI();
247         ui.getComputeSpeciesBatchButton().setVisible(newIndex < 4);
248         ui.getCleanSpeciesBatchButton().setVisible(newIndex > 0 && newIndex < 3);
249 
250         boolean result = super.onTabChanged(currentIndex, newIndex);
251 
252         if (result && currentIndex != newIndex) {
253 
254             result = getModel().isDoNotCheckLeavingFrequencyScreen() || blockIfNotLeavingFrequencyScreen();
255             if (!result) {
256                 return false;
257             }
258 
259             boolean showMainActions;
260 
261             if (currentIndex == 0) {
262                 editCatchesSvgHandler.clearSVG();
263             }
264             if (newIndex == 0) {
265 
266                 if (getUI().isVisible()) {
267 
268                     editCatchesSvgHandler.initResumeSvg();
269                 }
270                 showMainActions = true;
271 
272             } else {
273 
274                 JComponent componentAt = (JComponent) getTabPanel().getComponentAt(newIndex);
275                 CardLayout2Ext layout = (CardLayout2Ext) componentAt.getLayout();
276                 String selectedCard = layout.getSelected();
277                 showMainActions = selectedCard == null
278                         || MAIN_CARD.equals(selectedCard)
279                         || EditSpeciesBatchPanelUI.EDIT_BATCH_CARD.equals(selectedCard);
280 
281             }
282 
283             getUI().getCreateFishingOperationActions().setVisible(showMainActions);
284 
285         }
286 
287         return result;
288     }
289 
290     @Override
291     public boolean onHideTab(int currentIndex, int newIndex) {
292 
293         closeAttachments();
294 
295         EditCatchesUIModel model = getModel();
296         boolean result = blockIfNotLeavingFrequencyScreen();
297         if (!result) {
298             return false;
299         }
300 
301         if (model.isModify()) {
302 
303             if (model.isValid()) {
304 
305                 // ask user to save, do not save or cancel action
306                 int answer = askSaveBeforeLeaving(
307                         t("tutti.editCatchBatch.askSaveBeforeLeaving.saveCatchBatch"));
308                 switch (answer) {
309                     case JOptionPane.OK_OPTION:
310 
311                         // persist catch batch
312                         getContext().getActionEngine().runAction(getUI().getSaveButton());
313 
314                         result = true;
315                         break;
316 
317                     case JOptionPane.NO_OPTION:
318 
319                         // won't save modification
320                         // so since we will edit a new operation, nothing to do here
321 
322                         // persist catch batch
323                         getContext().getActionEngine().runAction(getUI().getCancelButton());
324 
325                         result = true;
326                         break;
327                     default:
328 
329                         // other case, use cancel action
330                         result = false;
331                 }
332             } else {
333 
334                 // model is not valid, ask user to loose modification or cancel
335                 result = askCancelEditBeforeLeaving(
336                         t("tutti.editCatchBatch.askCancelEditBeforeLeaving.cancelEditCatchBatch"));
337 
338                 if (result) {
339 
340                     // ok will revert any modification
341                     getContext().getActionEngine().runAction(ui.getCancelButton());
342                 }
343             }
344 
345         } else {
346 
347             // model not modify, can change tab
348             result = true;
349         }
350 
351         if (result) {
352             editCatchesSvgHandler.clearSVG();
353         }
354 
355         return result;
356     }
357 
358     @Override
359     public void onShowTab(int currentIndex, int newIndex) {
360         registerValidators();
361         editCatchesSvgHandler.initResumeSvg();
362     }
363 
364     @Override
365     public boolean removeTab(int i) {
366         return false;
367     }
368 
369     @Override
370     public boolean onRemoveTab() {
371         return false;
372     }
373 
374     //------------------------------------------------------------------------//
375     //-- Public methods                                                     --//
376     //------------------------------------------------------------------------//
377 
378     public EditSpeciesBatchPanelUI getEditSpeciesBatchPanelUI(SpeciesOrBenthosBatchUISupport batchUISupport) {
379         return batchUISupport instanceof BenthosBatchUISupportImpl ? ui.getBenthosTabPanel() : ui.getSpeciesTabPanel();
380     }
381 
382     public void uninstallTotalRejectWeightListener() {
383         getModel().removePropertyChangeListener(EditCatchesUIModel.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT, totalWeightRejectedListener);
384     }
385 
386     public void installTotalRejectWeightListener() {
387         getModel().addPropertyChangeListener(EditCatchesUIModel.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT, totalWeightRejectedListener);
388     }
389 
390     public TuttiBeanMonitor<EditCatchesUIModel> getCatchBatchMonitor() {
391         return catchBatchMonitor;
392     }
393 
394     protected void registerValidators() {
395         registerValidators(getValidator(),
396                            ui.getSpeciesTabPanel().getEditBatchesUI().getHandler().getValidator(),
397                            ui.getBenthosTabPanel().getEditBatchesUI().getHandler().getValidator(),
398                            ui.getMarineLitterTabContent().getHandler().getValidator()
399         );
400     }
401 
402     public void setMarineLitterSelectedCard(String card) {
403 
404         JPanel panel = ui.getMarineLitterTabPanel();
405         CardLayout2Ext layout = (CardLayout2Ext) panel.getLayout();
406         if (!card.equals(layout.getSelected())) {
407 
408             layout.setSelected(card);
409 
410             boolean showActionPanel;
411 
412             if (MAIN_CARD.equals(card)) {
413 
414                 registerValidators();
415                 showActionPanel = true;
416 
417             } else {
418 
419                 showActionPanel = false;
420 
421                 if (CREATE_BATCH_CARD.equals(card)) {
422 
423                     registerValidators(ui.getMarineLitterTabCreateBatch().getValidator());
424                     String title = n("tutti.createMarineLitterBatch.title");
425                     ui.getMarineLitterTabCreateBatchReminderLabel().setTitle(ui.getMarineLitterTabCreateBatchReminderLabel().getTitle() + " - " + t(title));
426 
427                 }
428 
429             }
430 
431             getUI().getCreateFishingOperationActions().setVisible(showActionPanel);
432 
433         }
434 
435     }
436 
437     public void setAccidentalSelectedCard(String card) {
438         setAccidentalSelectedCard(card, null);
439     }
440 
441     public void setAccidentalSelectedCard(String card, Species species) {
442 
443         JPanel panel = ui.getAccidentalTabPanel();
444         CardLayout2Ext layout = (CardLayout2Ext) panel.getLayout();
445         if (!card.equals(layout.getSelected())) {
446 
447             layout.setSelected(card);
448 
449             boolean showActionPanel;
450 
451             if (MAIN_CARD.equals(card)) {
452 
453                 registerValidators();
454                 showActionPanel = true;
455 
456             } else {
457 
458                 showActionPanel = false;
459 
460                 JXTitledPanel titlePanel = null;
461                 String title = "";
462 
463                 if (CREATE_BATCH_CARD.equals(card)) {
464 
465                     registerValidators(ui.getAccidentalTabCreateBatch().getValidator());
466                     titlePanel = ui.getAccidentalTabCreateBatchReminderLabel();
467                     title = n("tutti.createAccidentalBatch.title");
468 
469                 } else if (EDIT_CARACTERISTICS_CARD.equals(card)) {
470 
471                     titlePanel = ui.getAccidentalCaracteristicMapEditorReminderLabel();
472                     title = n("tutti.editCaracteristics.title");
473 
474                 }
475 
476                 if (titlePanel != null) {
477                     titlePanel.setTitle(ui.getAccidentalTabFishingOperationReminderLabel().getTitle() + " - " + t(title, decorate(species)));
478                 }
479 
480             }
481 
482             getUI().getCreateFishingOperationActions().setVisible(showActionPanel);
483 
484         }
485 
486     }
487 
488     private boolean blockIfNotLeavingFrequencyScreen() {
489 
490         Component selectedComponent = getUI().getTabPane().getSelectedComponent();
491 
492         if (selectedComponent != null) {
493 
494             EditSpeciesBatchPanelUI speciesTabPanel = getUI().getSpeciesTabPanel();
495             EditSpeciesBatchPanelUI benthosTabPanel = getUI().getBenthosTabPanel();
496 
497             if (speciesTabPanel.equals(selectedComponent)) {
498 
499                 if (EditSpeciesBatchPanelUI.EDIT_FREQUENCY_CARD.equals(speciesTabPanel.getTopPanelLayout().getSelected())) {
500 
501                     if (log.isInfoEnabled()) {
502                         log.info("Species frequencies screen on, try to leave it.");
503                     }
504                     boolean canContinue = speciesTabPanel.getEditFrequenciesUI().leaveIfConfirmed();
505                     if (!canContinue) {
506                         return false;
507                     }
508 
509                 }
510 
511             } else if (benthosTabPanel.equals(selectedComponent)) {
512 
513                 if (EditSpeciesBatchPanelUI.EDIT_FREQUENCY_CARD.equals(benthosTabPanel.getTopPanelLayout().getSelected())) {
514 
515                     if (log.isInfoEnabled()) {
516                         log.info("Benthos frequencies screen on, try to leave it.");
517                     }
518                     boolean canContinue = benthosTabPanel.getEditFrequenciesUI().leaveIfConfirmed();
519                     if (!canContinue) {
520                         return false;
521                     }
522 
523                 }
524 
525             }
526 
527         }
528 
529         return true;
530 
531     }
532 
533 }