1 package fr.ifremer.tutti.ui.swing.content.cruise;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Predicate;
26 import com.google.common.collect.Lists;
27 import fr.ifremer.tutti.persistence.entities.data.Attachment;
28 import fr.ifremer.tutti.persistence.entities.data.Cruise;
29 import fr.ifremer.tutti.persistence.entities.data.Program;
30 import fr.ifremer.tutti.persistence.entities.referential.Gear;
31 import fr.ifremer.tutti.persistence.entities.referential.GearWithOriginalRankOrder;
32 import fr.ifremer.tutti.persistence.entities.referential.GearWithOriginalRankOrders;
33 import fr.ifremer.tutti.persistence.entities.referential.Gears;
34 import fr.ifremer.tutti.persistence.entities.referential.Person;
35 import fr.ifremer.tutti.persistence.entities.referential.Vessel;
36 import fr.ifremer.tutti.service.DecoratorService;
37 import fr.ifremer.tutti.service.PersistenceService;
38 import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler;
39 import jaxx.runtime.JAXXUtil;
40 import jaxx.runtime.context.JAXXContextEntryDef;
41 import jaxx.runtime.swing.editor.bean.BeanDoubleListModel;
42 import jaxx.runtime.validator.swing.SwingValidator;
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45 import org.nuiton.jaxx.application.swing.util.CloseableUI;
46
47 import javax.swing.JComponent;
48 import javax.swing.JList;
49 import javax.swing.JPopupMenu;
50 import javax.swing.JSeparator;
51 import javax.swing.SwingUtilities;
52 import java.awt.Point;
53 import java.awt.Rectangle;
54 import java.awt.event.KeyAdapter;
55 import java.awt.event.KeyEvent;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.util.List;
59 import java.util.Set;
60
61 import static org.nuiton.i18n.I18n.t;
62
63
64
65
66
67
68
69 public class EditCruiseUIHandler extends AbstractTuttiUIHandler<EditCruiseUIModel, EditCruiseUI> implements CloseableUI {
70
71
72 private static final Log log = LogFactory.getLog(EditCruiseUIHandler.class);
73
74 public static final String CRUISE_CARD = "cruise";
75
76 public static final String GEAR_CARACTERISTICS_CARD = "gearCaracteristics";
77
78 public static String getTitle(boolean exist) {
79
80 String result;
81 if (exist) {
82 result = t("tutti.editCruise.title.edit.cruise");
83 } else {
84 result = t("tutti.editCruise.title.create.cruise");
85 }
86 return result;
87 }
88
89
90
91
92
93
94 protected JPopupMenu gearPopupMenu;
95
96 @Override
97 public void beforeInit(EditCruiseUI ui) {
98
99 super.beforeInit(ui);
100
101 getDataContext().resetValidationDataContext();
102
103 EditCruiseUIModel model = new EditCruiseUIModel();
104 model.setSynchronizationStatus("DIRTY");
105 model.setValidationContext(getContext().getValidationContext());
106
107 if (getContext().isCruiseFilled()) {
108
109
110 Cruise cruise = getDataContext().getCruise();
111
112 model.fromEntity(cruise);
113
114 if (!model.isGearEmpty()) {
115
116
117 for (GearWithOriginalRankOrder gear : model.getGear()) {
118
119
120 gear.setOriginalRankOrder(gear.getRankOrder());
121 }
122 }
123
124
125 List<Attachment> attachments = getPersistenceService().getAllAttachments(
126 model.getObjectType(), model.getObjectId());
127 model.addAllAttachment(attachments);
128
129 if (log.isDebugEnabled()) {
130 log.debug("Will edit cruise: " + cruise.getId());
131 }
132 } else {
133
134
135 Program program = getDataContext().getProgram();
136 model.setProgram(program);
137 model.setMultirigNumber(1);
138
139
140 if (log.isDebugEnabled()) {
141 log.debug("Will create a new cruise from program: " + program);
142 }
143 }
144 listModelIsModify(model);
145 this.ui.setContextValue(model);
146 }
147
148 @Override
149 public void afterInit(EditCruiseUI ui) {
150
151 initUI(this.ui);
152
153
154
155 ui.getBeginTimeField().setDate(getModel().getBeginDate());
156 ui.getEndTimeField().setDate(getModel().getEndDate());
157
158 PersistenceService persistenceService = getPersistenceService();
159
160 List<Person> users = persistenceService.getAllPerson();
161
162 EditCruiseUIModel model = getModel();
163
164 List<Vessel> scientificVesselList = getDataContext().getScientificVessels();
165 List<Vessel> fishingVesselList = getDataContext().getFishingVessels();
166 List<Vessel> allVesselList = Lists.newArrayList();
167 allVesselList.addAll(scientificVesselList);
168 allVesselList.addAll(fishingVesselList);
169
170 List<Gear> scientificGearList = getDataContext().getScientificGears();
171 List<Gear> fishingGearList = getDataContext().getFishingGears();
172 List<Gear> allGearList = Lists.newArrayList();
173 allGearList.addAll(scientificGearList);
174 allGearList.addAll(fishingGearList);
175
176
177 model.addPropertyChangeListener(EditCruiseUIModel.PROPERTY_VESSEL_TYPE, evt -> {
178
179 VesselTypeEnum vesselType = (VesselTypeEnum) evt.getNewValue();
180
181 Predicate<Gear> gearPredicate = null;
182
183 List<Vessel> allVesselList1 = Lists.newArrayList();
184
185
186 switch (vesselType) {
187 case FISHING:
188 gearPredicate = Gears.IS_FISHING_GEAR;
189 allVesselList1.addAll(getDataContext().getFishingVessels());
190 break;
191
192 case SCIENTIFIC:
193 gearPredicate = Gears.IS_SCIENTIFIC_GEAR;
194
195 allVesselList1.addAll(getDataContext().getScientificVessels());
196 break;
197 default: {
198 allVesselList1.addAll(getDataContext().getScientificVessels());
199 allVesselList1.addAll(getDataContext().getFishingVessels());
200 }
201 }
202
203 EditCruiseUIHandler.this.ui.getGearList().getHandler().clearFilters();
204 EditCruiseUIHandler.this.ui.getVesselComboBox().setData(null);
205 EditCruiseUIHandler.this.ui.getVesselComboBox().setData(allVesselList1);
206
207 if (gearPredicate != null) {
208 EditCruiseUIHandler.this.ui.getGearList().getHandler().addFilter(gearPredicate);
209 }
210
211 });
212
213 initBeanFilterableComboBox(this.ui.getProgramComboBox(),
214 Lists.newArrayList(persistenceService.getAllProgram()),
215 model.getProgram(),
216 DecoratorService.ONLY_NAME);
217
218 initBeanFilterableComboBox(this.ui.getDepartureLocationComboBox(),
219 Lists.newArrayList(persistenceService.getAllHarbour()),
220 model.getDepartureLocation());
221
222 initBeanFilterableComboBox(this.ui.getReturnLocationComboBox(),
223 Lists.newArrayList(persistenceService.getAllHarbour()),
224 model.getReturnLocation());
225
226 initBeanFilterableComboBox(this.ui.getVesselComboBox(),
227 allVesselList,
228 model.getVessel());
229
230 this.ui.getGearList().setModel(new BeanDoubleListModel<Gear>() {
231
232 private static final long serialVersionUID = 1L;
233
234 private boolean valueAdjusting;
235
236 @Override
237 public void moveUpSelected(Gear item) {
238 super.moveUpSelected(item);
239 rebuildRankOrder();
240 }
241
242 @Override
243 public void moveDownSelected(Gear item) {
244 super.moveDownSelected(item);
245 rebuildRankOrder();
246 }
247
248 @Override
249 public void setSelected(List<Gear> selected) {
250 valueAdjusting = true;
251 try {
252 super.setSelected(selected);
253 } finally {
254 valueAdjusting = false;
255 }
256 rebuildRankOrder();
257 }
258
259 @Override
260 public void addToSelected(Gear item) {
261
262
263 GearWithOriginalRankOrder target =
264 GearWithOriginalRankOrders.newGearWithOriginalRankOrder(item);
265
266 Short originalRankOrder = null;
267
268 if (item instanceof GearWithOriginalRankOrder) {
269
270 originalRankOrder = ((GearWithOriginalRankOrder) item).getOriginalRankOrder();
271 }
272 if (originalRankOrder == null) {
273 originalRankOrder = 0;
274 }
275 target.setOriginalRankOrder(originalRankOrder);
276 super.addToSelected(target);
277 rebuildRankOrder();
278 }
279
280 @Override
281 public void addToSelected(List<Gear> items) {
282 valueAdjusting = true;
283 try {
284 for (Gear item : items) {
285 addToSelected(item);
286 }
287 } finally {
288 valueAdjusting = false;
289 }
290 rebuildRankOrder();
291 }
292
293 @Override
294 public void removeFromSelected(Gear item) {
295 super.removeFromSelected(item);
296 rebuildRankOrder();
297 }
298
299 @Override
300 public void removeFromSelected(List<Gear> items) {
301 valueAdjusting = true;
302 try {
303 for (Gear item : items) {
304 removeFromSelected(item);
305 }
306 } finally {
307 valueAdjusting = false;
308 }
309 rebuildRankOrder();
310 }
311
312 protected void rebuildRankOrder() {
313 if (!valueAdjusting) {
314 int index = 1;
315 for (Gear gear : getSelected()) {
316 gear.setRankOrder((short) (index++));
317 }
318 }
319 selectedModel.refresh();
320 }
321 });
322 initBeanList(this.ui.getGearList(),
323 allGearList,
324 (List) model.getGear(),
325 getDecorator(Gear.class, DecoratorService.GEAR_WITH_RANK_ORDER));
326
327
328 gearPopupMenu = this.ui.getGearList().getSelectedList().getComponentPopupMenu();
329 this.ui.getGearList().getSelectedList().setComponentPopupMenu(null);
330
331 gearPopupMenu.add(new JSeparator(), 0);
332 gearPopupMenu.add(this.ui.getViewGearCaracteristicsItem(), 0);
333 gearPopupMenu.add(this.ui.getEditGearCaracteristicsItem(), 0);
334
335 initBeanList(this.ui.getHeadOfMissionList(),
336 users,
337 model.getHeadOfMission());
338
339 initBeanList(this.ui.getHeadOfSortRoomList(),
340 users,
341 model.getHeadOfSortRoom());
342
343 this.ui.getGearList().getSelectedList().addMouseListener(new MouseAdapter() {
344 @Override
345 public void mouseClicked(MouseEvent e) {
346
347 if (SwingUtilities.isRightMouseButton(e)) {
348 JList jList = (JList) e.getSource();
349 Point point = e.getPoint();
350 int selectedIndex = jList.locationToIndex(point);
351 Rectangle rect = jList.getCellBounds(selectedIndex, selectedIndex);
352 if (rect.contains(point)) {
353 jList.setSelectedIndex(selectedIndex);
354 } else {
355 jList.clearSelection();
356 }
357
358 GearWithOriginalRankOrder gear = (GearWithOriginalRankOrder) jList.getSelectedValue();
359 updateGearActionsAndShowPoup(gear, jList, e.getX(), e.getY());
360
361 }
362 }
363 });
364
365 this.ui.getGearList().getSelectedList().addKeyListener(new KeyAdapter() {
366 @Override
367 public void keyPressed(KeyEvent e) {
368 if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) {
369
370 JList source = (JList) e.getSource();
371
372
373 int[] selectedRows = source.getSelectedIndices();
374 int lowestRow = -1;
375 for (int row : selectedRows) {
376 lowestRow = Math.max(lowestRow, row);
377 }
378 Rectangle r = source.getCellBounds(lowestRow, lowestRow);
379
380
381 Point p = new Point(r.x + r.width / 2, r.y + r.height);
382
383 Object[] gears = source.getSelectedValues();
384 GearWithOriginalRankOrder gear = gears != null && gears.length == 1 ? (GearWithOriginalRankOrder) gears[0] : null;
385 updateGearActionsAndShowPoup(gear, source, p.x, p.y);
386 }
387 }
388 });
389
390 SwingValidator validator = this.ui.getValidator();
391 changeValidatorContext(model.getValidationContext(), ui.getValidator());
392
393 listenValidatorValid(validator, model);
394
395 model.setVesselType(VesselTypeEnum.SCIENTIFIC);
396
397
398 model.setModify(model.isCreate());
399
400 registerValidators(validator);
401
402
403 JAXXUtil.applyDataBinding(ui, EditCruiseUI.BINDING_RESET_BUTTON_ENABLED);
404 }
405
406 @Override
407 protected JComponent getComponentToFocus() {
408 return getUI().getProgramComboBox();
409 }
410
411 @Override
412 protected Set<String> getPropertiesToIgnore() {
413 Set<String> result = super.getPropertiesToIgnore();
414 result.add(EditCruiseUIModel.PROPERTY_ATTACHMENT);
415 result.add(EditCruiseUIModel.PROPERTY_VESSEL_TYPE);
416 result.add(EditCruiseUIModel.PROPERTY_VESSEL_TYPE_ALL);
417 result.add(EditCruiseUIModel.PROPERTY_VESSEL_TYPE_SCIENTIFIC);
418 result.add(EditCruiseUIModel.PROPERTY_VESSEL_TYPE_FISHING);
419 result.add(EditCruiseUIModel.PROPERTY_CAN_EDIT_GEAR_CARACTERISTIC);
420 result.add(EditCruiseUIModel.PROPERTY_CAN_SHOW_GEAR_CARACTERISTIC);
421 return result;
422 }
423
424 @Override
425 public void onCloseUI() {
426 if (log.isDebugEnabled()) {
427 log.debug("closing: " + ui);
428 }
429 clearValidators();
430
431 ui.getAttachmentsButton().onCloseUI();
432 }
433
434 @Override
435 public boolean quitUI() {
436 return quitScreen(
437 getModel().isValid(),
438 getModel().isModify(),
439 t("tutti.editCruise.askCancelEditBeforeLeaving.cancelSaveCruise"),
440 t("tutti.editCruise.askSaveBeforeLeaving.saveCruise"),
441 ui.getSaveButton().getAction()
442 );
443 }
444
445 @Override
446 public SwingValidator<EditCruiseUIModel> getValidator() {
447 return ui.getValidator();
448 }
449
450
451
452
453
454
455
456
457 public static final JAXXContextEntryDef<GearWithOriginalRankOrder> GEAR_EDIT_CONTEXT =
458 JAXXUtil.newContextEntryDef("editGear", GearWithOriginalRankOrder.class);
459
460 protected void updateGearActionsAndShowPoup(GearWithOriginalRankOrder gear,
461 JComponent source,
462 int x,
463 int y) {
464 boolean editMenuEnabled = false;
465 boolean viewMenuEnabled = false;
466 if (gear != null) {
467 editMenuEnabled = !getModel().isCreate() &&
468 !getModel().isModify() &&
469 (!gear.isScientificGear() ||
470 Gears.isTemporary(gear));
471 viewMenuEnabled = true;
472 GEAR_EDIT_CONTEXT.setContextValue(ui, gear);
473 }
474 getModel().setCanEditGearCatacteristic(editMenuEnabled);
475 getModel().setCanShowGearCatacteristic(viewMenuEnabled);
476
477 gearPopupMenu.show(source, x, y);
478 }
479
480 public void reloadCruise(Cruise cruise) {
481
482 EditCruiseUIModel model = getModel();
483
484 model.fromEntity(cruise);
485
486 if (!model.isGearEmpty()) {
487
488
489 for (GearWithOriginalRankOrder gear : model.getGear()) {
490
491
492 gear.setOriginalRankOrder(gear.getRankOrder());
493 }
494 }
495
496
497 List<Attachment> attachments = getPersistenceService().getAllAttachments(
498 model.getObjectType(), model.getObjectId());
499 model.addAllAttachment(attachments);
500
501 ui.getHeadOfMissionList().getModel().setSelected(model.getHeadOfMission());
502 ui.getHeadOfSortRoomList().getModel().setSelected(model.getHeadOfSortRoom());
503 ui.getGearList().getModel().setSelected((List) model.getGear());
504
505 getModel().setModify(false);
506
507 }
508 }