source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java@ 3206

Last change on this file since 3206 was 3206, checked in by jttt, 14 years ago

Remove obsoleted methods from Dataset, replace some calls of getNodes()/getWays()/getRelations() with allPrimitives()

  • Property svn:eol-style set to native
File size: 16.3 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.trc;
6
7import java.awt.BorderLayout;
8import java.awt.FlowLayout;
9import java.awt.GridBagConstraints;
10import java.awt.GridBagLayout;
11import java.awt.Insets;
12import java.awt.event.ActionEvent;
13import java.awt.event.ComponentAdapter;
14import java.awt.event.ComponentEvent;
15import java.beans.PropertyChangeEvent;
16import java.beans.PropertyChangeListener;
17import java.text.SimpleDateFormat;
18import java.util.Collection;
19import java.util.Collections;
20import java.util.HashSet;
21import java.util.Set;
22
23import javax.swing.AbstractAction;
24import javax.swing.BorderFactory;
25import javax.swing.JLabel;
26import javax.swing.JOptionPane;
27import javax.swing.JPanel;
28import javax.swing.JTextArea;
29import javax.swing.JTextField;
30import javax.swing.JToolBar;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.actions.AutoScaleAction;
34import org.openstreetmap.josm.data.osm.Changeset;
35import org.openstreetmap.josm.data.osm.ChangesetCache;
36import org.openstreetmap.josm.data.osm.OsmPrimitive;
37import org.openstreetmap.josm.gui.HelpAwareOptionPane;
38import org.openstreetmap.josm.gui.MapView;
39import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
40import org.openstreetmap.josm.gui.help.HelpUtil;
41import org.openstreetmap.josm.gui.layer.OsmDataLayer;
42import org.openstreetmap.josm.tools.ImageProvider;
43
44/**
45 * This panel displays the properties of the currently selected changeset in the
46 * {@see ChangesetCacheManager}.
47 *
48 */
49public class ChangesetDetailPanel extends JPanel implements PropertyChangeListener{
50
51 private JTextField tfID;
52 private JTextArea taComment;
53 private JTextField tfOpen;
54 private JTextField tfUser;
55 private JTextField tfCreatedOn;
56 private JTextField tfClosedOn;
57 private DonwloadChangesetContentAction actDownloadChangesetContent;
58 private UpdateChangesetAction actUpdateChangesets;
59 private RemoveFromCacheAction actRemoveFromCache;
60 private SelectInCurrentLayerAction actSelectInCurrentLayer;
61 private ZoomInCurrentLayerAction actZoomInCurrentLayerAction;
62
63 private Changeset current = null;
64
65 protected JPanel buildActionButtonPanel() {
66 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
67
68 JToolBar tb = new JToolBar(JToolBar.VERTICAL);
69 tb.setFloatable(false);
70
71 // -- remove from cache action
72 tb.add(actRemoveFromCache = new RemoveFromCacheAction());
73 actRemoveFromCache.initProperties(current);
74
75 // -- changeset update
76 tb.add(actUpdateChangesets = new UpdateChangesetAction());
77 actUpdateChangesets.initProperties(current);
78
79 // -- changeset content download
80 tb.add(actDownloadChangesetContent =new DonwloadChangesetContentAction());
81 actDownloadChangesetContent.initProperties(current);
82
83 tb.add(actSelectInCurrentLayer = new SelectInCurrentLayerAction());
84 MapView.addEditLayerChangeListener(actSelectInCurrentLayer);
85
86 tb.add(actZoomInCurrentLayerAction = new ZoomInCurrentLayerAction());
87 MapView.addEditLayerChangeListener(actZoomInCurrentLayerAction);
88
89 addComponentListener(
90 new ComponentAdapter() {
91 @Override
92 public void componentHidden(ComponentEvent e) {
93 // make sure the listener is unregistered when the panel becomes
94 // invisible
95 MapView.removeEditLayerChangeListener(actSelectInCurrentLayer);
96 MapView.removeEditLayerChangeListener(actZoomInCurrentLayerAction);
97 }
98 }
99 );
100
101 pnl.add(tb);
102 return pnl;
103 }
104
105 protected JPanel buildDetailViewPanel() {
106 JPanel pnl = new JPanel(new GridBagLayout());
107
108 GridBagConstraints gc = new GridBagConstraints();
109 gc.anchor = GridBagConstraints.FIRST_LINE_START;
110 gc.insets = new Insets(0,0,2,3);
111
112 //-- id
113 gc.fill = GridBagConstraints.HORIZONTAL;
114 gc.weightx = 0.0;
115 pnl.add(new JLabel(tr("ID:")), gc);
116
117 gc.fill = GridBagConstraints.HORIZONTAL;
118 gc.weightx = 0.0;
119 gc.gridx = 1;
120 pnl.add(tfID = new JTextField(10), gc);
121 tfID.setEditable(false);
122
123 //-- comment
124 gc.gridx = 0;
125 gc.gridy = 1;
126 gc.fill = GridBagConstraints.HORIZONTAL;
127 gc.weightx = 0.0;
128 pnl.add(new JLabel(tr("Comment:")), gc);
129
130 gc.fill = GridBagConstraints.BOTH;
131 gc.weightx = 1.0;
132 gc.weighty = 1.0;
133 gc.gridx = 1;
134 pnl.add(taComment= new JTextArea(5,40), gc);
135 taComment.setEditable(false);
136
137 //-- Open/Closed
138 gc.gridx = 0;
139 gc.gridy = 2;
140 gc.fill = GridBagConstraints.HORIZONTAL;
141 gc.weightx = 0.0;
142 gc.weighty = 0.0;
143 pnl.add(new JLabel(tr("Open/Closed:")), gc);
144
145 gc.fill = GridBagConstraints.HORIZONTAL;
146 gc.gridx = 1;
147 pnl.add(tfOpen= new JTextField(10), gc);
148 tfOpen.setEditable(false);
149
150 //-- Created by:
151 gc.gridx = 0;
152 gc.gridy = 3;
153 gc.fill = GridBagConstraints.HORIZONTAL;
154 gc.weightx = 0.0;
155 pnl.add(new JLabel(tr("Created by:")), gc);
156
157 gc.fill = GridBagConstraints.HORIZONTAL;
158 gc.weightx = 1.0;
159 gc.gridx = 1;
160 pnl.add(tfUser= new JTextField(""), gc);
161 tfUser.setEditable(false);
162
163 //-- Created On:
164 gc.gridx = 0;
165 gc.gridy = 4;
166 gc.fill = GridBagConstraints.HORIZONTAL;
167 gc.weightx = 0.0;
168 pnl.add(new JLabel(tr("Created on:")), gc);
169
170 gc.fill = GridBagConstraints.HORIZONTAL;
171 gc.gridx = 1;
172 pnl.add(tfCreatedOn= new JTextField(20), gc);
173 tfCreatedOn.setEditable(false);
174
175 //-- Closed On:
176 gc.gridx = 0;
177 gc.gridy = 5;
178 gc.fill = GridBagConstraints.HORIZONTAL;
179 gc.weightx = 0.0;
180 pnl.add(new JLabel(tr("Closed on:")), gc);
181
182 gc.fill = GridBagConstraints.HORIZONTAL;
183 gc.gridx = 1;
184 pnl.add(tfClosedOn= new JTextField(20), gc);
185 tfClosedOn.setEditable(false);
186
187 return pnl;
188 }
189
190 protected void build() {
191 setLayout(new BorderLayout());
192 setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
193 add(buildDetailViewPanel(), BorderLayout.CENTER);
194 add(buildActionButtonPanel(), BorderLayout.WEST);
195 }
196
197 protected void clearView() {
198 tfID.setText("");
199 taComment.setText("");
200 tfOpen.setText("");
201 tfUser.setText("");
202 tfCreatedOn.setText("");
203 tfClosedOn.setText("");
204 }
205
206 protected void updateView(Changeset cs) {
207 String msg;
208 if (cs == null) return;
209 tfID.setText(Integer.toString(cs.getId()));
210 String comment = cs.get("comment");
211 taComment.setText(comment == null ? "" : comment);
212
213 if (cs.isOpen()) {
214 msg = trc("changeset.state", "Open");
215 } else {
216 msg = trc("changeset.state", "Closed");
217 }
218 tfOpen.setText(msg);
219
220 if (cs.getUser() == null) {
221 msg = tr("anonymous");
222 } else {
223 msg = cs.getUser().getName();
224 }
225 tfUser.setText(msg);
226 SimpleDateFormat sdf = new SimpleDateFormat();
227
228 tfCreatedOn.setText(cs.getCreatedAt() == null ? "" : sdf.format(cs.getCreatedAt()));
229 tfClosedOn.setText(cs.getClosedAt() == null ? "" : sdf.format(cs.getClosedAt()));
230 }
231
232 public ChangesetDetailPanel() {
233 build();
234 }
235
236 protected void setCurrentChangeset(Changeset cs) {
237 current = cs;
238 if (cs == null) {
239 clearView();
240 } else {
241 updateView(cs);
242 }
243 actDownloadChangesetContent.initProperties(current);
244 actUpdateChangesets.initProperties(current);
245 actRemoveFromCache.initProperties(current);
246 actSelectInCurrentLayer.updateEnabledState();
247 actZoomInCurrentLayerAction.updateEnabledState();
248 }
249
250 /* ---------------------------------------------------------------------------- */
251 /* interface PropertyChangeListener */
252 /* ---------------------------------------------------------------------------- */
253 public void propertyChange(PropertyChangeEvent evt) {
254 if (! evt.getPropertyName().equals(ChangesetCacheManagerModel.CHANGESET_IN_DETAIL_VIEW_PROP))
255 return;
256 Changeset cs = (Changeset)evt.getNewValue();
257 setCurrentChangeset(cs);
258 }
259
260 /**
261 * The action for removing the currently selected changeset from the changeset cache
262 */
263 class RemoveFromCacheAction extends AbstractAction {
264 public RemoveFromCacheAction() {
265 putValue(NAME, tr("Remove from cache"));
266 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
267 putValue(SHORT_DESCRIPTION, tr("Remove the changeset in the detail view panel from the local cache"));
268 }
269
270 public void actionPerformed(ActionEvent evt) {
271 if (current == null)
272 return;
273 ChangesetCache.getInstance().remove(current);
274 }
275
276 public void initProperties(Changeset cs) {
277 setEnabled(cs != null);
278 }
279 }
280
281 /**
282 * Removes the selected changesets from the local changeset cache
283 *
284 */
285 class DonwloadChangesetContentAction extends AbstractAction{
286 public DonwloadChangesetContentAction() {
287 putValue(NAME, tr("Download content"));
288 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","downloadchangesetcontent"));
289 putValue(SHORT_DESCRIPTION, tr("Download the changeset content from the OSM server"));
290 }
291
292 public void actionPerformed(ActionEvent evt) {
293 if (current == null) return;
294 ChangesetContentDownloadTask task = new ChangesetContentDownloadTask(ChangesetDetailPanel.this,current.getId());
295 ChangesetCacheManager.getInstance().runDownloadTask(task);
296 }
297
298 public void initProperties(Changeset cs) {
299 if (cs == null) {
300 setEnabled(false);
301 return;
302 } else {
303 setEnabled(true);
304 }
305 if (cs.getContent() == null) {
306 putValue(NAME, tr("Download content"));
307 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","downloadchangesetcontent"));
308 putValue(SHORT_DESCRIPTION, tr("Download the changeset content from the OSM server"));
309 } else {
310 putValue(NAME, tr("Update content"));
311 putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset","updatechangesetcontent"));
312 putValue(SHORT_DESCRIPTION, tr("Update the changeset content from the OSM server"));
313 }
314 }
315 }
316
317 /**
318 * Updates the current changeset from the OSM server
319 *
320 */
321 class UpdateChangesetAction extends AbstractAction{
322 public UpdateChangesetAction() {
323 putValue(NAME, tr("Update changeset"));
324 putValue(SMALL_ICON,ImageProvider.get("dialogs/changeset","updatechangeset"));
325 putValue(SHORT_DESCRIPTION, tr("Update the changeset from the OSM server"));
326 }
327
328 public void actionPerformed(ActionEvent evt) {
329 if (current == null) return;
330 Main.worker.submit(
331 new ChangesetHeaderDownloadTask(
332 ChangesetDetailPanel.this,
333 Collections.singleton(current.getId())
334 )
335 );
336 }
337
338 public void initProperties(Changeset cs) {
339 if (cs == null) {
340 setEnabled(false);
341 return;
342 } else {
343 setEnabled(true);
344 }
345 }
346 }
347
348 /**
349 * Selects the primitives in the content of this changeset in the current
350 * data layer.
351 *
352 */
353 class SelectInCurrentLayerAction extends AbstractAction implements EditLayerChangeListener{
354
355 public SelectInCurrentLayerAction() {
356 putValue(NAME, tr("Select in layer"));
357 putValue(SMALL_ICON, ImageProvider.get("dialogs", "select"));
358 putValue(SHORT_DESCRIPTION, tr("Select the primitives in the content of this changeset in the current data layer"));
359 updateEnabledState();
360 }
361
362 protected void alertNoPrimitivesToSelect(Collection<OsmPrimitive> primitives) {
363 HelpAwareOptionPane.showOptionDialog(
364 ChangesetDetailPanel.this,
365 tr("<html>None of the objects in the content of changeset {0} is available in the current<br>"
366 + "edit layer ''{1}''.</html>",
367 current.getId(),
368 Main.main.getEditLayer().getName()
369 ),
370 tr("Nothing to select"),
371 JOptionPane.WARNING_MESSAGE,
372 HelpUtil.ht("/Dialog/ChangesetCacheManager#NothingToSelectInLayer")
373 );
374 }
375
376 public void actionPerformed(ActionEvent arg0) {
377 if (!isEnabled())
378 return;
379 if (Main.main == null || Main.main.getEditLayer() == null) return;
380 OsmDataLayer layer = Main.main.getEditLayer();
381 Set<OsmPrimitive> target = new HashSet<OsmPrimitive>();
382 for (OsmPrimitive p: layer.data.allPrimitives()) {
383 if (p.isUsable() && p.getChangesetId() == current.getId()) {
384 target.add(p);
385 }
386 }
387 if (target.isEmpty()) {
388 alertNoPrimitivesToSelect(target);
389 return;
390 }
391 layer.data.setSelected(target);
392 }
393
394 public void updateEnabledState() {
395 if (Main.main == null || Main.main.getEditLayer() == null){
396 setEnabled(false);
397 return;
398 }
399 setEnabled(current != null);
400 }
401
402 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
403 updateEnabledState();
404 }
405 }
406
407 /**
408 * Zooms to the primitives in the content of this changeset in the current
409 * data layer.
410 *
411 */
412 class ZoomInCurrentLayerAction extends AbstractAction implements EditLayerChangeListener{
413
414 public ZoomInCurrentLayerAction() {
415 putValue(NAME, tr("Zoom to in layer"));
416 putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale", "selection"));
417 putValue(SHORT_DESCRIPTION, tr("Zoom to the primitives in the content of this changeset in the current data layer"));
418 updateEnabledState();
419 }
420
421 protected void alertNoPrimitivesToZoomTo() {
422 HelpAwareOptionPane.showOptionDialog(
423 ChangesetDetailPanel.this,
424 tr("<html>None of the objects in the content of changeset {0} is available in the current<br>"
425 + "edit layer ''{1}''.</html>",
426 current.getId(),
427 Main.main.getEditLayer().getName()
428 ),
429 tr("Nothing to zoom to"),
430 JOptionPane.WARNING_MESSAGE,
431 HelpUtil.ht("/Dialog/ChangesetCacheManager#NothingToZoomTo")
432 );
433 }
434
435 public void actionPerformed(ActionEvent arg0) {
436 if (!isEnabled())
437 return;
438 if (Main.main == null || Main.main.getEditLayer() == null) return;
439 OsmDataLayer layer = Main.main.getEditLayer();
440 Set<OsmPrimitive> target = new HashSet<OsmPrimitive>();
441 for (OsmPrimitive p: layer.data.allPrimitives()) {
442 if (p.isUsable() && p.getChangesetId() == current.getId()) {
443 target.add(p);
444 }
445 }
446 if (target.isEmpty()) {
447 alertNoPrimitivesToZoomTo();
448 return;
449 }
450 layer.data.setSelected(target);
451 AutoScaleAction.zoomToSelection();
452 }
453
454 public void updateEnabledState() {
455 if (Main.main == null || Main.main.getEditLayer() == null){
456 setEnabled(false);
457 return;
458 }
459 setEnabled(current != null);
460 }
461
462 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
463 updateEnabledState();
464 }
465 }
466}
Note: See TracBrowser for help on using the repository browser.