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 }