I18 changes
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / preferences / PreferencesDialog.java
1 package net.sf.openrocket.gui.dialogs.preferences;
2
3 import java.awt.Dialog;
4 import java.awt.Window;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.WindowAdapter;
8 import java.awt.event.WindowEvent;
9 import java.io.File;
10 import java.util.ArrayList;
11 import java.util.List;
12
13 import javax.swing.AbstractListModel;
14 import javax.swing.ComboBoxModel;
15 import javax.swing.JButton;
16 import javax.swing.JCheckBox;
17 import javax.swing.JComboBox;
18 import javax.swing.JDialog;
19 import javax.swing.JFileChooser;
20 import javax.swing.JLabel;
21 import javax.swing.JOptionPane;
22 import javax.swing.JPanel;
23 import javax.swing.JProgressBar;
24 import javax.swing.JTabbedPane;
25 import javax.swing.JTextField;
26 import javax.swing.Timer;
27 import javax.swing.event.DocumentEvent;
28 import javax.swing.event.DocumentListener;
29
30 import net.miginfocom.swing.MigLayout;
31 import net.sf.openrocket.communication.UpdateInfo;
32 import net.sf.openrocket.communication.UpdateInfoRetriever;
33 import net.sf.openrocket.gui.components.DescriptionArea;
34 import net.sf.openrocket.gui.components.StyledLabel;
35 import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
36 import net.sf.openrocket.gui.main.SimpleFileFilter;
37 import net.sf.openrocket.l10n.Translator;
38 import net.sf.openrocket.logging.LogHelper;
39 import net.sf.openrocket.startup.Application;
40 import net.sf.openrocket.unit.Unit;
41 import net.sf.openrocket.unit.UnitGroup;
42 import net.sf.openrocket.util.GUIUtil;
43 import net.sf.openrocket.util.Prefs;
44
45 public class PreferencesDialog extends JDialog {
46         private static final LogHelper log = Application.getLogger();
47         
48         private final List<DefaultUnitSelector> unitSelectors = new ArrayList<DefaultUnitSelector>();
49         
50         private File defaultDirectory = null;
51         private static final Translator trans = Application.getTranslator();
52
53         private PreferencesDialog() {
54                 //// Preferences
55                 super((Window) null, trans.get("pref.dlg.title.Preferences"), Dialog.ModalityType.APPLICATION_MODAL);
56                 
57                 JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", "[grow][]"));
58                 
59                 JTabbedPane tabbedPane = new JTabbedPane();
60                 panel.add(tabbedPane, "grow, wrap");
61                 
62                 //// Units and Default units
63                 tabbedPane.addTab(trans.get("pref.dlg.tab.Units"), null, unitsPane(), 
64                                 trans.get("pref.dlg.tab.Defaultunits"));
65                 //// Materials and Custom materials
66                 tabbedPane.addTab(trans.get("pref.dlg.tab.Materials"), null, new MaterialEditPanel(),
67                                 trans.get("pref.dlg.tab.Custommaterials"));
68                 //// Options and Miscellaneous options
69                 tabbedPane.addTab(trans.get("pref.dlg.tab.Options"), null, optionsPane(), 
70                                 trans.get("pref.dlg.tab.Miscellaneousoptions"));
71                 
72                 //// Close button
73                 JButton close = new JButton(trans.get("dlg.but.close"));
74                 close.addActionListener(new ActionListener() {
75                         @Override
76                         public void actionPerformed(ActionEvent arg0) {
77                                 PreferencesDialog.this.setVisible(false);
78                                 PreferencesDialog.this.dispose();
79                         }
80                 });
81                 panel.add(close, "span, right, tag close");
82                 
83                 this.setContentPane(panel);
84                 pack();
85                 this.setLocationRelativeTo(null);
86                 
87                 this.addWindowListener(new WindowAdapter() {
88                         @Override
89                         public void windowClosed(WindowEvent e) {
90                                 Prefs.storeDefaultUnits();
91                         }
92                 });
93                 
94                 GUIUtil.setDisposableDialogOptions(this, close);
95         }
96         
97         
98         private JPanel optionsPane() {
99                 JPanel panel = new JPanel(new MigLayout("fillx, ins 30lp n n n"));
100                 
101                 //// Position to insert new body components:
102                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")), "gapright para");
103                 panel.add(new JComboBox(new PrefChoiseSelector(Prefs.BODY_COMPONENT_INSERT_POSITION_KEY,
104                                 "Always ask", "Insert in middle", "Add to end")), "wrap para, growx, sg combos");
105                 
106                 //// Confirm deletion of simulations:
107                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Confirmdeletion")));
108                 panel.add(new JComboBox(new PrefBooleanSelector(Prefs.CONFIRM_DELETE_SIMULATION,
109                                 "Delete", "Confirm", true)), "wrap 40lp, growx, sg combos");
110                 
111                 //// User-defined thrust curves:
112                 panel.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap");
113                 final JTextField field = new JTextField();
114                 List<File> files = Prefs.getUserThrustCurveFiles();
115                 String str = "";
116                 for (File file : files) {
117                         if (str.length() > 0) {
118                                 str += ";";
119                         }
120                         str += file.getAbsolutePath();
121                 }
122                 field.setText(str);
123                 field.getDocument().addDocumentListener(new DocumentListener() {
124                         @Override
125                         public void removeUpdate(DocumentEvent e) {
126                                 changed();
127                         }
128                         
129                         @Override
130                         public void insertUpdate(DocumentEvent e) {
131                                 changed();
132                         }
133                         
134                         @Override
135                         public void changedUpdate(DocumentEvent e) {
136                                 changed();
137                         }
138                         
139                         private void changed() {
140                                 String text = field.getText();
141                                 List<File> list = new ArrayList<File>();
142                                 for (String s : text.split(";")) {
143                                         s = s.trim();
144                                         if (s.length() > 0) {
145                                                 list.add(new File(s));
146                                         }
147                                 }
148                                 Prefs.setUserThrustCurveFiles(list);
149                         }
150                 });
151                 panel.add(field, "w 100px, gapright unrel, spanx, growx, split");
152                 
153                 //// Add button
154                 JButton button = new JButton(trans.get("pref.dlg.but.add"));
155                 button.addActionListener(new ActionListener() {
156                         @Override
157                         public void actionPerformed(ActionEvent e) {
158                                 JFileChooser chooser = new JFileChooser();
159                                 SimpleFileFilter filter = 
160                                         new SimpleFileFilter(
161                                                         //// All thrust curve files (*.eng; *.rse; *.zip; directories)
162                                                         trans.get("pref.dlg.Allthrustcurvefiles"),
163                                                 true, "eng", "rse", "zip");
164                                 chooser.addChoosableFileFilter(filter);
165                                 //// RASP motor files (*.eng)
166                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RASPfiles"),
167                                                 true, "eng"));
168                                 //// RockSim engine files (*.rse)
169                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RockSimfiles"),
170                                                 true, "rse"));
171                                 //// ZIP archives (*.zip)
172                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.ZIParchives"),
173                                                 true, "zip"));
174                                 chooser.setFileFilter(filter);
175                                 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
176                                 if (defaultDirectory != null) {
177                                         chooser.setCurrentDirectory(defaultDirectory);
178                                 }
179                                 
180                                 int returnVal = chooser.showDialog(PreferencesDialog.this, "Add");
181                                 if (returnVal == JFileChooser.APPROVE_OPTION) {
182                                         log.user("Adding user thrust curve: " + chooser.getSelectedFile());
183                                         defaultDirectory = chooser.getCurrentDirectory();
184                                         String text = field.getText().trim();
185                                         if (text.length() > 0) {
186                                                 text += ";";
187                                         }
188                                         text += chooser.getSelectedFile().getAbsolutePath();
189                                         field.setText(text);
190                                 }
191                         }
192                 });
193                 panel.add(button, "gapright unrel");
194                 
195                 //// Reset button
196                 button = new JButton(trans.get("pref.dlg.but.reset"));
197                 
198                 button.addActionListener(new ActionListener() {
199                         @Override
200                         public void actionPerformed(ActionEvent e) {
201                                 // First one sets to the default, but does not un-set the pref
202                                 field.setText(Prefs.getDefaultUserThrustCurveFile().getAbsolutePath());
203                                 Prefs.setUserThrustCurveFiles(null);
204                         }
205                 });
206                 panel.add(button, "wrap");
207                 
208                 DescriptionArea desc = new DescriptionArea("Add directories, RASP motor files (*.eng), " +
209                                 "RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external " +
210                                 "thrust curves.  Changes will take effect the next time you start OpenRocket.", 3, -3, false);
211                 desc.setBackground(getBackground());
212                 panel.add(desc, "spanx, growx, wrap 40lp");
213                 
214
215
216                 //// Check for software updates at startup
217                 final JCheckBox softwareUpdateBox = 
218                         new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates"));
219                 softwareUpdateBox.setSelected(Prefs.getCheckUpdates());
220                 softwareUpdateBox.addActionListener(new ActionListener() {
221                         @Override
222                         public void actionPerformed(ActionEvent e) {
223                                 Prefs.setCheckUpdates(softwareUpdateBox.isSelected());
224                         }
225                 });
226                 panel.add(softwareUpdateBox);
227                 
228                 //// Check now button
229                 button = new JButton(trans.get("pref.dlg.but.checknow"));
230                 //// Check for software updates now
231                 button.setToolTipText(trans.get("pref.dlg.ttip.Checkupdatesnow"));
232                 button.addActionListener(new ActionListener() {
233                         @Override
234                         public void actionPerformed(ActionEvent e) {
235                                 checkForUpdates();
236                         }
237                 });
238                 panel.add(button, "right, wrap");
239                 
240
241                 return panel;
242         }
243         
244         private JPanel unitsPane() {
245                 JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]"));
246                 JComboBox combo;
247                 
248                 //// Select your preferred units:
249                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Selectprefunits")), "span, wrap paragraph");
250                 
251
252                 //// Rocket dimensions:
253                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Rocketdimensions")));
254                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH));
255                 panel.add(combo, "sizegroup boxes");
256                 
257                 //// Line density:
258                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Linedensity")));
259                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE));
260                 panel.add(combo, "sizegroup boxes, wrap");
261                 
262
263                 //// Motor dimensions:
264                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Motordimensions")));
265                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS));
266                 panel.add(combo, "sizegroup boxes");
267                 
268                 //// Surface density:
269                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfacedensity")));
270                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE));
271                 panel.add(combo, "sizegroup boxes, wrap");
272                 
273
274                 //// Distance:
275                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Distance")));
276                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE));
277                 panel.add(combo, "sizegroup boxes");
278                 
279                 //// Bulk density::
280                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Bulkdensity")));
281                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK));
282                 panel.add(combo, "sizegroup boxes, wrap");
283                 
284
285                 //// Velocity:
286                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Velocity")));
287                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY));
288                 panel.add(combo, "sizegroup boxes");
289                 
290                 //// Surface roughness:
291                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfaceroughness")));
292                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS));
293                 panel.add(combo, "sizegroup boxes, wrap");
294                 
295
296                 //// Acceleration:
297                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Acceleration")));
298                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION));
299                 panel.add(combo, "sizegroup boxes");
300                 
301                 //// Area:
302                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Area")));
303                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA));
304                 panel.add(combo, "sizegroup boxes, wrap");
305                 
306
307                 //// Mass:
308                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Mass")));
309                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS));
310                 panel.add(combo, "sizegroup boxes");
311                 
312                 //// Angle:
313                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Angle")));
314                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE));
315                 panel.add(combo, "sizegroup boxes, wrap");
316                 
317
318                 //// Force:
319                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Force")));
320                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE));
321                 panel.add(combo, "sizegroup boxes");
322                 
323                 //// Roll rate:
324                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Rollrate")));
325                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL));
326                 panel.add(combo, "sizegroup boxes, wrap");
327                 
328
329                 //// Total impulse:
330                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Totalimpulse")));
331                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE));
332                 panel.add(combo, "sizegroup boxes");
333                 
334                 //// Temperature:
335                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Temperature")));
336                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE));
337                 panel.add(combo, "sizegroup boxes, wrap");
338                 
339
340                 //// Moment of inertia:
341                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Momentofinertia")));
342                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_INERTIA));
343                 panel.add(combo, "sizegroup boxes");
344                 
345                 //// Pressure:
346                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Pressure")));
347                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE));
348                 panel.add(combo, "sizegroup boxes, wrap");
349                 
350                 //// Stability:
351                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Stability")));
352                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY));
353                 panel.add(combo, "sizegroup boxes, wrap para");
354                 
355
356
357                 //// Default metric button
358                 JButton button = new JButton(trans.get("pref.dlg.but.defaultmetric"));
359                 button.addActionListener(new ActionListener() {
360                         @Override
361                         public void actionPerformed(ActionEvent e) {
362                                 UnitGroup.setDefaultMetricUnits();
363                                 for (DefaultUnitSelector s : unitSelectors)
364                                         s.fireChange();
365                         }
366                 });
367                 panel.add(button, "spanx, split 2, grow");
368                 
369                 //// Default imperial button
370                 button = new JButton(trans.get("pref.dlg.but.defaultimperial"));
371                 button.addActionListener(new ActionListener() {
372                         @Override
373                         public void actionPerformed(ActionEvent e) {
374                                 UnitGroup.setDefaultImperialUnits();
375                                 for (DefaultUnitSelector s : unitSelectors)
376                                         s.fireChange();
377                         }
378                 });
379                 panel.add(button, "grow, wrap para");
380                 
381                 //// The effects will take place the next time you open a window.
382                 panel.add(new StyledLabel(
383                                 trans.get("pref.dlg.lbl.effect1"), -2),
384                                 "spanx, wrap");
385                 
386
387                 return panel;
388         }
389         
390         
391
392
393
394         private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel {
395                 
396                 private final UnitGroup group;
397                 
398                 public DefaultUnitSelector(UnitGroup group) {
399                         this.group = group;
400                         unitSelectors.add(this);
401                 }
402                 
403                 @Override
404                 public Object getSelectedItem() {
405                         return group.getDefaultUnit();
406                 }
407                 
408                 @Override
409                 public void setSelectedItem(Object item) {
410                         if (item == null) {
411                                 // Clear selection - huh?
412                                 return;
413                         }
414                         if (!(item instanceof Unit)) {
415                                 throw new IllegalArgumentException("Illegal argument " + item);
416                         }
417                         group.setDefaultUnit(group.getUnitIndex((Unit) item));
418                 }
419                 
420                 @Override
421                 public Object getElementAt(int index) {
422                         return group.getUnit(index);
423                 }
424                 
425                 @Override
426                 public int getSize() {
427                         return group.getUnitCount();
428                 }
429                 
430                 
431                 public void fireChange() {
432                         this.fireContentsChanged(this, 0, this.getSize());
433                 }
434         }
435         
436         
437
438         private class PrefChoiseSelector extends AbstractListModel implements ComboBoxModel {
439                 private final String preference;
440                 private final String[] descriptions;
441                 
442                 public PrefChoiseSelector(String preference, String... descriptions) {
443                         this.preference = preference;
444                         this.descriptions = descriptions;
445                 }
446                 
447                 @Override
448                 public Object getSelectedItem() {
449                         return descriptions[Prefs.getChoise(preference, descriptions.length, 0)];
450                 }
451                 
452                 @Override
453                 public void setSelectedItem(Object item) {
454                         if (item == null) {
455                                 // Clear selection - huh?
456                                 return;
457                         }
458                         if (!(item instanceof String)) {
459                                 throw new IllegalArgumentException("Illegal argument " + item);
460                         }
461                         int index;
462                         for (index = 0; index < descriptions.length; index++) {
463                                 if (((String) item).equalsIgnoreCase(descriptions[index]))
464                                         break;
465                         }
466                         if (index >= descriptions.length) {
467                                 throw new IllegalArgumentException("Illegal argument " + item);
468                         }
469                         
470                         Prefs.putChoise(preference, index);
471                 }
472                 
473                 @Override
474                 public Object getElementAt(int index) {
475                         return descriptions[index];
476                 }
477                 
478                 @Override
479                 public int getSize() {
480                         return descriptions.length;
481                 }
482         }
483         
484         
485         private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel {
486                 private final String preference;
487                 private final String trueDesc, falseDesc;
488                 private final boolean def;
489                 
490                 public PrefBooleanSelector(String preference, String falseDescription,
491                                 String trueDescription, boolean defaultState) {
492                         this.preference = preference;
493                         this.trueDesc = trueDescription;
494                         this.falseDesc = falseDescription;
495                         this.def = defaultState;
496                 }
497                 
498                 @Override
499                 public Object getSelectedItem() {
500                         if (Prefs.NODE.getBoolean(preference, def)) {
501                                 return trueDesc;
502                         } else {
503                                 return falseDesc;
504                         }
505                 }
506                 
507                 @Override
508                 public void setSelectedItem(Object item) {
509                         if (item == null) {
510                                 // Clear selection - huh?
511                                 return;
512                         }
513                         if (!(item instanceof String)) {
514                                 throw new IllegalArgumentException("Illegal argument " + item);
515                         }
516                         
517                         if (trueDesc.equals(item)) {
518                                 Prefs.NODE.putBoolean(preference, true);
519                         } else if (falseDesc.equals(item)) {
520                                 Prefs.NODE.putBoolean(preference, false);
521                         } else {
522                                 throw new IllegalArgumentException("Illegal argument " + item);
523                         }
524                 }
525                 
526                 @Override
527                 public Object getElementAt(int index) {
528                         switch (index) {
529                         case 0:
530                                 return def ? trueDesc : falseDesc;
531                                 
532                         case 1:
533                                 return def ? falseDesc : trueDesc;
534                                 
535                         default:
536                                 throw new IndexOutOfBoundsException("Boolean asked for index=" + index);
537                         }
538                 }
539                 
540                 @Override
541                 public int getSize() {
542                         return 2;
543                 }
544         }
545         
546         
547         private void checkForUpdates() {
548                 final UpdateInfoRetriever retriever = new UpdateInfoRetriever();
549                 retriever.start();
550                 
551
552                 // Progress dialog
553                 final JDialog dialog = new JDialog(this, ModalityType.APPLICATION_MODAL);
554                 JPanel panel = new JPanel(new MigLayout());
555                 
556                 //// Checking for updates...
557                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Checkingupdates")), "wrap");
558                 
559                 JProgressBar bar = new JProgressBar();
560                 bar.setIndeterminate(true);
561                 panel.add(bar, "growx, wrap para");
562                 
563                 //// Cancel button
564                 JButton cancel = new JButton(trans.get("dlg.but.cancel"));
565                 cancel.addActionListener(new ActionListener() {
566                         @Override
567                         public void actionPerformed(ActionEvent e) {
568                                 dialog.dispose();
569                         }
570                 });
571                 panel.add(cancel, "right");
572                 dialog.add(panel);
573                 
574                 GUIUtil.setDisposableDialogOptions(dialog, cancel);
575                 
576
577                 // Timer to monitor progress
578                 final Timer timer = new Timer(100, null);
579                 final long startTime = System.currentTimeMillis();
580                 
581                 ActionListener listener = new ActionListener() {
582                         @Override
583                         public void actionPerformed(ActionEvent e) {
584                                 if (!retriever.isRunning() || startTime + 10000 < System.currentTimeMillis()) {
585                                         timer.stop();
586                                         dialog.dispose();
587                                 }
588                         }
589                 };
590                 timer.addActionListener(listener);
591                 timer.start();
592                 
593
594                 // Wait for action
595                 dialog.setVisible(true);
596                 
597
598                 // Check result
599                 UpdateInfo info = retriever.getUpdateInfo();
600                 if (info == null) {
601                         JOptionPane.showMessageDialog(this,
602                                         //// An error occurred while communicating with the server.
603                                         trans.get("pref.dlg.lbl.msg1"),
604                                         //// Unable to retrieve update information
605                                         trans.get("pref.dlg.lbl.msg2"), JOptionPane.WARNING_MESSAGE, null);
606                 } else if (info.getLatestVersion() == null ||
607                                 info.getLatestVersion().equals("") ||
608                                 Prefs.getVersion().equalsIgnoreCase(info.getLatestVersion())) {
609                         JOptionPane.showMessageDialog(this,
610                                         //// You are running the latest version of OpenRocket.
611                                         trans.get("pref.dlg.lbl.msg3"),
612                                         //// No updates available
613                                         trans.get("pref.dlg.lbl.msg4"), JOptionPane.INFORMATION_MESSAGE, null);
614                 } else {
615                         UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
616                         infoDialog.setVisible(true);
617                         if (infoDialog.isReminderSelected()) {
618                                 Prefs.putString(Prefs.LAST_UPDATE, "");
619                         } else {
620                                 Prefs.putString(Prefs.LAST_UPDATE, info.getLatestVersion());
621                         }
622                 }
623                 
624         }
625         
626         
627         ////////  Singleton implementation  ////////
628         
629         private static PreferencesDialog dialog = null;
630         
631         public static void showPreferences() {
632                 if (dialog != null) {
633                         dialog.dispose();
634                 }
635                 dialog = new PreferencesDialog();
636                 dialog.setVisible(true);
637         }
638         
639
640 }