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.WindowAdapter; 012import java.awt.event.WindowEvent; 013 014import javax.swing.AbstractAction; 015import javax.swing.JButton; 016import javax.swing.JDialog; 017import javax.swing.JLabel; 018import javax.swing.JPanel; 019 020import org.openstreetmap.josm.Main; 021import org.openstreetmap.josm.data.osm.PrimitiveId; 022import org.openstreetmap.josm.data.osm.history.History; 023import org.openstreetmap.josm.data.osm.history.HistoryDataSet; 024import org.openstreetmap.josm.data.osm.history.HistoryDataSetListener; 025import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 026import org.openstreetmap.josm.gui.help.HelpUtil; 027import org.openstreetmap.josm.gui.util.GuiHelper; 028import org.openstreetmap.josm.tools.ImageProvider; 029import org.openstreetmap.josm.tools.InputMapUtils; 030 031/** 032 * This is non-modal dialog, always showing on top, which displays history information 033 * about a given {@link org.openstreetmap.josm.data.osm.OsmPrimitive}. 034 * @since 1709 035 */ 036public class HistoryBrowserDialog extends JDialog implements HistoryDataSetListener { 037 038 /** the embedded browser */ 039 private final HistoryBrowser browser = new HistoryBrowser(); 040 private final CloseAction closeAction = new CloseAction(); 041 private final JLabel titleLabel = new JLabel("", JLabel.CENTER); 042 043 /** 044 * Constructs a new {@code HistoryBrowserDialog}. 045 * 046 * @param history the history to be displayed 047 */ 048 public HistoryBrowserDialog(History history) { 049 super(GuiHelper.getFrameForComponent(Main.parent), false); 050 build(); 051 setHistory(history); 052 setTitle(buildTitle(history)); 053 pack(); 054 if (getInsets().top > 0) { 055 titleLabel.setVisible(false); 056 } 057 HistoryDataSet.getInstance().addHistoryDataSetListener(this); 058 addWindowListener(new WindowClosingAdapter()); 059 } 060 061 /** 062 * Constructs the title for this dialog 063 * 064 * @param h the current history 065 * @return the title for this dialog 066 */ 067 static String buildTitle(History h) { 068 String title; 069 switch (h.getEarliest().getType()) { 070 case NODE: title = marktr("History for node {0}"); 071 break; 072 case WAY: title = marktr("History for way {0}"); 073 break; 074 case RELATION: title = marktr("History for relation {0}"); 075 break; 076 default: title = ""; 077 } 078 return tr(title, Long.toString(h.getId())); 079 } 080 081 @Override 082 public void setTitle(String title) { 083 super.setTitle(title); 084 if (titleLabel != null) { 085 titleLabel.setText(title); 086 } 087 } 088 089 /** 090 * builds the GUI 091 */ 092 protected void build() { 093 setLayout(new BorderLayout()); 094 095 add(titleLabel, BorderLayout.NORTH); 096 097 add(browser, BorderLayout.CENTER); 098 099 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER)); 100 101 JButton btn = new JButton(new ReloadAction()); 102 btn.setName("btn.reload"); 103 pnl.add(btn); 104 105 btn = new JButton(closeAction); 106 final String closeHistoryBrowserDialogKey = "CloseHistoryBrowserDialog"; 107 btn.setName("btn.close"); 108 pnl.add(btn); 109 InputMapUtils.addEscapeAction(getRootPane(), closeAction); 110 111 btn = new JButton(new ContextSensitiveHelpAction(ht("/Action/ObjectHistory"))); 112 btn.setName("btn.help"); 113 pnl.add(btn); 114 add(pnl, BorderLayout.SOUTH); 115 116 HelpUtil.setHelpContext(getRootPane(), ht("/Action/ObjectHistory")); 117 } 118 119 /** 120 * Sets the current history. 121 * @param history current history 122 */ 123 protected void setHistory(History history) { 124 browser.populate(history); 125 } 126 127 /** 128 * Removes this history browser model as listener for data change and layer change events. 129 */ 130 public void unlinkAsListener() { 131 getHistoryBrowser().getModel().unlinkAsListener(); 132 } 133 134 /* ---------------------------------------------------------------------------------- */ 135 /* interface HistoryDataSetListener */ 136 /* ---------------------------------------------------------------------------------- */ 137 138 @Override 139 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 140 if (primitiveId == null || primitiveId.equals(browser.getHistory().getPrimitiveId())) { 141 History history = source.getHistory(browser.getHistory().getPrimitiveId()); 142 if (history != null) { 143 browser.populate(history); 144 } 145 } 146 } 147 148 @Override 149 public void historyDataSetCleared(HistoryDataSet source) { 150 closeAction.run(); 151 } 152 153 class CloseAction extends AbstractAction { 154 CloseAction() { 155 putValue(NAME, tr("Close")); 156 putValue(SHORT_DESCRIPTION, tr("Close the dialog")); 157 new ImageProvider("ok").getResource().attachImageIcon(this); 158 } 159 160 public void run() { 161 getHistoryBrowser().getModel().unlinkAsListener(); 162 HistoryDataSet.getInstance().removeHistoryDataSetListener(HistoryBrowserDialog.this); 163 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this); 164 } 165 166 @Override 167 public void actionPerformed(ActionEvent e) { 168 run(); 169 } 170 } 171 172 class ReloadAction extends AbstractAction { 173 ReloadAction() { 174 putValue(NAME, tr("Reload")); 175 putValue(SHORT_DESCRIPTION, tr("Reload the history from the server")); 176 new ImageProvider("dialogs", "refresh").getResource().attachImageIcon(this); 177 } 178 179 @Override 180 public void actionPerformed(ActionEvent e) { 181 HistoryLoadTask task = new HistoryLoadTask(); 182 task.add(browser.getHistory()); 183 Main.worker.submit(task); 184 } 185 } 186 187 class WindowClosingAdapter extends WindowAdapter { 188 @Override 189 public void windowClosing(WindowEvent e) { 190 closeAction.run(); 191 } 192 } 193 194 /** 195 * Replies the history browser. 196 * @return the history browser 197 */ 198 public HistoryBrowser getHistoryBrowser() { 199 return browser; 200 } 201}