package tim.prune.function; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import tim.prune.App; import tim.prune.ExternalTools; import tim.prune.GenericFunction; import tim.prune.GpsPrune; import tim.prune.I18nManager; import tim.prune.jpeg.ExifGateway; import tim.prune.threedee.WindowFactory; /** * Class to represent the "About" popup window */ public class AboutScreen extends GenericFunction { private JDialog _dialog = null; private JTabbedPane _tabs = null; private JButton _okButton = null; private JTextArea _aboutTextArea = null; /** Labels for whether tools installed or not */ private JLabel[] _installedLabels = null; /** * Constructor * @param inApp app object */ public AboutScreen(App inApp) { super(inApp); } /** * Return the name key for this function */ public String getNameKey() { return "function.about"; } /** * @return the contents of the window as a Component */ private Component makeContents() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); _tabs = new JTabbedPane(); mainPanel.add(_tabs, BorderLayout.CENTER); JPanel aboutPanel = new JPanel(); aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS)); aboutPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JLabel titleLabel = new JLabel("GpsPrune"); titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24)); titleLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(titleLabel); JLabel versionLabel = new JLabel(I18nManager.getText("dialog.about.version") + ": " + GpsPrune.VERSION_NUMBER); versionLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(versionLabel); JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPrune.BUILD_NUMBER); buildLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(buildLabel); aboutPanel.add(new JLabel(" ")); StringBuffer descBuffer = new StringBuffer(); descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext1")).append("</p>"); descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext2")).append("</p>"); descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext3")).append("</p>"); descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ") .append("afrikaans, \u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano,<br>" + " magyar, nederlands, polski, portugu\u00EAs, rom\u00E2n\u0103, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian), \u4e2d\u6587 (chinese),<br>" + " \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, ukrainian</p>"); descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>"); JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString()); descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); descPane.setEditable(false); descPane.setOpaque(false); descPane.setAlignmentX(JEditorPane.CENTER_ALIGNMENT); aboutPanel.add(descPane); aboutPanel.add(new JLabel(" ")); _tabs.add(I18nManager.getText("function.about"), aboutPanel); // Second pane for system info JPanel sysInfoPanel = new JPanel(); GridBagLayout gridBag = new GridBagLayout(); sysInfoPanel.setLayout(gridBag); GridBagConstraints constraints = new GridBagConstraints(); constraints.weightx = 0.0; constraints.weighty = 0.0; addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.os") + " : "), 0, 0); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(System.getProperty("os.name")), 1, 0); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.java") + " : "), 0, 1); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(System.getProperty("java.runtime.version")), 1, 1); // Create install labels to be populated later final int NUM_INSTALL_CHECKS = 5; _installedLabels = new JLabel[NUM_INSTALL_CHECKS]; for (int i=0; i<NUM_INSTALL_CHECKS; i++) { _installedLabels[i] = new JLabel("..."); } addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.java3d") + " : "), 0, 2); addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[0], 1, 2); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.exiftool") + " : "), 0, 3); addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[1], 1, 3); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.gpsbabel") + " : "), 0, 4); addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[2], 1, 4); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.gnuplot") + " : "), 0, 5); addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[3], 1, 5); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel("Xerces : "), 0, 6); addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[4], 1, 6); // Exif library addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.systeminfo.exiflib") + " : "), 0, 7); final String exiflibkey = "dialog.about.systeminfo.exiflib." + ExifGateway.getDescriptionKey(); addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(I18nManager.getText(exiflibkey)), 1, 7); _tabs.add(I18nManager.getText("dialog.about.systeminfo"), sysInfoPanel); // Third pane for credits JPanel creditsPanel = new JPanel(); gridBag = new GridBagLayout(); creditsPanel.setLayout(gridBag); constraints = new GridBagConstraints(); constraints.weightx = 0.0; constraints.weighty = 0.0; constraints.ipady = 3; addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "), 0, 0); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("activityworkshop.net"), 1, 0); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.exifcode") + " : "), 0, 1); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Drew Noakes"), 1, 1); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.icons") + " : "), 0, 2); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Eclipse"), 1, 2); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.translators") + " : "), 0, 3); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"), 1, 3); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko,"), 1, 4); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d, Gy\u00F6rgy,"), 1, 5); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(" HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian, Roman"), 1, 6); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "), 0, 7); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Open Office, Gpsdrive, Babelfish, Leo, Launchpad"), 1, 7); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "), 0, 8); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Debian Linux, Sun Java, OpenJDK, Eclipse, Svn, Gimp, Inkscape"), 1, 8); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "), 0, 9); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Openstreetmap, Povray, Exiftool, Gpsbabel, Gnuplot"), 1, 9); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "), 0, 10); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel("Friends and loved ones, for encouragement and support"), 1, 10); _tabs.add(I18nManager.getText("dialog.about.credits"), creditsPanel); // Read me JPanel readmePanel = new JPanel(); readmePanel.setLayout(new BorderLayout()); _aboutTextArea = new JTextArea(I18nManager.getText("details.photo.loading")); // Set readme text in separate thread so that about screen pops up sooner new Thread(new Runnable() { public void run() { _aboutTextArea.setText(getReadmeText()); } }).start(); _aboutTextArea.setEditable(false); _aboutTextArea.setLineWrap(true); _aboutTextArea.setWrapStyleWord(true); JScrollPane scrollPane = new JScrollPane(_aboutTextArea); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setPreferredSize(new Dimension(600, 130)); readmePanel.add(scrollPane, BorderLayout.CENTER); _tabs.add(I18nManager.getText("dialog.about.readme"), readmePanel); // OK button at the bottom JPanel okPanel = new JPanel(); okPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); _okButton = new JButton(I18nManager.getText("button.ok")); _okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _dialog.dispose(); } }); _okButton.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();} } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} }); okPanel.add(_okButton); mainPanel.add(okPanel, BorderLayout.SOUTH); return mainPanel; } /** * Helper function to reduce complexity of gui-making code * when adding labels to a GridBagLayout * @param inPanel panel to add to * @param inLayout GridBagLayout object * @param inConstraints GridBagConstraints object * @param inLabel label to add * @param inX grid x * @param inY grid y */ private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout, GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY) { // set x and y in constraints inConstraints.gridx = inX; inConstraints.gridy = inY; // set anchor inConstraints.anchor = (inX == 0?GridBagConstraints.EAST:GridBagConstraints.WEST); // set constraints to label inLayout.setConstraints(inLabel, inConstraints); // add label to panel inPanel.add(inLabel); } /** * @return text from the readme file */ private String getReadmeText() { // First, try locally-held readme.txt if available (as it normally should be) // Readme file can either be in file system or packed in the same jar as code String errorMessage = null; String readme = null; InputStream in = null; try { // For some reason using ../readme.txt doesn't work, so need absolute path in = AboutScreen.class.getResourceAsStream("/tim/prune/readme.txt"); if (in != null) { byte[] buffer = new byte[in.available()]; in.read(buffer); in.close(); readme = new String(buffer); } } catch (IOException e) { errorMessage = e.getMessage(); } finally { try {in.close();} catch (Exception e) {} } if (readme != null) {return readme;} // Locally-held file failed, so try to find gz file installed on system (eg Debian) try { File gzFile = new File("/usr/share/doc/gpsprune/readme.txt.gz"); if (gzFile.exists()) { // Copy decompressed bytes from gz file into out in = new GZIPInputStream(new FileInputStream(gzFile)); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[8 * 1024]; int count = 0; do { out.write(buffer, 0, count); count = in.read(buffer, 0, buffer.length); } while (count != -1); out.close(); in.close(); readme = out.toString(); } } catch (IOException e) { System.err.println("Exception trying to get readme.gz : " + e.getMessage()); } finally { try {in.close();} catch (Exception e) {} } if (readme != null) {return readme;} // Only show first error message if couldn't get readme from gz either if (errorMessage != null) { System.err.println("Exception trying to get readme: " + errorMessage); } return I18nManager.getText("error.readme.notfound"); } /** * Show window */ public void begin() { if (_dialog == null) { _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey())); _dialog.getContentPane().add(makeContents()); _dialog.pack(); } _tabs.setSelectedIndex(0); checkInstalls(); _dialog.setVisible(true); _okButton.requestFocus(); } /** * Check the installed components and set the label texts accordingly */ private void checkInstalls() { String yesText = I18nManager.getText("dialog.about.yes"); String noText = I18nManager.getText("dialog.about.no"); _installedLabels[0].setText(WindowFactory.isJava3dEnabled()?yesText:noText); final int[] tools = {ExternalTools.TOOL_EXIFTOOL, ExternalTools.TOOL_GPSBABEL, ExternalTools.TOOL_GNUPLOT, ExternalTools.TOOL_XERCES}; for (int i=0; i<tools.length; i++) { _installedLabels[i+1].setText(ExternalTools.isToolInstalled(tools[i])?yesText:noText); } } }