OSDN Git Service

Add interrupt to index thread in case it becomes hung.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / NeverNote.java
index bc58d73..988ae34 100644 (file)
@@ -128,6 +128,9 @@ import com.trolltech.qt.gui.QTableWidgetItem;
 import com.trolltech.qt.gui.QTextEdit;
 import com.trolltech.qt.gui.QToolBar;
 import com.trolltech.qt.gui.QTreeWidgetItem;
+import com.trolltech.qt.network.QNetworkAccessManager;
+import com.trolltech.qt.network.QNetworkReply;
+import com.trolltech.qt.network.QNetworkRequest;
 import com.trolltech.qt.webkit.QWebPage.WebAction;
 import com.trolltech.qt.webkit.QWebSettings;
 
@@ -139,6 +142,7 @@ import cx.fbn.nevernote.dialog.DBEncryptDialog;
 import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
 import cx.fbn.nevernote.dialog.DatabaseStatus;
 import cx.fbn.nevernote.dialog.FindDialog;
+import cx.fbn.nevernote.dialog.IgnoreSync;
 import cx.fbn.nevernote.dialog.LoginDialog;
 import cx.fbn.nevernote.dialog.NotebookArchive;
 import cx.fbn.nevernote.dialog.NotebookEdit;
@@ -150,6 +154,7 @@ 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.UpgradeAvailableDialog;
 import cx.fbn.nevernote.dialog.WatchFolder;
 import cx.fbn.nevernote.filters.FilterEditorNotebooks;
 import cx.fbn.nevernote.filters.FilterEditorTags;
@@ -195,6 +200,7 @@ public class NeverNote extends QMainWindow{
        QAction                                 trayExitAction;                         // Exit the application
        QAction                                 trayShowAction;                         // toggle the show/hide action          
        QAction                                 trayAddNoteAction;                      // Add a note from the system tray
+       QNetworkAccessManager   versionChecker;                         // Used when checking for new versions
        
     NotebookTreeWidget                 notebookTree;                           // List of notebooks
     AttributeTreeWidget                attributeTree;                          // List of note attributes
@@ -212,9 +218,7 @@ public class NeverNote extends QMainWindow{
     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;
     
@@ -314,6 +318,7 @@ public class NeverNote extends QMainWindow{
     List<QPixmap>              syncIcons;                                      // Array of icons used in sync animation
     private boolean            closeAction = false;            // Used to say when to close or when to minimize
     private static Logger log = Logger.getLogger(NeverNote.class); 
+    private String             saveLastPath;                           // last path we used
     
     
     String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
@@ -668,14 +673,18 @@ public class NeverNote extends QMainWindow{
        historyGuids.add(currentNoteGuid);
        historyPosition = 1;
        
+       menuBar.blockSignals(true);
+       menuBar.narrowListView.blockSignals(true);
+       menuBar.wideListView.blockSignals(true);
         if (Global.getListView() == Global.View_List_Narrow) { 
                menuBar.narrowListView.setChecked(true);
-//             narrowListView();
         }
         else{ 
                menuBar.wideListView.setChecked(true);
-//             wideListView();
         }
+        menuBar.blockSignals(false);
+       menuBar.narrowListView.blockSignals(false);
+       menuBar.wideListView.blockSignals(false);
 
         if (Global.getListView() == Global.View_List_Wide) {
                browserIndexSplitter.addWidget(noteTableView);
@@ -688,10 +697,10 @@ public class NeverNote extends QMainWindow{
        int sortCol = Global.getSortColumn();
                int sortOrder = Global.getSortOrder();
                noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
-
+               if (Global.checkVersionUpgrade())
+                       checkForUpdates();
        }
-
-       
+               
        // Main entry point
        public static void main(String[] args) {
                log.setLevel(Level.FATAL);
@@ -950,8 +959,14 @@ public class NeverNote extends QMainWindow{
                Global.keepRunning = false;
                try {
                        logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
-                       indexRunner.thread().join(50);
-                       logger.log(logger.MEDIUM, "Index thread has stopped");
+                       if (indexRunner.thread().isAlive())
+                               indexRunner.thread().join(50);
+                       if (!indexRunner.thread().isAlive())
+                               logger.log(logger.MEDIUM, "Index thread has stopped");
+                       else {
+                               logger.log(logger.MEDIUM, "Index thread still running - interrupting");
+                               indexRunner.thread().interrupt();
+                       }
                } catch (InterruptedException e1) {
                        e1.printStackTrace();
                }
@@ -1116,8 +1131,15 @@ public class NeverNote extends QMainWindow{
        }    
        // Load the style sheet
        private void loadStyleSheet() {
-               String fileName = Global.getFileManager().getQssDirPath("default.qss");
+               String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
+               fileName = Global.getFileManager().getQssDirPath("default.qss");
                QFile file = new QFile(fileName);
+               
+               // If a user default.qss doesn't exist, we use the one shipped with NeverNote
+               if (!file.exists()) {
+                       fileName = Global.getFileManager().getQssDirPath("default.qss");
+                       file = new QFile(fileName);
+               }
                file.open(OpenModeFlag.ReadOnly);
                String styleSheet = file.readAll().toString();
                file.close();
@@ -1187,7 +1209,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.itemClicked.connect(this, "notebookTreeSelection()");
+//     notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
+       notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
        listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
        logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
     }   
@@ -1210,65 +1233,36 @@ public class NeverNote extends QMainWindow{
        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);
-                       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());
-                               }
-                       }
-               }
-       
-               
-               // There is the potential for no notebooks to be selected if this 
-               // happens then we make it look like all notebooks were selecetd.
-               // If that happens, just select the "all notebooks"
-               selections = notebookTree.selectedItems();
-               if (selections.size()==0) {
-                       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 = "";
+               String guid = "";
+               String stackName = "";
+               if (selections.size() > 0) {
+               guid = (selections.get(0).text(2));
+               stackName = selections.get(0).text(0);
+       }
+               if (!Global.mimicEvernoteInterface) {
+                       // If no notebooks are selected, we make it look like the "all notebooks" one was selected
+                       if (selections.size()==0) {
+                               selectedNotebookGUIDs.clear();
+                               for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
+                                       selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
+                               }
+                               menuBar.notebookEditAction.setEnabled(false);
+                               menuBar.notebookDeleteAction.setEnabled(false);
+                               menuBar.notebookStackAction.setEnabled(false);
+                               menuBar.notebookIconAction.setEnabled(false);
+                       }
+               }
+       if (!guid.equals("") && !guid.equals("STACK")) {
+               selectedNotebookGUIDs.add(guid);
+               menuBar.notebookIconAction.setEnabled(true);
        } else {
-               String guid = "";
-               String stackName = "";
-               if (selections.size() > 0) {
-                       guid = (selections.get(0).text(2));
-                       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());
-                               }
-               }
+               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();
@@ -1482,7 +1476,13 @@ public class NeverNote extends QMainWindow{
                                nbooks.add(listManager.getNotebookIndex().get(i));
                }
                
-               browserWindow.setNotebookList(nbooks);
+               
+               FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
+               List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
+               browserWindow.setNotebookList(filteredBooks);
+               Iterator<String> set = externalWindows.keySet().iterator();
+               while(set.hasNext())
+                       externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
                logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
        }
        // Publish a notebook
@@ -1619,9 +1619,10 @@ public class NeverNote extends QMainWindow{
                }
         }
 
-        notebookTreeSelection();
-        notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
-        listManager.countNotebookResults(listManager.getNoteIndex());
+               notebookIndexUpdated();
+//        notebookTreeSelection();
+//        notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
+//        listManager.countNotebookResults(listManager.getNoteIndex());
         logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
        }
        // A note's notebook has been updated
@@ -1710,8 +1711,17 @@ public class NeverNote extends QMainWindow{
                        if (!found)
                                nbooks.add(listManager.getNotebookIndex().get(i));
                }
+               
+               FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
+               List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
+               browserWindow.setNotebookList(filteredBooks);
+               
+               // Update any external windows
+               Iterator<String> set = externalWindows.keySet().iterator();
+               while(set.hasNext())
+                       externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
+               
                waitCursor(false);
-               browserWindow.setNotebookList(nbooks);
        }
        // Change the notebook's icon
        @SuppressWarnings("unused")
@@ -1738,10 +1748,10 @@ public class NeverNote extends QMainWindow{
                if (!stackSelected && !allNotebookSelected) {
                        icon = conn.getNotebookTable().getIcon(guid);
                        if (icon == null) {
-                               dialog = new SetIcon(currentIcon);
+                               dialog = new SetIcon(currentIcon, saveLastPath);
                                dialog.setUseDefaultIcon(true);
                        } else {
-                               dialog = new SetIcon(icon);
+                               dialog = new SetIcon(icon, saveLastPath);
                                dialog.setUseDefaultIcon(false);
                        }
                } else {
@@ -1751,15 +1761,17 @@ public class NeverNote extends QMainWindow{
                                icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");                              
                        }
                        if (icon == null) {
-                               dialog = new SetIcon(currentIcon);
+                               dialog = new SetIcon(currentIcon, saveLastPath);
                                dialog.setUseDefaultIcon(true);
                        } else {
-                               dialog = new SetIcon(icon);
+                               dialog = new SetIcon(icon, saveLastPath);
                                dialog.setUseDefaultIcon(false);
                        }
                }
                dialog.exec();
                if (dialog.okPressed()) {
+               saveLastPath = dialog.getPath();
+
                        QIcon newIcon = dialog.getIcon();
                        if (stackSelected) {
                                conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
@@ -1921,7 +1933,8 @@ public class NeverNote extends QMainWindow{
     private void initializeTagTree() {
        logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
 //     tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
-       tagTree.itemClicked.connect(this, "tagTreeSelection()");
+//     tagTree.itemClicked.connect(this, "tagTreeSelection()");
+       tagTree.selectionSignal.connect(this, "tagTreeSelection()");
        listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
        logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
     }
@@ -1952,17 +1965,6 @@ public class NeverNote extends QMainWindow{
                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);
@@ -2125,14 +2127,15 @@ public class NeverNote extends QMainWindow{
                QIcon icon = conn.getTagTable().getIcon(guid);
                SetIcon dialog;
                if (icon == null) {
-                       dialog = new SetIcon(currentIcon);
+                       dialog = new SetIcon(currentIcon, saveLastPath);
                        dialog.setUseDefaultIcon(true);
                } else {
-                       dialog = new SetIcon(icon);
+                       dialog = new SetIcon(icon, saveLastPath);
                        dialog.setUseDefaultIcon(false);
                }
                dialog.exec();
                if (dialog.okPressed()) {
+               saveLastPath = dialog.getPath();
                        QIcon newIcon = dialog.getIcon();
                        conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
                        if (newIcon == null) 
@@ -2360,14 +2363,15 @@ public class NeverNote extends QMainWindow{
                QIcon icon = conn.getSavedSearchTable().getIcon(guid);
                SetIcon dialog;
                if (icon == null) {
-                       dialog = new SetIcon(currentIcon);
+                       dialog = new SetIcon(currentIcon, saveLastPath);
                        dialog.setUseDefaultIcon(true);
                } else {
-                       dialog = new SetIcon(icon);
+                       dialog = new SetIcon(icon, saveLastPath);
                        dialog.setUseDefaultIcon(false);
                }
                dialog.exec();
                if (dialog.okPressed()) {
+               saveLastPath = dialog.getPath();
                        QIcon newIcon = dialog.getIcon();
                        conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
                        if (newIcon == null) 
@@ -2505,7 +2509,74 @@ public class NeverNote extends QMainWindow{
                Global.saveWindowVisible("leftPanel", hidden);
                
        }
+       public void checkForUpdates() {
+               // Send off thread to check for a new version
+               versionChecker = new QNetworkAccessManager(this);
+               versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
+               QNetworkRequest request = new QNetworkRequest();
+               request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
+               versionChecker.get(request);
+       }
+       @SuppressWarnings("unused")
+       private void upgradeFileRead(QNetworkReply reply) {
+               if (!reply.isReadable())
+                       return;
+               
+               String winVersion = Global.version;
+               String osxVersion = Global.version;
+               String linuxVersion = Global.version;
+               String linux64Version = Global.version;
+               String version = Global.version;
+               
+               // Determine the versions available
+               QByteArray data = reply.readLine();
+               while (data != null && !reply.atEnd()) {
+                       String line = data.toString();
+                       String lineVersion;
+                       if (line.contains(":")) 
+                               lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
+                       else
+                               lineVersion = "";
+                       if (line.toLowerCase().contains("windows")) 
+                               winVersion = lineVersion;
+                       else if (line.toLowerCase().contains("os-x")) 
+                               osxVersion = lineVersion;
+                       else if (line.toLowerCase().contains("linux amd64")) 
+                               linux64Version = lineVersion;
+                       else if (line.toLowerCase().contains("linux i386")) 
+                               linuxVersion = lineVersion;
+                       else if (line.toLowerCase().contains("default")) 
+                               version = lineVersion;
                        
+                       // Read the next line
+                       data = reply.readLine();
+               }
+               
+               // Now we need to determine what system we are on.
+               if (System.getProperty("os.name").toLowerCase().contains("windows"))
+                       version = winVersion;
+               if (System.getProperty("os.name").toLowerCase().contains("mac os"))
+                       version = osxVersion;
+               if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
+                       if (System.getProperty("os.arch").contains("amd64") ||
+                               System.getProperty("os.arch").contains("x86_64"))
+                                       version = linux64Version;
+                       else
+                               version = linuxVersion;
+               }
+               
+               
+               if (Global.version.equals(version))
+                       return;
+               
+               UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
+               dialog.exec();
+               if (dialog.remindMe())
+                       Global.setCheckVersionUpgrade(true);
+               else
+                       Global.setCheckVersionUpgrade(false);
+       }
+               
        
     //***************************************************************
     //***************************************************************
@@ -2539,6 +2610,9 @@ public class NeverNote extends QMainWindow{
        // otherwise we trigger off searchFieldChanged.
        @SuppressWarnings("unused")
        private void searchFieldTextChanged(String text) {
+               QWebSettings.setMaximumPagesInCache(0);
+               QWebSettings.setObjectCacheCapacities(0, 0, 0);
+
                if (text.trim().equals("")) {
                        searchFieldCleared();
                        if (searchPerformed) {
@@ -2548,8 +2622,6 @@ public class NeverNote extends QMainWindow{
                                noteCache.clear();
                                readOnlyCache.clear();
                                inkNoteCache.clear();
-                               QWebSettings.setMaximumPagesInCache(0);
-                               QWebSettings.setObjectCacheCapacities(0, 0, 0);
                                
                                listManager.setEnSearch("");
                                listManager.loadNotesIndex();
@@ -3018,6 +3090,7 @@ public class NeverNote extends QMainWindow{
                menuBar.connectAction.setText(tr("Connect"));
                menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
                menuBar.synchronizeAction.setEnabled(false);
+               Global.isConnected = false;
                synchronizeAnimationTimer.stop();
                return;
        }
@@ -3298,6 +3371,22 @@ public class NeverNote extends QMainWindow{
        refreshEvernoteNoteList();
        logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
        noteTableView.load(reload);
+       if (currentNoteGuid == null || currentNoteGuid.equals("")) {
+               int pos;
+               if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
+                       pos = noteTableView.proxyModel.rowCount();
+               else 
+                       pos = 1;
+               if (noteTableView.proxyModel.rowCount() == 0)
+                       pos = 0;
+               if (pos>0)      {
+                       QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
+                       if (i!=null) {
+                               currentNoteGuid = (String)i.data();
+                               noteTableView.selectRow(pos-1);
+                       }
+               }
+       }               
        scrollToGuid(currentNoteGuid);
                logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
     }
@@ -3335,14 +3424,10 @@ public class NeverNote extends QMainWindow{
                        browserWindow.setDisabled(true);
                } 
                
-               if (saveCurrentNoteGuid.equals("") && listManager.getNoteIndex().size() > 0) {
-                       currentNote = listManager.getNoteIndex().get(listManager.getNoteIndex().size()-1);
-                       currentNoteGuid = currentNote.getGuid();
-                       refreshEvernoteNote(true);
-               } else {
-                       //we can reload if note not dirty
-//                     refreshEvernoteNote(!noteDirty);
+               if (!saveCurrentNoteGuid.equals("")) {
                        refreshEvernoteNote(false);
+               } else {
+                       currentNoteGuid = "";
                }
                reloadTagTree(false);
 
@@ -3726,7 +3811,12 @@ public class NeverNote extends QMainWindow{
        saveNoteColumnPositions();
        saveNoteIndexWidth();
        saveWindowState();
-       Global.setListView(Global.View_List_Narrow);
+               int sortCol = noteTableView.proxyModel.sortColumn();
+               int sortOrder = noteTableView.proxyModel.sortOrder().value();
+               Global.setSortColumn(sortCol);
+               Global.setSortOrder(sortOrder);
+
+               Global.setListView(Global.View_List_Narrow);
        
        menuBar.wideListView.blockSignals(true);
        menuBar.narrowListView.blockSignals(true);
@@ -3743,12 +3833,22 @@ public class NeverNote extends QMainWindow{
        noteTableView.repositionColumns();
        noteTableView.resizeColumnWidths();
        noteTableView.resizeRowHeights();
+       
+       sortCol = Global.getSortColumn();
+               sortOrder = Global.getSortOrder();
+               noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
+               
        showColumns();
        noteTableView.load(false);
        scrollToCurrentGuid();
     }
     public void wideListView() {
-       saveWindowState();
+               int sortCol = noteTableView.proxyModel.sortColumn();
+               int sortOrder = noteTableView.proxyModel.sortOrder().value();
+               Global.setSortColumn(sortCol);
+               Global.setSortOrder(sortOrder);
+
+               saveWindowState();
        saveNoteColumnPositions();
        saveNoteIndexWidth();
        Global.setListView(Global.View_List_Wide);
@@ -3768,6 +3868,11 @@ public class NeverNote extends QMainWindow{
        noteTableView.repositionColumns();
        noteTableView.resizeColumnWidths();
        noteTableView.resizeRowHeights();
+       
+       sortCol = Global.getSortColumn();
+               sortOrder = Global.getSortOrder();
+               noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
+       
        showColumns();
        noteTableView.load(false);
        scrollToCurrentGuid();
@@ -4030,11 +4135,6 @@ public class NeverNote extends QMainWindow{
                                nbooks.add(listManager.getNotebookIndex().get(i));
                }
                
-//             browser.setNotebookList(nbooks);
-               
-               FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
-               browserWindow.setNotebookList(notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex()));
-
                browser.setTitle(currentNote.getTitle());
                browser.setTag(getTagNamesForNote(currentNote));
                browser.setAuthor(currentNote.getAttributes().getAuthor());
@@ -4047,7 +4147,6 @@ public class NeverNote extends QMainWindow{
                        browser.setSubjectDate(currentNote.getCreated());
                browser.setUrl(currentNote.getAttributes().getSourceURL());
                
-//             browser.setAllTags(listManager.getTagIndex());
                FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
                List<Tag> tagList = tagFilter.getValidTags(currentNote);
                browser.setAllTags(tagList);
@@ -4059,6 +4158,10 @@ public class NeverNote extends QMainWindow{
                browser.loadingData(false);
                if (thumbnailViewer.isActiveWindow())
                        thumbnailView();
+               
+               FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
+               browser.setNotebookList(notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex()));
+
                waitCursor(false);
                logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
        }
@@ -4347,38 +4450,44 @@ public class NeverNote extends QMainWindow{
     @SuppressWarnings("unused")
        private void invalidateNoteCache(String guid, String content) {
        String v = noteCache.remove(guid);
-       if (content != null && !noteDirty) {
-               //noteCache.put(guid, content);
-       }
-               if (guid.equals(currentNoteGuid) && !noteDirty)
+//             if (guid.equals(currentNoteGuid) && !noteDirty)
                        refreshEvernoteNote(true);
     }
     // Signal received that a note guid has changed
     @SuppressWarnings("unused")
        private void noteGuidChanged(String oldGuid, String newGuid) {
        if (noteCache.containsKey(oldGuid)) {
-               String cache = noteCache.get(oldGuid);
-               noteCache.put(newGuid, cache);
-               noteCache.remove(oldGuid);
+               if (!oldGuid.equals(currentNoteGuid)) {
+                       String cache = noteCache.get(oldGuid);
+                       noteCache.put(newGuid, cache);
+                       noteCache.remove(oldGuid);
+               } else {
+                       noteCache.remove(oldGuid);
+                       noteCache.put(newGuid, browserWindow.getContent());
+               }
        }
+  
        listManager.updateNoteGuid(oldGuid, newGuid, false);
        if (currentNoteGuid.equals(oldGuid)) {
                if (currentNote != null)
                        currentNote.setGuid(newGuid);
                currentNoteGuid = newGuid;
        }
-               if (externalWindows.containsKey(oldGuid)) {
+               
+       if (externalWindows.containsKey(oldGuid)) {
                        ExternalBrowse b = externalWindows.get(oldGuid);
                        externalWindows.remove(oldGuid);
                        b.getBrowserWindow().getNote().setGuid(newGuid);
                        externalWindows.put(newGuid, b);
                }
+
        for (int i=0; i<listManager.getNoteIndex().size(); i++) {
                if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
                        noteTableView.proxyModel.addGuid(newGuid);
                        i=listManager.getNoteIndex().size();
                }
        }
+       
        if (listManager.getNoteTableModel().titleColors.containsKey(oldGuid)) {
                int color = listManager.getNoteTableModel().titleColors.get(oldGuid);
                listManager.getNoteTableModel().titleColors.put(newGuid, color);
@@ -4647,9 +4756,11 @@ public class NeverNote extends QMainWindow{
     private void setupOnlineMenu() {
        if (!Global.isConnected) {
                menuBar.noteOnlineHistoryAction.setEnabled(false);
+               menuBar.selectiveSyncAction.setEnabled(false);
                return;
        } else {
                menuBar.noteOnlineHistoryAction.setEnabled(true);
+               menuBar.selectiveSyncAction.setEnabled(true);
        }
     }
     @SuppressWarnings("unused")
@@ -4781,7 +4892,138 @@ public class NeverNote extends QMainWindow{
        refreshEvernoteNote(true);
        setMessage(tr("Note has been restored."));
     }
-    
+    @SuppressWarnings("unused")
+       private void setupSelectiveSync() {
+       
+       // Get a list of valid notebooks
+       List<Notebook> notebooks = null; 
+       List<Tag> tags = null;
+       List<LinkedNotebook> linkedNotebooks = null;
+       try {
+                       notebooks = syncRunner.noteStore.listNotebooks(syncRunner.authToken);
+                       tags = syncRunner.noteStore.listTags(syncRunner.authToken);
+                       linkedNotebooks = syncRunner.noteStore.listLinkedNotebooks(syncRunner.authToken);
+               } catch (EDAMUserException e) {
+                       setMessage("EDAMUserException: " +e.getMessage());
+                       return;
+               } catch (EDAMSystemException e) {
+                       setMessage("EDAMSystemException: " +e.getMessage());
+                       return;
+               } catch (TException e) {
+                       setMessage("EDAMTransactionException: " +e.getMessage());
+                       return;
+               } catch (EDAMNotFoundException e) {
+                       setMessage("EDAMNotFoundException: " +e.getMessage());
+                       return;
+               }
+       
+               // Split up notebooks into synchronized & non-synchronized
+       List<Notebook> ignoredBooks = new ArrayList<Notebook>();
+       List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
+       
+       for (int i=notebooks.size()-1; i>=0; i--) {
+               for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
+                       if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
+                               ignoredBooks.add(notebooks.get(i));
+                               j=dbIgnoredNotebooks.size();
+                       }
+               }
+       }
+       
+       // split up tags into synchronized & non-synchronized
+       List<Tag> ignoredTags = new ArrayList<Tag>();
+       List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
+       
+       for (int i=tags.size()-1; i>=0; i--) {
+               for (int j=0; j<dbIgnoredTags.size(); j++) {
+                       if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
+                               ignoredTags.add(tags.get(i));
+                               j=dbIgnoredTags.size();
+                       }
+               }
+       }
+       
+       // split up linked notebooks into synchronized & non-synchronized
+       List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
+       List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
+       for (int i=linkedNotebooks.size()-1; i>=0; i--) {
+               String notebookGuid = linkedNotebooks.get(i).getGuid();
+               for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
+                       if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
+                               ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
+                               j=dbIgnoredLinkedNotebooks.size();
+                       }
+               }
+       }
+       
+               IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
+               ignore.exec();
+               if (!ignore.okClicked())
+                       return;
+               
+               waitCursor(true);
+               
+               // Clear out old notebooks & add  the new ones
+               List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
+               for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
+                       conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
+               }
+               
+               List<String> newNotebooks = new ArrayList<String>();
+               for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
+                       String text = ignore.getIgnoredBookList().takeItem(i).text();
+                       for (int j=0; j<notebooks.size(); j++) {
+                               if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
+                                       Notebook n = notebooks.get(j);
+                                       conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
+                                       j=notebooks.size();
+                                       newNotebooks.add(n.getGuid());
+                               }
+                       }
+               }
+               
+               // Clear out old tags & add new ones
+               List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
+               for (int i=0; i<oldIgnoreTags.size(); i++) {
+                       conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
+               }
+               
+               List<String> newTags = new ArrayList<String>();
+               for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
+                       String text = ignore.getIgnoredTagList().takeItem(i).text();
+                       for (int j=0; j<tags.size(); j++) {
+                               if (tags.get(j).getName().equalsIgnoreCase(text)) {
+                                       Tag t = tags.get(j);
+                                       conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
+                                       newTags.add(t.getGuid());
+                                       j=tags.size();
+                               }
+                       }
+               }
+               
+               // Clear out old tags & add new ones
+               List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
+               for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
+                       conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
+               }
+               
+               List<String> newLinked = new ArrayList<String>();
+               for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
+                       String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
+                       for (int j=0; j<linkedNotebooks.size(); j++) {
+                               if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
+                                       LinkedNotebook t = linkedNotebooks.get(j);
+                                       conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
+                                       newLinked.add(t.getGuid());
+                                       j=linkedNotebooks.size();
+                               }
+                       }
+               }
+               
+               conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
+               waitCursor(false);
+               refreshLists();
+    }
     
     
        //**********************************************************
@@ -5038,13 +5280,18 @@ public class NeverNote extends QMainWindow{
                fd.setWindowTitle(tr("Backup Database"));
                fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)"));
                fd.setAcceptMode(AcceptMode.AcceptSave);
-               fd.setDirectory(System.getProperty("user.home"));
+               if (saveLastPath == null || saveLastPath.equals(""))
+                       fd.setDirectory(System.getProperty("user.home"));
+               else
+                       fd.setDirectory(saveLastPath);
                if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
                        return;
                }
                
                
        waitCursor(true);
+       saveLastPath = fd.selectedFiles().get(0);
+       saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
        setMessage(tr("Backing up database"));
        saveNote();
 //     conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
@@ -5079,13 +5326,19 @@ public class NeverNote extends QMainWindow{
                fd.setWindowTitle(tr("Restore Database"));
                fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)"));
                fd.setAcceptMode(AcceptMode.AcceptOpen);
-               fd.setDirectory(System.getProperty("user.home"));
+               if (saveLastPath == null || saveLastPath.equals(""))
+                       fd.setDirectory(System.getProperty("user.home"));
+               else
+                       fd.setDirectory(saveLastPath);
                if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
                        return;
                }
                
                
                waitCursor(true);
+       saveLastPath = fd.selectedFiles().get(0);
+       saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
+
                setMessage(tr("Restoring database"));
        ImportData noteReader = new ImportData(conn, true);
        noteReader.importData(fd.selectedFiles().get(0));
@@ -5144,7 +5397,10 @@ public class NeverNote extends QMainWindow{
                fd.setWindowTitle(tr("Import Notes"));
                fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)"));
                fd.setAcceptMode(AcceptMode.AcceptOpen);
-               fd.setDirectory(System.getProperty("user.home"));
+               if (saveLastPath == null || saveLastPath.equals(""))
+                       fd.setDirectory(System.getProperty("user.home"));
+               else
+                       fd.setDirectory(saveLastPath);
                if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
                        return;
                }
@@ -5159,6 +5415,7 @@ public class NeverNote extends QMainWindow{
                
        ImportData noteReader = new ImportData(conn, false);
        String fileName = fd.selectedFiles().get(0);
+       saveLastPath.substring(0,fileName.lastIndexOf("/"));
 
        if (!fileName.endsWith(".nnex"))
                fileName = fileName +".nnex";