OSDN Git Service

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