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 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 @Override 125 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 126 if (primitiveId == null || primitiveId.equals(browser.getHistory().getPrimitiveId())) { 127 browser.populate(source.getHistory(browser.getHistory().getPrimitiveId())); 128 } 129 } 130 131 @Override 132 public void historyDataSetCleared(HistoryDataSet source) { 133 closeAction.run(); 134 } 135 136 137 class CloseAction extends AbstractAction { 138 public CloseAction() { 139 putValue(NAME, tr("Close")); 140 putValue(SHORT_DESCRIPTION, tr("Close the dialog")); 141 putValue(SMALL_ICON, ImageProvider.get("ok")); 142 } 143 144 public void run() { 145 getHistoryBrowser().getModel().unlinkAsListener(); 146 HistoryDataSet.getInstance().removeHistoryDataSetListener(HistoryBrowserDialog.this); 147 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this); 148 } 149 150 @Override 151 public void actionPerformed(ActionEvent e) { 152 run(); 153 } 154 } 155 156 class ReloadAction extends AbstractAction { 157 public ReloadAction() { 158 putValue(NAME, tr("Reload")); 159 putValue(SHORT_DESCRIPTION, tr("Reload the history from the server")); 160 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh")); 161 } 162 163 @Override 164 public void actionPerformed(ActionEvent e) { 165 HistoryLoadTask task = new HistoryLoadTask(); 166 task.add(browser.getHistory()); 167 Main.worker.submit(task); 168 } 169 } 170 171 class WindowClosingAdapter extends WindowAdapter { 172 @Override 173 public void windowClosing(WindowEvent e) { 174 closeAction.run(); 175 } 176 } 177 178 public HistoryBrowser getHistoryBrowser() { 179 return browser; 180 } 181}