OSDN Git Service

ノートコンテンツをwordテーブルに登録しないように変更。
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / utilities / ListManager.java
index e46e398..366f7ec 100644 (file)
-/*\r
- * This file is part of NeverNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.utilities;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Notebook;\r
-import com.evernote.edam.type.SavedSearch;\r
-import com.evernote.edam.type.Tag;\r
-import com.trolltech.qt.QThread;\r
-import com.trolltech.qt.core.QDateTime;\r
-import com.trolltech.qt.sql.QSqlQuery;\r
-import com.trolltech.qt.xml.QDomAttr;\r
-import com.trolltech.qt.xml.QDomDocument;\r
-import com.trolltech.qt.xml.QDomElement;\r
-import com.trolltech.qt.xml.QDomNodeList;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.filters.EnSearch;\r
-import cx.fbn.nevernote.filters.NotebookCounter;\r
-import cx.fbn.nevernote.filters.TagCounter;\r
-import cx.fbn.nevernote.gui.NoteTableModel;\r
-import cx.fbn.nevernote.signals.NotebookSignal;\r
-import cx.fbn.nevernote.signals.StatusSignal;\r
-import cx.fbn.nevernote.signals.TagSignal;\r
-import cx.fbn.nevernote.signals.ThreadSignal;\r
-import cx.fbn.nevernote.signals.TrashSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.threads.CounterRunner;\r
-import cx.fbn.nevernote.threads.SaveRunner;\r
-\r
-\r
-public class ListManager  {\r
-\r
-       \r
-       private final ApplicationLogger logger;  \r
-       DatabaseConnection                              conn;\r
-       QSqlQuery                                               deleteWords;\r
-       QSqlQuery                                               insertWords;\r
-       \r
-       private List<Tag>                               tagIndex;\r
-       private List<Notebook>                  notebookIndex;\r
-       private List<Notebook>                  archiveNotebookIndex;\r
-       private List<String>                    localNotebookIndex;\r
-\r
-       private List<SavedSearch>               searchIndex;\r
-\r
-       private List<String>                    selectedNotebooks;\r
-       private final NoteTableModel                    noteModel;\r
-       \r
-       \r
-       private List<String>                    selectedTags;\r
-       private String                                  selectedSearch;\r
-       ThreadSignal                                    signals;\r
-       public StatusSignal                             status;\r
-       private final CounterRunner             notebookCounterRunner;\r
-       private final QThread                   notebookThread;\r
-       private final CounterRunner             tagCounterRunner;\r
-       private final QThread                   tagThread;\r
-       \r
-       private final CounterRunner             trashCounterRunner;\r
-       private final QThread                   trashThread;\r
-       public TrashSignal                              trashSignal;\r
-       \r
-       private List<NotebookCounter>   notebookCounter;                                // count of displayed notes in each notebook\r
-       private List<TagCounter>                tagCounter;                                             // count of displayed notes for each tag\r
-       \r
-       private EnSearch                                enSearch;\r
-       private boolean                                 enSearchChanged;\r
-       public HashMap<String, String>  wordMap;\r
-       public TagSignal                                tagSignal;\r
-       public NotebookSignal                   notebookSignal;\r
-       private int                                             trashCount;\r
-    SaveRunner                 saveRunner;                                     // Thread used to save content.  Used because the xml conversion is slowwwww\r
-    QThread                            saveThread;\r
-       \r
-       // Constructor\r
-       public ListManager(DatabaseConnection d, ApplicationLogger l) {\r
-               conn = d;\r
-               logger = l;\r
-               \r
-       status = new StatusSignal();\r
-               signals = new ThreadSignal();\r
-               \r
-               // setup index locks\r
-               enSearchChanged = false;\r
-               \r
-               // Setup arrays\r
-               noteModel = new NoteTableModel(this);\r
-               selectedTags = new ArrayList<String>();\r
-\r
-               notebookCounter = new ArrayList<NotebookCounter>();\r
-               tagCounter = new ArrayList<TagCounter>();\r
-               selectedNotebooks = new ArrayList<String>();\r
-                               \r
-               reloadIndexes();\r
-               \r
-               notebookSignal = new NotebookSignal();\r
-               notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
-               notebookCounterRunner.setNoteIndex(getNoteIndex());\r
-               notebookCounterRunner.notebookSignal.countsChanged.connect(this, "setNotebookCounter(List)");\r
-               notebookThread = new QThread(notebookCounterRunner, "Notebook Counter Thread");\r
-               notebookThread.start();\r
-               \r
-               tagSignal = new TagSignal();\r
-               tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
-               tagCounterRunner.setNoteIndex(getNoteIndex());\r
-               tagCounterRunner.tagSignal.countsChanged.connect(this, "setTagCounter(List)");\r
-               tagThread = new QThread(tagCounterRunner, "Tag Counter Thread");\r
-               tagThread.start();\r
-               \r
-               trashSignal = new TrashSignal();\r
-               trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH, Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
-               trashCounterRunner.trashSignal.countChanged.connect(this, "trashSignalReceiver(Integer)");\r
-               trashThread = new QThread(trashCounterRunner, "Trash Counter Thread");\r
-               trashThread.start();\r
-               reloadTrashCount();\r
-               \r
-               wordMap = new HashMap<String, String>();\r
-               tagSignal = new TagSignal();\r
-               \r
-               logger.log(logger.EXTREME, "Setting save thread");\r
-               saveRunner = new SaveRunner("saveRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
-               saveThread = new QThread(saveRunner, "Save Runner Thread");\r
-               saveThread.start();\r
-\r
-               loadNoteTitleColors();\r
-                               \r
-       }\r
-       \r
-       public void stop() {\r
-               saveRunner.addWork("stop", "");\r
-               tagCounterRunner.release(CounterRunner.EXIT);\r
-               notebookCounterRunner.release(CounterRunner.EXIT);\r
-               trashCounterRunner.release(CounterRunner.EXIT);\r
-               \r
-               logger.log(logger.MEDIUM, "Waiting for notebookCounterThread to stop");                         \r
-               try {\r
-                       notebookThread.join();\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               \r
-               logger.log(logger.MEDIUM, "Waiting for tagCounterThread to stop");                      \r
-               try {\r
-                       tagThread.join();\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-\r
-               logger.log(logger.MEDIUM, "Waiting for trashThread to stop");                   \r
-               try {\r
-                       trashThread.join();\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-\r
-\r
-               logger.log(logger.MEDIUM, "Waiting for saveThread to stop");                    \r
-               try {\r
-                       saveThread.join(0);\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-\r
-\r
-       }\r
-\r
-       //***************************************************************\r
-       //***************************************************************\r
-       //* Refresh lists after a db sync\r
-       //***************************************************************\r
-       //***************************************************************\r
-       public void refreshLists(Note n, boolean dirty, String content) {\r
-               if (dirty) {\r
-//                     conn.getNoteTable().updateNoteContent(n.getGuid(), n.getContent());\r
-                       saveRunner.addWork(n.getGuid(), content);\r
-                       conn.getNoteTable().updateNoteTitle(n.getGuid(), n.getTitle());\r
-               }\r
-               \r
-               setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
-               setTagIndex(conn.getTagTable().getAll());\r
-               setNotebookIndex(conn.getNotebookTable().getAll());\r
-               \r
-               List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
-               localNotebookIndex = new ArrayList<String>();\r
-               for (int i=0; i<local.size(); i++)\r
-                       localNotebookIndex.add(local.get(i).getGuid());\r
-               \r
-               noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
-               // For performance reasons, we didn't get the tags for every note individually.  We now need to \r
-               // get them\r
-               List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       List<String> tags = new ArrayList<String>();\r
-                       List<String> names = new ArrayList<String>();\r
-                       for (int j=0; j<noteTags.size(); j++) {\r
-                               if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
-                                       tags.add(noteTags.get(j).tagGuid);\r
-                                       names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
-                               }\r
-                       }\r
-                       \r
-                       getMasterNoteIndex().get(i).setTagGuids(tags);\r
-                       getMasterNoteIndex().get(i).setTagNames(names);\r
-               }\r
-               \r
-               \r
-               setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
-               \r
-               enSearchChanged = true;\r
-       }\r
-\r
-       public void reloadIndexes() {\r
-               setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
-\r
-               List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
-               localNotebookIndex = new ArrayList<String>();\r
-               for (int i=0; i<local.size(); i++)\r
-                       localNotebookIndex.add(local.get(i).getGuid());\r
-               \r
-               // Load tags\r
-               setTagIndex(conn.getTagTable().getAll());\r
-               // Load notebooks\r
-               setNotebookIndex(conn.getNotebookTable().getAll());\r
-               // load archived notebooks (if note using the EN interface)\r
-               setArchiveNotebookIndex(conn.getNotebookTable().getAllArchived());\r
-               // load saved search index\r
-               setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
-               // Load search helper utility\r
-               enSearch = new EnSearch(conn,  logger, "", getTagIndex(), Global.getMinimumWordLength(), Global.getRecognitionWeight());\r
-               logger.log(logger.HIGH, "Building note index");\r
-\r
-//             if (getMasterNoteIndex() == null) { \r
-                       noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
-//             }\r
-               // For performance reasons, we didn't get the tags for every note individually.  We now need to \r
-               // get them\r
-               List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       List<String> tags = new ArrayList<String>();\r
-                       List<String> names = new ArrayList<String>();\r
-                       for (int j=0; j<noteTags.size(); j++) {\r
-                               if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
-                                       tags.add(noteTags.get(j).tagGuid);\r
-                                       names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
-                               }\r
-                       }\r
-                       \r
-                       getMasterNoteIndex().get(i).setTagGuids(tags);\r
-                       getMasterNoteIndex().get(i).setTagNames(names);\r
-               }\r
-               \r
-               setNoteIndex(getMasterNoteIndex());\r
-\r
-       }\r
-       \r
-       //***************************************************************\r
-       //***************************************************************\r
-       //* selected notebooks\r
-       //***************************************************************\r
-       //***************************************************************\r
-       // Return the selected notebook(s)\r
-       public List<String> getSelectedNotebooks() {\r
-               return selectedNotebooks;\r
-       }\r
-       // Set the current selected notebook(s)\r
-       public void setSelectedNotebooks(List <String> s) {\r
-               if (s == null) \r
-                       s = new ArrayList<String>();\r
-               selectedNotebooks = s;\r
-       }\r
-       \r
-                               \r
-    //***************************************************************\r
-    //***************************************************************\r
-    //** These functions deal with setting & retrieving the master lists\r
-    //***************************************************************\r
-    //***************************************************************\r
-       // Get the note table model\r
-       public NoteTableModel getNoteTableModel() {\r
-               return noteModel;\r
-       }\r
-       // save the saved search index\r
-       private void setSavedSearchIndex(List<SavedSearch> t) {\r
-               searchIndex = t;\r
-       }\r
-       // Retrieve the Tag index\r
-       public List<SavedSearch> getSavedSearchIndex() {\r
-               return searchIndex;\r
-\r
-       }\r
-       // save the tag index\r
-       private void setTagIndex(List<Tag> t) {\r
-               tagIndex = t;\r
-       }       \r
-       // Retrieve the Tag index\r
-       public List<Tag> getTagIndex() {\r
-               return tagIndex;\r
-       }\r
-       private void setNotebookIndex(List<Notebook> t) {\r
-               notebookIndex = t;\r
-       }\r
-       private void setArchiveNotebookIndex(List<Notebook> t) {\r
-               archiveNotebookIndex = t;\r
-       }\r
-       // Retrieve the Notebook index\r
-       public List<Notebook> getNotebookIndex() {\r
-               return notebookIndex;\r
-\r
-       }\r
-       public List<Notebook> getArchiveNotebookIndex() {\r
-               return archiveNotebookIndex;\r
-       }\r
-       // Save the current note list\r
-       private void setNoteIndex(List<Note> n) {\r
-               noteModel.setNoteIndex(n);\r
-       }\r
-       // Get the note index\r
-       public synchronized List<Note> getNoteIndex() {\r
-               return noteModel.getNoteIndex();\r
-       }\r
-       // Save the count of notes per notebook\r
-       public void setNotebookCounter(List<NotebookCounter> n) {\r
-               notebookCounter = n;\r
-               notebookSignal.refreshNotebookTreeCounts.emit(getNotebookIndex(), notebookCounter);\r
-       }\r
-       public List<NotebookCounter> getNotebookCounter() {\r
-               return notebookCounter;\r
-       }\r
-       // Save the count of notes for each tag\r
-       public void setTagCounter(List<TagCounter> n) {\r
-               tagCounter = n;\r
-               tagSignal.refreshTagTreeCounts.emit(tagCounter);\r
-       }\r
-       public List<TagCounter> getTagCounter() {\r
-               return tagCounter;\r
-       }\r
-       public List<String> getLocalNotebooks() {\r
-               return localNotebookIndex;\r
-       }\r
-       // Unsynchronized Note List\r
-       public List<String> getUnsynchronizedNotes() {\r
-               return noteModel.getUnsynchronizedNotes();\r
-       }\r
-       public void setUnsynchronizedNotes(List<String> l) {\r
-               noteModel.setUnsynchronizedNotes(l);\r
-       }\r
-       // Return a count of items in the trash\r
-       public int getTrashCount() {\r
-               return trashCount;\r
-       }\r
-       // get the EnSearch variable\r
-       public EnSearch getEnSearch() {\r
-               return enSearch;\r
-       }\r
-       public List<Note> getMasterNoteIndex() {\r
-               return noteModel.getMasterNoteIndex();\r
-       }\r
-       \r
-    //***************************************************************\r
-    //***************************************************************\r
-    //** These functions deal with setting & retrieving filters\r
-    //***************************************************************\r
-    //***************************************************************\r
-       public void setEnSearch(String t) {\r
-               enSearch = new EnSearch(conn,logger, t, getTagIndex(), Global.getMinimumWordLength(), Global.getRecognitionWeight());\r
-               enSearchChanged = true;\r
-       }\r
-       // Save search tags\r
-       public void setSelectedTags(List<String> selectedTags) {\r
-               this.selectedTags = selectedTags;\r
-       }\r
-       // Save seleceted search\r
-       public void setSelectedSavedSearch(String s) {\r
-               this.selectedSearch = s;\r
-       }\r
-       // Get search tags\r
-       public List<String> getSelectedTags() {\r
-               return selectedTags;\r
-       }\r
-       // Get saved search\r
-       public String getSelectedSearch() {\r
-               return selectedSearch;\r
-       }\r
-       \r
-       \r
-       \r
-       \r
-    //***************************************************************\r
-    //***************************************************************\r
-    //** Note functions\r
-    //***************************************************************\r
-    //***************************************************************\r
-       // Save Note Tags\r
-       public void saveNoteTags(String noteGuid, List<String> tags) {\r
-               logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");\r
-               String tagName;\r
-               conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);\r
-               List<String> tagGuids = new ArrayList<String>();\r
-               boolean newTagCreated = false;\r
-               \r
-               for (int i=0; i<tags.size(); i++) {\r
-                       tagName = tags.get(i);\r
-                       boolean found = false;\r
-                       for (int j=0; j<tagIndex.size(); j++) {\r
-                               if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {\r
-                                       conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, tagIndex.get(j).getGuid());\r
-                                       tagGuids.add(tagIndex.get(j).getGuid());\r
-                                       j=tagIndex.size()+1;\r
-                                       found = true;\r
-                               }\r
-                       }\r
-                       if (!found) {\r
-                               Tag nTag = new Tag();\r
-                               nTag.setName(tagName);\r
-                               Calendar currentTime = new GregorianCalendar();\r
-                               Long l = new Long(currentTime.getTimeInMillis());\r
-                               long prevTime = l;\r
-                               while (l==prevTime) {\r
-                                       currentTime = new GregorianCalendar();\r
-                                       l=currentTime.getTimeInMillis();\r
-                               }\r
-                               String randint = new String(Long.toString(l));\r
-                       \r
-                               nTag.setUpdateSequenceNum(0);\r
-                               nTag.setGuid(randint);\r
-                               conn.getTagTable().addTag(nTag, true);\r
-                               getTagIndex().add(nTag);\r
-                               conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, nTag.getGuid());\r
-                               tagGuids.add(nTag.getGuid());\r
-                               newTagCreated = true;\r
-                       }\r
-               }\r
-               \r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(noteGuid)) {\r
-                               getNoteIndex().get(i).setTagNames(tags);\r
-                               getNoteIndex().get(i).setTagGuids(tagGuids);\r
-                               i=getNoteIndex().size()+1;\r
-                       }\r
-               }\r
-               if (newTagCreated)\r
-                       tagSignal.listChanged.emit();\r
-               logger.log(logger.HIGH, "Leaving ListManager.saveNoteTags");\r
-       }\r
-       // Delete a note\r
-       public void deleteNote(String guid) {\r
-               trashCounterRunner.abortCount = true;\r
-               Calendar currentTime = new GregorianCalendar();\r
-               Long l = new Long(currentTime.getTimeInMillis());\r
-               long prevTime = l;\r
-               while (l==prevTime) {\r
-                       currentTime = new GregorianCalendar();\r
-                       l=currentTime.getTimeInMillis();\r
-               }\r
-               \r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getMasterNoteIndex().get(i).setActive(false);\r
-                               getMasterNoteIndex().get(i).setDeleted(l);\r
-                               i=getMasterNoteIndex().size();\r
-                       }\r
-               }\r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().get(i).setActive(false);\r
-                               getNoteIndex().get(i).setDeleted(l);\r
-                               i=getNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNoteTable().deleteNote(guid);\r
-               reloadTrashCount();\r
-       }\r
-       // Delete a note\r
-       public void restoreNote(String guid) {\r
-               trashCounterRunner.abortCount = true;\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getMasterNoteIndex().get(i).setActive(true);\r
-                               getMasterNoteIndex().get(i).setDeleted(0);\r
-                               i=getMasterNoteIndex().size();\r
-                       }\r
-               }\r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().get(i).setActive(true);\r
-                               getNoteIndex().get(i).setDeleted(0);\r
-                               i=getNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNoteTable().restoreNote(guid);\r
-               reloadTrashCount();\r
-       }\r
-       public void updateNote(Note n) {\r
-               \r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
-                               getMasterNoteIndex().remove(i);\r
-                               getMasterNoteIndex().add(n);\r
-                       }\r
-               }\r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
-                               getNoteIndex().get(i).setActive(true);\r
-                               getNoteIndex().get(i).setDeleted(0);\r
-                               i=getNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNoteTable().updateNote(n, true);\r
-       }\r
-       // Add a note.  \r
-       public void addNote(Note n) {\r
-               noteModel.addNote(n);\r
-       }\r
-       // Expunge a note\r
-       public void expungeNote(String guid) {\r
-               trashCounterRunner.abortCount = true;\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getMasterNoteIndex().remove(i);\r
-                               i=getMasterNoteIndex().size();\r
-                       }\r
-               }\r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().remove(i);\r
-                               i=getNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNoteTable().expungeNote(guid, false, true);\r
-               reloadTrashCount();\r
-       }\r
-       // Expunge a note\r
-       public void emptyTrash() {\r
-               trashCounterRunner.abortCount = true;           \r
-               for (int i=getMasterNoteIndex().size()-1; i>=0; i--) {\r
-                       if (!getMasterNoteIndex().get(i).isActive()) {\r
-                               getMasterNoteIndex().remove(i);\r
-                       }\r
-               }\r
-               \r
-               for (int i=getNoteIndex().size()-1; i>=0; i--) {\r
-                       if (!getNoteIndex().get(i).isActive()) {\r
-                               getNoteIndex().remove(i);\r
-                       } \r
-               }\r
-\r
-               conn.getNoteTable().expungeAllDeletedNotes();\r
-               reloadTrashCount();\r
-       }\r
-       // The trash counter thread has produced a result\r
-       @SuppressWarnings("unused")\r
-       private void trashSignalReceiver(Integer i) {\r
-               trashCount = i;\r
-               trashSignal.countChanged.emit(i);\r
-       }\r
-       // Update note contents\r
-       public void updateNoteContent(String guid, String content) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");\r
-//             EnmlConverter enml = new EnmlConverter(logger);\r
-//             String text = enml.convert(guid, content);\r
-               \r
-               // Update the list tables \r
-/*             for (int i=0; i<masterNoteIndex.size(); i++) {\r
-                       if (masterNoteIndex.get(i).getGuid().equals(guid)) {\r
-                               masterNoteIndex.get(i).setContent(text);\r
-                               i = masterNoteIndex.size();\r
-                       }\r
-               }\r
-               // Update the list tables \r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().get(i).setContent(text);\r
-                               i = getNoteIndex().size();\r
-                       }\r
-               }\r
-*/             \r
-               // Check if any new tags were encountered\r
-/*             if (enml.saveInvalidXML) {\r
-                       List<String> elements = Global.invalidElements;\r
-                       for (int i=0; i<elements.size(); i++) {\r
-                               conn.getInvalidXMLTable().addInvalidElement(elements.get(i));\r
-                       }\r
-                       for (String key : Global.invalidAttributes.keySet()) {\r
-                               ArrayList<String> attributes = Global.invalidAttributes.get(key);\r
-                               for (int i=0; i<attributes.size(); i++) {\r
-                                       conn.getInvalidXMLTable().addInvalidAttribute(key, attributes.get(i));\r
-                               }\r
-                       }\r
-               }\r
-*/\r
-               saveRunner.addWork(guid, content);\r
-//             conn.getNoteTable().updateNoteContent(guid, content);\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");\r
-       }\r
-       // Update a note creation date\r
-       public void updateNoteCreatedDate(String guid, QDateTime date) {\r
-               noteModel.updateNoteCreatedDate(guid, date);\r
-               conn.getNoteTable().updateNoteCreatedDate(guid, date);\r
-       }\r
-       // Subject date has been changed\r
-       public void updateNoteSubjectDate(String guid, QDateTime date) {\r
-               noteModel.updateNoteSubjectDate(guid, date);\r
-               conn.getNoteTable().updateNoteSubjectDate(guid, date);\r
-       }\r
-       // Author has changed\r
-       public void updateNoteAuthor(String guid, String author) {\r
-               noteModel.updateNoteAuthor(guid, author);\r
-               conn.getNoteTable().updateNoteAuthor(guid, author);\r
-       }\r
-       // Author has changed\r
-       public void updateNoteGeoTag(String guid, Double lon, Double lat, Double alt) {\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getMasterNoteIndex().get(i).getAttributes().setLongitude(lon);\r
-                               getMasterNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
-                               getMasterNoteIndex().get(i).getAttributes().setLatitude(lat);\r
-                               getMasterNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
-                               getMasterNoteIndex().get(i).getAttributes().setAltitude(alt);\r
-                               getMasterNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
-                               i = getMasterNoteIndex().size();\r
-                       }       \r
-               }\r
-               // Update the list tables \r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().get(i).getAttributes().setLongitude(lon);\r
-                               getNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
-                               getNoteIndex().get(i).getAttributes().setLatitude(lat);\r
-                               getNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
-                               getNoteIndex().get(i).getAttributes().setAltitude(alt);\r
-                               getNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
-                               i = getNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNoteTable().updateNoteGeoTags(guid, lon, lat, alt);\r
-       }\r
-       // Source URL changed\r
-       public void updateNoteSourceUrl(String guid, String url) {\r
-               noteModel.updateNoteSourceUrl(guid, url);\r
-               conn.getNoteTable().updateNoteSourceUrl(guid, url);\r
-       }\r
-       // Update a note last changed date\r
-       public void updateNoteAlteredDate(String guid, QDateTime date) {\r
-               noteModel.updateNoteChangedDate(guid, date);\r
-               conn.getNoteTable().updateNoteAlteredDate(guid, date);\r
-       }\r
-       // Update a note title\r
-       public void updateNoteTitle(String guid, String title) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNoteTitle");\r
-               conn.getNoteTable().updateNoteTitle(guid, title);\r
-               noteModel.updateNoteTitle(guid, title);\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNoteTitle");\r
-       }\r
-       // Update a note's notebook\r
-       public void updateNoteNotebook(String guid, String notebookGuid) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNoteNotebook");\r
-               noteModel.updateNoteNotebook(guid, notebookGuid);\r
-               conn.getNoteTable().updateNoteNotebook(guid, notebookGuid, true);\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNoteNotebook");\r
-       }\r
-       // Update a note sequence number\r
-       public void updateNoteSequence(String guid, int sequence) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNoteSequence");\r
-\r
-               conn.getNoteTable().updateNoteSequence(guid, sequence);\r
-               \r
-               for (int i=0; i<noteModel.getMasterNoteIndex().size(); i++) {\r
-                       if (noteModel.getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               noteModel.getMasterNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
-                               i=noteModel.getMasterNoteIndex().size()+1;\r
-                       }\r
-               }\r
-               \r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
-                               getNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
-                               i=getNoteIndex().size()+1;\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNoteSequence");\r
-       }\r
-       public void updateNoteGuid(String oldGuid, String newGuid, boolean updateDatabase) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNoteGuid");\r
-               if (updateDatabase) \r
-                       conn.getNoteTable().updateNoteGuid(oldGuid, newGuid);\r
-               noteModel.updateNoteGuid(oldGuid, newGuid);\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNoteGuid");\r
-\r
-       }\r
-\r
-       \r
-       //************************************************************************************\r
-       //************************************************************************************\r
-       //**  Tag functions\r
-       //************************************************************************************\r
-       //************************************************************************************  \r
-       // Update a tag sequence number\r
-       public void updateTagSequence(String guid, int sequence) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateTagSequence");\r
-\r
-               conn.getTagTable().updateTagSequence(guid, sequence);   \r
-               for (int i=0; i<tagIndex.size(); i++) {\r
-                       if (tagIndex.get(i).getGuid().equals(guid)) {\r
-                               getTagIndex().get(i).setUpdateSequenceNum(sequence);\r
-                               i=tagIndex.size()+1;\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateTagSequence");\r
-       }\r
-       // Update a tag guid number\r
-       public void updateTagGuid(String oldGuid, String newGuid) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateTagGuid");\r
-\r
-               conn.getTagTable().updateTagGuid(oldGuid, newGuid);     \r
-               for (int i=0; i<tagIndex.size(); i++) {\r
-                       if (tagIndex.get(i).getGuid().equals(oldGuid)) {\r
-                               tagIndex.get(i).setGuid(newGuid);\r
-                               i=tagIndex.size()+1;\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateTagGuid");\r
-\r
-       }\r
-\r
-\r
-       //************************************************************************************\r
-       //************************************************************************************\r
-       //**  Notebook functions\r
-       //************************************************************************************\r
-       //************************************************************************************  \r
-       // Delete a notebook\r
-       public void deleteNotebook(String guid) {\r
-               for (int i=0; i<getNotebookIndex().size(); i++) {\r
-                       if (getNotebookIndex().get(i).getGuid().equals(guid)) {\r
-                               getNotebookIndex().remove(i);\r
-                               i=getMasterNoteIndex().size();\r
-                       }\r
-               }\r
-               conn.getNotebookTable().expungeNotebook(guid, true);            \r
-       }\r
-       // Update a notebook sequence number\r
-       public void updateNotebookSequence(String guid, int sequence) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNotebookSequence");\r
-\r
-               conn.getNotebookTable().updateNotebookSequence(guid, sequence);\r
-               \r
-               for (int i=0; i<notebookIndex.size(); i++) {\r
-                       if (notebookIndex.get(i).getGuid().equals(guid)) {\r
-                               notebookIndex.get(i).setUpdateSequenceNum(sequence);\r
-                               i=notebookIndex.size()+1;\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNotebookSequence");\r
-\r
-       }\r
-       // Update a notebook Guid number\r
-       public void updateNotebookGuid(String oldGuid, String newGuid) {\r
-               logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");\r
-\r
-               conn.getNotebookTable().updateNotebookGuid(oldGuid, newGuid);\r
-               \r
-               for (int i=0; i<notebookIndex.size(); i++) {\r
-                       if (notebookIndex.get(i).getGuid().equals(oldGuid)) {\r
-                               notebookIndex.get(i).setGuid(newGuid);\r
-                               i=notebookIndex.size()+1;\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");\r
-\r
-       }\r
-       \r
-       \r
-       //************************************************************************************\r
-       //************************************************************************************\r
-       //**  Load and filter the note index\r
-       //************************************************************************************\r
-       //************************************************************************************\r
-       \r
-       public void noteDownloaded(Note n) {\r
-               boolean found = false;\r
-               for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
-                       if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
-                               getMasterNoteIndex().set(i,n);\r
-                               found = true;\r
-                               i=getMasterNoteIndex().size();\r
-                       }\r
-               }\r
-               \r
-               if (!found)\r
-                       getMasterNoteIndex().add(n);\r
-               \r
-               for (int i=0; i<getNoteIndex().size(); i++) {\r
-                       if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
-                               if (filterRecord(getNoteIndex().get(i)))\r
-                                       getNoteIndex().add(n);\r
-                               getNoteIndex().remove(i);\r
-                               i=getNoteIndex().size();\r
-                       }\r
-               }\r
-               \r
-               if (filterRecord(n))\r
-                       getNoteIndex().add(n);\r
-               \r
-       }\r
-       // Check if a note matches the currently selected notebooks, tags, or attribute searches.\r
-       public boolean filterRecord(Note n) {\r
-                               \r
-               boolean goodNotebook = false;\r
-               boolean goodTag = false;\r
-               boolean goodStatus = false;\r
-                       \r
-               // Check note status\r
-               if (!n.isActive() && Global.showDeleted)\r
-                       return true;\r
-               else {\r
-                       if (n.isActive() && !Global.showDeleted)\r
-                               goodStatus = true;\r
-                       // Begin filtering results\r
-                       if (goodStatus)\r
-                               goodNotebook = filterByNotebook(n.getNotebookGuid());\r
-                       if (goodNotebook) \r
-                               goodTag = filterByTag(n.getTagGuids());\r
-                       if (goodTag) {\r
-                               boolean goodCreatedBefore = false;\r
-                               boolean goodCreatedSince = false;\r
-                               boolean goodChangedBefore = false;\r
-                               boolean goodChangedSince = false;\r
-                               boolean goodContains = false;\r
-                                       \r
-                               if (!Global.createdBeforeFilter.hasSelection())\r
-                                       goodCreatedBefore = true;\r
-                               else\r
-                                       goodCreatedBefore = Global.createdBeforeFilter.check(n);\r
-                               \r
-                               if (!Global.createdSinceFilter.hasSelection())\r
-                                       goodCreatedSince = true;\r
-                               else\r
-                                       goodCreatedSince = Global.createdSinceFilter.check(n);\r
-                               \r
-                               if (!Global.changedBeforeFilter.hasSelection())\r
-                                       goodChangedBefore = true;\r
-                               else\r
-                                       goodChangedBefore = Global.changedBeforeFilter.check(n);\r
-                                       if (!Global.changedSinceFilter.hasSelection())\r
-                                       goodChangedSince = true;\r
-                               else\r
-                                       goodChangedSince = Global.changedSinceFilter.check(n);\r
-                               if (!Global.containsFilter.hasSelection())\r
-                                       goodContains = true;\r
-                               else\r
-                                       goodContains = Global.containsFilter.check(conn.getNoteTable(), n);\r
-                                       \r
-                               if (goodCreatedSince && goodCreatedBefore && goodChangedSince && goodChangedBefore && goodContains)\r
-                                       return true;\r
-                       }\r
-               }       \r
-               return false;\r
-       }\r
-       \r
-       // Load the note index based upon what the user wants.\r
-       public void loadNotesIndex() {\r
-               logger.log(logger.EXTREME, "Entering ListManager.loadNotesIndex()");\r
-               tagCounterRunner.abortCount = true;\r
-               notebookCounterRunner.abortCount = true;\r
-               trashCounterRunner.abortCount = true;\r
-               \r
-               List<Note> matches;\r
-               if (enSearchChanged || getMasterNoteIndex() == null)\r
-                       matches = enSearch.matchWords();\r
-               else\r
-                       matches = getMasterNoteIndex();\r
-               \r
-               if (matches == null)\r
-                       matches = getMasterNoteIndex();\r
-               \r
-               setNoteIndex(new ArrayList<Note>());\r
-               for (int i=0; i<matches.size(); i++) {\r
-                       if (filterRecord(matches.get(i)))\r
-                               getNoteIndex().add(matches.get(i));\r
-               }\r
-               countNotebookResults(getNoteIndex());\r
-               countTagResults(getNoteIndex());\r
-               enSearchChanged = false;\r
-               reloadTrashCount();\r
-               logger.log(logger.EXTREME, "Leaving ListManager.loadNotesIndex()");\r
-       }\r
-       public void countNotebookResults(List<Note> index) {\r
-               logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults()");\r
-               if (!Global.mimicEvernoteInterface) {\r
-                       notebookCounterRunner.setNoteIndex(index);\r
-                       notebookCounterRunner.release(CounterRunner.NOTEBOOK);\r
-               } else {\r
-                       notebookCounterRunner.setNoteIndex(getMasterNoteIndex());\r
-                       notebookCounterRunner.release(CounterRunner.NOTEBOOK_ALL);\r
-               }\r
-               logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");\r
-       }\r
-       public void countTagResults(List<Note> index) {\r
-               logger.log(logger.EXTREME, "Entering ListManager.countTagResults");\r
-               if (!Global.tagBehavior().equalsIgnoreCase("DoNothing")) {\r
-                       tagCounterRunner.setNoteIndex(index);\r
-                       tagCounterRunner.release(CounterRunner.TAG);\r
-               } else {\r
-                       tagCounterRunner.setNoteIndex(null);\r
-                       tagCounterRunner.release(CounterRunner.TAG_ALL);\r
-               }\r
-               logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");\r
-       }\r
-       // Update the count of items in the trash\r
-       public void reloadTrashCount() {\r
-               logger.log(logger.EXTREME, "Entering ListManager.reloadTrashCount");\r
-               trashCounterRunner.setNoteIndex(getNoteIndex());\r
-               trashCounterRunner.release(CounterRunner.TRASH);\r
-               logger.log(logger.EXTREME, "Leaving ListManager.reloadTrashCount");\r
-       }       \r
-       \r
-       private boolean filterByNotebook(String guid) {\r
-               boolean good = false;\r
-               if (selectedNotebooks.size() == 0)\r
-                       good = true;\r
-               if (!good && selectedNotebooks.contains(guid)) \r
-                       good = true;\r
-\r
-               for (int i=0; i<getArchiveNotebookIndex().size() && good; i++) {\r
-                       if (guid.equals(getArchiveNotebookIndex().get(i).getGuid())) {\r
-                               good = false;\r
-                               return good;\r
-                       }\r
-               }\r
-               return good;\r
-       }\r
-       private boolean filterByTag(List<String> noteTags) {\r
-               if (noteTags == null || selectedTags == null)\r
-                       return true;\r
-               \r
-               if (selectedTags.size() == 0) \r
-                       return true;\r
-               \r
-               for (int i=0; i<selectedTags.size(); i++) {\r
-                       String selectedGuid = selectedTags.get(i);\r
-                       if (noteTags.contains(selectedGuid))\r
-                                       return true;\r
-               }\r
-               return false;\r
-       }\r
-\r
-       \r
-       \r
-       public void updateNoteTitleColor(String guid, Integer color) {\r
-               noteModel.updateNoteTitleColor(guid, color);\r
-               conn.getNoteTable().setNoteTitleColor(guid, color);\r
-       }\r
-       public void loadNoteTitleColors() {\r
-               List<Pair<String,Integer>> colors = conn.getNoteTable().getNoteTitleColors();\r
-               if (noteModel.getTitleColors() == null)\r
-                       noteModel.setTitleColors(new HashMap<String,Integer>());\r
-               else\r
-                       noteModel.getTitleColors().clear();\r
-               for (int i=0; i<colors.size(); i++) {\r
-                       noteModel.getTitleColors().put(colors.get(i).getFirst(), colors.get(i).getSecond());\r
-               }\r
-       }\r
-       \r
-       //********************************************************************************\r
-       //********************************************************************************\r
-       //* Support signals from the index thread\r
-       //********************************************************************************\r
-       //********************************************************************************\r
-       // Reset a flag if an index is needed\r
-       public void setIndexNeeded(String guid, String type, Boolean b) {\r
-               if (Global.keepRunning && type.equalsIgnoreCase("content"))\r
-                       conn.getNoteTable().setIndexNeeded(guid, false);\r
-               if (Global.keepRunning && type.equalsIgnoreCase("resource")) {\r
-                       conn.getNoteTable().noteResourceTable.setIndexNeeded(guid, b);\r
-               }\r
-       }\r
-       \r
-       public boolean threadCheck(int id) {\r
-               if (id == Global.notebookCounterThreadId) \r
-                       return notebookThread.isAlive();\r
-               if (id == Global.tagCounterThreadId) \r
-                       return tagThread.isAlive();\r
-               if (id == Global.trashCounterThreadId) \r
-                       return trashThread.isAlive();\r
-               if (id == Global.saveThreadId) \r
-                       return saveThread.isAlive();\r
-               return false;\r
-       }\r
-       \r
-       \r
-       \r
-       //********************************************************************************\r
-       //********************************************************************************\r
-       //* Utility Functions\r
-       //********************************************************************************\r
-       //********************************************************************************\r
-       public void compactDatabase() {\r
-               conn.compactDatabase();\r
-//             IndexConnection idx = new IndexConnection(logger, "nevernote-compact");\r
-//             idx.dbSetup();\r
-//             idx.dbShutdown();\r
-       }\r
-\r
-       // Rebuild the note HTML to something usable\r
-       public List<String> scanNoteForResources(Note n) {\r
-               logger.log(logger.HIGH, "Entering ListManager.scanNoteForResources");\r
-               logger.log(logger.EXTREME, "Note guid: " +n.getGuid());\r
-               QDomDocument doc = new QDomDocument();\r
-               QDomDocument.Result result = doc.setContent(n.getContent());\r
-               if (!result.success) {\r
-                       logger.log(logger.MEDIUM, "Parse error when scanning note for resources.");\r
-                       logger.log(logger.MEDIUM, "Note guid: " +n.getGuid());\r
-                       return null;\r
-               }\r
-                               \r
-               List<String> returnArray = new ArrayList<String>();\r
-               QDomNodeList anchors = doc.elementsByTagName("en-media");\r
-               for (int i=0; i<anchors.length(); i++) {\r
-                       QDomElement enmedia = anchors.at(i).toElement();\r
-                       if (enmedia.hasAttribute("type")) {\r
-                               QDomAttr hash = enmedia.attributeNode("hash");\r
-                               returnArray.add(hash.value().toString());\r
-                       }\r
-               }\r
-               logger.log(logger.HIGH, "Leaving ListManager.scanNoteForResources");\r
-               return returnArray;\r
-       }\r
-       // Given a list of tags, produce a string list of tag names\r
-       public String getTagNamesForNote(Note n) {\r
-               StringBuffer buffer = new StringBuffer(100);\r
-               Vector<String> v = new Vector<String>();\r
-               List<String> guids = n.getTagGuids();\r
-               \r
-               if (guids == null) \r
-                       return "";\r
-               \r
-               for (int i=0; i<guids.size(); i++) {\r
-                       v.add(getTagNameByGuid(guids.get(i)));\r
-               }\r
-               Comparator<String> comparator = Collections.reverseOrder();\r
-               Collections.sort(v,comparator);\r
-               Collections.reverse(v);\r
-               \r
-               for (int i = 0; i<v.size(); i++) {\r
-                       if (i>0) \r
-                               buffer.append(", ");\r
-                       buffer.append(v.get(i));\r
-               }\r
-               \r
-               return buffer.toString();\r
-       }\r
-       // Get a tag name when given a tag guid\r
-       public String getTagNameByGuid(String guid) {\r
-               for (int i=0; i<getTagIndex().size(); i++) {\r
-                       String s = getTagIndex().get(i).getGuid();\r
-                       if (s.equals(guid)) { \r
-                               return getTagIndex().get(i).getName();\r
-                       }\r
-               }\r
-               return "";\r
-       }\r
-       // For a notebook guid, return the name\r
-       public String getNotebookNameByGuid(String guid) {\r
-               if (notebookIndex == null)\r
-                       return null;\r
-               for (int i=0; i<notebookIndex.size(); i++) {\r
-                       String s = notebookIndex.get(i).getGuid();\r
-                       if (s.equals(guid)) { \r
-                               return notebookIndex.get(i).getName();\r
-                       }\r
-               }\r
-               return "";\r
-       }\r
-       \r
-       \r
-}\r
+/*
+ * This file is part of NixNote/NeighborNote 
+ * Copyright 2009 Randy Baumgarte
+ * Copyright 2013 Yuki Takahashi
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.utilities;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+
+import com.evernote.edam.type.LinkedNotebook;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.SavedSearch;
+import com.evernote.edam.type.Tag;
+import com.trolltech.qt.QThread;
+import com.trolltech.qt.core.QDateTime;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QPixmap;
+import com.trolltech.qt.sql.QSqlQuery;
+import com.trolltech.qt.xml.QDomAttr;
+import com.trolltech.qt.xml.QDomDocument;
+import com.trolltech.qt.xml.QDomElement;
+import com.trolltech.qt.xml.QDomNodeList;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.evernote.NoteMetadata;
+import cx.fbn.nevernote.filters.EnSearch;
+import cx.fbn.nevernote.filters.NotebookCounter;
+import cx.fbn.nevernote.filters.TagCounter;
+import cx.fbn.nevernote.gui.NoteTableModel;
+import cx.fbn.nevernote.signals.NotebookSignal;
+import cx.fbn.nevernote.signals.StatusSignal;
+import cx.fbn.nevernote.signals.TagSignal;
+import cx.fbn.nevernote.signals.ThreadSignal;
+import cx.fbn.nevernote.signals.TrashSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.threads.CounterRunner;
+import cx.fbn.nevernote.threads.SaveRunner;
+
+
+public class ListManager  {
+
+       
+       private final ApplicationLogger logger;  
+       DatabaseConnection                              conn;
+       QSqlQuery                                               deleteWords;
+       QSqlQuery                                               insertWords;
+       
+       private List<Tag>                               tagIndex;
+       private List<Notebook>                  notebookIndex;
+       private List<Notebook>                  archiveNotebookIndex;
+       private List<String>                    localNotebookIndex;
+       private List<LinkedNotebook>    linkedNotebookIndex;
+
+       private List<SavedSearch>               searchIndex;
+
+       private List<String>                    selectedNotebooks;
+       private final NoteTableModel                    noteModel;
+       
+       
+       private List<String>                    selectedTags;
+       private String                                  selectedSearch;
+       ThreadSignal                                    signals;
+       public StatusSignal                             status;
+       private final CounterRunner             notebookCounterRunner;
+       private final QThread                   notebookThread;
+       private final CounterRunner             tagCounterRunner;
+       private final QThread                   tagThread;
+       
+       private final CounterRunner             trashCounterRunner;
+       private final QThread                   trashThread;
+       public TrashSignal                              trashSignal;
+       
+       private List<NotebookCounter>   notebookCounter;                                // count of displayed notes in each notebook
+       private List<TagCounter>                tagCounter;                                             // count of displayed notes for each tag
+       
+       private EnSearch                                enSearch;
+       private boolean                                 enSearchChanged;
+       public HashMap<String, String>  wordMap;
+       public TagSignal                                tagSignal;
+       public NotebookSignal                   notebookSignal;
+       public boolean                                  refreshCounters;                        // Used to control when to recount lists
+       private int                                             trashCount;
+    public SaveRunner                          saveRunner;                                     // Thread used to save content.  Used because the xml conversion is slowwwww
+    QThread                                                    saveThread;
+       
+//    private final HashMap<String, QImage> thumbnailList;
+    
+       // Constructor
+       public ListManager(DatabaseConnection d, ApplicationLogger l) {
+               conn = d;
+               logger = l;
+                       
+               conn.getTagTable().cleanupTags();
+       status = new StatusSignal();
+               signals = new ThreadSignal();
+               
+               // setup index locks
+               enSearchChanged = false;
+               
+               // Setup arrays
+               noteModel = new NoteTableModel(this);
+               selectedTags = new ArrayList<String>();
+
+               notebookCounter = new ArrayList<NotebookCounter>();
+               tagCounter = new ArrayList<TagCounter>();
+               selectedNotebooks = new ArrayList<String>();
+                               
+               reloadIndexes();
+               
+               notebookSignal = new NotebookSignal();
+               // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+               notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK, 
+                                               Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+                                               Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+               notebookCounterRunner.setNoteIndex(getNoteIndex());
+               notebookCounterRunner.notebookSignal.countsChanged.connect(this, "setNotebookCounter(List)");
+               notebookThread = new QThread(notebookCounterRunner, "Notebook Counter Thread");
+               notebookThread.start();
+               
+               tagSignal = new TagSignal();
+               // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+               tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG, 
+                               Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+                               Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+               tagCounterRunner.setNoteIndex(getNoteIndex());
+               tagCounterRunner.tagSignal.countsChanged.connect(this, "setTagCounter(List)");
+               tagThread = new QThread(tagCounterRunner, "Tag Counter Thread");
+               tagThread.start();
+               
+               trashSignal = new TrashSignal();
+               // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+               trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH, 
+                               Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+                               Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+               trashCounterRunner.trashSignal.countChanged.connect(this, "trashSignalReceiver(Integer)");
+               trashThread = new QThread(trashCounterRunner, "Trash Counter Thread");
+               trashThread.start();
+//             reloadTrashCount();
+               
+               wordMap = new HashMap<String, String>();
+               tagSignal = new TagSignal();
+               
+               logger.log(logger.EXTREME, "Setting save thread");
+               // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+               saveRunner = new SaveRunner("saveRunner.log", 
+                               Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+                               Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+               saveThread = new QThread(saveRunner, "Save Runner Thread");
+               saveThread.start();
+               
+//             thumbnailList = conn.getNoteTable().getThumbnails();
+//             thumbnailList = new HashMap<String,QImage>();
+               
+               linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();
+               loadNoteTitleColors();
+               refreshCounters = true;
+               refreshCounters();
+                               
+       }
+       
+       public void stop() {
+               saveRunner.addWork("stop", "");
+               tagCounterRunner.release(CounterRunner.EXIT);
+               notebookCounterRunner.release(CounterRunner.EXIT);
+               trashCounterRunner.release(CounterRunner.EXIT);
+               
+               logger.log(logger.MEDIUM, "Waiting for notebookCounterThread to stop");                         
+               try {
+                       notebookThread.join();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+               
+               logger.log(logger.MEDIUM, "Waiting for tagCounterThread to stop");                      
+               try {
+                       tagThread.join();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+
+               logger.log(logger.MEDIUM, "Waiting for trashThread to stop");                   
+               try {
+                       trashThread.join();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+
+
+               logger.log(logger.MEDIUM, "Waiting for saveThread to stop");                    
+               try {
+                       saveThread.join(0);
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       //***************************************************************
+       //***************************************************************
+       //* Refresh lists after a db sync
+       //***************************************************************
+       //***************************************************************
+       // ICHANGED
+       public void saveUpdatedNotes(HashMap<Integer, Note> notes, HashMap<Integer, String> contents) {
+               for (int i = 0; i < notes.size(); i++) {
+                       Note n = notes.get(i);
+                       String content = contents.get(i);
+                       saveRunner.addWork(n.getGuid(), content);
+                       conn.getNoteTable().updateNoteTitle(n.getGuid(), n.getTitle());
+               }
+       }
+       
+       // ICHANGED
+       public void refreshLists() {
+               setSavedSearchIndex(conn.getSavedSearchTable().getAll());
+               setTagIndex(conn.getTagTable().getAll());
+               setNotebookIndex(conn.getNotebookTable().getAll());
+               
+               List<Notebook> local = conn.getNotebookTable().getAllLocal();
+               localNotebookIndex = new ArrayList<String>();
+               for (int i=0; i<local.size(); i++)
+                       localNotebookIndex.add(local.get(i).getGuid());
+               
+               noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());
+               // For performance reasons, we didn't get the tags for every note individually.  We now need to 
+               // get them
+               List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       List<String> tags = new ArrayList<String>();
+                       List<String> names = new ArrayList<String>();
+                       for (int j=0; j<noteTags.size(); j++) {
+                               if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {
+                                       tags.add(noteTags.get(j).tagGuid);
+                                       names.add(getTagNameByGuid(noteTags.get(j).tagGuid));
+                               }
+                       }
+                       
+                       getMasterNoteIndex().get(i).setTagGuids(tags);
+                       getMasterNoteIndex().get(i).setTagNames(names);
+               }
+               
+               
+               //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());
+               
+               linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();
+               
+               enSearchChanged = true;
+       }
+
+       public void reloadTagIndex() {
+               setTagIndex(conn.getTagTable().getAll());       
+       }
+       public void reloadIndexes() {
+               //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());
+
+               List<Notebook> local = conn.getNotebookTable().getAllLocal();
+               localNotebookIndex = new ArrayList<String>();
+               for (int i=0; i<local.size(); i++)
+                       localNotebookIndex.add(local.get(i).getGuid());
+               
+               reloadTagIndex();
+               // Load notebooks
+               setNotebookIndex(conn.getNotebookTable().getAll());
+               // load archived notebooks (if note using the EN interface)
+               setArchiveNotebookIndex(conn.getNotebookTable().getAllArchived());
+               // load saved search index
+               setSavedSearchIndex(conn.getSavedSearchTable().getAll());
+               // Load search helper utility
+               enSearch = new EnSearch(conn,  logger, "", getTagIndex(), Global.getRecognitionWeight());
+               logger.log(logger.HIGH, "Building note index");
+
+//             if (getMasterNoteIndex() == null) { 
+                       noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());
+//             }
+               // For performance reasons, we didn't get the tags for every note individually.  We now need to 
+               // get them
+               List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       List<String> tags = new ArrayList<String>();
+                       List<String> names = new ArrayList<String>();
+                       for (int j=0; j<noteTags.size(); j++) {
+                               if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {
+                                       tags.add(noteTags.get(j).tagGuid);
+                                       names.add(getTagNameByGuid(noteTags.get(j).tagGuid));
+                               }
+                       }
+                       
+                       getMasterNoteIndex().get(i).setTagGuids(tags);
+                       getMasterNoteIndex().get(i).setTagNames(names);
+               }
+               
+               setNoteIndex(getMasterNoteIndex());
+
+       }
+       
+       //***************************************************************
+       //***************************************************************
+       //* selected notebooks
+       //***************************************************************
+       //***************************************************************
+       // Return the selected notebook(s)
+       public List<String> getSelectedNotebooks() {
+               return selectedNotebooks;
+       }
+       // Set the current selected notebook(s)
+       public void setSelectedNotebooks(List <String> s) {
+               if (s == null) 
+                       s = new ArrayList<String>();
+               selectedNotebooks = s;
+       }
+       
+                               
+    //***************************************************************
+    //***************************************************************
+    //** These functions deal with setting & retrieving the master lists
+    //***************************************************************
+    //***************************************************************
+       // Get the note table model
+       public NoteTableModel getNoteTableModel() {
+               return noteModel;
+       }
+       // save the saved search index
+       private void setSavedSearchIndex(List<SavedSearch> t) {
+               searchIndex = t;
+       }
+       // Retrieve the Tag index
+       public List<SavedSearch> getSavedSearchIndex() {
+               return searchIndex;
+
+       }
+       // save the tag index
+       private void setTagIndex(List<Tag> t) {
+               tagIndex = t;
+       }       
+       // Retrieve the Tag index
+       public List<Tag> getTagIndex() {
+               return tagIndex;
+       }
+       private void setNotebookIndex(List<Notebook> t) {
+               notebookIndex = t;
+       }
+       private void setArchiveNotebookIndex(List<Notebook> t) {
+               archiveNotebookIndex = t;
+       }
+       // Retrieve the Notebook index
+       public List<Notebook> getNotebookIndex() {
+               return notebookIndex;
+
+       }
+       public List<LinkedNotebook> getLinkedNotebookIndex() {
+               return linkedNotebookIndex;
+       }
+       public List<Notebook> getArchiveNotebookIndex() {
+               return archiveNotebookIndex;
+       }
+       // Save the current note list
+       private void setNoteIndex(List<Note> n) {
+               noteModel.setNoteIndex(n);
+               refreshNoteMetadata();
+       }
+       public void refreshNoteMetadata() {
+               noteModel.setNoteMetadata(conn.getNoteTable().getNotesMetaInformation());
+       }
+       // Update a note's meta data
+       public void updateNoteMetadata(NoteMetadata meta) {
+               noteModel.metaData.remove(meta);
+               noteModel.metaData.put(meta.getGuid(), meta);
+               conn.getNoteTable().updateNoteMetadata(meta);
+       }
+       // Get the note index
+       public synchronized List<Note> getNoteIndex() {
+               return noteModel.getNoteIndex();
+       }
+       // Save the count of notes per notebook
+       public void setNotebookCounter(List<NotebookCounter> n) {
+               notebookCounter = n;
+               notebookSignal.refreshNotebookTreeCounts.emit(getNotebookIndex(), notebookCounter);
+       }
+       public List<NotebookCounter> getNotebookCounter() {
+               return notebookCounter;
+       }
+       // Save the count of notes for each tag
+       public void setTagCounter(List<TagCounter> n) {
+               tagCounter = n;
+               tagSignal.refreshTagTreeCounts.emit(tagCounter);
+       }
+       public List<TagCounter> getTagCounter() {
+               return tagCounter;
+       }
+       public List<String> getLocalNotebooks() {
+               return localNotebookIndex;
+       }
+
+//     public void setUnsynchronizedNotes(List<String> l) {
+//             noteModel.setUnsynchronizedNotes(l);
+//     }
+       // Return a count of items in the trash
+       public int getTrashCount() {
+               return trashCount;
+       }
+       // get the EnSearch variable
+       public EnSearch getEnSearch() {
+               return enSearch;
+       }
+       public List<Note> getMasterNoteIndex() {
+               return noteModel.getMasterNoteIndex();
+       }
+       // Thumbnails
+//     public HashMap<String, QImage> getThumbnails() {
+//             return thumbnailList;
+//     }
+       public HashMap<String, NoteMetadata> getNoteMetadata() {
+               return noteModel.metaData;
+       }
+       public QImage getThumbnail(String guid) {
+//             if (getThumbnails().containsKey(guid))
+//                     return getThumbnails().get(guid);
+               
+               QImage img = new QImage();
+               img = QImage.fromData(conn.getNoteTable().getThumbnail(guid));
+               if (img == null || img.isNull()) 
+                       return null;
+               //getThumbnails().put(guid, img);
+               return img;
+       }
+       public QPixmap getThumbnailPixmap(String guid) {
+//             if (getThumbnails().containsKey(guid))
+//                     return getThumbnails().get(guid);
+               
+               QPixmap img = new QPixmap();
+               img.loadFromData(conn.getNoteTable().getThumbnail(guid));
+               if (img == null || img.isNull()) 
+                       return null;
+               //getThumbnails().put(guid, img);
+               return img;
+       }
+    //***************************************************************
+    //***************************************************************
+    //** These functions deal with setting & retrieving filters
+    //***************************************************************
+    //***************************************************************
+       public void setEnSearch(String t) {
+               enSearch = new EnSearch(conn,logger, t, getTagIndex(), Global.getRecognitionWeight());
+               enSearchChanged = true;
+       }
+       // Save search tags
+       public void setSelectedTags(List<String> selectedTags) {
+               this.selectedTags = selectedTags;
+       }
+       // Save seleceted search
+       public void setSelectedSavedSearch(String s) {
+               this.selectedSearch = s;
+       }
+       // Get search tags
+       public List<String> getSelectedTags() {
+               return selectedTags;
+       }
+       // Get saved search
+       public String getSelectedSearch() {
+               return selectedSearch;
+       }
+       
+       
+       
+       
+    //***************************************************************
+    //***************************************************************
+    //** Note functions
+    //***************************************************************
+    //***************************************************************
+       // Save Note Tags
+       public void saveNoteTags(String noteGuid, List<String> tags, boolean isDirty) {\r
+               logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");
+               // ICHANGED 同じタグが付けられた履歴を記録(必ずdeleteNoteTagの前にやる)
+               for (int i = 0; i < tags.size(); i++) {
+                       String tagName = tags.get(i);
+                       for (int j = 0; j < tagIndex.size(); j++) {
+                               if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {
+                                       conn.getHistoryTable().addSameTagHistory(noteGuid, tagIndex.get(j).getGuid());
+                               }
+                       }
+               }
+               
+               String tagName;
+               conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
+               List<String> tagGuids = new ArrayList<String>();
+               boolean newTagCreated = false;
+               
+               for (int i=0; i<tags.size(); i++) {
+                       tagName = tags.get(i);
+                       boolean found = false;
+                       for (int j=0; j<tagIndex.size(); j++) {
+                               if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {
+                                       conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, tagIndex.get(j).getGuid(), isDirty);\r
+                                       tagGuids.add(tagIndex.get(j).getGuid());
+                                       j=tagIndex.size()+1;
+                                       found = true;
+                               }
+                       }
+                       if (!found) {
+                               Tag nTag = new Tag();
+                               nTag.setName(tagName);
+                               Calendar currentTime = new GregorianCalendar();
+                               Long l = new Long(currentTime.getTimeInMillis());
+                               long prevTime = l;
+                               while (l==prevTime) {
+                                       currentTime = new GregorianCalendar();
+                                       l=currentTime.getTimeInMillis();
+                               }
+                               String randint = new String(Long.toString(l));
+                       
+                               nTag.setUpdateSequenceNum(0);
+                               nTag.setGuid(randint);
+                               conn.getTagTable().addTag(nTag, true);
+                               getTagIndex().add(nTag);
+                               conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, nTag.getGuid(), isDirty);\r
+                               tagGuids.add(nTag.getGuid());
+                               newTagCreated = true;
+                       }
+               }
+               
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(noteGuid)) {
+                               getNoteIndex().get(i).setTagNames(tags);
+                               getNoteIndex().get(i).setTagGuids(tagGuids);
+                               i=getNoteIndex().size()+1;
+                       }
+               }
+               if (newTagCreated)
+                       tagSignal.listChanged.emit();
+               logger.log(logger.HIGH, "Leaving ListManager.saveNoteTags");
+       }
+       // Delete a note
+       public void deleteNote(String guid) {
+               trashCounterRunner.abortCount = true;
+               Calendar currentTime = new GregorianCalendar();
+               Long l = new Long(currentTime.getTimeInMillis());
+               long prevTime = l;
+               while (l==prevTime) {
+                       currentTime = new GregorianCalendar();
+                       l=currentTime.getTimeInMillis();
+               }
+               
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+                               getMasterNoteIndex().get(i).setActive(false);
+                               getMasterNoteIndex().get(i).setDeleted(l);
+                               i=getMasterNoteIndex().size();
+                       }
+               }
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().get(i).setActive(false);
+                               getNoteIndex().get(i).setDeleted(l);
+                               i=getNoteIndex().size();
+                       }
+               }
+               conn.getNoteTable().deleteNote(guid);
+               reloadTrashCount();
+       }
+       // Delete a note
+       public void restoreNote(String guid) {
+               trashCounterRunner.abortCount = true;
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+                               getMasterNoteIndex().get(i).setActive(true);
+                               getMasterNoteIndex().get(i).setDeleted(0);
+                               i=getMasterNoteIndex().size();
+                       }
+               }
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().get(i).setActive(true);
+                               getNoteIndex().get(i).setDeleted(0);
+                               i=getNoteIndex().size();
+                       }
+               }
+               conn.getNoteTable().restoreNote(guid);
+               reloadTrashCount();
+       }
+       public void updateNote(Note n) {
+               
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+                               getMasterNoteIndex().remove(i);
+                               getMasterNoteIndex().add(n);
+                       }
+               }
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+                               getNoteIndex().get(i).setActive(true);
+                               getNoteIndex().get(i).setDeleted(0);
+                               i=getNoteIndex().size();
+                       }
+               }
+               conn.getNoteTable().updateNote(n);
+       }
+       // Add a note.  
+       public void addNote(Note n, NoteMetadata meta) {
+               noteModel.addNote(n, meta);
+               noteModel.metaData.put(n.getGuid(), meta);
+       }
+       // Expunge a note
+       public void expungeNote(String guid) {
+               trashCounterRunner.abortCount = true;
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+                               getMasterNoteIndex().remove(i);
+                               i=getMasterNoteIndex().size();
+                       }
+               }
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().remove(i);
+                               i=getNoteIndex().size();
+                       }
+               }
+               conn.getNoteTable().expungeNote(guid, false, true);
+               reloadTrashCount();
+       }
+       // Expunge a note
+       public void emptyTrash() {
+               trashCounterRunner.abortCount = true;           
+               for (int i=getMasterNoteIndex().size()-1; i>=0; i--) {
+                       if (!getMasterNoteIndex().get(i).isActive()) {
+                               getMasterNoteIndex().remove(i);
+                       }
+               }
+               
+               for (int i=getNoteIndex().size()-1; i>=0; i--) {
+                       if (!getNoteIndex().get(i).isActive()) {
+                               getNoteIndex().remove(i);
+                       } 
+               }
+
+               conn.getNoteTable().expungeAllDeletedNotes();
+               reloadTrashCount();
+       }
+       // The trash counter thread has produced a result
+       @SuppressWarnings("unused")
+       private void trashSignalReceiver(Integer i) {
+               trashCount = i;
+               trashSignal.countChanged.emit(i);
+       }
+       // Update note contents
+       public void updateNoteContent(String guid, String content) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");
+//             EnmlConverter enml = new EnmlConverter(logger);
+//             String text = enml.convert(guid, content);
+               
+               // Update the list tables 
+/*             for (int i=0; i<masterNoteIndex.size(); i++) {
+                       if (masterNoteIndex.get(i).getGuid().equals(guid)) {
+                               masterNoteIndex.get(i).setContent(text);
+                               i = masterNoteIndex.size();
+                       }
+               }
+               // Update the list tables 
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().get(i).setContent(text);
+                               i = getNoteIndex().size();
+                       }
+               }
+*/             
+               // Check if any new tags were encountered
+/*             if (enml.saveInvalidXML) {
+                       List<String> elements = Global.invalidElements;
+                       for (int i=0; i<elements.size(); i++) {
+                               conn.getInvalidXMLTable().addInvalidElement(elements.get(i));
+                       }
+                       for (String key : Global.invalidAttributes.keySet()) {
+                               ArrayList<String> attributes = Global.invalidAttributes.get(key);
+                               for (int i=0; i<attributes.size(); i++) {
+                                       conn.getInvalidXMLTable().addInvalidAttribute(key, attributes.get(i));
+                               }
+                       }
+               }
+*/
+               saveRunner.addWork(guid, content);
+//             conn.getNoteTable().updateNoteContent(guid, content);
+               logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");
+       }
+       // Update a note creation date
+       public void updateNoteCreatedDate(String guid, QDateTime date) {
+               noteModel.updateNoteCreatedDate(guid, date);
+               conn.getNoteTable().updateNoteCreatedDate(guid, date);
+       }
+       // Subject date has been changed
+       public void updateNoteSubjectDate(String guid, QDateTime date) {
+               noteModel.updateNoteSubjectDate(guid, date);
+               conn.getNoteTable().updateNoteSubjectDate(guid, date);
+       }
+       // Author has changed
+       public void updateNoteAuthor(String guid, String author) {
+               noteModel.updateNoteAuthor(guid, author);
+               conn.getNoteTable().updateNoteAuthor(guid, author);
+       }
+       // Author has changed
+       public void updateNoteGeoTag(String guid, Double lon, Double lat, Double alt) {
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+                               getMasterNoteIndex().get(i).getAttributes().setLongitude(lon);
+                               getMasterNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);
+                               getMasterNoteIndex().get(i).getAttributes().setLatitude(lat);
+                               getMasterNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);
+                               getMasterNoteIndex().get(i).getAttributes().setAltitude(alt);
+                               getMasterNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);
+                               i = getMasterNoteIndex().size();
+                       }       
+               }
+               // Update the list tables 
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().get(i).getAttributes().setLongitude(lon);
+                               getNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);
+                               getNoteIndex().get(i).getAttributes().setLatitude(lat);
+                               getNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);
+                               getNoteIndex().get(i).getAttributes().setAltitude(alt);
+                               getNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);
+                               i = getNoteIndex().size();
+                       }
+               }
+               conn.getNoteTable().updateNoteGeoTags(guid, lon, lat, alt);
+       }
+       // Source URL changed
+       public void updateNoteSourceUrl(String guid, String url) {
+               noteModel.updateNoteSourceUrl(guid, url);
+               conn.getNoteTable().updateNoteSourceUrl(guid, url);
+       }
+       // Update a note last changed date
+       public void updateNoteAlteredDate(String guid, QDateTime date) {
+               noteModel.updateNoteChangedDate(guid, date);
+               conn.getNoteTable().updateNoteAlteredDate(guid, date);
+       }
+       // Update a note title
+       public void updateNoteTitle(String guid, String title) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNoteTitle");
+               conn.getNoteTable().updateNoteTitle(guid, title);
+               noteModel.updateNoteTitle(guid, title);
+               logger.log(logger.HIGH, "Leaving ListManager.updateNoteTitle");
+       }
+       // Update a note's notebook
+       public void updateNoteNotebook(String guid, String notebookGuid) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNoteNotebook");
+               noteModel.updateNoteNotebook(guid, notebookGuid);
+               conn.getNoteTable().updateNoteNotebook(guid, notebookGuid, true);
+               logger.log(logger.HIGH, "Leaving ListManager.updateNoteNotebook");
+       }
+       // Update a note sequence number
+       public void updateNoteSequence(String guid, int sequence) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNoteSequence");
+
+               conn.getNoteTable().updateNoteSequence(guid, sequence);
+               
+               for (int i=0; i<noteModel.getMasterNoteIndex().size(); i++) {
+                       if (noteModel.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+                               noteModel.getMasterNoteIndex().get(i).setUpdateSequenceNum(sequence);
+                               i=noteModel.getMasterNoteIndex().size()+1;
+                       }
+               }
+               
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(guid)) {
+                               getNoteIndex().get(i).setUpdateSequenceNum(sequence);
+                               i=getNoteIndex().size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateNoteSequence");
+       }
+       public void updateNoteGuid(String oldGuid, String newGuid, boolean updateDatabase) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNoteGuid");
+               if (updateDatabase) 
+                       conn.getNoteTable().updateNoteGuid(oldGuid, newGuid);
+               noteModel.updateNoteGuid(oldGuid, newGuid);
+               logger.log(logger.HIGH, "Leaving ListManager.updateNoteGuid");
+
+       }
+
+       
+       //************************************************************************************
+       //************************************************************************************
+       //**  Tag functions
+       //************************************************************************************
+       //************************************************************************************  
+       // Update a tag sequence number
+       public void updateTagSequence(String guid, int sequence) {
+               logger.log(logger.HIGH, "Entering ListManager.updateTagSequence");
+
+               conn.getTagTable().updateTagSequence(guid, sequence);   
+               for (int i=0; i<tagIndex.size(); i++) {
+                       if (tagIndex.get(i).getGuid().equals(guid)) {
+                               getTagIndex().get(i).setUpdateSequenceNum(sequence);
+                               i=tagIndex.size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateTagSequence");
+       }
+       // Update a tag guid number
+       public void updateTagGuid(String oldGuid, String newGuid) {
+               logger.log(logger.HIGH, "Entering ListManager.updateTagGuid");
+
+               conn.getTagTable().updateTagGuid(oldGuid, newGuid);     
+               for (int i=0; i<tagIndex.size(); i++) {
+                       if (tagIndex.get(i).getGuid().equals(oldGuid)) {
+                               tagIndex.get(i).setGuid(newGuid);
+                               i=tagIndex.size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateTagGuid");
+
+       }
+       // Find all children for a tag
+       public List<Tag> findAllChildren(String guid) {
+               List<Tag> tags = new ArrayList<Tag>();
+               return findAllChildrenRecursive(guid, tags);
+       }
+       public List<Tag> findAllChildrenRecursive(String guid, List<Tag> tags) {
+               
+               // Start looping through the tags.  If we find a tag which has a parent that
+               // matches guid, then we add it to the list of tags & search for its children.
+               for (int i=0; i<getTagIndex().size(); i++) {
+                       if (getTagIndex().get(i).getParentGuid() != null && getTagIndex().get(i).getParentGuid().equals(guid)) {
+                               tags.add(getTagIndex().get(i));
+                               tags = findAllChildrenRecursive(getTagIndex().get(i).getGuid(), tags);
+                       }
+               }
+               return tags;
+       }
+       // Give a list of tags, does any of them match a child tag?
+       public boolean checkNoteForChildTags(String guid, List<String> noteTags) {
+               boolean returnValue = false;
+               List<Tag> children = findAllChildren(guid);
+               for (int i=0; i<noteTags.size(); i++) {
+                       String noteTag = noteTags.get(i);
+                       for (int j=0; j<children.size(); j++) {
+                               if (noteTag.equals(children.get(j).getGuid()))
+                                       return true;
+                       }
+               }
+               return returnValue;
+       }
+
+
+       //************************************************************************************
+       //************************************************************************************
+       //**  Notebook functions
+       //************************************************************************************
+       //************************************************************************************  
+       // Delete a notebook
+       public void deleteNotebook(String guid) {
+               for (int i=0; i<getNotebookIndex().size(); i++) {
+                       if (getNotebookIndex().get(i).getGuid().equals(guid)) {
+                               getNotebookIndex().remove(i);
+                               i=getMasterNoteIndex().size();
+                       }
+               }
+               conn.getNotebookTable().expungeNotebook(guid, true);            
+       }
+       // Rename a stack
+       public void renameStack(String oldName, String newName) {
+               for (int i=0; i<getNotebookIndex().size(); i++) {
+                       if (getNotebookIndex().get(i).getStack() != null && 
+                                       getNotebookIndex().get(i).getStack().equalsIgnoreCase(oldName)) {
+                               getNotebookIndex().get(i).setStack(newName);
+                       }
+               }       
+       }
+       // Update a notebook sequence number
+       public void updateNotebookSequence(String guid, int sequence) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNotebookSequence");
+
+               conn.getNotebookTable().updateNotebookSequence(guid, sequence);
+               
+               for (int i=0; i<notebookIndex.size(); i++) {
+                       if (notebookIndex.get(i).getGuid().equals(guid)) {
+                               notebookIndex.get(i).setUpdateSequenceNum(sequence);
+                               i=notebookIndex.size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateNotebookSequence");
+
+       }
+       // Update a notebook Guid number
+       public void updateNotebookGuid(String oldGuid, String newGuid) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");
+
+               conn.getNotebookTable().updateNotebookGuid(oldGuid, newGuid);
+               
+               for (int i=0; i<notebookIndex.size(); i++) {
+                       if (notebookIndex.get(i).getGuid().equals(oldGuid)) {
+                               notebookIndex.get(i).setGuid(newGuid);
+                               i=notebookIndex.size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");
+
+       }
+       // Update a notebook Guid number
+       public void updateNotebookStack(String oldGuid, String stack) {
+               logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");
+
+               conn.getNotebookTable().setStack(oldGuid, stack);
+               
+               for (int i=0; i<notebookIndex.size(); i++) {
+                       if (notebookIndex.get(i).getGuid().equals(oldGuid)) {
+                               notebookIndex.get(i).setStack(stack);
+                               i=notebookIndex.size()+1;
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");
+
+       }
+       
+       
+       //************************************************************************************
+       //************************************************************************************
+       //**  Load and filter the note index
+       //************************************************************************************
+       //************************************************************************************
+       
+       public void noteDownloaded(Note n) {
+               boolean found = false;
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+                               getMasterNoteIndex().set(i,n);
+                               found = true;
+                               i=getMasterNoteIndex().size();
+                       }
+               }
+               
+               if (!found)
+                       getMasterNoteIndex().add(n);
+               
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+                               if (filterRecord(getNoteIndex().get(i)))
+                                       getNoteIndex().add(n);
+                               getNoteIndex().remove(i);
+                               i=getNoteIndex().size();
+                       }
+               }
+               
+               if (filterRecord(n))
+                       getNoteIndex().add(n);
+               
+       }
+       // Check if a note matches the currently selected notebooks, tags, or attribute searches.
+       public boolean filterRecord(Note n) {
+                               
+               boolean goodNotebook = false;
+               boolean goodTag = false;
+               boolean goodStatus = false;
+                       
+               // Check note status
+               if (!n.isActive() && Global.showDeleted)
+                       return true;
+               else {
+                       if (n.isActive() && !Global.showDeleted)
+                               goodStatus = true;
+               }
+               
+               // Begin filtering results
+               if (goodStatus)
+                       goodNotebook = filterByNotebook(n.getNotebookGuid());
+               if (goodNotebook) 
+                       goodTag = filterByTag(n.getTagGuids());
+               if (goodTag) {
+                       boolean goodCreatedBefore = false;
+                       boolean goodCreatedSince = false;
+                       boolean goodChangedBefore = false;
+                       boolean goodChangedSince = false;
+                       boolean goodContains = false;
+                       if (!Global.createdBeforeFilter.hasSelection())
+                               goodCreatedBefore = true;
+                       else
+                               goodCreatedBefore = Global.createdBeforeFilter.check(n);
+                               
+                       if (!Global.createdSinceFilter.hasSelection())
+                               goodCreatedSince = true;
+                       else
+                               goodCreatedSince = Global.createdSinceFilter.check(n);
+                               
+                       if (!Global.changedBeforeFilter.hasSelection())
+                               goodChangedBefore = true;
+                       else
+                               goodChangedBefore = Global.changedBeforeFilter.check(n);
+                               if (!Global.changedSinceFilter.hasSelection())
+                               goodChangedSince = true;
+                       else
+                               goodChangedSince = Global.changedSinceFilter.check(n);
+                       if (!Global.containsFilter.hasSelection())
+                               goodContains = true;
+                       else
+                               goodContains = Global.containsFilter.check(conn.getNoteTable(), n);
+                               
+                       if (goodCreatedSince && goodCreatedBefore && goodChangedSince && goodChangedBefore && goodContains)
+                               return true;
+               }       
+               return false;
+       }
+       
+       // Trigger a recount of counters
+       public void refreshCounters() {
+//             refreshCounters= false;
+               if (!refreshCounters)
+                       return;
+               refreshCounters = false;
+               tagCounterRunner.abortCount = true;
+               notebookCounterRunner.abortCount = true;
+               trashCounterRunner.abortCount = true;
+               countNotebookResults(getNoteIndex());
+               countTagResults(getNoteIndex());
+               reloadTrashCount();
+
+       }
+       // Load the note index based upon what the user wants.
+       public void loadNotesIndex() {
+               logger.log(logger.EXTREME, "Entering ListManager.loadNotesIndex()");
+               
+               List<Note> matches;
+               if (enSearchChanged || getMasterNoteIndex() == null)
+                       matches = enSearch.matchWords();
+               else
+                       matches = getMasterNoteIndex();
+               
+               if (matches == null)
+                       matches = getMasterNoteIndex();
+               
+               setNoteIndex(new ArrayList<Note>());
+               for (int i=0; i<matches.size(); i++) {
+                       if (filterRecord(matches.get(i)))
+                               getNoteIndex().add(matches.get(i));
+               }
+               refreshCounters = true;
+               enSearchChanged = false;
+               logger.log(logger.EXTREME, "Leaving ListManager.loadNotesIndex()");
+       }
+       public void countNotebookResults(List<Note> index) {
+               logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults()");
+               notebookCounterRunner.abortCount = true;
+               if (!Global.mimicEvernoteInterface) 
+                       notebookCounterRunner.setNoteIndex(index);
+               else 
+                       notebookCounterRunner.setNoteIndex(getMasterNoteIndex());
+               notebookCounterRunner.release(CounterRunner.NOTEBOOK);
+               logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");
+       }
+       public void countTagResults(List<Note> index) {
+               logger.log(logger.EXTREME, "Entering ListManager.countTagResults");
+               trashCounterRunner.abortCount = true;
+               if (!Global.tagBehavior().equalsIgnoreCase("DoNothing")) 
+                       tagCounterRunner.setNoteIndex(index);
+               else
+                       tagCounterRunner.setNoteIndex(getMasterNoteIndex());
+               tagCounterRunner.release(CounterRunner.TAG);
+               logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");
+       }
+       // Update the count of items in the trash
+       public void reloadTrashCount() {
+               logger.log(logger.EXTREME, "Entering ListManager.reloadTrashCount");
+               trashCounterRunner.abortCount = true;
+               trashCounterRunner.setNoteIndex(getMasterNoteIndex());
+               trashCounterRunner.release(CounterRunner.TRASH);
+               logger.log(logger.EXTREME, "Leaving ListManager.reloadTrashCount");
+       }       
+       
+       private boolean filterByNotebook(String guid) {
+               boolean good = false;
+               if (selectedNotebooks.size() == 0)
+                       good = true;
+               if (!good && selectedNotebooks.contains(guid)) 
+                       good = true;
+
+               for (int i=0; i<getArchiveNotebookIndex().size() && good; i++) {
+                       if (guid.equals(getArchiveNotebookIndex().get(i).getGuid())) {
+                               good = false;
+                               return good;
+                       }
+               }
+               return good;
+       }
+       private boolean filterByTag(List<String> noteTags) {
+               // If either the note has no tags or there are
+               // no selected tags, then any note is good.
+               if (noteTags == null || selectedTags == null)
+                       return true;
+               
+               // If there are no tags selected, then any note  is good
+               if (selectedTags.size() == 0) 
+                       return true;
+               
+               // If ALL tags must be matched, then check ALL note tags, 
+               // otherwise we match on any criteria.
+               if (!Global.anyTagSelectionMatch()) {
+                       for (int i=0; i<selectedTags.size(); i++) {
+                               String selectedGuid = selectedTags.get(i);
+                               boolean childMatch = false;
+                               // If we should include children in the results
+                               if (Global.includeTagChildren()) {
+                                       childMatch = checkNoteForChildTags(selectedGuid, noteTags);
+                                       // Do we have a match with this tag or any children
+                                       if (!noteTags.contains(selectedGuid)&& !childMatch)
+                                               return false;
+                               } else {
+                                       // Does this note have a matching tag
+                                       if (!noteTags.contains(selectedGuid))
+                                               return false;
+                               }
+                       }
+                       return true;
+               } else {
+                       // Any match is displayed.
+                       for (int i=0; i<selectedTags.size(); i++) {
+                               String selectedGuid = selectedTags.get(i);
+                               // If we have a simple match, then we're good
+                               if (noteTags.contains(selectedGuid))
+                                               return true;
+                               // If we have a match with one of the children tags && we should include child tags
+                               if (Global.includeTagChildren() && checkNoteForChildTags(selectedGuid, noteTags))
+                                       return true;
+                       }
+                       return false;
+               }
+       }
+
+       public void setNoteSynchronized(String guid, boolean value) {
+               getNoteTableModel().updateNoteSyncStatus(guid, value);
+       }
+       
+       public void updateNoteTitleColor(String guid, Integer color) {
+               NoteMetadata meta = getNoteMetadata().get(guid);
+               if (meta != null) {
+                       noteModel.updateNoteTitleColor(guid, color);
+                       meta.setColor(color);
+                       conn.getNoteTable().updateNoteMetadata(meta);
+               }
+       }
+       public void loadNoteTitleColors() {
+               noteModel.setMetaData(getNoteMetadata());
+       }
+       
+       //********************************************************************************
+       //********************************************************************************
+       //* Support signals from the index thread
+       //********************************************************************************
+       //********************************************************************************
+       // Reset a flag if an index is needed
+       public void setIndexNeeded(String guid, String type, Boolean b) {
+               if (Global.keepRunning && type.equalsIgnoreCase("content"))
+                       conn.getNoteTable().setIndexNeeded(guid, false);
+               if (Global.keepRunning && type.equalsIgnoreCase("resource")) {
+                       conn.getNoteTable().noteResourceTable.setIndexNeeded(guid, b);
+               }
+       }
+       
+       public boolean threadCheck(int id) {
+               if (id == Global.notebookCounterThreadId) 
+                       return notebookThread.isAlive();
+               if (id == Global.tagCounterThreadId) 
+                       return tagThread.isAlive();
+               if (id == Global.trashCounterThreadId) 
+                       return trashThread.isAlive();
+               if (id == Global.saveThreadId) 
+                       return saveThread.isAlive();
+               return false;
+       }
+       
+       
+       
+       //********************************************************************************
+       //********************************************************************************
+       //* Utility Functions
+       //********************************************************************************
+       //********************************************************************************
+       public void compactDatabase() {
+               conn.compactDatabase();
+//             IndexConnection idx = new IndexConnection(logger, "nevernote-compact");
+//             idx.dbSetup();
+//             idx.dbShutdown();
+       }
+
+       // Rebuild the note HTML to something usable
+       public List<String> scanNoteForResources(Note n) {
+               logger.log(logger.HIGH, "Entering ListManager.scanNoteForResources");
+               logger.log(logger.EXTREME, "Note guid: " +n.getGuid());
+               QDomDocument doc = new QDomDocument();
+               QDomDocument.Result result = doc.setContent(n.getContent());
+               if (!result.success) {
+                       logger.log(logger.MEDIUM, "Parse error when scanning note for resources.");
+                       logger.log(logger.MEDIUM, "Note guid: " +n.getGuid());
+                       return null;
+               }
+                               
+               List<String> returnArray = new ArrayList<String>();
+               QDomNodeList anchors = doc.elementsByTagName("en-media");
+               for (int i=0; i<anchors.length(); i++) {
+                       QDomElement enmedia = anchors.at(i).toElement();
+                       if (enmedia.hasAttribute("type")) {
+                               QDomAttr hash = enmedia.attributeNode("hash");
+                               returnArray.add(hash.value().toString());
+                       }
+               }
+               logger.log(logger.HIGH, "Leaving ListManager.scanNoteForResources");
+               return returnArray;
+       }
+       // Given a list of tags, produce a string list of tag names
+       public String getTagNamesForNote(Note n) {
+               StringBuffer buffer = new StringBuffer(100);
+               Vector<String> v = new Vector<String>();
+               List<String> guids = n.getTagGuids();
+               
+               if (guids == null) 
+                       return "";
+               
+               for (int i=0; i<guids.size(); i++) {
+                       v.add(getTagNameByGuid(guids.get(i)));
+               }
+               Comparator<String> comparator = Collections.reverseOrder();
+               Collections.sort(v,comparator);
+               Collections.reverse(v);
+               
+               for (int i = 0; i<v.size(); i++) {
+                       if (i>0) 
+                               buffer.append(", ");
+                       buffer.append(v.get(i));
+               }
+               
+               return buffer.toString();
+       }
+       // Get a tag name when given a tag guid
+       public String getTagNameByGuid(String guid) {
+               for (int i=0; i<getTagIndex().size(); i++) {
+                       String s = getTagIndex().get(i).getGuid();
+                       if (s.equals(guid)) { 
+                               return getTagIndex().get(i).getName();
+                       }
+               }
+               return "";
+       }
+       // For a notebook guid, return the name
+       public String getNotebookNameByGuid(String guid) {
+               if (notebookIndex == null)
+                       return null;
+               for (int i=0; i<notebookIndex.size(); i++) {
+                       String s = notebookIndex.get(i).getGuid();
+                       if (s.equals(guid)) { 
+                               return notebookIndex.get(i).getName();
+                       }
+               }
+               return "";
+       }
+       
+       
+       // Reload the note's tag names.  This is called when a tag's name changes by
+       // the user.  It updates all notes with that tag to the new tag name.
+       public void reloadNoteTagNames(String tagGuid, String newName) {
+               
+               // Set the master index
+               for (int i=0; i<getMasterNoteIndex().size(); i++) {
+                       for (int j=0; j<getMasterNoteIndex().get(i).getTagGuids().size(); j++) {
+                               if (getMasterNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {
+                                       getMasterNoteIndex().get(i).getTagNames().set(j, newName);
+                               }
+                       }
+               }
+               
+               // Set the current index
+               for (int i=0; i<getNoteIndex().size(); i++) {
+                       for (int j=0; j<getNoteIndex().get(i).getTagGuids().size(); j++) {
+                               if (getNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {
+                                       getNoteIndex().get(i).getTagNames().set(j, newName);
+                               }
+                       }
+               }
+       }
+       
+}