source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/NotesDialog.java@ 9983

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

remove unused code

  • Property svn:eol-style set to native
File size: 15.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Image;
9import java.awt.event.ActionEvent;
10import java.awt.event.MouseAdapter;
11import java.awt.event.MouseEvent;
12import java.text.DateFormat;
13import java.util.ArrayList;
14import java.util.Arrays;
15import java.util.Collection;
16import java.util.List;
17
18import javax.swing.AbstractAction;
19import javax.swing.AbstractListModel;
20import javax.swing.DefaultListCellRenderer;
21import javax.swing.ImageIcon;
22import javax.swing.JLabel;
23import javax.swing.JList;
24import javax.swing.JOptionPane;
25import javax.swing.JPanel;
26import javax.swing.JScrollPane;
27import javax.swing.ListCellRenderer;
28import javax.swing.ListSelectionModel;
29import javax.swing.SwingUtilities;
30import javax.swing.event.ListSelectionEvent;
31import javax.swing.event.ListSelectionListener;
32
33import org.openstreetmap.josm.Main;
34import org.openstreetmap.josm.actions.DownloadNotesInViewAction;
35import org.openstreetmap.josm.actions.UploadNotesAction;
36import org.openstreetmap.josm.actions.mapmode.AddNoteAction;
37import org.openstreetmap.josm.data.notes.Note;
38import org.openstreetmap.josm.data.notes.Note.State;
39import org.openstreetmap.josm.data.osm.NoteData;
40import org.openstreetmap.josm.gui.MapView;
41import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
42import org.openstreetmap.josm.gui.NoteInputDialog;
43import org.openstreetmap.josm.gui.NoteSortDialog;
44import org.openstreetmap.josm.gui.SideButton;
45import org.openstreetmap.josm.gui.layer.Layer;
46import org.openstreetmap.josm.gui.layer.NoteLayer;
47import org.openstreetmap.josm.tools.ImageProvider;
48import org.openstreetmap.josm.tools.date.DateUtils;
49
50/**
51 * Dialog to display and manipulate notes.
52 * @since 7852 (renaming)
53 * @since 7608 (creation)
54 */
55public class NotesDialog extends ToggleDialog implements LayerChangeListener {
56
57 /** Small icon size for use in graphics calculations */
58 public static final int ICON_SMALL_SIZE = 16;
59 /** 24x24 icon for unresolved notes */
60 public static final ImageIcon ICON_OPEN = ImageProvider.get("dialogs/notes", "note_open");
61 /** 16x16 icon for unresolved notes */
62 public static final ImageIcon ICON_OPEN_SMALL =
63 new ImageIcon(ICON_OPEN.getImage().getScaledInstance(ICON_SMALL_SIZE, ICON_SMALL_SIZE, Image.SCALE_SMOOTH));
64 /** 24x24 icon for resolved notes */
65 public static final ImageIcon ICON_CLOSED = ImageProvider.get("dialogs/notes", "note_closed");
66 /** 16x16 icon for resolved notes */
67 public static final ImageIcon ICON_CLOSED_SMALL =
68 new ImageIcon(ICON_CLOSED.getImage().getScaledInstance(ICON_SMALL_SIZE, ICON_SMALL_SIZE, Image.SCALE_SMOOTH));
69 /** 24x24 icon for new notes */
70 public static final ImageIcon ICON_NEW = ImageProvider.get("dialogs/notes", "note_new");
71 /** 16x16 icon for new notes */
72 public static final ImageIcon ICON_NEW_SMALL =
73 new ImageIcon(ICON_NEW.getImage().getScaledInstance(ICON_SMALL_SIZE, ICON_SMALL_SIZE, Image.SCALE_SMOOTH));
74 /** Icon for note comments */
75 public static final ImageIcon ICON_COMMENT = ImageProvider.get("dialogs/notes", "note_comment");
76
77 private NoteTableModel model;
78 private JList<Note> displayList;
79 private final AddCommentAction addCommentAction;
80 private final CloseAction closeAction;
81 private final DownloadNotesInViewAction downloadNotesInViewAction;
82 private final NewAction newAction;
83 private final ReopenAction reopenAction;
84 private final SortAction sortAction;
85 private final UploadNotesAction uploadAction;
86
87 private transient NoteData noteData;
88
89 /** Creates a new toggle dialog for notes */
90 public NotesDialog() {
91 super(tr("Notes"), "notes/note_open", tr("List of notes"), null, 150);
92 addCommentAction = new AddCommentAction();
93 closeAction = new CloseAction();
94 downloadNotesInViewAction = DownloadNotesInViewAction.newActionWithDownloadIcon();
95 newAction = new NewAction();
96 reopenAction = new ReopenAction();
97 sortAction = new SortAction();
98 uploadAction = new UploadNotesAction();
99 buildDialog();
100 MapView.addLayerChangeListener(this);
101 }
102
103 private void buildDialog() {
104 model = new NoteTableModel();
105 displayList = new JList<>(model);
106 displayList.setCellRenderer(new NoteRenderer());
107 displayList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
108 displayList.addListSelectionListener(new ListSelectionListener() {
109 @Override
110 public void valueChanged(ListSelectionEvent e) {
111 if (noteData != null) { //happens when layer is deleted while note selected
112 noteData.setSelectedNote(displayList.getSelectedValue());
113 }
114 updateButtonStates();
115 }
116 });
117 displayList.addMouseListener(new MouseAdapter() {
118 //center view on selected note on double click
119 @Override
120 public void mouseClicked(MouseEvent e) {
121 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
122 if (noteData != null && noteData.getSelectedNote() != null) {
123 Main.map.mapView.zoomTo(noteData.getSelectedNote().getLatLon());
124 }
125 }
126 }
127 });
128
129 JPanel pane = new JPanel(new BorderLayout());
130 pane.add(new JScrollPane(displayList), BorderLayout.CENTER);
131
132 createLayout(pane, false, Arrays.asList(new SideButton[]{
133 new SideButton(downloadNotesInViewAction, false),
134 new SideButton(newAction, false),
135 new SideButton(addCommentAction, false),
136 new SideButton(closeAction, false),
137 new SideButton(reopenAction, false),
138 new SideButton(sortAction, false),
139 new SideButton(uploadAction, false)}));
140 updateButtonStates();
141 }
142
143 private void updateButtonStates() {
144 if (noteData == null || noteData.getSelectedNote() == null) {
145 closeAction.setEnabled(false);
146 addCommentAction.setEnabled(false);
147 reopenAction.setEnabled(false);
148 } else if (noteData.getSelectedNote().getState() == State.open) {
149 closeAction.setEnabled(true);
150 addCommentAction.setEnabled(true);
151 reopenAction.setEnabled(false);
152 } else { //note is closed
153 closeAction.setEnabled(false);
154 addCommentAction.setEnabled(false);
155 reopenAction.setEnabled(true);
156 }
157 if (noteData == null || !noteData.isModified()) {
158 uploadAction.setEnabled(false);
159 } else {
160 uploadAction.setEnabled(true);
161 }
162 //enable sort button if any notes are loaded
163 if (noteData == null || noteData.getNotes().isEmpty()) {
164 sortAction.setEnabled(false);
165 } else {
166 sortAction.setEnabled(true);
167 }
168 }
169
170 @Override
171 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
172 // Do nothing
173 }
174
175 @Override
176 public void layerAdded(Layer newLayer) {
177 if (newLayer instanceof NoteLayer) {
178 noteData = ((NoteLayer) newLayer).getNoteData();
179 model.setData(noteData.getNotes());
180 setNotes(noteData.getSortedNotes());
181 }
182 }
183
184 @Override
185 public void layerRemoved(Layer oldLayer) {
186 if (oldLayer instanceof NoteLayer) {
187 noteData = null;
188 model.clearData();
189 if (Main.map.mapMode instanceof AddNoteAction) {
190 Main.map.selectMapMode(Main.map.mapModeSelect);
191 }
192 }
193 }
194
195 /**
196 * Sets the list of notes to be displayed in the dialog.
197 * The dialog should match the notes displayed in the note layer.
198 * @param noteList List of notes to display
199 */
200 public void setNotes(Collection<Note> noteList) {
201 model.setData(noteList);
202 updateButtonStates();
203 this.repaint();
204 }
205
206 /**
207 * Notify the dialog that the note selection has changed.
208 * Causes it to update or clear its selection in the UI.
209 */
210 public void selectionChanged() {
211 if (noteData == null || noteData.getSelectedNote() == null) {
212 displayList.clearSelection();
213 } else {
214 displayList.setSelectedValue(noteData.getSelectedNote(), true);
215 }
216 updateButtonStates();
217 // TODO make a proper listener mechanism to handle change of note selection
218 Main.main.menu.infoweb.noteSelectionChanged();
219 }
220
221 /**
222 * Returns the currently selected note, if any.
223 * @return currently selected note, or null
224 * @since 8475
225 */
226 public Note getSelectedNote() {
227 return noteData != null ? noteData.getSelectedNote() : null;
228 }
229
230 private static class NoteRenderer implements ListCellRenderer<Note> {
231
232 private final DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer();
233 private final DateFormat dateFormat = DateUtils.getDateTimeFormat(DateFormat.MEDIUM, DateFormat.SHORT);
234
235 @Override
236 public Component getListCellRendererComponent(JList<? extends Note> list, Note note, int index,
237 boolean isSelected, boolean cellHasFocus) {
238 Component comp = defaultListCellRenderer.getListCellRendererComponent(list, note, index, isSelected, cellHasFocus);
239 if (note != null && comp instanceof JLabel) {
240 String text = note.getFirstComment().getText();
241 String userName = note.getFirstComment().getUser().getName();
242 if (userName == null || userName.isEmpty()) {
243 userName = "<Anonymous>";
244 }
245 String toolTipText = userName + " @ " + dateFormat.format(note.getCreatedAt());
246 JLabel jlabel = (JLabel) comp;
247 jlabel.setText(note.getId() + ": " +text);
248 ImageIcon icon;
249 if (note.getId() < 0) {
250 icon = ICON_NEW_SMALL;
251 } else if (note.getState() == State.closed) {
252 icon = ICON_CLOSED_SMALL;
253 } else {
254 icon = ICON_OPEN_SMALL;
255 }
256 jlabel.setIcon(icon);
257 jlabel.setToolTipText(toolTipText);
258 }
259 return comp;
260 }
261 }
262
263 class NoteTableModel extends AbstractListModel<Note> {
264 private final transient List<Note> data;
265
266 /**
267 * Constructs a new {@code NoteTableModel}.
268 */
269 NoteTableModel() {
270 data = new ArrayList<>();
271 }
272
273 @Override
274 public int getSize() {
275 if (data == null) {
276 return 0;
277 }
278 return data.size();
279 }
280
281 @Override
282 public Note getElementAt(int index) {
283 return data.get(index);
284 }
285
286 public void setData(Collection<Note> noteList) {
287 data.clear();
288 data.addAll(noteList);
289 fireContentsChanged(this, 0, noteList.size());
290 }
291
292 public void clearData() {
293 displayList.clearSelection();
294 data.clear();
295 fireIntervalRemoved(this, 0, getSize());
296 }
297 }
298
299 class AddCommentAction extends AbstractAction {
300
301 /**
302 * Constructs a new {@code AddCommentAction}.
303 */
304 AddCommentAction() {
305 putValue(SHORT_DESCRIPTION, tr("Add comment"));
306 putValue(NAME, tr("Comment"));
307 putValue(SMALL_ICON, ICON_COMMENT);
308 }
309
310 @Override
311 public void actionPerformed(ActionEvent e) {
312 Note note = displayList.getSelectedValue();
313 if (note == null) {
314 JOptionPane.showMessageDialog(Main.map,
315 "You must select a note first",
316 "No note selected",
317 JOptionPane.ERROR_MESSAGE);
318 return;
319 }
320 NoteInputDialog dialog = new NoteInputDialog(Main.parent, tr("Comment on note"), tr("Add comment"));
321 dialog.showNoteDialog(tr("Add comment to note:"), NotesDialog.ICON_COMMENT);
322 if (dialog.getValue() != 1) {
323 return;
324 }
325 int selectedIndex = displayList.getSelectedIndex();
326 noteData.addCommentToNote(note, dialog.getInputText());
327 noteData.setSelectedNote(model.getElementAt(selectedIndex));
328 }
329 }
330
331 class CloseAction extends AbstractAction {
332
333 /**
334 * Constructs a new {@code CloseAction}.
335 */
336 CloseAction() {
337 putValue(SHORT_DESCRIPTION, tr("Close note"));
338 putValue(NAME, tr("Close"));
339 putValue(SMALL_ICON, ICON_CLOSED);
340 }
341
342 @Override
343 public void actionPerformed(ActionEvent e) {
344 NoteInputDialog dialog = new NoteInputDialog(Main.parent, tr("Close note"), tr("Close note"));
345 dialog.showNoteDialog(tr("Close note with message:"), NotesDialog.ICON_CLOSED);
346 if (dialog.getValue() != 1) {
347 return;
348 }
349 Note note = displayList.getSelectedValue();
350 int selectedIndex = displayList.getSelectedIndex();
351 noteData.closeNote(note, dialog.getInputText());
352 noteData.setSelectedNote(model.getElementAt(selectedIndex));
353 }
354 }
355
356 class NewAction extends AbstractAction {
357
358 /**
359 * Constructs a new {@code NewAction}.
360 */
361 NewAction() {
362 putValue(SHORT_DESCRIPTION, tr("Create a new note"));
363 putValue(NAME, tr("Create"));
364 putValue(SMALL_ICON, ICON_NEW);
365 }
366
367 @Override
368 public void actionPerformed(ActionEvent e) {
369 if (noteData == null) { //there is no notes layer. Create one first
370 Main.map.mapView.addLayer(new NoteLayer());
371 }
372 Main.map.selectMapMode(new AddNoteAction(Main.map, noteData));
373 }
374 }
375
376 class ReopenAction extends AbstractAction {
377
378 /**
379 * Constructs a new {@code ReopenAction}.
380 */
381 ReopenAction() {
382 putValue(SHORT_DESCRIPTION, tr("Reopen note"));
383 putValue(NAME, tr("Reopen"));
384 putValue(SMALL_ICON, ICON_OPEN);
385 }
386
387 @Override
388 public void actionPerformed(ActionEvent e) {
389 NoteInputDialog dialog = new NoteInputDialog(Main.parent, tr("Reopen note"), tr("Reopen note"));
390 dialog.showNoteDialog(tr("Reopen note with message:"), NotesDialog.ICON_OPEN);
391 if (dialog.getValue() != 1) {
392 return;
393 }
394
395 Note note = displayList.getSelectedValue();
396 int selectedIndex = displayList.getSelectedIndex();
397 noteData.reOpenNote(note, dialog.getInputText());
398 noteData.setSelectedNote(model.getElementAt(selectedIndex));
399 }
400 }
401
402 class SortAction extends AbstractAction {
403
404 /**
405 * Constructs a new {@code SortAction}.
406 */
407 SortAction() {
408 putValue(SHORT_DESCRIPTION, tr("Sort notes"));
409 putValue(NAME, tr("Sort"));
410 putValue(SMALL_ICON, ImageProvider.get("dialogs", "sort"));
411 }
412
413 @Override
414 public void actionPerformed(ActionEvent e) {
415 NoteSortDialog sortDialog = new NoteSortDialog(Main.parent, tr("Sort notes"), tr("Apply"));
416 sortDialog.showSortDialog(noteData.getCurrentSortMethod());
417 if (sortDialog.getValue() == 1) {
418 noteData.setSortMethod(sortDialog.getSelectedComparator());
419 }
420 }
421 }
422}
Note: See TracBrowser for help on using the repository browser.