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