001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.preferences;
020
021import java.awt.Dimension;
022import java.awt.GridBagConstraints;
023import java.awt.GridBagLayout;
024import java.awt.Insets;
025import java.awt.event.ActionEvent;
026import java.awt.event.ActionListener;
027import java.io.File;
028
029import javax.swing.JButton;
030import javax.swing.JCheckBox;
031import javax.swing.JFileChooser;
032import javax.swing.JLabel;
033import javax.swing.JPanel;
034import javax.swing.JSeparator;
035import javax.swing.JSpinner;
036import javax.swing.SpinnerNumberModel;
037
038import icy.gui.component.IcyTextField;
039import icy.gui.dialog.MessageDialog;
040import icy.math.MathUtil;
041import icy.preferences.ApplicationPreferences;
042import icy.preferences.GeneralPreferences;
043import icy.system.SystemUtil;
044import icy.util.StringUtil;
045
046/**
047 * @author stephane
048 */
049public class GeneralPreferencePanel extends PreferencePanel
050{
051    private static final long serialVersionUID = -5376356916415550024L;
052
053    public static final String NODE_NAME = "General";
054
055    /**
056     * gui
057     */
058    JCheckBox exitConfirm;
059    private JCheckBox sequencePersistence;
060    private JCheckBox saveNewSequence;
061    JCheckBox autoUpdateCheckBox;
062    private JCheckBox usageStatistics;
063    private JSpinner maxMemoryMBSpinner;
064    private JLabel maxMemoryMBLabel;
065    private JSpinner cacheMemoryPercent;
066    IcyTextField cachePath;
067    private JButton setCachePathButton;
068    private JButton reenableAllToolTipButton;
069    private JButton reenableAllConfirmButton;
070    private JSeparator separator;
071    private JLabel label;
072    private JPanel panel;
073
074    /**
075     * @param parent
076     */
077    GeneralPreferencePanel(PreferenceFrame parent)
078    {
079        super(parent, NODE_NAME, PreferenceFrame.NODE_NAME);
080
081        final int maxMemMB = (int) MathUtil.prevMultiple(ApplicationPreferences.getMaxMemoryMBLimit(), 32);
082
083        initializeGUI(maxMemMB);
084
085        String maxMemoryMess = " MB  (max = " + maxMemMB + " MB";
086        if (SystemUtil.is32bits() && ((SystemUtil.getTotalMemory() / (1024 * 1024)) >= 1500))
087            maxMemoryMess += " - use 64bit JVM to allow more)";
088        else
089            maxMemoryMess += ")";
090
091        reenableAllConfirmButton.addActionListener(new ActionListener()
092        {
093            @Override
094            public void actionPerformed(ActionEvent e)
095            {
096                // clear the saved tool tips preference to re-enable them
097                GeneralPreferences.getPreferencesConfirms().removeChildren();
098                GeneralPreferences.getPreferencesConfirms().clear();
099                exitConfirm.setSelected(true);
100
101                MessageDialog.showDialog("All confirmation dialogs are now enabled again !");
102            }
103        });
104
105        reenableAllToolTipButton.addActionListener(new ActionListener()
106        {
107            @Override
108            public void actionPerformed(ActionEvent e)
109            {
110                // clear the saved tool tips preference to re-enable them
111                GeneralPreferences.getPreferencesToolTips().removeChildren();
112                GeneralPreferences.getPreferencesToolTips().clear();
113
114                MessageDialog.showDialog("All tooltips are now enabled again !");
115            }
116        });
117        setCachePathButton.addActionListener(new ActionListener()
118        {
119            @Override
120            public void actionPerformed(ActionEvent e)
121            {
122                final JFileChooser fc = new JFileChooser();
123
124                // start at application current directory
125                fc.setCurrentDirectory(new File(cachePath.getText()));
126                fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
127
128                if (fc.showSaveDialog(GeneralPreferencePanel.this) == JFileChooser.APPROVE_OPTION)
129                    cachePath.setText(fc.getSelectedFile().getAbsolutePath());
130            }
131        });
132
133        load();
134    }
135
136    private void initializeGUI(int maxMemMB)
137    {
138        GridBagLayout gbl_mainPanel = new GridBagLayout();
139        gbl_mainPanel.columnWidths = new int[] {200, 0, 80, 0, 4, 0};
140        gbl_mainPanel.rowHeights = new int[] {0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 0};
141        gbl_mainPanel.columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
142        gbl_mainPanel.rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
143                Double.MIN_VALUE};
144        mainPanel.setLayout(gbl_mainPanel);
145
146        exitConfirm = new JCheckBox("Show confirmation when exiting application");
147        GridBagConstraints gbc_exitConfirm = new GridBagConstraints();
148        gbc_exitConfirm.anchor = GridBagConstraints.WEST;
149        gbc_exitConfirm.gridwidth = 4;
150        gbc_exitConfirm.insets = new Insets(0, 0, 5, 5);
151        gbc_exitConfirm.gridx = 0;
152        gbc_exitConfirm.gridy = 0;
153        mainPanel.add(exitConfirm, gbc_exitConfirm);
154        autoUpdateCheckBox = new JCheckBox("Enable application update");
155        GridBagConstraints gbc_autoUpdateCheckBox = new GridBagConstraints();
156        gbc_autoUpdateCheckBox.anchor = GridBagConstraints.WEST;
157        gbc_autoUpdateCheckBox.gridwidth = 4;
158        gbc_autoUpdateCheckBox.insets = new Insets(0, 0, 5, 5);
159        gbc_autoUpdateCheckBox.gridx = 0;
160        gbc_autoUpdateCheckBox.gridy = 1;
161        mainPanel.add(autoUpdateCheckBox, gbc_autoUpdateCheckBox);
162        autoUpdateCheckBox.setToolTipText("Enable automatic update for application as soon a new version is available");
163        sequencePersistence = new JCheckBox("Enable sequence persistence");
164        GridBagConstraints gbc_sequencePersistence = new GridBagConstraints();
165        gbc_sequencePersistence.anchor = GridBagConstraints.WEST;
166        gbc_sequencePersistence.gridwidth = 4;
167        gbc_sequencePersistence.insets = new Insets(0, 0, 5, 5);
168        gbc_sequencePersistence.gridx = 0;
169        gbc_sequencePersistence.gridy = 2;
170        mainPanel.add(sequencePersistence, gbc_sequencePersistence);
171        sequencePersistence.setToolTipText(
172                "Enable the XML persistence for sequence (file is automatically loaded/saved when sequence is opened/closed)");
173        saveNewSequence = new JCheckBox("Ask to save new sequence when closing them");
174        GridBagConstraints gbc_saveNewSequence = new GridBagConstraints();
175        gbc_saveNewSequence.anchor = GridBagConstraints.WEST;
176        gbc_saveNewSequence.gridwidth = 4;
177        gbc_saveNewSequence.insets = new Insets(0, 0, 5, 5);
178        gbc_saveNewSequence.gridx = 0;
179        gbc_saveNewSequence.gridy = 3;
180        mainPanel.add(saveNewSequence, gbc_saveNewSequence);
181        usageStatistics = new JCheckBox("Usage statistics report");
182        GridBagConstraints gbc_usageStatistics = new GridBagConstraints();
183        gbc_usageStatistics.gridwidth = 4;
184        gbc_usageStatistics.anchor = GridBagConstraints.WEST;
185        gbc_usageStatistics.insets = new Insets(0, 0, 5, 5);
186        gbc_usageStatistics.gridx = 0;
187        gbc_usageStatistics.gridy = 4;
188        mainPanel.add(usageStatistics, gbc_usageStatistics);
189        usageStatistics.setToolTipText(
190                "Report is 100% anonymous, very light on network trafic and help developers so keep it enabled please :)");
191
192        separator = new JSeparator();
193        GridBagConstraints gbc_separator = new GridBagConstraints();
194        gbc_separator.anchor = GridBagConstraints.WEST;
195        gbc_separator.fill = GridBagConstraints.VERTICAL;
196        gbc_separator.gridwidth = 4;
197        gbc_separator.insets = new Insets(0, 0, 5, 5);
198        gbc_separator.gridx = 0;
199        gbc_separator.gridy = 5;
200        mainPanel.add(separator, gbc_separator);
201
202        JLabel label_1 = new JLabel(" Max memory (max = " + maxMemMB + " MB)");
203        GridBagConstraints gbc_label_1 = new GridBagConstraints();
204        gbc_label_1.gridwidth = 2;
205        gbc_label_1.anchor = GridBagConstraints.WEST;
206        gbc_label_1.insets = new Insets(0, 0, 5, 5);
207        gbc_label_1.gridx = 0;
208        gbc_label_1.gridy = 6;
209        mainPanel.add(label_1, gbc_label_1);
210        maxMemoryMBSpinner = new JSpinner(new SpinnerNumberModel(128, 64, maxMemMB, 32));
211        GridBagConstraints gbc_maxMemoryMBSpinner = new GridBagConstraints();
212        gbc_maxMemoryMBSpinner.fill = GridBagConstraints.HORIZONTAL;
213        gbc_maxMemoryMBSpinner.insets = new Insets(0, 0, 5, 5);
214        gbc_maxMemoryMBSpinner.gridx = 2;
215        gbc_maxMemoryMBSpinner.gridy = 6;
216        mainPanel.add(maxMemoryMBSpinner, gbc_maxMemoryMBSpinner);
217        maxMemoryMBSpinner.setToolTipText("Change the maximum memory available for application");
218        maxMemoryMBLabel = new JLabel(" MB");
219        GridBagConstraints gbc_lblMbmax = new GridBagConstraints();
220        gbc_lblMbmax.anchor = GridBagConstraints.WEST;
221        gbc_lblMbmax.insets = new Insets(0, 0, 5, 5);
222        gbc_lblMbmax.gridx = 3;
223        gbc_lblMbmax.gridy = 6;
224        mainPanel.add(maxMemoryMBLabel, gbc_lblMbmax);
225        JLabel lblMemoryAllocatedFor = new JLabel(" Memory allocated for data cache ");
226        lblMemoryAllocatedFor.setToolTipText(
227                "Change the memory portion allocated for image data caching (higher value allow faster image processing but less memory for others taks)");
228        GridBagConstraints gbc_lblMemoryAllocatedFor = new GridBagConstraints();
229        gbc_lblMemoryAllocatedFor.gridwidth = 2;
230        gbc_lblMemoryAllocatedFor.anchor = GridBagConstraints.WEST;
231        gbc_lblMemoryAllocatedFor.insets = new Insets(0, 0, 5, 5);
232        gbc_lblMemoryAllocatedFor.gridx = 0;
233        gbc_lblMemoryAllocatedFor.gridy = 7;
234        mainPanel.add(lblMemoryAllocatedFor, gbc_lblMemoryAllocatedFor);
235
236        cacheMemoryPercent = new JSpinner(new SpinnerNumberModel(40, 10, 80, 5));
237        GridBagConstraints gbc_cacheMemoryPercent = new GridBagConstraints();
238        gbc_cacheMemoryPercent.fill = GridBagConstraints.HORIZONTAL;
239        gbc_cacheMemoryPercent.insets = new Insets(0, 0, 5, 5);
240        gbc_cacheMemoryPercent.gridx = 2;
241        gbc_cacheMemoryPercent.gridy = 7;
242        mainPanel.add(cacheMemoryPercent, gbc_cacheMemoryPercent);
243        cacheMemoryPercent.setToolTipText(
244                "Change the memory portion allocated for image data caching (higher value allow faster image processing but less memory for others taks)");
245
246        label = new JLabel("%");
247        GridBagConstraints gbc_label = new GridBagConstraints();
248        gbc_label.anchor = GridBagConstraints.WEST;
249        gbc_label.insets = new Insets(0, 0, 5, 5);
250        gbc_label.gridx = 3;
251        gbc_label.gridy = 7;
252        mainPanel.add(label, gbc_label);
253        JLabel lblCacheLocation = new JLabel(" Disk data cache location");
254        lblCacheLocation.setToolTipText(
255                "Folder used to store image data cache (it's recommended to use fast storage location as SSD disk)");
256        GridBagConstraints gbc_lblCacheLocation = new GridBagConstraints();
257        gbc_lblCacheLocation.anchor = GridBagConstraints.WEST;
258        gbc_lblCacheLocation.insets = new Insets(0, 0, 5, 5);
259        gbc_lblCacheLocation.gridx = 0;
260        gbc_lblCacheLocation.gridy = 8;
261        mainPanel.add(lblCacheLocation, gbc_lblCacheLocation);
262
263        cachePath = new IcyTextField();
264        GridBagConstraints gbc_cachePath = new GridBagConstraints();
265        gbc_cachePath.fill = GridBagConstraints.HORIZONTAL;
266        gbc_cachePath.gridwidth = 2;
267        gbc_cachePath.insets = new Insets(0, 0, 5, 5);
268        gbc_cachePath.gridx = 1;
269        gbc_cachePath.gridy = 8;
270        mainPanel.add(cachePath, gbc_cachePath);
271        cachePath.setToolTipText(
272                "Folder used to store image data cache (it's recommended to use fast storage location as SSD disk)");
273        cachePath.setColumns(10);
274
275        setCachePathButton = new JButton("...");
276        setCachePathButton.setPreferredSize(new Dimension(32, 23));
277        GridBagConstraints gbc_setCachePathButton = new GridBagConstraints();
278        gbc_setCachePathButton.anchor = GridBagConstraints.WEST;
279        gbc_setCachePathButton.insets = new Insets(0, 0, 5, 5);
280        gbc_setCachePathButton.gridx = 3;
281        gbc_setCachePathButton.gridy = 8;
282        mainPanel.add(setCachePathButton, gbc_setCachePathButton);
283
284        panel = new JPanel();
285        GridBagConstraints gbc_panel = new GridBagConstraints();
286        gbc_panel.insets = new Insets(0, 0, 5, 5);
287        gbc_panel.gridwidth = 4;
288        gbc_panel.fill = GridBagConstraints.BOTH;
289        gbc_panel.gridx = 0;
290        gbc_panel.gridy = 10;
291        mainPanel.add(panel, gbc_panel);
292        GridBagLayout gbl_panel = new GridBagLayout();
293        gbl_panel.columnWidths = new int[] {16, 0, 0, 0, 16, 0};
294        gbl_panel.rowHeights = new int[] {0, 0};
295        gbl_panel.columnWeights = new double[] {0.0, 1.0, 1.0, 1.0, 0.0, Double.MIN_VALUE};
296        gbl_panel.rowWeights = new double[] {0.0, Double.MIN_VALUE};
297        panel.setLayout(gbl_panel);
298
299        reenableAllToolTipButton = new JButton("Reactivate tooltips");
300        GridBagConstraints gbc_reenableAllToolTipButton = new GridBagConstraints();
301        gbc_reenableAllToolTipButton.insets = new Insets(0, 0, 0, 5);
302        gbc_reenableAllToolTipButton.gridx = 1;
303        gbc_reenableAllToolTipButton.gridy = 0;
304        panel.add(reenableAllToolTipButton, gbc_reenableAllToolTipButton);
305        reenableAllToolTipButton.setToolTipText("All hidden tooltips will be made visible again");
306
307        reenableAllConfirmButton = new JButton("Reactivate confirmations");
308        GridBagConstraints gbc_reenableAllConfirmButton = new GridBagConstraints();
309        gbc_reenableAllConfirmButton.insets = new Insets(0, 0, 0, 5);
310        gbc_reenableAllConfirmButton.gridx = 3;
311        gbc_reenableAllConfirmButton.gridy = 0;
312        panel.add(reenableAllConfirmButton, gbc_reenableAllConfirmButton);
313        reenableAllConfirmButton.setToolTipText("All hidden confimation dialogs be made visible again");
314
315        mainPanel.validate();
316    }
317
318    @Override
319    protected void load()
320    {
321        maxMemoryMBSpinner.setValue(Integer.valueOf(ApplicationPreferences.getMaxMemoryMB()));
322        cacheMemoryPercent.setValue(Integer.valueOf(ApplicationPreferences.getCacheMemoryPercent()));
323        cachePath.setText(ApplicationPreferences.getCachePath());
324        exitConfirm.setSelected(GeneralPreferences.getExitConfirm());
325        sequencePersistence.setSelected(GeneralPreferences.getSequencePersistence());
326        saveNewSequence.setSelected(GeneralPreferences.getSaveNewSequence());
327        autoUpdateCheckBox.setSelected(GeneralPreferences.getAutomaticUpdate());
328        usageStatistics.setSelected(GeneralPreferences.getUsageStatisticsReport());
329    }
330
331    @Override
332    protected void save()
333    {
334        int intValue;
335        String stringValue;
336
337        intValue = ((Integer) maxMemoryMBSpinner.getValue()).intValue();
338        // launcher setting modified, restart needed
339        if (ApplicationPreferences.getMaxMemoryMB() != intValue)
340            getPreferenceFrame().setNeedRestart();
341        ApplicationPreferences.setMaxMemoryMB(intValue);
342
343        intValue = ((Integer) cacheMemoryPercent.getValue()).intValue();
344        // launcher setting modified, restart needed
345        if (ApplicationPreferences.getCacheMemoryPercent() != intValue)
346            getPreferenceFrame().setNeedRestart();
347        ApplicationPreferences.setCacheMemoryPercent(intValue);
348
349        stringValue = cachePath.getText();
350        if (!StringUtil.equals(ApplicationPreferences.getCachePath(), stringValue))
351            getPreferenceFrame().setNeedRestart();
352        ApplicationPreferences.setCachePath(stringValue);
353
354        GeneralPreferences.setExitConfirm(exitConfirm.isSelected());
355        GeneralPreferences.setSequencePersistence(sequencePersistence.isSelected());
356        GeneralPreferences.setSaveNewSequence(saveNewSequence.isSelected());
357        GeneralPreferences.setAutomaticUpdate(autoUpdateCheckBox.isSelected());
358        GeneralPreferences.setUsageStatisticsReport(usageStatistics.isSelected());
359    }
360}