Browse Source

Issue 391: Profile manager should cache data (Complete profile manager rewrite)

git-svn-id: http://svn.dmdirc.com/trunk@2446 00569f92-eb28-0410-84fd-f71c24880f
tags/0.5.5
Gregory Holmes 16 years ago
parent
commit
d362054a4a

BIN
src/com/dmdirc/res/nothing.png View File


+ 2
- 2
src/com/dmdirc/ui/swing/MainFrame.java View File

@@ -44,10 +44,10 @@ import com.dmdirc.ui.swing.components.SwingStatusBar;
44 44
 import com.dmdirc.ui.swing.dialogs.NewServerDialog;
45 45
 import com.dmdirc.ui.swing.dialogs.PluginDialog;
46 46
 import com.dmdirc.ui.swing.dialogs.PreferencesDialog;
47
-import com.dmdirc.ui.swing.dialogs.ProfileEditorDialog;
48 47
 import com.dmdirc.ui.swing.dialogs.about.AboutDialog;
49 48
 import com.dmdirc.ui.swing.dialogs.actionseditor.ActionsManagerDialog;
50 49
 import com.dmdirc.ui.swing.dialogs.aliases.AliasManagerDialog;
50
+import com.dmdirc.ui.swing.dialogs.profiles.ProfileManagerDialog;
51 51
 import com.dmdirc.ui.swing.framemanager.MainFrameManager;
52 52
 import static com.dmdirc.ui.swing.UIUtilities.SMALL_BORDER;
53 53
 
@@ -915,7 +915,7 @@ public final class MainFrame extends JFrame implements WindowListener,
915 915
         if (e.getActionCommand().equals("About")) {
916 916
             AboutDialog.showAboutDialog();
917 917
         } else if (e.getActionCommand().equals("Profile")) {
918
-            ProfileEditorDialog.showProfileEditorDialog();
918
+            ProfileManagerDialog.showProfileManagerDialog();
919 919
         } else if (e.getActionCommand().equals("Exit")) {
920 920
             quit();
921 921
         } else if (e.getActionCommand().equals("ManagePlugins")) {

+ 0
- 5
src/com/dmdirc/ui/swing/UIUtilities.java View File

@@ -26,22 +26,17 @@ import com.dmdirc.ui.swing.actions.RedoAction;
26 26
 import com.dmdirc.ui.swing.actions.UndoAction;
27 27
 import com.dmdirc.ui.swing.components.DMDircUndoableEditListener;
28 28
 
29
-import java.awt.Color;
30 29
 import java.awt.Component;
31 30
 import java.awt.Container;
32 31
 import java.awt.Dimension;
33
-import java.awt.Font;
34
-import java.awt.Insets;
35 32
 
36 33
 import javax.swing.BorderFactory;
37
-import javax.swing.JLabel;
38 34
 import javax.swing.KeyStroke;
39 35
 import javax.swing.Spring;
40 36
 import javax.swing.SpringLayout;
41 37
 import javax.swing.UIManager;
42 38
 import javax.swing.UIManager.LookAndFeelInfo;
43 39
 import javax.swing.UnsupportedLookAndFeelException;
44
-import javax.swing.plaf.FontUIResource;
45 40
 import javax.swing.text.JTextComponent;
46 41
 import javax.swing.undo.UndoManager;
47 42
 

+ 22
- 1
src/com/dmdirc/ui/swing/components/ImageButton.java View File

@@ -39,7 +39,17 @@ public class ImageButton extends JButton {
39 39
      * structure is changed (or anything else that would prevent serialized
40 40
      * objects being unserialized with the new class).
41 41
      */
42
-    private static final long serialVersionUID = 1;
42
+    private static final long serialVersionUID = 2;
43
+    
44
+    /**
45
+     * Creates a new instance of ImageButton.
46
+     *
47
+     * @param actionCommand Action command for the button
48
+     * @param icon Normal icon for the button
49
+     */
50
+    public ImageButton(final String actionCommand, final Icon icon) {
51
+        this(actionCommand, icon, icon);
52
+    }
43 53
     
44 54
     /**
45 55
      * Creates a new instance of ImageButton.
@@ -74,4 +84,15 @@ public class ImageButton extends JButton {
74 84
         setPreferredSize(new Dimension(16, 0));
75 85
         setActionCommand(actionCommand);
76 86
     }
87
+    
88
+    /**
89
+     * Sets all the image buttons icons
90
+     * 
91
+     * @param icon New icon
92
+     */
93
+    public void setIcons(final Icon icon) {
94
+        setIcon(icon);
95
+        setRolloverIcon(icon);
96
+        setPressedIcon(icon);
97
+    }
77 98
 }

+ 387
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/Profile.java View File

@@ -0,0 +1,387 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+import com.dmdirc.config.Identity;
26
+import com.dmdirc.config.IdentityManager;
27
+
28
+import java.util.ArrayList;
29
+import java.util.List;
30
+
31
+/** Profile wrapper class. */
32
+public class Profile {
33
+
34
+    /** Name. */
35
+    private String name;
36
+    /** Nickname. */
37
+    private String nickname;
38
+    /** Real name. */
39
+    private String realname;
40
+    /** Ident. */
41
+    private String ident;
42
+    /** Alternate nicknames. */
43
+    private List<String> altNicknames;
44
+    /** Does this profile need saving? */
45
+    private boolean modified;
46
+
47
+    /** Creates a new profile. */
48
+    public Profile() {
49
+        this("");
50
+    }
51
+    
52
+    /**
53
+     * Creates a new profile.
54
+     *
55
+     * @param name Profile's name
56
+     */
57
+    public Profile(final String name) {
58
+        this(name, "");
59
+    }
60
+
61
+    /**
62
+     * Creates a new profile.
63
+     *
64
+     * @param name Profile's name
65
+     * @param nickname Profile's nickname
66
+     */
67
+    public Profile(final String name, final String nickname) {
68
+        this(name, nickname, "");
69
+    }
70
+
71
+    /**
72
+     *
73
+     *
74
+     * @param name Profile's name
75
+     * @param nickname Profile's nickname
76
+     * @param realname Profile's realname
77
+     */
78
+    public Profile(final String name, final String nickname,
79
+            final String realname) {
80
+        this(name, nickname, realname, "");
81
+    }
82
+
83
+    /**
84
+     * Creates a new profile.
85
+     *
86
+     * @param name Profile's name
87
+     * @param nickname Profile's nickname
88
+     * @param realname Profile's realname
89
+     * @param ident Profile's ident
90
+     */
91
+    public Profile(final String name, final String nickname,
92
+            final String realname, final String ident) {
93
+        this(name, nickname, realname, ident,
94
+                new ArrayList<String>());
95
+    }
96
+
97
+    /**
98
+     * Creates a new profile.
99
+     *
100
+     * @param name Profile's name
101
+     * @param nickname Profile's nickname
102
+     * @param realname Profile's realname
103
+     * @param ident Profile's ident
104
+     * @param altNicknames Profile's alternate nicknames list
105
+     */
106
+    public Profile(final String name, final String nickname,
107
+            final String realname, final String ident,
108
+            final List<String> altNicknames) {
109
+        this(name, nickname, realname, ident, altNicknames, true);
110
+    }
111
+
112
+    /**
113
+     * Creates a new profile.
114
+     *
115
+     * @param name Profile's name
116
+     * @param nickname Profile's nickname
117
+     * @param realname Profile's realname
118
+     * @param ident Profile's ident
119
+     * @param altNicknames Profile's alternate nicknames list
120
+     * @param modified Has this profile been modified
121
+     */
122
+    public Profile(final String name, final String nickname,
123
+            final String realname, final String ident,
124
+            final List<String> altNicknames, final boolean modified) {
125
+        this.name = name;
126
+        this.nickname = nickname;
127
+        this.realname = realname;
128
+        this.ident = ident;
129
+        this.altNicknames = altNicknames;
130
+        this.modified = modified;
131
+    }
132
+
133
+    /**
134
+     * Returns the name of this profile.
135
+     *
136
+     * @return Profile's name
137
+     */
138
+    public String getName() {
139
+        return name;
140
+    }
141
+
142
+    /**
143
+     * Sets the name of this profile.
144
+     *
145
+     * @param name Profile's new name
146
+     */
147
+    public void setName(final String name) {
148
+        if (!this.name.equals(name)) {
149
+            this.name = name;
150
+            setModified(true);
151
+        }
152
+    }
153
+
154
+    /**
155
+     * Gets the main nickname for this profile.
156
+     *
157
+     * @return Profile's nickname
158
+     */
159
+    public String getNickname() {
160
+        return nickname;
161
+    }
162
+
163
+    /**
164
+     * Sets the main nickname for this profile.
165
+     *
166
+     * @param nickname Profile's new nickname
167
+     */
168
+    public void setNickname(final String nickname) {
169
+        if (!this.nickname.equals(nickname)) {
170
+            this.nickname = nickname;
171
+            setModified(true);
172
+        }
173
+    }
174
+
175
+    /**
176
+     * Gets the realname for this profile.
177
+     *
178
+     * @return Profile's realname
179
+     */
180
+    public String getRealname() {
181
+        return realname;
182
+    }
183
+
184
+    /**
185
+     * Sets the realname for this profile.
186
+     *
187
+     * @param realname Profile's new realname
188
+     */
189
+    public void setRealname(final String realname) {
190
+        if (!this.realname.equals(realname)) {
191
+            this.realname = realname;
192
+            setModified(true);
193
+        }
194
+    }
195
+
196
+    /**
197
+     * Gets the ident for this profile.
198
+     *
199
+     * @return Profile's ident
200
+     */
201
+    public String getIdent() {
202
+        return ident;
203
+    }
204
+
205
+    /**
206
+     * Sets the ident for this profile.
207
+     *
208
+     * @param ident Profile's new ident
209
+     */
210
+    public void setIdent(final String ident) {
211
+        if (!this.ident.equals(ident)) {
212
+            this.ident = ident;
213
+            setModified(true);
214
+        }
215
+    }
216
+
217
+    /**
218
+     * Gets the alternate nicknames list for this profile.
219
+     *
220
+     * @return Profile's alternate nicknames list
221
+     */
222
+    public List<String> getAltNicknames() {
223
+        return altNicknames;
224
+    }
225
+
226
+    /**
227
+     * Sets the alternate nicknames list for this profile.
228
+     *
229
+     * @param altNicknames Profile's new alternate nicknames list
230
+     */
231
+    public void setAltNicknames(final List<String> altNicknames) {
232
+        if (!this.altNicknames.equals(altNicknames)) {
233
+            this.altNicknames = altNicknames;
234
+            setModified(true);
235
+        }
236
+    }
237
+
238
+    /**
239
+     * Adds an alternate nickname to this profile.
240
+     *
241
+     * @param altNickname A new alternate nickname for the profile
242
+     */
243
+    public void addAltNickname(final String altNickname) {
244
+        if (!altNicknames.contains(altNickname)) {
245
+            altNicknames.add(altNickname);
246
+            setModified(true);
247
+        }
248
+    }
249
+
250
+    /**
251
+     * Adds an alternate nickname to this profile.
252
+     *
253
+     * @param altNickname A new alternate nickname for the profile
254
+     * @param position Position for the new alternate nickname
255
+     */
256
+    public void addAltNickname(final String altNickname, final int position) {
257
+        if (!altNicknames.contains(altNickname)) {
258
+            altNicknames.add(position, altNickname);
259
+            setModified(true);
260
+        }
261
+    }
262
+
263
+    /**
264
+     * Deletes an alternate nickname from this profile.
265
+     *
266
+     * @param altNickname An existing alternate nickname for the profile
267
+     */
268
+    public void delAltNickname(final String altNickname) {
269
+        if (altNicknames.remove(altNickname)) {
270
+            setModified(true);
271
+        }
272
+    }
273
+
274
+    /**
275
+     * Has this profile been modified?
276
+     *
277
+     * @return true iif the profile has been modified
278
+     */
279
+    public boolean isModified() {
280
+        return modified;
281
+    }
282
+
283
+    /**
284
+     * Sets whether the profile has been modified.
285
+     *
286
+     * @param modified Modified state for the profile
287
+     */
288
+    public void setModified(final boolean modified) {
289
+        this.modified = modified;
290
+    }
291
+
292
+    /** Saves this profile. */
293
+    public void save() {
294
+        if (modified) {
295
+            final String profileString = "profile";
296
+            final List<Identity> identities = IdentityManager.getProfiles();
297
+            Identity profile = null;
298
+
299
+            for (Identity identity : identities) {
300
+                if (identity.getName().equals(name)) {
301
+                    profile = identity;
302
+                    break;
303
+                }
304
+            }
305
+
306
+            if (profile == null) {
307
+                profile = Identity.buildProfile(name);
308
+            }
309
+
310
+            if (!profile.getName().equals(name)) {
311
+                profile.setOption("identity", "name", name);
312
+            }
313
+            profile.setOption(profileString, "nickname", nickname);
314
+            profile.setOption(profileString, "realname", realname);
315
+            profile.setOption(profileString, "ident", ident);
316
+            profile.setOption(profileString, "altnicks", altNicknames);
317
+        }
318
+    }
319
+
320
+    /** {@inheritDoc} */
321
+    @Override
322
+    public boolean equals(final Object obj) {
323
+        if (obj == null) {
324
+            return false;
325
+        }
326
+        if (getClass() != obj.getClass()) {
327
+            return false;
328
+        }
329
+
330
+        final Profile other = (Profile) obj;
331
+
332
+        if (!this.name.equals(other.name) &&
333
+                (this.name == null || !this.name.equals(other.name))) {
334
+            return false;
335
+        }
336
+        if (!this.nickname.equals(other.nickname) &&
337
+                (this.nickname == null || !this.nickname.equals(other.nickname))) {
338
+            return false;
339
+        }
340
+        if (!this.realname.equals(other.realname) &&
341
+                (this.realname == null || !this.realname.equals(other.realname))) {
342
+            return false;
343
+        }
344
+        if (!this.ident.equals(other.ident) &&
345
+                (this.ident == null || !this.ident.equals(other.ident))) {
346
+            return false;
347
+        }
348
+        if (this.altNicknames != other.altNicknames &&
349
+                (this.altNicknames == null ||
350
+                !this.altNicknames.equals(other.altNicknames))) {
351
+            return false;
352
+        }
353
+
354
+        return true;
355
+    }
356
+
357
+    /** {@inheritDoc} */
358
+    @Override
359
+    public int hashCode() {
360
+        int hash = 5;
361
+        hash = 79 * hash + (this.name != null ? this.name.hashCode() : 0);
362
+        hash =  79 * hash +
363
+                (this.nickname != null ? this.nickname.hashCode() : 0);
364
+        hash =  79 * hash +
365
+                (this.realname != null ? this.realname.hashCode() : 0);
366
+        hash = 79 * hash + (this.ident != null ? this.ident.hashCode() : 0);
367
+        hash =  79 * hash +
368
+                (this.altNicknames != null ? this.altNicknames.hashCode() : 0);
369
+
370
+        return hash;
371
+    }
372
+
373
+    /** {@inheritDoc} */
374
+    @Override
375
+    protected Object clone() throws CloneNotSupportedException {
376
+        throw new CloneNotSupportedException();
377
+    }
378
+
379
+    /** {@inheritDoc} */
380
+    @Override
381
+    public String toString() {
382
+        return "[Profile: name='" + name + "', nickname='" + nickname +
383
+                "', realname='" + realname + "', ident='" + ident +
384
+                "', altNicknames='" + altNicknames + "', modified='" +
385
+                modified + "']";
386
+    }
387
+}

+ 536
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/ProfileDetailPanel.java View File

@@ -0,0 +1,536 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+import com.dmdirc.IconManager;
26
+import com.dmdirc.ui.swing.components.ImageButton;
27
+import static com.dmdirc.ui.swing.UIUtilities.layoutGrid;
28
+import static com.dmdirc.ui.swing.UIUtilities.SMALL_BORDER;
29
+
30
+import java.awt.Component;
31
+import java.awt.Dimension;
32
+import java.awt.GridLayout;
33
+import java.awt.event.ActionEvent;
34
+import java.awt.event.ActionListener;
35
+import java.util.ArrayList;
36
+import java.util.Enumeration;
37
+import java.util.HashMap;
38
+import java.util.Map;
39
+
40
+import javax.swing.Box;
41
+import javax.swing.DefaultListModel;
42
+import javax.swing.Icon;
43
+import javax.swing.JButton;
44
+import javax.swing.JLabel;
45
+import javax.swing.JList;
46
+import javax.swing.JOptionPane;
47
+import javax.swing.JPanel;
48
+import javax.swing.JScrollPane;
49
+import javax.swing.JTextField;
50
+import javax.swing.SpringLayout;
51
+import javax.swing.event.DocumentEvent;
52
+import javax.swing.event.DocumentListener;
53
+import javax.swing.event.ListDataEvent;
54
+import javax.swing.event.ListDataListener;
55
+import javax.swing.event.ListSelectionEvent;
56
+import javax.swing.event.ListSelectionListener;
57
+import javax.swing.text.Document;
58
+
59
+/** Profile detail panel. */
60
+public class ProfileDetailPanel extends JPanel implements ActionListener,
61
+        ListSelectionListener, DocumentListener,
62
+        ListDataListener {
63
+
64
+    /**
65
+     * A version number for this class. It should be changed whenever the class
66
+     * structure is changed (or anything else that would prevent serialized
67
+     * objects being unserialized with the new class).
68
+     */
69
+    private static final long serialVersionUID = 1;
70
+    /** Invalid filename characters. */
71
+    private static final String FILENAME_REGEX = ".*[\\a\\f\\n\\r\\t\\v#&/\\\\s].*";
72
+    /** Invalid nickname characters. */
73
+    private static final String NICKNAME_REGEX = ".*[\\a\\f\\n\\r\\t\\v\\s].*";
74
+    /** Invalid ident characters. */
75
+    private static final String IDENT_REGEX = ".*[\\a\\f\\n\\r\\t\\v\\s].*";
76
+    /** Displayed profile. */
77
+    private Profile profile;
78
+    /** Name text field. */
79
+    private JTextField name;
80
+    /** Nick name text field. */
81
+    private JTextField nickname;
82
+    /** Realname text field. */
83
+    private JTextField realname;
84
+    /** Ident text field. */
85
+    private JTextField ident;
86
+    /** Alternate nicknames list. */
87
+    private JList altNicknames;
88
+    /** Buttons panel. */
89
+    private JPanel buttonsPanel;
90
+    /** Add button. */
91
+    private JButton addButton;
92
+    /** Delete button. */
93
+    private JButton delButton;
94
+    /** Edit button. */
95
+    private JButton editButton;
96
+    /** name error. */
97
+    private ImageButton nameError;
98
+    /** nick error. */
99
+    private ImageButton nicknameError;
100
+    /** real name error. */
101
+    private ImageButton realnameError;
102
+    /** ident error. */
103
+    private ImageButton identError;
104
+    /** Alt nicknames error. */
105
+    private ImageButton altNicknamesError;
106
+    /** Document -> Component map. */
107
+    private Map<Document, Component> map;
108
+    /** Error icon. */
109
+    private Icon errorIcon;
110
+    /** Warning icon. */
111
+    private Icon warningIcon;
112
+    /** Transparent icon. */
113
+    private Icon normalIcon;
114
+
115
+    /** Creates a new profile detail panel. */
116
+    public ProfileDetailPanel() {
117
+        initMainComponents();
118
+        initButtonsPanel();
119
+        layoutComponents();
120
+
121
+        clearProfile();
122
+    }
123
+
124
+    /** Initialises the components in the main panel. */
125
+    private void initMainComponents() {
126
+        map =   new HashMap<Document, Component>();
127
+
128
+        errorIcon =
129
+                IconManager.getIconManager().getIcon("input-error");
130
+        warningIcon = IconManager.getIconManager().getIcon("warning");
131
+        normalIcon = IconManager.getIconManager().getIcon("nothing");
132
+
133
+        name = new JTextField();
134
+        nickname = new JTextField();
135
+        realname = new JTextField();
136
+        ident = new JTextField();
137
+        altNicknames = new JList(new DefaultListModel());
138
+
139
+        nameError =
140
+                new ImageButton("nicknameError", normalIcon);
141
+        nicknameError =
142
+                new ImageButton("nicknameError", normalIcon);
143
+        realnameError =
144
+                new ImageButton("realnameError", normalIcon);
145
+        identError = new ImageButton("identError", normalIcon);
146
+        altNicknamesError =
147
+                new ImageButton("altNicknamesError", normalIcon);
148
+
149
+        nameError.setFocusable(false);
150
+        nicknameError.setFocusable(false);
151
+        realnameError.setFocusable(false);
152
+        identError.setFocusable(false);
153
+        altNicknamesError.setFocusable(false);
154
+
155
+        map.put(name.getDocument(), nameError);
156
+        map.put(nickname.getDocument(), nicknameError);
157
+        map.put(realname.getDocument(), realnameError);
158
+        map.put(ident.getDocument(), identError);
159
+
160
+        name.setPreferredSize(new Dimension(0, name.getFont().getSize()));
161
+        nickname.setPreferredSize(new Dimension(0, nickname.getFont().getSize()));
162
+        realname.setPreferredSize(new Dimension(0, nickname.getFont().getSize()));
163
+        ident.setPreferredSize(new Dimension(0, nickname.getFont().getSize()));
164
+        altNicknames.setVisibleRowCount(3);
165
+
166
+        name.getDocument().addDocumentListener(this);
167
+        nickname.getDocument().addDocumentListener(this);
168
+        realname.getDocument().addDocumentListener(this);
169
+        ident.getDocument().addDocumentListener(this);
170
+        altNicknames.addListSelectionListener(this);
171
+        altNicknames.getModel().addListDataListener(this);
172
+    }
173
+
174
+    /** Initialiases the components in the buttons panel. */
175
+    private void initButtonsPanel() {
176
+        buttonsPanel =
177
+                new JPanel(new GridLayout(1, 3, SMALL_BORDER, SMALL_BORDER));
178
+        addButton = new JButton("Add");
179
+        delButton = new JButton("Delete");
180
+        editButton = new JButton("Edit");
181
+
182
+        addButton.addActionListener(this);
183
+        delButton.addActionListener(this);
184
+        editButton.addActionListener(this);
185
+    }
186
+
187
+    /** Lays out the components in the panel. */
188
+    private void layoutComponents() {
189
+        buttonsPanel.add(addButton);
190
+        buttonsPanel.add(editButton);
191
+        buttonsPanel.add(delButton);
192
+
193
+        setLayout(new SpringLayout());
194
+
195
+        add(new JLabel("Name:"));
196
+        add(nameError);
197
+        add(name);
198
+
199
+        add(new JLabel("Nickname:"));
200
+        add(nicknameError);
201
+        add(nickname);
202
+
203
+        add(new JLabel("Realname:"));
204
+        add(realnameError);
205
+        add(realname);
206
+
207
+        add(new JLabel("Ident:"));
208
+        add(identError);
209
+        add(ident);
210
+
211
+        add(new JLabel("Alternate nicknames:"));
212
+        add(altNicknamesError);
213
+        add(new JScrollPane(altNicknames));
214
+
215
+        add(Box.createHorizontalGlue());
216
+        add(Box.createHorizontalGlue());
217
+        add(buttonsPanel);
218
+
219
+        layoutGrid(this, 6, 3, SMALL_BORDER, SMALL_BORDER, SMALL_BORDER,
220
+                SMALL_BORDER);
221
+    }
222
+
223
+    /**
224
+     * Sets the profile for the detail panel.
225
+     *
226
+     * @param profile new Profile for the detail panel
227
+     */
228
+    public void setProfile(final Profile profile) {
229
+        this.profile = profile;
230
+
231
+        updateProfile();
232
+    }
233
+
234
+    /** Updates this detail panel. */
235
+    public void updateProfile() {
236
+        if (profile == null) {
237
+            clearProfile();
238
+            return;
239
+        }
240
+        name.setEnabled(true);
241
+        nickname.setEnabled(true);
242
+        realname.setEnabled(true);
243
+        ident.setEnabled(true);
244
+        altNicknames.setEnabled(true);
245
+        addButton.setEnabled(true);
246
+
247
+        name.setText(profile.getName());
248
+        nickname.setText(profile.getNickname());
249
+        realname.setText(profile.getRealname());
250
+        ident.setText(profile.getIdent());
251
+
252
+        ((DefaultListModel) altNicknames.getModel()).clear();
253
+        for (String altNick : profile.getAltNicknames()) {
254
+            ((DefaultListModel) altNicknames.getModel()).addElement(altNick);
255
+        }
256
+    }
257
+
258
+    /** Clears this detail panel. */
259
+    public void clearProfile() {
260
+        name.setText("");
261
+        nickname.setText("");
262
+        realname.setText("");
263
+        ident.setText("");
264
+        ((DefaultListModel) altNicknames.getModel()).clear();
265
+
266
+        name.setEnabled(false);
267
+        nickname.setEnabled(false);
268
+        realname.setEnabled(false);
269
+        ident.setEnabled(false);
270
+        altNicknames.setEnabled(false);
271
+        addButton.setEnabled(false);
272
+        delButton.setEnabled(false);
273
+        editButton.setEnabled(false);
274
+    }
275
+
276
+    /** Saves the detail panels details to the profile. */
277
+    public void save() {
278
+        if (profile == null) {
279
+            return;
280
+        }
281
+
282
+        profile.setName(name.getText());
283
+        profile.setNickname(nickname.getText());
284
+        profile.setRealname(realname.getText());
285
+        profile.setIdent(ident.getText());
286
+        profile.setAltNicknames(new ArrayList<String>());
287
+        final Enumeration<?> enumeration =
288
+                ((DefaultListModel) altNicknames.getModel()).elements();
289
+        while (enumeration.hasMoreElements()) {
290
+            profile.addAltNickname((String) enumeration.nextElement());
291
+        }
292
+    }
293
+
294
+    /**
295
+     * Validates the current details.
296
+     *
297
+     * @return Validation Result
298
+     */
299
+    public ValidationResult validateDetails() {
300
+        nameError.setToolTipText("");
301
+        nicknameError.setToolTipText("");
302
+        realnameError.setToolTipText("");
303
+        identError.setToolTipText("");
304
+        altNicknamesError.setToolTipText("");
305
+        
306
+        nameError.setIcons(normalIcon);
307
+        nicknameError.setIcons(normalIcon);
308
+        realnameError.setIcons(normalIcon);
309
+        identError.setIcons(normalIcon);
310
+        altNicknamesError.setIcons(normalIcon);
311
+
312
+        final ValidationResult checkAltNicknames = checkAltNicknames();
313
+        final ValidationResult checkIdent = checkIdent();
314
+        final ValidationResult checkRealname = checkRealname();
315
+        final ValidationResult checkNickname = checkNickname();
316
+        final ValidationResult checkName = checkName();
317
+
318
+        if (checkAltNicknames.equals(ValidationResult.FAIL) ||
319
+                checkIdent.equals(ValidationResult.FAIL) ||
320
+                checkRealname.equals(ValidationResult.FAIL) ||
321
+                checkNickname.equals(ValidationResult.FAIL) || 
322
+                checkName.equals(ValidationResult.FAIL)) {
323
+            return ValidationResult.FAIL;
324
+        } else if (checkAltNicknames.equals(ValidationResult.WARNING) ||
325
+                checkIdent.equals(ValidationResult.WARNING) ||
326
+                checkRealname.equals(ValidationResult.WARNING) ||
327
+                checkNickname.equals(ValidationResult.WARNING) ||
328
+                checkName.equals(ValidationResult.WARNING)) {
329
+            return ValidationResult.WARNING;
330
+        } else {
331
+            return ValidationResult.PASS;
332
+        }
333
+    }
334
+
335
+    /**
336
+     * Validates the alternate nicknames.
337
+     *
338
+     * @return Validation result
339
+     */
340
+    private ValidationResult checkAltNicknames() {
341
+        if (altNicknames.getModel().getSize() == 0) {
342
+            altNicknamesError.setIcons(errorIcon);
343
+            addButton.requestFocus();
344
+            altNicknamesError.setToolTipText("You must specify at least one alternate nickname.");
345
+            return ValidationResult.FAIL;
346
+        }
347
+
348
+        ValidationResult returnValue =
349
+                ValidationResult.PASS;
350
+        final Enumeration<?> enumeration =
351
+                ((DefaultListModel) altNicknames.getModel()).elements();
352
+        while (enumeration.hasMoreElements()) {
353
+            final String altNickname =
354
+                    (String) enumeration.nextElement();
355
+            if (altNickname.isEmpty() || altNickname.matches(NICKNAME_REGEX)) {
356
+                altNicknamesError.setIcons(errorIcon);
357
+                altNicknamesError.setToolTipText("Your nickname cannot be blank.");
358
+                return ValidationResult.FAIL;
359
+            } else if (altNickname.length() <= 1 || altNickname.length() > 9) {
360
+                altNicknamesError.setIcons(warningIcon);
361
+                returnValue =
362
+                        ValidationResult.WARNING;
363
+                altNicknamesError.setToolTipText("Some servers may not accept this nickname.");
364
+            }
365
+        }
366
+
367
+        return returnValue;
368
+    }
369
+
370
+    /**
371
+     * Validates the ident.
372
+     *
373
+     * @return Validation result
374
+     */
375
+    private ValidationResult checkIdent() {
376
+        ValidationResult returnValue =
377
+                ValidationResult.PASS;
378
+        final String identText = ident.getText();
379
+
380
+        if (identText.isEmpty() || identText.matches(IDENT_REGEX)) {
381
+            identError.setIcons(errorIcon);
382
+            ident.requestFocus();
383
+            returnValue =
384
+                    ValidationResult.FAIL;
385
+            identError.setToolTipText("Your ident cannot be blank.");
386
+        }
387
+
388
+        return returnValue;
389
+    }
390
+
391
+    /**
392
+     * Validates the realname.
393
+     *
394
+     * @return Validation result
395
+     */
396
+    private ValidationResult checkRealname() {
397
+        ValidationResult returnValue =
398
+                ValidationResult.PASS;
399
+        final String realnameText = realname.getText();
400
+
401
+        if (realnameText.isEmpty()) {
402
+            realnameError.setIcons(errorIcon);
403
+            realname.requestFocus();
404
+            returnValue =
405
+                    ValidationResult.FAIL;
406
+            realnameError.setToolTipText("Your realname cannot be blank.");
407
+        }
408
+
409
+        return returnValue;
410
+    }
411
+
412
+    /**
413
+     * Validates the nickname.
414
+     *
415
+     * @return Validation result
416
+     */
417
+    private ValidationResult checkNickname() {
418
+        ValidationResult returnValue =
419
+                ValidationResult.PASS;
420
+        final String nicknameText = nickname.getText();
421
+
422
+        if (nicknameText.isEmpty() || nicknameText.matches(NICKNAME_REGEX)) {
423
+            nicknameError.setIcons(errorIcon);
424
+            nickname.requestFocus();
425
+            returnValue =
426
+                    ValidationResult.FAIL;
427
+            nicknameError.setToolTipText("Your nickname cannot be blank.");
428
+        } else if (nicknameText.length() <= 1 || nicknameText.length() > 9) {
429
+            nicknameError.setIcons(warningIcon);
430
+            returnValue =
431
+                    ValidationResult.WARNING;
432
+            nicknameError.setToolTipText("Some servers may not accept this nickname.");
433
+        }
434
+
435
+        return returnValue;
436
+    }
437
+
438
+    /**
439
+     * Validates the name.
440
+     *
441
+     * @return Validation result
442
+     */
443
+    private ValidationResult checkName() {
444
+        ValidationResult returnValue =
445
+                ValidationResult.PASS;
446
+        final String nameText = name.getText();
447
+
448
+        if (nameText.isEmpty() || nameText.matches(FILENAME_REGEX)) {
449
+            nameError.setIcons(errorIcon);
450
+            name.requestFocus();
451
+            returnValue =
452
+                    ValidationResult.FAIL;
453
+            nameError.setToolTipText("The profile name cannot be blank.");
454
+        }
455
+
456
+        return returnValue;
457
+    }
458
+
459
+    /** {@inheritDoc} */
460
+    @Override
461
+    public void actionPerformed(final ActionEvent e) {
462
+        if (e.getSource() == addButton) {
463
+            final String newName =
464
+                    JOptionPane.showInputDialog(this,
465
+                    "Please enter the name for alternate nickname",
466
+                    "New Alternate Nickname");
467
+            if (newName != null && !newName.isEmpty()) {
468
+                ((DefaultListModel) altNicknames.getModel()).addElement(newName);
469
+            }
470
+        } else if (e.getSource() == editButton) {
471
+            final String newName =
472
+                    JOptionPane.showInputDialog(this,
473
+                    "Please enter the new nickname for the alternate nickname",
474
+                    altNicknames.getSelectedValue());
475
+            if (newName != null && !newName.isEmpty()) {
476
+                ((DefaultListModel) altNicknames.getModel()).setElementAt(newName,
477
+                        altNicknames.getSelectedIndex());
478
+            }
479
+        } else if (e.getSource() == delButton) {
480
+            if (JOptionPane.showConfirmDialog(this,
481
+                    "Are you sure you want to delete this profile?",
482
+                    "Delete Confirmaton", JOptionPane.YES_NO_OPTION) ==
483
+                    JOptionPane.YES_OPTION) {
484
+                ((DefaultListModel) altNicknames.getModel()).removeElementAt(altNicknames.getSelectedIndex());
485
+            }
486
+        }
487
+    }
488
+
489
+    /** {@inheritDoc} */
490
+    @Override
491
+    public void valueChanged(final ListSelectionEvent e) {
492
+        if (!e.getValueIsAdjusting() && altNicknames.getSelectedIndex() == -1) {
493
+            editButton.setEnabled(false);
494
+            delButton.setEnabled(false);
495
+        } else {
496
+            editButton.setEnabled(true);
497
+            delButton.setEnabled(true);
498
+        }
499
+    }
500
+
501
+    /** {@inheritDoc} */
502
+    @Override
503
+    public void insertUpdate(final DocumentEvent e) {
504
+        validateDetails();
505
+    }
506
+
507
+    /** {@inheritDoc} */
508
+    @Override
509
+    public void removeUpdate(final DocumentEvent e) {
510
+        validateDetails();
511
+    }
512
+
513
+    /** {@inheritDoc} */
514
+    @Override
515
+    public void changedUpdate(final DocumentEvent e) {
516
+        //Ignore
517
+    }
518
+
519
+    /** {@inheritDoc} */
520
+    @Override
521
+    public void intervalAdded(final ListDataEvent e) {
522
+        validateDetails();
523
+    }
524
+
525
+    /** {@inheritDoc} */
526
+    @Override
527
+    public void intervalRemoved(final ListDataEvent e) {
528
+        validateDetails();
529
+    }
530
+
531
+    /** {@inheritDoc} */
532
+    @Override
533
+    public void contentsChanged(final ListDataEvent e) {
534
+        validateDetails();
535
+    }
536
+}

+ 61
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/ProfileListCellRenderer.java View File

@@ -0,0 +1,61 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+import java.awt.Component;
26
+
27
+import javax.swing.DefaultListCellRenderer;
28
+import javax.swing.JList;
29
+
30
+/** Profile list renderer. */
31
+public class ProfileListCellRenderer extends DefaultListCellRenderer {
32
+
33
+    /**
34
+     * A version number for this class. It should be changed whenever the class
35
+     * structure is changed (or anything else that would prevent serialized
36
+     * objects being unserialized with the new class).
37
+     */
38
+    private static final long serialVersionUID = 1;
39
+
40
+    /** Creates a new instance of ActionCellRenderer. */
41
+    public ProfileListCellRenderer() {
42
+        super();
43
+    }
44
+
45
+    /** {@inheritDoc} */
46
+    @Override
47
+    public Component getListCellRendererComponent(final JList list,
48
+            final Object value, final int index, final boolean isSelected,
49
+            final boolean cellHasFocus) {
50
+        super.getListCellRendererComponent(list, value, index, isSelected,
51
+                cellHasFocus);
52
+
53
+        if (!(value instanceof Profile)) {
54
+            setText("");
55
+        } else {
56
+            setText(((Profile) value).getName());
57
+        }
58
+
59
+        return this;
60
+    }
61
+}

+ 220
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/ProfileListModel.java View File

@@ -0,0 +1,220 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+import java.util.ArrayList;
26
+import java.util.Iterator;
27
+import java.util.List;
28
+
29
+import javax.swing.AbstractListModel;
30
+
31
+/** Profile list model. */
32
+public class ProfileListModel extends AbstractListModel {
33
+
34
+    /**
35
+     * A version number for this class. It should be changed whenever the class
36
+     * structure is changed (or anything else that would prevent serialized
37
+     * objects being unserialized with the new class).
38
+     */
39
+    private static final long serialVersionUID = 1;
40
+    /** Profile list. */
41
+    private final List<Profile> profiles;
42
+
43
+    /** Creates a new profile list model. */
44
+    public ProfileListModel() {
45
+        this(new ArrayList<Profile>());
46
+    }
47
+
48
+    /**
49
+     * Creates a new profile list model.
50
+     *
51
+     * @param profiles Profile list to use
52
+     */
53
+    public ProfileListModel(final List<Profile> profiles) {
54
+        this.profiles = profiles;
55
+    }
56
+
57
+    /** {@inheritDoc} */
58
+    @Override
59
+    public int getSize() {
60
+        return profiles.size();
61
+    }
62
+
63
+    /** {@inheritDoc} */
64
+    @Override
65
+    public Profile getElementAt(int index) {
66
+        return profiles.get(index);
67
+    }
68
+
69
+    /**
70
+     * Removes the index from the model.
71
+     *
72
+     * @param index Index to remove
73
+     *
74
+     * @return the profile that was removed
75
+     */
76
+    public Profile remove(int index) {
77
+        final Profile returnValue = profiles.remove(index);
78
+
79
+        fireIntervalRemoved(this, index, index);
80
+
81
+        return returnValue;
82
+    }
83
+
84
+    /**
85
+     * Removes the object from the model.
86
+     *
87
+     * @param p object to remove from the model
88
+     *
89
+     * @return true if the object was removed
90
+     */
91
+    public boolean remove(Profile p) {
92
+        final int index = profiles.indexOf(p);
93
+        final boolean returnValue = profiles.remove(p);
94
+
95
+        fireIntervalRemoved(this, index, index);
96
+
97
+        return returnValue;
98
+    }
99
+
100
+    /**
101
+     * Checks if the model is empty.
102
+     *
103
+     * @return true if the model is empty
104
+     */
105
+    public boolean isEmpty() {
106
+        return profiles.isEmpty();
107
+    }
108
+
109
+    /**
110
+     * Returns the index of the object.
111
+     *
112
+     * @param p object to find the index of
113
+     *
114
+     * @return index of the specified object
115
+     */
116
+    public int indexOf(Profile p) {
117
+        return profiles.indexOf(p);
118
+    }
119
+
120
+    /**
121
+     * Returns the profile at the index.
122
+     *
123
+     * @param index index to retrieve
124
+     *
125
+     * @return the profile that was removed
126
+     */
127
+    public Profile get(int index) {
128
+        return profiles.get(index);
129
+    }
130
+
131
+    /**
132
+     *
133
+     * Checks if the model contains the profile
134
+     *
135
+     * @param p profile to check for
136
+     *
137
+     * @return true if the model contains the profile
138
+     */
139
+    public boolean contains(Profile p) {
140
+        return profiles.contains(p);
141
+    }
142
+
143
+    /**
144
+     *
145
+     * Checks if the model contains a profile with the specified name.
146
+     *
147
+     * @param name name to match against
148
+     *
149
+     * @return true if the model contains a profile with the specified name
150
+     */
151
+    public boolean contains(String name) {
152
+        synchronized (profiles) {
153
+            for (Profile profile : profiles) {
154
+                if (profile.getName().equals(name)) {
155
+                    return true;
156
+                }
157
+            }
158
+
159
+            return false;
160
+        }
161
+    }
162
+
163
+    /**
164
+     * Clears the model.
165
+     */
166
+    public void clear() {
167
+        final int size = profiles.size();
168
+        profiles.clear();
169
+        fireIntervalRemoved(this, 0, size);
170
+    }
171
+
172
+    /**
173
+     * Adds a profile at the index
174
+     *
175
+     * @param index index to add the profile
176
+     * @param element profile to add
177
+     */
178
+    public void add(int index, Profile element) {
179
+        profiles.add(index, element);
180
+
181
+        fireIntervalAdded(this, index, index);
182
+    }
183
+
184
+    /**
185
+     * Adds the profile to the model
186
+     *
187
+     * @param p profile to add
188
+     *
189
+     * @return true if the item was added
190
+     */
191
+    public boolean add(Profile p) {
192
+        final boolean returnValue = profiles.add(p);
193
+        final int index = profiles.indexOf(p);
194
+
195
+        fireIntervalAdded(this, index, index);
196
+
197
+        return returnValue;
198
+    }
199
+
200
+    /**
201
+     * Returns an iterator for this model.
202
+     *
203
+     * @return Iterator for the model
204
+     */
205
+    public Iterator<Profile> iterator() {
206
+        return profiles.iterator();
207
+    }
208
+
209
+    /** {@inheritDoc} */
210
+    @Override
211
+    public boolean equals(Object o) {
212
+        return profiles.equals(o);
213
+    }
214
+
215
+    /** {@inheritDoc} */
216
+    @Override
217
+    public int hashCode() {
218
+        return profiles.hashCode();
219
+    }
220
+}

+ 309
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/ProfileManagerDialog.java View File

@@ -0,0 +1,309 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+import com.dmdirc.Main;
26
+import com.dmdirc.config.Identity;
27
+import com.dmdirc.config.IdentityManager;
28
+import com.dmdirc.ui.swing.MainFrame;
29
+import com.dmdirc.ui.swing.components.StandardDialog;
30
+import com.dmdirc.ui.swing.components.TextLabel;
31
+import static com.dmdirc.ui.swing.UIUtilities.SMALL_BORDER;
32
+
33
+import java.awt.Dimension;
34
+import java.awt.GridBagConstraints;
35
+import java.awt.GridBagLayout;
36
+import java.awt.event.ActionEvent;
37
+import java.awt.event.ActionListener;
38
+import java.util.Arrays;
39
+import java.util.Iterator;
40
+import java.util.List;
41
+
42
+import javax.swing.Box;
43
+import javax.swing.BoxLayout;
44
+import javax.swing.JButton;
45
+import javax.swing.JList;
46
+import javax.swing.JOptionPane;
47
+import javax.swing.JPanel;
48
+import javax.swing.JScrollPane;
49
+import javax.swing.UIManager;
50
+import javax.swing.WindowConstants;
51
+import javax.swing.event.ListSelectionEvent;
52
+import javax.swing.event.ListSelectionListener;
53
+
54
+/** Profile editing dialog. */
55
+public final class ProfileManagerDialog extends StandardDialog implements ActionListener,
56
+        ListSelectionListener {
57
+
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 = 1;
64
+    /** Previously created instance of ProfileEditorDialog. */
65
+    private static ProfileManagerDialog me;
66
+    /** Profile list. */
67
+    private final List<Identity> profiles;
68
+    /** Profile list. */
69
+    private JList profileList;
70
+    /** Profile list mode. */
71
+    private ProfileListModel model;
72
+    /** Profile detail panel. */
73
+    private ProfileDetailPanel details;
74
+    /** Buttons panel. */
75
+    private JPanel buttonsPanel;
76
+    /** Info label. */
77
+    private TextLabel infoLabel;
78
+    /** Add button. */
79
+    private JButton addButton;
80
+    /** Delete button. */
81
+    private JButton deleteButton;
82
+    /** Selected index. */
83
+    private int selectedIndex;
84
+
85
+    /** Creates a new instance of ProfileEditorDialog. */
86
+    private ProfileManagerDialog() {
87
+        super((MainFrame) Main.getUI().getMainWindow(), false);
88
+
89
+        profiles = IdentityManager.getProfiles();
90
+
91
+        initComponents();
92
+
93
+        layoutComponents();
94
+
95
+        addListeners();
96
+
97
+        if (model.getSize() > 0) {
98
+            profileList.setSelectedIndex(0);
99
+        } else {
100
+            selectedIndex = -1;
101
+        }
102
+    }
103
+
104
+    /** Creates the dialog if one doesn't exist, and displays it. */
105
+    public static synchronized void showProfileManagerDialog() {
106
+        me = getProfileManagerDialog();
107
+
108
+        me.setLocationRelativeTo((MainFrame) Main.getUI().getMainWindow());
109
+        me.setVisible(true);
110
+        me.requestFocus();
111
+    }
112
+
113
+    /**
114
+     * Returns the current instance of the ProfileManagerDialog.
115
+     *
116
+     * @return The current ProfileManagerDialog instance
117
+     */
118
+    public static synchronized ProfileManagerDialog getProfileManagerDialog() {
119
+        if (me == null) {
120
+            me = new ProfileManagerDialog();
121
+        }
122
+
123
+        return me;
124
+    }
125
+
126
+    /** Initialises the components. */
127
+    private void initComponents() {
128
+        setTitle("Profile Editor");
129
+        setMinimumSize(new Dimension(600, 400));
130
+        setPreferredSize(new Dimension(600, 400));
131
+        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
132
+        setResizable(false);
133
+
134
+        model = new ProfileListModel();
135
+        profileList = new JList(model);
136
+        details = new ProfileDetailPanel();
137
+        addButton = new JButton("Add");
138
+        deleteButton = new JButton("Delete");
139
+        infoLabel =
140
+                new TextLabel("Profiles describe information needed to " +
141
+                "connect to a server.  You can use a different profile for " +
142
+                "each connection. Profiles are automatically saved when you " +
143
+                "select another or click OK", this);
144
+
145
+        profileList.setCellRenderer(new ProfileListCellRenderer());
146
+        profileList.setFixedCellWidth(200 -
147
+                UIManager.getInt("ScrollBar.width"));
148
+
149
+        initButtonsPanel();
150
+        populateList();
151
+    }
152
+
153
+    /** Initialises the buttons panel. */
154
+    private void initButtonsPanel() {
155
+        buttonsPanel = new JPanel();
156
+        orderButtons(new JButton(), new JButton());
157
+    }
158
+
159
+    /** Lays out the dialog. */
160
+    private void layoutComponents() {
161
+        layoutButtonsPanel();
162
+
163
+        final GridBagConstraints constraints = new GridBagConstraints();
164
+        setLayout(new GridBagLayout());
165
+
166
+        final JScrollPane sp = new JScrollPane(profileList);
167
+        sp.setMinimumSize(new Dimension(200, 0));
168
+        constraints.weighty = 0.0;
169
+        constraints.weightx = 0.0;
170
+        constraints.gridx = 0;
171
+        constraints.gridy = 0;
172
+        constraints.gridwidth = 1;
173
+        constraints.gridheight = 3;
174
+        constraints.fill = GridBagConstraints.BOTH;
175
+        constraints.insets.set(SMALL_BORDER, SMALL_BORDER, SMALL_BORDER, 0);
176
+        getContentPane().add(sp, constraints);
177
+
178
+        constraints.insets.set(0, SMALL_BORDER, 0, 0);
179
+        constraints.gridheight = 1;
180
+        constraints.gridy = 4;
181
+        getContentPane().add(addButton, constraints);
182
+
183
+        constraints.gridy = 5;
184
+        constraints.insets.set(SMALL_BORDER, SMALL_BORDER, SMALL_BORDER, 0);
185
+        getContentPane().add(deleteButton, constraints);
186
+
187
+        constraints.weightx = 1.0;
188
+        constraints.weighty = 0.0;
189
+        constraints.gridx = 1;
190
+        constraints.gridy = 0;
191
+        constraints.gridheight = 1;
192
+        constraints.gridwidth = 2;
193
+        constraints.insets.set(SMALL_BORDER, SMALL_BORDER, SMALL_BORDER, 0);
194
+        getContentPane().add(infoLabel, constraints);
195
+
196
+        constraints.weighty = 1.0;
197
+        constraints.gridy = 1;
198
+        constraints.insets.set(0, SMALL_BORDER, 0, 0);
199
+        getContentPane().add(details, constraints);
200
+
201
+        constraints.gridwidth = 1;
202
+        constraints.weighty = 0.0;
203
+        constraints.gridy = 5;
204
+        constraints.insets.set(0, SMALL_BORDER, SMALL_BORDER, SMALL_BORDER);
205
+        getContentPane().add(buttonsPanel, constraints);
206
+
207
+        pack();
208
+    }
209
+
210
+    /** Lays out the buttons panel. */
211
+    private void layoutButtonsPanel() {
212
+        buttonsPanel.setLayout(new BoxLayout(buttonsPanel,
213
+                BoxLayout.LINE_AXIS));
214
+        buttonsPanel.add(Box.createHorizontalGlue());
215
+        buttonsPanel.add(getLeftButton());
216
+        buttonsPanel.add(Box.createHorizontalStrut(SMALL_BORDER));
217
+        buttonsPanel.add(getRightButton());
218
+    }
219
+
220
+    /** Adds listeners to the components. */
221
+    private void addListeners() {
222
+        getOkButton().addActionListener(this);
223
+        getCancelButton().addActionListener(this);
224
+
225
+        addButton.addActionListener(this);
226
+        deleteButton.addActionListener(this);
227
+
228
+        profileList.addListSelectionListener(this);
229
+    }
230
+
231
+    /** Populates the profile list. */
232
+    public void populateList() {
233
+        final String profileString = "profile";
234
+        model.clear();
235
+
236
+        for (Identity profile : profiles) {
237
+            model.add(new Profile(profile.getName(),
238
+                    profile.getOption(profileString, "nickname"),
239
+                    profile.getOption(profileString, "realname"),
240
+                    profile.getOption(profileString, "ident"),
241
+                    Arrays.asList(profile.getOption(profileString, "altnicks").
242
+                    split("\n")), false));
243
+        }
244
+    }
245
+
246
+    /** Saves the profile list. */
247
+    private void save() {
248
+        if (!details.validateDetails().equals(ValidationResult.FAIL)) {
249
+            details.save();
250
+            final Iterator<Profile> it = model.iterator();
251
+
252
+            while (it.hasNext()) {
253
+                it.next().save();
254
+            }
255
+
256
+            dispose();
257
+        }
258
+    }
259
+
260
+    /** {@inheritDoc} */
261
+    @Override
262
+    public void actionPerformed(final ActionEvent e) {
263
+        if (e.getSource().equals(getOkButton())) {
264
+            save();
265
+        } else if (e.getSource().equals(getCancelButton())) {
266
+            dispose();
267
+        } else if (e.getSource().equals(addButton)) {
268
+            final Profile profile = new Profile("Unnamed");
269
+            model.add(profile);
270
+            profileList.setSelectedIndex(model.indexOf(profile));
271
+        } else if (e.getSource().equals(deleteButton)) {
272
+            if (JOptionPane.showConfirmDialog(this,
273
+                    "Are you sure you want to delete this nick?",
274
+                    "Delete Confirmaton", JOptionPane.YES_NO_OPTION) ==
275
+                    JOptionPane.YES_OPTION) {
276
+                model.remove((Profile) profileList.getSelectedValue());
277
+            }
278
+        }
279
+    }
280
+
281
+    /** {@inheritDoc} */
282
+    @Override
283
+    public void valueChanged(final ListSelectionEvent e) {
284
+        if (e.getValueIsAdjusting()) {
285
+            if (details.validateDetails().equals(ValidationResult.FAIL)) {
286
+                profileList.setSelectedIndex(selectedIndex);
287
+            }
288
+        }
289
+        if (!e.getValueIsAdjusting()) {
290
+            details.save();
291
+            details.setProfile((Profile) profileList.getSelectedValue());
292
+            if (profileList.getSelectedIndex() == -1) {
293
+                deleteButton.setEnabled(false);
294
+            } else {
295
+                deleteButton.setEnabled(true);
296
+            }
297
+        }
298
+        selectedIndex = profileList.getSelectedIndex();
299
+    }
300
+
301
+    /** {@inheritDoc} */
302
+    @Override
303
+    public void dispose() {
304
+        synchronized (me) {
305
+            super.dispose();
306
+            me = null;
307
+        }
308
+    }
309
+}

+ 34
- 0
src/com/dmdirc/ui/swing/dialogs/profiles/ValidationResult.java View File

@@ -0,0 +1,34 @@
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
+
23
+package com.dmdirc.ui.swing.dialogs.profiles;
24
+
25
+/** Validation result. */
26
+public enum ValidationResult {
27
+
28
+    /** Validation has passed */
29
+    PASS, 
30
+    /** Validation has passed, but a warning is attatched. */
31
+    WARNING, 
32
+    /** Validation has failed */
33
+    FAIL;
34
+}

Loading…
Cancel
Save