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.

PreferencesCategory.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * Copyright (c) 2006-2009 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.util.ListenerList;
  24. import java.util.ArrayList;
  25. import java.util.List;
  26. /**
  27. * Represents one category of preferences. Categories can contain 0 or more
  28. * subcategories, and either 0 or more PreferencesSettings or exactly 1
  29. * PreferencesInterface object.
  30. *
  31. * @author chris
  32. */
  33. public class PreferencesCategory {
  34. /** A logger for this class. */
  35. private static final java.util.logging.Logger LOGGER = java.util.logging
  36. .Logger.getLogger(PreferencesCategory.class.getName());
  37. /** The title (name) of this category. */
  38. private final String title;
  39. /** A description of this category. */
  40. private final String description;
  41. /** The icon to use for this category. */
  42. private final String icon;
  43. /** Whether or not this category is inline. */
  44. private boolean isInline = false;
  45. /** Whether or not to show inline categories before settings. */
  46. private boolean inlineBefore = true;
  47. /** Our parent category, if known. */
  48. private PreferencesCategory parent;
  49. /** A list of settings in this category. */
  50. private final List<PreferencesSetting> settings = new ArrayList<PreferencesSetting>();
  51. /** A list of subcategories of this category. */
  52. private final List<PreferencesCategory> subcats = new ArrayList<PreferencesCategory>();
  53. /** The replacement object to use for this category. */
  54. private final PreferencesInterface object;
  55. /** A list of listeners who are interested in this category. */
  56. private final ListenerList listeners = new ListenerList();
  57. /**
  58. * Creates a new preferences category that contains settings.
  59. *
  60. * @param title The title of this preferences category
  61. * @param description The description of this category
  62. */
  63. public PreferencesCategory(final String title, final String description) {
  64. this(title, description, null, null);
  65. }
  66. /**
  67. * Creates a new preferences category that contains settings.
  68. *
  69. * @since 0.6.3m1
  70. * @param title The title of this preferences category
  71. * @param description The description of this category
  72. * @param icon The icon to use for this category
  73. */
  74. public PreferencesCategory(final String title, final String description,
  75. final String icon) {
  76. this(title, description, icon, null);
  77. }
  78. /**
  79. * Creates a new preferences category that contains an object.
  80. *
  81. * @param title The title of this preferences category
  82. * @param description The description of this category
  83. * @param object The replacement object for this category
  84. */
  85. public PreferencesCategory(final String title, final String description,
  86. final PreferencesInterface object) {
  87. this(title, description, null, object);
  88. }
  89. /**
  90. * Creates a new preferences category that contains an object.
  91. *
  92. * @since 0.6.3m1
  93. * @param title The title of this preferences category
  94. * @param description The description of this category
  95. * @param icon The icon to use for this category
  96. * @param object The replacement object for this category
  97. */
  98. public PreferencesCategory(final String title, final String description,
  99. final String icon, final PreferencesInterface object) {
  100. this.title = title;
  101. this.description = description;
  102. this.icon = icon;
  103. this.object = object;
  104. }
  105. /**
  106. * Sets this as an inline category.
  107. *
  108. * @return A reference to this category, for convenience
  109. */
  110. public PreferencesCategory setInline() {
  111. isInline = true;
  112. return this;
  113. }
  114. /**
  115. * Sets this category to show inline categories after settings, rather than
  116. * before.
  117. *
  118. * @return A reference to this category, for convenience
  119. */
  120. public PreferencesCategory setInlineAfter() {
  121. inlineBefore = false;
  122. return this;
  123. }
  124. /**
  125. * Determines if this category is meant to be displayed inline or not.
  126. *
  127. * @return True if this category should be shown inline, false otherwise
  128. */
  129. public boolean isInline() {
  130. return isInline;
  131. }
  132. /**
  133. * Determines whether this category wants inline subcats to be displayed
  134. * before the settings, or after.
  135. *
  136. * @return True if subcats should be displayed first, false otherwise.
  137. */
  138. public boolean isInlineBefore() {
  139. return inlineBefore;
  140. }
  141. /**
  142. * Adds the specified setting to this category.
  143. *
  144. * @param setting The setting to be added
  145. */
  146. public void addSetting(final PreferencesSetting setting) {
  147. if (hasObject()) {
  148. throw new IllegalArgumentException("Can't add settings to a " +
  149. "category that uses a replacement object");
  150. }
  151. settings.add(setting);
  152. }
  153. /**
  154. * Adds the specified subcategory to this category.
  155. *
  156. * @param subcategory The category to be asdded
  157. */
  158. public void addSubCategory(final PreferencesCategory subcategory) {
  159. if (isInline() && !subcategory.isInline()) {
  160. throw new IllegalArgumentException("Can't add non-inline " +
  161. "subcategories to inline ones");
  162. }
  163. subcategory.setParent(this);
  164. subcats.add(subcategory);
  165. }
  166. /**
  167. * Retrieves the description of this category.
  168. *
  169. * @return This category's description
  170. */
  171. public String getDescription() {
  172. return description;
  173. }
  174. /**
  175. * Retrieves the settings in this category.
  176. *
  177. * @return This category's settings
  178. */
  179. public List<PreferencesSetting> getSettings() {
  180. return settings;
  181. }
  182. /**
  183. * Retrieves the subcategories of this category.
  184. *
  185. * @return This category's subcategories
  186. */
  187. public List<PreferencesCategory> getSubcats() {
  188. return subcats;
  189. }
  190. /**
  191. * Retrieves the title of this category.
  192. *
  193. * @return This category's title
  194. */
  195. public String getTitle() {
  196. return title;
  197. }
  198. /**
  199. * Retrieves the icon to use for this category.
  200. *
  201. * @return This category's icon
  202. * @since 0.6.3m1
  203. */
  204. public String getIcon() {
  205. return icon;
  206. }
  207. /**
  208. * Determines if this category has a replacement object.
  209. *
  210. * @return True if the category has a replacement object, false otherwise
  211. * @see #getObject()
  212. */
  213. public boolean hasObject() {
  214. return object != null;
  215. }
  216. /**
  217. * Retrieves this category's replacement object.
  218. *
  219. * @return This category's replacement object.
  220. * @see #hasObject()
  221. */
  222. public PreferencesInterface getObject() {
  223. return object;
  224. }
  225. /**
  226. * Retrieves the full path of this category. A category's path is the name
  227. * of each of its parent categories, starting with the furthest up the
  228. * hierarchy, separated by '→' characters.
  229. *
  230. * @return This category's path
  231. * @since 0.6.3m1
  232. */
  233. public String getPath() {
  234. return (parent == null ? "" : parent.getPath() + " → ") + getTitle();
  235. }
  236. /**
  237. * Sets this category's parent.
  238. *
  239. * @param parent The parent of this category
  240. * @since 0.6.3m1
  241. */
  242. public void setParent(final PreferencesCategory parent) {
  243. this.parent = parent;
  244. }
  245. /**
  246. * Retrieves the parent of this category.
  247. *
  248. * @return This category's parent, or null if it's an orphan
  249. * @since 0.6.3m1
  250. */
  251. public PreferencesCategory getParent() {
  252. return parent;
  253. }
  254. /**
  255. * Saves all the settings in this category.
  256. *
  257. * @return Is a restart needed after saving?
  258. */
  259. public boolean save() {
  260. LOGGER.fine(getTitle() + ": save method called");
  261. boolean restart = false;
  262. for (PreferencesSetting setting : settings) {
  263. LOGGER.finest(getTitle() + ": saving setting '" + setting.getTitle() + "'");
  264. if (setting.save() && setting.isRestartNeeded()) {
  265. restart = true;
  266. }
  267. }
  268. for (PreferencesCategory child : getSubcats()) {
  269. restart |= child.save();
  270. }
  271. return restart;
  272. }
  273. /**
  274. * Dismisses all the settings in this category.
  275. */
  276. public void dismiss() {
  277. for (PreferencesSetting setting : settings) {
  278. setting.dismiss();
  279. }
  280. for (PreferencesCategory child : getSubcats()) {
  281. child.dismiss();
  282. }
  283. }
  284. /**
  285. * Registers a change listener for this category.
  286. *
  287. * @param listener The listener to be added
  288. */
  289. public void addChangeListener(final CategoryChangeListener listener) {
  290. listeners.add(CategoryChangeListener.class, listener);
  291. }
  292. /**
  293. * Removes a change listener from this category.
  294. *
  295. * @param listener The listener to be added
  296. */
  297. public void removeChangeListener(final CategoryChangeListener listener) {
  298. listeners.remove(CategoryChangeListener.class, listener);
  299. }
  300. /**
  301. * Informs all registered listeners that this category has been selected.
  302. */
  303. public void fireCategorySelected() {
  304. for (CategoryChangeListener listener : listeners.get(CategoryChangeListener.class)) {
  305. listener.categorySelected(this);
  306. }
  307. }
  308. /**
  309. * Informs all registered listeners that this category has been deselected.
  310. */
  311. public void fireCategoryDeselected() {
  312. for (CategoryChangeListener listener : listeners.get(CategoryChangeListener.class)) {
  313. listener.categoryDeselected(this);
  314. }
  315. }
  316. }