You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PreferencesSetting.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright (c) 2006-2011 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.config.prefs;
  23. import com.dmdirc.config.ConfigManager;
  24. import com.dmdirc.config.Identity;
  25. import com.dmdirc.config.IdentityManager;
  26. import com.dmdirc.util.validators.PermissiveValidator;
  27. import com.dmdirc.util.validators.Validator;
  28. import java.util.ArrayList;
  29. import java.util.HashMap;
  30. import java.util.List;
  31. import java.util.Map;
  32. /**
  33. * Represents a single setting.
  34. */
  35. public class PreferencesSetting {
  36. /** The type of this setting. */
  37. protected final PreferencesType type;
  38. /** The possible options for a multichoice setting. */
  39. protected final Map<String, String> combooptions;
  40. /** The validator to use to validate this setting. */
  41. protected final Validator<String> validator;
  42. /** The domain of the setting. */
  43. protected final String domain;
  44. /** The option name of the setting. */
  45. protected final String option;
  46. /** The title of this setting. */
  47. protected final String title;
  48. /** Text to inform the user what the setting is for. */
  49. protected final String helptext;
  50. /** The current value of the setting. */
  51. protected String current;
  52. /** Whether or not we need a restart. */
  53. protected boolean restartNeeded;
  54. /** The original value of this vsetting. */
  55. private String original;
  56. /** A list of change listeners. */
  57. private final List<SettingChangeListener> listeners
  58. = new ArrayList<SettingChangeListener>();
  59. /** Identity to save settings to. */
  60. private final Identity identity;
  61. /**
  62. * Creates a new preferences setting for any type except multi-choice.
  63. *
  64. * @param type The type of the setting to create
  65. * @param validator A validator to validate the setting's value
  66. * @param domain The domain of the setting
  67. * @param option The option name of the setting
  68. * @param title The title of this setting
  69. * @param helptext Text to display to help the user
  70. */
  71. public PreferencesSetting(final PreferencesType type,
  72. final Validator<String> validator, final String domain,
  73. final String option, final String title, final String helptext) {
  74. this(type, validator, domain, option, title, helptext,
  75. IdentityManager.getGlobalConfig(),
  76. IdentityManager.getConfigIdentity());
  77. }
  78. /**
  79. * Creates a new preferences setting for any type except multi-choice.
  80. *
  81. * @param type The type of the setting to create
  82. * @param validator A validator to validate the setting's value
  83. * @param domain The domain of the setting
  84. * @param option The option name of the setting
  85. * @param title The title of this setting
  86. * @param helptext Text to display to help the user
  87. * @param configManager Config Manager
  88. * @param identity Identity to save setting to
  89. */
  90. public PreferencesSetting(final PreferencesType type,
  91. final Validator<String> validator, final String domain,
  92. final String option, final String title, final String helptext,
  93. final ConfigManager configManager, final Identity identity) {
  94. if (PreferencesType.MULTICHOICE.equals(type)) {
  95. throw new IllegalArgumentException("Multi-choice preferences must "
  96. + "have their options specified.");
  97. }
  98. this.type = type;
  99. this.combooptions = null;
  100. this.validator = validator;
  101. this.domain = domain;
  102. this.option = option;
  103. this.title = title;
  104. this.helptext = helptext;
  105. this.identity = identity;
  106. current = configManager.getOption(domain, option);
  107. original = current;
  108. }
  109. /**
  110. * Creates a new preferences setting for any type except multi-choice, with
  111. * a default permissive validator.
  112. *
  113. * @param type The type of the setting to create
  114. * @param domain The domain of the setting
  115. * @param option The option name of the setting
  116. * @param title The title of this setting
  117. * @param helptext Text to display to help the user
  118. */
  119. public PreferencesSetting(final PreferencesType type, final String domain,
  120. final String option, final String title, final String helptext) {
  121. this(type, domain, option, title, helptext,
  122. IdentityManager.getGlobalConfig(),
  123. IdentityManager.getConfigIdentity());
  124. }
  125. /**
  126. * Creates a new preferences setting for any type except multi-choice, with
  127. * a default permissive validator.
  128. *
  129. * @param type The type of the setting to create
  130. * @param domain The domain of the setting
  131. * @param option The option name of the setting
  132. * @param title The title of this setting
  133. * @param helptext Text to display to help the user
  134. * @param configManager Config Manager
  135. * @param identity Identity to save setting to
  136. */
  137. public PreferencesSetting(final PreferencesType type, final String domain,
  138. final String option, final String title, final String helptext,
  139. final ConfigManager configManager, final Identity identity) {
  140. if (PreferencesType.MULTICHOICE.equals(type)) {
  141. throw new IllegalArgumentException("Multi-choice preferences must "
  142. + "have their options specified.");
  143. }
  144. this.type = type;
  145. this.combooptions = null;
  146. this.validator = new PermissiveValidator<String>();
  147. this.domain = domain;
  148. this.option = option;
  149. this.title = title;
  150. this.helptext = helptext;
  151. this.identity = identity;
  152. current = configManager.getOption(domain, option);
  153. original = current;
  154. }
  155. /**
  156. * Creates a new preferences setting for multi-choice preferences.
  157. *
  158. * @param domain The domain of the setting
  159. * @param option The option name of the setting
  160. * @param options A map of setting values to display names for this setting
  161. * @param title The title of this setting
  162. * @param helptext Text to display to help the user
  163. */
  164. public PreferencesSetting(final String domain, final String option,
  165. final String title, final String helptext,
  166. final Map<String, String> options) {
  167. this(domain, option, title, helptext, options,
  168. IdentityManager.getGlobalConfig(),
  169. IdentityManager.getConfigIdentity());
  170. }
  171. /**
  172. * Creates a new preferences setting for multi-choice preferences.
  173. *
  174. * @param domain The domain of the setting
  175. * @param option The option name of the setting
  176. * @param options A map of setting values to display names for this setting
  177. * @param title The title of this setting
  178. * @param helptext Text to display to help the user
  179. * @param configManager Config Manager
  180. * @param identity Identity to save setting to
  181. */
  182. public PreferencesSetting(final String domain, final String option,
  183. final String title, final String helptext,
  184. final Map<String, String> options,
  185. final ConfigManager configManager, final Identity identity) {
  186. this.type = PreferencesType.MULTICHOICE;
  187. this.combooptions = new HashMap<String, String>(options);
  188. this.validator = new PermissiveValidator<String>();
  189. this.domain = domain;
  190. this.option = option;
  191. this.title = title;
  192. this.helptext = helptext;
  193. this.identity = identity;
  194. current = configManager.getOption(domain, option);
  195. original = current;
  196. if (!combooptions.containsKey(current)) {
  197. combooptions.put(current, "Current (" + current + ")");
  198. }
  199. }
  200. /**
  201. * Retrieves the possible options for use in a multi-choice preference.
  202. *
  203. * @return A map of setting values to display names, representing the
  204. * possible options for this setting.
  205. */
  206. public Map<String, String> getComboOptions() {
  207. return combooptions;
  208. }
  209. /**
  210. * Retrieves the help text for this setting.
  211. *
  212. * @return This setting's help text.
  213. */
  214. public String getHelptext() {
  215. return helptext;
  216. }
  217. /**
  218. * Retrieves the title of this setting.
  219. *
  220. * @return This setting's title.
  221. */
  222. public String getTitle() {
  223. return title;
  224. }
  225. /**
  226. * Retrieves the current value of this setting.
  227. *
  228. * @return The current value of this setting.
  229. */
  230. public String getValue() {
  231. return current;
  232. }
  233. /**
  234. * Retieves the type of this setting.
  235. *
  236. * @return This setting's type.
  237. */
  238. public PreferencesType getType() {
  239. return type;
  240. }
  241. /**
  242. * Returns a validator that can validate this setting.
  243. *
  244. * @return This setting's validator.
  245. */
  246. public Validator<String> getValidator() {
  247. return validator;
  248. }
  249. /**
  250. * Sets the current value of this setting. Note that the setting is not
  251. * saved to the configuration file until the save method is called.
  252. *
  253. * @param newValue The new value of the setting
  254. */
  255. public void setValue(final String newValue) {
  256. current = newValue;
  257. for (SettingChangeListener listener : listeners) {
  258. listener.settingChanged(this);
  259. }
  260. }
  261. /**
  262. * Determines whether or not this setting needs a restart when it's changed.
  263. *
  264. * @return True if this setting needs a restart, false otherwise
  265. */
  266. public boolean isRestartNeeded() {
  267. return restartNeeded;
  268. }
  269. /**
  270. * Sets the "restart needed" flag for this setting, indicating a client
  271. * restart is needed before the setting takes effect.
  272. *
  273. * @return A reference to this setting, for convenience
  274. */
  275. public PreferencesSetting setRestartNeeded() {
  276. restartNeeded = true;
  277. return this;
  278. }
  279. /**
  280. * Registers the specified setting change listener.
  281. *
  282. * @param listener The listener to be registered
  283. * @return A reference to this setting, for convenience
  284. */
  285. public PreferencesSetting registerChangeListener(final SettingChangeListener listener) {
  286. listeners.add(listener);
  287. return this;
  288. }
  289. /**
  290. * Saves the current value of this setting to the global configuration.
  291. *
  292. * @return True if the setting has changed, false otherwise
  293. */
  294. public boolean save() {
  295. if (!needsSaving()) {
  296. return false;
  297. }
  298. if (current == null) {
  299. identity.unsetOption(domain, option);
  300. } else {
  301. identity.setOption(domain, option, current);
  302. }
  303. original = current;
  304. return true;
  305. }
  306. /**
  307. * Dismisses changes to this setting.
  308. */
  309. public void dismiss() {
  310. if ((original != null && original.equals(current))
  311. || (original == null && current == null)) {
  312. return;
  313. }
  314. current = original;
  315. for (SettingChangeListener listener : listeners) {
  316. listener.settingChanged(this);
  317. }
  318. }
  319. /**
  320. * Does the setting need saving?
  321. *
  322. * @return true iif the setting will be changed if saved
  323. */
  324. public boolean needsSaving() {
  325. return (current == null || !current.equals(original))
  326. && (current != null || original != null)
  327. && (validator == null || !validator.validate(current).isFailure());
  328. }
  329. /**
  330. * Does this setting's identity have this setting?
  331. *
  332. * @return true iif the setting is present
  333. */
  334. public boolean isSet() {
  335. return identity.hasOptionString(domain, option, validator);
  336. }
  337. }