001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.history;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.BorderLayout;
007import java.awt.Dimension;
008
009import javax.swing.JPanel;
010import javax.swing.JScrollPane;
011import javax.swing.JSplitPane;
012import javax.swing.JTabbedPane;
013import javax.swing.event.ChangeEvent;
014import javax.swing.event.ChangeListener;
015
016import org.openstreetmap.josm.data.osm.OsmPrimitive;
017import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
018import org.openstreetmap.josm.data.osm.history.History;
019
020/**
021 * HistoryBrowser is an UI component which displays history information about an {@link OsmPrimitive}.
022 *
023 *
024 */
025public class HistoryBrowser extends JPanel {
026
027    /** the model */
028    private transient HistoryBrowserModel model;
029    private TagInfoViewer tagInfoViewer;
030    private NodeListViewer nodeListViewer;
031    private RelationMemberListViewer relationMemberListViewer;
032    private CoordinateInfoViewer coordinateInfoViewer;
033    private JTabbedPane tpViewers;
034
035    /**
036     * creates the table which shows the list of versions
037     *
038     * @return  the panel with the version table
039     */
040    protected JPanel createVersionTablePanel() {
041        JPanel pnl = new JPanel(new BorderLayout());
042
043        VersionTable versionTable = new VersionTable(model);
044        pnl.add(new JScrollPane(versionTable), BorderLayout.CENTER);
045        return pnl;
046    }
047
048    /**
049     * creates the panel which shows information about two different versions
050     * of the same {@link OsmPrimitive}.
051     *
052     * @return the panel
053     */
054    protected JPanel createVersionComparePanel() {
055        tpViewers = new JTabbedPane();
056
057        // create the viewers, but don't add them yet.
058        // see populate()
059        //
060        tagInfoViewer = new TagInfoViewer(model);
061        nodeListViewer = new NodeListViewer(model);
062        relationMemberListViewer = new RelationMemberListViewer(model);
063        coordinateInfoViewer = new CoordinateInfoViewer(model);
064        JPanel pnl = new JPanel(new BorderLayout());
065        pnl.add(tpViewers, BorderLayout.CENTER);
066
067        tpViewers.addChangeListener(new ChangeListener() {
068            @Override
069            public void stateChanged(ChangeEvent e) {
070                if (tpViewers.getSelectedComponent() == coordinateInfoViewer) {
071                    // while building the component size is not yet known, thus panning does not give reasonable results
072                    coordinateInfoViewer.setDisplayToFitMapMarkers();
073                }
074            }
075        });
076
077        return pnl;
078    }
079
080    /**
081     * builds the GUI
082     */
083    protected void build() {
084        JPanel left;
085        JPanel right;
086        setLayout(new BorderLayout());
087        JSplitPane pane = new JSplitPane(
088                JSplitPane.HORIZONTAL_SPLIT,
089                left = createVersionTablePanel(),
090                right = createVersionComparePanel()
091        );
092        add(pane, BorderLayout.CENTER);
093
094        pane.setOneTouchExpandable(true);
095        pane.setDividerLocation(300);
096
097        Dimension minimumSize = new Dimension(100, 50);
098        left.setMinimumSize(minimumSize);
099        right.setMinimumSize(minimumSize);
100    }
101
102    /**
103     * constructor
104     */
105    public HistoryBrowser() {
106        model = new HistoryBrowserModel();
107        build();
108    }
109
110    /**
111     * constructor
112     * @param history  the history of an {@link OsmPrimitive}
113     */
114    public HistoryBrowser(History history) {
115        this();
116        populate(history);
117    }
118
119    /**
120     * populates the browser with the history of a specific {@link OsmPrimitive}
121     *
122     * @param history the history
123     */
124    public void populate(History history) {
125        model.setHistory(history);
126
127        tpViewers.removeAll();
128
129        tpViewers.add(tagInfoViewer);
130        tpViewers.setTitleAt(0, tr("Tags"));
131
132        if (history.getEarliest().getType().equals(OsmPrimitiveType.NODE)) {
133            tpViewers.add(coordinateInfoViewer);
134            tpViewers.setTitleAt(1, tr("Coordinates"));
135        } else if (history.getEarliest().getType().equals(OsmPrimitiveType.WAY)) {
136            tpViewers.add(nodeListViewer);
137            tpViewers.setTitleAt(1, tr("Nodes"));
138        } else if (history.getEarliest().getType().equals(OsmPrimitiveType.RELATION)) {
139            tpViewers.add(relationMemberListViewer);
140            tpViewers.setTitleAt(1, tr("Members"));
141        }
142        revalidate();
143    }
144
145    /**
146     * replies the {@link History} currently displayed by this browser
147     *
148     * @return the current history
149     */
150    public History getHistory() {
151        return model.getHistory();
152    }
153
154    /**
155     * replies the model used by this browser
156     * @return the model
157     */
158    public HistoryBrowserModel getModel() {
159        return model;
160    }
161}