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

Last change on this file since 8510 was 8510, checked in by Don-vip, 9 years ago

checkstyle: enable relevant whitespace checks and fix them

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