OSDN Git Service

Cleanup of initial sync with ink notes and added the ability to highlight words in...
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / NeverNote.java
index 0ad39eb..e4d8397 100644 (file)
@@ -55,6 +55,7 @@ import com.evernote.edam.type.Data;
 import com.evernote.edam.type.Note;
 import com.evernote.edam.type.NoteAttributes;
 import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.Publishing;
 import com.evernote.edam.type.QueryFormat;
 import com.evernote.edam.type.Resource;
 import com.evernote.edam.type.SavedSearch;
@@ -92,6 +93,7 @@ import com.trolltech.qt.gui.QCloseEvent;
 import com.trolltech.qt.gui.QColor;
 import com.trolltech.qt.gui.QComboBox;
 import com.trolltech.qt.gui.QComboBox.InsertPolicy;
+import com.trolltech.qt.gui.QCursor;
 import com.trolltech.qt.gui.QDesktopServices;
 import com.trolltech.qt.gui.QDialog;
 import com.trolltech.qt.gui.QFileDialog;
@@ -138,7 +140,11 @@ import cx.fbn.nevernote.dialog.LoginDialog;
 import cx.fbn.nevernote.dialog.NotebookArchive;
 import cx.fbn.nevernote.dialog.NotebookEdit;
 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
+import cx.fbn.nevernote.dialog.PublishNotebook;
 import cx.fbn.nevernote.dialog.SavedSearchEdit;
+import cx.fbn.nevernote.dialog.SetIcon;
+import cx.fbn.nevernote.dialog.ShareNotebook;
+import cx.fbn.nevernote.dialog.StackNotebook;
 import cx.fbn.nevernote.dialog.TagEdit;
 import cx.fbn.nevernote.dialog.ThumbnailViewer;
 import cx.fbn.nevernote.dialog.WatchFolder;
@@ -284,6 +290,7 @@ public class NeverNote extends QMainWindow{
     int                                saveThreadDeadCount=0;          // number of consecutive dead times for the save thread
     
     HashMap<String, String>            noteCache;                      // Cash of note content 
+    HashMap<String, Boolean>   readOnlyCache;          // List of cash notes that are read-only
     List<String>               historyGuids;                           // GUIDs of previously viewed items
     int                                        historyPosition;                        // Position within the viewed items
     boolean                            fromHistory;                            // Is this from the history queue?
@@ -307,14 +314,15 @@ public class NeverNote extends QMainWindow{
     //***************************************************************
     //***************************************************************
     // Application Constructor 
+       @SuppressWarnings("static-access")
        public NeverNote(DatabaseConnection dbConn)  {
                conn = dbConn;          
                if (conn.getConnection() == null) {
-                       String msg = "Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
+                       String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
                                "is accessing the database or NeverNote is already running.\n\n" +
-                               "Please end any other process or shutdown the other NeverNote before starting.\n\nExiting program.";
+                               "Please end any other process or shutdown the other NeverNote before starting.\n\nExiting program."));
                        
-            QMessageBox.critical(null, "Database Connection Error",msg);
+            QMessageBox.critical(null, tr("Database Connection Error") ,msg);
                        System.exit(16);
                }
 
@@ -412,7 +420,7 @@ public class NeverNote extends QMainWindow{
                thumbnailTimer = new QTimer();
                thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
                thumbnailTimer();
-               thumbnailTimer.setInterval(5*1000);  // Thumbnail every 2 min
+               thumbnailTimer.setInterval(60*1000);  // Thumbnail every minute
                thumbnailTimer.start();
                
                logger.log(logger.EXTREME, "Starting authentication timer");
@@ -439,7 +447,7 @@ public class NeverNote extends QMainWindow{
                importFilesKeep = new ArrayList<String>();
                externalFileSaveTimer.start();
                
-        notebookTree = new NotebookTreeWidget();
+        notebookTree = new NotebookTreeWidget(conn);
         attributeTree = new AttributeTreeWidget();
         tagTree = new TagTreeWidget(conn);
         savedSearchTree = new SavedSearchTreeWidget();
@@ -456,6 +464,7 @@ public class NeverNote extends QMainWindow{
         
         // Setup the browser window
         noteCache = new HashMap<String,String>();
+        readOnlyCache = new HashMap<String, Boolean>();
         browserWindow = new BrowserWindow(conn);
 
         mainLeftRightSplitter.addWidget(leftSplitter1);
@@ -504,6 +513,7 @@ public class NeverNote extends QMainWindow{
                tagTree.setDeleteAction(menuBar.tagDeleteAction);
                tagTree.setEditAction(menuBar.tagEditAction);
                tagTree.setAddAction(menuBar.tagAddAction);
+               tagTree.setIconAction(menuBar.tagIconAction);
                tagTree.setVisible(Global.isWindowVisible("tagTree"));
                tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
                menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
@@ -512,6 +522,10 @@ public class NeverNote extends QMainWindow{
                notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
                notebookTree.setEditAction(menuBar.notebookEditAction);
                notebookTree.setAddAction(menuBar.notebookAddAction);
+               notebookTree.setIconAction(menuBar.notebookIconAction);
+               notebookTree.setStackAction(menuBar.notebookStackAction);
+               notebookTree.setPublishAction(menuBar.notebookPublishAction);
+               notebookTree.setShareAction(menuBar.notebookShareAction);
                notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
                notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
                menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
@@ -519,6 +533,7 @@ public class NeverNote extends QMainWindow{
                savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
                savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
                savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
+               savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
                savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
                savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
                menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
@@ -681,7 +696,7 @@ public class NeverNote extends QMainWindow{
             dbConn = setupDatabaseConnection();
 
             // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
-            Global.getFileManager().purgeResDirectory();
+            Global.getFileManager().purgeResDirectory(true);
 
         } catch (InitializationException e) {
             // Fatal
@@ -947,10 +962,14 @@ public class NeverNote extends QMainWindow{
        }
                
        private void waitCursor(boolean wait) {
-//             if (wait)
-//                     QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
-//             else
-//                     QApplication.restoreOverrideCursor();
+               if (wait) {
+                       if (QApplication.overrideCursor() == null)
+                               QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
+               }
+               else {
+                       while (QApplication.overrideCursor() != null)
+                               QApplication.restoreOverrideCursor();
+               }
        }
        
        private void setupIndexListeners() {
@@ -1037,6 +1056,7 @@ public class NeverNote extends QMainWindow{
 //        if (!dateFormat.equals(Global.getDateFormat()) ||
 //                     !timeFormat.equals(Global.getTimeFormat())) {
                noteCache.clear();
+               readOnlyCache.clear();
                noteIndexUpdated(true);
 //        }
         
@@ -1138,10 +1158,8 @@ public class NeverNote extends QMainWindow{
     // Setup the tree containing the user's notebooks.
     private void initializeNotebookTree() {       
        logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
- //    notebookTree.itemSelectionChanged.connect(this, "notebookTreeSelection()");
        notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
        listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
- //    notebookTree.resize(Global.getSize("notebookTree"));
        logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
     }   
     // Listener when a notebook is selected
@@ -1158,13 +1176,26 @@ public class NeverNote extends QMainWindow{
                menuBar.noteRestoreAction.setVisible(false);            
        menuBar.notebookEditAction.setEnabled(true);
        menuBar.notebookDeleteAction.setEnabled(true);
+       menuBar.notebookPublishAction.setEnabled(true);
+       menuBar.notebookShareAction.setEnabled(true);
+       menuBar.notebookIconAction.setEnabled(true);
+       menuBar.notebookStackAction.setEnabled(true);
        List<QTreeWidgetItem> selections = notebookTree.selectedItems();
        QTreeWidgetItem currentSelection;
        selectedNotebookGUIDs.clear();
        if (!Global.mimicEvernoteInterface) {
                for (int i=0; i<selections.size(); i++) {
                        currentSelection = selections.get(i);
-                       selectedNotebookGUIDs.add(currentSelection.text(2));
+                       if (!currentSelection.text(2).equals("STACK"))
+                               selectedNotebookGUIDs.add(currentSelection.text(2));
+                       else {
+                               String stackName = currentSelection.text(0);
+                               for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
+                                       Notebook book = listManager.getNotebookIndex().get(j);
+                                       if (book.getStack()!=null && book.getStack().equalsIgnoreCase(stackName))
+                                               selectedNotebookGUIDs.add(book.getGuid());
+                               }
+                       }
                }
        
                
@@ -1176,6 +1207,8 @@ public class NeverNote extends QMainWindow{
                        selectedNotebookGUIDs.clear();
                        menuBar.notebookEditAction.setEnabled(false);
                        menuBar.notebookDeleteAction.setEnabled(false);
+                       menuBar.notebookIconAction.setEnabled(false);
+               menuBar.notebookStackAction.setEnabled(false);
                }
                if (selectedNotebookGUIDs.size() == 1 && selectedNotebookGUIDs.get(0).equals(previousSelectedNotebook)) {
                        previousSelectedNotebook = selectedNotebookGUIDs.get(0);
@@ -1190,10 +1223,23 @@ public class NeverNote extends QMainWindow{
                        previousSelectedNotebook = "";
        } else {
                String guid = "";
-               if (selections.size() > 0)
+               String stackName = "";
+               if (selections.size() > 0) {
                        guid = (selections.get(0).text(2));
-               if (!guid.equals(""))
+                       stackName = selections.get(0).text(0);
+               }
+               if (!guid.equals("") && !guid.equals("STACK")) {
                        selectedNotebookGUIDs.add(guid);
+                       menuBar.notebookIconAction.setEnabled(true);
+               }
+               else {
+                       menuBar.notebookIconAction.setEnabled(true);
+                               for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
+                                       Notebook book = listManager.getNotebookIndex().get(j);
+                                       if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
+                                               selectedNotebookGUIDs.add(book.getGuid());
+                               }
+               }
        }
        listManager.setSelectedNotebooks(selectedNotebookGUIDs);
        listManager.loadNotesIndex();
@@ -1214,7 +1260,12 @@ public class NeverNote extends QMainWindow{
        // Triggered when the notebook DB has been updated
        private void notebookIndexUpdated() {
                logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
-               if (selectedNotebookGUIDs == null)
+       
+               // Get the possible icons
+               HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
+       notebookTree.setIcons(icons);
+       
+       if (selectedNotebookGUIDs == null)
                        selectedNotebookGUIDs = new ArrayList<String>();
                List<Notebook> books = conn.getNotebookTable().getAll();
                for (int i=books.size()-1; i>=0; i--) {
@@ -1285,29 +1336,89 @@ public class NeverNote extends QMainWindow{
        }
        // Edit an existing notebook
        @SuppressWarnings("unused")
+       private void stackNotebook() {
+               logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
+               StackNotebook edit = new StackNotebook();
+               
+               List<QTreeWidgetItem> selections = notebookTree.selectedItems();
+               QTreeWidgetItem currentSelection;
+               for (int i=0; i<selections.size(); i++) {
+                       currentSelection = selections.get(0);
+                       String guid = currentSelection.text(2);
+                       if (guid.equalsIgnoreCase("")) {
+                                QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
+                                return;
+                       }
+                       if (guid.equalsIgnoreCase("STACK")) {
+                                QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
+                                return;
+                       }
+               }
+
+               edit.setStackNames(conn.getNotebookTable().getAllStackNames());
+
+               
+               edit.exec();
+       
+               if (!edit.okPressed())
+                       return;
+        
+               String stack = edit.getStackName();
+               
+               for (int i=0; i<selections.size(); i++) {
+                       currentSelection = selections.get(i);
+                       String guid = currentSelection.text(2);
+                       listManager.updateNotebookStack(guid, stack);
+               }
+               notebookIndexUpdated();
+               logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
+       }
+       // Edit an existing notebook
+       @SuppressWarnings("unused")
        private void editNotebook() {
                logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
                NotebookEdit edit = new NotebookEdit();
-               edit.setTitle(tr("Edit Notebook"));
-               edit.setLocalCheckboxEnabled(false);
+               
                List<QTreeWidgetItem> selections = notebookTree.selectedItems();
                QTreeWidgetItem currentSelection;
                currentSelection = selections.get(0);
                edit.setNotebook(currentSelection.text(0));
-               edit.setNotebooks(listManager.getNotebookIndex());
-
+               
                String guid = currentSelection.text(2);
-               for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
-                       if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
-                               edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
-                               i=listManager.getNotebookIndex().size();
+               if (!guid.equalsIgnoreCase("STACK")) {
+                       edit.setTitle(tr("Edit Notebook"));
+                       edit.setNotebooks(listManager.getNotebookIndex());
+                       edit.setLocalCheckboxEnabled(false);
+                       for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
+                               if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
+                                       edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
+                                       i=listManager.getNotebookIndex().size();
+                               }
                        }
+               } else {
+                       edit.setTitle(tr("Edit Stack"));
+                       edit.setStacks(conn.getNotebookTable().getAllStackNames());
+                       edit.hideLocalCheckbox();
+                       edit.hideDefaultCheckbox();
                }
+               
                edit.exec();
        
                if (!edit.okPressed())
                        return;
         
+               
+               if (guid.equalsIgnoreCase("STACK")) {
+                       conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
+                       for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
+                               if (listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
+                                               listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
+                       }
+                       conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
+                       currentSelection.setText(0, edit.getNotebook());
+                       return;
+               }
+               
                updateListNotebookName(currentSelection.text(0), edit.getNotebook());
                currentSelection.setText(0, edit.getNotebook());
                
@@ -1340,10 +1451,76 @@ public class NeverNote extends QMainWindow{
                browserWindow.setNotebookList(nbooks);
                logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
        }
+       // Publish a notebook
+       @SuppressWarnings("unused")
+       private void publishNotebook() {
+               List<QTreeWidgetItem> selections = notebookTree.selectedItems();
+               QTreeWidgetItem currentSelection;
+               currentSelection = selections.get(0);
+               String guid = currentSelection.text(2);
+
+               if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
+                       return;
+               
+               Notebook n = null;
+               int position = 0;
+               for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
+                       if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
+                               n = listManager.getNotebookIndex().get(i);
+                               position = i;
+                               i = listManager.getNotebookIndex().size();
+                       }
+               }
+               if (n == null)
+                       return;
+               
+               PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
+               publish.exec();
+               
+               if (!publish.okClicked()) 
+                       return;
+               
+               Publishing p = publish.getPublishing();
+               boolean isPublished = !publish.isStopPressed();
+               conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
+               n.setPublished(isPublished);
+               n.setPublishing(p);
+               listManager.getNotebookIndex().set(position, n);
+               notebookIndexUpdated();
+       }
+       // Publish a notebook
+       @SuppressWarnings("unused")
+       private void shareNotebook() {
+               List<QTreeWidgetItem> selections = notebookTree.selectedItems();
+               QTreeWidgetItem currentSelection;
+               currentSelection = selections.get(0);
+               String guid = currentSelection.text(2);
+
+               if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
+                       return;
+               
+               Notebook n = null;;
+               for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
+                       if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
+                               n = listManager.getNotebookIndex().get(i);
+                               i = listManager.getNotebookIndex().size();
+                       }
+               }
+                               
+               String authToken = null;
+               if (syncRunner.isConnected)
+                       authToken = syncRunner.authToken;
+               ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
+               share.exec();
+               
+       }
+
        // Delete an existing notebook
        @SuppressWarnings("unused")
        private void deleteNotebook() {
                logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
+               boolean stacksFound = false;
+               boolean notebooksFound = false;
                boolean assigned = false;
                // Check if any notes have this notebook
                List<QTreeWidgetItem> selections = notebookTree.selectedItems();
@@ -1351,13 +1528,18 @@ public class NeverNote extends QMainWindow{
                QTreeWidgetItem currentSelection;
                currentSelection = selections.get(i);
                String guid = currentSelection.text(2);
-               for (int j=0; j<listManager.getNoteIndex().size(); j++) {
-                       String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
-                       if (noteGuid.equals(guid)) {
-                               assigned = true;
-                               j=listManager.getNoteIndex().size();
-                               i=selections.size();
+               if (!guid.equalsIgnoreCase("STACK")) {
+                       notebooksFound = true;
+                       for (int j=0; j<listManager.getNoteIndex().size(); j++) {
+                               String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
+                               if (noteGuid.equals(guid)) {
+                                       assigned = true;
+                                       j=listManager.getNoteIndex().size();
+                                       i=selections.size();
+                               }
                        }
+               } else {
+                       stacksFound = true;
                }
         }
                if (assigned) {
@@ -1372,7 +1554,18 @@ public class NeverNote extends QMainWindow{
                }
         
         // If all notebooks are clear, verify the delete
-               if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected notebooks?"),
+               String msg1 = new String(tr("Delete selected notebooks?"));
+               String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
+               String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
+                               " not deleted unless selected?"));
+               String msg = "";
+               if (stacksFound && notebooksFound)
+                       msg = msg3;
+               if (!stacksFound && notebooksFound)
+                       msg = msg1;
+               if (stacksFound && !notebooksFound)
+                       msg = msg2;
+               if (QMessageBox.question(this, tr("Confirmation"), msg,
                        QMessageBox.StandardButton.Yes, 
                        QMessageBox.StandardButton.No)==StandardButton.No.value()) {
                        return;
@@ -1383,16 +1576,18 @@ public class NeverNote extends QMainWindow{
                QTreeWidgetItem currentSelection;
                currentSelection = selections.get(i);
                String guid = currentSelection.text(2);
-               conn.getNotebookTable().expungeNotebook(guid, true);
-               listManager.deleteNotebook(guid);
+               if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
+                               conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
+                               listManager.renameStack(currentSelection.text(0), "");
+               } else {
+                       conn.getNotebookTable().expungeNotebook(guid, true);
+                       listManager.deleteNotebook(guid);
+               }
         }
-//        for (int i=<dbRunner.getLocalNotebooks().size()-1; i>=0; i--) {
- //            if (dbRunner.getLocalNotebooks().get(i).equals(arg0))
- //       }
+
         notebookTreeSelection();
         notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
         listManager.countNotebookResults(listManager.getNoteIndex());
-//             notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
         logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
        }
        // A note's notebook has been updated
@@ -1483,9 +1678,86 @@ public class NeverNote extends QMainWindow{
                waitCursor(false);
                browserWindow.setNotebookList(nbooks);
        }
+       // Change the notebook's icon
+       @SuppressWarnings("unused")
+       private void setNotebookIcon() {
+               boolean stackSelected = false;
+               boolean allNotebookSelected = false;
+               
+               QTreeWidgetItem currentSelection;
+               List<QTreeWidgetItem> selections = notebookTree.selectedItems();
+               if (selections.size() == 0)
+                       return;
+               
+               currentSelection = selections.get(0);   
+               String guid = currentSelection.text(2);
+               if (guid.equalsIgnoreCase(""))
+                       allNotebookSelected = true;
+               if (guid.equalsIgnoreCase("STACK"))
+                       stackSelected = true;
 
+               QIcon currentIcon = currentSelection.icon(0);
+               QIcon icon;
+               SetIcon dialog;
+               
+               if (!stackSelected && !allNotebookSelected) {
+                       icon = conn.getNotebookTable().getIcon(guid);
+                       if (icon == null) {
+                               dialog = new SetIcon(currentIcon);
+                               dialog.setUseDefaultIcon(true);
+                       } else {
+                               dialog = new SetIcon(icon);
+                               dialog.setUseDefaultIcon(false);
+                       }
+               } else {
+                       if (stackSelected) {
+                               icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
+                       } else {
+                               icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");                              
+                       }
+                       if (icon == null) {
+                               dialog = new SetIcon(currentIcon);
+                               dialog.setUseDefaultIcon(true);
+                       } else {
+                               dialog = new SetIcon(icon);
+                               dialog.setUseDefaultIcon(false);
+                       }
+               }
+               dialog.exec();
+               if (dialog.okPressed()) {
+                       QIcon newIcon = dialog.getIcon();
+                       if (stackSelected) {
+                               conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
+                               if (newIcon == null) {
+                                       newIcon = new QIcon(iconPath+"books2.png");
+                               }
+                               currentSelection.setIcon(0,newIcon);
+                               return;
+                       }
+                       if (allNotebookSelected) {
+                               conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
+                               if (newIcon == null) {
+                                       newIcon = new QIcon(iconPath+"notebook-green.png");
+                               }
+                               currentSelection.setIcon(0,newIcon);
+                               return;
+                       }
+                       conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
+                       if (newIcon == null) {
+                               boolean isPublished = false;;
+                               boolean found = false;
+                               for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
+                                       if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
+                                               isPublished = listManager.getNotebookIndex().get(i).isPublished();
+                                               found = true;
+                                       }
+                               }
+                               newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
+                       }
+                       currentSelection.setIcon(0, newIcon);
+               }
        
-       
+       }
        
        
     //***************************************************************
@@ -1518,6 +1790,7 @@ public class NeverNote extends QMainWindow{
                
                logger.log(logger.HIGH, "Leaving NeverNote.addTag");
        }
+       @SuppressWarnings("unused")
        private void reloadTagTree() {
                reloadTagTree(false);
        }
@@ -1637,10 +1910,12 @@ public class NeverNote extends QMainWindow{
        if (selections.size() > 0) {
                menuBar.tagEditAction.setEnabled(true);
                menuBar.tagDeleteAction.setEnabled(true);
+               menuBar.tagIconAction.setEnabled(true);
        }
        else {
                menuBar.tagEditAction.setEnabled(false);
                menuBar.tagDeleteAction.setEnabled(false);
+               menuBar.tagIconAction.setEnabled(true);
        }
        if (selectedTagGUIDs.size() == 1 && selectedTagGUIDs.get(0).equals(previousSelectedTag)) {
                previousSelectedTag = selectedTagGUIDs.get(0);
@@ -1670,8 +1945,10 @@ public class NeverNote extends QMainWindow{
 //             selectedTagGUIDs.clear();  // clear out old entries
 
                tagTree.blockSignals(true);
-               if (reload)
+               if (reload) {
+                       tagTree.setIcons(conn.getTagTable().getAllIcons());
                        tagTree.load(listManager.getTagIndex());
+               }
        for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
                boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
                if (!found)
@@ -1792,11 +2069,43 @@ public class NeverNote extends QMainWindow{
                menuBar.noteRestoreAction.setVisible(false);
                menuBar.tagEditAction.setEnabled(false);
                menuBar.tagDeleteAction.setEnabled(false);
+               menuBar.tagIconAction.setEnabled(false);
                selectedTagGUIDs.clear();
        listManager.setSelectedTags(selectedTagGUIDs);
        tagTree.blockSignals(false);
        }
+       // Change the icon for a tag
+       @SuppressWarnings("unused")
+       private void setTagIcon() {
+               QTreeWidgetItem currentSelection;
+               List<QTreeWidgetItem> selections = tagTree.selectedItems();
+               if (selections.size() == 0)
+                       return;
+               
+               currentSelection = selections.get(0);   
+               String guid = currentSelection.text(2);
+
+               QIcon currentIcon = currentSelection.icon(0);
+               QIcon icon = conn.getTagTable().getIcon(guid);
+               SetIcon dialog;
+               if (icon == null) {
+                       dialog = new SetIcon(currentIcon);
+                       dialog.setUseDefaultIcon(true);
+               } else {
+                       dialog = new SetIcon(icon);
+                       dialog.setUseDefaultIcon(false);
+               }
+               dialog.exec();
+               if (dialog.okPressed()) {
+                       QIcon newIcon = dialog.getIcon();
+                       conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
+                       if (newIcon == null) 
+                               newIcon = new QIcon(iconPath+"tag.png");
+                       currentSelection.setIcon(0, newIcon);
+               }
        
+       }
+
        
     //***************************************************************
     //***************************************************************
@@ -1912,6 +2221,7 @@ public class NeverNote extends QMainWindow{
        String currentGuid = selectedSavedSearchGUID;
        menuBar.savedSearchEditAction.setEnabled(true);
        menuBar.savedSearchDeleteAction.setEnabled(true);
+       menuBar.savedSearchIconAction.setEnabled(true);
        List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
        QTreeWidgetItem currentSelection;
        selectedSavedSearchGUID = "";
@@ -1938,6 +2248,7 @@ public class NeverNote extends QMainWindow{
     private void clearSavedSearchFilter() {
        menuBar.savedSearchEditAction.setEnabled(false);
        menuBar.savedSearchDeleteAction.setEnabled(false);
+       menuBar.savedSearchIconAction.setEnabled(false);
        savedSearchTree.blockSignals(true);
        savedSearchTree.clearSelection();
        savedSearchTree.blockSignals(false);
@@ -1951,6 +2262,7 @@ public class NeverNote extends QMainWindow{
                if (selectedSavedSearchGUID == null)
                        selectedSavedSearchGUID = new String();
                savedSearchTree.blockSignals(true);
+               savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
        savedSearchTree.load(listManager.getSavedSearchIndex());
        savedSearchTree.selectGuid(selectedSavedSearchGUID);
        savedSearchTree.blockSignals(false);
@@ -1962,17 +2274,20 @@ public class NeverNote extends QMainWindow{
                
        menuBar.savedSearchEditAction.setEnabled(true);
        menuBar.savedSearchDeleteAction.setEnabled(true);
+       menuBar.savedSearchIconAction.setEnabled(true);
        List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
 
        if (selections.size() > 0) {
                menuBar.savedSearchEditAction.setEnabled(true);
                menuBar.savedSearchDeleteAction.setEnabled(true);
+               menuBar.savedSearchIconAction.setEnabled(true);
                selectedSavedSearchGUID = selections.get(0).text(1);
                SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
                searchField.setEditText(s.getQuery());
        } else { 
                menuBar.savedSearchEditAction.setEnabled(false);
                menuBar.savedSearchDeleteAction.setEnabled(false);
+               menuBar.savedSearchIconAction.setEnabled(false);
                selectedSavedSearchGUID = "";
                searchField.setEditText("");
        }
@@ -1994,6 +2309,37 @@ public class NeverNote extends QMainWindow{
                Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
        logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
     }
+       // Change the icon for a saved search
+       @SuppressWarnings("unused")
+       private void setSavedSearchIcon() {
+               QTreeWidgetItem currentSelection;
+               List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
+               if (selections.size() == 0)
+                       return;
+               
+               currentSelection = selections.get(0);   
+               String guid = currentSelection.text(1);
+
+               QIcon currentIcon = currentSelection.icon(0);
+               QIcon icon = conn.getSavedSearchTable().getIcon(guid);
+               SetIcon dialog;
+               if (icon == null) {
+                       dialog = new SetIcon(currentIcon);
+                       dialog.setUseDefaultIcon(true);
+               } else {
+                       dialog = new SetIcon(icon);
+                       dialog.setUseDefaultIcon(false);
+               }
+               dialog.exec();
+               if (dialog.okPressed()) {
+                       QIcon newIcon = dialog.getIcon();
+                       conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
+                       if (newIcon == null) 
+                               newIcon = new QIcon(iconPath+"search.png");
+                       currentSelection.setIcon(0, newIcon);
+               }
+       
+       }
        
        
        
@@ -2131,9 +2477,19 @@ public class NeverNote extends QMainWindow{
     //***************************************************************  
        // Text in the search bar has been cleared
        private void searchFieldCleared() {
+               saveNote();
+               
+               // This is done because we want to force a reload of
+               // images.  Some images we may want to highlight the text.
+               readOnlyCache.clear();
+               noteCache.clear();
+               QWebSettings.setMaximumPagesInCache(0);
+               QWebSettings.setObjectCacheCapacities(0, 0, 0);
+        
                searchField.setEditText("");
                saveNoteColumnPositions();
                saveNoteIndexWidth();
+               loadNoteBrowserInformation(browserWindow);
        }
        // text in the search bar changed.  We only use this to tell if it was cleared, 
        // otherwise we trigger off searchFieldChanged.
@@ -2142,10 +2498,15 @@ public class NeverNote extends QMainWindow{
                if (text.trim().equals("")) {
                        searchFieldCleared();
                        if (searchPerformed) {
+
+                               // This is done because we want to force a reload of
+                               // images.  Some images we may want to highlight the text.
                                noteCache.clear();
+                               readOnlyCache.clear();
+                               QWebSettings.setMaximumPagesInCache(0);
+                               QWebSettings.setObjectCacheCapacities(0, 0, 0);
+                               
                                listManager.setEnSearch("");
-/////                          listManager.clearNoteIndexSearch();
-                               //noteIndexUpdated(true);
                                listManager.loadNotesIndex();
                                refreshEvernoteNote(true);
                                noteIndexUpdated(false);
@@ -2157,6 +2518,7 @@ public class NeverNote extends QMainWindow{
     private void searchFieldChanged() {
        logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
        noteCache.clear();
+       readOnlyCache.clear();
        saveNoteColumnPositions();
        saveNoteIndexWidth();
        String text = searchField.currentText();
@@ -2717,10 +3079,10 @@ public class NeverNote extends QMainWindow{
     @SuppressWarnings("unused")
        private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
        
-       clearTagFilter();
-       clearNotebookFilter();
+//     clearTagFilter();
+//     clearNotebookFilter();
        clearTrashFilter();
-       clearSavedSearchFilter();
+//     clearSavedSearchFilter();
 
        if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
                if (item.childCount() > 0) {
@@ -3084,6 +3446,7 @@ public class NeverNote extends QMainWindow{
        }
        logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
     }
+       @SuppressWarnings("unused")
        private void updateListGuid(String oldGuid, String newGuid) {
        logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
 
@@ -3201,7 +3564,6 @@ public class NeverNote extends QMainWindow{
        }
        logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
     }
-    @SuppressWarnings("unused")
        private void updateListDateChanged(String guid, QDateTime date) {
        logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
 
@@ -3226,7 +3588,6 @@ public class NeverNote extends QMainWindow{
        logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
     }  
     // Redo scroll
-    @SuppressWarnings("unused")
        private void scrollToCurrentGuid() {
        //scrollToGuid(currentNoteGuid);
        List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
@@ -3379,14 +3740,12 @@ public class NeverNote extends QMainWindow{
     //** External editor window functions                    
     //***************************************************************
     //***************************************************************
-    @SuppressWarnings("unused")
        private void listDoubleClick() {
        saveNote();
        if (externalWindows.containsKey(currentNoteGuid)) {
                externalWindows.get(currentNoteGuid).raise();
                return;
        }
-       
        // We have a new external editor to create
        QIcon appIcon = new QIcon(iconPath+"nevernote.png");
        ExternalBrowse newBrowser = new ExternalBrowse(conn);
@@ -3412,7 +3771,7 @@ public class NeverNote extends QMainWindow{
                browserWindow.setTitle(text);
        }
     }
-    @SuppressWarnings("unused")
+    @SuppressWarnings({ "rawtypes", "unused" })
        private void externalWindowTagsEdited(String guid, List values) {
        StringBuffer line = new StringBuffer(100);
        for (int i=0; i<values.size(); i++) {
@@ -3486,6 +3845,7 @@ public class NeverNote extends QMainWindow{
                browserWindow.getBrowser().setContent(unicode);
        } 
        if (save) {
+               thumbnailRunner.addWork("GENERATE "+ guid);
                saveNote(guid, browser);
        }
        
@@ -3493,6 +3853,7 @@ public class NeverNote extends QMainWindow{
     private void saveNote() {
        if (noteDirty) {
                saveNote(currentNoteGuid, browserWindow);
+               thumbnailRunner.addWork("GENERATE "+ currentNoteGuid);
                noteDirty = false;
        }
     }
@@ -3551,8 +3912,9 @@ public class NeverNote extends QMainWindow{
                
                loadNoteBrowserInformation(browserWindow);
        }
+
        private void loadNoteBrowserInformation(BrowserWindow browser) {
-               NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
+               NoteFormatter   formatter = new NoteFormatter(logger, conn, tempFiles);
                formatter.setNote(currentNote, Global.pdfPreview());
                formatter.setHighlight(listManager.getEnSearch());
                QByteArray js;
@@ -3573,19 +3935,24 @@ public class NeverNote extends QMainWindow{
                        js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
                        browser.getBrowser().setContent(js);
                        noteCache.put(currentNoteGuid, js.toString());
+
+                       if (formatter.resourceError)
+                               resourceErrorMessage();
+                       inkNote = formatter.readOnly;
+                       if (inkNote)
+                               readOnlyCache.put(currentNoteGuid, true);
                } else {
                        logger.log(logger.HIGH, "Note content is being pulled from the cache");
                        String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(currentNoteGuid));
                        js = new QByteArray(cachedContent);
                        browser.getBrowser().setContent(js);
+                       if (readOnlyCache.containsKey(currentNoteGuid))
+                                       inkNote = true;
                }
                if (conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) {
                        thumbnailHTMLReady(currentNoteGuid, js, Global.calculateThumbnailZoom(js.toString()));
                }
 
-               if (formatter.resourceError)
-                       resourceErrorMessage();
-               inkNote = formatter.readOnly;
                
                browser.getBrowser().page().setContentEditable(!inkNote);  // We don't allow editing of ink notes
                browser.setNote(currentNote);
@@ -3884,7 +4251,11 @@ public class NeverNote extends QMainWindow{
        listManager.countNotebookResults(listManager.getNoteIndex());
        browserWindow.titleLabel.setFocus();
        browserWindow.titleLabel.selectAll();
-//     notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());    
+//     notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
+       
+       // If the window is hidden, then we want to popup this in an external window & 
+       if (!isVisible())
+               listDoubleClick();
        logger.log(logger.HIGH, "Leaving NeverNote.addNote");
     }
     // Restore a note from the trash;
@@ -3912,7 +4283,8 @@ public class NeverNote extends QMainWindow{
        browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
        find.setFocus();
     }
-    private void updateNoteTitle(String guid, String title) {
+    @SuppressWarnings("unused")
+       private void updateNoteTitle(String guid, String title) {
        listManager.setNoteSynchronized(guid, false);
     }
     // Signal received that note content has changed.  Normally we just need the guid to remove
@@ -4048,6 +4420,7 @@ public class NeverNote extends QMainWindow{
                waitCursor(false);
        }
        // View all notes
+       @SuppressWarnings("unused")
        private void allNotes() {
                clearAttributeFilter();
                clearNotebookFilter();
@@ -4181,7 +4554,6 @@ public class NeverNote extends QMainWindow{
                }
        }
        private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
-               
                logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
                logger.log(logger.HIGH, "Thumbnail ready for " +guid);
                // Find an idle preview object
@@ -4636,8 +5008,12 @@ public class NeverNote extends QMainWindow{
        }
 
        private void thumbnailTimer() {
-               if (Global.enableThumbnails())
+               if (Global.enableThumbnails() && conn.getNoteTable().getThumbnailNeededCount() > 1) {
+                       thumbnailTimer.setInterval(10*1000);
                        thumbnailRunner.addWork("SCAN");
+               } else {
+                       thumbnailTimer.setInterval(60*1000);
+               }
        }
        
        //**************************************************