001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.ArrayList; 005import java.util.Date; 006import java.util.List; 007 008import org.openstreetmap.josm.Main; 009import org.openstreetmap.josm.data.coor.LatLon; 010import org.openstreetmap.josm.data.notes.Note; 011import org.openstreetmap.josm.data.notes.Note.State; 012import org.openstreetmap.josm.data.notes.NoteComment; 013import org.openstreetmap.josm.gui.JosmUserIdentityManager; 014 015/** 016 * Class to hold and perform operations on a set of notes 017 */ 018public class NoteData { 019 020 private long newNoteId = -1; 021 022 private final List<Note> noteList; 023 private Note selectedNote = null; 024 025 /** 026 * Construct a new note container with an empty note list 027 */ 028 public NoteData() { 029 noteList = new ArrayList<>(); 030 } 031 032 /** 033 * Construct a new note container with a given list of notes 034 * @param notes The list of notes to populate the container with 035 */ 036 public NoteData(List<Note> notes) { 037 noteList = notes; 038 } 039 040 /** 041 * Returns the notes stored in this layer 042 * @return List of Note objects 043 */ 044 public List<Note> getNotes() { 045 return noteList; 046 } 047 048 /** Returns the currently selected note 049 * @return currently selected note 050 */ 051 public Note getSelectedNote() { 052 return selectedNote; 053 } 054 055 /** Set a selected note. Causes the dialog to select the note and 056 * the note layer to draw the selected note's comments. 057 * @param note Selected note. Null indicates no selection 058 */ 059 public void setSelectedNote(Note note) { 060 selectedNote = note; 061 Main.map.noteDialog.selectionChanged(); 062 Main.map.mapView.repaint(); 063 } 064 065 /** 066 * Add notes to the data set. It only adds a note if the ID is not already present 067 * @param newNotes A list of notes to add 068 */ 069 public void addNotes(List<Note> newNotes) { 070 for (Note newNote : newNotes) { 071 if (!noteList.contains(newNote)) { 072 noteList.add(newNote); 073 } 074 if (newNote.getId() <= newNoteId) { 075 newNoteId = newNote.getId() - 1; 076 } 077 } 078 dataUpdated(); 079 Main.debug("notes in current set: " + noteList.size()); 080 } 081 082 /** 083 * Create a new note 084 * @param location Location of note 085 * @param text Required comment with which to open the note 086 */ 087 public void createNote(LatLon location, String text) { 088 if(text == null || text.isEmpty()) { 089 throw new IllegalArgumentException("Comment can not be blank when creating a note"); 090 } 091 Note note = new Note(location); 092 note.setCreatedAt(new Date()); 093 note.setState(State.open); 094 note.setId(newNoteId--); 095 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.opened, true); 096 note.addComment(comment); 097 Main.debug("Created note {0} with comment: {1}", note.getId(), text); 098 noteList.add(note); 099 dataUpdated(); 100 } 101 102 /** 103 * Add a new comment to an existing note 104 * @param note Note to add comment to. Must already exist in the layer 105 * @param text Comment to add 106 */ 107 public void addCommentToNote(Note note, String text) { 108 if (!noteList.contains(note)) { 109 throw new IllegalArgumentException("Note to modify must be in layer"); 110 } 111 if (note.getState() == State.closed) { 112 throw new IllegalStateException("Cannot add a comment to a closed note"); 113 } 114 Main.debug("Adding comment to note {0}: {1}", note.getId(), text); 115 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.commented, true); 116 note.addComment(comment); 117 dataUpdated(); 118 } 119 120 /** 121 * Close note with comment 122 * @param note Note to close. Must already exist in the layer 123 * @param text Comment to attach to close action, if desired 124 */ 125 public void closeNote(Note note, String text) { 126 if (!noteList.contains(note)) { 127 throw new IllegalArgumentException("Note to close must be in layer"); 128 } 129 if (note.getState() != State.open) { 130 throw new IllegalStateException("Cannot close a note that isn't open"); 131 } 132 Main.debug("closing note {0} with comment: {1}", note.getId(), text); 133 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.closed, true); 134 note.addComment(comment); 135 note.setState(State.closed); 136 note.setClosedAt(new Date()); 137 dataUpdated(); 138 } 139 140 /** 141 * Reopen a closed note. 142 * @param note Note to reopen. Must already exist in the layer 143 * @param text Comment to attach to the reopen action, if desired 144 */ 145 public void reOpenNote(Note note, String text) { 146 if (!noteList.contains(note)) { 147 throw new IllegalArgumentException("Note to reopen must be in layer"); 148 } 149 if (note.getState() != State.closed) { 150 throw new IllegalStateException("Cannot reopen a note that isn't closed"); 151 } 152 Main.debug("reopening note {0} with comment: {1}", note.getId(), text); 153 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.reopened, true); 154 note.addComment(comment); 155 note.setState(State.open); 156 dataUpdated(); 157 } 158 159 private void dataUpdated() { 160 Main.map.noteDialog.setNoteList(noteList); 161 Main.map.mapView.repaint(); 162 } 163 164 private User getCurrentUser() { 165 JosmUserIdentityManager userMgr = JosmUserIdentityManager.getInstance(); 166 return User.createOsmUser(userMgr.getUserId(), userMgr.getUserName()); 167 } 168}