| 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others |
|---|
| 2 | package org.openstreetmap.josm.gui; |
|---|
| 3 | |
|---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr; |
|---|
| 5 | |
|---|
| 6 | import java.awt.Component; |
|---|
| 7 | import java.awt.GridBagLayout; |
|---|
| 8 | import java.awt.HeadlessException; |
|---|
| 9 | |
|---|
| 10 | import javax.swing.JCheckBox; |
|---|
| 11 | import javax.swing.JLabel; |
|---|
| 12 | import javax.swing.JOptionPane; |
|---|
| 13 | import javax.swing.JPanel; |
|---|
| 14 | |
|---|
| 15 | import org.openstreetmap.josm.Main; |
|---|
| 16 | import org.openstreetmap.josm.tools.GBC; |
|---|
| 17 | |
|---|
| 18 | /** |
|---|
| 19 | * ConditionalOptionPaneUtil provides static utility methods for displaying modal message dialogs |
|---|
| 20 | * which can be enabled/disabled by the user. |
|---|
| 21 | * |
|---|
| 22 | * They wrap the methods provided by {@see JOptionPane}. Within JOSM you should use these |
|---|
| 23 | * methods rather than the bare methods from {@see JOptionPane} because the methods provided |
|---|
| 24 | * by ConditionalOptionPaneUtil ensure that a dialog window is always on top and isn't hidden by one of the |
|---|
| 25 | * JOSM windows for detached dialogs, relation editors, history browser and the like. |
|---|
| 26 | * |
|---|
| 27 | */ |
|---|
| 28 | public class ConditionalOptionPaneUtil { |
|---|
| 29 | static public final int DIALOG_DISABLED_OPTION = Integer.MIN_VALUE; |
|---|
| 30 | |
|---|
| 31 | /** |
|---|
| 32 | * this is a static utility class only |
|---|
| 33 | */ |
|---|
| 34 | private ConditionalOptionPaneUtil() {} |
|---|
| 35 | |
|---|
| 36 | /** |
|---|
| 37 | * Replies the preference value for the preference key "message." + <code>prefKey</code>. |
|---|
| 38 | * The default value if the preference key is missing is true. |
|---|
| 39 | * |
|---|
| 40 | * @param the preference key |
|---|
| 41 | * @return prefKey the preference value for the preference key "message." + <code>prefKey</code> |
|---|
| 42 | */ |
|---|
| 43 | public static boolean getDialogShowingEnabled(String prefKey) { |
|---|
| 44 | return Main.pref.getBoolean("message."+prefKey, true); |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | /** |
|---|
| 48 | * sets the value for the preference key "message." + <code>prefKey</code>. |
|---|
| 49 | * |
|---|
| 50 | * @param prefKey the key |
|---|
| 51 | * @param enabled the value |
|---|
| 52 | */ |
|---|
| 53 | public static void setDialogShowingEnabled(String prefKey, boolean enabled) { |
|---|
| 54 | Main.pref.put("message."+prefKey, enabled); |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | /** |
|---|
| 58 | * Returns the preference value for the preference key "message." + <code>prefKey</code> + ".value". |
|---|
| 59 | * The default value if the preference key is missing is -1. |
|---|
| 60 | * |
|---|
| 61 | * @param the preference key |
|---|
| 62 | * @return prefKey the preference value for the preference key "message." + <code>prefKey</code> + ".value" |
|---|
| 63 | */ |
|---|
| 64 | public static Integer getDialogReturnValue(String prefKey) { |
|---|
| 65 | return Main.pref.getInteger("message."+prefKey+".value", -1); |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | /** |
|---|
| 69 | * sets the value for the preference key "message." + <code>prefKey</code> + ".value". |
|---|
| 70 | * |
|---|
| 71 | * @param prefKey the key |
|---|
| 72 | * @param value the value |
|---|
| 73 | */ |
|---|
| 74 | public static void setDialogReturnValue(String prefKey, Integer value) { |
|---|
| 75 | Main.pref.putInteger("message."+prefKey+".value", value); |
|---|
| 76 | } |
|---|
| 77 | |
|---|
| 78 | /** |
|---|
| 79 | * Displays an confirmation dialog with some option buttons given by <code>optionType</code>. |
|---|
| 80 | * It is always on top even if there are other open windows like detached dialogs, |
|---|
| 81 | * relation editors, history browsers and the like. |
|---|
| 82 | * |
|---|
| 83 | * Set <code>optionType</code> to {@see JOptionPane#YES_NO_OPTION} for a dialog with a YES and |
|---|
| 84 | * a NO button. |
|---|
| 85 | |
|---|
| 86 | * Set <code>optionType</code> to {@see JOptionPane#YES_NO_CANCEL_OPTION} for a dialog with a YES, |
|---|
| 87 | * a NO and a CANCEL button |
|---|
| 88 | * |
|---|
| 89 | * Returns one of the constants JOptionPane.YES_OPTION, JOptionPane.NO_OPTION, |
|---|
| 90 | * JOptionPane.CANCEL_OPTION or JOptionPane.CLOSED_OPTION depending on the action chosen by |
|---|
| 91 | * the user. |
|---|
| 92 | * |
|---|
| 93 | * @param preferenceKey the preference key |
|---|
| 94 | * @param parent the parent component |
|---|
| 95 | * @param message the message |
|---|
| 96 | * @param title the title |
|---|
| 97 | * @param optionType the option type |
|---|
| 98 | * @param messageType the message type |
|---|
| 99 | * @param options a list of options |
|---|
| 100 | * @param defaultOption the default option |
|---|
| 101 | * |
|---|
| 102 | * @return the option selected by user. {@see JOptionPane#CLOSED_OPTION} if the dialog was closed. |
|---|
| 103 | */ |
|---|
| 104 | static public int showOptionDialog(String preferenceKey, Component parent, Object message, String title, int optionType, int messageType, Object [] options, Object defaultOption) throws HeadlessException { |
|---|
| 105 | int ret = getDialogReturnValue(preferenceKey); |
|---|
| 106 | if (!getDialogShowingEnabled(preferenceKey) && ((ret == JOptionPane.YES_OPTION) || (ret == JOptionPane.NO_OPTION))) |
|---|
| 107 | return ret; |
|---|
| 108 | MessagePanel pnl = new MessagePanel(false, message); |
|---|
| 109 | ret = JOptionPane.showOptionDialog(parent, pnl, title, optionType, messageType, null, options, defaultOption); |
|---|
| 110 | |
|---|
| 111 | if (((ret == JOptionPane.YES_OPTION) || (ret == JOptionPane.NO_OPTION)) && !pnl.getDialogShowingEnabled()) { |
|---|
| 112 | setDialogShowingEnabled(preferenceKey, false); |
|---|
| 113 | setDialogReturnValue(preferenceKey, ret); |
|---|
| 114 | } |
|---|
| 115 | return ret; |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | /** |
|---|
| 119 | * Displays a confirmation dialog with some option buttons given by <code>optionType</code>. |
|---|
| 120 | * It is always on top even if there are other open windows like detached dialogs, |
|---|
| 121 | * relation editors, history browsers and the like. |
|---|
| 122 | * |
|---|
| 123 | * Set <code>optionType</code> to {@see JOptionPane#YES_NO_OPTION} for a dialog with a YES and |
|---|
| 124 | * a NO button. |
|---|
| 125 | |
|---|
| 126 | * Set <code>optionType</code> to {@see JOptionPane#YES_NO_CANCEL_OPTION} for a dialog with a YES, |
|---|
| 127 | * a NO and a CANCEL button |
|---|
| 128 | * |
|---|
| 129 | * Replies true, if the selected option is equal to <code>trueOption</code>, otherwise false. |
|---|
| 130 | * Replies true, if the dialog is not displayed because the respective preference option |
|---|
| 131 | * <code>preferenceKey</code> is set to false and the user has previously chosen |
|---|
| 132 | * <code>trueOption</code>. |
|---|
| 133 | * |
|---|
| 134 | * @param preferenceKey the preference key |
|---|
| 135 | * @param parent the parent component |
|---|
| 136 | * @param message the message |
|---|
| 137 | * @param title the title |
|---|
| 138 | * @param optionType the option type |
|---|
| 139 | * @param messageType the message type |
|---|
| 140 | * @param trueOption if this option is selected the method replies true |
|---|
| 141 | * |
|---|
| 142 | * |
|---|
| 143 | * @return true, if the selected option is equal to <code>trueOption</code>, otherwise false. |
|---|
| 144 | * |
|---|
| 145 | * @see JOptionPane#INFORMATION_MESSAGE |
|---|
| 146 | * @see JOptionPane#WARNING_MESSAGE |
|---|
| 147 | * @see JOptionPane#ERROR_MESSAGE |
|---|
| 148 | */ |
|---|
| 149 | static public boolean showConfirmationDialog(String preferenceKey, Component parent, Object message, String title, int optionType, int messageType, int trueOption) throws HeadlessException { |
|---|
| 150 | int ret = getDialogReturnValue(preferenceKey); |
|---|
| 151 | if (!getDialogShowingEnabled(preferenceKey) && ((ret == JOptionPane.YES_OPTION) || (ret == JOptionPane.NO_OPTION))) |
|---|
| 152 | return ret == trueOption; |
|---|
| 153 | MessagePanel pnl = new MessagePanel(false, message); |
|---|
| 154 | ret = JOptionPane.showConfirmDialog(parent, pnl, title, optionType, messageType); |
|---|
| 155 | if (((ret == JOptionPane.YES_OPTION) || (ret == JOptionPane.NO_OPTION)) && !pnl.getDialogShowingEnabled()) { |
|---|
| 156 | setDialogShowingEnabled(preferenceKey, false); |
|---|
| 157 | setDialogReturnValue(preferenceKey, ret); |
|---|
| 158 | } |
|---|
| 159 | return ret == trueOption; |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | /** |
|---|
| 163 | * Displays an message in modal dialog with an OK button. Makes sure the dialog |
|---|
| 164 | * is always on top even if there are other open windows like detached dialogs, |
|---|
| 165 | * relation editors, history browsers and the like. |
|---|
| 166 | * |
|---|
| 167 | * If there is a preference with key <code>preferenceKey</code> and value <code>false</code> |
|---|
| 168 | * the dialog is not show. |
|---|
| 169 | * |
|---|
| 170 | * @param preferenceKey the preference key |
|---|
| 171 | * @param parent the parent component |
|---|
| 172 | * @param message the message |
|---|
| 173 | * @param title the title |
|---|
| 174 | * @param messageType the message type |
|---|
| 175 | * |
|---|
| 176 | * @see JOptionPane#INFORMATION_MESSAGE |
|---|
| 177 | * @see JOptionPane#WARNING_MESSAGE |
|---|
| 178 | * @see JOptionPane#ERROR_MESSAGE |
|---|
| 179 | */ |
|---|
| 180 | static public void showMessageDialog(String preferenceKey, Component parent, Object message, String title,int messageType) { |
|---|
| 181 | if (!getDialogShowingEnabled(preferenceKey)) |
|---|
| 182 | return; |
|---|
| 183 | MessagePanel pnl = new MessagePanel(false, message); |
|---|
| 184 | JOptionPane.showMessageDialog(parent, pnl, title, messageType); |
|---|
| 185 | if(!pnl.getDialogShowingEnabled()) { |
|---|
| 186 | setDialogShowingEnabled(preferenceKey, false); |
|---|
| 187 | } |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | /** |
|---|
| 191 | * This is a message panel used in dialogs which can be enabled/disabled with a preference |
|---|
| 192 | * setting. |
|---|
| 193 | * In addition to the normal message any {@see JOptionPane} would display it includes |
|---|
| 194 | * a checkbox for enabling/disabling this particular dialog. |
|---|
| 195 | * |
|---|
| 196 | */ |
|---|
| 197 | private static class MessagePanel extends JPanel { |
|---|
| 198 | JCheckBox cbShowDialog; |
|---|
| 199 | |
|---|
| 200 | public MessagePanel(boolean donotshow, Object message) { |
|---|
| 201 | cbShowDialog = new JCheckBox(tr("Do not show again (remembers choice)")); |
|---|
| 202 | cbShowDialog.setSelected(donotshow); |
|---|
| 203 | setLayout(new GridBagLayout()); |
|---|
| 204 | |
|---|
| 205 | if (message instanceof Component) { |
|---|
| 206 | add((Component)message, GBC.eop()); |
|---|
| 207 | } else { |
|---|
| 208 | add(new JLabel(message.toString()),GBC.eop()); |
|---|
| 209 | } |
|---|
| 210 | add(cbShowDialog, GBC.eol()); |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | public boolean getDialogShowingEnabled() { |
|---|
| 214 | return !cbShowDialog.isSelected(); |
|---|
| 215 | } |
|---|
| 216 | } |
|---|
| 217 | } |
|---|