1 package fr.ifremer.allegro.obsdeb.ui.swing.content.catches.treetable;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.base.Predicate;
27 import com.google.common.collect.Lists;
28 import fr.ifremer.allegro.obsdeb.decorator.ObsdebDecorator;
29 import fr.ifremer.allegro.obsdeb.dto.ObsdebEntities;
30 import fr.ifremer.allegro.obsdeb.dto.ObsdebEntity;
31 import fr.ifremer.allegro.obsdeb.dto.ObsdebEntityComparator;
32 import fr.ifremer.allegro.obsdeb.dto.data.fishingtrip.FishingOperationGroupDTO;
33 import fr.ifremer.allegro.obsdeb.dto.data.sales.SaleDTO;
34 import fr.ifremer.allegro.obsdeb.dto.referential.QualitativeValueDTO;
35 import fr.ifremer.allegro.obsdeb.dto.referential.TaxonGroupDTO;
36 import fr.ifremer.allegro.obsdeb.service.ObsdebDataContext;
37 import fr.ifremer.allegro.obsdeb.service.ObsdebTechnicalException;
38 import fr.ifremer.allegro.obsdeb.ui.swing.content.catches.CatchesUI;
39 import fr.ifremer.allegro.obsdeb.ui.swing.content.catches.CatchesUIHandler;
40 import fr.ifremer.allegro.obsdeb.ui.swing.content.catches.SaveCatchesWorkerAction;
41 import fr.ifremer.allegro.obsdeb.ui.swing.util.ObsdebBeanMonitor;
42 import fr.ifremer.allegro.obsdeb.ui.swing.util.ObsdebUI;
43 import fr.ifremer.allegro.obsdeb.ui.swing.util.ObsdebUIUtil;
44 import fr.ifremer.allegro.obsdeb.ui.swing.util.table.ObsdebColumnIdentifier;
45 import fr.ifremer.allegro.obsdeb.ui.swing.util.table.component.ComboBoxCellRenderer;
46 import fr.ifremer.allegro.obsdeb.ui.swing.util.table.component.FilterableComboBoxCellEditor;
47 import fr.ifremer.allegro.obsdeb.ui.swing.util.treetable.AbstractObsdebTreeTableModel;
48 import fr.ifremer.allegro.obsdeb.ui.swing.util.treetable.AbstractObsdebTreeTableNode;
49 import fr.ifremer.allegro.obsdeb.ui.swing.util.treetable.AbstractObsdebTreeTableUIHandler;
50 import fr.ifremer.allegro.obsdeb.ui.swing.util.treetable.TreeTableCellRenderer;
51 import jaxx.runtime.SwingUtil;
52 import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
53 import jaxx.runtime.validator.swing.SwingValidator;
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56 import org.jdesktop.swingx.JXTreeTable;
57 import org.jdesktop.swingx.table.TableColumnExt;
58
59 import javax.swing.*;
60 import javax.swing.event.CellEditorListener;
61 import javax.swing.event.ChangeEvent;
62 import javax.swing.table.TableModel;
63 import javax.swing.tree.DefaultTreeCellRenderer;
64 import java.awt.*;
65 import java.beans.PropertyChangeEvent;
66 import java.beans.PropertyChangeListener;
67 import java.util.ArrayList;
68 import java.util.Collections;
69 import java.util.List;
70 import java.util.Objects;
71
72 import static org.nuiton.i18n.I18n.t;
73
74
75
76
77 public class CatchesTreeTableUIHandler extends AbstractObsdebTreeTableUIHandler<
78 CatchesRowModel, CatchesTreeTableUIModel, CatchesTreeTableNode, CatchesTreeTableHelper, CatchesTreeTableUI> {
79
80 private static final Log log = LogFactory.getLog(CatchesTreeTableUIHandler.class);
81
82 private CatchesTreeTableHelper helper;
83
84 private SaveCatchesWorkerAction saveCatchesWorkerAction;
85
86 private FilterableComboBoxCellEditor<QualitativeValueDTO> dressingCellEditor;
87 private FilterableComboBoxCellEditor<QualitativeValueDTO> preservationCellEditor;
88 private FilterableComboBoxCellEditor<QualitativeValueDTO> sizeCategoryCellEditor;
89 private FilterableComboBoxCellEditor<QualitativeValueDTO> packagingCellEditor;
90 private FilterableComboBoxCellEditor<FishingOperationGroupDTO> effortCellEditor;
91 private ComboBoxCellRenderer effortCellRenderer;
92
93 public void setCatchesUIHandler(CatchesUIHandler catchesUIHandler) {
94 saveCatchesWorkerAction = getContext().getActionFactory().createNonBlockingUIAction(catchesUIHandler, SaveCatchesWorkerAction.class);
95 }
96
97 public CatchesTreeTableUIHandler() {
98 super(CatchesRowModel.PROPERTY_TAXON_GROUP,
99 CatchesRowModel.PROPERTY_WEIGHT,
100 CatchesRowModel.PROPERTY_NUMBER,
101 CatchesRowModel.PROPERTY_PACKAGING,
102 CatchesRowModel.PROPERTY_OPERATION_GROUP,
103 CatchesRowModel.PROPERTY_DRESSING,
104 CatchesRowModel.PROPERTY_PRESERVATION,
105 CatchesRowModel.PROPERTY_CATCH_FIELD_CATEGORY);
106 }
107
108 @Override
109 public void beforeInit(CatchesTreeTableUI ui) {
110 super.beforeInit(ui);
111 CatchesTreeTableUIModel model = new CatchesTreeTableUIModel();
112 ui.setContextValue(model);
113 }
114
115 @Override
116 public void afterInit(CatchesTreeTableUI ui) {
117 initUI(ui);
118
119 initRenderersAndEditors();
120
121 initCatchesTreeTable();
122
123
124 getModel().addPropertyChangeListener(CatchesTreeTableUIModel.PROPERTY_SELECTED_EFFORT, new PropertyChangeListener() {
125
126 @Override
127 public void propertyChange(PropertyChangeEvent evt) {
128
129
130 getHelper().modelChanged();
131
132 }
133 });
134
135 ui.applyDataBinding(CatchesTreeTableUI.BINDING_DELETE_BUTTON_ENABLED);
136 ui.applyDataBinding(CatchesTreeTableUI.BINDING_DELETE_MENU_ITEM_ENABLED);
137
138 }
139
140 private void initRenderersAndEditors() {
141
142
143
144
145 dressingCellEditor = newFilterableComboBoxCellEditor(
146 new ArrayList<QualitativeValueDTO>(),
147 QualitativeValueDTO.class, false);
148
149 dressingCellEditor.addCellEditorListener(new CellEditorListener() {
150
151 @Override
152 public void editingStopped(ChangeEvent e) {
153 getModel().setLastDressing((QualitativeValueDTO) dressingCellEditor.getCellEditorValue());
154 }
155
156 @Override
157 public void editingCanceled(ChangeEvent e) {
158 }
159 });
160
161
162
163
164 preservationCellEditor = newFilterableComboBoxCellEditor(
165 new ArrayList<QualitativeValueDTO>(),
166 QualitativeValueDTO.class, false);
167
168 preservationCellEditor.addCellEditorListener(new CellEditorListener() {
169
170 @Override
171 public void editingStopped(ChangeEvent e) {
172 getModel().setLastPreservation((QualitativeValueDTO) preservationCellEditor.getCellEditorValue());
173 }
174
175 @Override
176 public void editingCanceled(ChangeEvent e) {
177 }
178 });
179
180
181
182
183 sizeCategoryCellEditor = newFilterableComboBoxCellEditor(
184 new ArrayList<QualitativeValueDTO>(),
185 QualitativeValueDTO.class, false);
186
187
188
189
190 packagingCellEditor = newFilterableComboBoxCellEditor(
191 new ArrayList<QualitativeValueDTO>(),
192 QualitativeValueDTO.class, false);
193
194
195
196
197 effortCellRenderer = new ComboBoxCellRenderer<FishingOperationGroupDTO>(newTableCellRender(FishingOperationGroupDTO.class)) {
198
199 @Override
200 protected List<FishingOperationGroupDTO> getList() {
201 return getFishingOperationGroupList();
202 }
203 };
204
205
206
207
208 effortCellEditor = newFilterableComboBoxCellEditor(
209 getFishingOperationGroupList(),
210 FishingOperationGroupDTO.class, false);
211
212
213 getContext().getDataContext().addPropertyChangeListener(ObsdebDataContext.PROPERTY_FISHING_OPERATION_GROUP, new PropertyChangeListener() {
214
215 @Override
216 public void propertyChange(PropertyChangeEvent evt) {
217
218
219 List<FishingOperationGroupDTO> newList = getFishingOperationGroupList();
220 effortCellEditor.getCombo().setData(newList);
221 effortCellEditor.getCombo().firePropertyChange(BeanFilterableComboBox.PROPERTY_DATA, null, newList);
222
223
224 getModel().setLastEffort(null);
225 }
226 });
227
228
229 getModel().addPropertyChangeListener(new PropertyChangeListener() {
230
231 @Override
232 public void propertyChange(PropertyChangeEvent evt) {
233
234 if (null != evt.getPropertyName()) {
235 switch (evt.getPropertyName()) {
236
237 case CatchesTreeTableUIModel.PROPERTY_EFFORT_DECORATOR_INDEX:
238
239 int index = (int) evt.getNewValue();
240
241 effortCellEditor.getCombo().setIndex(index);
242
243 TreeTableCellRenderer decoratorRenderer = (TreeTableCellRenderer) effortCellRenderer.getDelegateRenderer();
244 ObsdebDecorator decorator = (ObsdebDecorator) decoratorRenderer.getDecorator();
245 decorator.setContextIndex(index);
246 break;
247
248 case CatchesTreeTableUIModel.PROPERTY_EFFORT_DECORATOR_REVERSE_SORT:
249
250 boolean reverseSort = (boolean) evt.getNewValue();
251 effortCellEditor.getCombo().setReverseSort(reverseSort);
252 break;
253 }
254 }
255 }
256 });
257
258
259 effortCellEditor.addCellEditorListener(new CellEditorListener() {
260
261 @Override
262 public void editingStopped(ChangeEvent e) {
263 FishingOperationGroupDTO opGroup = (FishingOperationGroupDTO) effortCellEditor.getCellEditorValue();
264 getModel().setLastEffort(opGroup);
265 }
266
267 @Override
268 public void editingCanceled(ChangeEvent e) {
269 }
270 });
271
272 }
273
274 private void initCatchesTreeTable() {
275
276
277 CatchesDataProvider catchesDataProvider = new CatchesDataProvider() {
278
279 @Override
280 protected List<CatchesRowModel> getData() {
281
282
283 return getFilteredCatchesRowList();
284
285 }
286
287 @Override
288 protected void setData(List<CatchesRowModel> list) {
289
290
291 getModel().deleteRows(ObsdebEntities.getSet(getFilteredCatchesRowList()));
292
293
294 getModel().addRows(list);
295 }
296 };
297
298
299 helper = new CatchesTreeTableHelper(catchesDataProvider, this);
300
301
302 initTreeTable();
303
304
305 final Icon batchIcon = SwingUtil.createActionIcon("batch");
306 final Icon fractionBatchIcon = SwingUtil.createActionIcon("fractionBatch");
307
308
309 getTreeTable().setTreeCellRenderer(new DefaultTreeCellRenderer() {
310
311 @Override
312 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
313 JLabel label = (JLabel) super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
314
315
316 CatchesTreeTableNode node = (CatchesTreeTableNode) value;
317 label.setIcon(null);
318 if (CatchesTreeTableNode.CONTEXT_NORMAL_ROW.equals(node.getContext())
319 || CatchesTreeTableNode.CONTEXT_NEW_ROW.equals(node.getContext())) {
320 label.setIcon(batchIcon);
321 } else if (CatchesTreeTableNode.CONTEXT_PARENT_ROW.equals(node.getContext())) {
322 label.setIcon(batchIcon);
323 } else if (CatchesTreeTableNode.CONTEXT_CHILD_ROW.equals(node.getContext())) {
324 label.setIcon(fractionBatchIcon);
325 }
326
327
328 label.setText(null);
329
330 return label;
331 }
332
333 });
334
335 getTreeTable().setDefaultRenderer(QualitativeValueDTO.class, newTableCellRender(QualitativeValueDTO.class));
336
337 }
338
339 @Override
340 public void configureTreeTableColumn(TableModel model, TableColumnExt columnExt) {
341
342 ObsdebColumnIdentifier identifier = (ObsdebColumnIdentifier) columnExt.getIdentifier();
343 switch (identifier.getPropertyName()) {
344
345 case CatchesRowModel.PROPERTY_TAXON_GROUP: {
346
347
348 columnExt.setCellRenderer(newTableCellRender(TaxonGroupDTO.class));
349
350
351 columnExt.setCellEditor(newFilterableComboBoxCellEditor(
352 getContext().getReferentialService().getAllTaxonGroup(), TaxonGroupDTO.class, false));
353
354 }
355 break;
356
357 case CatchesRowModel.PROPERTY_WEIGHT: {
358
359 columnExt.setCellEditor(newNumberCellEditor(Double.class, false, ObsdebUI.DECIMAL2_PATTERN));
360 columnExt.setCellRenderer(newNumberCellRenderer(2));
361
362 }
363 break;
364
365 case CatchesRowModel.PROPERTY_NUMBER: {
366
367 columnExt.setCellEditor(newNumberCellEditor(Integer.class, false, ObsdebUI.INT_4_DIGITS_PATTERN));
368 columnExt.setCellRenderer(newNumberCellRenderer(0));
369
370 }
371 break;
372
373 case CatchesRowModel.PROPERTY_PACKAGING: {
374
375 columnExt.setCellEditor(packagingCellEditor);
376
377 }
378 break;
379
380 case CatchesRowModel.PROPERTY_OPERATION_GROUP: {
381
382
383 columnExt.setHideable(false);
384
385
386 columnExt.setCellRenderer(effortCellRenderer);
387
388
389 columnExt.setCellEditor(effortCellEditor);
390 }
391 break;
392
393 case CatchesRowModel.PROPERTY_DRESSING: {
394
395 columnExt.setCellEditor(dressingCellEditor);
396
397 }
398 break;
399
400 case CatchesRowModel.PROPERTY_PRESERVATION: {
401
402 columnExt.setCellEditor(preservationCellEditor);
403
404 }
405 break;
406
407 case CatchesRowModel.PROPERTY_CATCH_FIELD_CATEGORY: {
408
409 columnExt.setCellEditor(sizeCategoryCellEditor);
410
411 }
412 break;
413
414 }
415 }
416
417 @Override
418 protected void onAfterSelectedNodeChanged(CatchesTreeTableNode oldNode, CatchesTreeTableNode newNode) {
419 super.onAfterSelectedNodeChanged(oldNode, newNode);
420
421
422 if (newNode != null && !AbstractObsdebTreeTableNode.CONTEXT_PARENT_ROW.equals(newNode.getContext())) {
423 populateAvailableLists(newNode.getUserObject());
424 }
425 }
426
427 private class PopulatorWorker extends SwingWorker<Object, Object> {
428
429 CatchesRowModel row;
430
431 List<QualitativeValueDTO> dressings;
432 List<QualitativeValueDTO> preservations;
433 List<QualitativeValueDTO> sizeCategories;
434
435 public void setRow(CatchesRowModel row) {
436 this.row = row;
437 }
438
439 @Override
440 protected Object doInBackground() throws Exception {
441 Integer taxonGroupId = row.getTaxonGroup() != null ? row.getTaxonGroup().getId() : null;
442
443
444 dressings = getContext().getRegionalizedDressings(taxonGroupId);
445
446
447 preservations = getContext().getRegionalizedPreservations(taxonGroupId);
448
449
450 sizeCategories = getContext().getReferentialService().getAllSizeSortingCategory();
451
452 return null;
453 }
454
455 @Override
456 protected void done() {
457
458
459 if (getModel().getLastDressing() == null) {
460 if (row.getDressing() != null) {
461 getModel().setLastDressing(row.getDressing());
462 } else {
463 getModel().setLastDressing(getLastDressingInRows());
464 }
465 }
466 if (getModel().getLastPreservation() == null) {
467 if (row.getPreservation() != null) {
468 getModel().setLastPreservation(row.getPreservation());
469 } else {
470 getModel().setLastPreservation(getLastPreservationInRows());
471 }
472 }
473
474
475 row.setOperationGroup(getDefaultValue(row.getOperationGroup(), getModel().getLastEffort(), null, getFishingOperationGroupList()));
476
477
478 dressingCellEditor.getCombo().setData(dressings);
479
480 QualitativeValueDTO defaultDressing = getConfig().isCatchesWholeAndFreshByDefaultEnable()
481 ? getContext().getReferentialService().getDressing(
482 getConfig().getQualitativeValueIdDressingWhole())
483 : null;
484 row.setDressing(getDefaultValue(row.getDressing(), getModel().getLastDressing(), defaultDressing, dressings));
485
486
487 preservationCellEditor.getCombo().setData(preservations);
488 QualitativeValueDTO defaultPreservation = getConfig().isCatchesWholeAndFreshByDefaultEnable()
489 ? getContext().getReferentialService().getPreservation(
490 getConfig().getQualitativeValueIdPreservationFresh())
491 : null;
492 row.setPreservation(getDefaultValue(row.getPreservation(), getModel().getLastPreservation(), defaultPreservation, preservations));
493
494
495 sizeCategoryCellEditor.getCombo().setData(sizeCategories);
496 row.setCatchFieldCategory(getDefaultValue(row.getCatchFieldCategory(),
497 getContext().getReferentialService().getSizeSortingCategory(
498 getConfig().getQualitativeValueIdSizeSortingCategoryNone()),
499 null,
500 sizeCategories));
501
502 }
503
504 }
505
506 protected void populateAvailableLists(CatchesRowModel row) {
507
508 if (row == null) {
509 return;
510 }
511
512
513 PopulatorWorker populatorWorker = new PopulatorWorker();
514 populatorWorker.setRow(row);
515 populatorWorker.execute();
516
517 populateAvailablePackaging(row);
518 }
519
520 private void populateAvailablePackaging(CatchesRowModel row) {
521 if (row == null) {
522 return;
523 }
524
525
526 List<QualitativeValueDTO> packagings = getContext().getReferentialService().getAllProducePackaging();
527 packagingCellEditor.getCombo().setData(packagings);
528
529 if (row.getNumber() != null) {
530
531 row.setPackaging(getDefaultValue(row.getPackaging(),
532 getContext().getReferentialService().getProducePackaging(
533 getConfig().getQualitativeValueIdDefaultPackaging()),
534 null,
535 packagings));
536 } else {
537 row.setPackaging(null);
538 }
539 }
540
541 private <E extends ObsdebEntity> E getDefaultValue(E actualValue, E lastValue, E fallbackValue, List<E> values) {
542 E defaultValue = actualValue;
543
544 if (defaultValue == null) {
545 defaultValue = lastValue;
546 }
547
548 if (!values.contains(defaultValue) && values.size() == 1) {
549 defaultValue = values.get(0);
550 }
551
552
553 if (defaultValue == null && values.contains(fallbackValue)) {
554 defaultValue = fallbackValue;
555 }
556
557 return defaultValue;
558 }
559
560 private List<CatchesRowModel> getFilteredCatchesRowList() {
561
562 if (getModel().getRowCount() == 0) {
563 return Lists.newArrayList();
564 }
565
566 if (getModel().getSelectedEffort() == null) {
567 return getModel().getRows();
568 }
569
570
571 return ObsdebEntities.filter(getModel().getRows(), new Predicate<CatchesRowModel>() {
572
573 @Override
574 public boolean apply(CatchesRowModel input) {
575 return input != null && Objects.equals(getModel().getSelectedEffort(), input.getOperationGroup());
576 }
577 });
578 }
579
580 public List<FishingOperationGroupDTO> getFishingOperationGroupList() {
581 return getParentHandler().getFishingOperationGroupList();
582 }
583
584 private CatchesUIHandler getParentHandler() {
585
586 ObsdebUI parentUI = ObsdebUIUtil.getParentUI(getUI());
587
588 if (parentUI instanceof CatchesUI) {
589 CatchesUI catchesUI = (CatchesUI) parentUI;
590 return catchesUI.getHandler();
591 }
592
593 throw new ObsdebTechnicalException("the CatchesUIHandler has not been found from CatchesTreeTableUIHandler");
594 }
595
596 @Override
597 public Class<? extends AbstractObsdebTreeTableModel> getTreeTableModelClass() {
598 return CatchesTreeTableModel.class;
599 }
600
601 @Override
602 public CatchesTreeTableHelper getHelper() {
603 return helper;
604 }
605
606 @Override
607 public JXTreeTable getTreeTable() {
608 return ui.getTreeTable();
609 }
610
611 @Override
612 protected boolean isRowValid(CatchesRowModel row) {
613
614 if (row.isCalculated()) {
615
616 return true;
617 }
618
619 boolean valid = super.isRowValid(row);
620
621
622 valid &= row.getWeight() != null || row.getNumber() != null;
623
624
625 valid &= !(row.getNumber() == null ^ row.getPackaging() == null);
626
627 return valid;
628 }
629
630 @Override
631 protected void saveSelectedRowIfRequired(ObsdebBeanMonitor<CatchesRowModel> rowMonitor, CatchesTreeTableNode node) {
632 }
633
634 public void saveDataWithDelete() {
635
636
637 saveCatchesWorkerAction.setForceDirty(true);
638
639 saveData();
640 }
641
642 public void reloadData() {
643
644
645 saveCatchesWorkerAction.setReloadCatches(true);
646
647 saveData();
648 }
649
650 public void saveData() {
651
652
653 saveCatchesWorkerAction.execute();
654 }
655
656 @Override
657 protected void onRowModified(CatchesRowModel row, String propertyName, Object oldValue, Object newValue) {
658
659
660 if (!row.isEditable()) {
661 return;
662 }
663 row.setEditable(false);
664
665
666 boolean isRowToSave = !row.isDirty() || row.isCreate();
667
668 if (CatchesRowModel.PROPERTY_TAXON_GROUP.equals(propertyName)) {
669
670 TaxonGroupDTO oldTaxonGroup = (TaxonGroupDTO) oldValue;
671
672 if (!row.isCreate() && oldTaxonGroup != null && newValue == null) {
673
674 row.setTaxonGroup(oldTaxonGroup);
675 isRowToSave = false;
676 } else {
677
678
679 if (isSaleCantBeDeleted(CatchesTreeTableModel.TAXON_GROUP, oldTaxonGroup, row.getPackaging(), row.getCatchFieldCategory())) {
680
681 row.setTaxonGroup(oldTaxonGroup);
682 isRowToSave = false;
683 }
684 }
685
686
687 populateAvailableLists(row);
688 }
689
690 if (CatchesRowModel.PROPERTY_NUMBER.equals(propertyName)) {
691 Integer oldNumber = (Integer) oldValue;
692
693 row.setEditable(true);
694 populateAvailablePackaging(row);
695
696 if (!isRowToSave) {
697 row.setEditable(false);
698 row.setNumber(oldNumber);
699 isRowToSave = false;
700 }
701 }
702
703 if (CatchesRowModel.PROPERTY_PACKAGING.equals(propertyName)) {
704
705 QualitativeValueDTO oldPackaging = (QualitativeValueDTO) oldValue;
706
707 if (isSaleCantBeDeleted(CatchesTreeTableModel.PACKAGING, row.getTaxonGroup(), oldPackaging, row.getCatchFieldCategory())) {
708
709 row.setPackaging(oldPackaging);
710 isRowToSave = false;
711 }
712 }
713
714 if (CatchesRowModel.PROPERTY_CATCH_FIELD_CATEGORY.equals(propertyName)) {
715
716 QualitativeValueDTO oldCategory = (QualitativeValueDTO) oldValue;
717
718 if (isSaleCantBeDeleted(CatchesTreeTableModel.CATCH_FIELD_CATEGORY, row.getTaxonGroup(), row.getPackaging(), oldCategory)) {
719
720 row.setCatchFieldCategory(oldCategory);
721 isRowToSave = false;
722 }
723 }
724
725 if (row.hasParent()) {
726
727 CatchesRowModel parentRow = row.getParent();
728 getHelper().getDataProvider().calculateAggregation(parentRow);
729 recomputeRowValidState(parentRow);
730 getHelper().refreshRow(row);
731 }
732
733 if (isRowToSave) {
734 super.onRowModified(row, propertyName, oldValue, newValue);
735 row.setDirty(true);
736 if (row.isValid()) {
737 saveData();
738 }
739 }
740
741 row.setEditable(true);
742 }
743
744 private boolean isSaleCantBeDeleted(ObsdebColumnIdentifier columnIdentifier, TaxonGroupDTO taxonGroup, QualitativeValueDTO packaging, QualitativeValueDTO category) {
745 return isCatchHasSale(taxonGroup, packaging, category)
746 && !askBeforeDelete(
747 t("obsdeb.action.edit.catches.canDeleteSale.title"),
748 t("obsdeb.action.edit.catches.canDeleteSale.message", t(columnIdentifier.getHeaderI18nKey())));
749 }
750
751 private boolean isCatchHasSale(TaxonGroupDTO taxonGroup, QualitativeValueDTO packaging, QualitativeValueDTO category) {
752
753 List<? extends SaleDTO> sales = getContext().getOverallSale().getSales();
754 for (SaleDTO sale : sales) {
755 if (sale.getId() != null
756 && Objects.equals(taxonGroup, sale.getTaxonGroup())
757 && Objects.equals(category, sale.getCategory())
758 && Objects.equals(packaging, sale.getPackaging())) {
759
760
761 return true;
762 }
763 }
764 return false;
765 }
766
767 @Override
768 protected String[] getRowPropertiesToIgnore() {
769 return new String[]{CatchesRowModel.PROPERTY_DIRTY};
770 }
771
772 @Override
773 public void onCloseUI() {
774 if (log.isDebugEnabled()) {
775 log.debug("Closing: " + ui);
776 }
777 }
778
779 @Override
780 public SwingValidator<CatchesTreeTableUIModel> getValidator() {
781 return null;
782 }
783
784 @Override
785 protected JComponent getComponentToFocus() {
786 return null;
787 }
788
789 private QualitativeValueDTO getLastDressingInRows() {
790 for (CatchesRowModel row : getSortedRows()) {
791 QualitativeValueDTO dressing = row.getDressing();
792 if (dressing != null) {
793 return dressing;
794 }
795 }
796 return null;
797 }
798
799 private QualitativeValueDTO getLastPreservationInRows() {
800 for (CatchesRowModel row : getSortedRows()) {
801 QualitativeValueDTO preservation = row.getPreservation();
802 if (preservation != null) {
803 return preservation;
804 }
805 }
806 return null;
807 }
808
809 private List<CatchesRowModel> getSortedRows() {
810 List<CatchesRowModel> rows = Lists.newArrayList(getModel().getRows());
811
812 Collections.sort(rows, new ObsdebEntityComparator() {
813
814 @Override
815 public int compare(ObsdebEntity left, ObsdebEntity right) {
816 return -super.compare(left, right);
817 }
818 });
819 return rows;
820 }
821
822 }