OSDN Git Service

Add selective sync, cleanup debug messages, & correct network sync not disconnecting...
authorRandy Baumgarte <randy@fbn.cx>
Tue, 28 Dec 2010 11:41:00 +0000 (06:41 -0500)
committerRandy Baumgarte <randy@fbn.cx>
Sat, 1 Jan 2011 23:40:23 +0000 (18:40 -0500)
src/cx/fbn/nevernote/NeverNote.java
src/cx/fbn/nevernote/dialog/IgnoreSync.java [new file with mode: 0644]
src/cx/fbn/nevernote/gui/MainMenuBar.java
src/cx/fbn/nevernote/sql/NoteTable.java
src/cx/fbn/nevernote/sql/SyncTable.java
src/cx/fbn/nevernote/threads/IndexRunner.java
src/cx/fbn/nevernote/threads/SyncRunner.java

index d754850..861d9fe 100644 (file)
@@ -139,6 +139,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;
@@ -1695,7 +1696,7 @@ public class NeverNote extends QMainWindow{
                        if (!found)
                                nbooks.add(listManager.getNotebookIndex().get(i));
                }
-               waitCursor(false);
+               
                FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
                List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
                browserWindow.setNotebookList(filteredBooks);
@@ -1704,6 +1705,8 @@ public class NeverNote extends QMainWindow{
                Iterator<String> set = externalWindows.keySet().iterator();
                while(set.hasNext())
                        externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
+               
+               waitCursor(false);
        }
        // Change the notebook's icon
        @SuppressWarnings("unused")
@@ -3001,6 +3004,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;
        }
@@ -4654,9 +4658,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")
@@ -4788,7 +4794,101 @@ 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;
+       try {
+                       notebooks = syncRunner.noteStore.listNotebooks(syncRunner.authToken);
+                       tags = syncRunner.noteStore.listTags(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;
+               }
+       
+               // 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();
+                       }
+               }
+       }
+       
+               IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags);
+               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();
+                               }
+                       }
+               }
+               
+               conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags);
+               waitCursor(false);
+               refreshLists();
+    }
     
     
        //**********************************************************
diff --git a/src/cx/fbn/nevernote/dialog/IgnoreSync.java b/src/cx/fbn/nevernote/dialog/IgnoreSync.java
new file mode 100644 (file)
index 0000000..466a779
--- /dev/null
@@ -0,0 +1,326 @@
+/*\r
+ * This file is part of NeverNote \r
+ * Copyright 2009 Randy Baumgarte\r
+ * \r
+ * This file may be licensed under the terms of of the\r
+ * GNU General Public License Version 2 (the ``GPL'').\r
+ *\r
+ * Software distributed under the License is distributed\r
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
+ * express or implied. See the GPL for the specific language\r
+ * governing rights and limitations.\r
+ *\r
+ * You should have received a copy of the GPL along with this\r
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
+ * or write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+ *\r
+*/\r
+\r
+package cx.fbn.nevernote.dialog;\r
+\r
+import java.util.List;\r
+\r
+import com.evernote.edam.type.Notebook;\r
+import com.evernote.edam.type.Tag;\r
+import com.trolltech.qt.gui.QAbstractItemView;\r
+import com.trolltech.qt.gui.QDialog;\r
+import com.trolltech.qt.gui.QHBoxLayout;\r
+import com.trolltech.qt.gui.QIcon;\r
+import com.trolltech.qt.gui.QLabel;\r
+import com.trolltech.qt.gui.QListWidget;\r
+import com.trolltech.qt.gui.QListWidgetItem;\r
+import com.trolltech.qt.gui.QPushButton;\r
+import com.trolltech.qt.gui.QSpacerItem;\r
+import com.trolltech.qt.gui.QVBoxLayout;\r
+\r
+public class IgnoreSync extends QDialog {\r
+       private final QListWidget               syncBookList;\r
+       private final QListWidget               ignoreBookList;\r
+       private final QListWidget               syncTagList;\r
+       private final QListWidget               ignoreTagList;\r
+       private final QPushButton               okButton;\r
+       private final QPushButton               cancelButton;\r
+       private boolean                                 okClicked;\r
+       private final QPushButton               leftButton;\r
+       private final QPushButton               rightButton;\r
+       private final QPushButton               leftTagButton;\r
+       private final QPushButton               rightTagButton;\r
+       \r
+       private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
+       \r
+       public IgnoreSync(List<Notebook> allBooks, List<Notebook> archive, List<Tag> allTags, List<Tag> ignoreTags) {\r
+               setWindowIcon(new QIcon(iconPath+"synchronize.png"));\r
+               okClicked = false;\r
+               syncBookList = new QListWidget();\r
+               syncBookList.setSortingEnabled(true);\r
+               syncBookList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection);\r
+               \r
+               syncTagList = new QListWidget();\r
+               syncTagList.setSortingEnabled(true);\r
+               syncTagList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection);\r
+               \r
+               okButton = new QPushButton();\r
+               okButton.setText(tr("OK"));\r
+               okButton.pressed.connect(this, "onClicked()");\r
+               \r
+               cancelButton = new QPushButton();\r
+               cancelButton.setText(tr("Cancel"));\r
+               cancelButton.pressed.connect(this, "onCancel()");\r
+               \r
+               QVBoxLayout openLayout = new QVBoxLayout();\r
+               openLayout.addWidget(new QLabel(tr("Synchronized Notebooks")));\r
+               openLayout.addWidget(syncBookList);\r
+               \r
+               QVBoxLayout openTagLayout = new QVBoxLayout();\r
+               openTagLayout.addWidget(new QLabel(tr("Synchronized Tags")));\r
+               openTagLayout.addWidget(syncTagList);\r
+               \r
+               rightButton = new QPushButton(this);\r
+               rightButton.setIcon(new QIcon(iconPath+"forward.png"));\r
+               leftButton = new QPushButton(this);\r
+               leftButton.setIcon(new QIcon(iconPath+"back.png"));\r
+               leftButton.setEnabled(false);\r
+               rightButton.setEnabled(false);\r
+               \r
+               rightTagButton = new QPushButton(this);\r
+               rightTagButton.setIcon(new QIcon(iconPath+"forward.png"));\r
+               leftTagButton = new QPushButton(this);\r
+               leftTagButton.setIcon(new QIcon(iconPath+"back.png"));\r
+               leftTagButton.setEnabled(false);\r
+               rightTagButton.setEnabled(false);\r
+               \r
+               QVBoxLayout middleLayout = new QVBoxLayout();\r
+               middleLayout.addSpacerItem(new QSpacerItem(1,1));\r
+               middleLayout.addWidget(rightButton);\r
+               middleLayout.addWidget(leftButton);\r
+               middleLayout.addSpacerItem(new QSpacerItem(1,1));\r
+               \r
+               QVBoxLayout middleTagLayout = new QVBoxLayout();\r
+               middleTagLayout.addSpacerItem(new QSpacerItem(1,1));\r
+               middleTagLayout.addWidget(rightTagButton);\r
+               middleTagLayout.addWidget(leftTagButton);\r
+               middleTagLayout.addSpacerItem(new QSpacerItem(1,1));\r
+\r
+               QVBoxLayout closeLayout = new QVBoxLayout();\r
+               closeLayout.addWidget(new QLabel(tr("Non-Synchronized Notebooks")));\r
+               ignoreBookList = new QListWidget();\r
+               ignoreBookList.setSortingEnabled(true);\r
+               ignoreBookList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection);\r
+               closeLayout.addWidget(ignoreBookList);\r
+\r
+               QVBoxLayout closeTagLayout = new QVBoxLayout();\r
+               closeTagLayout.addWidget(new QLabel(tr("Non-Synchronized Tags")));\r
+               ignoreTagList = new QListWidget();\r
+               ignoreTagList.setSortingEnabled(true);\r
+               ignoreTagList.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection);\r
+               closeTagLayout.addWidget(ignoreTagList);\r
+               \r
+               syncBookList.itemSelectionChanged.connect(this, "syncBookSelected()");\r
+               ignoreBookList.itemSelectionChanged.connect(this, "ignoreBookSelected()");\r
+               leftButton.clicked.connect(this, "toOpenList()");\r
+               rightButton.clicked.connect(this, "toClosedList()");\r
+               \r
+               syncTagList.itemSelectionChanged.connect(this, "syncTagSelected()");\r
+               ignoreTagList.itemSelectionChanged.connect(this, "ignoreTagSelected()");\r
+               leftTagButton.clicked.connect(this, "toOpenTagList()");\r
+               rightTagButton.clicked.connect(this, "toClosedTagList()");\r
+               \r
+               QHBoxLayout buttonLayout = new QHBoxLayout();\r
+               buttonLayout.addStretch(1);\r
+               buttonLayout.addWidget(okButton);\r
+               buttonLayout.addWidget(cancelButton);\r
+               setWindowTitle(tr("Open/Close Notebooks"));\r
+               \r
+               QHBoxLayout upperLayout = new QHBoxLayout();\r
+               upperLayout.addLayout(openLayout);\r
+               upperLayout.addLayout(middleLayout);\r
+               upperLayout.addLayout(closeLayout);\r
+               \r
+               QHBoxLayout tagLayout = new QHBoxLayout();\r
+               tagLayout.addLayout(openTagLayout);\r
+               tagLayout.addLayout(middleTagLayout);\r
+               tagLayout.addLayout(closeTagLayout);\r
+               \r
+               QVBoxLayout mainLayout = new QVBoxLayout();\r
+               mainLayout.addLayout(upperLayout);\r
+               mainLayout.addLayout(tagLayout);\r
+               mainLayout.addSpacing(1);\r
+               mainLayout.addLayout(buttonLayout);\r
+               setLayout(mainLayout);\r
+\r
+               for (int i=0; i<allBooks.size(); i++) {\r
+                       boolean found = false;\r
+                       for (int j=0; j<archive.size(); j++) {\r
+                               if (archive.get(j).getName().equalsIgnoreCase(allBooks.get(i).getName())) {\r
+                                       found = true;\r
+                                       j=archive.size();\r
+                               }\r
+                       }\r
+                       if (!found) {\r
+                               QListWidgetItem item = new QListWidgetItem(allBooks.get(i).getName());\r
+                               item.setSelected(false);\r
+                               syncBookList.addItem(item);\r
+                       }\r
+               }\r
+               \r
+               setWindowTitle(tr("Open Notebooks"));\r
+               for (int i=0; i<archive.size(); i++) {\r
+                       QListWidgetItem item = new QListWidgetItem(archive.get(i).getName());\r
+                       item.setSelected(false);\r
+                       ignoreBookList.addItem(item);\r
+               }\r
+               \r
+               for (int i=0; i<allTags.size(); i++) {\r
+                       boolean found = false;\r
+                       for (int j=0; j<ignoreTags.size(); j++) {\r
+                               if (ignoreTags.get(j).getName().equalsIgnoreCase(allTags.get(i).getName())) {\r
+                                       found = true;\r
+                                       j=ignoreTags.size();\r
+                               }\r
+                       }\r
+                       if (!found) {\r
+                               QListWidgetItem item = new QListWidgetItem(allTags.get(i).getName());\r
+                               item.setSelected(false);\r
+                               syncTagList.addItem(item);\r
+                       }\r
+               }\r
+               \r
+               setWindowTitle(tr("Ignore Synchronized Notes"));\r
+               for (int i=0; i<ignoreTags.size(); i++) {\r
+                       QListWidgetItem item = new QListWidgetItem(ignoreTags.get(i).getName());\r
+                       item.setSelected(false);\r
+                       ignoreTagList.addItem(item);\r
+               }\r
+               syncBookList.itemSelectionChanged.connect(this, "itemSelected()");\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void toClosedList() {\r
+               List<QListWidgetItem> items = syncBookList.selectedItems();\r
+               for (int i=items.size()-1; i>=0; i--) {\r
+                       int row = syncBookList.row(items.get(i));\r
+                       syncBookList.takeItem(row);\r
+                       ignoreBookList.addItem(items.get(i).text());\r
+               }\r
+               if (syncBookList.count() == 0)\r
+                       okButton.setEnabled(false);\r
+               rightButton.setEnabled(false);\r
+       }\r
+       \r
+       \r
+       @SuppressWarnings("unused")\r
+       private void toOpenList() {\r
+               List<QListWidgetItem> items = ignoreBookList.selectedItems();\r
+               for (int i=items.size()-1; i>=0; i--) {\r
+                       int row = ignoreBookList.row(items.get(i));\r
+                       ignoreBookList.takeItem(row);\r
+                       syncBookList.addItem(items.get(i).text());\r
+               }\r
+               okButton.setEnabled(true);\r
+               leftButton.setEnabled(false);\r
+       }\r
+       \r
+       \r
+       @SuppressWarnings("unused")\r
+       private void toClosedTagList() {\r
+               List<QListWidgetItem> items = syncTagList.selectedItems();\r
+               for (int i=items.size()-1; i>=0; i--) {\r
+                       int row = syncTagList.row(items.get(i));\r
+                       syncTagList.takeItem(row);\r
+                       ignoreTagList.addItem(items.get(i).text());\r
+               }\r
+               if (syncTagList.count() == 0)\r
+                       okButton.setEnabled(false);\r
+               rightTagButton.setEnabled(false);\r
+       }\r
+       \r
+       \r
+       @SuppressWarnings("unused")\r
+       private void toOpenTagList() {\r
+               List<QListWidgetItem> items = ignoreTagList.selectedItems();\r
+               for (int i=items.size()-1; i>=0; i--) {\r
+                       int row = ignoreTagList.row(items.get(i));\r
+                       ignoreTagList.takeItem(row);\r
+                       syncTagList.addItem(items.get(i).text());\r
+               }\r
+               okButton.setEnabled(true);\r
+               leftTagButton.setEnabled(false);\r
+       }\r
+       \r
+       \r
+       @SuppressWarnings("unused")\r
+       private void ignoreBookSelected() {\r
+               if (ignoreBookList.selectedItems().size() > 0)\r
+                       leftButton.setEnabled(true);\r
+               else\r
+                       leftButton.setEnabled(false);\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void syncBookSelected() {\r
+               if (syncBookList.selectedItems().size() > 0)\r
+                       rightButton.setEnabled(true);\r
+               else\r
+                       rightButton.setEnabled(false);\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void ignoreTagSelected() {\r
+               if (ignoreTagList.selectedItems().size() > 0)\r
+                       leftTagButton.setEnabled(true);\r
+               else\r
+                       leftTagButton.setEnabled(false);\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void syncTagSelected() {\r
+               if (syncTagList.selectedItems().size() > 0)\r
+                       rightTagButton.setEnabled(true);\r
+               else\r
+                       rightTagButton.setEnabled(false);\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void onClicked() {\r
+               okClicked = true;\r
+               close();\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void onCancel() {\r
+               okClicked = false;\r
+               close();\r
+       }\r
+       \r
+       public boolean okClicked() {\r
+               return okClicked;\r
+       }\r
+       \r
+       public QListWidget getSyncBookList() {\r
+               return syncBookList;\r
+       }\r
+       \r
+       public QListWidget getIgnoredBookList() {\r
+               return ignoreBookList;\r
+       }\r
+       \r
+       public QListWidget getSyncTagList() {\r
+               return syncTagList;\r
+       }\r
+       \r
+       public QListWidget getIgnoredTagList() {\r
+               return ignoreTagList;\r
+       }\r
+       \r
+       @SuppressWarnings("unused")\r
+       private void itemSelected() {\r
+               if (syncBookList.selectedItems().size() == syncBookList.count()) {\r
+                       okButton.setEnabled(false);\r
+                       rightButton.setEnabled(false);\r
+                       return;\r
+               }\r
+               rightButton.setEnabled(true);\r
+               okButton.setEnabled(true);\r
+       }\r
+}\r
index 39ede05..72e7311 100644 (file)
@@ -31,7 +31,8 @@ public class MainMenuBar extends QMenuBar {
        public QAction                  printAction;                            // Action when a user selects Print from the file menu\r
        public QAction                  connectAction;                          // Connect/Disconnect to Evernote\r
        public QAction                  fullReindexAction;                      // Action when a user wants to reindex the entire database\r
-       public QAction                  synchronizeAction;                      // Synchronize data with Evernote                                       \r
+       public QAction                  synchronizeAction;                      // Synchronize data with Evernote       \r
+       public QAction                  selectiveSyncAction;            // Specify which notebooks or tags to ignore\r
        public QAction                  settingsAction;                         // Show user config settings\r
        public QAction                  emailAction;                            // Action when a user selects "email"\r
        public QAction                  backupAction;                           // Backup the database\r
@@ -536,7 +537,11 @@ public class MainMenuBar extends QMenuBar {
                noteOnlineHistoryAction.setEnabled(false);\r
                setupShortcut(noteOnlineHistoryAction, "Online_Note_History");\r
                \r
-               \r
+               selectiveSyncAction = new QAction(tr("Selective Synchronize"), this);\r
+               selectiveSyncAction.setToolTip("Selectively ignore some notes");\r
+               selectiveSyncAction.triggered.connect(parent, "setupSelectiveSync()");\r
+               selectiveSyncAction.setEnabled(false);\r
+               setupShortcut(synchronizeAction, "Online_Selective_Sync");\r
                \r
                \r
                \r
@@ -714,6 +719,7 @@ public class MainMenuBar extends QMenuBar {
                onlineMenu.addAction(connectAction);\r
                onlineMenu.addSeparator();\r
                onlineMenu.addAction(noteOnlineHistoryAction);\r
+               onlineMenu.addAction(selectiveSyncAction);\r
                \r
                toolsMenu = addMenu(tr("&Tools"));\r
                toolsMenu.addAction(spellCheckAction);\r
index 446d1a6..97c0b15 100644 (file)
@@ -975,6 +975,60 @@ public class NoteTable {
                return note.replace("<div/>", "<div>&nbsp;</div>");\r
        }\r
        \r
+       // Expunge notes that we don't want to synchronize\r
+       public List<String> expungeIgnoreSynchronizedNotes(List<String> notebooks, List<String>tags) {\r
+               \r
+               List<String> noteGuids = new ArrayList<String>();\r
+               for (int i=0; i<notebooks.size(); i++) {\r
+                       List<String> notes = findNotesByNotebook(notebooks.get(i));\r
+                       for (int j=0; j<notes.size(); j++) {\r
+                               if (!isNoteDirty(notes.get(j))) {\r
+                                       expungeNote(notes.get(j), true, false);\r
+                                       noteGuids.add(notes.get(j));\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               for (int i=0; i<tags.size(); i++) {\r
+                       List<String> notes = findNotesByTag(tags.get(i));\r
+                       for (int j=0; j<notes.size(); j++) {\r
+                               if (!isNoteDirty(notes.get(j))) {\r
+                                       expungeNote(notes.get(j), true, false);\r
+                                       noteGuids.add(notes.get(j));\r
+                               }\r
+                       }\r
+               }\r
+               return noteGuids;\r
+       }\r
+       \r
+       // Find a note by its notebook\r
+       // Expunge notes that we don't want to synchronize\r
+       public List<String> findNotesByNotebook(String notebook) {\r
+               List<String> values = new ArrayList<String>();\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               query.prepare("Select guid from note where notebookguid=:notebook");\r
+\r
+               query.bindValue(":notebook", notebook);\r
+               query.exec();\r
+               while (query.next()) {\r
+                       values.add(query.valueString(0));\r
+               }\r
+               return values;\r
+       }\r
+       \r
+       public List<String> findNotesByTag(String tag) {\r
+               List<String> values = new ArrayList<String>();\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               query.prepare("Select distinct noteguid from notetags where tagguid=:tag");\r
+\r
+               query.bindValue(":tag", tag);\r
+               query.exec();\r
+               while (query.next()) {\r
+                       values.add(query.valueString(0));\r
+               }\r
+               return values;\r
+       }\r
+       \r
        \r
        \r
        //********************************************************************************\r
index 092609b..21f90ea 100644 (file)
@@ -20,6 +20,9 @@
 \r
 package cx.fbn.nevernote.sql;\r
 \r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
 import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
 import cx.fbn.nevernote.utilities.ListManager;\r
@@ -70,7 +73,7 @@ public class SyncTable {
                        logger.log(logger.MEDIUM, query.lastError());\r
                }\r
        }\r
-       // Set a key field\r
+       // Get a key field\r
        public String getRecord(String key) {\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
         query.prepare("Select value from Sync where key=:key");\r
@@ -114,7 +117,23 @@ public class SyncTable {
        public int getUpdateSequenceNumber() {\r
                return new Integer(getRecord("UpdateSequenceNumber"));\r
        }\r
-       \r
-\r
+       // Get notebooks/tags to ignore\r
+       public List<String> getIgnoreRecords(String type) {\r
+               List<String> values = new ArrayList<String>();\r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+        if (!query.prepare("Select value from Sync where key like :type")) {\r
+                       logger.log(logger.MEDIUM, "getIgnoreRecords from sync failed.");\r
+                       logger.log(logger.MEDIUM, query.lastError());\r
+                       return null;\r
+               }\r
+        query.bindValue(":type", "IGNORE" +type +"-%");\r
+        query.exec();\r
+               while (query.next()) {\r
+                       values.add(query.valueString(0));\r
+               }\r
+               return values;\r
+       }\r
+       // Expunge ignore records\r
+       // Add an item to the table\r
 \r
 }\r
index a94b597..fa59a94 100644 (file)
@@ -159,7 +159,6 @@ public class IndexRunner extends QObject implements Runnable {
                Note n = conn.getNoteTable().getNote(guid,true,false,true,true, true);\r
                String data = n.getContent();\r
                data = conn.getNoteTable().getNoteContentNoUTFConversion(n.getGuid());\r
-               System.out.println(data);\r
                \r
                logger.log(logger.EXTREME, "Removing any encrypted data");\r
                data = removeEnCrypt(data.toString());\r
index bce4fa8..57fb0fb 100644 (file)
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.Calendar;\r
 import java.util.Date;\r
 import java.util.GregorianCalendar;\r
+import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.Vector;\r
 import java.util.concurrent.LinkedBlockingQueue;\r
@@ -132,12 +133,13 @@ public class SyncRunner extends QObject implements Runnable {
            public int updateSequenceNumber;\r
            private boolean refreshNeeded;\r
            private volatile LinkedBlockingQueue<String> workQueue;\r
-//             private static int MAX_EMPTY_QUEUE_COUNT = 1;\r
                private static int MAX_QUEUED_WAITING = 1000;\r
                String dbuid;\r
                String dburl;\r
                String dbpswd;\r
                String dbcpswd;\r
+               private final HashMap<String,String> ignoreTags;\r
+               private final HashMap<String,String> ignoreNotebooks;\r
        \r
                \r
                \r
@@ -168,6 +170,9 @@ public class SyncRunner extends QObject implements Runnable {
                userStore = null;\r
                authToken = null;\r
                disableUploads = false;\r
+               ignoreTags = new HashMap<String,String>();\r
+               ignoreNotebooks = new HashMap<String,String>();\r
+               \r
 //             setAutoDelete(false);\r
                workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);\r
        }\r
@@ -183,7 +188,7 @@ public class SyncRunner extends QObject implements Runnable {
                                        return;\r
                                idle=false;\r
                                error=false;\r
-                               if (authRefreshNeeded == true) {\r
+                               if (authRefreshNeeded == true || !isConnected) {\r
                                        logger.log(logger.EXTREME, "Refreshing connection");\r
                                        refreshConnection();\r
                                }\r
@@ -204,6 +209,10 @@ public class SyncRunner extends QObject implements Runnable {
                                idle=true;\r
                                logger.log(logger.EXTREME, "Signaling refresh finished.  refreshNeeded=" +refreshNeeded);\r
                                syncSignal.finished.emit(refreshNeeded);\r
+                               if (error) {\r
+                                       syncSignal.errorDisconnect.emit();\r
+                                       status.message.emit(tr("Error synchronizing - see log for details."));\r
+                               }\r
                        }\r
                }       \r
                catch (InterruptedException e1) {\r
@@ -252,7 +261,19 @@ public class SyncRunner extends QObject implements Runnable {
        @SuppressWarnings("unused")\r
        private void evernoteSync() throws java.net.UnknownHostException {\r
                logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync");\r
+               \r
+               // Rebuild list of tags & notebooks to ignore\r
+               ignoreNotebooks.clear();\r
+               List<String> ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");\r
+               for (int i=0; i<ignore.size(); i++) \r
+                       ignoreNotebooks.put(ignore.get(i),"");\r
+               \r
+               ignoreTags.clear();\r
+               ignore = conn.getSyncTable().getIgnoreRecords("TAG");\r
+               for (int i=0; i<ignore.size(); i++) \r
+                       ignoreTags.put(ignore.get(i),"");\r
 \r
+               // Make sure we are connected & should keep running\r
                if (isConnected && keepRunning) {\r
                        error = false;\r
                        logger.log(logger.EXTREME, "Synchronizing with Evernote");\r
@@ -268,17 +289,20 @@ public class SyncRunner extends QObject implements Runnable {
                                e1.printStackTrace();\r
                                status.message.emit(tr("User exception getting user account information.  Aborting sync and disconnecting"));\r
                                syncSignal.errorDisconnect.emit();\r
+                               error = true;\r
                                enDisconnect();\r
                                return;\r
                        } catch (EDAMSystemException e1) {\r
                                e1.printStackTrace();\r
                                status.message.emit(tr("System error user account information.  Aborting sync and disconnecting!"));\r
                                syncSignal.errorDisconnect.emit();\r
+                               error = true;\r
                                enDisconnect();\r
                                return;\r
                        } catch (TException e1) {\r
                                e1.printStackTrace();\r
                                syncSignal.errorDisconnect.emit();\r
+                               error = true;\r
                                status.message.emit(tr("Transaction error getting user account information.  Aborting sync and disconnecting!"));\r
                                enDisconnect();\r
                                return;\r
@@ -387,6 +411,11 @@ public class SyncRunner extends QObject implements Runnable {
                                        syncLocalSavedSearches();\r
                        }\r
                        \r
+                       status.message.emit(tr("Cleaning up"));\r
+                       List<String> notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"), conn.getSyncTable().getIgnoreRecords("TAG"));\r
+                       if (notes.size() > 0)\r
+                               syncSignal.refreshLists.emit();\r
+                       \r
                        //*****************************************\r
                        //* End of synchronization\r
                        //*****************************************\r
@@ -421,7 +450,8 @@ public class SyncRunner extends QObject implements Runnable {
                for (int i=0; i<expunged.size() && keepRunning; i++) {\r
                        \r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
 \r
                        try {\r
                                if (expunged.get(i).type.equalsIgnoreCase("TAG")) {\r
@@ -480,7 +510,8 @@ public class SyncRunner extends QObject implements Runnable {
                for (int i=0; i<notes.size() && keepRunning; i++) {\r
                        \r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
                        \r
                        Note enNote = notes.get(i);\r
                        try {\r
@@ -546,7 +577,8 @@ public class SyncRunner extends QObject implements Runnable {
                status.message.emit(tr("Sending local notes."));\r
 \r
                if (authRefreshNeeded)\r
-                       refreshConnection();\r
+                       if (!refreshConnection())\r
+                               return;\r
                        \r
                if (enNote.isActive()) {\r
                        try {\r
@@ -645,7 +677,8 @@ public class SyncRunner extends QObject implements Runnable {
                for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
                        \r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
                        \r
                        Notebook enNotebook = notebooks.get(i);\r
                        try {\r
@@ -733,7 +766,8 @@ public class SyncRunner extends QObject implements Runnable {
                Tag enTag = findNextTag();\r
                while(enTag!=null) {\r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
 \r
                        try {\r
                                if (enTag.getUpdateSequenceNum() > 0) {\r
@@ -864,7 +898,8 @@ public class SyncRunner extends QObject implements Runnable {
                for (int i=0; i<searches.size() &&  keepRunning; i++) {\r
                        \r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
                        \r
                        SavedSearch enSearch = searches.get(i);\r
                        try {\r
@@ -943,7 +978,8 @@ public class SyncRunner extends QObject implements Runnable {
                while(more &&  keepRunning) {\r
                        \r
                        if (authRefreshNeeded)\r
-                               refreshConnection();\r
+                               if (!refreshConnection())\r
+                                       return;\r
                        \r
                        chunk = null;\r
                        int sequence = updateSequenceNumber;\r
@@ -1191,7 +1227,17 @@ public class SyncRunner extends QObject implements Runnable {
                                if (conflictingNote)\r
                                        moveConflictingNote(n.getGuid());\r
                        }\r
-                       if (conflictingNote || fullSync) {\r
+                       boolean ignoreNote = false;\r
+                       if (ignoreNotebooks.containsKey(n.getNotebookGuid()))\r
+                               ignoreNote = true;\r
+                       for (int i=0; i<n.getTagGuidsSize(); i++) {\r
+                               if (ignoreTags.containsKey(n.getTagGuids().get(i))) {\r
+                                       ignoreNote = true;\r
+                                       i=n.getTagGuidsSize();\r
+                               }\r
+                       }\r
+                               \r
+                       if ((conflictingNote || fullSync) && !ignoreNote) {\r
                                logger.log(logger.EXTREME, "Saving Note");\r
                                conn.getNoteTable().syncNote(n, false);\r
                                noteSignal.noteChanged.emit(n.getGuid(), null);   // Signal to ivalidate note cache\r
@@ -1483,19 +1529,20 @@ public class SyncRunner extends QObject implements Runnable {
        isConnected = false;\r
     }\r
     // Refresh the connection\r
-    private synchronized void refreshConnection() {\r
+    private synchronized boolean refreshConnection() {\r
                logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()");\r
 //        Calendar cal = Calendar.getInstance();\r
                \r
         // If we are not connected let's get out of here\r
         if (!isConnected)\r
-               return;\r
+               return false;\r
         \r
                // If we fail too many times, then let's give up.\r
                if (failedRefreshes >=5) {\r
                        logger.log(logger.EXTREME, "Refresh attempts have failed.  Disconnecting.");\r
                        isConnected = false;\r
-                       return;\r
+                       status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
+                       return false;\r
                }\r
         \r
                // If this is the first time through, then we need to set this\r
@@ -1512,31 +1559,33 @@ public class SyncRunner extends QObject implements Runnable {
                if (userStore != null && authToken != null) \r
                        newAuth = userStore.refreshAuthentication(authToken); \r
                else\r
-                       return;\r
+                       return false;\r
                logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded.");\r
                } catch (EDAMUserException e) {\r
                        e.printStackTrace();\r
                        syncSignal.authRefreshComplete.emit(false);\r
                        failedRefreshes++;\r
-                       return;\r
+                       return false;\r
                } catch (EDAMSystemException e) {\r
                        e.printStackTrace();\r
                        syncSignal.authRefreshComplete.emit(false);\r
                        failedRefreshes++;\r
-                       return;         \r
+                       return false;           \r
                } catch (TException e) { \r
                        e.printStackTrace();\r
                        syncSignal.authRefreshComplete.emit(false);\r
                        failedRefreshes++;\r
-                       return;\r
+                       return false;\r
                }\r
                \r
                // If we didn't get a good auth, then we've failed\r
                if (newAuth == null) {\r
                        failedRefreshes++;\r
+                       status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
                        logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes);\r
+                       status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
                        syncSignal.authRefreshComplete.emit(false);\r
-                       return;\r
+                       return false;\r
                }\r
                \r
                // We got a good token.  Now we need to setup the time to renew it.\r
@@ -1554,6 +1603,8 @@ public class SyncRunner extends QObject implements Runnable {
 //                     failedRefreshes++;\r
 //                     syncSignal.authRefreshComplete.emit(false);\r
 //             }\r
+               \r
+               return true;\r
     }\r
     \r
        public synchronized boolean addWork(String request) {\r