source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentPanel.java@ 2847

Last change on this file since 2847 was 2847, checked in by mjulius, 14 years ago

fix messages for gui/dialogs

File size: 18.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.changeset;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.BorderLayout;
8import java.awt.FlowLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.ComponentAdapter;
11import java.awt.event.ComponentEvent;
12import java.awt.event.MouseAdapter;
13import java.awt.event.MouseEvent;
14import java.beans.PropertyChangeEvent;
15import java.beans.PropertyChangeListener;
16import java.util.ArrayList;
17import java.util.Collection;
18import java.util.HashSet;
19import java.util.List;
20import java.util.Set;
21
22import javax.swing.AbstractAction;
23import javax.swing.BorderFactory;
24import javax.swing.DefaultListSelectionModel;
25import javax.swing.JButton;
26import javax.swing.JOptionPane;
27import javax.swing.JPanel;
28import javax.swing.JPopupMenu;
29import javax.swing.JScrollPane;
30import javax.swing.JSeparator;
31import javax.swing.JTable;
32import javax.swing.JToolBar;
33import javax.swing.SwingUtilities;
34import javax.swing.event.ListSelectionEvent;
35import javax.swing.event.ListSelectionListener;
36
37import org.openstreetmap.josm.Main;
38import org.openstreetmap.josm.actions.AutoScaleAction;
39import org.openstreetmap.josm.data.osm.Changeset;
40import org.openstreetmap.josm.data.osm.OsmPrimitive;
41import org.openstreetmap.josm.data.osm.history.History;
42import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
43import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
44import org.openstreetmap.josm.gui.HelpAwareOptionPane;
45import org.openstreetmap.josm.gui.JMultilineLabel;
46import org.openstreetmap.josm.gui.MapView;
47import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
48import org.openstreetmap.josm.gui.help.HelpUtil;
49import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager;
50import org.openstreetmap.josm.gui.history.HistoryLoadTask;
51import org.openstreetmap.josm.gui.layer.OsmDataLayer;
52import org.openstreetmap.josm.tools.BugReportExceptionHandler;
53import org.openstreetmap.josm.tools.ImageProvider;
54
55/**
56 * The panel which displays the content of a changeset in a scollable table.
57 *
58 * It listens to property change events for {@see ChangesetCacheManagerModel#CHANGESET_IN_DETAIL_VIEW_PROP}
59 * and updates its view accordingly.
60 *
61 */
62public class ChangesetContentPanel extends JPanel implements PropertyChangeListener{
63
64 private ChangesetContentTableModel model;
65 private Changeset currentChangeset;
66 private JTable tblContent;
67
68 private DonwloadChangesetContentAction actDownloadContentAction;
69 private ShowHistoryAction actShowHistory;
70 private SelectInCurrentLayerAction actSelectInCurrentLayerAction;
71 private ZoomInCurrentLayerAction actZoomInCurrentLayerAction;
72
73 private HeaderPanel pnlHeader;
74
75 protected void buildModels() {
76 DefaultListSelectionModel selectionModel =new DefaultListSelectionModel();
77 model = new ChangesetContentTableModel(selectionModel);
78 actDownloadContentAction = new DonwloadChangesetContentAction();
79 actDownloadContentAction.initProperties(currentChangeset);
80 actShowHistory = new ShowHistoryAction();
81 model.getSelectionModel().addListSelectionListener(actShowHistory);
82
83 actSelectInCurrentLayerAction = new SelectInCurrentLayerAction();
84 model.getSelectionModel().addListSelectionListener(actSelectInCurrentLayerAction);
85 MapView.addEditLayerChangeListener(actSelectInCurrentLayerAction);
86
87 actZoomInCurrentLayerAction = new ZoomInCurrentLayerAction();
88 model.getSelectionModel().addListSelectionListener(actZoomInCurrentLayerAction);
89 MapView.addEditLayerChangeListener(actZoomInCurrentLayerAction);
90
91 addComponentListener(
92 new ComponentAdapter() {
93 @Override
94 public void componentHidden(ComponentEvent e) {
95 // make sure the listener is unregistered when the panel becomes
96 // invisible
97 MapView.removeEditLayerChangeListener(actSelectInCurrentLayerAction);
98 MapView.removeEditLayerChangeListener(actZoomInCurrentLayerAction);
99 }
100 }
101 );
102 }
103
104 protected JPanel buildContentPanel() {
105 JPanel pnl = new JPanel(new BorderLayout());
106 tblContent = new JTable(
107 model,
108 new ChangesetContentTableColumnModel(),
109 model.getSelectionModel()
110 );
111 tblContent.addMouseListener(new ChangesetContentTablePopupMenuLauncher());
112 pnl.add(new JScrollPane(tblContent), BorderLayout.CENTER);
113 return pnl;
114 }
115
116 protected JPanel buildActionButtonPanel() {
117 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
118 JToolBar tb = new JToolBar(JToolBar.VERTICAL);
119 tb.setFloatable(false);
120
121 tb.add(actDownloadContentAction);
122 tb.add(actShowHistory);
123 tb.add(actSelectInCurrentLayerAction);
124 tb.add(actZoomInCurrentLayerAction);
125
126 pnl.add(tb);
127 return pnl;
128 }
129
130 protected void build() {
131 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
132 setLayout(new BorderLayout());
133 buildModels();
134
135 add(pnlHeader = new HeaderPanel(), BorderLayout.NORTH);
136 add(buildActionButtonPanel(), BorderLayout.WEST);
137 add(buildContentPanel(), BorderLayout.CENTER);
138
139 }
140
141 public ChangesetContentPanel() {
142 build();
143 }
144
145 public ChangesetContentTableModel getModel() {
146 return model;
147 }
148
149 protected void setCurrentChangeset(Changeset cs) {
150 currentChangeset = cs;
151 if (cs == null) {
152 model.populate(null);
153 } else {
154 model.populate(cs.getContent());
155 }
156 actDownloadContentAction.initProperties(cs);
157 pnlHeader.setChangeset(cs);
158 }
159
160 /* ---------------------------------------------------------------------------- */
161 /* interface PropertyChangeListener */
162 /* ---------------------------------------------------------------------------- */
163 public void propertyChange(PropertyChangeEvent evt) {
164 if(!evt.getPropertyName().equals(ChangesetCacheManagerModel.CHANGESET_IN_DETAIL_VIEW_PROP))
165 return;
166 Changeset cs = (Changeset)evt.getNewValue();
167 setCurrentChangeset(cs);
168 }
169
170 /**
171 * Downloads/Updates the content of the changeset
172 *
173 */
174 class DonwloadChangesetContentAction extends AbstractAction{
175 public DonwloadChangesetContentAction() {
176 putValue(NAME, tr("Download content"));
177 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","downloadchangesetcontent"));
178 putValue(SHORT_DESCRIPTION, tr("Download the changeset content from the OSM server"));
179 }
180
181 public void actionPerformed(ActionEvent evt) {
182 if (currentChangeset == null) return;
183 ChangesetContentDownloadTask task = new ChangesetContentDownloadTask(ChangesetContentPanel.this,currentChangeset.getId());
184 ChangesetCacheManager.getInstance().runDownloadTask(task);
185 }
186
187 public void initProperties(Changeset cs) {
188 if (cs == null) {
189 setEnabled(false);
190 return;
191 } else {
192 setEnabled(true);
193 }
194 if (cs.getContent() == null) {
195 putValue(NAME, tr("Download content"));
196 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","downloadchangesetcontent"));
197 putValue(SHORT_DESCRIPTION, tr("Download the changeset content from the OSM server"));
198 } else {
199 putValue(NAME, tr("Update content"));
200 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","updatechangesetcontent"));
201 putValue(SHORT_DESCRIPTION, tr("Update the changeset content from the OSM server"));
202 }
203 }
204 }
205
206 class ChangesetContentTablePopupMenuLauncher extends MouseAdapter {
207 ChangesetContentTablePopupMenu menu = new ChangesetContentTablePopupMenu();
208
209 protected void launch(MouseEvent evt) {
210 if (! evt.isPopupTrigger()) return;
211 if (! model.hasSelectedPrimitives()) {
212 int row = tblContent.rowAtPoint(evt.getPoint());
213 if (row >= 0) {
214 model.setSelectedByIdx(row);
215 }
216 }
217 menu.show(tblContent, evt.getPoint().x, evt.getPoint().y);
218 }
219
220 @Override
221 public void mouseClicked(MouseEvent evt) {
222 launch(evt);
223 }
224
225 @Override
226 public void mousePressed(MouseEvent evt) {
227 launch(evt);
228 }
229
230 @Override
231 public void mouseReleased(MouseEvent evt) {
232 launch(evt);
233 }
234 }
235
236 class ChangesetContentTablePopupMenu extends JPopupMenu {
237 public ChangesetContentTablePopupMenu() {
238 add(actDownloadContentAction);
239 add(actShowHistory);
240 add(new JSeparator());
241 add(actSelectInCurrentLayerAction);
242 add(actZoomInCurrentLayerAction);
243 }
244 }
245
246 class ShowHistoryAction extends AbstractAction implements ListSelectionListener{
247 public ShowHistoryAction() {
248 putValue(NAME, tr("Show history"));
249 putValue(SMALL_ICON, ImageProvider.get("dialogs", "history"));
250 putValue(SHORT_DESCRIPTION, tr("Download and show the history of the selected primitives"));
251 updateEnabledState();
252 }
253
254 protected List<HistoryOsmPrimitive> filterPrimitivesWithUnloadedHistory(Collection<HistoryOsmPrimitive> primitives) {
255 ArrayList<HistoryOsmPrimitive> ret = new ArrayList<HistoryOsmPrimitive>(primitives.size());
256 for (HistoryOsmPrimitive p: primitives) {
257 if (HistoryDataSet.getInstance().getHistory(p.getPrimitiveId()) == null) {
258 ret.add(p);
259 }
260 }
261 return ret;
262 }
263
264 public void showHistory(final Collection<HistoryOsmPrimitive> primitives) {
265 List<HistoryOsmPrimitive> toLoad = filterPrimitivesWithUnloadedHistory(primitives);
266 if (!toLoad.isEmpty()) {
267 HistoryLoadTask task = new HistoryLoadTask(ChangesetContentPanel.this);
268 for (HistoryOsmPrimitive p: toLoad) {
269 task.add(p);
270 }
271 Main.worker.submit(task);
272 }
273
274 Runnable r = new Runnable() {
275 public void run() {
276 try {
277 for (HistoryOsmPrimitive p : primitives) {
278 History h = HistoryDataSet.getInstance().getHistory(p.getPrimitiveId());
279 if (h == null) {
280 continue;
281 }
282 HistoryBrowserDialogManager.getInstance().show(h);
283 }
284 } catch (final Exception e) {
285 SwingUtilities.invokeLater(new Runnable() {
286 public void run() {
287 BugReportExceptionHandler.handleException(e);
288 }
289 });
290 }
291
292 }
293 };
294 Main.worker.submit(r);
295 }
296
297 protected void updateEnabledState() {
298 setEnabled(model.hasSelectedPrimitives());
299 }
300
301 public void actionPerformed(ActionEvent arg0) {
302 Set<HistoryOsmPrimitive> selected = model.getSelectedPrimitives();
303 if (selected.isEmpty()) return;
304 showHistory(selected);
305 }
306
307 public void valueChanged(ListSelectionEvent e) {
308 updateEnabledState();
309 }
310 }
311
312 class SelectInCurrentLayerAction extends AbstractAction implements ListSelectionListener, EditLayerChangeListener{
313
314 public SelectInCurrentLayerAction() {
315 putValue(NAME, tr("Select in layer"));
316 putValue(SMALL_ICON, ImageProvider.get("dialogs", "select"));
317 putValue(SHORT_DESCRIPTION, tr("Select the corresponding primitives in the current data layer"));
318 updateEnabledState();
319 }
320
321 protected void alertNoPrimitivesToSelect(Collection<HistoryOsmPrimitive> primitives) {
322 HelpAwareOptionPane.showOptionDialog(
323 ChangesetContentPanel.this,
324 trn("<html>The selected object is not available in the current<br>"
325 + "edit layer ''{0}''.</html>",
326 "<html>None of the selected objects is available in the current<br>"
327 + "edit layer ''{0}''.</html>",
328 primitives.size(),
329 Main.main.getEditLayer().getName()
330 ),
331 tr("Nothing to select"),
332 JOptionPane.WARNING_MESSAGE,
333 HelpUtil.ht("/Dialog/ChangesetCacheManager#NothingToSelectInLayer")
334 );
335 }
336
337 public void actionPerformed(ActionEvent arg0) {
338 if (!isEnabled())
339 return;
340 if (Main.main == null || Main.main.getEditLayer() == null) return;
341 OsmDataLayer layer = Main.main.getEditLayer();
342 Set<HistoryOsmPrimitive> selected = model.getSelectedPrimitives();
343 Set<OsmPrimitive> target = new HashSet<OsmPrimitive>();
344 for (HistoryOsmPrimitive p : model.getSelectedPrimitives()) {
345 OsmPrimitive op = layer.data.getPrimitiveById(p.getPrimitiveId());
346 if (op != null) {
347 target.add(op);
348 }
349 }
350 if (target.isEmpty()) {
351 alertNoPrimitivesToSelect(selected);
352 return;
353 }
354 layer.data.setSelected(target);
355 }
356
357 public void updateEnabledState() {
358 if (Main.main == null || Main.main.getEditLayer() == null){
359 setEnabled(false);
360 return;
361 }
362 setEnabled(model.hasSelectedPrimitives());
363 }
364
365 public void valueChanged(ListSelectionEvent e) {
366 updateEnabledState();
367 }
368
369 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
370 updateEnabledState();
371 }
372 }
373
374 class ZoomInCurrentLayerAction extends AbstractAction implements ListSelectionListener, EditLayerChangeListener{
375
376 public ZoomInCurrentLayerAction() {
377 putValue(NAME, tr("Zoom to in layer"));
378 putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale", "selection"));
379 putValue(SHORT_DESCRIPTION, tr("Zoom to the corresponding primitives in the current data layer"));
380 updateEnabledState();
381 }
382
383 protected void alertNoPrimitivesToZoomTo(Collection<HistoryOsmPrimitive> primitives) {
384 HelpAwareOptionPane.showOptionDialog(
385 ChangesetContentPanel.this,
386 trn("<html>The selected object is not available in the current<br>"
387 + "edit layer ''{0}''.</html>",
388 "<html>None of the selected objects is available in the current<br>"
389 + "edit layer ''{0}''.</html>",
390 primitives.size(),
391 Main.main.getEditLayer().getName()
392 ),
393 tr("Nothing to zoom to"),
394 JOptionPane.WARNING_MESSAGE,
395 HelpUtil.ht("/Dialog/ChangesetCacheManager#NothingToZoomTo")
396 );
397 }
398
399 public void actionPerformed(ActionEvent arg0) {
400 if (!isEnabled())
401 return;
402 if (Main.main == null || Main.main.getEditLayer() == null) return;
403 OsmDataLayer layer = Main.main.getEditLayer();
404 Set<HistoryOsmPrimitive> selected = model.getSelectedPrimitives();
405 Set<OsmPrimitive> target = new HashSet<OsmPrimitive>();
406 for (HistoryOsmPrimitive p : model.getSelectedPrimitives()) {
407 OsmPrimitive op = layer.data.getPrimitiveById(p.getPrimitiveId());
408 if (op != null) {
409 target.add(op);
410 }
411 }
412 if (target.isEmpty()) {
413 alertNoPrimitivesToZoomTo(selected);
414 return;
415 }
416 layer.data.setSelected(target);
417 AutoScaleAction.zoomToSelection();
418 }
419
420 public void updateEnabledState() {
421 if (Main.main == null || Main.main.getEditLayer() == null){
422 setEnabled(false);
423 return;
424 }
425 setEnabled(model.hasSelectedPrimitives());
426 }
427
428 public void valueChanged(ListSelectionEvent e) {
429 updateEnabledState();
430 }
431
432 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
433 updateEnabledState();
434 }
435 }
436
437 static private class HeaderPanel extends JPanel {
438
439 private JMultilineLabel lblMessage;
440 private Changeset current;
441 private DownloadAction actDownload;
442
443 protected void build() {
444 setLayout(new FlowLayout(FlowLayout.LEFT));
445 lblMessage = new JMultilineLabel(
446 tr("The content of this changeset is not downloaded yet.")
447 );
448 add(lblMessage);
449 add(new JButton(actDownload = new DownloadAction()));
450
451 }
452
453 public HeaderPanel() {
454 build();
455 }
456
457 public void setChangeset(Changeset cs) {
458 setVisible(cs != null && cs.getContent() == null);
459 this.current = cs;
460 }
461
462 private class DownloadAction extends AbstractAction {
463 public DownloadAction() {
464 putValue(NAME, tr("Download now"));
465 putValue(SHORT_DESCRIPTION, tr("Download the changeset content"));
466 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset", "downloadchangesetcontent"));
467 }
468
469 public void actionPerformed(ActionEvent evt) {
470 if (current == null) return;
471 ChangesetContentDownloadTask task = new ChangesetContentDownloadTask(HeaderPanel.this, current.getId());
472 ChangesetCacheManager.getInstance().runDownloadTask(task);
473 }
474 }
475 }
476}
Note: See TracBrowser for help on using the repository browser.