View Javadoc
1   package fr.ifremer.tutti.ui.swing.content;
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.base.Preconditions;
26  import fr.ifremer.tutti.caliper.feed.CaliperFeedReader;
27  import fr.ifremer.tutti.ichtyometer.feed.IchtyometerFeedReader;
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.protocol.TuttiProtocol;
31  import fr.ifremer.tutti.ui.swing.RunTutti;
32  import fr.ifremer.tutti.ui.swing.TuttiScreen;
33  import fr.ifremer.tutti.ui.swing.TuttiUIContext;
34  import fr.ifremer.tutti.ui.swing.content.category.EditSampleCategoryModelUI;
35  import fr.ifremer.tutti.ui.swing.content.config.TuttiConfigUI;
36  import fr.ifremer.tutti.ui.swing.content.cruise.EditCruiseUI;
37  import fr.ifremer.tutti.ui.swing.content.cruise.EditCruiseUIHandler;
38  import fr.ifremer.tutti.ui.swing.content.db.DbManagerUI;
39  import fr.ifremer.tutti.ui.swing.content.db.DbManagerUIHandler;
40  import fr.ifremer.tutti.ui.swing.content.genericformat.GenericFormatExportUI;
41  import fr.ifremer.tutti.ui.swing.content.genericformat.GenericFormatImportUI;
42  import fr.ifremer.tutti.ui.swing.content.home.SelectCruiseUI;
43  import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUI;
44  import fr.ifremer.tutti.ui.swing.content.program.EditProgramUI;
45  import fr.ifremer.tutti.ui.swing.content.program.EditProgramUIHandler;
46  import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUI;
47  import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIHandler;
48  import fr.ifremer.tutti.ui.swing.content.referential.ManageTemporaryReferentialUI;
49  import fr.ifremer.tutti.ui.swing.content.report.ReportUI;
50  import fr.ifremer.tutti.ui.swing.content.validation.ValidateCruiseUI;
51  import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler;
52  import fr.ifremer.tutti.ui.swing.util.RemoveablePropertyChangeListener;
53  import fr.ifremer.tutti.ui.swing.util.TuttiUI;
54  import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil;
55  import jaxx.runtime.JAXXBinding;
56  import jaxx.runtime.SwingUtil;
57  import jaxx.runtime.validator.swing.SwingValidator;
58  import org.apache.commons.logging.Log;
59  import org.apache.commons.logging.LogFactory;
60  import org.nuiton.jaxx.application.swing.action.ApplicationActionUI;
61  import org.nuiton.jaxx.application.swing.util.CloseableUI;
62  
63  import javax.swing.Icon;
64  import javax.swing.JButton;
65  import javax.swing.JComponent;
66  import javax.swing.JLabel;
67  import javax.swing.JToolBar;
68  import java.awt.Cursor;
69  import java.beans.PropertyChangeEvent;
70  import java.beans.PropertyChangeListener;
71  import java.beans.PropertyChangeListenerProxy;
72  import java.util.Locale;
73  
74  import static org.nuiton.i18n.I18n.t;
75  
76  /**
77   * @author Tony Chemit - chemit@codelutin.com
78   * @since 0.1
79   */
80  public class MainUIHandler extends AbstractTuttiUIHandler<TuttiUIContext, MainUI> {
81  
82      /** Logger. */
83      private static final Log log = LogFactory.getLog(MainUIHandler.class);
84  
85      protected JComponent currentBody;
86  
87      public void reloadDbManagerText() {
88  
89          TuttiUI<?, ?> body = (TuttiUI<?, ?>) currentBody;
90  
91          if (body != null && body.getHandler() instanceof DbManagerUIHandler) {
92              DbManagerUIHandler dbManagerUIHandler = (DbManagerUIHandler) body.getHandler();
93              dbManagerUIHandler.updateMessage();
94          }
95      }
96  
97      public String getIchtyometerStatusTip(boolean connected) {
98          String result;
99          if (connected) {
100             IchtyometerFeedReader ichtyometerReader = getModel().getIchtyometerReader();
101             result = t("tutti.ichtyometer.status.connected.tip", ichtyometerReader.getClientName());
102         } else {
103             result = t("tutti.ichtyometer.status.not.connected.tip");
104         }
105         return result;
106     }
107 
108     public String getCaliperStatusLabel(boolean connected) {
109         String result = null;
110         if (connected) {
111             CaliperFeedReader caliperReader = getModel().getCaliperReader();
112             result = caliperReader.getSerialPortName();
113         }
114         return result;
115     }
116 
117     public String getCaliperStatusTip(boolean connected) {
118         String result;
119         if (connected) {
120             CaliperFeedReader caliperReader = getModel().getCaliperReader();
121             result = t("tutti.caliper.status.connected.tip", caliperReader.getSerialPortName());
122         } else {
123             result = t("tutti.caliper.status.not.connected.tip");
124         }
125         return result;
126     }
127     //------------------------------------------------------------------------//
128     //-- AbstractTuttiUIHandler methods                                     --//
129     //------------------------------------------------------------------------//
130 
131     @Override
132     public void beforeInit(MainUI ui) {
133         super.beforeInit(ui);
134         TuttiUIContext context = getContext();
135         ui.setContextValue(context);
136         context.setMainUI(ui);
137         context.setActionUI(new ApplicationActionUI(ui, context));
138         context.addPropertyChangeListener(new RemoveablePropertyChangeListener() {
139             @Override
140             public void propertyChange(PropertyChangeEvent evt) {
141                 String propertyName = evt.getPropertyName();
142                 if (TuttiUIContext.PROPERTIES_TO_SAVE.contains(propertyName)) {
143 
144                     // reset cruise in case the listener which is supposed to reset
145                     // the cruise is called after this one (cf #2276)
146                     if (TuttiUIContext.PROPERTY_CRUISE_ID.equals(propertyName)) {
147                         getDataContext().resetCruise();
148                     }
149                     // reset protocol in case the listener which is supposed to reset
150                     // the protocol is called after this one (cf #2276)
151                     if (TuttiUIContext.PROPERTY_PROTOCOL_ID.equals(propertyName)) {
152                         getDataContext().resetProtocol();
153                     }
154                     // change the ui title
155                     changeTitle();
156 
157                 } else if (propertyName.equals(TuttiUIContext.PROPERTY_SCREEN)) {
158                     setScreen((TuttiScreen) evt.getNewValue());
159                 }
160             }
161         });
162         ui.setContextValue(ui, MainUI.class.getName());
163 
164         // ecoute des changements de l'état busy
165         context.addPropertyChangeListener(TuttiUIContext.PROPERTY_BUSY, new RemoveablePropertyChangeListener() {
166 
167             @Override
168             public void propertyChange(PropertyChangeEvent evt) {
169                 Boolean newvalue = (Boolean) evt.getNewValue();
170                 updateBusyState(newvalue != null && newvalue);
171             }
172         });
173 
174         // ecoute des changements de l'état busy
175         context.addPropertyChangeListener(TuttiUIContext.PROPERTY_HIDE_BODY, new RemoveablePropertyChangeListener() {
176 
177             @Override
178             public void propertyChange(PropertyChangeEvent evt) {
179                 Boolean newvalue = (Boolean) evt.getNewValue();
180                 if (getUI() != null && getUI().getBody() != null) {
181                     getUI().getBody().setVisible(newvalue != null && newvalue);
182                 }
183             }
184         });
185     }
186 
187     protected void updateBusyState(boolean busy) {
188         if (busy) {
189             // ui bloquee
190             if (log.isDebugEnabled()) {
191                 log.debug("block ui in busy mode");
192             }
193             ui.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
194         } else {
195             // ui debloquee
196             if (log.isDebugEnabled()) {
197                 log.debug("unblock ui in none busy mode");
198             }
199             ui.setCursor(Cursor.getDefaultCursor());
200         }
201     }
202 
203     @Override
204     public void afterInit(MainUI ui) {
205 
206         initUI(ui);
207 
208         // installation layer de blocage en mode busy
209         SwingUtil.setLayerUI(ui.getBody(), ui.getBusyBlockLayerUI());
210 
211         //FIXME-TC See why this binding is not setted ?
212         ui.applyDataBinding(MainUI.BINDING_MENU_CHANGE_LOCALE_FR_ENABLED);
213         ui.applyDataBinding(MainUI.BINDING_MENU_CHANGE_LOCALE_UK_ENABLED);
214 
215         // Init SwingSession
216         getContext().addInSwingSession(ui, false);
217 
218         changeTitle();
219 
220         JToolBar bar = ui.getBottomBar();
221         ui.getStatus().addWidget(bar, 0);
222     }
223 
224     @Override
225     protected JComponent getComponentToFocus() {
226         return currentBody;
227     }
228 
229     @Override
230     public void onCloseUI() {
231 
232         TuttiUIContext context = getContext();
233 
234         // remove any screen
235         context.setScreen(null);
236         context.removeMessageNotifier(this);
237 
238         // clean context
239 
240         PropertyChangeListener[] propertyChangeListeners =
241                 context.getPropertyChangeListeners();
242         for (PropertyChangeListener listener : propertyChangeListeners) {
243             if (listener instanceof PropertyChangeListenerProxy) {
244                 PropertyChangeListenerProxy proxy = (PropertyChangeListenerProxy) listener;
245                 listener = proxy.getListener();
246             }
247             if (listener instanceof RemoveablePropertyChangeListener) {
248                 if (log.isDebugEnabled()) {
249                     log.debug("Remove listener: " + listener);
250                 }
251                 context.removePropertyChangeListener(listener);
252             }
253         }
254 
255         if (ui != null) {
256 
257             // clean ui
258 
259             JAXXBinding[] bindings = ui.getDataBindings();
260             for (JAXXBinding binding : bindings) {
261                 SwingUtil.removeDataBinding(ui, binding.getId());
262             }
263             ui.setVisible(false);
264             ui.dispose();
265         }
266 
267     }
268 
269     @Override
270     public SwingValidator<TuttiUIContext> getValidator() {
271         return null;
272     }
273 
274     //------------------------------------------------------------------------//
275     //-- Public methods                                                     --//
276     //------------------------------------------------------------------------//
277 
278     public void reloadUI() {
279 
280         //close ui
281         onCloseUI();
282 
283         // restart ui
284         RunTutti.startTutti(getContext(), false);
285     }
286 
287     public boolean acceptLocale(Locale l, String expected) {
288         return l != null && l.toString().equals(expected);
289     }
290 
291 //    public void changeLocale(Locale locale) {
292 //
293 //        // change locale (and save configuration)
294 //        getModel().setLocale(locale);
295 //
296 //        // change i18n locale
297 //        I18n.setDefaultLocale(getConfig().getI18nLocale());
298 //
299 //        // reload decorator service (TODO Check if this is necessary)
300 //        getContext().reloadDecoratorService();
301 //
302 //        // close reload
303 //        reloadUI();
304 //    }
305 
306 //    public void gotoSite() {
307 //        TuttiConfiguration config = getConfig();
308 //
309 //        URL siteURL = config.getSiteUrl();
310 //
311 //        if (log.isDebugEnabled()) {
312 //            log.debug("goto " + siteURL);
313 //        }
314 //        TuttiUIUtil.openLink(siteURL);
315 //    }
316 
317 //    public void showHelp() {
318 //        getModel().showHelp(ui, ui.getBroker(), null);
319 //    }
320 
321     @Override
322     public final void showInformationMessage(String message) {
323         ui.getStatus().setStatus("<html><body>" + message + "</body></html>");
324     }
325 
326     public void registerValidator(SwingValidator validator) {
327         if (log.isInfoEnabled()) {
328             log.info("Register validator: " + validator.getType() + " - " + validator.getContext() + " (" + validator + ")");
329         }
330         ui.getValidatorMessageWidget().registerValidator(validator);
331     }
332 
333     @Override
334     public void clearValidators() {
335         if (log.isInfoEnabled()) {
336             log.info("Clean all registred validators.");
337         }
338         ui.getValidatorMessageWidget().clearValidators();
339     }
340 
341     public boolean quitCurrentScreen() {
342 
343         boolean canClose;
344         if (getContext().getScreen() == null || currentBody == null) {
345 
346             // no screen, surely can quit
347             canClose = true;
348             if (log.isWarnEnabled()) {
349                 log.warn("==================================================");
350                 log.warn("No screen, Should then skipCheckCurrent in action.");
351                 log.warn("==================================================");
352             }
353         } else {
354             TuttiUI<?, ?> body = (TuttiUI<?, ?>) currentBody;
355             Preconditions.checkNotNull(currentBody);
356             AbstractTuttiUIHandler<?, ?> handler = body.getHandler();
357             if (handler instanceof CloseableUI) {
358 
359                 // try to quit UI
360                 canClose = ((CloseableUI) handler).quitUI();
361             } else {
362 
363                 // can always close ui
364                 canClose = true;
365             }
366         }
367         return canClose;
368     }
369 
370     //------------------------------------------------------------------------//
371     //-- Internal methods                                                   --//
372     //------------------------------------------------------------------------//
373 
374     protected void setScreen(TuttiScreen screen) {
375 
376         TuttiUIContext context = getContext();
377 
378         // close current body (if any)
379         if (currentBody != null) {
380             TuttiUI<?, ?> body = (TuttiUI<?, ?>) currentBody;
381             body.getHandler().onCloseUI();
382 
383             context.saveSwingSession();
384 
385             ui.getBody().remove(currentBody);
386 
387             currentBody = null;
388         }
389 
390         if (screen != null) {
391 
392             // load new body
393 
394             JComponent screenUI;
395             JToolBar rightDecoration = null;
396             String screenTitle;
397 
398             Icon icon;
399             switch (screen) {
400                 case CONFIG:
401 
402                     screenUI = new TuttiConfigUI(ui);
403                     screenTitle = t("tutti.config.title");
404                     icon = ui.getMenuFileConfiguration().getIcon();
405                     break;
406 
407                 case EDIT_SAMPLE_CATEGORY_MODEL:
408 
409                     screenUI = new EditSampleCategoryModelUI(ui);
410                     screenTitle = t("tutti.editSampleCategoryModel.title");
411                     icon = ui.getMenuEditSampleCategoryModel().getIcon();
412                     break;
413                 default:
414                 case MANAGE_DB:
415 
416                     screenUI = new DbManagerUI(ui);
417                     screenTitle = t("tutti.dbMabager.title");
418                     icon = ui.getMenuFileManageDb().getIcon();
419                     break;
420 
421                 case SELECT_CRUISE:
422 
423                     screenUI = new SelectCruiseUI(ui);
424                     screenTitle = t("tutti.selectCruise.title");
425                     icon = ui.getMenuActionSelectCruise().getIcon();
426                     break;
427 
428                 case EDIT_PROGRAM:
429 
430                     screenTitle = EditProgramUIHandler.getTitle(
431                             context.isProgramFilled());
432 
433                     screenUI = new EditProgramUI(ui);
434                     icon = ui.getMenuActionEditProgram().getIcon();
435                     break;
436 
437                 case EDIT_CRUISE:
438 
439                     screenTitle = EditCruiseUIHandler.getTitle(
440                             context.isCruiseFilled());
441 
442                     screenUI = new EditCruiseUI(ui);
443                     rightDecoration = ((EditCruiseUI) screenUI).getTopToolBar();
444                     Cruise cruise = context.getDataContext().getCruise();
445                     icon = TuttiUIUtil.getCruiseIcon(cruise == null ? ((EditCruiseUI) screenUI).getModel() : cruise);
446                     break;
447 
448                 case EDIT_PROTOCOL:
449 
450                     screenTitle = EditProtocolUIHandler.getTitle(
451                             context.isProtocolFilled());
452 
453                     screenUI = new EditProtocolUI(ui);
454                     icon = ui.getMenuActionEditProtocol().getIcon();
455                     break;
456 
457                 case EDIT_FISHING_OPERATION:
458 
459                     screenTitle = t("tutti.fishingOperations.title.edit.operations", getSelectedCruiseTitle());
460                     icon = ui.getMenuActionEditCatches().getIcon();
461                     screenUI = new FishingOperationsUI(ui);
462 
463                     break;
464 
465                 case IMPORT_TEMPORARY_REFERENTIAL:
466 
467                     screenTitle = t("tutti.manageTemporaryReferential.title");
468                     screenUI = new ManageTemporaryReferentialUI(ui);
469                     icon = ui.getMenuImportTemporaryReferential().getIcon();
470                     break;
471 
472                 case VALIDATE_CRUISE:
473 
474                     screenUI = new ValidateCruiseUI(ui);
475                     screenTitle = t("tutti.fishingOperations.title.validate.operations", getSelectedCruiseTitle());
476                     icon = ui.getMenuActionValidateCatches().getIcon();
477                     break;
478 
479                 case REPORT:
480 
481                     screenUI = new ReportUI(ui);
482                     screenTitle = t("tutti.report.title");
483                     icon = ui.getMenuActionGenerateCruiseReport().getIcon();
484                     break;
485 
486                 case GENERIC_FORMAT_IMPORT:
487 
488                     screenUI = new GenericFormatImportUI(ui);
489                     screenTitle = t("tutti.genericFormatImport.title");
490                     icon = ui.getMenuActionGenericFormatImport().getIcon();
491                     break;
492 
493                 case GENERIC_FORMAT_EXPORT:
494 
495                     screenUI = new GenericFormatExportUI(ui);
496                     screenTitle = t("tutti.genericFormatExport.title");
497                     icon = ui.getMenuActionGenericFormatExport().getIcon();
498                     break;
499             }
500 
501             JButton showHelp = ui.getShowHelp();
502             if (rightDecoration == null) {
503                 rightDecoration = new JToolBar();
504                 rightDecoration.setFloatable(false);
505                 rightDecoration.setOpaque(false);
506                 rightDecoration.setBorderPainted(false);
507             } else {
508                 rightDecoration.remove(showHelp);
509             }
510             rightDecoration.add(showHelp, 0);
511             this.currentBody = screenUI;
512             context.addInSwingSession(currentBody, true);
513             ui.getBody().setTitle(screenTitle);
514             ui.getBody().add(currentBody);
515             ui.getBody().setLeftDecoration(new JLabel(icon));
516             ui.getBody().setRightDecoration(rightDecoration);
517             // Fix #2510: [AIDE] perte de l'aide contextuelle sur ecran campagne
518             //FIXME tchemit-2013-05-28 Find out why
519             ui.getBody().getRightDecoration().setVisible(true);
520 
521         }
522     }
523 
524     public void changeTitle() {
525 
526         String title = getSelectedCruiseTitle();
527 
528         ui.setTitle(t("tutti.main.title.application",
529                       getConfig().getVersion(),
530                       title));
531     }
532 
533     protected String getSelectedCruiseTitle() {
534 
535         TuttiUIContext context = getContext();
536 
537         String title;
538 
539         if (context.isDbLoaded()) {
540 
541             if (context.isProgramFilled()) {
542 
543                 // selected program
544 
545                 Program program = getDataContext().getProgram();
546 
547                 title = t("tutti.main.title.selectedProgram", program.getName()) + " / ";
548 
549                 if (context.isCruiseFilled()) {
550 
551                     // selected cruise
552                     Cruise cruise = getDataContext().getCruise();
553 
554                     if (cruise != null) {
555                         title += t("tutti.main.title.selectedCruise", cruise.getName());
556                     }
557                 } else {
558 
559                     // no selected cruise
560 
561                     title += t("tutti.main.title.noSelectedCruise");
562                 }
563 
564             } else {
565 
566                 // no program selected (so neither cruise)
567 
568                 title = t("tutti.main.title.noSelectedProgram");
569 
570             }
571 
572             title += " / ";
573 
574             if (context.isProtocolFilled()) {
575 
576                 // selected protocol
577                 TuttiProtocol protocol = getDataContext().getProtocol();
578 
579                 title += t("tutti.main.title.selectedProtocol", protocol.getName());
580             } else {
581 
582                 // no selected protocol
583 
584                 title += t("tutti.main.title.noSelectedProtocol");
585             }
586         } else {
587 
588             // no db loaded
589 
590             title = t("tutti.main.title.nodb");
591         }
592         return title;
593     }
594 
595     public void setBodyTitle(String title) {
596         ui.getBody().setTitle(title);
597     }
598 
599     public JComponent getCurrentBody() {
600         return currentBody;
601     }
602 }