remove warnings
[jSite2.git] / src / net / pterodactylus / jsite / gui / SwingInterface.java
1 /*
2  * jSite2 - SwingInterface.java -
3  * Copyright © 2008 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.jsite.gui;
21
22 import java.awt.event.ActionEvent;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Properties;
31
32 import javax.swing.JOptionPane;
33
34 import net.pterodactylus.jsite.core.Core;
35 import net.pterodactylus.jsite.core.CoreListener;
36 import net.pterodactylus.jsite.core.Node;
37 import net.pterodactylus.jsite.core.Project;
38 import net.pterodactylus.jsite.i18n.I18n;
39 import net.pterodactylus.jsite.i18n.gui.I18nAction;
40 import net.pterodactylus.util.io.Closer;
41
42 /**
43  * The Swing user interface.
44  *
45  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
46  * @version $Id$
47  */
48 public class SwingInterface implements CoreListener {
49
50         /** The application core. */
51         private final Core core;
52
53         /** The configuration directory. */
54         private final String configDirectory;
55
56         /** The main window. */
57         private MainWindow mainWindow;
58
59         /** The “configure” action. */
60         private I18nAction configureAction;
61
62         /** The “import config” action. */
63         private I18nAction importConfigAction;
64
65         /** The “quit” action. */
66         private I18nAction quitAction;
67
68         /** The “manage nodes” action. */
69         private I18nAction manageNodesAction;
70
71         /** The “connect to node” action. */
72         private I18nAction nodeConnectAction;
73
74         /** The “disconnect from node” action. */
75         private I18nAction nodeDisconnectAction;
76
77         /** The node manager dialog. */
78         private ManageNodesDialog manageNodesDialog;
79
80         /** All lanugage menu items. */
81         private List<I18nAction> languageActions = new ArrayList<I18nAction>();
82
83         /** The “about” action. */
84         private I18nAction helpAboutAction;
85
86         /** The “add project” action. */
87         private I18nAction addProjectAction;
88
89         /** The “clone project” action. */
90         private I18nAction cloneProjectAction;
91
92         /** The “delete project” action. */
93         private I18nAction deleteProjectAction;
94
95         /** The “about” dialog. */
96         private AboutDialog aboutDialog;
97
98         /** The configuration dialog. */
99         private ConfigurationDialog configurationDialog;
100
101         /** The list of all defined nodes. */
102         private List<Node> nodeList;
103
104         //
105         // CONFIGURATION
106         //
107
108         /** Whether to antialias the GUI. */
109         private boolean antialias;
110
111         /** The control font. */
112         private String controlFont;
113
114         /** The user font. */
115         private String userFont;
116
117         /**
118          * Creates a new swing interface.
119          *
120          * @param core
121          *            The core to operate on
122          * @param configDirectory
123          *            The directory the configuration is stored in
124          */
125         public SwingInterface(Core core, String configDirectory) {
126                 this.core = core;
127                 this.configDirectory = configDirectory;
128                 I18n.setLocale(Locale.ENGLISH);
129                 loadConfig();
130                 if (antialias) {
131                         System.setProperty("swing.aatext", "true");
132                 }
133                 if (controlFont != null) {
134                         System.setProperty("swing.plaf.metal.controlFont", controlFont);
135                 }
136                 if (userFont != null) {
137                         System.setProperty("swing.plaf.metal.userFont", userFont);
138                 }
139                 initActions();
140                 initDialogs();
141         }
142
143         //
144         // ACCESSORS
145         //
146
147         /**
148          * Returns the core that is controlled by the Swing interface.
149          *
150          * @return The core
151          */
152         Core getCore() {
153                 return core;
154         }
155
156         /**
157          * Returns the main window of the Swing interface.
158          *
159          * @return The main window
160          */
161         MainWindow getMainWindow() {
162                 return mainWindow;
163         }
164
165         /**
166          * Returns the “configure” action.
167          *
168          * @return The “configure” action
169          */
170         I18nAction getConfigureAction() {
171                 return configureAction;
172         }
173
174         /**
175          * Returns the “import config” action.
176          *
177          * @return The “import config” action
178          */
179         I18nAction getImportConfigAction() {
180                 return importConfigAction;
181         }
182
183         /**
184          * Returns the “quit” action.
185          *
186          * @return The “quit” action
187          */
188         I18nAction getQuitAction() {
189                 return quitAction;
190         }
191
192         /**
193          * Returns the “manage nodes” action.
194          *
195          * @return The “manage nodes” action
196          */
197         I18nAction getManageNodesAction() {
198                 return manageNodesAction;
199         }
200
201         /**
202          * Returns the “connect to node” action.
203          *
204          * @return The “connect to node” action
205          */
206         I18nAction getNodeConnectAction() {
207                 return nodeConnectAction;
208         }
209
210         /**
211          * Returns the “disconnect from node” action.
212          *
213          * @return The “disconnect from node” action
214          */
215         I18nAction getNodeDisconnectAction() {
216                 return nodeDisconnectAction;
217         }
218
219         /**
220          * Returns all language actions.
221          *
222          * @return All language actions
223          */
224         List<I18nAction> getLanguageActions() {
225                 return languageActions;
226         }
227
228         /**
229          * Returns the “about” action.
230          *
231          * @return The “about” action
232          */
233         I18nAction getHelpAboutAction() {
234                 return helpAboutAction;
235         }
236
237         /**
238          * Returns the “add project” action.
239          *
240          * @return The “add project” action
241          */
242         I18nAction getAddProjectAction() {
243                 return addProjectAction;
244         }
245
246         /**
247          * Returns the “clone project” action.
248          *
249          * @return The “clone project” action
250          */
251         I18nAction getCloneProjectAction() {
252                 return cloneProjectAction;
253         }
254
255         /**
256          * Returns the “delete project” action.
257          *
258          * @return The “delete project” action
259          */
260         I18nAction getDeleteProjectAction() {
261                 return deleteProjectAction;
262         }
263
264         //
265         // ACTIONS
266         //
267
268         //
269         // SERVICE METHODS
270         //
271
272         /**
273          * Starts the interface.
274          */
275         public void start() {
276                 mainWindow = new MainWindow(this);
277         }
278
279         //
280         // PRIVATE METHODS
281         //
282
283         /**
284          * Loads the configuration of the interface.
285          */
286         private void loadConfig() {
287                 /* initialize default stuff. */
288                 antialias = false;
289                 /* now read config. */
290                 File configFile = new File(configDirectory, "swing-interface.properties");
291                 if (!configFile.exists() || !configFile.canRead() || !configFile.isFile()) {
292                         System.err.println("could not find “" + configFile.getAbsolutePath() + "”!");
293                         return;
294                 }
295                 Properties configProperties = new Properties();
296                 FileInputStream configInputStream = null;
297                 try {
298                         configInputStream = new FileInputStream(configFile);
299                         configProperties.load(configInputStream);
300                 } catch (IOException ioe1) {
301                         System.err.println("could not load config, " + ioe1.getMessage());
302                 } finally {
303                         Closer.close(configInputStream);
304                 }
305                 if (configProperties.containsKey("antialias")) {
306                         antialias = Boolean.valueOf(configProperties.getProperty("antialias"));
307                 }
308                 if (configProperties.containsKey("controlFont")) {
309                         controlFont = configProperties.getProperty("controlFont");
310                 }
311                 if (configProperties.containsKey("userFont")) {
312                         userFont = configProperties.getProperty("userFont");
313                 }
314                 if (configProperties.containsKey("language")) {
315                         I18n.setLocale(new Locale(configProperties.getProperty("language")));
316                 }
317         }
318
319         /**
320          * Saves the configuration.
321          */
322         private void saveConfig() {
323                 File configDirectory = new File(this.configDirectory);
324                 if (!configDirectory.exists()) {
325                         if (!configDirectory.mkdirs()) {
326                                 System.err.println("could not create “" + this.configDirectory + "”!");
327                                 return;
328                         }
329                 }
330                 if (!configDirectory.exists() || !configDirectory.isDirectory() || !configDirectory.canWrite()) {
331                         System.err.println("can not access “" + this.configDirectory + "”!");
332                         return;
333                 }
334                 File configFile = new File(configDirectory, "swing-interface.properties");
335                 Properties configProperties = new Properties();
336                 configProperties.setProperty("antialias", String.valueOf(antialias));
337                 if (controlFont != null) {
338                         configProperties.setProperty("controlFont", controlFont);
339                 }
340                 if (userFont != null) {
341                         configProperties.setProperty("userFont", userFont);
342                 }
343                 configProperties.setProperty("language", I18n.getLocale().getLanguage());
344                 FileOutputStream configOutputStream = null;
345                 try {
346                         configOutputStream = new FileOutputStream(configFile);
347                         configProperties.store(configOutputStream, "configuration of swing interface");
348                 } catch (IOException ioe1) {
349                         System.err.println("could not save config, " + ioe1.getMessage());
350                 } finally {
351                         Closer.close(configOutputStream);
352                 }
353         }
354
355         /**
356          * Initializes all actions.
357          */
358         private void initActions() {
359                 configureAction = new I18nAction("mainWindow.menu.jSite.configure") {
360
361                         /**
362                          * {@inheritDoc}
363                          */
364                         @SuppressWarnings("synthetic-access")
365                         public void actionPerformed(ActionEvent actionEvent) {
366                                 configure();
367                         }
368                 };
369                 importConfigAction = new I18nAction("mainWindow.menu.jSite.importConfig") {
370
371                         /**
372                          * {@inheritDoc}
373                          */
374                         @SuppressWarnings("synthetic-access")
375                         public void actionPerformed(ActionEvent actionEvent) {
376                                 importConfig();
377                         }
378                 };
379                 quitAction = new I18nAction("mainWindow.menu.jSite.quit") {
380
381                         /**
382                          * {@inheritDoc}
383                          */
384                         @SuppressWarnings("synthetic-access")
385                         public void actionPerformed(ActionEvent actionEvent) {
386                                 quit();
387                         }
388                 };
389                 manageNodesAction = new I18nAction("mainWindow.menu.node.item.manageNodes") {
390
391                         /**
392                          * {@inheritDoc}
393                          */
394                         @SuppressWarnings("synthetic-access")
395                         public void actionPerformed(ActionEvent actionEvent) {
396                                 manageNodes();
397                         }
398                 };
399                 nodeConnectAction = new I18nAction("mainWindow.menu.node.item.connect", false) {
400
401                         @SuppressWarnings("synthetic-access")
402                         public void actionPerformed(ActionEvent actionEvent) {
403                                 nodeConnect();
404                         }
405
406                 };
407                 nodeDisconnectAction = new I18nAction("mainWindow.menu.node.item.disconnect", false) {
408
409                         /**
410                          * {@inheritDoc}
411                          */
412                         @SuppressWarnings("synthetic-access")
413                         public void actionPerformed(ActionEvent e) {
414                                 nodeDisconnect();
415                         }
416                 };
417                 List<Locale> availableLanguages = I18n.findAvailableLanguages();
418                 for (final Locale locale: availableLanguages) {
419                         I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) {
420
421                                 @SuppressWarnings("synthetic-access")
422                                 public void actionPerformed(ActionEvent e) {
423                                         changeLanguage(locale, this);
424                                 }
425
426                         };
427                         if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) {
428                                 languageAction.setEnabled(false);
429                         }
430                         languageActions.add(languageAction);
431                 }
432                 helpAboutAction = new I18nAction("mainWindow.menu.help.item.about") {
433
434                         /**
435                          * {@inheritDoc}
436                          */
437                         @SuppressWarnings("synthetic-access")
438                         public void actionPerformed(ActionEvent actionEvent) {
439                                 helpAbout();
440                         }
441                 };
442                 addProjectAction = new I18nAction("mainWindow.button.addProject") {
443
444                         /**
445                          * {@inheritDoc}
446                          */
447                         @SuppressWarnings("synthetic-access")
448                         public void actionPerformed(ActionEvent actionEvent) {
449                                 addProject();
450                         }
451                 };
452                 cloneProjectAction = new I18nAction("mainWindow.button.cloneProject") {
453
454                         /**
455                          * {@inheritDoc}
456                          */
457                         @SuppressWarnings("synthetic-access")
458                         public void actionPerformed(ActionEvent actionEvent) {
459                                 cloneProject();
460                         }
461                 };
462                 deleteProjectAction = new I18nAction("mainWindow.button.deleteProject") {
463
464                         /**
465                          * {@inheritDoc}
466                          */
467                         @SuppressWarnings("synthetic-access")
468                         public void actionPerformed(ActionEvent actionEvent) {
469                                 deleteProject();
470                         }
471                 };
472         }
473
474         /**
475          * Initializes all child dialogs.
476          */
477         private void initDialogs() {
478                 manageNodesDialog = new ManageNodesDialog(this);
479                 aboutDialog = new AboutDialog(this);
480                 configurationDialog = new ConfigurationDialog(this);
481         }
482
483         //
484         // PRIVATE ACTIONS
485         //
486
487         /**
488          * Shows the configuration dialog.
489          */
490         private void configure() {
491                 configurationDialog.setAntialias(antialias);
492                 configurationDialog.setControlFont(controlFont);
493                 configurationDialog.setUserFont(userFont);
494                 configurationDialog.setVisible(true);
495                 if (!configurationDialog.wasCancelled()) {
496                         antialias = configurationDialog.isAntialias();
497                         controlFont = configurationDialog.getControlFont();
498                         userFont = configurationDialog.getUserFont();
499                         saveConfig();
500                 }
501         }
502
503         /**
504          * Imports old jSite configuration.
505          */
506         private void importConfig() {
507                 /* TODO */
508         }
509
510         /**
511          * Quits jSite.
512          */
513         private void quit() {
514                 saveConfig();
515                 System.exit(0);
516         }
517
518         /**
519          * Pops up the “manage nodes” dialog.
520          */
521         private void manageNodes() {
522                 manageNodesDialog.setNodeList(nodeList);
523                 manageNodesDialog.setVisible(true);
524                 nodeList = manageNodesDialog.getNodeList();
525         }
526
527         /**
528          * Connects to the node.
529          */
530         private void nodeConnect() {
531                 /* TODO */
532         }
533
534         /**
535          * Disconnects from the node.
536          */
537         private void nodeDisconnect() {
538                 /* TODO */
539         }
540
541         /**
542          * Changes the language of the interface. This method also disables the
543          * action for the newly set language and enables all others.
544          *
545          * @param newLocale
546          *            The new language
547          * @param languageAction
548          *            The action that triggered the change
549          */
550         private void changeLanguage(Locale newLocale, I18nAction languageAction) {
551                 for (I18nAction i18nAction: languageActions) {
552                         i18nAction.setEnabled(i18nAction != languageAction);
553                 }
554                 I18n.setLocale(newLocale);
555         }
556
557         /**
558          * Shows the “about” dialog.
559          */
560         private void helpAbout() {
561                 aboutDialog.setVisible(true);
562         }
563
564         /**
565          * Adds a project.
566          */
567         private void addProject() {
568                 Project project = new Project();
569                 project.setName("New Project");
570                 project.setDescription("");
571         }
572
573         /**
574          * Clones a project.
575          */
576         private void cloneProject() {
577                 /* TODO */
578         }
579
580         /**
581          * Deletes a project.
582          */
583         private void deleteProject() {
584                 /* TODO */
585         }
586
587         //
588         // INTERFACE CoreListener
589         //
590
591         /**
592          * {@inheritDoc}
593          */
594         public void loadingProjectsFailed(String directory) {
595                 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.projectLoadingFailed.message", directory), I18n.get("mainWindow.error.projectLoadingFailed.title"), JOptionPane.ERROR_MESSAGE);
596         }
597
598         /**
599          * {@inheritDoc}
600          */
601         public void coreLoaded() {
602                 this.nodeList = core.getNodes();
603                 manageNodesDialog.setNodeList(nodeList);
604                 mainWindow.setVisible(true);
605                 mainWindow.setStatusBarText("Core loaded.");
606         }
607
608         /**
609          * {@inheritDoc}
610          */
611         public void nodeConnected(Node node) {
612                 /* TODO */
613         }
614
615         /**
616          * {@inheritDoc}
617          */
618         public void nodeConnecting(Node node) {
619                 /* TODO */
620         }
621
622         /**
623          * {@inheritDoc}
624          */
625         public void nodeDisconnected(Node node) {
626                 /* TODO */
627         }
628
629 }