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.

PreferencesDialogModel.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. /*
  2. * Copyright (c) 2006-2017 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  5. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  7. * permit persons to whom the Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
  10. * Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
  14. * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  15. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. */
  17. package com.dmdirc.config.prefs;
  18. import com.dmdirc.events.ClientPrefsClosedEvent;
  19. import com.dmdirc.events.ClientPrefsOpenedEvent;
  20. import com.dmdirc.events.eventbus.EventBus;
  21. import com.dmdirc.interfaces.config.AggregateConfigProvider;
  22. import com.dmdirc.interfaces.config.ConfigProvider;
  23. import com.dmdirc.plugins.Service;
  24. import com.dmdirc.plugins.ServiceManager;
  25. import com.dmdirc.util.collections.ListenerList;
  26. import com.dmdirc.util.validators.NumericalValidator;
  27. import com.dmdirc.util.validators.OptionalValidator;
  28. import java.util.ArrayList;
  29. import java.util.Collections;
  30. import java.util.HashMap;
  31. import java.util.List;
  32. import java.util.Map;
  33. import javax.inject.Inject;
  34. /**
  35. * Manages categories that should appear in the preferences dialog.
  36. */
  37. public class PreferencesDialogModel {
  38. /** A list of categories. */
  39. private final List<PreferencesCategory> categories = new ArrayList<>();
  40. /** A list of listeners. */
  41. private final ListenerList listeners = new ListenerList();
  42. /** UI specific plugin panel. */
  43. private final PreferencesInterface pluginPanel;
  44. /** UI specific theme panel. */
  45. private final PreferencesInterface themePanel;
  46. /** UI specific updates panel. */
  47. private final PreferencesInterface updatesPanel;
  48. /** UI specific URL panel. */
  49. private final PreferencesInterface urlHandlerPanel;
  50. /** Config Manager to read settings from. */
  51. private final AggregateConfigProvider configManager;
  52. /** Identity to write settings to. */
  53. private final ConfigProvider identity;
  54. /** Service manager. */
  55. private final ServiceManager serviceManager;
  56. /** Event bus to post events on. */
  57. private final EventBus eventBus;
  58. /**
  59. * Creates a new instance of PreferencesDialogModel.
  60. */
  61. @Inject
  62. public PreferencesDialogModel(final PreferencesInterface pluginPanel,
  63. final PreferencesInterface themePanel,
  64. final PreferencesInterface updatesPanel,
  65. final PreferencesInterface urlHandlerPanel,
  66. final AggregateConfigProvider configManager,
  67. final ConfigProvider identity,
  68. final ServiceManager serviceManager,
  69. final EventBus eventBus) {
  70. this.pluginPanel = pluginPanel;
  71. this.themePanel = themePanel;
  72. this.updatesPanel = updatesPanel;
  73. this.urlHandlerPanel = urlHandlerPanel;
  74. this.configManager = configManager;
  75. this.identity = identity;
  76. this.serviceManager = serviceManager;
  77. this.eventBus = eventBus;
  78. addDefaultCategories();
  79. eventBus.publish(new ClientPrefsOpenedEvent(this));
  80. }
  81. public AggregateConfigProvider getConfigManager() {
  82. return configManager;
  83. }
  84. public ConfigProvider getIdentity() {
  85. return identity;
  86. }
  87. /**
  88. * Adds the specified category to the preferences manager.
  89. *
  90. * @param category The category to be added
  91. */
  92. public void addCategory(final PreferencesCategory category) {
  93. categories.add(category);
  94. }
  95. /**
  96. * Retrieves a list of categories registered with the preferences manager.
  97. *
  98. * @return An ordered list of categories
  99. */
  100. public List<PreferencesCategory> getCategories() {
  101. return Collections.unmodifiableList(categories);
  102. }
  103. /**
  104. * Finds and retrieves the category with the specified name.
  105. *
  106. * @param name The name (title) of the category to find.
  107. *
  108. * @return The appropriate category, or null if none was found
  109. */
  110. public PreferencesCategory getCategory(final String name) {
  111. for (PreferencesCategory category : categories) {
  112. if (category.getTitle().equals(name)) {
  113. return category;
  114. }
  115. }
  116. return null;
  117. }
  118. /**
  119. * Saves all the settings in this manager.
  120. *
  121. * @return Is a restart needed after saving?
  122. */
  123. public boolean save() {
  124. fireSaveListeners();
  125. boolean restart = false;
  126. for (PreferencesCategory category : categories) {
  127. if (category.save()) {
  128. restart |= true;
  129. }
  130. }
  131. return restart;
  132. }
  133. /**
  134. * Dismisses all the settings in this manager.
  135. */
  136. public void dismiss() {
  137. categories.forEach(PreferencesCategory::dismiss);
  138. }
  139. /**
  140. * Adds the default categories to this preferences manager.
  141. */
  142. private void addDefaultCategories() {
  143. addGeneralCategory();
  144. addConnectionCategory();
  145. addMessagesCategory();
  146. addGuiCategory();
  147. addPluginsCategory();
  148. addUrlHandlerCategory();
  149. addUpdatesCategory();
  150. addAdvancedCategory();
  151. }
  152. /**
  153. * Creates and adds the "General" category.
  154. */
  155. private void addGeneralCategory() {
  156. final PreferencesCategory category = new PreferencesCategory("General", "");
  157. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  158. "ui", "confirmQuit", "Confirm quit",
  159. "Show a confirmation message when you try to close the client",
  160. configManager, identity));
  161. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  162. "channel", "showmodeprefix", "Show mode prefix",
  163. "Prefix users' names with their mode (e.g. @) in channels",
  164. configManager, identity));
  165. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  166. "ui", "awayindicator", "Away indicator",
  167. "Show an indicator in windows when you are marked as away",
  168. configManager, identity));
  169. category.addSetting(new PreferencesSetting(PreferencesType.OPTIONALINTEGER,
  170. new OptionalValidator(new NumericalValidator(0, 100)), "ui",
  171. "pasteProtectionLimit", "Paste protection trigger",
  172. "Confirm pasting of text that contains more than this many "
  173. + "lines.", configManager, identity));
  174. addTabCompletionCategory(category);
  175. addCategory(category.setInlineAfter());
  176. }
  177. /**
  178. * Creates and adds the "Tab Completion" category.
  179. *
  180. * @param parent Parent category to add this category to
  181. *
  182. * @since 0.6.4
  183. */
  184. private void addTabCompletionCategory(final PreferencesCategory parent) {
  185. final PreferencesCategory category = new PreferencesCategory("Tab Completion", "");
  186. final Map<String, String> taboptions = new HashMap<>();
  187. for (Service service : serviceManager.getServicesByType("tabcompletion")) {
  188. taboptions.put(service.getName(), service.getName());
  189. }
  190. category.addSetting(new PreferencesSetting("tabcompletion", "style",
  191. "Tab completion style", "Determines the behaviour of "
  192. + "the tab completer when there are multiple matches",
  193. taboptions, configManager, identity));
  194. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  195. "tabcompletion", "casesensitive", "Case-sensitive tab completion",
  196. "Respect case when tab completing", configManager, identity));
  197. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  198. "tabcompletion", "allowempty", "Allow empty tab completion",
  199. "Attempt to tab complete when the Tab key is pressed even "
  200. + "if there is nothing to complete", configManager, identity));
  201. parent.addSubCategory(category.setInline());
  202. }
  203. /**
  204. * Creates and adds the "Connection" category.
  205. */
  206. private void addConnectionCategory() {
  207. final PreferencesCategory category = new PreferencesCategory("Connection",
  208. "", "category-connection");
  209. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  210. "general", "closechannelsonquit", "Close channels on quit",
  211. "Close channel windows when you manually disconnect from the server",
  212. configManager, identity));
  213. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  214. "general", "closechannelsondisconnect",
  215. "Close channels on disconnect", "Close channel windows when "
  216. + "the server is disconnected (because of an error)",
  217. configManager, identity));
  218. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  219. "general", "closequeriesonquit", "Close queries on quit",
  220. "Close query windows when you manually disconnect from the server",
  221. configManager, identity));
  222. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  223. "general", "closequeriesondisconnect",
  224. "Close queries on disconnect", "Close query windows when "
  225. + "the server is disconnected (because of an error)",
  226. configManager, identity));
  227. category.addSetting(new PreferencesSetting(PreferencesType.DURATION,
  228. "server", "pingtimer", "Ping warning time",
  229. "How long to wait after a ping reply is sent before showing "
  230. + "a warning message", configManager, identity));
  231. category.addSetting(new PreferencesSetting(PreferencesType.DURATION,
  232. "server", "pingtimeout", "Ping timeout",
  233. "How long to wait for a server to reply to a PING request "
  234. + "before assuming the server has died", configManager, identity));
  235. category.addSetting(new PreferencesSetting(PreferencesType.DURATION,
  236. "server", "pingfrequency", "Ping frequency",
  237. "How often a PING request should be sent to the server (to "
  238. + "check that it is still alive)", configManager, identity));
  239. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  240. "general", "reconnectonconnectfailure", "Reconnect on failure",
  241. "Attempt to reconnect if there is an error when connecting",
  242. configManager, identity));
  243. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  244. "general", "reconnectondisconnect", "Reconnect on disconnect",
  245. "Attempt to reconnect if the server is disconnected",
  246. configManager, identity));
  247. category.addSetting(new PreferencesSetting(PreferencesType.DURATION,
  248. "general", "reconnectdelay", "Reconnect delay",
  249. "How long to wait before attempting to reconnect to a server",
  250. configManager, identity));
  251. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  252. "general", "rejoinchannels", "Rejoin open channels",
  253. "Rejoin open channels when reconnecting to a server",
  254. configManager, identity));
  255. addSSLCategory(category);
  256. addCategory(category);
  257. }
  258. /**
  259. * Creates and adds the "SSL" category.
  260. *
  261. * @param parent Parent category to add this category to
  262. */
  263. private void addSSLCategory(final PreferencesCategory parent) {
  264. final PreferencesCategory category = new PreferencesCategory("SSL",
  265. "Options relating to encrypted (SSL) connections", "secure-server");
  266. category.addSetting(new PreferencesSetting(PreferencesType.FILE, "ssl",
  267. "clientcert.file", "Client certificate", "Path to PKCS12 client "
  268. + "certificate to send when connecting to servers using SSL",
  269. configManager, identity));
  270. category.addSetting(new PreferencesSetting(PreferencesType.TEXT, "ssl",
  271. "clientcert.pass", "Client password", "Password for client "
  272. + "certificate file", configManager, identity));
  273. parent.addSubCategory(category);
  274. }
  275. /**
  276. * Creates and adds the "Messages" category.
  277. */
  278. private void addMessagesCategory() {
  279. final PreferencesCategory category = new PreferencesCategory("Messages",
  280. "", "category-messages");
  281. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  282. "general", "closemessage",
  283. "Close message", "Default quit message to use when closing DMDirc",
  284. configManager, identity));
  285. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  286. "general", "partmessage",
  287. "Part message", "Default part message to use when leaving channels",
  288. configManager, identity));
  289. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  290. "general", "quitmessage",
  291. "Quit message", "Default quit message to use when disconnecting",
  292. configManager, identity));
  293. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  294. "general", "cyclemessage",
  295. "Cycle message", "Default part message to use when cycling channels",
  296. configManager, identity));
  297. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  298. "general", "kickmessage",
  299. "Kick message", "Default message to use when kicking people",
  300. configManager, identity));
  301. category.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  302. "general", "reconnectmessage",
  303. "Reconnect message", "Default quit message to use when reconnecting",
  304. configManager, identity));
  305. addNotificationsCategory(category);
  306. addCategory(category);
  307. }
  308. /**
  309. * Creates and adds the "Notifications" category.
  310. *
  311. * @param parent The parent category.
  312. */
  313. private void addNotificationsCategory(final PreferencesCategory parent) {
  314. final PreferencesCategory category = new PreferencesCategory("Notifications",
  315. "", "input-error");
  316. final Map<String, String> options = new HashMap<>();
  317. final Map<String, String> commonOptions = new HashMap<>();
  318. final Map<String, String> whoisOptions = new HashMap<>();
  319. final Map<String, String> ctcprOptions = new HashMap<>();
  320. final Map<String, String> mapOptions = new HashMap<>();
  321. options.put("all", "All windows");
  322. options.put("active", "Active window");
  323. options.put("server", "Server window");
  324. options.put("none", "Nowhere");
  325. commonOptions.putAll(options);
  326. commonOptions.put("comchans:%1$s server", "Common channels");
  327. whoisOptions.putAll(options);
  328. whoisOptions.put("lastcommand:(raw )?whois %4$s( %4$s)?", "Source of whois command");
  329. whoisOptions.put("comchans:%4$s server", "Common channels");
  330. ctcprOptions.putAll(commonOptions);
  331. ctcprOptions.put("lastcommand:ctcp %1$s %4$S", "Source of ctcp command");
  332. mapOptions.putAll(options);
  333. mapOptions.put("window:Network Map", "Map window");
  334. category.addSetting(new PreferencesSetting("notifications", "socketClosed",
  335. "Socket closed", "Where to display socket closed notifications",
  336. options, configManager, identity));
  337. category.addSetting(new PreferencesSetting("notifications", "privateNotice",
  338. "Private notice", "Where to display private notices",
  339. commonOptions, configManager, identity));
  340. category.addSetting(new PreferencesSetting("notifications", "serverNotice",
  341. "Server notice", "Where to display server notices",
  342. options, configManager, identity));
  343. category.addSetting(new PreferencesSetting("notifications", "privateCTCP",
  344. "CTCP request", "Where to display CTCP request notifications",
  345. commonOptions, configManager, identity));
  346. category.addSetting(new PreferencesSetting("notifications", "privateCTCPreply",
  347. "CTCP reply", "Where to display CTCP replies",
  348. ctcprOptions, configManager, identity));
  349. category.addSetting(new PreferencesSetting("notifications", "connectError",
  350. "Connect error", "Where to display connect error notifications",
  351. options, configManager, identity));
  352. category.addSetting(new PreferencesSetting("notifications", "connectRetry",
  353. "Connect retry", "Where to display connect retry notifications",
  354. options, configManager, identity));
  355. category.addSetting(new PreferencesSetting("notifications", "stonedServer",
  356. "Stoned server", "Where to display stoned server notifications",
  357. options, configManager, identity));
  358. category.addSetting(new PreferencesSetting("notifications", "whois",
  359. "Whois output", "Where to display /whois output",
  360. whoisOptions, configManager, identity));
  361. category.addSetting(new PreferencesSetting("notifications", "lusers",
  362. "Lusers output", "Where to display /lusers output",
  363. options, configManager, identity));
  364. category.addSetting(new PreferencesSetting("notifications", "map",
  365. "Map output", "Where to display /map output",
  366. mapOptions, configManager, identity));
  367. category.addSetting(new PreferencesSetting("notifications", "away",
  368. "Away notification", "Where to display /away output",
  369. options, configManager, identity));
  370. category.addSetting(new PreferencesSetting("notifications", "back",
  371. "Back notification", "Where to display /away output",
  372. options, configManager, identity));
  373. parent.addSubCategory(category);
  374. }
  375. /**
  376. * Creates and adds the "Advanced" category.
  377. */
  378. private void addAdvancedCategory() {
  379. final PreferencesCategory category = new PreferencesCategory("Advanced",
  380. "", "category-advanced");
  381. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  382. "browser", "uselaunchdelay", "Use browser launch delay",
  383. "Enable delay between browser launches (to prevent mistakenly"
  384. + " double clicking)", configManager, identity));
  385. category.addSetting(new PreferencesSetting(PreferencesType.DURATION,
  386. "browser", "launchdelay", "Browser launch delay",
  387. "Minimum time between opening of URLs if enabled",
  388. configManager, identity));
  389. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  390. "general", "submitErrors", "Automatically submit errors",
  391. "Automatically submit client errors to the developers",
  392. configManager, identity));
  393. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  394. "general", "logerrors", "Log errors to disk",
  395. "Save copies of all client errors to disk",
  396. configManager, identity));
  397. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  398. "ui", "quickCopy", "Quick copy", "Automatically copy"
  399. + " text that's selected when the mouse button is released",
  400. configManager, identity));
  401. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  402. "ui", "showversion", "Show version",
  403. "Show the current DMDirc version in the titlebar",
  404. configManager, identity));
  405. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  406. "general", "showglobalwindow", "Show global window",
  407. "Show a global window which can be used to enter commands",
  408. configManager, identity));
  409. addCategory(category);
  410. }
  411. /**
  412. * Creates and adds the "GUI" category.
  413. */
  414. private void addGuiCategory() {
  415. final PreferencesCategory category = new PreferencesCategory("GUI", "",
  416. "category-gui");
  417. category.addSetting(new PreferencesSetting(PreferencesType.COLOUR,
  418. "ui", "backgroundcolour", "Background colour", "Default "
  419. + "background colour to use", configManager, identity));
  420. category.addSetting(new PreferencesSetting(PreferencesType.COLOUR,
  421. "ui", "foregroundcolour", "Foreground colour", "Default "
  422. + "foreground colour to use", configManager, identity));
  423. category.addSetting(new PreferencesSetting(PreferencesType.OPTIONALCOLOUR,
  424. "ui", "inputbackgroundcolour", "Input background colour",
  425. "Default background colour to use for input fields",
  426. configManager, identity));
  427. category.addSetting(new PreferencesSetting(PreferencesType.OPTIONALCOLOUR,
  428. "ui", "inputforegroundcolour", "Input foreground colour",
  429. "Default foreground colour to use for input fields",
  430. configManager, identity));
  431. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  432. "general", "showcolourdialog", "Show colour dialog",
  433. "Show colour picker dialog when using colour control codes",
  434. configManager, identity));
  435. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  436. "ui", "antialias", "System anti-alias",
  437. "Anti-alias all fonts", configManager, identity).setRestartNeeded());
  438. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  439. "ui", "shownickcoloursintext", "Show nick colours in text area",
  440. "Show nickname colours (if set) in text areas",
  441. configManager, identity));
  442. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  443. "ui", "shownickcoloursinnicklist", "Show nick colours in nicklists",
  444. "Show nickname colours (if set) in channel nicklists",
  445. configManager, identity));
  446. addThemesCategory(category);
  447. addStyleSubCategory(category);
  448. addCategory(category.setInlineAfter());
  449. }
  450. /**
  451. * Creates the Style subcategory in "GUI".
  452. *
  453. * @since 0.6.4
  454. * @param parent Parent category to add this category to
  455. */
  456. private void addStyleSubCategory(final PreferencesCategory parent) {
  457. final PreferencesCategory category = new PreferencesCategory("Link styles"
  458. + " and colours", "");
  459. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  460. "ui", "stylelinks", "Style hyperlinks", "Style hyperlinks in "
  461. + "text areas with underlines", configManager, identity));
  462. category.addSetting(new PreferencesSetting(PreferencesType.OPTIONALCOLOUR,
  463. "ui", "linkcolour", "Hyperlink colour", "Default colour to use "
  464. + "for hyperlinks in the text area", configManager, identity));
  465. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  466. "ui", "stylechannels", "Style channel links", "Styles channel "
  467. + "links in text areas with underlines", configManager, identity));
  468. category.addSetting(new PreferencesSetting(PreferencesType.OPTIONALCOLOUR,
  469. "ui", "channelcolour", "Channel link colour", "Default colour to use "
  470. + "for channel links in the text area", configManager, identity));
  471. parent.addSubCategory(category.setInline());
  472. }
  473. /**
  474. * Creates and adds the "Themes" category.
  475. *
  476. * @param parent The parent category
  477. */
  478. private void addThemesCategory(final PreferencesCategory parent) {
  479. parent.addSubCategory(new PreferencesCategory("Themes", "",
  480. "category-addons", themePanel));
  481. }
  482. /**
  483. * Creates and adds the "Plugins" category.
  484. */
  485. private void addPluginsCategory() {
  486. addCategory(new PreferencesCategory("Plugins", "", "category-addons",
  487. pluginPanel));
  488. }
  489. /**
  490. * Creates and adds the "Updates" category.
  491. */
  492. private void addUpdatesCategory() {
  493. addCategory(new PreferencesCategory("Updates", "", "category-updates",
  494. updatesPanel));
  495. }
  496. /**
  497. * Creates and adds the "URL Handlers" category.
  498. */
  499. private void addUrlHandlerCategory() {
  500. addCategory(new PreferencesCategory("URL Handlers",
  501. "Configure how DMDirc handles different types of URLs",
  502. "category-urlhandlers", urlHandlerPanel));
  503. }
  504. /**
  505. * Registers the specified save listener with this manager.
  506. *
  507. * @param listener The listener to be registered
  508. */
  509. public void registerSaveListener(final PreferencesInterface listener) {
  510. listeners.add(PreferencesInterface.class, listener);
  511. }
  512. /**
  513. * Fires the "save" methods of all registered listeners.
  514. */
  515. public void fireSaveListeners() {
  516. listeners.get(PreferencesInterface.class).forEach(PreferencesInterface::save);
  517. categories.forEach(this::fireSaveListener);
  518. }
  519. /**
  520. * Fires the save listener for any objects within the specified category.
  521. *
  522. * @param category The category to check
  523. */
  524. private void fireSaveListener(final PreferencesCategory category) {
  525. if (category.hasObject()) {
  526. category.getObject().save();
  527. }
  528. category.getSubcats().forEach(this::fireSaveListener);
  529. }
  530. /**
  531. * Fires the CLIENT_PREFS_CLOSED action.
  532. *
  533. * @since 0.6
  534. */
  535. public void close() {
  536. eventBus.publishAsync(new ClientPrefsClosedEvent());
  537. }
  538. }