OSDN Git Service

Alter save thread logic so that if an error happens, a message box is produced rather...
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / utilities / ListManager.java
1 /*\r
2  * This file is part of NeverNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18 */\r
19 \r
20 package cx.fbn.nevernote.utilities;\r
21 \r
22 import java.util.ArrayList;\r
23 import java.util.Calendar;\r
24 import java.util.Collections;\r
25 import java.util.Comparator;\r
26 import java.util.GregorianCalendar;\r
27 import java.util.HashMap;\r
28 import java.util.List;\r
29 import java.util.Vector;\r
30 \r
31 import com.evernote.edam.type.Note;\r
32 import com.evernote.edam.type.Notebook;\r
33 import com.evernote.edam.type.SavedSearch;\r
34 import com.evernote.edam.type.Tag;\r
35 import com.trolltech.qt.QThread;\r
36 import com.trolltech.qt.core.QDateTime;\r
37 import com.trolltech.qt.sql.QSqlQuery;\r
38 import com.trolltech.qt.xml.QDomAttr;\r
39 import com.trolltech.qt.xml.QDomDocument;\r
40 import com.trolltech.qt.xml.QDomElement;\r
41 import com.trolltech.qt.xml.QDomNodeList;\r
42 \r
43 import cx.fbn.nevernote.Global;\r
44 import cx.fbn.nevernote.filters.EnSearch;\r
45 import cx.fbn.nevernote.filters.NotebookCounter;\r
46 import cx.fbn.nevernote.filters.TagCounter;\r
47 import cx.fbn.nevernote.gui.NoteTableModel;\r
48 import cx.fbn.nevernote.signals.NotebookSignal;\r
49 import cx.fbn.nevernote.signals.StatusSignal;\r
50 import cx.fbn.nevernote.signals.TagSignal;\r
51 import cx.fbn.nevernote.signals.ThreadSignal;\r
52 import cx.fbn.nevernote.signals.TrashSignal;\r
53 import cx.fbn.nevernote.sql.DatabaseConnection;\r
54 import cx.fbn.nevernote.threads.CounterRunner;\r
55 import cx.fbn.nevernote.threads.SaveRunner;\r
56 \r
57 \r
58 public class ListManager  {\r
59 \r
60         \r
61         private final ApplicationLogger logger;  \r
62         DatabaseConnection                              conn;\r
63         QSqlQuery                                               deleteWords;\r
64         QSqlQuery                                               insertWords;\r
65         \r
66         private List<Tag>                               tagIndex;\r
67         private List<Notebook>                  notebookIndex;\r
68         private List<Notebook>                  archiveNotebookIndex;\r
69         private List<String>                    localNotebookIndex;\r
70 \r
71         private List<SavedSearch>               searchIndex;\r
72 \r
73         private List<String>                    selectedNotebooks;\r
74         private final NoteTableModel                    noteModel;\r
75         \r
76         \r
77         private List<String>                    selectedTags;\r
78         private String                                  selectedSearch;\r
79         ThreadSignal                                    signals;\r
80         public StatusSignal                             status;\r
81         private final CounterRunner             notebookCounterRunner;\r
82         private final QThread                   notebookThread;\r
83         private final CounterRunner             tagCounterRunner;\r
84         private final QThread                   tagThread;\r
85         \r
86         private final CounterRunner             trashCounterRunner;\r
87         private final QThread                   trashThread;\r
88         public TrashSignal                              trashSignal;\r
89         \r
90         private List<NotebookCounter>   notebookCounter;                                // count of displayed notes in each notebook\r
91         private List<TagCounter>                tagCounter;                                             // count of displayed notes for each tag\r
92         \r
93         private EnSearch                                enSearch;\r
94         private boolean                                 enSearchChanged;\r
95         public HashMap<String, String>  wordMap;\r
96         public TagSignal                                tagSignal;\r
97         public NotebookSignal                   notebookSignal;\r
98         private int                                             trashCount;\r
99     public SaveRunner                           saveRunner;                                     // Thread used to save content.  Used because the xml conversion is slowwwww\r
100     QThread                             saveThread;\r
101         \r
102         // Constructor\r
103         public ListManager(DatabaseConnection d, ApplicationLogger l) {\r
104                 conn = d;\r
105                 logger = l;\r
106                 \r
107         status = new StatusSignal();\r
108                 signals = new ThreadSignal();\r
109                 \r
110                 // setup index locks\r
111                 enSearchChanged = false;\r
112                 \r
113                 // Setup arrays\r
114                 noteModel = new NoteTableModel(this);\r
115                 selectedTags = new ArrayList<String>();\r
116 \r
117                 notebookCounter = new ArrayList<NotebookCounter>();\r
118                 tagCounter = new ArrayList<TagCounter>();\r
119                 selectedNotebooks = new ArrayList<String>();\r
120                                 \r
121                 reloadIndexes();\r
122                 \r
123                 notebookSignal = new NotebookSignal();\r
124                 notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
125                 notebookCounterRunner.setNoteIndex(getNoteIndex());\r
126                 notebookCounterRunner.notebookSignal.countsChanged.connect(this, "setNotebookCounter(List)");\r
127                 notebookThread = new QThread(notebookCounterRunner, "Notebook Counter Thread");\r
128                 notebookThread.start();\r
129                 \r
130                 tagSignal = new TagSignal();\r
131                 tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
132                 tagCounterRunner.setNoteIndex(getNoteIndex());\r
133                 tagCounterRunner.tagSignal.countsChanged.connect(this, "setTagCounter(List)");\r
134                 tagThread = new QThread(tagCounterRunner, "Tag Counter Thread");\r
135                 tagThread.start();\r
136                 \r
137                 trashSignal = new TrashSignal();\r
138                 trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
139                 trashCounterRunner.trashSignal.countChanged.connect(this, "trashSignalReceiver(Integer)");\r
140                 trashThread = new QThread(trashCounterRunner, "Trash Counter Thread");\r
141                 trashThread.start();\r
142                 reloadTrashCount();\r
143                 \r
144                 wordMap = new HashMap<String, String>();\r
145                 tagSignal = new TagSignal();\r
146                 \r
147                 logger.log(logger.EXTREME, "Setting save thread");\r
148                 saveRunner = new SaveRunner("saveRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
149                 saveThread = new QThread(saveRunner, "Save Runner Thread");\r
150                 saveThread.start();\r
151 \r
152                 loadNoteTitleColors();\r
153                                 \r
154         }\r
155         \r
156         public void stop() {\r
157                 saveRunner.addWork("stop", "");\r
158                 tagCounterRunner.release(CounterRunner.EXIT);\r
159                 notebookCounterRunner.release(CounterRunner.EXIT);\r
160                 trashCounterRunner.release(CounterRunner.EXIT);\r
161                 \r
162                 logger.log(logger.MEDIUM, "Waiting for notebookCounterThread to stop");                         \r
163                 try {\r
164                         notebookThread.join();\r
165                 } catch (InterruptedException e) {\r
166                         e.printStackTrace();\r
167                 }\r
168                 \r
169                 logger.log(logger.MEDIUM, "Waiting for tagCounterThread to stop");                      \r
170                 try {\r
171                         tagThread.join();\r
172                 } catch (InterruptedException e) {\r
173                         e.printStackTrace();\r
174                 }\r
175 \r
176                 logger.log(logger.MEDIUM, "Waiting for trashThread to stop");                   \r
177                 try {\r
178                         trashThread.join();\r
179                 } catch (InterruptedException e) {\r
180                         e.printStackTrace();\r
181                 }\r
182 \r
183 \r
184                 logger.log(logger.MEDIUM, "Waiting for saveThread to stop");                    \r
185                 try {\r
186                         saveThread.join(0);\r
187                 } catch (InterruptedException e) {\r
188                         e.printStackTrace();\r
189                 }\r
190 \r
191 \r
192         }\r
193 \r
194         //***************************************************************\r
195         //***************************************************************\r
196         //* Refresh lists after a db sync\r
197         //***************************************************************\r
198         //***************************************************************\r
199         public void refreshLists(Note n, boolean dirty, String content) {\r
200                 if (dirty) {\r
201 //                      conn.getNoteTable().updateNoteContent(n.getGuid(), n.getContent());\r
202                         saveRunner.addWork(n.getGuid(), content);\r
203                         conn.getNoteTable().updateNoteTitle(n.getGuid(), n.getTitle());\r
204                 }\r
205                 \r
206                 setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
207                 setTagIndex(conn.getTagTable().getAll());\r
208                 setNotebookIndex(conn.getNotebookTable().getAll());\r
209                 \r
210                 List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
211                 localNotebookIndex = new ArrayList<String>();\r
212                 for (int i=0; i<local.size(); i++)\r
213                         localNotebookIndex.add(local.get(i).getGuid());\r
214                 \r
215                 noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
216                 // For performance reasons, we didn't get the tags for every note individually.  We now need to \r
217                 // get them\r
218                 List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
219                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
220                         List<String> tags = new ArrayList<String>();\r
221                         List<String> names = new ArrayList<String>();\r
222                         for (int j=0; j<noteTags.size(); j++) {\r
223                                 if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
224                                         tags.add(noteTags.get(j).tagGuid);\r
225                                         names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
226                                 }\r
227                         }\r
228                         \r
229                         getMasterNoteIndex().get(i).setTagGuids(tags);\r
230                         getMasterNoteIndex().get(i).setTagNames(names);\r
231                 }\r
232                 \r
233                 \r
234                 setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
235                 \r
236                 enSearchChanged = true;\r
237         }\r
238 \r
239         public void reloadIndexes() {\r
240                 setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
241 \r
242                 List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
243                 localNotebookIndex = new ArrayList<String>();\r
244                 for (int i=0; i<local.size(); i++)\r
245                         localNotebookIndex.add(local.get(i).getGuid());\r
246                 \r
247                 // Load tags\r
248                 setTagIndex(conn.getTagTable().getAll());\r
249                 // Load notebooks\r
250                 setNotebookIndex(conn.getNotebookTable().getAll());\r
251                 // load archived notebooks (if note using the EN interface)\r
252                 setArchiveNotebookIndex(conn.getNotebookTable().getAllArchived());\r
253                 // load saved search index\r
254                 setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
255                 // Load search helper utility\r
256                 enSearch = new EnSearch(conn,  logger, "", getTagIndex(), Global.getMinimumWordLength(), Global.getRecognitionWeight());\r
257                 logger.log(logger.HIGH, "Building note index");\r
258 \r
259 //              if (getMasterNoteIndex() == null) { \r
260                         noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
261 //              }\r
262                 // For performance reasons, we didn't get the tags for every note individually.  We now need to \r
263                 // get them\r
264                 List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
265                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
266                         List<String> tags = new ArrayList<String>();\r
267                         List<String> names = new ArrayList<String>();\r
268                         for (int j=0; j<noteTags.size(); j++) {\r
269                                 if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
270                                         tags.add(noteTags.get(j).tagGuid);\r
271                                         names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
272                                 }\r
273                         }\r
274                         \r
275                         getMasterNoteIndex().get(i).setTagGuids(tags);\r
276                         getMasterNoteIndex().get(i).setTagNames(names);\r
277                 }\r
278                 \r
279                 setNoteIndex(getMasterNoteIndex());\r
280 \r
281         }\r
282         \r
283         //***************************************************************\r
284         //***************************************************************\r
285         //* selected notebooks\r
286         //***************************************************************\r
287         //***************************************************************\r
288         // Return the selected notebook(s)\r
289         public List<String> getSelectedNotebooks() {\r
290                 return selectedNotebooks;\r
291         }\r
292         // Set the current selected notebook(s)\r
293         public void setSelectedNotebooks(List <String> s) {\r
294                 if (s == null) \r
295                         s = new ArrayList<String>();\r
296                 selectedNotebooks = s;\r
297         }\r
298         \r
299                                 \r
300     //***************************************************************\r
301     //***************************************************************\r
302     //** These functions deal with setting & retrieving the master lists\r
303     //***************************************************************\r
304     //***************************************************************\r
305         // Get the note table model\r
306         public NoteTableModel getNoteTableModel() {\r
307                 return noteModel;\r
308         }\r
309         // save the saved search index\r
310         private void setSavedSearchIndex(List<SavedSearch> t) {\r
311                 searchIndex = t;\r
312         }\r
313         // Retrieve the Tag index\r
314         public List<SavedSearch> getSavedSearchIndex() {\r
315                 return searchIndex;\r
316 \r
317         }\r
318         // save the tag index\r
319         private void setTagIndex(List<Tag> t) {\r
320                 tagIndex = t;\r
321         }       \r
322         // Retrieve the Tag index\r
323         public List<Tag> getTagIndex() {\r
324                 return tagIndex;\r
325         }\r
326         private void setNotebookIndex(List<Notebook> t) {\r
327                 notebookIndex = t;\r
328         }\r
329         private void setArchiveNotebookIndex(List<Notebook> t) {\r
330                 archiveNotebookIndex = t;\r
331         }\r
332         // Retrieve the Notebook index\r
333         public List<Notebook> getNotebookIndex() {\r
334                 return notebookIndex;\r
335 \r
336         }\r
337         public List<Notebook> getArchiveNotebookIndex() {\r
338                 return archiveNotebookIndex;\r
339         }\r
340         // Save the current note list\r
341         private void setNoteIndex(List<Note> n) {\r
342                 noteModel.setNoteIndex(n);\r
343         }\r
344         // Get the note index\r
345         public synchronized List<Note> getNoteIndex() {\r
346                 return noteModel.getNoteIndex();\r
347         }\r
348         // Save the count of notes per notebook\r
349         public void setNotebookCounter(List<NotebookCounter> n) {\r
350                 notebookCounter = n;\r
351                 notebookSignal.refreshNotebookTreeCounts.emit(getNotebookIndex(), notebookCounter);\r
352         }\r
353         public List<NotebookCounter> getNotebookCounter() {\r
354                 return notebookCounter;\r
355         }\r
356         // Save the count of notes for each tag\r
357         public void setTagCounter(List<TagCounter> n) {\r
358                 tagCounter = n;\r
359                 tagSignal.refreshTagTreeCounts.emit(tagCounter);\r
360         }\r
361         public List<TagCounter> getTagCounter() {\r
362                 return tagCounter;\r
363         }\r
364         public List<String> getLocalNotebooks() {\r
365                 return localNotebookIndex;\r
366         }\r
367         // Unsynchronized Note List\r
368         public List<String> getUnsynchronizedNotes() {\r
369                 return noteModel.getUnsynchronizedNotes();\r
370         }\r
371         public void setUnsynchronizedNotes(List<String> l) {\r
372                 noteModel.setUnsynchronizedNotes(l);\r
373         }\r
374         // Return a count of items in the trash\r
375         public int getTrashCount() {\r
376                 return trashCount;\r
377         }\r
378         // get the EnSearch variable\r
379         public EnSearch getEnSearch() {\r
380                 return enSearch;\r
381         }\r
382         public List<Note> getMasterNoteIndex() {\r
383                 return noteModel.getMasterNoteIndex();\r
384         }\r
385         \r
386     //***************************************************************\r
387     //***************************************************************\r
388     //** These functions deal with setting & retrieving filters\r
389     //***************************************************************\r
390     //***************************************************************\r
391         public void setEnSearch(String t) {\r
392                 enSearch = new EnSearch(conn,logger, t, getTagIndex(), Global.getMinimumWordLength(), Global.getRecognitionWeight());\r
393                 enSearchChanged = true;\r
394         }\r
395         // Save search tags\r
396         public void setSelectedTags(List<String> selectedTags) {\r
397                 this.selectedTags = selectedTags;\r
398         }\r
399         // Save seleceted search\r
400         public void setSelectedSavedSearch(String s) {\r
401                 this.selectedSearch = s;\r
402         }\r
403         // Get search tags\r
404         public List<String> getSelectedTags() {\r
405                 return selectedTags;\r
406         }\r
407         // Get saved search\r
408         public String getSelectedSearch() {\r
409                 return selectedSearch;\r
410         }\r
411         \r
412         \r
413         \r
414         \r
415     //***************************************************************\r
416     //***************************************************************\r
417     //** Note functions\r
418     //***************************************************************\r
419     //***************************************************************\r
420         // Save Note Tags\r
421         public void saveNoteTags(String noteGuid, List<String> tags) {\r
422                 logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");\r
423                 String tagName;\r
424                 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);\r
425                 List<String> tagGuids = new ArrayList<String>();\r
426                 boolean newTagCreated = false;\r
427                 \r
428                 for (int i=0; i<tags.size(); i++) {\r
429                         tagName = tags.get(i);\r
430                         boolean found = false;\r
431                         for (int j=0; j<tagIndex.size(); j++) {\r
432                                 if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {\r
433                                         conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, tagIndex.get(j).getGuid());\r
434                                         tagGuids.add(tagIndex.get(j).getGuid());\r
435                                         j=tagIndex.size()+1;\r
436                                         found = true;\r
437                                 }\r
438                         }\r
439                         if (!found) {\r
440                                 Tag nTag = new Tag();\r
441                                 nTag.setName(tagName);\r
442                                 Calendar currentTime = new GregorianCalendar();\r
443                                 Long l = new Long(currentTime.getTimeInMillis());\r
444                                 long prevTime = l;\r
445                                 while (l==prevTime) {\r
446                                         currentTime = new GregorianCalendar();\r
447                                         l=currentTime.getTimeInMillis();\r
448                                 }\r
449                                 String randint = new String(Long.toString(l));\r
450                         \r
451                                 nTag.setUpdateSequenceNum(0);\r
452                                 nTag.setGuid(randint);\r
453                                 conn.getTagTable().addTag(nTag, true);\r
454                                 getTagIndex().add(nTag);\r
455                                 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, nTag.getGuid());\r
456                                 tagGuids.add(nTag.getGuid());\r
457                                 newTagCreated = true;\r
458                         }\r
459                 }\r
460                 \r
461                 for (int i=0; i<getNoteIndex().size(); i++) {\r
462                         if (getNoteIndex().get(i).getGuid().equals(noteGuid)) {\r
463                                 getNoteIndex().get(i).setTagNames(tags);\r
464                                 getNoteIndex().get(i).setTagGuids(tagGuids);\r
465                                 i=getNoteIndex().size()+1;\r
466                         }\r
467                 }\r
468                 if (newTagCreated)\r
469                         tagSignal.listChanged.emit();\r
470                 logger.log(logger.HIGH, "Leaving ListManager.saveNoteTags");\r
471         }\r
472         // Delete a note\r
473         public void deleteNote(String guid) {\r
474                 trashCounterRunner.abortCount = true;\r
475                 Calendar currentTime = new GregorianCalendar();\r
476                 Long l = new Long(currentTime.getTimeInMillis());\r
477                 long prevTime = l;\r
478                 while (l==prevTime) {\r
479                         currentTime = new GregorianCalendar();\r
480                         l=currentTime.getTimeInMillis();\r
481                 }\r
482                 \r
483                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
484                         if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
485                                 getMasterNoteIndex().get(i).setActive(false);\r
486                                 getMasterNoteIndex().get(i).setDeleted(l);\r
487                                 i=getMasterNoteIndex().size();\r
488                         }\r
489                 }\r
490                 for (int i=0; i<getNoteIndex().size(); i++) {\r
491                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
492                                 getNoteIndex().get(i).setActive(false);\r
493                                 getNoteIndex().get(i).setDeleted(l);\r
494                                 i=getNoteIndex().size();\r
495                         }\r
496                 }\r
497                 conn.getNoteTable().deleteNote(guid);\r
498                 reloadTrashCount();\r
499         }\r
500         // Delete a note\r
501         public void restoreNote(String guid) {\r
502                 trashCounterRunner.abortCount = true;\r
503                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
504                         if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
505                                 getMasterNoteIndex().get(i).setActive(true);\r
506                                 getMasterNoteIndex().get(i).setDeleted(0);\r
507                                 i=getMasterNoteIndex().size();\r
508                         }\r
509                 }\r
510                 for (int i=0; i<getNoteIndex().size(); i++) {\r
511                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
512                                 getNoteIndex().get(i).setActive(true);\r
513                                 getNoteIndex().get(i).setDeleted(0);\r
514                                 i=getNoteIndex().size();\r
515                         }\r
516                 }\r
517                 conn.getNoteTable().restoreNote(guid);\r
518                 reloadTrashCount();\r
519         }\r
520         public void updateNote(Note n) {\r
521                 \r
522                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
523                         if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
524                                 getMasterNoteIndex().remove(i);\r
525                                 getMasterNoteIndex().add(n);\r
526                         }\r
527                 }\r
528                 for (int i=0; i<getNoteIndex().size(); i++) {\r
529                         if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
530                                 getNoteIndex().get(i).setActive(true);\r
531                                 getNoteIndex().get(i).setDeleted(0);\r
532                                 i=getNoteIndex().size();\r
533                         }\r
534                 }\r
535                 conn.getNoteTable().updateNote(n, true);\r
536         }\r
537         // Add a note.  \r
538         public void addNote(Note n) {\r
539                 noteModel.addNote(n);\r
540         }\r
541         // Expunge a note\r
542         public void expungeNote(String guid) {\r
543                 trashCounterRunner.abortCount = true;\r
544                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
545                         if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
546                                 getMasterNoteIndex().remove(i);\r
547                                 i=getMasterNoteIndex().size();\r
548                         }\r
549                 }\r
550                 for (int i=0; i<getNoteIndex().size(); i++) {\r
551                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
552                                 getNoteIndex().remove(i);\r
553                                 i=getNoteIndex().size();\r
554                         }\r
555                 }\r
556                 conn.getNoteTable().expungeNote(guid, false, true);\r
557                 reloadTrashCount();\r
558         }\r
559         // Expunge a note\r
560         public void emptyTrash() {\r
561                 trashCounterRunner.abortCount = true;           \r
562                 for (int i=getMasterNoteIndex().size()-1; i>=0; i--) {\r
563                         if (!getMasterNoteIndex().get(i).isActive()) {\r
564                                 getMasterNoteIndex().remove(i);\r
565                         }\r
566                 }\r
567                 \r
568                 for (int i=getNoteIndex().size()-1; i>=0; i--) {\r
569                         if (!getNoteIndex().get(i).isActive()) {\r
570                                 getNoteIndex().remove(i);\r
571                         } \r
572                 }\r
573 \r
574                 conn.getNoteTable().expungeAllDeletedNotes();\r
575                 reloadTrashCount();\r
576         }\r
577         // The trash counter thread has produced a result\r
578         @SuppressWarnings("unused")\r
579         private void trashSignalReceiver(Integer i) {\r
580                 trashCount = i;\r
581                 trashSignal.countChanged.emit(i);\r
582         }\r
583         // Update note contents\r
584         public void updateNoteContent(String guid, String content) {\r
585                 logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");\r
586 //              EnmlConverter enml = new EnmlConverter(logger);\r
587 //              String text = enml.convert(guid, content);\r
588                 \r
589                 // Update the list tables \r
590 /*              for (int i=0; i<masterNoteIndex.size(); i++) {\r
591                         if (masterNoteIndex.get(i).getGuid().equals(guid)) {\r
592                                 masterNoteIndex.get(i).setContent(text);\r
593                                 i = masterNoteIndex.size();\r
594                         }\r
595                 }\r
596                 // Update the list tables \r
597                 for (int i=0; i<getNoteIndex().size(); i++) {\r
598                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
599                                 getNoteIndex().get(i).setContent(text);\r
600                                 i = getNoteIndex().size();\r
601                         }\r
602                 }\r
603 */              \r
604                 // Check if any new tags were encountered\r
605 /*              if (enml.saveInvalidXML) {\r
606                         List<String> elements = Global.invalidElements;\r
607                         for (int i=0; i<elements.size(); i++) {\r
608                                 conn.getInvalidXMLTable().addInvalidElement(elements.get(i));\r
609                         }\r
610                         for (String key : Global.invalidAttributes.keySet()) {\r
611                                 ArrayList<String> attributes = Global.invalidAttributes.get(key);\r
612                                 for (int i=0; i<attributes.size(); i++) {\r
613                                         conn.getInvalidXMLTable().addInvalidAttribute(key, attributes.get(i));\r
614                                 }\r
615                         }\r
616                 }\r
617 */\r
618                 saveRunner.addWork(guid, content);\r
619 //              conn.getNoteTable().updateNoteContent(guid, content);\r
620                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");\r
621         }\r
622         // Update a note creation date\r
623         public void updateNoteCreatedDate(String guid, QDateTime date) {\r
624                 noteModel.updateNoteCreatedDate(guid, date);\r
625                 conn.getNoteTable().updateNoteCreatedDate(guid, date);\r
626         }\r
627         // Subject date has been changed\r
628         public void updateNoteSubjectDate(String guid, QDateTime date) {\r
629                 noteModel.updateNoteSubjectDate(guid, date);\r
630                 conn.getNoteTable().updateNoteSubjectDate(guid, date);\r
631         }\r
632         // Author has changed\r
633         public void updateNoteAuthor(String guid, String author) {\r
634                 noteModel.updateNoteAuthor(guid, author);\r
635                 conn.getNoteTable().updateNoteAuthor(guid, author);\r
636         }\r
637         // Author has changed\r
638         public void updateNoteGeoTag(String guid, Double lon, Double lat, Double alt) {\r
639                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
640                         if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
641                                 getMasterNoteIndex().get(i).getAttributes().setLongitude(lon);\r
642                                 getMasterNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
643                                 getMasterNoteIndex().get(i).getAttributes().setLatitude(lat);\r
644                                 getMasterNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
645                                 getMasterNoteIndex().get(i).getAttributes().setAltitude(alt);\r
646                                 getMasterNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
647                                 i = getMasterNoteIndex().size();\r
648                         }       \r
649                 }\r
650                 // Update the list tables \r
651                 for (int i=0; i<getNoteIndex().size(); i++) {\r
652                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
653                                 getNoteIndex().get(i).getAttributes().setLongitude(lon);\r
654                                 getNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
655                                 getNoteIndex().get(i).getAttributes().setLatitude(lat);\r
656                                 getNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
657                                 getNoteIndex().get(i).getAttributes().setAltitude(alt);\r
658                                 getNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
659                                 i = getNoteIndex().size();\r
660                         }\r
661                 }\r
662                 conn.getNoteTable().updateNoteGeoTags(guid, lon, lat, alt);\r
663         }\r
664         // Source URL changed\r
665         public void updateNoteSourceUrl(String guid, String url) {\r
666                 noteModel.updateNoteSourceUrl(guid, url);\r
667                 conn.getNoteTable().updateNoteSourceUrl(guid, url);\r
668         }\r
669         // Update a note last changed date\r
670         public void updateNoteAlteredDate(String guid, QDateTime date) {\r
671                 noteModel.updateNoteChangedDate(guid, date);\r
672                 conn.getNoteTable().updateNoteAlteredDate(guid, date);\r
673         }\r
674         // Update a note title\r
675         public void updateNoteTitle(String guid, String title) {\r
676                 logger.log(logger.HIGH, "Entering ListManager.updateNoteTitle");\r
677                 conn.getNoteTable().updateNoteTitle(guid, title);\r
678                 noteModel.updateNoteTitle(guid, title);\r
679                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteTitle");\r
680         }\r
681         // Update a note's notebook\r
682         public void updateNoteNotebook(String guid, String notebookGuid) {\r
683                 logger.log(logger.HIGH, "Entering ListManager.updateNoteNotebook");\r
684                 noteModel.updateNoteNotebook(guid, notebookGuid);\r
685                 conn.getNoteTable().updateNoteNotebook(guid, notebookGuid, true);\r
686                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteNotebook");\r
687         }\r
688         // Update a note sequence number\r
689         public void updateNoteSequence(String guid, int sequence) {\r
690                 logger.log(logger.HIGH, "Entering ListManager.updateNoteSequence");\r
691 \r
692                 conn.getNoteTable().updateNoteSequence(guid, sequence);\r
693                 \r
694                 for (int i=0; i<noteModel.getMasterNoteIndex().size(); i++) {\r
695                         if (noteModel.getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
696                                 noteModel.getMasterNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
697                                 i=noteModel.getMasterNoteIndex().size()+1;\r
698                         }\r
699                 }\r
700                 \r
701                 for (int i=0; i<getNoteIndex().size(); i++) {\r
702                         if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
703                                 getNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
704                                 i=getNoteIndex().size()+1;\r
705                         }\r
706                 }\r
707                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteSequence");\r
708         }\r
709         public void updateNoteGuid(String oldGuid, String newGuid, boolean updateDatabase) {\r
710                 logger.log(logger.HIGH, "Entering ListManager.updateNoteGuid");\r
711                 if (updateDatabase) \r
712                         conn.getNoteTable().updateNoteGuid(oldGuid, newGuid);\r
713                 noteModel.updateNoteGuid(oldGuid, newGuid);\r
714                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteGuid");\r
715 \r
716         }\r
717 \r
718         \r
719         //************************************************************************************\r
720         //************************************************************************************\r
721         //**  Tag functions\r
722         //************************************************************************************\r
723         //************************************************************************************  \r
724         // Update a tag sequence number\r
725         public void updateTagSequence(String guid, int sequence) {\r
726                 logger.log(logger.HIGH, "Entering ListManager.updateTagSequence");\r
727 \r
728                 conn.getTagTable().updateTagSequence(guid, sequence);   \r
729                 for (int i=0; i<tagIndex.size(); i++) {\r
730                         if (tagIndex.get(i).getGuid().equals(guid)) {\r
731                                 getTagIndex().get(i).setUpdateSequenceNum(sequence);\r
732                                 i=tagIndex.size()+1;\r
733                         }\r
734                 }\r
735                 logger.log(logger.HIGH, "Leaving ListManager.updateTagSequence");\r
736         }\r
737         // Update a tag guid number\r
738         public void updateTagGuid(String oldGuid, String newGuid) {\r
739                 logger.log(logger.HIGH, "Entering ListManager.updateTagGuid");\r
740 \r
741                 conn.getTagTable().updateTagGuid(oldGuid, newGuid);     \r
742                 for (int i=0; i<tagIndex.size(); i++) {\r
743                         if (tagIndex.get(i).getGuid().equals(oldGuid)) {\r
744                                 tagIndex.get(i).setGuid(newGuid);\r
745                                 i=tagIndex.size()+1;\r
746                         }\r
747                 }\r
748                 logger.log(logger.HIGH, "Leaving ListManager.updateTagGuid");\r
749 \r
750         }\r
751 \r
752 \r
753         //************************************************************************************\r
754         //************************************************************************************\r
755         //**  Notebook functions\r
756         //************************************************************************************\r
757         //************************************************************************************  \r
758         // Delete a notebook\r
759         public void deleteNotebook(String guid) {\r
760                 for (int i=0; i<getNotebookIndex().size(); i++) {\r
761                         if (getNotebookIndex().get(i).getGuid().equals(guid)) {\r
762                                 getNotebookIndex().remove(i);\r
763                                 i=getMasterNoteIndex().size();\r
764                         }\r
765                 }\r
766                 conn.getNotebookTable().expungeNotebook(guid, true);            \r
767         }\r
768         // Update a notebook sequence number\r
769         public void updateNotebookSequence(String guid, int sequence) {\r
770                 logger.log(logger.HIGH, "Entering ListManager.updateNotebookSequence");\r
771 \r
772                 conn.getNotebookTable().updateNotebookSequence(guid, sequence);\r
773                 \r
774                 for (int i=0; i<notebookIndex.size(); i++) {\r
775                         if (notebookIndex.get(i).getGuid().equals(guid)) {\r
776                                 notebookIndex.get(i).setUpdateSequenceNum(sequence);\r
777                                 i=notebookIndex.size()+1;\r
778                         }\r
779                 }\r
780                 logger.log(logger.HIGH, "Leaving ListManager.updateNotebookSequence");\r
781 \r
782         }\r
783         // Update a notebook Guid number\r
784         public void updateNotebookGuid(String oldGuid, String newGuid) {\r
785                 logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");\r
786 \r
787                 conn.getNotebookTable().updateNotebookGuid(oldGuid, newGuid);\r
788                 \r
789                 for (int i=0; i<notebookIndex.size(); i++) {\r
790                         if (notebookIndex.get(i).getGuid().equals(oldGuid)) {\r
791                                 notebookIndex.get(i).setGuid(newGuid);\r
792                                 i=notebookIndex.size()+1;\r
793                         }\r
794                 }\r
795                 logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");\r
796 \r
797         }\r
798         \r
799         \r
800         //************************************************************************************\r
801         //************************************************************************************\r
802         //**  Load and filter the note index\r
803         //************************************************************************************\r
804         //************************************************************************************\r
805         \r
806         public void noteDownloaded(Note n) {\r
807                 boolean found = false;\r
808                 for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
809                         if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
810                                 getMasterNoteIndex().set(i,n);\r
811                                 found = true;\r
812                                 i=getMasterNoteIndex().size();\r
813                         }\r
814                 }\r
815                 \r
816                 if (!found)\r
817                         getMasterNoteIndex().add(n);\r
818                 \r
819                 for (int i=0; i<getNoteIndex().size(); i++) {\r
820                         if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
821                                 if (filterRecord(getNoteIndex().get(i)))\r
822                                         getNoteIndex().add(n);\r
823                                 getNoteIndex().remove(i);\r
824                                 i=getNoteIndex().size();\r
825                         }\r
826                 }\r
827                 \r
828                 if (filterRecord(n))\r
829                         getNoteIndex().add(n);\r
830                 \r
831         }\r
832         // Check if a note matches the currently selected notebooks, tags, or attribute searches.\r
833         public boolean filterRecord(Note n) {\r
834                                 \r
835                 boolean goodNotebook = false;\r
836                 boolean goodTag = false;\r
837                 boolean goodStatus = false;\r
838                         \r
839                 // Check note status\r
840                 if (!n.isActive() && Global.showDeleted)\r
841                         return true;\r
842                 else {\r
843                         if (n.isActive() && !Global.showDeleted)\r
844                                 goodStatus = true;\r
845                         // Begin filtering results\r
846                         if (goodStatus)\r
847                                 goodNotebook = filterByNotebook(n.getNotebookGuid());\r
848                         if (goodNotebook) \r
849                                 goodTag = filterByTag(n.getTagGuids());\r
850                         if (goodTag) {\r
851                                 boolean goodCreatedBefore = false;\r
852                                 boolean goodCreatedSince = false;\r
853                                 boolean goodChangedBefore = false;\r
854                                 boolean goodChangedSince = false;\r
855                                 boolean goodContains = false;\r
856                                         \r
857                                 if (!Global.createdBeforeFilter.hasSelection())\r
858                                         goodCreatedBefore = true;\r
859                                 else\r
860                                         goodCreatedBefore = Global.createdBeforeFilter.check(n);\r
861                                 \r
862                                 if (!Global.createdSinceFilter.hasSelection())\r
863                                         goodCreatedSince = true;\r
864                                 else\r
865                                         goodCreatedSince = Global.createdSinceFilter.check(n);\r
866                                 \r
867                                 if (!Global.changedBeforeFilter.hasSelection())\r
868                                         goodChangedBefore = true;\r
869                                 else\r
870                                         goodChangedBefore = Global.changedBeforeFilter.check(n);\r
871                                         if (!Global.changedSinceFilter.hasSelection())\r
872                                         goodChangedSince = true;\r
873                                 else\r
874                                         goodChangedSince = Global.changedSinceFilter.check(n);\r
875                                 if (!Global.containsFilter.hasSelection())\r
876                                         goodContains = true;\r
877                                 else\r
878                                         goodContains = Global.containsFilter.check(conn.getNoteTable(), n);\r
879                                         \r
880                                 if (goodCreatedSince && goodCreatedBefore && goodChangedSince && goodChangedBefore && goodContains)\r
881                                         return true;\r
882                         }\r
883                 }       \r
884                 return false;\r
885         }\r
886         \r
887         // Load the note index based upon what the user wants.\r
888         public void loadNotesIndex() {\r
889                 logger.log(logger.EXTREME, "Entering ListManager.loadNotesIndex()");\r
890                 tagCounterRunner.abortCount = true;\r
891                 notebookCounterRunner.abortCount = true;\r
892                 trashCounterRunner.abortCount = true;\r
893                 \r
894                 List<Note> matches;\r
895                 if (enSearchChanged || getMasterNoteIndex() == null)\r
896                         matches = enSearch.matchWords();\r
897                 else\r
898                         matches = getMasterNoteIndex();\r
899                 \r
900                 if (matches == null)\r
901                         matches = getMasterNoteIndex();\r
902                 \r
903                 setNoteIndex(new ArrayList<Note>());\r
904                 for (int i=0; i<matches.size(); i++) {\r
905                         if (filterRecord(matches.get(i)))\r
906                                 getNoteIndex().add(matches.get(i));\r
907                 }\r
908                 countNotebookResults(getNoteIndex());\r
909                 countTagResults(getNoteIndex());\r
910                 enSearchChanged = false;\r
911                 reloadTrashCount();\r
912                 logger.log(logger.EXTREME, "Leaving ListManager.loadNotesIndex()");\r
913         }\r
914         public void countNotebookResults(List<Note> index) {\r
915                 logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults()");\r
916                 if (!Global.mimicEvernoteInterface) {\r
917                         notebookCounterRunner.setNoteIndex(index);\r
918                         notebookCounterRunner.release(CounterRunner.NOTEBOOK);\r
919                 } else {\r
920                         notebookCounterRunner.setNoteIndex(getMasterNoteIndex());\r
921                         notebookCounterRunner.release(CounterRunner.NOTEBOOK_ALL);\r
922                 }\r
923                 logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");\r
924         }\r
925         public void countTagResults(List<Note> index) {\r
926                 logger.log(logger.EXTREME, "Entering ListManager.countTagResults");\r
927                 if (!Global.tagBehavior().equalsIgnoreCase("DoNothing")) {\r
928                         tagCounterRunner.setNoteIndex(index);\r
929                         tagCounterRunner.release(CounterRunner.TAG);\r
930                 } else {\r
931                         tagCounterRunner.setNoteIndex(null);\r
932                         tagCounterRunner.release(CounterRunner.TAG_ALL);\r
933                 }\r
934                 logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");\r
935         }\r
936         // Update the count of items in the trash\r
937         public void reloadTrashCount() {\r
938                 logger.log(logger.EXTREME, "Entering ListManager.reloadTrashCount");\r
939                 trashCounterRunner.setNoteIndex(getNoteIndex());\r
940                 trashCounterRunner.release(CounterRunner.TRASH);\r
941                 logger.log(logger.EXTREME, "Leaving ListManager.reloadTrashCount");\r
942         }       \r
943         \r
944         private boolean filterByNotebook(String guid) {\r
945                 boolean good = false;\r
946                 if (selectedNotebooks.size() == 0)\r
947                         good = true;\r
948                 if (!good && selectedNotebooks.contains(guid)) \r
949                         good = true;\r
950 \r
951                 for (int i=0; i<getArchiveNotebookIndex().size() && good; i++) {\r
952                         if (guid.equals(getArchiveNotebookIndex().get(i).getGuid())) {\r
953                                 good = false;\r
954                                 return good;\r
955                         }\r
956                 }\r
957                 return good;\r
958         }\r
959         private boolean filterByTag(List<String> noteTags) {\r
960                 if (noteTags == null || selectedTags == null)\r
961                         return true;\r
962                 \r
963                 if (selectedTags.size() == 0) \r
964                         return true;\r
965                 \r
966                 for (int i=0; i<selectedTags.size(); i++) {\r
967                         String selectedGuid = selectedTags.get(i);\r
968                         if (noteTags.contains(selectedGuid))\r
969                                         return true;\r
970                 }\r
971                 return false;\r
972         }\r
973 \r
974         \r
975         \r
976         public void updateNoteTitleColor(String guid, Integer color) {\r
977                 noteModel.updateNoteTitleColor(guid, color);\r
978                 conn.getNoteTable().setNoteTitleColor(guid, color);\r
979         }\r
980         public void loadNoteTitleColors() {\r
981                 List<Pair<String,Integer>> colors = conn.getNoteTable().getNoteTitleColors();\r
982                 if (noteModel.getTitleColors() == null)\r
983                         noteModel.setTitleColors(new HashMap<String,Integer>());\r
984                 else\r
985                         noteModel.getTitleColors().clear();\r
986                 for (int i=0; i<colors.size(); i++) {\r
987                         noteModel.getTitleColors().put(colors.get(i).getFirst(), colors.get(i).getSecond());\r
988                 }\r
989         }\r
990         \r
991         //********************************************************************************\r
992         //********************************************************************************\r
993         //* Support signals from the index thread\r
994         //********************************************************************************\r
995         //********************************************************************************\r
996         // Reset a flag if an index is needed\r
997         public void setIndexNeeded(String guid, String type, Boolean b) {\r
998                 if (Global.keepRunning && type.equalsIgnoreCase("content"))\r
999                         conn.getNoteTable().setIndexNeeded(guid, false);\r
1000                 if (Global.keepRunning && type.equalsIgnoreCase("resource")) {\r
1001                         conn.getNoteTable().noteResourceTable.setIndexNeeded(guid, b);\r
1002                 }\r
1003         }\r
1004         \r
1005         public boolean threadCheck(int id) {\r
1006                 if (id == Global.notebookCounterThreadId) \r
1007                         return notebookThread.isAlive();\r
1008                 if (id == Global.tagCounterThreadId) \r
1009                         return tagThread.isAlive();\r
1010                 if (id == Global.trashCounterThreadId) \r
1011                         return trashThread.isAlive();\r
1012                 if (id == Global.saveThreadId) \r
1013                         return saveThread.isAlive();\r
1014                 return false;\r
1015         }\r
1016         \r
1017         \r
1018         \r
1019         //********************************************************************************\r
1020         //********************************************************************************\r
1021         //* Utility Functions\r
1022         //********************************************************************************\r
1023         //********************************************************************************\r
1024         public void compactDatabase() {\r
1025                 conn.compactDatabase();\r
1026 //              IndexConnection idx = new IndexConnection(logger, "nevernote-compact");\r
1027 //              idx.dbSetup();\r
1028 //              idx.dbShutdown();\r
1029         }\r
1030 \r
1031         // Rebuild the note HTML to something usable\r
1032         public List<String> scanNoteForResources(Note n) {\r
1033                 logger.log(logger.HIGH, "Entering ListManager.scanNoteForResources");\r
1034                 logger.log(logger.EXTREME, "Note guid: " +n.getGuid());\r
1035                 QDomDocument doc = new QDomDocument();\r
1036                 QDomDocument.Result result = doc.setContent(n.getContent());\r
1037                 if (!result.success) {\r
1038                         logger.log(logger.MEDIUM, "Parse error when scanning note for resources.");\r
1039                         logger.log(logger.MEDIUM, "Note guid: " +n.getGuid());\r
1040                         return null;\r
1041                 }\r
1042                                 \r
1043                 List<String> returnArray = new ArrayList<String>();\r
1044                 QDomNodeList anchors = doc.elementsByTagName("en-media");\r
1045                 for (int i=0; i<anchors.length(); i++) {\r
1046                         QDomElement enmedia = anchors.at(i).toElement();\r
1047                         if (enmedia.hasAttribute("type")) {\r
1048                                 QDomAttr hash = enmedia.attributeNode("hash");\r
1049                                 returnArray.add(hash.value().toString());\r
1050                         }\r
1051                 }\r
1052                 logger.log(logger.HIGH, "Leaving ListManager.scanNoteForResources");\r
1053                 return returnArray;\r
1054         }\r
1055         // Given a list of tags, produce a string list of tag names\r
1056         public String getTagNamesForNote(Note n) {\r
1057                 StringBuffer buffer = new StringBuffer(100);\r
1058                 Vector<String> v = new Vector<String>();\r
1059                 List<String> guids = n.getTagGuids();\r
1060                 \r
1061                 if (guids == null) \r
1062                         return "";\r
1063                 \r
1064                 for (int i=0; i<guids.size(); i++) {\r
1065                         v.add(getTagNameByGuid(guids.get(i)));\r
1066                 }\r
1067                 Comparator<String> comparator = Collections.reverseOrder();\r
1068                 Collections.sort(v,comparator);\r
1069                 Collections.reverse(v);\r
1070                 \r
1071                 for (int i = 0; i<v.size(); i++) {\r
1072                         if (i>0) \r
1073                                 buffer.append(", ");\r
1074                         buffer.append(v.get(i));\r
1075                 }\r
1076                 \r
1077                 return buffer.toString();\r
1078         }\r
1079         // Get a tag name when given a tag guid\r
1080         public String getTagNameByGuid(String guid) {\r
1081                 for (int i=0; i<getTagIndex().size(); i++) {\r
1082                         String s = getTagIndex().get(i).getGuid();\r
1083                         if (s.equals(guid)) { \r
1084                                 return getTagIndex().get(i).getName();\r
1085                         }\r
1086                 }\r
1087                 return "";\r
1088         }\r
1089         // For a notebook guid, return the name\r
1090         public String getNotebookNameByGuid(String guid) {\r
1091                 if (notebookIndex == null)\r
1092                         return null;\r
1093                 for (int i=0; i<notebookIndex.size(); i++) {\r
1094                         String s = notebookIndex.get(i).getGuid();\r
1095                         if (s.equals(guid)) { \r
1096                                 return notebookIndex.get(i).getName();\r
1097                         }\r
1098                 }\r
1099                 return "";\r
1100         }\r
1101         \r
1102         \r
1103 }\r