1 package tim.prune.function;
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
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;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.zip.GZIPInputStream;
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;
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;
41 * Class to represent the "About" popup window
43 public class AboutScreen extends GenericFunction
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;
55 * @param inApp app object
57 public AboutScreen(App inApp)
63 * Return the name key for this function
65 public String getNameKey()
67 return "function.about";
71 * @return the contents of the window as a Component
73 private Component makeContents()
75 JPanel mainPanel = new JPanel();
76 mainPanel.setLayout(new BorderLayout());
78 _tabs = new JTabbedPane();
79 mainPanel.add(_tabs, BorderLayout.CENTER);
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("\u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, magyar,<br>" +
101 " nederlands, polski, portugu\u00EAs, \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean),<br>" +
102 " schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, rom\u00E2n\u0103, afrikaans, bahasa indonesia, farsi</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);
110 aboutPanel.add(descPane);
111 aboutPanel.add(new JLabel(" "));
112 _tabs.add(I18nManager.getText("function.about"), aboutPanel);
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") + " : "),
123 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
124 new JLabel(System.getProperty("os.name")),
126 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
127 new JLabel(I18nManager.getText("dialog.about.systeminfo.java") + " : "),
129 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
130 new JLabel(System.getProperty("java.runtime.version")),
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("...");
138 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
139 new JLabel(I18nManager.getText("dialog.about.systeminfo.java3d") + " : "),
141 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[0], 1, 2);
142 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
143 new JLabel(I18nManager.getText("dialog.about.systeminfo.exiftool") + " : "),
145 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[1], 1, 3);
146 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
147 new JLabel(I18nManager.getText("dialog.about.systeminfo.gpsbabel") + " : "),
149 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[2], 1, 4);
150 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
151 new JLabel(I18nManager.getText("dialog.about.systeminfo.gnuplot") + " : "),
153 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[3], 1, 5);
155 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
156 new JLabel(I18nManager.getText("dialog.about.systeminfo.exiflib") + " : "),
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);
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;
170 addToGridBagPanel(creditsPanel, gridBag, constraints,
171 new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
173 addToGridBagPanel(creditsPanel, gridBag, constraints,
174 new JLabel("activityworkshop.net"),
176 addToGridBagPanel(creditsPanel, gridBag, constraints,
177 new JLabel(I18nManager.getText("dialog.about.credits.exifcode") + " : "),
179 addToGridBagPanel(creditsPanel, gridBag, constraints,
180 new JLabel("Drew Noakes"),
182 addToGridBagPanel(creditsPanel, gridBag, constraints,
183 new JLabel(I18nManager.getText("dialog.about.credits.icons") + " : "),
185 addToGridBagPanel(creditsPanel, gridBag, constraints,
186 new JLabel("Eclipse"),
188 addToGridBagPanel(creditsPanel, gridBag, constraints,
189 new JLabel(I18nManager.getText("dialog.about.credits.translators") + " : "),
191 addToGridBagPanel(creditsPanel, gridBag, constraints,
192 new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"),
194 addToGridBagPanel(creditsPanel, gridBag, constraints,
195 new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko,"),
197 addToGridBagPanel(creditsPanel, gridBag, constraints,
198 new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d, Gy\u00F6rgy, HooAU"),
200 addToGridBagPanel(creditsPanel, gridBag, constraints,
201 new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
203 addToGridBagPanel(creditsPanel, gridBag, constraints,
204 new JLabel("Open Office, Gpsdrive, Babelfish, Leo, Launchpad"),
206 addToGridBagPanel(creditsPanel, gridBag, constraints,
207 new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "),
209 addToGridBagPanel(creditsPanel, gridBag, constraints,
210 new JLabel("Debian Linux, Sun Java, Eclipse, Svn, Gimp, Inkscape"),
212 addToGridBagPanel(creditsPanel, gridBag, constraints,
213 new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "),
215 addToGridBagPanel(creditsPanel, gridBag, constraints,
216 new JLabel("Openstreetmap, Povray, Exiftool, Google Earth, Gpsbabel, Gnuplot"),
218 addToGridBagPanel(creditsPanel, gridBag, constraints,
219 new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "),
221 addToGridBagPanel(creditsPanel, gridBag, constraints,
222 new JLabel("Friends and loved ones, for encouragement and support"),
224 _tabs.add(I18nManager.getText("dialog.about.credits"), creditsPanel);
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() {
233 _aboutTextArea.setText(getReadmeText());
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);
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()
250 public void actionPerformed(ActionEvent e)
255 _okButton.addKeyListener(new KeyListener() {
256 public void keyPressed(KeyEvent e)
258 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
260 public void keyTyped(KeyEvent e) {}
261 public void keyReleased(KeyEvent e) {}
263 okPanel.add(_okButton);
264 mainPanel.add(okPanel, BorderLayout.SOUTH);
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
278 private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout,
279 GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY)
281 // set x and y in constraints
282 inConstraints.gridx = inX;
283 inConstraints.gridy = inY;
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);
293 * @return text from the readme file
295 private String getReadmeText()
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 String readme = null;
301 InputStream in = null;
304 // For some reason using ../readme.txt doesn't work, so need absolute path
305 in = AboutScreen.class.getResourceAsStream("/tim/prune/readme.txt");
307 byte[] buffer = new byte[in.available()];
310 readme = new String(buffer);
313 catch (IOException e) {
314 errorMessage = e.getMessage();
317 try {in.close();} catch (Exception e) {}
319 if (readme != null) {return readme;}
321 // Locally-held file failed, so try to find gz file installed on system (eg Debian)
324 File gzFile = new File("/usr/share/doc/gpsprune/readme.txt.gz");
327 // Copy decompressed bytes from gz file into out
328 in = new GZIPInputStream(new FileInputStream(gzFile));
329 ByteArrayOutputStream out = new ByteArrayOutputStream();
330 byte[] buffer = new byte[8 * 1024];
333 out.write(buffer, 0, count);
334 count = in.read(buffer, 0, buffer.length);
335 } while (count != -1);
338 readme = out.toString();
341 catch (IOException e) {
342 System.err.println("Exception trying to get readme.gz : " + e.getMessage());
345 try {in.close();} catch (Exception e) {}
347 if (readme != null) {return readme;}
348 // Only show first error message if couldn't get readme from gz either
349 if (errorMessage != null) {
350 System.err.println("Exception trying to get readme: " + errorMessage);
352 return I18nManager.getText("error.readme.notfound");
362 _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()));
363 _dialog.getContentPane().add(makeContents());
366 _tabs.setSelectedIndex(0);
368 _dialog.setVisible(true);
369 _okButton.requestFocus();
373 * Check the installed components and set the label texts accordingly
375 private void checkInstalls()
377 String yesText = I18nManager.getText("dialog.about.yes");
378 String noText = I18nManager.getText("dialog.about.no");
379 _installedLabels[0].setText(WindowFactory.isJava3dEnabled()?yesText:noText);
380 final int[] tools = {ExternalTools.TOOL_EXIFTOOL, ExternalTools.TOOL_GPSBABEL, ExternalTools.TOOL_GNUPLOT};
381 for (int i=0; i<tools.length; i++) {
382 _installedLabels[i+1].setText(ExternalTools.isToolInstalled(tools[i])?yesText:noText);