OSDN Git Service

Add the ability to add & remove notebook stacks.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / NeverNote.java
index 9af637f..5e6f845 100644 (file)
@@ -112,7 +112,6 @@ import com.trolltech.qt.gui.QPalette.ColorRole;
 import com.trolltech.qt.gui.QPixmap;
 import com.trolltech.qt.gui.QPrintDialog;
 import com.trolltech.qt.gui.QPrinter;
-import com.trolltech.qt.gui.QProgressBar;
 import com.trolltech.qt.gui.QSizePolicy;
 import com.trolltech.qt.gui.QSizePolicy.Policy;
 import com.trolltech.qt.gui.QSpinBox;
@@ -140,6 +139,8 @@ import cx.fbn.nevernote.dialog.NotebookArchive;
 import cx.fbn.nevernote.dialog.NotebookEdit;
 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
 import cx.fbn.nevernote.dialog.SavedSearchEdit;
+import cx.fbn.nevernote.dialog.SetIcon;
+import cx.fbn.nevernote.dialog.StackNotebook;
 import cx.fbn.nevernote.dialog.TagEdit;
 import cx.fbn.nevernote.dialog.ThumbnailViewer;
 import cx.fbn.nevernote.dialog.WatchFolder;
@@ -154,6 +155,7 @@ import cx.fbn.nevernote.gui.TableView;
 import cx.fbn.nevernote.gui.TagTreeWidget;
 import cx.fbn.nevernote.gui.Thumbnailer;
 import cx.fbn.nevernote.gui.TrashTreeWidget;
+import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
 import cx.fbn.nevernote.sql.DatabaseConnection;
 import cx.fbn.nevernote.sql.WatchFolderRecord;
 import cx.fbn.nevernote.threads.IndexRunner;
@@ -194,15 +196,16 @@ public class NeverNote extends QMainWindow{
 
     public BrowserWindow       browserWindow;                          // Window containing browser & labels
     public QToolBar            toolBar;                                        // The tool bar under the menu
-//    QLineEdit                                searchField;                            // The search filter bar on the toolbar
     QComboBox                          searchField;                            // search filter bar on the toolbar;
     boolean                                    searchPerformed = false;        // Search was done?
-    QProgressBar                       quotaBar;                                       // The current quota usage
+    QuotaProgressBar           quotaBar;                                       // The current quota usage
     
     ApplicationLogger          logger;
     List<String>                       selectedNotebookGUIDs;          // List of notebook GUIDs
     List<String>                       selectedTagGUIDs;                       // List of selected tag GUIDs
+    String                                     previousSelectedTag;            // Tag that was selected last time
     List<String>                       selectedNoteGUIDs;                      // List of selected notes
+    String                                     previousSelectedNotebook;       // Notebook selected last time
     String                                     selectedSavedSearchGUID;        // Currently selected saved searches
     private final HashMap<String, ExternalBrowse>      externalWindows;        // Notes being edited by an external window;
     
@@ -287,7 +290,7 @@ public class NeverNote extends QMainWindow{
     int                                        historyPosition;                        // Position within the viewed items
     boolean                            fromHistory;                            // Is this from the history queue?
     String                             trashNoteGuid;                          // Guid to restore / set into or out of trash to save position
-    List<Thumbnailer>  previewList;                            // generate preview image
+    List<Thumbnailer>  thumbGenerators;                                // generate preview image
     ThumbnailViewer            thumbnailViewer;                        // View preview thumbnail; 
     boolean                            encryptOnShutdown;                      // should I encrypt when I close?
     boolean                            decryptOnShutdown;                      // should I decrypt on shutdown;
@@ -309,11 +312,11 @@ public class NeverNote extends QMainWindow{
        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);
                }
 
@@ -347,7 +350,7 @@ public class NeverNote extends QMainWindow{
                if (Global.useStandardPalette())
                        QApplication.setPalette(QApplication.style().standardPalette());
         setWindowTitle("NeverNote");
-        
+
         mainLeftRightSplitter = new QSplitter();
         setCentralWidget(mainLeftRightSplitter);
         leftSplitter1 = new QSplitter();
@@ -405,14 +408,14 @@ public class NeverNote extends QMainWindow{
                pdfReadyQueue = new ArrayList<String>();
                thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
                thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
-               thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,String)");
-//             thumbnailThread.start();
-               previewList = new ArrayList<Thumbnailer>();
+               thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
+               thumbnailThread.start();
+               thumbGenerators = new ArrayList<Thumbnailer>();
                thumbnailTimer = new QTimer();
                thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
                thumbnailTimer();
-               thumbnailTimer.setInterval(30*1000);
-//             thumbnailTimer.start();
+               thumbnailTimer.setInterval(60*1000);  // Thumbnail every minute
+               thumbnailTimer.start();
                
                logger.log(logger.EXTREME, "Starting authentication timer");
                authTimer = new QTimer();
@@ -425,7 +428,6 @@ public class NeverNote extends QMainWindow{
                saveTimer.timeout.connect(this, "saveNote()");
                if (Global.getAutoSaveInterval() > 0) {
                        saveTimer.setInterval(1000*60*Global.getAutoSaveInterval()); 
-//                     saveTimer.setInterval(1000*10); // auto save every 10 seconds;
                        saveTimer.start();
                }
                listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
@@ -439,7 +441,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();
@@ -458,19 +460,16 @@ public class NeverNote extends QMainWindow{
         noteCache = new HashMap<String,String>();
         browserWindow = new BrowserWindow(conn);
 
+        mainLeftRightSplitter.addWidget(leftSplitter1);
+        mainLeftRightSplitter.addWidget(browserIndexSplitter);
+        
         if (Global.getListView() == Global.View_List_Wide) {
                browserIndexSplitter.addWidget(noteTableView);
                browserIndexSplitter.addWidget(browserWindow); 
-        }
-        
-        mainLeftRightSplitter.addWidget(leftSplitter1);
-        mainLeftRightSplitter.addWidget(browserIndexSplitter);
-
-        if (Global.getListView() == Global.View_List_Narrow) {
+        } else {
                mainLeftRightSplitter.addWidget(noteTableView);
                mainLeftRightSplitter.addWidget(browserWindow); 
         }
-
         
         searchField = new QComboBox();
         searchField.setEditable(true);
@@ -478,7 +477,7 @@ public class NeverNote extends QMainWindow{
        searchField.setDuplicatesEnabled(false);
        searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
         
-       quotaBar = new QProgressBar();
+       quotaBar = new QuotaProgressBar();
        
        // Setup the thumbnail viewer
        thumbnailViewer = new ThumbnailViewer();
@@ -507,6 +506,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"));
@@ -515,6 +515,8 @@ 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.setVisible(Global.isWindowVisible("notebookTree"));
                notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
                menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
@@ -522,6 +524,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"));
@@ -537,6 +540,9 @@ public class NeverNote extends QMainWindow{
                noteTableView.resetViewport.connect(this, "scrollToCurrentGuid()");
                noteTableView.doubleClicked.connect(this, "listDoubleClick()");
                listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
+               
+               quotaBar.setMouseClickAction(menuBar.accountAction);
+               
                trashTree.load();
         trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
                trashTree.setEmptyAction(menuBar.emptyTrashAction);
@@ -625,7 +631,7 @@ public class NeverNote extends QMainWindow{
        setupFolderImports();
        
        loadStyleSheet();
-       restoreWindowState();
+       restoreWindowState(true);
        
        if (Global.mimicEvernoteInterface) {
                notebookTree.selectGuid("");
@@ -640,29 +646,25 @@ public class NeverNote extends QMainWindow{
        
         if (Global.getListView() == Global.View_List_Narrow) { 
                menuBar.narrowListView.setChecked(true);
-               narrowListView();
+//             narrowListView();
         }
         else{ 
                menuBar.wideListView.setChecked(true);
-               wideListView();
+//             wideListView();
         }
 
-       
+        if (Global.getListView() == Global.View_List_Wide) {
+               browserIndexSplitter.addWidget(noteTableView);
+               browserIndexSplitter.addWidget(browserWindow); 
+        } else {
+               mainLeftRightSplitter.addWidget(noteTableView);
+               mainLeftRightSplitter.addWidget(browserWindow); 
+        }
+        
        int sortCol = Global.getSortColumn();
                int sortOrder = Global.getSortOrder();
                noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
 
-               /*
-               for (int i=0; i<listManager.getNoteIndex().size(); i++) {
-                       Note n = listManager.getNoteIndex().get(i);
-                       if (n.getNotebookGuid().equalsIgnoreCase("2")) {
-                               conn.getNoteTable().updateNoteSequence(n.getGuid(), 0);
-                               n = conn.getNoteTable().getNote(n.getGuid(), false, true, false, false, true);
-                               for (int j=0; j<n.getResourcesSize(); j++) {
-                                       conn.getNoteTable().noteResourceTable.resetUpdateSequenceNumber(n.getResources().get(j).getGuid(), true);       
-                               }
-                       }
-               } */
        }
 
        
@@ -895,32 +897,9 @@ public class NeverNote extends QMainWindow{
         syncRunner.notebookSignal.listChanged.disconnect();
         syncRunner.noteIndexSignal.listChanged.disconnect();
 
-
-               int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
-               Global.setColumnPosition("noteTableCreationPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
-               Global.setColumnPosition("noteTableTagPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
-               Global.setColumnPosition("noteTableNotebookPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
-               Global.setColumnPosition("noteTableChangedPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
-               Global.setColumnPosition("noteTableAuthorPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
-               Global.setColumnPosition("noteTableSourceUrlPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
-               Global.setColumnPosition("noteTableSubjectDatePosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
-               Global.setColumnPosition("noteTableTitlePosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
-               Global.setColumnPosition("noteTableSynchronizedPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
-               Global.setColumnPosition("noteTableGuidPosition", position);
-               position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
-               Global.setColumnPosition("noteTableThumbnailPosition", position);
-
                if (isVisible())
                        Global.saveWindowVisible("toolBar", toolBar.isVisible());
+               saveNoteColumnPositions();
                saveNoteIndexWidth();
                
                int width = notebookTree.columnWidth(0);
@@ -1035,7 +1014,9 @@ public class NeverNote extends QMainWindow{
        @SuppressWarnings("unused")
        private void settings() {
                logger.log(logger.HIGH, "Entering NeverNote.settings");
+               saveNoteColumnPositions();
                saveNoteIndexWidth();
+               showColumns();
         ConfigDialog settings = new ConfigDialog(this);
         String dateFormat = Global.getDateFormat();
         String timeFormat = Global.getTimeFormat();
@@ -1068,7 +1049,7 @@ public class NeverNote extends QMainWindow{
         logger.log(logger.HIGH, "Leaving NeverNote.settings");
        }
        // Restore things to the way they were
-       private void restoreWindowState() {
+       private void restoreWindowState(boolean mainWindow) {
                // We need to name things or this doesn't work.
                setObjectName("NeverNote");
                mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
@@ -1076,7 +1057,8 @@ public class NeverNote extends QMainWindow{
                leftSplitter1.setObjectName("leftSplitter1");   
                
                // Restore the actual positions.
-               restoreGeometry(Global.restoreGeometry(objectName()));
+               if (mainWindow)
+                       restoreGeometry(Global.restoreGeometry(objectName()));
         mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
         browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
         leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
@@ -1098,6 +1080,32 @@ public class NeverNote extends QMainWindow{
                file.close();
                setStyleSheet(styleSheet);
        }
+       // Save column positions for the next time
+       private void saveNoteColumnPositions() {
+               int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
+               Global.setColumnPosition("noteTableCreationPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
+               Global.setColumnPosition("noteTableTagPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
+               Global.setColumnPosition("noteTableNotebookPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
+               Global.setColumnPosition("noteTableChangedPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
+               Global.setColumnPosition("noteTableAuthorPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
+               Global.setColumnPosition("noteTableSourceUrlPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
+               Global.setColumnPosition("noteTableSubjectDatePosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
+               Global.setColumnPosition("noteTableTitlePosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
+               Global.setColumnPosition("noteTableSynchronizedPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
+               Global.setColumnPosition("noteTableGuidPosition", position);
+               position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
+               Global.setColumnPosition("noteTableThumbnailPosition", position);
+
+       }
        // Save column widths for the next time
        private void saveNoteIndexWidth() {
                int width;
@@ -1136,9 +1144,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
@@ -1155,13 +1162,24 @@ public class NeverNote extends QMainWindow{
                menuBar.noteRestoreAction.setVisible(false);            
        menuBar.notebookEditAction.setEnabled(true);
        menuBar.notebookDeleteAction.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());
+                               }
+                       }
                }
        
                
@@ -1173,13 +1191,39 @@ 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);
+                       previousSelectedNotebook = "";
+                       notebookTree.clearSelection();
+                       notebookTreeSelection();
+                       return;
+               }
+               if (selectedNotebookGUIDs.size() == 1)
+                       previousSelectedNotebook = selectedNotebookGUIDs.get(0);
+               if (selectedNotebookGUIDs.size() > 1) 
+                       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(false);
+                               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();
@@ -1200,7 +1244,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--) {
@@ -1271,29 +1320,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());
                
@@ -1330,6 +1439,8 @@ public class NeverNote extends QMainWindow{
        @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();
@@ -1337,13 +1448,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) {
@@ -1358,7 +1474,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;
@@ -1369,16 +1496,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
@@ -1469,9 +1598,47 @@ public class NeverNote extends QMainWindow{
                waitCursor(false);
                browserWindow.setNotebookList(nbooks);
        }
+       // Change the notebook's icon
+       private void setNotebookIcon() {
+               QTreeWidgetItem currentSelection;
+               List<QTreeWidgetItem> selections = notebookTree.selectedItems();
+               if (selections.size() == 0)
+                       return;
+               
+               currentSelection = selections.get(0);   
+               String guid = currentSelection.text(2);
+               if (guid.equalsIgnoreCase(""))
+                       return;
 
+               QIcon currentIcon = currentSelection.icon(0);
+               QIcon icon = conn.getNotebookTable().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.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);
+               }
        
-       
+       }
        
        
     //***************************************************************
@@ -1500,13 +1667,16 @@ public class NeverNote extends QMainWindow{
                newTag.setName(edit.getTag());
                conn.getTagTable().addTag(newTag, true);
                listManager.getTagIndex().add(newTag);
-               reloadTagTree();
+               reloadTagTree(true);
                
                logger.log(logger.HIGH, "Leaving NeverNote.addTag");
        }
        private void reloadTagTree() {
+               reloadTagTree(false);
+       }
+       private void reloadTagTree(boolean reload) {
                logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
-               tagIndexUpdated(false);
+               tagIndexUpdated(reload);
                boolean filter = false;
                listManager.countTagResults(listManager.getNoteIndex());
                if (notebookTree.selectedItems().size() > 0 
@@ -1595,7 +1765,8 @@ public class NeverNote extends QMainWindow{
        // Setup the tree containing the user's tags
     private void initializeTagTree() {
        logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
-       tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
+//     tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
+       tagTree.itemClicked.connect(this, "tagTreeSelection()");
        listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
        logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
     }
@@ -1619,11 +1790,24 @@ 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);
+               previousSelectedTag = "";
+               tagTree.clearSelection();
+               tagTreeSelection();
+               return;
+       }
+       if (selectedTagGUIDs.size() == 1)
+               previousSelectedTag = selectedTagGUIDs.get(0);
+       if (selectedTagGUIDs.size() > 1) 
+               previousSelectedTag = "";
        listManager.setSelectedTags(selectedTagGUIDs);
        listManager.loadNotesIndex();
        noteIndexUpdated(false);
@@ -1641,8 +1825,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)
@@ -1763,11 +1949,42 @@ 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
+       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);
+               }
        
+       }
+
        
     //***************************************************************
     //***************************************************************
@@ -1883,6 +2100,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 = "";
@@ -1909,6 +2127,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);
@@ -1922,6 +2141,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);
@@ -1933,17 +2153,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("");
        }
@@ -1965,6 +2188,36 @@ public class NeverNote extends QMainWindow{
                Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
        logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
     }
+       // Change the icon for a saved search
+       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);
+               }
+       
+       }
        
        
        
@@ -2103,6 +2356,7 @@ public class NeverNote extends QMainWindow{
        // Text in the search bar has been cleared
        private void searchFieldCleared() {
                searchField.setEditText("");
+               saveNoteColumnPositions();
                saveNoteIndexWidth();
        }
        // text in the search bar changed.  We only use this to tell if it was cleared, 
@@ -2127,6 +2381,7 @@ public class NeverNote extends QMainWindow{
     private void searchFieldChanged() {
        logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
        noteCache.clear();
+       saveNoteColumnPositions();
        saveNoteIndexWidth();
        String text = searchField.currentText();
        listManager.setEnSearch(text.trim());
@@ -2216,7 +2471,7 @@ public class NeverNote extends QMainWindow{
        toggleNewButton(Global.isToolbarButtonVisible("new"));
        
        allNotesButton = toolBar.addAction("All Notes");
-       QIcon allIcon = new QIcon(iconPath+"allNotes3.png");
+       QIcon allIcon = new QIcon(iconPath+"books.png");
        allNotesButton.triggered.connect(this, "allNotes()");
        allNotesButton.setIcon(allIcon);
        toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
@@ -2889,10 +3144,11 @@ public class NeverNote extends QMainWindow{
                if (currentNoteGuid == null) 
                        currentNoteGuid = new String();
                
+               //determine current note guid
                for (Note note : listManager.getNoteIndex()) {
                        tempNoteGuid = note.getGuid();
                        if (currentNoteGuid.equals(tempNoteGuid)) {
-                               saveCurrentNoteGuid = new String(tempNoteGuid);
+                               saveCurrentNoteGuid = tempNoteGuid;
                        }
                }
                
@@ -2903,14 +3159,15 @@ public class NeverNote extends QMainWindow{
                        browserWindow.setDisabled(true);
                } 
                
-               if (saveCurrentNoteGuid.equals("") && listManager.getNoteIndex().size() >0) {
-                       currentNoteGuid = listManager.getNoteIndex().get(listManager.getNoteIndex().size()-1).getGuid();
+               if (saveCurrentNoteGuid.equals("") && listManager.getNoteIndex().size() > 0) {
                        currentNote = listManager.getNoteIndex().get(listManager.getNoteIndex().size()-1);
+                       currentNoteGuid = currentNote.getGuid();
                        refreshEvernoteNote(true);
                } else {
-                       refreshEvernoteNote(false);
+                       //we can reload if note not dirty
+                       refreshEvernoteNote(!noteDirty);
                }
-               reloadTagTree();
+               reloadTagTree(false);
 
                logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
        } 
@@ -3238,6 +3495,7 @@ public class NeverNote extends QMainWindow{
                                i=listManager.getNoteTableModel().rowCount();
                }
        }
+       noteTableView.repaint();
     }
     // Show/Hide columns
     private void showColumns() {
@@ -3251,6 +3509,7 @@ public class NeverNote extends QMainWindow{
                noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
                noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
                noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
+               noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));                 
     }
     // Title color has changed
     @SuppressWarnings("unused")
@@ -3288,10 +3547,11 @@ public class NeverNote extends QMainWindow{
     }
     // Wide list was chosen
     public void narrowListView() {
-       if (!menuBar.narrowListView.isChecked()) {
-               wideListView();
-               return;
-       }
+       saveNoteColumnPositions();
+       saveNoteIndexWidth();
+       saveWindowState();
+       Global.setListView(Global.View_List_Narrow);
+       
        menuBar.wideListView.blockSignals(true);
        menuBar.narrowListView.blockSignals(true);
        
@@ -3300,17 +3560,23 @@ public class NeverNote extends QMainWindow{
        
        menuBar.wideListView.blockSignals(false);
        menuBar.narrowListView.blockSignals(false);
-//     browserIndexSplitter.setVisible(false);
        
-       Global.setListView(Global.View_List_Narrow);
        mainLeftRightSplitter.addWidget(noteTableView);
        mainLeftRightSplitter.addWidget(browserWindow);
+       restoreWindowState(false);
+       noteTableView.repositionColumns();
+       noteTableView.resizeColumnWidths();
+       noteTableView.resizeRowHeights();
+       showColumns();
+       noteTableView.load(false);
+       scrollToCurrentGuid();
     }
     public void wideListView() {
-       if (!menuBar.wideListView.isChecked()) {
-               narrowListView();
-               return;
-       }
+       saveWindowState();
+       saveNoteColumnPositions();
+       saveNoteIndexWidth();
+       Global.setListView(Global.View_List_Wide);
+
        menuBar.wideListView.blockSignals(true);
        menuBar.narrowListView.blockSignals(true);
        
@@ -3320,10 +3586,15 @@ public class NeverNote extends QMainWindow{
        menuBar.wideListView.blockSignals(false);
        menuBar.narrowListView.blockSignals(false);
        browserIndexSplitter.setVisible(true);
-       Global.setListView(Global.View_List_Wide);
-//     browserIndexSplitter.setVisible(true);
         browserIndexSplitter.addWidget(noteTableView);
         browserIndexSplitter.addWidget(browserWindow);
+        restoreWindowState(false);
+       noteTableView.repositionColumns();
+       noteTableView.resizeColumnWidths();
+       noteTableView.resizeRowHeights();
+       showColumns();
+       noteTableView.load(false);
+       scrollToCurrentGuid();
     }
     
     
@@ -3339,7 +3610,6 @@ public class NeverNote extends QMainWindow{
                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);
@@ -3439,6 +3709,7 @@ public class NeverNote extends QMainWindow{
                browserWindow.getBrowser().setContent(unicode);
        } 
        if (save) {
+               thumbnailRunner.addWork("GENERATE "+ guid);
                saveNote(guid, browser);
        }
        
@@ -3446,6 +3717,7 @@ public class NeverNote extends QMainWindow{
     private void saveNote() {
        if (noteDirty) {
                saveNote(currentNoteGuid, browserWindow);
+               thumbnailRunner.addWork("GENERATE "+ currentNoteGuid);
                noteDirty = false;
        }
     }
@@ -3491,6 +3763,7 @@ public class NeverNote extends QMainWindow{
                        browserWindow.setReadOnly(true);
                        return;
                }
+               
                if (!reload)
                        return;
                
@@ -3503,12 +3776,14 @@ public class NeverNote extends QMainWindow{
                
                loadNoteBrowserInformation(browserWindow);
        }
+
        private void loadNoteBrowserInformation(BrowserWindow browser) {
                NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
                formatter.setNote(currentNote, Global.pdfPreview());
                formatter.setHighlight(listManager.getEnSearch());
+               QByteArray js;
                if (!noteCache.containsKey(currentNoteGuid) || conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) {
-                       QByteArray js = new QByteArray();
+                       js = new QByteArray();
                        // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly 
                        js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");               
                        js.append("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>");
@@ -3524,13 +3799,14 @@ public class NeverNote extends QMainWindow{
                        js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
                        browser.getBrowser().setContent(js);
                        noteCache.put(currentNoteGuid, js.toString());
-                       if (conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) {
-                               thumbnailRunner.addWork("GENERATE " +currentNoteGuid);
-                       }
                } else {
                        logger.log(logger.HIGH, "Note content is being pulled from the cache");
                        String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(currentNoteGuid));
-                       browser.getBrowser().setContent(new QByteArray(cachedContent));
+                       js = new QByteArray(cachedContent);
+                       browser.getBrowser().setContent(js);
+               }
+               if (conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) {
+                       thumbnailHTMLReady(currentNoteGuid, js, Global.calculateThumbnailZoom(js.toString()));
                }
 
                if (formatter.resourceError)
@@ -3834,7 +4110,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;
@@ -4130,22 +4410,35 @@ public class NeverNote extends QMainWindow{
                        QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
                }
        }
-       private void thumbnailHTMLReady(String guid,String file) {
-               Thumbnailer preview = null;
+       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
-               for (int i=0; i<previewList.size(); i++) {
-                       if (previewList.get(i).idle) {
-                               preview = previewList.get(i);
-                               i=previewList.size();
+               for (int i=0; i<thumbGenerators.size(); i++) {
+                       if (thumbGenerators.get(i).mutex.tryLock()) {
+                               logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
+                               thumbGenerators.get(i).loadContent(guid, html, zoom);
+                               return;
                        }
                } 
-               if (preview == null) {
-                       preview = new Thumbnailer(conn, listManager);
-                       previewList.add(preview);
+               if (thumbGenerators.size() >= 1) {
+                       logger.log(logger.EXTREME, "No available thumbnail generators.  Aborting " +guid);
+                       return;
+               }
+               
+               logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
+               Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
+               thumbGenerators.add(preview);
+
+               if (preview.mutex.tryLock()) {
+                       logger.log(logger.EXTREME, "Loading thumbnail for  " +guid);
+                       preview.loadContent(guid, html, zoom);
                }
-               preview.loadContent(guid, file);
+               logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
        }
        
+       
+       
        //**********************************************************
     //**********************************************************
     //* Online user actions
@@ -4223,7 +4516,7 @@ public class NeverNote extends QMainWindow{
                int usn = 0;
                
                for (int i=0; i<versions.size(); i++) {
-                       StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getServiceUpdated()));
+                       StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
                        if (versionDate.toString().equals(selection))
                                index = i;
                }
@@ -4340,6 +4633,7 @@ public class NeverNote extends QMainWindow{
                        
                        if (syncThreadsReady > 0) {
                                saveNoteIndexWidth();
+                               saveNoteColumnPositions();
                                if (syncRunner.addWork("SYNC")) {
                                        syncRunning = true;
                                        syncRunner.syncNeeded = true;
@@ -4571,7 +4865,12 @@ public class NeverNote extends QMainWindow{
        }
 
        private void thumbnailTimer() {
-               thumbnailRunner.addWork("SCAN");
+               if (Global.enableThumbnails() && conn.getNoteTable().getThumbnailNeededCount() > 1) {
+                       thumbnailTimer.setInterval(10*1000);
+                       thumbnailRunner.addWork("SCAN");
+               } else {
+                       thumbnailTimer.setInterval(60*1000);
+               }
        }
        
        //**************************************************