add other projects’ licenses
[jSite2.git] / src / net / pterodactylus / jsite / gui / AboutDialog.java
1 /*
2  * jSite2 - AboutDialog.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.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.Font;
25 import java.awt.event.ActionEvent;
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.UnsupportedEncodingException;
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import javax.swing.BorderFactory;
34 import javax.swing.Box;
35 import javax.swing.BoxLayout;
36 import javax.swing.JButton;
37 import javax.swing.JComponent;
38 import javax.swing.JDialog;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTabbedPane;
43 import javax.swing.JTextArea;
44 import javax.swing.SwingConstants;
45
46 import net.pterodactylus.jsite.i18n.I18n;
47 import net.pterodactylus.jsite.i18n.I18nable;
48 import net.pterodactylus.jsite.i18n.gui.I18nAction;
49 import net.pterodactylus.jsite.i18n.gui.I18nLabel;
50 import net.pterodactylus.jsite.main.Version;
51 import net.pterodactylus.util.io.StreamCopier;
52 import net.pterodactylus.util.swing.SwingUtils;
53
54 /**
55  * An “about” dialog.
56  * 
57  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
58  * @version $Id$
59  */
60 public class AboutDialog extends JDialog implements I18nable {
61
62         /** A list of all contributors. */
63         private static final List<Contributor> CONTRIBUTORS = new ArrayList<Contributor>();
64         
65         /** A list of all code usages. */
66         private static final List<CodeUsage> CODE_USAGES = new ArrayList<CodeUsage>();
67
68         static {
69                 CONTRIBUTORS.add(new Contributor("David ‘Bombe’ Roden", "bombe@freenetproject.org", "Main code"));
70                 CODE_USAGES.add(new CodeUsage("Tango Desktop Project", "http://tango.freedesktop.org/", "Creative Commons Attribution-Share Alike 2.5", "Icons"));
71         }
72
73         /** The “okay” button action. */
74         private I18nAction okayAction;
75
76         /** The contributors label. */
77         private I18nLabel contributorsLabel;
78
79         /** The i18n maintainer label. */
80         private I18nLabel i18nMaintainerLabel;
81
82         /** The i18n maintainer’s name label. */
83         private JLabel i18nMaintainerNameLabel;
84
85         /** The “other people’s code used” label. */
86         private I18nLabel codeUsageLabel;
87         
88         /** The license header. */
89         private I18nLabel licenseHeaderLabel;
90
91         /** The tabbed pane with all the pages. */
92         private JTabbedPane pagesPane;
93
94         /**
95          * Creates a new “about” dialog.
96          * 
97          * @param swingInterface
98          *            The Swing interface
99          */
100         public AboutDialog(SwingInterface swingInterface) {
101                 super(swingInterface.getMainWindow(), I18n.get("aboutDialog.title"));
102                 initActions();
103                 initComponents();
104                 pack();
105                 SwingUtils.center(this);
106                 I18n.registerI18nable(this);
107         }
108
109         //
110         // PRIVATE METHODS
111         //
112
113         /**
114          * Initializes all actions.
115          */
116         private void initActions() {
117                 okayAction = new I18nAction("general.button.okay") {
118
119                         /**
120                          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
121                          */
122                         @SuppressWarnings("synthetic-access")
123                         public void actionPerformed(ActionEvent e) {
124                                 actionOkay();
125                         }
126                 };
127         }
128
129         /**
130          * Initiliazes all components of the dialog.
131          */
132         private void initComponents() {
133                 JPanel contentPane = new JPanel(new BorderLayout(12, 12));
134                 getContentPane().add(contentPane, BorderLayout.CENTER);
135                 contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
136
137                 pagesPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
138                 contentPane.add(pagesPane, BorderLayout.CENTER);
139
140                 pagesPane.addTab(I18n.get("aboutDialog.page.about.title"), createAboutPage());
141                 pagesPane.setToolTipTextAt(0, I18n.get("aboutDialog.page.about.shortDescription"));
142                 pagesPane.addTab(I18n.get("aboutDialog.page.license.title"), createLicensePage());
143                 pagesPane.setToolTipTextAt(1, I18n.get("aboutDialog.page.license.shortDescription"));
144
145                 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
146                 contentPane.add(buttonPanel, BorderLayout.PAGE_END);
147                 buttonPanel.add(new JButton(okayAction));
148         }
149
150         /**
151          * Creates the “about” page.
152          * 
153          * @return The “about” page
154          */
155         private JComponent createAboutPage() {
156                 JPanel aboutPanel = new JPanel(new BorderLayout(12, 12));
157                 aboutPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
158
159                 /* the about page consists of an image to the left and text to right. */
160                 JComponent textPanel = new Box(BoxLayout.PAGE_AXIS);
161                 aboutPanel.add(textPanel, BorderLayout.CENTER);
162
163                 JLabel jSiteHeaderLabel = new JLabel("jSite " + Version.getVersion());
164                 textPanel.add(jSiteHeaderLabel);
165                 textPanel.add(Box.createVerticalStrut(24));
166                 Font jSiteHeaderLabelFont = jSiteHeaderLabel.getFont();
167                 jSiteHeaderLabel.setFont(jSiteHeaderLabelFont.deriveFont(jSiteHeaderLabelFont.getSize2D() * 2).deriveFont(Font.BOLD));
168
169                 contributorsLabel = new I18nLabel("aboutDialog.page.about.label.contributor");
170                 textPanel.add(contributorsLabel);
171                 textPanel.add(Box.createVerticalStrut(12));
172                 contributorsLabel.setFont(contributorsLabel.getFont().deriveFont(Font.BOLD));
173
174                 for (Contributor contributor: CONTRIBUTORS) {
175                         JLabel contributorLabel = new JLabel(contributor.getName() + " <" + contributor.getEmail() + "> (" + contributor.getPart() + ")");
176                         textPanel.add(contributorLabel);
177                 }
178                 textPanel.add(Box.createVerticalStrut(24));
179
180                 i18nMaintainerLabel = new I18nLabel("aboutDialog.page.about.label.i18nMaintainer");
181                 textPanel.add(i18nMaintainerLabel);
182                 textPanel.add(Box.createVerticalStrut(12));
183                 i18nMaintainerLabel.setFont(i18nMaintainerLabel.getFont().deriveFont(Font.BOLD));
184
185                 i18nMaintainerNameLabel = new JLabel(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
186                 textPanel.add(i18nMaintainerNameLabel);
187                 textPanel.add(Box.createVerticalStrut(24));
188
189                 codeUsageLabel = new I18nLabel("aboutDialog.page.about.label.codeUsage");
190                 codeUsageLabel.setFont(codeUsageLabel.getFont().deriveFont(Font.BOLD));
191                 textPanel.add(codeUsageLabel);
192                 textPanel.add(Box.createVerticalStrut(12));
193                 
194                 for (CodeUsage codeUsage: CODE_USAGES) {
195                         JLabel usageLabel = new JLabel(codeUsage.getName() + " (" + codeUsage.getURL() + ", " + codeUsage.getLicense() + ")");
196                         textPanel.add(usageLabel);
197                 }
198                 
199                 return aboutPanel;
200         }
201
202         /**
203          * Creates the “license” page.
204          * 
205          * @return The “license” page
206          */
207         private JComponent createLicensePage() {
208                 JPanel licensePanel = new JPanel(new BorderLayout(12, 12));
209                 licensePanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
210
211                 JPanel licenseHeaderPanel = new JPanel(new FlowLayout());
212                 licensePanel.add(licenseHeaderPanel, BorderLayout.PAGE_START);
213
214                 licenseHeaderLabel = new I18nLabel("aboutDialog.page.license.header", Version.getVersion());
215                 licenseHeaderPanel.add(licenseHeaderLabel);
216                 licenseHeaderLabel.setAlignmentX(0.5f);
217
218                 String licenseText = loadLicenseText();
219                 JTextArea licenseArea = new JTextArea(licenseText, 25, 80);
220                 licensePanel.add(new JScrollPane(licenseArea), BorderLayout.CENTER);
221                 licenseArea.setFont(new Font("Courier", Font.PLAIN, licenseArea.getFont().getSize()));
222                 licenseArea.setEditable(false);
223
224                 return licensePanel;
225         }
226
227         /**
228          * Loads the license text.
229          * 
230          * @return The license text
231          */
232         private String loadLicenseText() {
233                 InputStream licenseInputStream = getClass().getResourceAsStream("/LICENSE");
234                 if (licenseInputStream == null) {
235                         return "Could not load LICENSE, check your installation.";
236                 }
237                 ByteArrayOutputStream licenseOutputStream = new ByteArrayOutputStream(20000);
238                 try {
239                         StreamCopier.copy(licenseInputStream, licenseOutputStream);
240                 } catch (IOException e) {
241                         return "Could not load LICENSE, check your installation.";
242                 }
243                 String licenseText;
244                 try {
245                         licenseText = new String(licenseOutputStream.toByteArray(), "ISO-8859-1");
246                 } catch (UnsupportedEncodingException e) {
247                         licenseText = new String(licenseOutputStream.toByteArray());
248                 }
249                 return licenseText;
250         }
251
252         //
253         // PRIVATE ACTIONS
254         //
255
256         /**
257          * Closes the dialog.
258          */
259         private void actionOkay() {
260                 setVisible(false);
261         }
262
263         //
264         // INTERFACE I18nable
265         //
266
267         /**
268          * @see net.pterodactylus.jsite.i18n.I18nable#updateI18n()
269          */
270         public void updateI18n() {
271                 contributorsLabel.updateI18n();
272                 licenseHeaderLabel.updateI18n();
273                 i18nMaintainerLabel.updateI18n();
274                 codeUsageLabel.updateI18n();
275                 i18nMaintainerNameLabel.setText(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
276                 okayAction.updateI18n();
277                 setTitle(I18n.get("aboutDialog.title"));
278                 pagesPane.setTitleAt(0, I18n.get("aboutDialog.page.about.title"));
279                 pagesPane.setToolTipTextAt(0, I18n.get("aboutDialog.page.about.shortDescription"));
280                 pagesPane.setTitleAt(1, I18n.get("aboutDialog.page.license.title"));
281                 pagesPane.setToolTipTextAt(1, I18n.get("aboutDialog.page.license.shortDescription"));
282                 SwingUtils.repackCentered(this);
283         }
284
285         /**
286          * Container for a contributor.
287          * 
288          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
289          * @version $Id$
290          */
291         private static class Contributor {
292
293                 /** The name of the contributor. */
294                 private final String name;
295
296                 /** The email address of the contributor. */
297                 private final String email;
298
299                 /** The parts where the contributor helped. */
300                 private final String part;
301
302                 /**
303                  * Creates a new contributor.
304                  * 
305                  * @param name
306                  *            The name of the contributor
307                  * @param email
308                  *            The email address of the contributor
309                  * @param part
310                  *            The parts where the contributor helped
311                  */
312                 public Contributor(String name, String email, String part) {
313                         this.name = name;
314                         this.email = email;
315                         this.part = part;
316                 }
317
318                 /**
319                  * Returns the name of the contributor.
320                  * 
321                  * @return The name of the contributor
322                  */
323                 String getName() {
324                         return name;
325                 }
326
327                 /**
328                  * Returns the email address of the contributor.
329                  * 
330                  * @return The email address of the contributor
331                  */
332                 String getEmail() {
333                         return email;
334                 }
335
336                 /**
337                  * Returns the parts where the contributor helped.
338                  * 
339                  * @return The parts where the contributor helped
340                  */
341                 String getPart() {
342                         return part;
343                 }
344
345         }
346
347         /**
348          * A code usage object describes code or other resources that have been
349          * taken from other projects.
350          * 
351          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
352          */
353         private static class CodeUsage {
354
355                 /** The name of the project. */
356                 private final String name;
357
358                 /** The URL of the project. */
359                 private final String url;
360
361                 /** The license of the project. */
362                 private final String license;
363
364                 /** The part that is used. */
365                 private final String part;
366
367                 /**
368                  * Creates a new code usage object.
369                  * 
370                  * @param name
371                  *            The name of the project
372                  * @param url
373                  *            The URL of the project
374                  * @param license
375                  *            The license of the used code
376                  * @param part
377                  *            The part that is used
378                  */
379                 public CodeUsage(String name, String url, String license, String part) {
380                         this.name = name;
381                         this.url = url;
382                         this.license = license;
383                         this.part = part;
384                 }
385
386                 /**
387                  * Returns the name of the project.
388                  * 
389                  * @return The name of the project
390                  */
391                 public String getName() {
392                         return name;
393                 }
394
395                 /**
396                  * Returns the URL of the project.
397                  * 
398                  * @return The URL of the project
399                  */
400                 public String getURL() {
401                         return url;
402                 }
403
404                 /**
405                  * Returns the license of the used part.
406                  * 
407                  * @return The license of the used part
408                  */
409                 public String getLicense() {
410                         return license;
411                 }
412
413                 /**
414                  * Returns the used part.
415                  * 
416                  * @return The used part
417                  */
418                 public String getPart() {
419                         return part;
420                 }
421
422         }
423
424 }