001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools.bugreport;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GridBagLayout;
007import java.io.IOException;
008
009import javax.swing.JButton;
010import javax.swing.JPanel;
011import javax.swing.SwingUtilities;
012
013import org.openstreetmap.josm.Main;
014import org.openstreetmap.josm.data.Version;
015import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
016import org.openstreetmap.josm.gui.widgets.UrlLabel;
017import org.openstreetmap.josm.tools.GBC;
018import org.openstreetmap.josm.tools.ImageProvider;
019import org.openstreetmap.josm.tools.WikiReader;
020
021/**
022 * This is a panel that displays the current JOSM version and the ability to update JOSM.
023 * @author Michael Zangl
024 * @since 10649
025 */
026public class JosmUpdatePanel extends JPanel {
027    private final JMultilineLabel testedVersionField;
028    private final int josmVersion;
029
030    /**
031     * Create a new {@link JosmUpdatePanel}
032     */
033    public JosmUpdatePanel() {
034        super(new GridBagLayout());
035        josmVersion = Version.getInstance().getVersion();
036
037        add(new JMultilineLabel(tr("Your current version of JOSM is {0}", josmVersion)), GBC.eol().fill(GBC.HORIZONTAL));
038        testedVersionField = new JMultilineLabel(tr("JOSM is searching for updates..."));
039        add(testedVersionField, GBC.eol().fill(GBC.HORIZONTAL));
040
041        checkCurrentVersion();
042    }
043
044    private void checkCurrentVersion() {
045        new Thread(this::readCurrentVersion, "JOSM version checker").start();
046    }
047
048    private void readCurrentVersion() {
049        int testedVersion = getTestedVersion();
050
051        if (testedVersion < 0) {
052            SwingUtilities.invokeLater(this::displayError);
053        } else if (josmVersion < testedVersion) {
054            SwingUtilities.invokeLater(() -> displayOutOfDate(testedVersion));
055        } else {
056            SwingUtilities.invokeLater(this::displayUpToDate);
057        }
058    }
059
060    private static int getTestedVersion() {
061        try {
062            String testedString = new WikiReader().read(Main.getJOSMWebsite() + "/wiki/TestedVersion?format=txt");
063            return Integer.parseInt(testedString.trim());
064        } catch (NumberFormatException | IOException e) {
065            Main.warn(e, "Unable to detect latest version of JOSM:");
066            return -1;
067        }
068    }
069
070    /**
071     * Display that there was an error while checking the current version.
072     */
073    private void displayError() {
074        testedVersionField.setText(tr("An error occured while checking if your JOSM instance is up to date."));
075        showUpdateButton();
076    }
077
078    private void displayUpToDate() {
079        testedVersionField.setText(tr("JOSM is up to date."));
080    }
081
082    private void displayOutOfDate(int testedVersion) {
083        testedVersionField
084                .setText(tr("JOSM is out of date. The current version is {0}. Try updating JOSM.", testedVersion));
085        showUpdateButton();
086    }
087
088    private void showUpdateButton() {
089        add(new JMultilineLabel(tr("Before you file a bug report make sure you have updated to the latest version of JOSM here:")), GBC.eol());
090        add(new UrlLabel(Main.getJOSMWebsite(), 2), GBC.eop().insets(8, 0, 0, 0));
091        JButton updateButton = new JButton(tr("Update JOSM"), ImageProvider.get("download"));
092        updateButton.addActionListener(e -> openJosmUpdateSite());
093        add(updateButton, GBC.eol().anchor(GBC.EAST));
094    }
095
096    private static void openJosmUpdateSite() {
097        try {
098            Main.platform.openUrl(Main.getJOSMWebsite());
099        } catch (IOException ex) {
100            Main.warn(ex, "Unable to access JOSM website:");
101        }
102    }
103}