001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Color; 007import java.awt.Dimension; 008import java.awt.GridBagLayout; 009import java.awt.event.ActionEvent; 010import java.awt.event.KeyEvent; 011import java.io.BufferedReader; 012import java.io.IOException; 013import java.io.InputStream; 014import java.io.InputStreamReader; 015 016import javax.swing.BorderFactory; 017import javax.swing.JLabel; 018import javax.swing.JPanel; 019import javax.swing.JScrollPane; 020import javax.swing.JTabbedPane; 021import javax.swing.JTextArea; 022 023import org.openstreetmap.josm.Main; 024import org.openstreetmap.josm.data.Version; 025import org.openstreetmap.josm.gui.ExtendedDialog; 026import org.openstreetmap.josm.gui.MainApplication; 027import org.openstreetmap.josm.gui.util.GuiHelper; 028import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 029import org.openstreetmap.josm.gui.widgets.JosmTextArea; 030import org.openstreetmap.josm.gui.widgets.UrlLabel; 031import org.openstreetmap.josm.plugins.PluginHandler; 032import org.openstreetmap.josm.tools.GBC; 033import org.openstreetmap.josm.tools.ImageProvider; 034import org.openstreetmap.josm.tools.Logging; 035import org.openstreetmap.josm.tools.Shortcut; 036import org.openstreetmap.josm.tools.Utils; 037 038/** 039 * Nice about screen. 040 * 041 * The REVISION resource is read and if present, it shows the revision information of the jar-file. 042 * 043 * @author imi 044 */ 045public final class AboutAction extends JosmAction { 046 047 /** 048 * Constructs a new {@code AboutAction}. 049 */ 050 public AboutAction() { 051 super(tr("About"), "logo", tr("Display the about screen."), 052 Shortcut.registerShortcut("system:about", tr("About"), 053 KeyEvent.VK_F1, Shortcut.SHIFT), true); 054 } 055 056 @Override 057 public void actionPerformed(ActionEvent e) { 058 final JTabbedPane about = new JTabbedPane(); 059 060 Version version = Version.getInstance(); 061 062 JosmTextArea readme = new JosmTextArea(); 063 readme.setFont(GuiHelper.getMonospacedFont(readme)); 064 readme.setEditable(false); 065 setTextFromResourceFile(readme, "/README"); 066 readme.setCaretPosition(0); 067 068 JosmTextArea revision = new JosmTextArea(); 069 revision.setFont(GuiHelper.getMonospacedFont(revision)); 070 revision.setEditable(false); 071 revision.setText(version.getReleaseAttributes()); 072 revision.setCaretPosition(0); 073 074 JosmTextArea contribution = new JosmTextArea(); 075 contribution.setEditable(false); 076 setTextFromResourceFile(contribution, "/CONTRIBUTION"); 077 contribution.setCaretPosition(0); 078 079 JosmTextArea license = new JosmTextArea(); 080 license.setEditable(false); 081 setTextFromResourceFile(license, "/LICENSE"); 082 license.setCaretPosition(0); 083 084 JPanel info = new JPanel(new GridBagLayout()); 085 final JMultilineLabel label = new JMultilineLabel("<html>" + 086 "<h1>" + "JOSM – " + tr("Java OpenStreetMap Editor") + "</h1>" + 087 "<p style='font-size:75%'></p>" + 088 "<p>" + tr("Version {0}", version.getVersionString()) + "</p>" + 089 "<p style='font-size:50%'></p>" + 090 "<p>" + tr("Last change at {0}", version.getTime()) + "</p>" + 091 "<p style='font-size:50%'></p>" + 092 "<p>" + tr("Java Version {0}", Utils.getSystemProperty("java.version")) + "</p>" + 093 "<p style='font-size:50%'></p>" + 094 "</html>"); 095 info.add(label, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 0, 0, 0)); 096 info.add(new JLabel(tr("Homepage")), GBC.std().insets(10, 0, 10, 0)); 097 info.add(new UrlLabel(Main.getJOSMWebsite(), 2), GBC.eol().fill(GBC.HORIZONTAL)); 098 info.add(GBC.glue(0, 5), GBC.eol()); 099 100 about.addTab(tr("Info"), info); 101 about.addTab(tr("Readme"), createScrollPane(readme)); 102 about.addTab(tr("Revision"), createScrollPane(revision)); 103 about.addTab(tr("Contribution"), createScrollPane(contribution)); 104 about.addTab(tr("License"), createScrollPane(license)); 105 about.addTab(tr("Plugins"), new JScrollPane(PluginHandler.getInfoPanel())); 106 107 // Intermediate panel to allow proper optionPane resizing 108 JPanel panel = new JPanel(new GridBagLayout()); 109 panel.setPreferredSize(new Dimension(890, 300)); 110 panel.add(new JLabel("", ImageProvider.get("logo.svg", ImageProvider.ImageSizes.ABOUT_LOGO), 111 JLabel.CENTER), GBC.std().insets(0, 5, 0, 0)); 112 panel.add(about, GBC.std().fill()); 113 114 GuiHelper.prepareResizeableOptionPane(panel, panel.getPreferredSize()); 115 int ret = new ExtendedDialog(Main.parent, tr("About JOSM..."), tr("OK"), tr("Report bug")) 116 .setButtonIcons("ok", "bug") 117 .setContent(panel, false) 118 .showDialog().getValue(); 119 if (2 == ret) { 120 MainApplication.getMenu().reportbug.actionPerformed(null); 121 } 122 } 123 124 /** 125 * Reads the contents of the resource file that is described by the {@code filePath}-attribute and puts that text 126 * into the {@link JTextArea} given by the {@code ta}-attribute. 127 * @param ta the {@link JTextArea} to put the files contents into 128 * @param filePath the path where the resource file to read resides 129 */ 130 private void setTextFromResourceFile(JTextArea ta, String filePath) { 131 InputStream is = getClass().getResourceAsStream(filePath); 132 if (is == null) { 133 displayErrorMessage(ta, tr("Failed to locate resource ''{0}''.", filePath)); 134 } else { 135 try (InputStreamReader reader = new InputStreamReader(is, "UTF-8"); 136 BufferedReader br = new BufferedReader(reader)) { 137 String line; 138 while ((line = br.readLine()) != null) { 139 ta.append(line+'\n'); 140 } 141 } catch (IOException e) { 142 Logging.warn(e); 143 displayErrorMessage(ta, tr("Failed to load resource ''{0}'', error is {1}.", filePath, e.toString())); 144 } 145 } 146 } 147 148 private static void displayErrorMessage(JTextArea ta, String msg) { 149 Logging.warn(msg); 150 ta.setForeground(new Color(200, 0, 0)); 151 ta.setText(msg); 152 } 153 154 private static JScrollPane createScrollPane(JosmTextArea area) { 155 area.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 156 area.setOpaque(false); 157 JScrollPane sp = new JScrollPane(area); 158 sp.setBorder(null); 159 sp.setOpaque(false); 160 return sp; 161 } 162}