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.

ProfileEditorDialog.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * Copyright (c) 2006-2007 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.ui.dialogs;
  23. import java.awt.Dimension;
  24. import java.awt.GridBagConstraints;
  25. import java.awt.GridBagLayout;
  26. import java.awt.GridLayout;
  27. import java.awt.event.ActionEvent;
  28. import java.awt.event.ActionListener;
  29. import java.util.List;
  30. import javax.swing.BorderFactory;
  31. import javax.swing.Box;
  32. import javax.swing.DefaultListModel;
  33. import javax.swing.JButton;
  34. import javax.swing.JLabel;
  35. import javax.swing.JList;
  36. import javax.swing.JOptionPane;
  37. import javax.swing.JPanel;
  38. import javax.swing.JScrollPane;
  39. import javax.swing.JTextArea;
  40. import javax.swing.JTextField;
  41. import javax.swing.SpringLayout;
  42. import javax.swing.WindowConstants;
  43. import javax.swing.event.ListSelectionEvent;
  44. import javax.swing.event.ListSelectionListener;
  45. import com.dmdirc.identities.ConfigSource;
  46. import com.dmdirc.identities.Identity;
  47. import com.dmdirc.identities.IdentityManager;
  48. import com.dmdirc.ui.MainFrame;
  49. import com.dmdirc.ui.components.StandardDialog;
  50. import static com.dmdirc.ui.UIUtilities.LARGE_BORDER;
  51. import static com.dmdirc.ui.UIUtilities.SMALL_BORDER;
  52. import static com.dmdirc.ui.UIUtilities.layoutGrid;
  53. /**
  54. * Profile editing dialog.
  55. */
  56. public final class ProfileEditorDialog extends StandardDialog implements
  57. ActionListener, ListSelectionListener {
  58. /**
  59. * A version number for this class. It should be changed whenever the class
  60. * structure is changed (or anything else that would prevent serialized
  61. * objects being unserialized with the new class).
  62. */
  63. private static final long serialVersionUID = 2;
  64. /** Component panel. */
  65. private JPanel panel;
  66. /** profile list. */
  67. private JList profileList;
  68. /** Selected profile index. */
  69. private int selectedProfile;
  70. /** add button. */
  71. private JButton addButton;
  72. /** delete button. */
  73. private JButton deleteButton;
  74. /** rename button. */
  75. private JButton renameButton;
  76. /** revert button. */
  77. private JButton revertButton;
  78. /** info label. */
  79. private JTextArea infoLabel;
  80. /** nickname label. */
  81. private JLabel nicknameLabel;
  82. /** nickname field. */
  83. private JTextField nickname;
  84. /** realname label. */
  85. private JLabel realnameLabel;
  86. /** realname field. */
  87. private JTextField realname;
  88. /** Ident label. */
  89. private JLabel identLabel;
  90. /** Ident field. */
  91. private JTextField ident;
  92. /** Alternate nicknames label. */
  93. private JLabel altNickLabel;
  94. /** Alternate nicknames list. */
  95. private JList altNick;
  96. /** Alternate nicknames button panel. */
  97. private JPanel altNickButtonsPanel;
  98. /** profiles. */
  99. private List<ConfigSource> profiles;
  100. /** Creates a new instance of ProfileEditorDialog. */
  101. public ProfileEditorDialog() {
  102. super(MainFrame.getMainFrame(), false);
  103. profiles = IdentityManager.getProfiles();
  104. initComponents();
  105. layoutComponents();
  106. addCallbacks();
  107. this.setLocationRelativeTo(MainFrame.getMainFrame());
  108. this.setVisible(true);
  109. }
  110. /** Initialises the components of the dialog. */
  111. private void initComponents() {
  112. setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  113. orderButtons(new JButton(), new JButton());
  114. setTitle("Profile Editor");
  115. setMinimumSize(new Dimension(600, 400));
  116. setPreferredSize(new Dimension(600, 400));
  117. panel = new JPanel(new SpringLayout());
  118. panel.setVisible(true);
  119. profileList = new JList(new DefaultListModel());
  120. profileList.setBorder(BorderFactory.createCompoundBorder(
  121. BorderFactory.createEtchedBorder(),
  122. BorderFactory.createEmptyBorder(SMALL_BORDER, SMALL_BORDER,
  123. SMALL_BORDER, SMALL_BORDER)));
  124. populateList();
  125. profileList.setSelectedIndex(0);
  126. selectedProfile = 0;
  127. profileList.setMinimumSize(new Dimension(200, Integer.MAX_VALUE));
  128. profileList.setPreferredSize(new Dimension(200, Integer.MAX_VALUE));
  129. addButton = new JButton("Add");
  130. deleteButton = new JButton("Delete");
  131. renameButton = new JButton("Rename");
  132. infoLabel = new JTextArea("Profiles describe information needed to "
  133. + "connect to a server. You can use a different profile for "
  134. + "each connection. Profiles are automatically saved when you "
  135. + "select another or click OK");
  136. infoLabel.setEditable(false);
  137. infoLabel.setWrapStyleWord(true);
  138. infoLabel.setLineWrap(true);
  139. infoLabel.setHighlighter(null);
  140. infoLabel.setBackground(panel.getBackground());
  141. nicknameLabel = new JLabel("Nickname: ");
  142. nickname = new JTextField();
  143. nickname.setPreferredSize(new Dimension(150, 10));
  144. nickname.setText(profiles.get(0).getOption("profile", "nickname"));
  145. realnameLabel = new JLabel("Realname: ");
  146. realname = new JTextField();
  147. realname.setPreferredSize(new Dimension(150, 10));
  148. realname.setText(profiles.get(0).getOption("profile", "realname"));
  149. identLabel = new JLabel("Ident: ");
  150. ident = new JTextField();
  151. ident.setPreferredSize(new Dimension(150, 10));
  152. ident.setText(profiles.get(0).getOption("profile", "ident"));
  153. altNickLabel = new JLabel("Alt nicknames: ");
  154. altNick = new JList(new DefaultListModel());
  155. altNick.setVisibleRowCount(2);
  156. altNick.setFixedCellHeight(altNick.getFont().getSize());
  157. populateAltNicks(0);
  158. altNickButtonsPanel = new JPanel();
  159. altNickButtonsPanel.setLayout(new GridLayout(1, 3, SMALL_BORDER,
  160. SMALL_BORDER));
  161. JButton button = new JButton("Add");
  162. button.setActionCommand("addAltNick");
  163. button.addActionListener(this);
  164. altNickButtonsPanel.add(button);
  165. button = new JButton("Edit");
  166. button.setActionCommand("editAltNick");
  167. button.addActionListener(this);
  168. altNickButtonsPanel.add(button);
  169. button = new JButton("Delete");
  170. button.setActionCommand("deleteAltNick");
  171. button.addActionListener(this);
  172. altNickButtonsPanel.add(button);
  173. revertButton = new JButton("Revert");
  174. }
  175. /** Lays out the dialog. */
  176. private void layoutComponents() {
  177. final GridBagConstraints constraints = new GridBagConstraints();
  178. getContentPane().setLayout(new GridBagLayout());
  179. panel.add(nicknameLabel);
  180. panel.add(nickname);
  181. panel.add(realnameLabel);
  182. panel.add(realname);
  183. panel.add(identLabel);
  184. panel.add(ident);
  185. panel.add(altNickLabel);
  186. panel.add(new JScrollPane(altNick));
  187. panel.add(Box.createHorizontalBox());
  188. panel.add(altNickButtonsPanel);
  189. panel.add(Box.createHorizontalBox());
  190. panel.add(revertButton);
  191. layoutGrid(panel, 6, 2, LARGE_BORDER, LARGE_BORDER, SMALL_BORDER, SMALL_BORDER);
  192. constraints.weighty = 0.0;
  193. constraints.weightx = 0.0;
  194. constraints.gridx = 0;
  195. constraints.gridy = 0;
  196. constraints.gridwidth = 1;
  197. constraints.gridheight = 3;
  198. constraints.fill = GridBagConstraints.BOTH;
  199. constraints.insets.set(LARGE_BORDER, LARGE_BORDER, LARGE_BORDER, 0);
  200. getContentPane().add(profileList, constraints);
  201. constraints.insets.set(0, LARGE_BORDER, 0, 0);
  202. constraints.gridheight = 1;
  203. constraints.gridy = 4;
  204. getContentPane().add(addButton, constraints);
  205. constraints.gridy = 5;
  206. getContentPane().add(deleteButton, constraints);
  207. constraints.gridy = 6;
  208. constraints.insets.set(0, LARGE_BORDER, LARGE_BORDER, 0);
  209. getContentPane().add(renameButton, constraints);
  210. constraints.weightx = 1.0;
  211. constraints.weighty = 0.0;
  212. constraints.gridx = 1;
  213. constraints.gridy = 0;
  214. constraints.gridheight = 1;
  215. constraints.gridwidth = 2;
  216. constraints.insets.set(LARGE_BORDER, LARGE_BORDER, LARGE_BORDER, 0);
  217. getContentPane().add(infoLabel, constraints);
  218. constraints.weighty = 1.0;
  219. constraints.gridy = 1;
  220. constraints.insets.set(0, SMALL_BORDER, 0, SMALL_BORDER);
  221. getContentPane().add(panel, constraints);
  222. constraints.gridwidth = 1;
  223. constraints.weighty = 0.0;
  224. constraints.gridy = 6;
  225. constraints.insets.set(0, 0, 0, 0);
  226. getContentPane().add(Box.createHorizontalGlue(), constraints);
  227. constraints.gridx = 1;
  228. constraints.weightx = 0.0;
  229. constraints.insets.set(0, LARGE_BORDER, LARGE_BORDER, 0);
  230. constraints.anchor = GridBagConstraints.EAST;
  231. constraints.fill = GridBagConstraints.NONE;
  232. getContentPane().add(getLeftButton(), constraints);
  233. constraints.gridx = 2;
  234. constraints.insets.set(0, LARGE_BORDER, LARGE_BORDER, LARGE_BORDER);
  235. getContentPane().add(getRightButton(), constraints);
  236. pack();
  237. }
  238. /** Adds listeners to various components in the dialog. */
  239. private void addCallbacks() {
  240. getCancelButton().addActionListener(this);
  241. getOkButton().addActionListener(this);
  242. revertButton.addActionListener(this);
  243. renameButton.addActionListener(this);
  244. deleteButton.addActionListener(this);
  245. addButton.addActionListener(this);
  246. profileList.addListSelectionListener(this);
  247. }
  248. /** {@inheritDoc}. */
  249. public void actionPerformed(final ActionEvent event) {
  250. if (event.getSource() == revertButton) {
  251. populateProfile(selectedProfile);
  252. } else if (event.getSource() == addButton) {
  253. final String newName = JOptionPane.showInputDialog(this,
  254. "Please enter the new profile's name", "New profile");
  255. if (newName != null && !"".equals(newName)) {
  256. final Identity newIdentity = Identity.buildProfile(newName);
  257. profiles = IdentityManager.getProfiles();
  258. populateList();
  259. selectedProfile = profiles.indexOf(newIdentity);
  260. populateProfile(selectedProfile);
  261. profileList.repaint();
  262. }
  263. } else if (event.getSource() == deleteButton) {
  264. final int response = JOptionPane.showConfirmDialog(this,
  265. "Are you sure you want to delete this profile?",
  266. "Delete confirmaton", JOptionPane.YES_NO_OPTION);
  267. if (response == JOptionPane.YES_OPTION) {
  268. final Identity oldIdentity =
  269. (Identity) profiles.get(profileList.getSelectedIndex());
  270. oldIdentity.delete();
  271. profiles = IdentityManager.getProfiles();
  272. populateList();
  273. selectedProfile = profiles.indexOf(oldIdentity);
  274. selectedProfile--;
  275. if (selectedProfile < 0) {
  276. selectedProfile = 0;
  277. }
  278. populateProfile(selectedProfile);
  279. profileList.repaint();
  280. }
  281. } else if (event.getSource() == renameButton) {
  282. final String newName = JOptionPane.showInputDialog(this,
  283. "Please enter the new name for the profile",
  284. profileList.getSelectedValue());
  285. if (newName != null && !"".equals(newName)) {
  286. profiles.get(profileList.getSelectedIndex()).setOption("identity", "name", newName);
  287. profileList.repaint();
  288. }
  289. } else if ("addAltNick".equals(event.getActionCommand())) {
  290. final String newName = JOptionPane.showInputDialog(this,
  291. "Please enter the new nickname", "New alt nickname");
  292. if (newName != null && !"".equals(newName)) {
  293. ((DefaultListModel) altNick.getModel()).addElement(newName);
  294. }
  295. } else if ("editAltNick".equals(event.getActionCommand())) {
  296. if (altNick.getSelectedIndex() != -1) {
  297. final String newName = JOptionPane.showInputDialog(this,
  298. "Please enter the nickname for the alt nickname",
  299. altNick.getSelectedValue());
  300. if (newName != null && !"".equals(newName)) {
  301. ((DefaultListModel) altNick.getModel()).setElementAt(newName, altNick.getSelectedIndex());
  302. }
  303. }
  304. } else if ("deleteAltNick".equals(event.getActionCommand())) {
  305. if (altNick.getSelectedIndex() != -1) {
  306. final int response = JOptionPane.showConfirmDialog(this,
  307. "Are you sure you want to delete this nick?",
  308. "Delete confirmaton", JOptionPane.YES_NO_OPTION);
  309. if (response == JOptionPane.YES_OPTION) {
  310. ((DefaultListModel) altNick.getModel()).removeElementAt(altNick.getSelectedIndex());
  311. }
  312. }
  313. } else if (event.getSource() == getOkButton()) {
  314. saveProfile(selectedProfile);
  315. NewServerDialog.getNewServerDialog().populateProfiles();
  316. this.dispose();
  317. } else if (event.getSource() == getCancelButton()) {
  318. NewServerDialog.getNewServerDialog().populateProfiles();
  319. this.dispose();
  320. }
  321. }
  322. /** {@inheritDoc}. */
  323. public void valueChanged(final ListSelectionEvent selectionEvent) {
  324. if (!selectionEvent.getValueIsAdjusting()) {
  325. final int selected = ((JList) selectionEvent.getSource()).getSelectedIndex();
  326. if (selected >= 0) {
  327. saveProfile(selectedProfile);
  328. populateProfile(selected);
  329. }
  330. selectedProfile = selected;
  331. }
  332. }
  333. /** Populates the identity list with identities from the identity manager. */
  334. private void populateList() {
  335. ((DefaultListModel) profileList.getModel()).clear();
  336. for (ConfigSource profile : profiles) {
  337. ((DefaultListModel) profileList.getModel()).addElement(profile);
  338. }
  339. }
  340. /**
  341. * Sets the profile options for the given index.
  342. *
  343. * @param index profile number to populate
  344. */
  345. private void populateProfile(final int index) {
  346. final ConfigSource profile = profiles.get(index);
  347. nickname.setText(profile.getOption("profile", "nickname"));
  348. realname.setText(profile.getOption("profile", "realname"));
  349. ident.setText(profile.getOption("profile", "ident"));
  350. populateAltNicks(index);
  351. }
  352. /**
  353. * Saves the profile options for the given index.
  354. *
  355. * @param index profile number to save
  356. */
  357. private void saveProfile(final int index) {
  358. StringBuffer altNicks;
  359. final ConfigSource profile = profiles.get(index);
  360. profile.setOption("profile", "nickname", nickname.getText());
  361. profile.setOption("profile", "realname", realname.getText());
  362. profile.setOption("profile", "ident", ident.getText());
  363. altNicks = new StringBuffer();
  364. for (int i = 0; i < altNick.getModel().getSize(); i++) {
  365. altNicks.append(altNick.getModel().getElementAt(i)).append('\n');
  366. }
  367. profile.setOption("profile", "altnicks", altNicks.toString().trim());
  368. }
  369. /**
  370. * Populates the alternate nick list.
  371. *
  372. * @param index profile number to populate from
  373. */
  374. private void populateAltNicks(final int index) {
  375. String[] altNicks;
  376. ((DefaultListModel) altNick.getModel()).clear();
  377. if (profiles.get(index).getOption("profile", "altnicks") != null
  378. && profiles.get(index).getOption("profile", "altnicks").length() != 0) {
  379. altNicks = profiles.get(index).getOption("profile", "altnicks").split("\\n");
  380. for (String altNickname : altNicks) {
  381. ((DefaultListModel) altNick.getModel()).addElement(altNickname);
  382. }
  383. }
  384. altNick.repaint();
  385. }
  386. }