View Javadoc
1   package fr.ifremer.tutti.ui.swing.content.config;
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 fr.ifremer.tutti.TuttiConfiguration;
26  import fr.ifremer.tutti.TuttiConfigurationOption;
27  import fr.ifremer.tutti.type.WeightUnit;
28  import fr.ifremer.tutti.ui.swing.TuttiUIContext;
29  import fr.ifremer.tutti.ui.swing.content.actions.GoToPreviousScreenAction;
30  import fr.ifremer.tutti.ui.swing.content.config.actions.ReloadTuttiAction;
31  import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler;
32  import fr.ifremer.tutti.ui.swing.util.editor.TuttiLocationTableCell;
33  import fr.ifremer.tutti.ui.swing.util.editor.VesselTableCell;
34  import jaxx.runtime.SwingUtil;
35  import jaxx.runtime.swing.config.ConfigCategoryUI;
36  import jaxx.runtime.swing.config.ConfigUI;
37  import jaxx.runtime.swing.config.ConfigUIHelper;
38  import jaxx.runtime.swing.config.model.MainCallBackFinalizer;
39  import jaxx.runtime.swing.editor.EnumEditor;
40  import jaxx.runtime.validator.swing.SwingValidator;
41  import org.apache.commons.logging.Log;
42  import org.apache.commons.logging.LogFactory;
43  import org.jdesktop.swingx.JXTable;
44  
45  import javax.swing.DefaultCellEditor;
46  import javax.swing.DefaultListCellRenderer;
47  import javax.swing.JComboBox;
48  import javax.swing.JComponent;
49  import javax.swing.JList;
50  import javax.swing.JTable;
51  import javax.swing.ListCellRenderer;
52  import javax.swing.table.DefaultTableCellRenderer;
53  import javax.swing.table.TableCellEditor;
54  import java.awt.BorderLayout;
55  import java.awt.Component;
56  import java.util.Objects;
57  
58  import static org.nuiton.i18n.I18n.n;
59  import static org.nuiton.i18n.I18n.t;
60  
61  /**
62   * @author Tony Chemit - chemit@codelutin.com
63   * @since 1.1
64   */
65  public class TuttiConfigUIHandler extends AbstractTuttiUIHandler<TuttiUIContext, TuttiConfigUI> {
66  
67      /** Logger. */
68      private static final Log log =
69              LogFactory.getLog(TuttiConfigUIHandler.class);
70  
71  
72      public static final String CALLBACK_APPLICATION = "application";
73  
74      public static final String CALLBACK_UI = "ui";
75  
76      public static final String CALLBACK_SHORTCUT = "shortcut";
77  
78      @Override
79      public SwingValidator<TuttiUIContext> getValidator() {
80          return null;
81      }
82  
83      @Override
84      public void afterInit(TuttiConfigUI ui) {
85  
86          initUI(ui);
87  
88          TuttiConfiguration config = getConfig();
89  
90          ConfigUIHelper helper = new ConfigUIHelper(config.getApplicationConfig(),
91                                                     config.getConfigFile());
92  
93          helper.registerCallBack(
94                  CALLBACK_UI, n("tutti.config.action.reload.ui"),
95                  SwingUtil.createActionIcon("reload-ui"),
96                  this::reloadUI
97          ).registerCallBack(
98                  CALLBACK_APPLICATION, n("tutti.config.action.reload.application"),
99                  SwingUtil.createActionIcon("reload-application"),
100                 this::reloadApplication
101         ).registerCallBack(
102                 CALLBACK_SHORTCUT, n("tutti.config.action.reload.actions"),
103                 SwingUtil.createActionIcon("reload-shortcut"),
104                 this::reloadShortcuts
105         );
106 
107         TableCellEditor stringDefaultEditor = new JXTable().getDefaultEditor(String.class);
108 
109         // Application category
110 
111         helper.addCategory(n("tutti.config.category.applications"),
112                            n("tutti.config.category.applications.description"))
113               .addOption(TuttiConfigurationOption.CSV_SEPARATOR)
114               .setOptionShortLabel(t("tutti.config.option.csv.separator.shortLabel"))
115 
116               .addOption(TuttiConfigurationOption.UI_CONFIG_FILE)
117               .setOptionShortLabel(t("tutti.config.option.ui.config.file.shortLabel"))
118               .setOptionCallBack(CALLBACK_APPLICATION)
119 
120               .addOption(TuttiConfigurationOption.TOTAL_SORTED_WEIGHTS_DIFFERENCE_RATE)
121               .setOptionShortLabel(t("tutti.config.option.weights.rate.difference.totalAndSorted.shortLabel"))
122 
123               .addOption(TuttiConfigurationOption.RTP_WEIGHTS_DIFFERENCE_RATE)
124               .setOptionShortLabel(t("tutti.config.option.weights.rate.difference.rtp.shortLabel"))
125 
126               .addOption(TuttiConfigurationOption.MAX_INDIVIDUAL_OBSERVATION_ROW_TO_CREATE)
127               .setOptionShortLabel(t("tutti.config.option.ui.individualObservationRowsToCreate.shortLabel"))
128 
129               .addOption(TuttiConfigurationOption.SAMPLING_CODE_PREFIX)
130               .setOptionShortLabel(t("tutti.config.option.ui.samplingCodePrefix.shortLabel"))
131               .setOptionEditor(stringDefaultEditor) // On force ici le type car les éditeurs de navire et pays sont aussi de type String...
132 
133               .addOption(TuttiConfigurationOption.SHOW_BATCH_LOG)
134               .setOptionShortLabel(t("tutti.config.option.ui.showBatchLog.shortLabel"))
135 
136               .addOption(TuttiConfigurationOption.SHOW_MEMORY_USAGE)
137               .setOptionShortLabel(t("tutti.config.option.ui.showMemoryUsage.shortLabel"))
138               .setOptionCallBack(CALLBACK_UI)
139 
140               .addOption(TuttiConfigurationOption.GENERIC_FORMAT_IMPORT_SKIP_BACKUP)
141               .setOptionShortLabel(t("tutti.config.option.ui.genericFormat.import.skipBackup.shortLabel"))
142 
143               .addOption(TuttiConfigurationOption.GENERIC_FORMAT_IMPORT_MAXIMUM_ROWS_IN_ERROR_PER_FILE)
144               .setOptionShortLabel(t("tutti.config.option.ui.genericFormat.import.maximumRowsInErrorPerFile.shortLabel"))
145 
146               .addOption(TuttiConfigurationOption.IMPORT_DB_SKIP_BACKUP)
147               .setOptionShortLabel(t("tutti.config.option.ui.db.import.skipBackup.shortLabel"))
148 
149               .addOption(TuttiConfigurationOption.PUPITRI_IMPORT_MISSING_BATCHES)
150               .setOptionShortLabel(t("tutti.config.option.pupitriImportMissingBatches.shortLabel"));
151 
152 
153         TuttiUIContext context = getContext();
154 
155         if (context.isDbLoaded()) {
156 
157             VesselTableCell vesselTableCellComponent = new VesselTableCell(context);
158             helper.addOption(TuttiConfigurationOption.TREMIE_CAROUSSEL_VESSEL_ID)
159                   .setOptionShortLabel(t("tutti.config.option.tremieCarousselVessel.shortLabel"))
160                   .setOptionEditor(vesselTableCellComponent.getNewTableCellEditor())
161                   .setOptionRenderer(vesselTableCellComponent.getNewTableCellRenderer());
162 
163             TuttiLocationTableCell tuttiLocationTableCellComponent = new TuttiLocationTableCell(context);
164             helper.addOption(TuttiConfigurationOption.EXPORT_COUNTRY_ID)
165                   .setOptionShortLabel(t("tutti.config.option.export.countryId.shortLabel"))
166                   .setOptionEditor(tuttiLocationTableCellComponent.getNewTableCellEditor())
167                   .setOptionRenderer(tuttiLocationTableCellComponent.getNewTableCellRenderer());
168         }
169 
170         // UI category
171 
172         helper.addCategory(n("tutti.config.category.ui"),
173                            n("tutti.config.category.ui.description"),
174                            CALLBACK_UI)
175               .addOption(TuttiConfigurationOption.COLOR_ALTERNATE_ROW)
176               .setOptionShortLabel(t("tutti.config.option.ui.color.alternateRow.shortLabel"))
177 
178               .addOption(TuttiConfigurationOption.COLOR_SELECTED_ROW)
179               .setOptionShortLabel(t("tutti.config.option.ui.color.selectedRow.shortLabel"))
180 
181               .addOption(TuttiConfigurationOption.COLOR_ROW_INVALID)
182               .setOptionShortLabel(t("tutti.config.option.ui.color.rowInvalid.shortLabel"))
183 
184               .addOption(TuttiConfigurationOption.COLOR_ROW_READ_ONLY)
185               .setOptionShortLabel(t("tutti.config.option.ui.color.rowReadOnly.shortLabel"))
186 
187               .addOption(TuttiConfigurationOption.COLOR_CELL_WITH_VALUE)
188               .setOptionShortLabel(t("tutti.config.option.ui.color.cellWithValue.shortLabel"))
189 
190               .addOption(TuttiConfigurationOption.COLOR_ROW_TO_CONFIRM)
191               .setOptionShortLabel(t("tutti.config.option.ui.color.rowToConfirm.shortLabel"))
192 
193               .addOption(TuttiConfigurationOption.COLOR_WARNING_ROW)
194               .setOptionShortLabel(t("tutti.config.option.ui.color.rowInWarning.shortLabel"))
195 
196               .addOption(TuttiConfigurationOption.COLOR_COMPUTED_WEIGHTS)
197               .setOptionShortLabel(t("tutti.config.option.ui.color.computedWeights.shortLabel"))
198 
199               .addOption(TuttiConfigurationOption.COLOR_BLOCKING_LAYER)
200               .setOptionShortLabel(t("tutti.config.option.ui.color.blockingLayer.shortLabel"))
201 
202               .addOption(TuttiConfigurationOption.COLOR_CATCH)
203               .setOptionShortLabel(t("tutti.config.option.ui.color.catch.shortLabel"))
204 
205               .addOption(TuttiConfigurationOption.COLOR_SPECIES)
206               .setOptionShortLabel(t("tutti.config.option.ui.color.species.shortLabel"))
207 
208               .addOption(TuttiConfigurationOption.COLOR_BENTHOS)
209               .setOptionShortLabel(t("tutti.config.option.ui.color.benthos.shortLabel"))
210 
211               .addOption(TuttiConfigurationOption.COLOR_SPECIES_OR_BENTHOS_UNSORTED_COMPUTED_WEIGHT_IN_WARNING)
212               .setOptionShortLabel(t("tutti.config.option.ui.color.speciesOrBenthosUnsortedComputedWeightInWarning.shortLabel"))
213 
214               .addOption(TuttiConfigurationOption.COLOR_MARINE_LITTER)
215               .setOptionShortLabel(t("tutti.config.option.ui.color.marineLitter.shortLabel"))
216 
217               .addOption(TuttiConfigurationOption.COLOR_HIGHLIGHT_INFO_BACKGROUND)
218               .setOptionShortLabel(t("tutti.config.option.ui.color.hightlightInfo.background.shortLabel"))
219 
220               .addOption(TuttiConfigurationOption.COLOR_HIGHLIGHT_INFO_FOREGROUND)
221               .setOptionShortLabel(t("tutti.config.option.ui.color.hightlightInfo.foreground.shortLabel"))
222 
223               .addOption(TuttiConfigurationOption.DATE_FORMAT)
224               .setOptionShortLabel(t("tutti.config.option.ui.dateFormat.shortLabel"))
225 
226               .addOption(TuttiConfigurationOption.COORDINATE_EDITOR_TYPE)
227               .setOptionShortLabel(t("tutti.config.option.ui.coordinateEditorType.shortLabel"));
228 
229         // Weight Unit category
230 
231         WeightUnitTableCellRenderer weightUnitTableCellRenderer = new WeightUnitTableCellRenderer();
232 
233         JComboBox<WeightUnit> weightUnitEnumEditor = EnumEditor.newEditor(WeightUnit.class);
234         weightUnitEnumEditor.setRenderer(new WeightUnitListCellRenderer());
235         DefaultCellEditor weightUnitTableCellEditor = new DefaultCellEditor(weightUnitEnumEditor);
236         helper.addCategory(n("tutti.config.category.weightUnit"),
237                            n("tutti.config.category.weightUnit.description"),
238                            CALLBACK_UI)
239               .addOption(TuttiConfigurationOption.WEIGHT_UNIT_SPECIES)
240               .setOptionShortLabel(t("tutti.config.option.weight.unit.species.shortLabel"))
241               .setOptionRenderer(weightUnitTableCellRenderer)
242               .setOptionEditor(weightUnitTableCellEditor)
243 
244               .addOption(TuttiConfigurationOption.WEIGHT_UNIT_BENTHOS)
245               .setOptionShortLabel(t("tutti.config.option.weight.unit.benthos.shortLabel"))
246               .setOptionRenderer(weightUnitTableCellRenderer)
247               .setOptionEditor(weightUnitTableCellEditor)
248 
249               .addOption(TuttiConfigurationOption.WEIGHT_UNIT_MARINE_LITTER)
250               .setOptionShortLabel(t("tutti.config.option.weight.unit.marineLitter.shortLabel"))
251               .setOptionRenderer(weightUnitTableCellRenderer)
252               .setOptionEditor(weightUnitTableCellEditor)
253 
254               .addOption(TuttiConfigurationOption.WEIGHT_UNIT_INDIVIDUAL_OBSERVATION)
255               .setOptionShortLabel(t("tutti.config.option.weight.unit.individualObservation.shortLabel"))
256               .setOptionRenderer(weightUnitTableCellRenderer)
257               .setOptionEditor(weightUnitTableCellEditor)
258 
259               .addOption(TuttiConfigurationOption.WEIGHT_UNIT_ACCIDENTAL_CATCH)
260               .setOptionShortLabel(t("tutti.config.option.weight.unit.accidentalCatch.shortLabel"))
261               .setOptionRenderer(weightUnitTableCellRenderer)
262               .setOptionEditor(weightUnitTableCellEditor);
263 
264 
265         // external devices category
266 
267         helper.addCategory(n("tutti.config.category.externalDevices"),
268                            n("tutti.config.category.externalDevices.description"))
269 
270               // ichtyometer
271 
272               .addOption(TuttiConfigurationOption.FULL_BLUETOOTH_SCAN)
273               .setOptionShortLabel(t("tutti.config.option.ui.fullBluetoothScan.shortLabel"))
274 
275               .addOption(TuttiConfigurationOption.ICHTYOMETER_MAXIMUM_NUMBER_OF_ATTEMPT_TO_CONNECT)
276               .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerMaximumNumberOfAttemptToConnect.shortLabel"))
277 
278               // caliper
279 
280               .addOption(TuttiConfigurationOption.CALIPER_SERIAL_PORT)
281               .setOptionShortLabel(t("tutti.config.option.ui.caliperSerialPort.shortLabel"))
282 
283               // all devices
284 
285               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_VOICE_ENABLED)
286               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesVoiceEnabled.shortLabel"))
287 
288               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_READS_UNIT)
289               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesReadsUnit.shortLabel"))
290 
291               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_ENABLED)
292               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesDataBeepEnabled.shortLabel"))
293 
294               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_FREQUENCY)
295               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesDataBeepFrequency.shortLabel"))
296 
297               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_ENABLED)
298               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesErrorBeepEnabled.shortLabel"))
299 
300               .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_FREQUENCY)
301               .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesErrorBeepFrequency.shortLabel"));
302 
303         // Technical category
304 
305         helper.addCategory(n("tutti.config.category.technical"),
306                            n("tutti.config.category.technical.description"))
307               .addOption(TuttiConfigurationOption.BASEDIR)
308               .setOptionShortLabel(t("tutti.config.option.basedir.shortLabel"))
309 
310               .addOption(TuttiConfigurationOption.DATA_DIRECTORY)
311               .setOptionShortLabel(t("tutti.config.option.data.directory.shortLabel"))
312 
313               .addOption(TuttiConfigurationOption.TMP_DIRECTORY)
314               .setOptionShortLabel(t("tutti.config.option.tmp.directory.shortLabel"))
315 
316               .addOption(TuttiConfigurationOption.I18N_DIRECTORY)
317               .setOptionShortLabel(t("tutti.config.option.i18n.directory.shortLabel"))
318 
319               .addOption(TuttiConfigurationOption.HELP_DIRECTORY)
320               .setOptionShortLabel(t("tutti.config.option.help.directory.shortLabel"))
321 
322               .addOption(TuttiConfigurationOption.REPORT_DIRECTORY)
323               .setOptionShortLabel(t("tutti.config.option.service.report.directory.shortLabel"))
324 
325               .addOption(TuttiConfigurationOption.REPORT_LOG_DIRECTORY)
326               .setOptionShortLabel(t("tutti.config.option.service.report.log.directory.shortLabel"))
327 
328               .addOption(TuttiConfigurationOption.DB_DIRECTORY)
329               .setOptionShortLabel(t("tutti.config.option.persistence.db.directory.shortLabel"))
330 
331               .addOption(TuttiConfigurationOption.DB_ATTACHMENT_DIRECTORY)
332               .setOptionShortLabel(t("tutti.config.option.persistence.db.attachment.directory.shortLabel"))
333 
334               .addOption(TuttiConfigurationOption.DB_PROTOCOL_DIRECTORY)
335               .setOptionShortLabel(t("tutti.config.option.persistence.db.protocol.directory.shortLabel"))
336 
337               .addOption(TuttiConfigurationOption.DB_CACHE_DIRECTORY)
338               .setOptionShortLabel(t("tutti.config.option.persistence.db.cache.directory.shortLabel"))
339 
340               .addOption(TuttiConfigurationOption.JDBC_URL)
341               .setOptionShortLabel(t("tutti.config.option.persistence.jdbc.url.shortLabel"))
342 
343               .addOption(TuttiConfigurationOption.SITE_URL)
344               .setOptionShortLabel(t("tutti.config.option.site.url.shortLabel"))
345 
346               .addOption(TuttiConfigurationOption.DB_BACKUP_DIRECTORY)
347               .setOptionShortLabel(t("tutti.config.option.persistence.db.backup.directory.shortLabel"))
348 
349               .addOption(TuttiConfigurationOption.REPORT_BACKUP_DIRECTORY)
350               .setOptionShortLabel(t("tutti.config.option.service.report.backup.directory.shortLabel"))
351 
352               .addOption(TuttiConfigurationOption.EXPORT_BACKUP_DIRECTORY)
353               .setOptionShortLabel(t("tutti.config.option.service.export.backup.directory.shortLabel"))
354 
355               .addOption(TuttiConfigurationOption.GENERIC_FORMAT_REPORT_BACKUP_DIRECTORY)
356               .setOptionShortLabel(t("tutti.config.option.service.genericFormat.export.backup.directory.shortLabel"))
357 
358               .addOption(TuttiConfigurationOption.UPDATE_APPLICATION_URL)
359               .setOptionShortLabel(t("tutti.config.option.update.application.url.shortLabel"))
360 
361               .addOption(TuttiConfigurationOption.UPDATE_DATA_URL)
362               .setOptionShortLabel(t("tutti.config.option.update.data.url.shortLabel"));
363 
364         helper.setFinalizer(new MainCallBackFinalizer(CALLBACK_APPLICATION));
365 
366         helper.setCloseAction(() -> getContext().getActionEngine().runInternalAction(TuttiConfigUIHandler.this, GoToPreviousScreenAction.class));
367         ConfigUI configUI = helper.buildUI(getUI(), n("tutti.config.category.applications"));
368 
369         configUI.getHandler().setTopContainer(getUI());
370 
371         // Forbids to sort rows in categories ui table
372         // See https://forge.codelutin.com/issues/6947
373         // FIXME Move this in jaxx helper
374         int tabCount = configUI.getCategories().getTabCount();
375         for (int i = 0; i < tabCount; i++) {
376 
377             ConfigCategoryUI configCategoryUI = (ConfigCategoryUI) configUI.getCategories().getComponentAt(i);
378             JXTable table = configCategoryUI.getTable();
379             table.setRowSorter(null);
380 
381             //FIXME tc ceci pour pouvoir éditer des int à déplacer dans jaxx
382             TableCellEditor defaultEditor = table.getDefaultEditor(Integer.class);
383             Objects.requireNonNull(defaultEditor);
384             table.setDefaultEditor(int.class, defaultEditor);
385 
386         }
387         getUI().add(configUI, BorderLayout.CENTER);
388     }
389 
390     @Override
391     protected JComponent getComponentToFocus() {
392         return getUI();
393     }
394 
395     @Override
396     public void onCloseUI() {
397         if (log.isDebugEnabled()) {
398             log.debug("closing: " + ui);
399         }
400     }
401 
402     protected void reloadApplication() {
403         ReloadTuttiAction action = getContext().getActionFactory().createLogicAction(this, ReloadTuttiAction.class);
404         getContext().getActionEngine().runAction(action);
405     }
406 
407     protected void reloadUI() {
408         getContext().getMainUI().getHandler().reloadUI();
409     }
410 
411     protected void reloadShortcuts() {
412         getContext().getMainUI().getHandler().reloadUI();
413     }
414 
415     private static class WeightUnitListCellRenderer implements ListCellRenderer<WeightUnit> {
416 
417         private final DefaultListCellRenderer delegate;
418 
419         private WeightUnitListCellRenderer() {
420             this.delegate = new DefaultListCellRenderer();
421         }
422 
423         @Override
424         public Component getListCellRendererComponent(JList<? extends WeightUnit> list, WeightUnit value, int index, boolean isSelected, boolean cellHasFocus) {
425 
426             Object value2 = value;
427             if (value != null) {
428                 value2 = value.getShortLabel();
429             }
430             return delegate.getListCellRendererComponent(list, value2, index, isSelected, cellHasFocus);
431         }
432     }
433 
434     private static class WeightUnitTableCellRenderer extends DefaultTableCellRenderer {
435 
436         private static final long serialVersionUID = 1L;
437 
438         @Override
439         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
440 
441             if (value != null) {
442 
443                 WeightUnit unit = (WeightUnit) value;
444                 value = unit.getShortLabel();
445             }
446             return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
447         }
448     }
449 
450 }