001package jmri;
002
003import java.awt.Dimension;
004import java.awt.Point;
005import java.beans.PropertyChangeListener;
006import java.util.ArrayList;
007import java.util.HashMap;
008
009import javax.annotation.CheckForNull;
010import javax.annotation.Nonnull;
011
012/**
013 * Interface for the User Preferences Manager.
014 * <p>
015 * The User Message Preference Manager keeps track of the options that a user
016 * has selected in messages where they have selected "Remember this setting for
017 * next time"
018 *
019 * @see jmri.managers.JmriUserPreferencesManager
020 *
021 * @author Kevin Dickerson Copyright (C) 2010
022 */
023public interface UserPreferencesManager {
024
025    public static final String PREFERENCES_UPDATED = "PreferencesUpdated"; // NOI18N
026
027    public void setLoading();
028
029    public void finishLoading();
030
031    /**
032     * Enquire as to the state of a user preference.
033     * <p>
034     * Preferences that have not been set will be considered to be false.
035     * <p>
036     * The name is free-form, but to avoid ambiguity it should start with the
037     * package name (package.Class) for the primary using class.
038     *
039     * @param name the name of the preference
040     * @return the state or false if never set
041     */
042    boolean getSimplePreferenceState(String name);
043
044    /**
045     * This is used to remember the last selected state of a checkBox and thus
046     * allow that checkBox to be set to a true state when it is next
047     * initialized. This can also be used anywhere else that a simple yes/no,
048     * true/false type preference needs to be stored.
049     * <p>
050     * It should not be used for remembering if a user wants to suppress a
051     * message as there is no means in the GUI for the user to reset the flag.
052     * setPreferenceState() should be used in this instance The name is
053     * free-form, but to avoid ambiguity it should start with the package name
054     * (package.Class) for the primary using class.
055     *
056     * @param name  A unique name to identify the state being stored
057     * @param state simple boolean
058     */
059    void setSimplePreferenceState(String name, boolean state);
060
061    /**
062     * Enquire as to the state of a user preference.
063     * <p>
064     * Preferences that have not been set will be considered to be defaultState.
065     * <p>
066     * The name is free-form, but to avoid ambiguity it should start with the
067     * package name (package.Class) for the primary using class.
068     *
069     * @param name the name of the preference
070     * @param defaultState the default state if not set
071     * @return the state or defaultState if never set
072     */
073    boolean getCheckboxPreferenceState(String name, boolean defaultState);
074
075    /**
076     * This is used to remember the last selected state of a checkBox and thus
077     * allow that checkBox to be set to a true state when it is next
078     * initialized. This can also be used anywhere else that a simple yes/no,
079     * true/false type preference needs to be stored.
080     * <p>
081     * It should not be used for remembering if a user wants to suppress a
082     * message as there is no means in the GUI for the user to reset the flag.
083     * setPreferenceState() should be used in this instance The name is
084     * free-form, but to avoid ambiguity it should start with the package name
085     * (package.Class) for the primary using class.
086     *
087     * @param name  A unique name to identify the state being stored
088     * @param state simple boolean
089     */
090    void setCheckboxPreferenceState(String name, boolean state);
091
092    /**
093     * Returns an ArrayList of the check box states set as true.
094     *
095     * @return list of simple preferences names
096     */
097    public ArrayList<String> getSimplePreferenceStateList();
098
099    /**
100     * Used to save the state of checkboxes which can suppress messages from
101     * being displayed. This method should be used by the initiating code in
102     * conjunction with the preferenceItemDetails. Here the items are stored
103     * against a specific class and access to change them is made available via
104     * the GUI, in the preference manager.
105     * <p>
106     * The strClass parameter does not have to be the exact class name of the
107     * initiating code, but can be one where the information is related and
108     * therefore can be grouped together with.
109     * <p>
110     * Both the strClass and item although free form, should make up a unique
111     * reference.
112     *
113     * @param strClass The class that this preference should be stored or
114     *                 grouped with.
115     * @param item     The specific item that is to be stored
116     * @param state    Boolean state of the item.
117     */
118    public void setPreferenceState(String strClass, String item, boolean state);
119
120    /**
121     * Returns the state of a given item registered against a specific class or
122     * item.
123     *
124     * @param strClass name of the class for this preference
125     * @param item     name of the item for which the state is being retrieved
126     * @return the state or false if not set
127     */
128    public boolean getPreferenceState(String strClass, String item);
129
130    /**
131     * Register details about a particular preference, so that it can be
132     * displayed in the GUI and provide a meaning full description when
133     * presented to the user.
134     *
135     * @param strClass    A string form of the class that the preference is
136     *                    stored or grouped with
137     * @param item        The specific item that is being stored
138     * @param description A meaningful description of the item that the user
139     *                    will understand
140     */
141    public void setPreferenceItemDetails(String strClass, String item, String description);
142
143    /**
144     * Returns a list of preferences that are registered against a specific
145     * class.
146     *
147     * @param strClass the class name
148     * @return the list of preference names
149     */
150    public ArrayList<String> getPreferenceList(String strClass);
151
152    /**
153     * Returns the itemName of the n preference in the given class
154     *
155     * @param strClass the name of the class
156     * @param n        the position in an array
157     * @return the name of the preference or null if non-existent
158     */
159    @CheckForNull
160    public String getPreferenceItemName(String strClass, int n);
161
162    /**
163     * Returns the description of the given item preference in the given class
164     *
165     * @param strClass the name of the class
166     * @param item     the name of the item
167     * @return the description of the preference
168     */
169    @CheckForNull
170    public String getPreferenceItemDescription(String strClass, String item);
171
172    /**
173     * Enquire as to the state of a user preference for the current session.
174     * <p>
175     * Preferences that have not been set will be considered to be false.
176     * <p>
177     * The name is free-form, but to avoid ambiguity it should start with the
178     * package name (package.Class) for the primary using class.
179     *
180     * @param name the name of the preference
181     * @return the state or false if not set
182     */
183    public boolean getSessionPreferenceState(String name);
184
185    /**
186     * Used to suppress messages for the current session, the information is not
187     * stored, can not be changed via the GUI.
188     * <p>
189     * This can be used to help prevent over loading the user with repetitive
190     * error messages such as turnout not found while loading a panel file due
191     * to a connection failing. The name is free-form, but to avoid ambiguity it
192     * should start with the package name (package.Class) for the primary using
193     * class.
194     *
195     * @param name  A unique identifier for preference.
196     * @param state suppression state of the item.
197     */
198    public void setSessionPreferenceState(String name, boolean state);
199
200    // The reset is used after the preferences have been loaded for the first time
201    public void resetChangeMade();
202
203    /**
204     * Show an info message ("don't forget ...") with a given dialog title and
205     * user message. Use a given preference name to determine whether to show it
206     * in the future. The combination of the classString and item parameters
207     * should form a unique value.
208     *
209     * @param title       message Box title
210     * @param message     message to be displayed
211     * @param classString name of the calling class
212     * @param item        name of the specific item this is used for
213     */
214    public void showInfoMessage(String title, String message, String classString, String item);
215
216    /**
217     * Show an error message ("don't forget ...") with a given dialog title and
218     * user message. Use a given preference name to determine whether to show it
219     * in the future. added flag to indicate that the message should be
220     * suppressed JMRI session only. The classString and item
221     * parameters should form a unique value
222     *
223     * @param title          Message Box title
224     * @param message        Message to be displayed
225     * @param classString    String value of the calling class
226     * @param item           String value of the specific item this is used for
227     * @param sessionOnly    Means this message will be suppressed in this JMRI
228     *                       session and not be remembered
229     * @param alwaysRemember Means that the suppression of the message will be
230     *                       saved
231     */
232    public void showErrorMessage(String title, String message, String classString, String item, boolean sessionOnly, boolean alwaysRemember);
233
234    /**
235     * Show an info message ("don't forget ...") with a given dialog title and
236     * user message. Use a given preference name to determine whether to show it
237     * in the future. added flag to indicate that the message should be
238     * suppressed JMRI session only. The classString and item
239     * parameters should form a unique value
240     *
241     * @param title          Message Box title
242     * @param message        Message to be displayed
243     * @param classString    String value of the calling class
244     * @param item           String value of the specific item this is used for
245     * @param sessionOnly    Means this message will be suppressed in this JMRI
246     *                       session and not be remembered
247     * @param alwaysRemember Means that the suppression of the message will be
248     *                       saved
249     */
250    public void showInfoMessage(String title, String message, String classString, String item, boolean sessionOnly, boolean alwaysRemember);
251
252    /**
253     * Show a warning message ("don't forget ...") with a given dialog title and
254     * user message. Use a given preference name to determine whether to show it
255     * in the future. added flag to indicate that the message should be
256     * suppressed JMRI session only. The classString and item
257     * parameters should form a unique value
258     *
259     * @param title          Message Box title
260     * @param message        Message to be displayed
261     * @param classString    String value of the calling class
262     * @param item           String value of the specific item this is used for
263     * @param sessionOnly    Means this message will be suppressed in this JMRI
264     *                       session and not be remembered
265     * @param alwaysRemember Means that the suppression of the message will be
266     *                       saved
267     */
268    public void showWarningMessage(String title, String message, String classString, String item, boolean sessionOnly, boolean alwaysRemember);
269
270    /**
271     * The last selected value in a given combo box.
272     *
273     * @param comboBoxName the combo box name
274     * @return the selected value
275     */
276    @CheckForNull
277    public String getComboBoxLastSelection(String comboBoxName);
278
279    /**
280     * Set the last selected value in a given combo box.
281     * <p>
282     * The name is free-form, but to avoid ambiguity it should start with the
283     * package name (package.Class) for the primary using class, followed by an
284     * identifier for the combo box.
285     *
286     * @param comboBoxName the combo box name
287     * @param lastValue    the selected value
288     */
289    public void setComboBoxLastSelection(String comboBoxName, String lastValue);
290
291    public Dimension getScreen();
292
293    /**
294     * Check if saving preferences is allowed.
295     *
296     * @return true if saving is allowed; false otherwise
297     */
298    public boolean isSaveAllowed();
299
300    /**
301     * Set if saving preferences is allowed. When setting true, preferences will
302     * be saved immediately if needed.
303     * <p>
304     * <strong>Note</strong> only set false if a number of preferences will be
305     * set together to avoid excessive disk I/O while setting preferences.
306     * <p>
307     * <strong>Note</strong> remember to allow saving as soon as blocking saving
308     * is no longer needed.
309     *
310     * @param saveAllowed true to allow saving; false to block saving
311     */
312    public void setSaveAllowed(boolean saveAllowed);
313
314    public void removePropertyChangeListener(PropertyChangeListener l);
315
316    public void addPropertyChangeListener(PropertyChangeListener l);
317
318    /**
319     * Get the description of a class/group registered with the preferences.
320     *
321     * @param strClass the class name
322     * @return the description
323     */
324    @Nonnull
325    public String getClassDescription(String strClass);
326
327    /**
328     * Get the list of the classes registered with the preference manager.
329     *
330     * @return the list of class names
331     */
332    @Nonnull
333    public ArrayList<String> getPreferencesClasses();
334
335    /**
336     * Given that we know the class as a string, we will try and attempt to
337     * gather details about the preferences that has been added, so that we can
338     * make better sense of the details in the preferences window.
339     * <p>
340     * This looks for specific methods within the class called
341     * "getClassDescription" and "setMessagePreferenceDetails". If found it will
342     * invoke the methods, this will then trigger the class to send details
343     * about its preferences back to this code.
344     *
345     * @param strClass description to use for the class
346     */
347    public void setClassDescription(String strClass);
348
349    /**
350     * Add descriptive details about a specific message box, so that if it needs
351     * to be reset in the preferences, then it is easily identifiable. displayed
352     * to the user in the preferences GUI.
353     *
354     * @param strClass      String value of the calling class/group
355     * @param item          String value of the specific item this is used for.
356     * @param description   A meaningful description that can be used in a label
357     *                      to describe the item
358     * @param options       A map of the integer value of the option against a
359     *                      meaningful description.
360     * @param defaultOption The default option for the given item.
361     */
362    public void setMessageItemDetails(String strClass, String item, String description, HashMap<Integer, String> options, int defaultOption);
363
364    /**
365     * Returns a map of the value against description of the different items in
366     * a given class. This information can then be used to build a Combo box.
367     *
368     * @param strClass Class or group of the given item
369     * @param item     the item which we wish to return the details about.
370     * @return map of choices
371     */
372    public HashMap<Integer, String> getChoiceOptions(String strClass, String item);
373
374    /**
375     * Get the number of Multiple Choice items registered with a given class.
376     *
377     * @param strClass the class name
378     * @return number of items
379     */
380    public int getMultipleChoiceSize(String strClass);
381
382    /**
383     * Get a list of all the multiple choice items registered with a given
384     * class.
385     *
386     * @param strClass the class name
387     * @return list of item names
388     */
389    public ArrayList<String> getMultipleChoiceList(String strClass);
390
391    /**
392     * Get the nth item name in a given class.
393     *
394     * @param strClass the class name
395     * @param n        the position
396     * @return the item name
397     */
398    public String getChoiceName(String strClass, int n);
399
400    /**
401     * Get the a meaningful description of a given item in a given class or
402     * group.
403     *
404     * @param strClass the class name
405     * @param item     the item name
406     * @return the item description
407     */
408    public String getChoiceDescription(String strClass, String item);
409
410    /**
411     * Get the current value of a given item in a given class.
412     *
413     * @param strClass the class name
414     * @param item     the item name
415     * @return the value
416     */
417    public int getMultipleChoiceOption(String strClass, String item);
418
419    /**
420     * Returns the default value of a given item in a given class
421     *
422     * @param strClass the class name
423     * @param choice   the item name
424     * @return the default value
425     */
426    public int getMultipleChoiceDefaultOption(String strClass, String choice);
427
428    /**
429     * Sets the value of a given item in a given class, by its string
430     * description.
431     *
432     * @param strClass the class name
433     * @param choice   the item name
434     * @param value    the item value description
435     */
436    public void setMultipleChoiceOption(String strClass, String choice, String value);
437
438    /**
439     * Sets the value of a given item in a given class, by its integer value.
440     *
441     * @param strClass the class name
442     * @param choice   the item name
443     * @param value    the item value
444     */
445    public void setMultipleChoiceOption(String strClass, String choice, int value);
446
447    /**
448     * Get the combined size of both types of items registered.
449     *
450     * @param strClass the class name
451     * @return number of registered preferences
452     */
453    public int getPreferencesSize(String strClass);
454
455    /**
456     * Saves the last location of a given component on the screen.
457     * <p>
458     * The jmri.util.JmriJFrame, will automatically use the class name of the
459     * frame if the class name returned is equal to jmri.util.JmriJFrame, the
460     * location is not stored
461     *
462     * @param strClass This is a unique identifier for window location being
463     *                 saved
464     * @param location The x,y location of the window given in a Point
465     */
466    public void setWindowLocation(String strClass, Point location);
467
468    /**
469     * Saves the last size of a given component on the screen
470     * <p>
471     * The jmri.util.JmriJFrame, will automatically use the class name of the
472     * frame if the class name returned is equal to jmri.util.JmriJFrame, the
473     * size is not stored
474     *
475     * @param strClass This is a unique identifier for window size being saved
476     * @param dim      The width, height size of the window given in a Dimension
477     */
478    public void setWindowSize(String strClass, Dimension dim);
479
480    /**
481     * Get the x,y location of a given Window.
482     *
483     * @param strClass the class name
484     * @return the location
485     */
486    public Point getWindowLocation(String strClass);
487
488    /**
489     * Returns the width, height size of a given Window
490     *
491     * @param strClass the class name
492     * @return the size
493     */
494    public Dimension getWindowSize(String strClass);
495
496    public ArrayList<String> getWindowList();
497
498    /**
499     * Check if there are properties for the given class
500     *
501     * @param strClass class to check
502     * @return true if properties for strClass are maintained; false otherwise
503     */
504    public boolean hasProperties(String strClass);
505
506    public boolean getSaveWindowSize(String strClass);
507
508    public boolean getSaveWindowLocation(String strClass);
509
510    /**
511     * Set if window sizes should be saved for a given class. Method has no
512     * effect if strClass is null or equals {@code jmri.util.JmriJFrame}.
513     *
514     * @param strClass name of the class
515     * @param b        true if window sizes should be saved; false otherwise
516     */
517    public void setSaveWindowSize(String strClass, boolean b);
518
519    /**
520     * Set if window locations should be saved for a given class. Method has no
521     * effect if strClass is null or equals {@code jmri.util.JmriJFrame}.
522     *
523     * @param strClass name of the class
524     * @param b        true if window locations should be saved; false otherwise
525     */
526    public void setSaveWindowLocation(String strClass, boolean b);
527
528    /**
529     * Attach a key/value pair to the given class, which can be retrieved later.
530     * These are not bound properties as yet, and don't throw events on
531     * modification. Key must not be null.
532     *
533     * @param strClass class to use
534     * @param key      Prior to 4.3.5, this could be an Object.
535     * @param value    value to use
536     */
537    public void setProperty(String strClass, String key, Object value);
538
539    /**
540     * Retrieve the value associated with a key in a given class If no value has
541     * been set for that key, returns null.
542     *
543     * @param strClass class to use
544     * @param key      item to retrieve
545     * @return stored value
546     */
547    public Object getProperty(String strClass, String key);
548
549    /**
550     * Retrieve the complete current set of keys for a given class.
551     *
552     * @param strClass class to use
553     * @return complete set of keys
554     */
555    public java.util.Set<String> getPropertyKeys(String strClass);
556
557    /*
558     Example informational message dialog box.
559
560     final UserPreferencesManager p;
561     p = jmri.InstanceManager.getDefault(jmri.UserPreferencesManager.class);
562     if (p.getProperty("thisClass", "routeSaveMsg") { // NOI18N
563         final JDialog dialog = new JDialog();
564         dialog.setTitle(Bundle.getMessage(""ReminderTitle")); // I18N
565         dialog.setLocationRelativeTo(null);
566         dialog.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
567         JPanel container = new JPanel();
568         container.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
569         container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
570
571         JLabel question = new JLabel("Remember to save your Route information.", JLabel.CENTER); // I18N
572         question.setAlignmentX(Component.CENTER_ALIGNMENT);
573         container.add(question);
574
575         JButton okButton = new JButton(Bundle.getMessage("ButtonOK");
576         JPanel buttons = new JPanel();
577         button.setAlignmentX(Component.CENTER_ALIGNMENT);
578         buttons.add(okButton);
579         container.add(buttons);
580
581         final JCheckBox remember = new JCheckBox(Bundle.getMessage("DontRemind");
582         remember.setAlignmentX(Component.CENTER_ALIGNMENT);
583         remember.setFont(remember.getFont().deriveFont(10f));
584         container.add(remember);
585
586         okButton.addActionListener(new ActionListener() {
587             public void actionPerformed(ActionEvent e) {
588                 p.setProperty("thisClass", "routeSaveMsg", remember.isSelected()) // NOI18N
589             }
590             dialog.dispose();
591         }
592         });
593
594         dialog.getContentPane().add(container);
595         dialog.pack();
596         dialog.setModal(true);
597         dialog.setVisible(true);
598     }
599
600 */
601
602 /*
603     Example question message dialog box.
604
605     final DefaultUserMessagePreferences p;
606     p = jmri.InstanceManager.getDefault(jmri.UserPreferencesManager.class);
607     if (p.getProperty("thisClass", "QuitAfterSave") == 0x00) { // NOI18N
608         final JDialog dialog = new JDialog();
609         dialog.setTitle(Bundle.getMessage("MessageShortQuitWarning")); // I18N
610         dialog.setLocationRelativeTo(null);
611         dialog.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
612         JPanel container = new JPanel();
613         container.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
614         container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
615
616         JLabel question = new JLabel(Bundle.getMessage("MessageLongQuitWarning")); // resource is in # AppsConfigBundle.properties
617         question.setAlignmentX(Component.CENTER_ALIGNMENT);
618         container.add(question);
619
620         final JCheckBox remember = new JCheckBox(Bundle.getMessage("MessageRememberSetting")); // I18N
621         remember.setFont(remember.getFont().deriveFont(10f));
622         remember.setAlignmentX(Component.CENTER_ALIGNMENT);
623
624         JButton yesButton = new JButton(Bundle.getMessage("ButtonYes"));
625         JButton noButton = new JButton(Bundle.getMessage("ButtonNo"));
626         JPanel buttons = new JPanel();
627         buttons.setAlignmentX(Component.CENTER_ALIGNMENT);
628         buttons.add(yesButton);
629         buttons.add(noButton);
630         container.add(buttons);
631
632         noButton.addActionListener(new ActionListener(){
633             public void actionPerformed(ActionEvent e) {
634                 if (remember.isSelected()) {
635                    p.setProperty("thisClass", "QuitAfterSave", 0x01) // NOI18N
636                 }
637                 dialog.dispose();
638             }
639         });
640
641         yesButton.addActionListener(new ActionListener(){
642             public void actionPerformed(ActionEvent e) {
643                 if (remember.isSelected()) {
644                    p.setProperty("thisClass", "QuitAfterSave", 0x02); // NOI18N
645                 }
646                 dialog.dispose();
647             }
648         });
649         container.add(remember);
650         container.setAlignmentX(Component.CENTER_ALIGNMENT);
651         container.setAlignmentY(Component.CENTER_ALIGNMENT);
652         dialog.getContentPane().add(container);
653         dialog.pack();
654         dialog.setModal(true);
655         dialog.setVisible(true);
656     }
657     */
658
659}