001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.history;
003
004 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005 import static org.openstreetmap.josm.tools.I18n.marktr;
006 import static org.openstreetmap.josm.tools.I18n.tr;
007
008 import java.awt.BorderLayout;
009 import java.awt.FlowLayout;
010 import java.awt.event.ActionEvent;
011 import java.awt.event.KeyEvent;
012 import java.awt.event.WindowAdapter;
013 import java.awt.event.WindowEvent;
014
015 import javax.swing.AbstractAction;
016 import javax.swing.JComponent;
017 import javax.swing.JDialog;
018 import javax.swing.JOptionPane;
019 import javax.swing.JPanel;
020 import javax.swing.KeyStroke;
021
022 import org.openstreetmap.josm.Main;
023 import org.openstreetmap.josm.data.osm.PrimitiveId;
024 import org.openstreetmap.josm.data.osm.history.History;
025 import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
026 import org.openstreetmap.josm.data.osm.history.HistoryDataSetListener;
027 import org.openstreetmap.josm.gui.SideButton;
028 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
029 import org.openstreetmap.josm.gui.help.HelpUtil;
030 import org.openstreetmap.josm.tools.ImageProvider;
031
032 /**
033 * This is non-modal dialog, always showing on top, which displays history information
034 * about a given {@link OsmPrimitive}.
035 *
036 */
037 public class HistoryBrowserDialog extends JDialog implements HistoryDataSetListener{
038
039 /** the embedded browser */
040 private HistoryBrowser browser;
041 private CloseAction closeAction;
042
043 /**
044 * displays the title for this dialog
045 *
046 * @param h the current history
047 */
048 protected void renderTitle(History h) {
049 String title = "";
050 switch(h.getEarliest().getType()) {
051 case NODE: title = marktr("History for node {0}"); break;
052 case WAY: title = marktr("History for way {0}"); break;
053 case RELATION: title = marktr("History for relation {0}"); break;
054 }
055 setTitle(tr(
056 title,
057 Long.toString(h.getId())
058 ));
059 }
060
061 /**
062 * builds the GUI
063 *
064 */
065 protected void build() {
066 setLayout(new BorderLayout());
067 browser = new HistoryBrowser();
068 add(browser, BorderLayout.CENTER);
069
070 JPanel pnl = new JPanel();
071 pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
072
073 SideButton btn = new SideButton(new ReloadAction());
074 btn.setName("btn.reload");
075 pnl.add(btn);
076
077 btn = new SideButton(closeAction = new CloseAction());
078 final String closeHistoryBrowserDialogKey = "CloseHistoryBrowserDialog";
079 KeyStroke escapeKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
080 getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(escapeKey, closeHistoryBrowserDialogKey);
081 getRootPane().getActionMap().put(closeHistoryBrowserDialogKey, closeAction);
082 btn.setName("btn.close");
083 pnl.add(btn);
084
085 btn = new SideButton(new ContextSensitiveHelpAction(ht("/Dialog/HistoryBrowser")));
086 btn.setName("btn.help");
087 pnl.add(btn);
088 add(pnl, BorderLayout.SOUTH);
089
090 HelpUtil.setHelpContext(getRootPane(), ht("/Dialog/HistoryBrowser"));
091
092 setSize(800, 500);
093 }
094
095 /**
096 * constructor
097 *
098 * @param history the history to be displayed
099 */
100 public HistoryBrowserDialog(History history) {
101 super(JOptionPane.getFrameForComponent(Main.parent), false);
102 build();
103 setHistory(history);
104 renderTitle(history);
105 HistoryDataSet.getInstance().addHistoryDataSetListener(this);
106 addWindowListener(new WindowClosingAdapter());
107 }
108
109 /**
110 * sets the current history
111 * @param history
112 */
113 protected void setHistory(History history) {
114 browser.populate(history);
115 }
116
117 public void unlinkAsListener() {
118 getHistoryBrowser().getModel().unlinkAsListener();
119 }
120
121 /* ---------------------------------------------------------------------------------- */
122 /* interface HistoryDataSetListener */
123 /* ---------------------------------------------------------------------------------- */
124 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) {
125 if (primitiveId == null || primitiveId.equals(browser.getHistory().getPrimitiveId())) {
126 browser.populate(source.getHistory(browser.getHistory().getPrimitiveId()));
127 }
128 }
129
130 public void historyDataSetCleared(HistoryDataSet source) {
131 closeAction.run();
132 }
133
134
135 class CloseAction extends AbstractAction {
136 public CloseAction() {
137 putValue(NAME, tr("Close"));
138 putValue(SHORT_DESCRIPTION, tr("Close the dialog"));
139 putValue(SMALL_ICON, ImageProvider.get("ok"));
140 }
141
142 public void run() {
143 getHistoryBrowser().getModel().unlinkAsListener();
144 HistoryDataSet.getInstance().removeHistoryDataSetListener(HistoryBrowserDialog.this);
145 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this);
146 }
147
148 public void actionPerformed(ActionEvent e) {
149 run();
150 }
151 }
152
153 class ReloadAction extends AbstractAction {
154 public ReloadAction() {
155 putValue(NAME, tr("Reload"));
156 putValue(SHORT_DESCRIPTION, tr("Reload the history from the server"));
157 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
158 }
159
160 public void actionPerformed(ActionEvent e) {
161 HistoryLoadTask task = new HistoryLoadTask();
162 task.add(browser.getHistory());
163 Main.worker.submit(task);
164 }
165 }
166
167 class WindowClosingAdapter extends WindowAdapter {
168 @Override
169 public void windowClosing(WindowEvent e) {
170 closeAction.run();
171 }
172 }
173
174 public HistoryBrowser getHistoryBrowser() {
175 return browser;
176 }
177 }