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 /** Labels for whether tools installed or not */
49 private JLabel[] _installedLabels = null;
54 * @param inApp app object
56 public AboutScreen(App inApp)
62 * Return the name key for this function
64 public String getNameKey()
66 return "function.about";
70 * @return the contents of the window as a Component
72 private Component makeContents()
74 JPanel mainPanel = new JPanel();
75 mainPanel.setLayout(new BorderLayout());
77 _tabs = new JTabbedPane();
78 mainPanel.add(_tabs, BorderLayout.CENTER);
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("Prune");
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") + ": " + GpsPruner.VERSION_NUMBER);
88 versionLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
89 aboutPanel.add(versionLabel);
90 JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPruner.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("deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, polski, \u4e2d\u6587; (chinese)<br>" +
100 "schwiizerd\u00FC\u00FCtsch, \u65E5\u672C\u8A9E (japanese), t\u00FCrk\u00E7e, portugu\u00EAs, " +
101 "bahasa indonesia, rom\u00E2n\u0103").append("</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);
109 aboutPanel.add(descPane);
110 aboutPanel.add(new JLabel(" "));
111 _tabs.add(I18nManager.getText("function.about"), aboutPanel);
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") + " : "),
122 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
123 new JLabel(System.getProperty("os.name")),
125 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
126 new JLabel(I18nManager.getText("dialog.about.systeminfo.java") + " : "),
128 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
129 new JLabel(System.getProperty("java.runtime.version")),
131 // Create install labels to be populated later
132 final int NUM_INSTALL_CHECKS = 4;
133 _installedLabels = new JLabel[NUM_INSTALL_CHECKS];
134 for (int i=0; i<NUM_INSTALL_CHECKS; i++) {
135 _installedLabels[i] = new JLabel("...");
137 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
138 new JLabel(I18nManager.getText("dialog.about.systeminfo.java3d") + " : "),
140 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[0], 1, 2);
141 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
142 new JLabel(I18nManager.getText("dialog.about.systeminfo.exiftool") + " : "),
144 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[1], 1, 3);
145 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
146 new JLabel(I18nManager.getText("dialog.about.systeminfo.gpsbabel") + " : "),
148 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[2], 1, 4);
149 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
150 new JLabel(I18nManager.getText("dialog.about.systeminfo.gnuplot") + " : "),
152 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[3], 1, 5);
154 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
155 new JLabel(I18nManager.getText("dialog.about.systeminfo.exiflib") + " : "),
157 final String exiflibkey = "dialog.about.systeminfo.exiflib." + ExifGateway.getDescriptionKey();
158 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
159 new JLabel(I18nManager.getText(exiflibkey)), 1, 6);
160 _tabs.add(I18nManager.getText("dialog.about.systeminfo"), sysInfoPanel);
162 // Third pane for credits
163 JPanel creditsPanel = new JPanel();
164 gridBag = new GridBagLayout();
165 creditsPanel.setLayout(gridBag);
166 constraints = new GridBagConstraints();
167 constraints.weightx = 0.0; constraints.weighty = 0.0;
169 addToGridBagPanel(creditsPanel, gridBag, constraints,
170 new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
172 addToGridBagPanel(creditsPanel, gridBag, constraints,
173 new JLabel("activityworkshop.net"),
175 addToGridBagPanel(creditsPanel, gridBag, constraints,
176 new JLabel(I18nManager.getText("dialog.about.credits.exifcode") + " : "),
178 addToGridBagPanel(creditsPanel, gridBag, constraints,
179 new JLabel("Drew Noakes"),
181 addToGridBagPanel(creditsPanel, gridBag, constraints,
182 new JLabel(I18nManager.getText("dialog.about.credits.icons") + " : "),
184 addToGridBagPanel(creditsPanel, gridBag, constraints,
185 new JLabel("Eclipse"),
187 addToGridBagPanel(creditsPanel, gridBag, constraints,
188 new JLabel(I18nManager.getText("dialog.about.credits.translators") + " : "),
190 addToGridBagPanel(creditsPanel, gridBag, constraints,
191 new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"),
193 addToGridBagPanel(creditsPanel, gridBag, constraints,
194 new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko,"),
196 addToGridBagPanel(creditsPanel, gridBag, constraints,
197 new JLabel(" katpatuka, R\u00E9mi"),
199 addToGridBagPanel(creditsPanel, gridBag, constraints,
200 new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
202 addToGridBagPanel(creditsPanel, gridBag, constraints,
203 new JLabel("Open Office, Gpsdrive, Babelfish, Leo, Launchpad"),
205 addToGridBagPanel(creditsPanel, gridBag, constraints,
206 new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "),
208 addToGridBagPanel(creditsPanel, gridBag, constraints,
209 new JLabel("Debian Linux, Sun Java, Eclipse, Svn, Gimp, Inkscape"),
211 addToGridBagPanel(creditsPanel, gridBag, constraints,
212 new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "),
214 addToGridBagPanel(creditsPanel, gridBag, constraints,
215 new JLabel("Openstreetmap, Povray, Exiftool, Google Earth, Gpsbabel, Gnuplot"),
217 addToGridBagPanel(creditsPanel, gridBag, constraints,
218 new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "),
220 addToGridBagPanel(creditsPanel, gridBag, constraints,
221 new JLabel("Friends and loved ones, for encouragement and support"),
223 _tabs.add(I18nManager.getText("dialog.about.credits"), creditsPanel);
226 JPanel readmePanel = new JPanel();
227 readmePanel.setLayout(new BorderLayout());
228 JTextArea textArea = new JTextArea(getReadmeText());
229 textArea.setEditable(false);
230 textArea.setLineWrap(true); textArea.setWrapStyleWord(true);
231 JScrollPane scrollPane = new JScrollPane(textArea);
232 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
233 scrollPane.setPreferredSize(new Dimension(600, 130));
234 readmePanel.add(scrollPane, BorderLayout.CENTER);
235 _tabs.add(I18nManager.getText("dialog.about.readme"), readmePanel);
237 // OK button at the bottom
238 JPanel okPanel = new JPanel();
239 okPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
240 _okButton = new JButton(I18nManager.getText("button.ok"));
241 _okButton.addActionListener(new ActionListener()
243 public void actionPerformed(ActionEvent e)
248 _okButton.addKeyListener(new KeyListener() {
249 public void keyPressed(KeyEvent e)
251 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
253 public void keyTyped(KeyEvent e) {}
254 public void keyReleased(KeyEvent e) {}
256 okPanel.add(_okButton);
257 mainPanel.add(okPanel, BorderLayout.SOUTH);
262 * Helper function to reduce complexity of gui-making code
263 * when adding labels to a GridBagLayout
264 * @param inPanel panel to add to
265 * @param inLayout GridBagLayout object
266 * @param inConstraints GridBagConstraints object
267 * @param inLabel label to add
271 private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout,
272 GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY)
274 // set x and y in constraints
275 inConstraints.gridx = inX;
276 inConstraints.gridy = inY;
278 inConstraints.anchor = (inX == 0?GridBagConstraints.EAST:GridBagConstraints.WEST);
279 // set constraints to label
280 inLayout.setConstraints(inLabel, inConstraints);
281 // add label to panel
282 inPanel.add(inLabel);
286 * @return text from the readme file
288 private String getReadmeText()
290 // First, try locally-held readme.txt if available (as it normally should be)
291 // Readme file can either be in file system or packed in the same jar as code
292 String errorMessage = null;
295 // For some reason using ../readme.txt doesn't work, so need absolute path
296 InputStream in = AboutScreen.class.getResourceAsStream("/tim/prune/readme.txt");
298 byte[] buffer = new byte[in.available()];
301 return new String(buffer);
304 catch (IOException e) {
305 errorMessage = e.getMessage();
307 // Locally-held file failed, so try to find gz file installed on system (eg Debian)
310 File gzFile = new File("/usr/share/doc/gpsprune/readme.txt.gz");
313 // Copy decompressed bytes from gz file into out
314 InputStream in = new GZIPInputStream(new FileInputStream(gzFile));
315 ByteArrayOutputStream out = new ByteArrayOutputStream();
316 byte[] buffer = new byte[8 * 1024];
319 out.write(buffer, 0, count);
320 count = in.read(buffer, 0, buffer.length);
321 } while (count != -1);
324 return out.toString();
327 catch (IOException e) {
328 System.err.println("Exception trying to get readme.gz : " + e.getMessage());
330 // Only show first error message if couldn't get readme from gz either
331 if (errorMessage != null) {
332 System.err.println("Exception trying to get readme: " + errorMessage);
334 return I18nManager.getText("error.readme.notfound");
344 _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()));
345 _dialog.getContentPane().add(makeContents());
348 _tabs.setSelectedIndex(0);
350 _dialog.setVisible(true);
351 _okButton.requestFocus();
355 * Check the installed components and set the label texts accordingly
357 private void checkInstalls()
359 String yesText = I18nManager.getText("dialog.about.yes");
360 String noText = I18nManager.getText("dialog.about.no");
361 _installedLabels[0].setText(WindowFactory.isJava3dEnabled()?yesText:noText);
362 final int[] tools = {ExternalTools.TOOL_EXIFTOOL, ExternalTools.TOOL_GPSBABEL, ExternalTools.TOOL_GNUPLOT};
363 for (int i=0; i<tools.length; i++) {
364 _installedLabels[i+1].setText(ExternalTools.isToolInstalled(tools[i])?yesText:noText);