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.GridBagConstraints;
008import java.awt.GridBagLayout;
009import java.awt.GridLayout;
010import java.io.UnsupportedEncodingException;
011import java.net.URLEncoder;
012import java.text.DateFormat;
013import java.util.Observable;
014import java.util.Observer;
015
016import javax.swing.JLabel;
017import javax.swing.JPanel;
018import javax.swing.JTextArea;
019
020import org.openstreetmap.josm.Main;
021import org.openstreetmap.josm.actions.AbstractInfoAction;
022import org.openstreetmap.josm.data.osm.OsmPrimitive;
023import org.openstreetmap.josm.data.osm.User;
024import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
025import org.openstreetmap.josm.gui.JosmUserIdentityManager;
026import org.openstreetmap.josm.gui.layer.OsmDataLayer;
027import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
028import org.openstreetmap.josm.gui.widgets.UrlLabel;
029import org.openstreetmap.josm.tools.CheckParameterUtil;
030
031/**
032 * VersionInfoPanel is an UI component which displays the basic properties of a version
033 * of a {@link OsmPrimitive}.
034 *
035 */
036public class VersionInfoPanel extends JPanel implements Observer{
037    private PointInTimeType pointInTimeType;
038    private HistoryBrowserModel model;
039    private JMultilineLabel lblInfo;
040    private UrlLabel lblUser;
041    private UrlLabel lblChangeset;
042    private JTextArea lblChangesetComment;
043
044    protected void build() {
045        JPanel pnl1 = new JPanel();
046        pnl1.setLayout(new BorderLayout());
047        lblInfo = new JMultilineLabel("");
048        pnl1.add(lblInfo, BorderLayout.CENTER);
049
050        JPanel pnlUserAndChangeset = new JPanel();
051        pnlUserAndChangeset.setLayout(new GridLayout(2,2));
052        lblUser = new UrlLabel("", 2);
053        pnlUserAndChangeset.add(new JLabel(tr("User:")));
054        pnlUserAndChangeset.add(lblUser);
055        pnlUserAndChangeset.add(new JLabel(tr("Changeset:")));
056        lblChangeset = new UrlLabel("", 2);
057        pnlUserAndChangeset.add(lblChangeset);
058
059        lblChangesetComment = new JTextArea();
060        lblChangesetComment.setLineWrap(true);
061        lblChangesetComment.setEditable(false);
062        lblChangesetComment.setOpaque(false);
063
064        setLayout(new GridBagLayout());
065        GridBagConstraints gc = new GridBagConstraints();
066        gc.anchor = GridBagConstraints.NORTHWEST;
067        gc.fill = GridBagConstraints.HORIZONTAL;
068        gc.weightx = 1.0;
069        gc.weighty = 1.0;
070        add(pnl1, gc);
071        gc.gridy = 1;
072        gc.weighty = 0.0;
073        add(pnlUserAndChangeset, gc);
074        gc.gridy = 2;
075        add(lblChangesetComment, gc);
076    }
077
078    protected HistoryOsmPrimitive getPrimitive() {
079        if (model == null || pointInTimeType == null)
080            return null;
081        return model.getPointInTime(pointInTimeType);
082    }
083
084    protected String getInfoText() {
085        HistoryOsmPrimitive primitive = getPrimitive();
086        if (primitive == null)
087            return "";
088        String text;
089        if (model.isLatest(primitive)) {
090            OsmDataLayer editLayer = Main.main.getEditLayer();
091            text = tr("<html>Version <strong>{0}</strong> currently edited in layer ''{1}''</html>",
092                    Long.toString(primitive.getVersion()),
093                    editLayer == null ? tr("unknown") : editLayer.getName()
094                    );
095        } else {
096            String date = "?";
097            if (primitive.getTimestamp() != null) {
098                date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(primitive.getTimestamp());
099            }
100            text = tr(
101                    "<html>Version <strong>{0}</strong> created on <strong>{1}</strong></html>",
102                    Long.toString(primitive.getVersion()), date);
103        }
104        return text;
105    }
106
107    /**
108     * Constructs a new {@code VersionInfoPanel}.
109     */
110    public VersionInfoPanel() {
111        pointInTimeType = null;
112        model = null;
113        build();
114    }
115
116    /**
117     * constructor
118     *
119     * @param model  the model (must not be null)
120     * @param pointInTimeType the point in time this panel visualizes (must not be null)
121     * @exception IllegalArgumentException thrown, if model is null
122     * @exception IllegalArgumentException thrown, if pointInTimeType is null
123     *
124     */
125    public VersionInfoPanel(HistoryBrowserModel model, PointInTimeType pointInTimeType) throws IllegalArgumentException {
126        CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType");
127        CheckParameterUtil.ensureParameterNotNull(model, "model");
128
129        this.model = model;
130        this.pointInTimeType = pointInTimeType;
131        model.addObserver(this);
132        build();
133    }
134
135    @Override
136    public void update(Observable o, Object arg) {
137        lblInfo.setText(getInfoText());
138
139        if (!model.isLatest(getPrimitive())) {
140            String url = AbstractInfoAction.getBaseBrowseUrl() + "/changeset/" + getPrimitive().getChangesetId();
141            lblChangeset.setUrl(url);
142            lblChangeset.setDescription(Long.toString(getPrimitive().getChangesetId()));
143            final String comment = getPrimitive().getChangeset() != null ? getPrimitive().getChangeset().get("comment") : null;
144            lblChangesetComment.setText(comment);
145            lblChangesetComment.setToolTipText(tr("Changeset comment"));
146
147            try {
148                if (getPrimitive().getUser() != null && getPrimitive().getUser() != User.getAnonymous()) {
149                    url = AbstractInfoAction.getBaseUserUrl() + "/" +  URLEncoder.encode(getPrimitive().getUser().getName(), "UTF-8").replaceAll("\\+", "%20");
150                    lblUser.setUrl(url);
151                } else {
152                    lblUser.setUrl(null);
153                }
154            } catch(UnsupportedEncodingException e) {
155                e.printStackTrace();
156                lblUser.setUrl(null);
157            }
158            String username = "";
159            if (getPrimitive().getUser() != null) {
160                username = getPrimitive().getUser().getName();
161            }
162            lblUser.setDescription(username);
163        } else {
164            String user = JosmUserIdentityManager.getInstance().getUserName();
165            if (user == null) {
166                lblUser.setDescription(tr("anonymous"));
167                lblUser.setUrl(null);
168            } else {
169                try {
170                    String url = AbstractInfoAction.getBaseUserUrl() + "/" +  URLEncoder.encode(user, "UTF-8").replaceAll("\\+", "%20");
171                    lblUser.setUrl(url);
172                } catch(UnsupportedEncodingException e) {
173                    e.printStackTrace();
174                    lblUser.setUrl(null);
175                }
176                lblUser.setDescription(user);
177            }
178            lblChangeset.setDescription(tr("none"));
179            lblChangeset.setUrl(null);
180        }
181    }
182}