]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/function/AboutScreen.java
Version 11, August 2010
[GpsPrune.git] / tim / prune / function / AboutScreen.java
1 package tim.prune.function;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
7 import java.awt.Font;
8 import java.awt.GridBagConstraints;
9 import java.awt.GridBagLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.KeyEvent;
13 import java.awt.event.KeyListener;
14 import java.io.ByteArrayOutputStream;
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.zip.GZIPInputStream;
20
21 import javax.swing.BorderFactory;
22 import javax.swing.BoxLayout;
23 import javax.swing.JButton;
24 import javax.swing.JDialog;
25 import javax.swing.JEditorPane;
26 import javax.swing.JLabel;
27 import javax.swing.JPanel;
28 import javax.swing.JScrollPane;
29 import javax.swing.JTabbedPane;
30 import javax.swing.JTextArea;
31
32 import tim.prune.App;
33 import tim.prune.ExternalTools;
34 import tim.prune.GenericFunction;
35 import tim.prune.GpsPruner;
36 import tim.prune.I18nManager;
37 import tim.prune.jpeg.ExifGateway;
38 import tim.prune.threedee.WindowFactory;
39
40 /**
41  * Class to represent the "About" popup window
42  */
43 public class AboutScreen extends GenericFunction
44 {
45         private JDialog _dialog = null;
46         private JTabbedPane _tabs = null;
47         private JButton _okButton = null;
48         private JTextArea _aboutTextArea = null;
49         /** Labels for whether tools installed or not */
50         private JLabel[] _installedLabels = null;
51
52
53         /**
54          * Constructor
55          * @param inApp app object
56          */
57         public AboutScreen(App inApp)
58         {
59                 super(inApp);
60         }
61
62         /**
63          * Return the name key for this function
64          */
65         public String getNameKey()
66         {
67                 return "function.about";
68         }
69
70         /**
71          * @return the contents of the window as a Component
72          */
73         private Component makeContents()
74         {
75                 JPanel mainPanel = new JPanel();
76                 mainPanel.setLayout(new BorderLayout());
77
78                 _tabs = new JTabbedPane();
79                 mainPanel.add(_tabs, BorderLayout.CENTER);
80
81                 JPanel aboutPanel = new JPanel();
82                 aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS));
83                 aboutPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
84                 JLabel titleLabel = new JLabel("Prune");
85                 titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
86                 titleLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
87                 aboutPanel.add(titleLabel);
88                 JLabel versionLabel = new JLabel(I18nManager.getText("dialog.about.version") + ": " + GpsPruner.VERSION_NUMBER);
89                 versionLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
90                 aboutPanel.add(versionLabel);
91                 JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPruner.BUILD_NUMBER);
92                 buildLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
93                 aboutPanel.add(buildLabel);
94                 aboutPanel.add(new JLabel(" "));
95                 StringBuffer descBuffer = new StringBuffer();
96                 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext1")).append("</p>");
97                 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext2")).append("</p>");
98                 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext3")).append("</p>");
99                 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ")
100                         .append("deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, nederlands,<br>" +
101                                 " polski, portugu\u00EAs, \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, " +
102                                 "<br> \u010de\u0161tina, rom\u00E2n\u0103, afrikaans, bahasa indonesia, farsi").append("</p>");
103                 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>");
104                 JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString());
105                 descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
106                 descPane.setEditable(false);
107                 descPane.setOpaque(false);
108                 descPane.setAlignmentX(JEditorPane.CENTER_ALIGNMENT);
109
110                 aboutPanel.add(descPane);
111                 aboutPanel.add(new JLabel(" "));
112                 _tabs.add(I18nManager.getText("function.about"), aboutPanel);
113
114                 // Second pane for system info
115                 JPanel sysInfoPanel = new JPanel();
116                 GridBagLayout gridBag = new GridBagLayout();
117                 sysInfoPanel.setLayout(gridBag);
118                 GridBagConstraints constraints = new GridBagConstraints();
119                 constraints.weightx = 0.0; constraints.weighty = 0.0;
120                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
121                         new JLabel(I18nManager.getText("dialog.about.systeminfo.os") + " : "),
122                         0, 0);
123                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
124                         new JLabel(System.getProperty("os.name")),
125                         1, 0);
126                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
127                         new JLabel(I18nManager.getText("dialog.about.systeminfo.java") + " : "),
128                         0, 1);
129                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
130                         new JLabel(System.getProperty("java.runtime.version")),
131                         1, 1);
132                 // Create install labels to be populated later
133                 final int NUM_INSTALL_CHECKS = 4;
134                 _installedLabels = new JLabel[NUM_INSTALL_CHECKS];
135                 for (int i=0; i<NUM_INSTALL_CHECKS; i++) {
136                         _installedLabels[i] = new JLabel("...");
137                 }
138                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
139                         new JLabel(I18nManager.getText("dialog.about.systeminfo.java3d") + " : "),
140                         0, 2);
141                 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[0], 1, 2);
142                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
143                         new JLabel(I18nManager.getText("dialog.about.systeminfo.exiftool") + " : "),
144                         0, 3);
145                 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[1], 1, 3);
146                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
147                         new JLabel(I18nManager.getText("dialog.about.systeminfo.gpsbabel") + " : "),
148                         0, 4);
149                 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[2], 1, 4);
150                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
151                         new JLabel(I18nManager.getText("dialog.about.systeminfo.gnuplot") + " : "),
152                         0, 5);
153                 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[3], 1, 5);
154                 // Exif library
155                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
156                         new JLabel(I18nManager.getText("dialog.about.systeminfo.exiflib") + " : "),
157                         0, 6);
158                 final String exiflibkey = "dialog.about.systeminfo.exiflib." + ExifGateway.getDescriptionKey();
159                 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
160                         new JLabel(I18nManager.getText(exiflibkey)), 1, 6);
161                 _tabs.add(I18nManager.getText("dialog.about.systeminfo"), sysInfoPanel);
162
163                 // Third pane for credits
164                 JPanel creditsPanel = new JPanel();
165                 gridBag = new GridBagLayout();
166                 creditsPanel.setLayout(gridBag);
167                 constraints = new GridBagConstraints();
168                 constraints.weightx = 0.0; constraints.weighty = 0.0;
169
170                 addToGridBagPanel(creditsPanel, gridBag, constraints,
171                         new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
172                         0, 0);
173                 addToGridBagPanel(creditsPanel, gridBag, constraints,
174                         new JLabel("activityworkshop.net"),
175                         1, 0);
176                 addToGridBagPanel(creditsPanel, gridBag, constraints,
177                         new JLabel(I18nManager.getText("dialog.about.credits.exifcode") + " : "),
178                         0, 1);
179                 addToGridBagPanel(creditsPanel, gridBag, constraints,
180                         new JLabel("Drew Noakes"),
181                         1, 1);
182                 addToGridBagPanel(creditsPanel, gridBag, constraints,
183                         new JLabel(I18nManager.getText("dialog.about.credits.icons") + " : "),
184                         0, 2);
185                 addToGridBagPanel(creditsPanel, gridBag, constraints,
186                         new JLabel("Eclipse"),
187                         1, 2);
188                 addToGridBagPanel(creditsPanel, gridBag, constraints,
189                         new JLabel(I18nManager.getText("dialog.about.credits.translators") + " : "),
190                         0, 3);
191                 addToGridBagPanel(creditsPanel, gridBag, constraints,
192                         new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"),
193                         1, 3);
194                 addToGridBagPanel(creditsPanel, gridBag, constraints,
195                         new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko,"),
196                         1, 4);
197                 addToGridBagPanel(creditsPanel, gridBag, constraints,
198                         new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d"),
199                         1, 5);
200                 addToGridBagPanel(creditsPanel, gridBag, constraints,
201                         new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
202                         0, 6);
203                 addToGridBagPanel(creditsPanel, gridBag, constraints,
204                         new JLabel("Open Office, Gpsdrive, Babelfish, Leo, Launchpad"),
205                         1, 6);
206                 addToGridBagPanel(creditsPanel, gridBag, constraints,
207                         new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "),
208                         0, 7);
209                 addToGridBagPanel(creditsPanel, gridBag, constraints,
210                         new JLabel("Debian Linux, Sun Java, Eclipse, Svn, Gimp, Inkscape"),
211                         1, 7);
212                 addToGridBagPanel(creditsPanel, gridBag, constraints,
213                         new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "),
214                         0, 8);
215                 addToGridBagPanel(creditsPanel, gridBag, constraints,
216                         new JLabel("Openstreetmap, Povray, Exiftool, Google Earth, Gpsbabel, Gnuplot"),
217                         1, 8);
218                 addToGridBagPanel(creditsPanel, gridBag, constraints,
219                         new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "),
220                         0, 9);
221                 addToGridBagPanel(creditsPanel, gridBag, constraints,
222                         new JLabel("Friends and loved ones, for encouragement and support"),
223                         1, 9);
224                 _tabs.add(I18nManager.getText("dialog.about.credits"), creditsPanel);
225
226                 // Read me
227                 JPanel readmePanel = new JPanel();
228                 readmePanel.setLayout(new BorderLayout());
229                 _aboutTextArea = new JTextArea(I18nManager.getText("details.photo.loading"));
230                 // Set readme text in separate thread so that about screen pops up sooner
231                 new Thread(new Runnable() {
232                         public void run() {
233                                 _aboutTextArea.setText(getReadmeText());
234                         }
235                 }).start();
236                 _aboutTextArea.setEditable(false);
237                 _aboutTextArea.setLineWrap(true); _aboutTextArea.setWrapStyleWord(true);
238                 JScrollPane scrollPane = new JScrollPane(_aboutTextArea);
239                 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
240                 scrollPane.setPreferredSize(new Dimension(600, 130));
241                 readmePanel.add(scrollPane, BorderLayout.CENTER);
242                 _tabs.add(I18nManager.getText("dialog.about.readme"), readmePanel);
243
244                 // OK button at the bottom
245                 JPanel okPanel = new JPanel();
246                 okPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
247                 _okButton = new JButton(I18nManager.getText("button.ok"));
248                 _okButton.addActionListener(new ActionListener()
249                 {
250                         public void actionPerformed(ActionEvent e)
251                         {
252                                 _dialog.dispose();
253                         }
254                 });
255                 _okButton.addKeyListener(new KeyListener() {
256                         public void keyPressed(KeyEvent e)
257                         {
258                                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
259                         }
260                         public void keyTyped(KeyEvent e) {}
261                         public void keyReleased(KeyEvent e) {}
262                 });
263                 okPanel.add(_okButton);
264                 mainPanel.add(okPanel, BorderLayout.SOUTH);
265                 return mainPanel;
266         }
267
268         /**
269          * Helper function to reduce complexity of gui-making code
270          * when adding labels to a GridBagLayout
271          * @param inPanel panel to add to
272          * @param inLayout GridBagLayout object
273          * @param inConstraints GridBagConstraints object
274          * @param inLabel label to add
275          * @param inX grid x
276          * @param inY grid y
277          */
278         private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout,
279                 GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY)
280         {
281                 // set x and y in constraints
282                 inConstraints.gridx = inX;
283                 inConstraints.gridy = inY;
284                 // set anchor
285                 inConstraints.anchor = (inX == 0?GridBagConstraints.EAST:GridBagConstraints.WEST);
286                 // set constraints to label
287                 inLayout.setConstraints(inLabel, inConstraints);
288                 // add label to panel
289                 inPanel.add(inLabel);
290         }
291
292         /**
293          * @return text from the readme file
294          */
295         private String getReadmeText()
296         {
297                 // First, try locally-held readme.txt if available (as it normally should be)
298                 // Readme file can either be in file system or packed in the same jar as code
299                 String errorMessage = null;
300                 try
301                 {
302                         // For some reason using ../readme.txt doesn't work, so need absolute path
303                         InputStream in = AboutScreen.class.getResourceAsStream("/tim/prune/readme.txt");
304                         if (in != null) {
305                                 byte[] buffer = new byte[in.available()];
306                                 in.read(buffer);
307                                 in.close();
308                                 return new String(buffer);
309                         }
310                 }
311                 catch (IOException e) {
312                         errorMessage =  e.getMessage();
313                 }
314                 // Locally-held file failed, so try to find gz file installed on system (eg Debian)
315                 try
316                 {
317                         File gzFile = new File("/usr/share/doc/gpsprune/readme.txt.gz");
318                         if (gzFile.exists())
319                         {
320                                 // Copy decompressed bytes from gz file into out
321                                 InputStream in = new GZIPInputStream(new FileInputStream(gzFile));
322                                 ByteArrayOutputStream out = new ByteArrayOutputStream();
323                                 byte[] buffer = new byte[8 * 1024];
324                                 int count = 0;
325                                 do {
326                                         out.write(buffer, 0, count);
327                                         count = in.read(buffer, 0, buffer.length);
328                                 } while (count != -1);
329                                 out.close();
330                                 in.close();
331                                 return out.toString();
332                         }
333                 }
334                 catch (IOException e) {
335                         System.err.println("Exception trying to get readme.gz : " + e.getMessage());
336                 }
337                 // Only show first error message if couldn't get readme from gz either
338                 if (errorMessage != null) {
339                         System.err.println("Exception trying to get readme: " + errorMessage);
340                 }
341                 return I18nManager.getText("error.readme.notfound");
342         }
343
344         /**
345          * Show window
346          */
347         public void begin()
348         {
349                 if (_dialog == null)
350                 {
351                         _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()));
352                         _dialog.getContentPane().add(makeContents());
353                         _dialog.pack();
354                 }
355                 _tabs.setSelectedIndex(0);
356                 checkInstalls();
357                 _dialog.setVisible(true);
358                 _okButton.requestFocus();
359         }
360
361         /**
362          * Check the installed components and set the label texts accordingly
363          */
364         private void checkInstalls()
365         {
366                 String yesText = I18nManager.getText("dialog.about.yes");
367                 String noText = I18nManager.getText("dialog.about.no");
368                 _installedLabels[0].setText(WindowFactory.isJava3dEnabled()?yesText:noText);
369                 final int[] tools = {ExternalTools.TOOL_EXIFTOOL, ExternalTools.TOOL_GPSBABEL, ExternalTools.TOOL_GNUPLOT};
370                 for (int i=0; i<tools.length; i++) {
371                         _installedLabels[i+1].setText(ExternalTools.isToolInstalled(tools[i])?yesText:noText);
372                 }
373         }
374 }