001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.history; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.marktr; 006import static org.openstreetmap.josm.tools.I18n.tr; 007 008import java.awt.BorderLayout; 009import java.awt.FlowLayout; 010import java.awt.event.ActionEvent; 011import java.awt.event.KeyEvent; 012import java.awt.event.WindowAdapter; 013import java.awt.event.WindowEvent; 014 015import javax.swing.AbstractAction; 016import javax.swing.JComponent; 017import javax.swing.JDialog; 018import javax.swing.JOptionPane; 019import javax.swing.JPanel; 020import javax.swing.KeyStroke; 021 022import org.openstreetmap.josm.Main; 023import org.openstreetmap.josm.data.osm.PrimitiveId; 024import org.openstreetmap.josm.data.osm.history.History; 025import org.openstreetmap.josm.data.osm.history.HistoryDataSet; 026import org.openstreetmap.josm.data.osm.history.HistoryDataSetListener; 027import org.openstreetmap.josm.gui.SideButton; 028import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 029import org.openstreetmap.josm.gui.help.HelpUtil; 030import 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 org.openstreetmap.josm.data.osm.OsmPrimitive}. 035 * 036 */ 037public 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 093 /** 094 * constructor 095 * 096 * @param history the history to be displayed 097 */ 098 public HistoryBrowserDialog(History history) { 099 super(JOptionPane.getFrameForComponent(Main.parent), false); 100 build(); 101 setHistory(history); 102 renderTitle(history); 103 HistoryDataSet.getInstance().addHistoryDataSetListener(this); 104 addWindowListener(new WindowClosingAdapter()); 105 } 106 107 /** 108 * sets the current history 109 * @param history 110 */ 111 protected void setHistory(History history) { 112 browser.populate(history); 113 } 114 115 public void unlinkAsListener() { 116 getHistoryBrowser().getModel().unlinkAsListener(); 117 } 118 119 /* ---------------------------------------------------------------------------------- */ 120 /* interface HistoryDataSetListener */ 121 /* ---------------------------------------------------------------------------------- */ 122 @Override 123 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 124 if (primitiveId == null || primitiveId.equals(browser.getHistory().getPrimitiveId())) { 125 browser.populate(source.getHistory(browser.getHistory().getPrimitiveId())); 126 } 127 } 128 129 @Override 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 @Override 149 public void actionPerformed(ActionEvent e) { 150 run(); 151 } 152 } 153 154 class ReloadAction extends AbstractAction { 155 public ReloadAction() { 156 putValue(NAME, tr("Reload")); 157 putValue(SHORT_DESCRIPTION, tr("Reload the history from the server")); 158 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh")); 159 } 160 161 @Override 162 public void actionPerformed(ActionEvent e) { 163 HistoryLoadTask task = new HistoryLoadTask(); 164 task.add(browser.getHistory()); 165 Main.worker.submit(task); 166 } 167 } 168 169 class WindowClosingAdapter extends WindowAdapter { 170 @Override 171 public void windowClosing(WindowEvent e) { 172 closeAction.run(); 173 } 174 } 175 176 public HistoryBrowser getHistoryBrowser() { 177 return browser; 178 } 179}