1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.pircbot;
21
22 import javax.swing.AbstractAction;
23 import javax.swing.Action;
24 import javax.swing.JPanel;
25 import javax.swing.JPopupMenu;
26 import javax.swing.JScrollPane;
27 import javax.swing.ListSelectionModel;
28 import javax.swing.event.TreeSelectionEvent;
29 import javax.swing.event.TreeSelectionListener;
30 import javax.swing.tree.TreePath;
31
32 import java.awt.GridBagLayout;
33 import java.awt.event.ActionEvent;
34 import java.io.File;
35 import java.io.IOException;
36 import java.util.Iterator;
37 import java.util.LinkedList;
38
39 import org.xnap.XNap;
40 import org.xnap.event.StateEvent;
41 import org.xnap.event.StateListener;
42 import org.xnap.gui.ActionProvider;
43 import org.xnap.gui.StatusBar;
44 import org.xnap.gui.action.CollapseAllNodesAction;
45 import org.xnap.gui.action.ExpandAllNodesAction;
46 import org.xnap.gui.component.XNapButton;
47 import org.xnap.gui.component.XNapMenuItem;
48 import org.xnap.gui.event.DoubleClickListener;
49 import org.xnap.gui.event.PopupListener;
50 import org.xnap.gui.table.JTreeTable;
51 import org.xnap.gui.table.TreeTableNode;
52 import org.xnap.gui.tree.NetworkTreeCellRenderer;
53 import org.xnap.gui.util.GUIHelper;
54 import org.xnap.gui.util.GridBagHelper;
55 import org.xnap.gui.util.IconHelper;
56 import org.xnap.util.FileHelper;
57
58 public class PircBotPanel extends JPanel
59 implements ActionProvider, StateListener, TreeSelectionListener {
60
61
62
63 public static final String SERVER_FILENAME = "pircbot_servers";
64
65
66
67 private PircBotServerTableModel tmServers;
68 private JTreeTable jttServers;
69
70 private Action acConnect = new ConnectAction();
71 private Action acDisconnect = new DisconnectAction();
72 private Action acNew = new NewAction();
73 private Action acEdit = new EditAction();
74 private Action acRemove = new RemoveAction();
75 private Action acCollapseAllNodes;
76 private Action acExpandAllNodes;
77
78 private PircBotServer currentServer;
79
80
81
82 public PircBotPanel()
83 {
84 initialize();
85
86
87 tmServers.add(XNap.tr("Local"));
88
89 readFile();
90
91
92 valueChanged();
93 }
94
95
96
97 private void initialize()
98 {
99 setLayout(new GridBagLayout());
100
101
102 GridBagHelper.add
103 (this, GUIHelper.createSeparator(XNap.tr("Servers")));
104
105 tmServers = new PircBotServerTableModel();
106 jttServers = tmServers.createTreeTable
107 (PircBotPlugin.getInstance().getPreferences(), "server");
108 jttServers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
109 jttServers.getTree().getSelectionModel().addTreeSelectionListener(this);
110 jttServers.getTree().setCellRenderer
111 (new NetworkTreeCellRenderer(tmServers));
112 jttServers.getTableHeader().setReorderingAllowed(false);
113 DoubleClickListener.install(jttServers, acConnect);
114 GUIHelper.bindEnterKey(jttServers, acConnect);
115
116 GridBagHelper.add(this, new JScrollPane(jttServers));
117
118 acCollapseAllNodes = new CollapseAllNodesAction(jttServers.getTree());
119 acExpandAllNodes = new ExpandAllNodesAction(jttServers.getTree());
120
121
122
123 JPopupMenu popup = new JPopupMenu();
124 popup.add(new XNapMenuItem(acConnect));
125 popup.add(new XNapMenuItem(acDisconnect));
126 popup.addSeparator();
127 popup.add(new XNapMenuItem(acEdit));
128 popup.add(new XNapMenuItem(acRemove));
129
130 jttServers.addMouseListener(new PopupListener(popup));
131
132
133 JPanel jpButtons = new JPanel(new GridBagLayout());
134 GridBagHelper.add(this, jpButtons);
135
136 GridBagHelper.addComponent(jpButtons, new XNapButton(acConnect));
137 GridBagHelper.addComponent(jpButtons, new XNapButton(acDisconnect));
138
139 GridBagHelper.addComponent(jpButtons, new XNapButton(acNew));
140 GridBagHelper.addComponent(jpButtons, new XNapButton(acEdit));
141 GridBagHelper.addComponent(jpButtons, new XNapButton(acRemove));
142
143 GridBagHelper.addVerticalSpacer(this);
144 GUIHelper.setMnemonics(this);
145 }
146
147 /***
148 * Returns the selected network.
149 *
150 * @return null, if no network is selected.
151 */
152 public String getSelectedNetwork()
153 {
154 TreePath path = jttServers.getTree().getSelectionPath();
155 if (path != null) {
156 TreeTableNode node = (TreeTableNode)path.getLastPathComponent();
157 return (node instanceof PircBotNetworkNode)
158 ? (String)node.getData() : null;
159 }
160 return null;
161 }
162
163 /***
164 * Returns the selected server.
165 *
166 * @return null, if no server is selected.
167 */
168 public PircBotServer getSelectedServer()
169 {
170 TreePath path = jttServers.getTree().getSelectionPath();
171 if (path != null) {
172 TreeTableNode node = (TreeTableNode)path.getLastPathComponent();
173 return (node instanceof PircBotNetworkNode)
174 ? null : (PircBotServer)node.getData();
175 }
176 return null;
177 }
178
179 public Action[] getActions()
180 {
181 return new Action[] {
182 acConnect, acDisconnect, null,
183 acCollapseAllNodes, acExpandAllNodes
184 };
185 }
186
187 public void savePrefs()
188 {
189
190 for (Iterator i = tmServers.servers(); i.hasNext();) {
191 ((PircBotServer)i.next()).close();
192 }
193
194 writeFile();
195 }
196
197 public void stateChanged(StateEvent e)
198 {
199 valueChanged();
200 }
201
202 public void valueChanged(TreeSelectionEvent e)
203 {
204 valueChanged();
205 }
206
207 public void valueChanged()
208 {
209 if (currentServer != null) {
210 currentServer.removeStateListener(this);
211 }
212
213 currentServer = getSelectedServer();
214
215 if (currentServer != null) {
216 currentServer.addStateListener(this);
217 }
218
219 acConnect.setEnabled(currentServer != null
220 && currentServer.isDisconnected());
221 acDisconnect.setEnabled(currentServer != null
222 && currentServer.isConnected());
223
224 acEdit.setEnabled(currentServer != null);
225 acRemove.setEnabled(currentServer != null);
226 }
227
228 private void addDefaultServers()
229 {
230 PircBotServerData data = new PircBotServerData();
231 data.network = "FreeNode";
232 data.name = "irc.freenode.net";
233 data.host = "irc.freenode.net";
234 data.port = 6667;
235 data.autoJoinChannels = "#xnap";
236 tmServers.add(new PircBotServer(data));
237
238 addServer("SourceForge", "irc.sourceforge.net",
239 "irc.sourceforge.net");
240 }
241
242 private void addServer(String network, String name, String host)
243 {
244 PircBotServerData data = new PircBotServerData();
245 data.network = network;
246 data.name = name;
247 data.host = host;
248 data.port = 6667;
249 tmServers.add(new PircBotServer(data));
250 }
251
252 private void readFile()
253 {
254 LinkedList list = new LinkedList();
255 try {
256 File f = new File(FileHelper.getHomeDir() + SERVER_FILENAME);
257 FileHelper.readBinary(f, list);
258 }
259 catch (IOException e) {
260 addDefaultServers();
261 StatusBar.setText(XNap.tr("Could not read file {0}",
262 SERVER_FILENAME));
263 }
264 for (Iterator i = list.iterator(); i.hasNext();) {
265 Object o = i.next();
266 if (o instanceof PircBotServerData) {
267 PircBotServerData data = (PircBotServerData)o;
268 if (data.network == null) {
269 data.network = XNap.tr("Local");
270 }
271
272 PircBotServer s = new PircBotServer(data);
273 tmServers.add(s);
274 }
275 }
276 }
277
278 private void writeFile()
279 {
280 LinkedList list = new LinkedList();
281 for (Iterator i = tmServers.servers(); i.hasNext();) {
282 list.add(((PircBotServer)i.next()).getData());
283 }
284
285 try {
286 File f = new File(FileHelper.getHomeDir() + SERVER_FILENAME);
287 FileHelper.writeBinary(f, list);
288 }
289 catch (IOException e) {
290 StatusBar.setText(XNap.tr("Could not write file {0}",
291 SERVER_FILENAME));
292 }
293 }
294
295
296
297 /***
298 * Connects to the selected server.
299 */
300 private class ConnectAction extends AbstractAction {
301
302 public ConnectAction()
303 {
304 putValue(Action.NAME, XNap.tr("Connect"));
305 putValue(Action.SHORT_DESCRIPTION,
306 XNap.tr("Connects to the selected server."));
307 putValue(IconHelper.XNAP_ICON, "connect_creating.png");
308 }
309
310 public void actionPerformed(ActionEvent event)
311 {
312 PircBotServer server = getSelectedServer();
313 if (server != null) {
314 server.connect();
315 valueChanged();
316 }
317 }
318
319 }
320
321 /***
322 * Disconnects from selected server.
323 */
324 private class DisconnectAction extends AbstractAction {
325
326 public DisconnectAction()
327 {
328 putValue(Action.NAME, XNap.tr("Disconnect"));
329 putValue(Action.SHORT_DESCRIPTION,
330 XNap.tr("Disconnects from the selected server."));
331 putValue(IconHelper.XNAP_ICON, "connect_no.png");
332 }
333
334 public void actionPerformed(ActionEvent event)
335 {
336 PircBotServer server = getSelectedServer();
337 if (server != null) {
338 server.getBot().disconnect();
339 valueChanged();
340 }
341 }
342
343 }
344
345 /***
346 * Creates a new server.
347 */
348 private class NewAction extends AbstractAction {
349
350 public NewAction()
351 {
352 putValue(Action.NAME, XNap.tr("New"));
353 putValue(Action.SHORT_DESCRIPTION,
354 XNap.tr("Creates a new server."));
355 putValue(IconHelper.XNAP_ICON, "filenew.png");
356 }
357
358 public void actionPerformed(ActionEvent event)
359 {
360 PircBotServerData data = new PircBotServerData();
361 PircBotServer server = getSelectedServer();
362 if (server != null) {
363 data.network = server.getNetwork();
364 }
365 else {
366 data.network = getSelectedNetwork();
367 }
368 server = new PircBotServer(data);
369
370 PircBotNewServerDialog d = new PircBotNewServerDialog(server);
371 d.setNetworks(tmServers.getNetworks());
372 d.show(PircBotPanel.this);
373 }
374
375 }
376
377 /***
378 * Edit selected server.
379 */
380 private class EditAction extends AbstractAction {
381
382 public EditAction()
383 {
384 putValue(Action.NAME, XNap.tr("Edit"));
385 putValue(Action.SHORT_DESCRIPTION,
386 XNap.tr("Edits the selected server."));
387 putValue(IconHelper.XNAP_ICON, "edit.png");
388 }
389
390 public void actionPerformed(ActionEvent event)
391 {
392 PircBotServer server = getSelectedServer();
393 if (server != null) {
394 PircBotServerDialog d = new PircBotServerDialog(server);
395 d.setNetworks(tmServers.getNetworks());
396 d.show(PircBotPanel.this);
397 }
398 }
399
400 }
401
402 /***
403 * Remove selected server.
404 */
405 private class RemoveAction extends AbstractAction {
406
407 public RemoveAction()
408 {
409 putValue(Action.NAME, XNap.tr("Remove"));
410 putValue(Action.SHORT_DESCRIPTION,
411 XNap.tr("Removes the selected server."));
412 putValue(IconHelper.XNAP_ICON, "eraser.png");
413 }
414
415 public void actionPerformed(ActionEvent event)
416 {
417 PircBotServer server = getSelectedServer();
418 if (server != null) {
419 tmServers.remove(server);
420 }
421 }
422
423 }
424
425 /***
426 * Used by {@link #NewAction}.
427 */
428 private class PircBotNewServerDialog extends PircBotServerDialog
429 {
430
431 public PircBotNewServerDialog(PircBotServer server)
432 {
433 super(server);
434 }
435
436 /***
437 * Adds server to table model, if successful.
438 */
439 public boolean apply()
440 {
441 super.apply();
442
443 tmServers.add(getServer());
444 return true;
445 }
446
447 }
448
449 }