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.data.osm.PrimitiveId; 021import org.openstreetmap.josm.data.osm.history.History; 022import org.openstreetmap.josm.data.osm.history.HistoryDataSet; 023import org.openstreetmap.josm.data.osm.history.HistoryDataSetListener; 024import org.openstreetmap.josm.gui.MainApplication; 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(MainApplication.getMainFrame()), 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 btn.setName("btn.close"); 107 pnl.add(btn); 108 InputMapUtils.addEscapeAction(getRootPane(), closeAction); 109 110 btn = new JButton(new ContextSensitiveHelpAction(ht("/Action/ObjectHistory"))); 111 btn.setName("btn.help"); 112 pnl.add(btn); 113 add(pnl, BorderLayout.SOUTH); 114 115 HelpUtil.setHelpContext(getRootPane(), ht("/Action/ObjectHistory")); 116 } 117 118 /** 119 * Sets the current history. 120 * @param history current history 121 */ 122 protected void setHistory(History history) { 123 browser.populate(history); 124 } 125 126 /* ---------------------------------------------------------------------------------- */ 127 /* interface HistoryDataSetListener */ 128 /* ---------------------------------------------------------------------------------- */ 129 130 @Override 131 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 132 if (primitiveId == null || primitiveId.equals(browser.getHistory().getPrimitiveId())) { 133 History history = source.getHistory(browser.getHistory().getPrimitiveId()); 134 if (history != null) { 135 browser.populate(history); 136 } 137 } 138 } 139 140 @Override 141 public void historyDataSetCleared(HistoryDataSet source) { 142 if (isVisible()) { 143 closeAction.run(); 144 } 145 } 146 147 class CloseAction extends AbstractAction { 148 CloseAction() { 149 putValue(NAME, tr("Close")); 150 putValue(SHORT_DESCRIPTION, tr("Close the dialog")); 151 new ImageProvider("ok").getResource().attachImageIcon(this); 152 } 153 154 void run() { 155 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this); 156 } 157 158 @Override 159 public void actionPerformed(ActionEvent e) { 160 run(); 161 } 162 } 163 164 class ReloadAction extends AbstractAction { 165 ReloadAction() { 166 putValue(NAME, tr("Reload")); 167 putValue(SHORT_DESCRIPTION, tr("Reload the history from the server")); 168 new ImageProvider("dialogs", "refresh").getResource().attachImageIcon(this); 169 } 170 171 @Override 172 public void actionPerformed(ActionEvent e) { 173 HistoryLoadTask task = new HistoryLoadTask(); 174 task.add(browser.getHistory()); 175 MainApplication.worker.submit(task); 176 } 177 } 178 179 class WindowClosingAdapter extends WindowAdapter { 180 @Override 181 public void windowClosing(WindowEvent e) { 182 if (isVisible()) { 183 closeAction.run(); 184 } 185 } 186 } 187 188 /** 189 * Replies the history browser. 190 * @return the history browser 191 */ 192 public HistoryBrowser getHistoryBrowser() { 193 return browser; 194 } 195 196 @Override 197 public void dispose() { 198 HistoryDataSet.getInstance().removeHistoryDataSetListener(this); 199 GuiHelper.destroyComponents(this, false); 200 super.dispose(); 201 } 202}