# Setup environment #
#####################
NN_CLASSPATH=$NEVERNOTE/nevernote.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/PDFRenderer.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/apache-mime4j-0.6.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-codec-1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-compress-1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-lang-2.4.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-logging-1.1.1.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/evernote.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/h2-1.2.136.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpclient-4.0.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpcore-4.0.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpmime-4.0.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jaxen-1.1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jazzy.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jtidy-r938.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/libthrift.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/log4j-1.2.14.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/PDFRenderer.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-lang-2.4.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jtidy-r938.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-macosx-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-macosx-gcc-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/pdfbox-app-1.3.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-ooxml-3.7.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-scratchpad-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/tika.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/xmlbeans-2.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/xsdlib-20060615.jar
###################
rem # Setup environment #\r
rem #####################\r
set NN_CLASSPATH=%NEVERNOTE%nevernote.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\evernote.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\libthrift.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\log4j-1.2.14.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\h2-1.2.136.jar\r
+\r
set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\PDFRenderer.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\apache-mime4j-0.6.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\commons-codec-1.3.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\commons-compress-1.1.jar\r
set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\commons-lang-2.4.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\commons-logging-1.1.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\evernote.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\h2-1.2.136.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\httpclient-4.0.3.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\httpcore-4.0.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\httpmime-4.0.3.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\jaxen-1.1.3.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\jazzy.jar\r
set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\jtidy-r938.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\libthrift.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\log4j-1.2.14.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\pdfbox-app-1.3.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\poi-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\poi-ooxml-3.7.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\poi-ooxml-schemas-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\poi-scratchpad-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\tika.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\xmlbeans-2.3.0.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\xsdlib-20060615.jar\r
+\r
if exist "%NEVERNOTE%lib\qtjambi-win32-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\qtjambi-win32-4.5.2_01.jar\r
if exist "%NEVERNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar\r
if exist "%NEVERNOTE%lib\qtjambi-win64-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEVERNOTE%lib\qtjambi-win64-4.5.2_01.jar\r
# Setup environment #
#####################
NN_CLASSPATH=$NEVERNOTE/nevernote.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/PDFRenderer.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/apache-mime4j-0.6.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-codec-1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-compress-1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-lang-2.4.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-logging-1.1.1.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/evernote.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/h2-1.2.136.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpclient-4.0.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpcore-4.0.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/httpmime-4.0.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jaxen-1.1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jazzy.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jtidy-r938.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/libthrift.jar
NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/log4j-1.2.14.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/PDFRenderer.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/commons-lang-2.4.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/jtidy-r938.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-linux32-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-linux32-gcc-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-linux64-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/qtjambi-linux64-gcc-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/pdfbox-app-1.3.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-ooxml-3.7.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/poi-scratchpad-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/tika.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/xmlbeans-2.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEVERNOTE/lib/xsdlib-20060615.jar
+
+
###################
import cx.fbn.nevernote.utilities.Pair;\r
\r
public class Global {\r
- public static String version = "0.94";\r
+ public static String version = "0.95";\r
public static String username = ""; \r
public static String password = ""; \r
\r
import com.evernote.edam.notestore.NoteFilter;
import com.evernote.edam.notestore.NoteVersionId;
import com.evernote.edam.type.Data;
+import com.evernote.edam.type.LinkedNotebook;
import com.evernote.edam.type.Note;
import com.evernote.edam.type.NoteAttributes;
import com.evernote.edam.type.Notebook;
import cx.fbn.nevernote.dialog.TagEdit;
import cx.fbn.nevernote.dialog.ThumbnailViewer;
import cx.fbn.nevernote.dialog.WatchFolder;
+import cx.fbn.nevernote.filters.FilterEditorNotebooks;
+import cx.fbn.nevernote.filters.FilterEditorTags;
import cx.fbn.nevernote.gui.AttributeTreeWidget;
import cx.fbn.nevernote.gui.BrowserWindow;
import cx.fbn.nevernote.gui.DateAttributeFilterTable;
String currentNoteGuid; // GUID of the current note
Note currentNote; // The currently viewed note
boolean noteDirty; // Has the note been changed?
- boolean inkNote; // if this is an ink note, it is read only
+ boolean inkNote; // if this is an ink note, it is read only
+ boolean readOnly; // Is this note read-only?
+
ListManager listManager; // DB runnable task
int saveThreadDeadCount=0; // number of consecutive dead times for the save thread
HashMap<String, String> noteCache; // Cash of note content
- HashMap<String, Boolean> readOnlyCache; // List of cash notes that are read-only
+ HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
+ HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
List<String> historyGuids; // GUIDs of previously viewed items
int historyPosition; // Position within the viewed items
boolean fromHistory; // Is this from the history queue?
// Setup the browser window
noteCache = new HashMap<String,String>();
readOnlyCache = new HashMap<String, Boolean>();
+ inkNoteCache = new HashMap<String, Boolean>();
browserWindow = new BrowserWindow(conn);
mainLeftRightSplitter.addWidget(leftSplitter1);
notebookTree.setShareAction(menuBar.notebookShareAction);
notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
+ notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
+ notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
// !timeFormat.equals(Global.getTimeFormat())) {
noteCache.clear();
readOnlyCache.clear();
+ inkNoteCache.clear();
noteIndexUpdated(true);
// }
conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
}
conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
+ if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
+ LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
+ linkedNotebook.setShareName(edit.getNotebook());
+ conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
+ }
i=listManager.getNotebookIndex().size();
}
}
listManager.loadNotesIndex();
notebookIndexUpdated();
noteIndexUpdated(false);
+ reloadTagTree(true);
// noteIndexUpdated(false);
// Build a list of non-closed notebooks
logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
if (selectedTagGUIDs == null)
selectedTagGUIDs = new ArrayList<String>();
-// selectedTagGUIDs.clear(); // clear out old entries
+ if (reload)
+ listManager.reloadTagIndex();
tagTree.blockSignals(true);
if (reload) {
// This is done because we want to force a reload of
// images. Some images we may want to highlight the text.
readOnlyCache.clear();
+ inkNoteCache.clear();
noteCache.clear();
QWebSettings.setMaximumPagesInCache(0);
QWebSettings.setObjectCacheCapacities(0, 0, 0);
// images. Some images we may want to highlight the text.
noteCache.clear();
readOnlyCache.clear();
+ inkNoteCache.clear();
QWebSettings.setMaximumPagesInCache(0);
QWebSettings.setObjectCacheCapacities(0, 0, 0);
logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
noteCache.clear();
readOnlyCache.clear();
+ inkNoteCache.clear();
saveNoteColumnPositions();
saveNoteIndexWidth();
String text = searchField.currentText();
// Get a note from Evernote (and put it in the browser)
private void refreshEvernoteNote(boolean reload) {
logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
+
if (Global.disableViewing) {
browserWindow.setEnabled(false);
return;
}
inkNote = false;
- if (!Global.showDeleted)
- browserWindow.setReadOnly(false);
+ readOnly = false;
+ if (Global.showDeleted)
+ readOnly = true;
Global.cryptCounter =0;
if (currentNoteGuid.equals("")) {
browserWindow.setReadOnly(true);
if (formatter.resourceError)
resourceErrorMessage();
- inkNote = formatter.readOnly;
- if (inkNote)
+ readOnly = formatter.readOnly;
+ inkNote = formatter.inkNote;
+ if (readOnly)
readOnlyCache.put(currentNoteGuid, true);
+ if (inkNote)
+ inkNoteCache.put(currentNoteGuid, true);
} else {
logger.log(logger.HIGH, "Note content is being pulled from the cache");
String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(currentNoteGuid));
js = new QByteArray(cachedContent);
browser.getBrowser().setContent(js);
if (readOnlyCache.containsKey(currentNoteGuid))
+ readOnly = true;
+ if (inkNoteCache.containsKey(currentNoteGuid))
inkNote = true;
}
if (conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) {
thumbnailHTMLReady(currentNoteGuid, js, Global.calculateThumbnailZoom(js.toString()));
}
-
- browser.getBrowser().page().setContentEditable(!inkNote); // We don't allow editing of ink notes
+ if (readOnly || inkNote)
+ browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
+ else
+ browser.getBrowser().page().setContentEditable(true);
+ browser.setReadOnly(readOnly);
+ deleteButton.setEnabled(!readOnly);
+ tagButton.setEnabled(!readOnly);
+ menuBar.noteDelete.setEnabled(!readOnly);
+ menuBar.noteTags.setEnabled(!readOnly);
browser.setNote(currentNote);
+ if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {
+ deleteButton.setEnabled(false);
+ menuBar.notebookDeleteAction.setEnabled(false);
+ } else {
+ deleteButton.setEnabled(true);
+ menuBar.notebookDeleteAction.setEnabled(true);
+ }
+
// Build a list of non-closed notebooks
List<Notebook> nbooks = new ArrayList<Notebook>();
for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
nbooks.add(listManager.getNotebookIndex().get(i));
}
- browser.setNotebookList(nbooks);
+// 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());
else
browser.setSubjectDate(currentNote.getCreated());
browser.setUrl(currentNote.getAttributes().getSourceURL());
- browser.setAllTags(listManager.getTagIndex());
+
+// browser.setAllTags(listManager.getTagIndex());
+ FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
+ List<Tag> tagList = tagFilter.getValidTags(currentNote);
+ browser.setAllTags(tagList);
+
browser.setCurrentTags(currentNote.getTagNames());
noteDirty = false;
scrollToGuid(currentNoteGuid);
logger.log(logger.EXTREME, "Leaving neverNote index timer");
}
+ @SuppressWarnings("unused")
private void indexStarted() {
setMessage(tr("Indexing notes"));
}
+ @SuppressWarnings("unused")
private void indexComplete() {
setMessage(tr("Index complete"));
}
private final List<String> tags;\r
private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
\r
- public TagAssign(List<Tag> allTags, List<String> selectedTags) {\r
+ public TagAssign(List<Tag> allTags, List<String> selectedTags, boolean permitNew) {\r
okClicked = false;\r
tags = new ArrayList<String>();\r
setWindowIcon(new QIcon(iconPath+"tag.png"));\r
addLayout.setStretch(0, 10);\r
addLayout.addWidget(newTagButton);\r
\r
+ if (!permitNew) {\r
+ newTagButton.setVisible(false);\r
+ newTag.setVisible(false);\r
+ }\r
+ \r
okButton = new QPushButton();\r
okButton.setText(tr("OK"));\r
okButton.pressed.connect(this, "onClicked()");\r
--- /dev/null
+/*\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.filters;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.evernote.edam.type.Note;\r
+import com.evernote.edam.type.Notebook;\r
+\r
+import cx.fbn.nevernote.sql.DatabaseConnection;\r
+import cx.fbn.nevernote.utilities.ApplicationLogger;\r
+\r
+public class FilterEditorNotebooks {\r
+ DatabaseConnection conn;\r
+ ApplicationLogger logger;\r
+ \r
+ public FilterEditorNotebooks(DatabaseConnection conn, ApplicationLogger logger) {\r
+ this.logger = logger;\r
+ this.conn = conn;\r
+ }\r
+ \r
+ \r
+ public List<Notebook> getValidNotebooks(Note note, List<Notebook> notebooks) {\r
+ \r
+ List<Notebook> books = new ArrayList<Notebook>();\r
+ for (int i=0; i<notebooks.size(); i++) \r
+ books.add(notebooks.get(i));\r
+ \r
+ // If this is a new note, it isn't tied to any particular notebook.h\r
+ if (note == null || note.getUpdateSequenceNum() == 0) {\r
+ for (int i=books.size()-1; i>=0; i--) {\r
+ if (conn.getNotebookTable().isReadOnly(books.get(i).getGuid()))\r
+ books.remove(i);\r
+ }\r
+ return books;\r
+ }\r
+ \r
+ boolean linked = conn.getNotebookTable().isLinked(note.getNotebookGuid());\r
+ \r
+ // If the notebook is linked, then we really only need to return the one notebookd\r
+ if (linked) {\r
+ List<Notebook> newList = new ArrayList<Notebook>();\r
+ for (int i=0; i<books.size(); i++) {\r
+ if (books.get(i).getGuid().equals(note.getNotebookGuid())) {\r
+ newList.add(books.get(i));\r
+ return newList;\r
+ }\r
+ }\r
+ } \r
+ // If the note's notebook isn't linked, then we need to return any non-linked notebook\r
+ List<Notebook> newList = new ArrayList<Notebook>();\r
+ for (int i=0; i<books.size(); i++) {\r
+ if (!conn.getNotebookTable().isLinked(books.get(i).getGuid())) {\r
+ newList.add(books.get(i));\r
+ }\r
+ }\r
+ return newList;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\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.filters;\r
+\r
+import java.util.List;\r
+\r
+import com.evernote.edam.type.Note;\r
+import com.evernote.edam.type.Tag;\r
+\r
+import cx.fbn.nevernote.sql.DatabaseConnection;\r
+import cx.fbn.nevernote.utilities.ApplicationLogger;\r
+\r
+public class FilterEditorTags {\r
+ DatabaseConnection conn;\r
+ ApplicationLogger logger;\r
+ public boolean permitNew;\r
+ \r
+ public FilterEditorTags(DatabaseConnection conn, ApplicationLogger logger) {\r
+ this.logger = logger;\r
+ this.conn = conn;\r
+ }\r
+ \r
+ \r
+ public List<Tag> getValidTags(Note note) {\r
+ // Reset permit new flag\r
+ permitNew = true;\r
+ \r
+ boolean linked = conn.getNotebookTable().isLinked(note.getNotebookGuid());\r
+ \r
+ // If the notebook is linked, then we really only need to return the one notebookd\r
+ if (linked) {\r
+ permitNew = false;\r
+ return conn.getTagTable().getTagsForNotebook(note.getNotebookGuid());\r
+ } else\r
+ return conn.getTagTable().getTagsForNotebook("");\r
+ }\r
+\r
+}\r
import com.trolltech.qt.gui.QListWidgetItem;\r
import com.trolltech.qt.gui.QMatrix;\r
import com.trolltech.qt.gui.QMessageBox;\r
+import com.trolltech.qt.gui.QPalette;\r
+import com.trolltech.qt.gui.QPalette.ColorRole;\r
import com.trolltech.qt.gui.QPushButton;\r
import com.trolltech.qt.gui.QShortcut;\r
import com.trolltech.qt.gui.QTimeEdit;\r
import cx.fbn.nevernote.dialog.TableDialog;\r
import cx.fbn.nevernote.dialog.TagAssign;\r
import cx.fbn.nevernote.evernote.EnCrypt;\r
+import cx.fbn.nevernote.filters.FilterEditorTags;\r
import cx.fbn.nevernote.signals.NoteResourceSignal;\r
import cx.fbn.nevernote.signals.NoteSignal;\r
import cx.fbn.nevernote.sql.DatabaseConnection;\r
\r
browser.page().microFocusChanged.connect(this, "microFocusChanged()");\r
\r
+ //Setup colors\r
+ \r
+ QPalette pal = new QPalette();\r
+ pal.setColor(ColorRole.Text, QColor.black);\r
+ titleLabel.setPalette(pal);\r
+ authorText.setPalette(pal);\r
+ authorLabel.setPalette(pal);\r
+ urlLabel.setPalette(pal);\r
+ urlText.setPalette(pal);\r
+ createdDate.setPalette(pal);\r
+ createdTime.setPalette(pal);\r
+ alteredDate.setPalette(pal);\r
+ alteredTime.setPalette(pal);\r
+ subjectDate.setPalette(pal);\r
+ subjectTime.setPalette(pal);\r
+ tagEdit.setPalette(pal);\r
+ notebookBox.setPalette(pal);\r
+ \r
logger.log(logger.HIGH, "Browser setup complete");\r
}\r
\r
createdDate.setEnabled(!v);\r
subjectDate.setEnabled(!v);\r
alteredDate.setEnabled(!v);\r
+ authorText.setEnabled(!v);\r
+ createdTime.setEnabled(!v);\r
+ alteredTime.setEnabled(!v);\r
+ subjectTime.setEnabled(!v);\r
getBrowser().setEnabled(true);\r
}\r
\r
// Modify a note's tags\r
@SuppressWarnings("unused")\r
private void modifyTags() {\r
- TagAssign tagWindow = new TagAssign(allTags, currentTags);\r
+ TagAssign tagWindow = new TagAssign(allTags, currentTags, !conn.getNotebookTable().isLinked(currentNote.getNotebookGuid()));\r
tagWindow.exec();\r
if (tagWindow.okClicked()) {\r
currentTags.clear();\r
if (!newTagArray[i].trim().equals(""))\r
newTagList.add(newTagArray[i]);\r
\r
+ if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {\r
+ for (int i=newTagList.size()-1; i>=0; i--) {\r
+ boolean found = false;\r
+ for (int j=0; j<allTags.size(); j++) {\r
+ if (allTags.get(j).getName().equalsIgnoreCase(newTagList.get(i))) {\r
+ found = true;\r
+ j=allTags.size();\r
+ }\r
+ }\r
+ if (!found)\r
+ newTagList.remove(i);\r
+ }\r
+ }\r
+\r
// Let's cleanup the appearance of the tag list\r
Collections.sort(newTagList);\r
String newDisplay = "";\r
for (int i = 0; i < notebookList.size(); i++) {\r
if (n.equals(notebookList.get(i).getName())) {\r
if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {\r
+ String guid = conn.getNotebookTable().findNotebookByName(n);\r
+ if (conn.getNotebookTable().isLinked(guid)) {\r
+ tagEdit.setText("");\r
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), new ArrayList<String>());\r
+ FilterEditorTags t = new FilterEditorTags(conn, logger);\r
+ setAllTags(t.getValidTags(currentNote));\r
+ }\r
currentNote.setNotebookGuid(notebookList.get(i).getGuid());\r
changed = true;\r
}\r
\r
notebookPublishAction = new QAction(tr("Share With The World"), this);\r
notebookPublishAction.setEnabled(false);\r
+ notebookPublishAction.setVisible(false);\r
notebookPublishAction.triggered.connect(parent, "publishNotebook()");\r
setupShortcut(notebookPublishAction, "File_Notebook_Publish");\r
\r
import java.util.HashMap;\r
import java.util.List;\r
\r
+import com.evernote.edam.type.Note;\r
import com.evernote.edam.type.Notebook;\r
import com.trolltech.qt.core.QByteArray;\r
import com.trolltech.qt.core.QMimeData;\r
return false;\r
}\r
\r
+ // This is really dead code. it is the beginning of logic to create stacks by\r
+ // dragging.\r
if (data.hasFormat("application/x-nevernote-notebook")) {\r
QByteArray d = data.data("application/x-nevernote-notebook");\r
String current = d.toString();\r
\r
// If we are dropping a note onto a notebook\r
if (data.hasFormat("application/x-nevernote-note")) {\r
+ // If we are dropping onto a read-only notebook, we are done.\r
+ if (db.getNotebookTable().isReadOnly(parent.text(2)))\r
+ return false;\r
+ \r
QByteArray d = data.data("application/x-nevernote-note");\r
String s = d.toString();\r
String noteGuidArray[] = s.split(" ");\r
for (String element : noteGuidArray) {\r
- if (!parent.text(0).equalsIgnoreCase("All Notebooks") && \r
- !parent.text(2).equalsIgnoreCase("STACK"))\r
+ Note n = db.getNoteTable().getNote(element.trim(), false, false, false, false, true);\r
+ \r
+ // We need to be sure that...\r
+ // 1.) We are not dropping onto the "All Notebooks" stack\r
+ // 2.) We are not dropping onto a stack\r
+ // 3.) We are actually dropping onto a different notebook.\r
+ if (!parent.text(2).equalsIgnoreCase("") && \r
+ !parent.text(2).equalsIgnoreCase(tr("STACK")) &&\r
+ !(n.getNotebookGuid().equalsIgnoreCase(parent.text(2))\r
+ )) {\r
noteSignal.notebookChanged.emit(element.trim(), parent.text(2));\r
+ if (db.getNotebookTable().isLinked(parent.text(2))) {\r
+ noteSignal.tagsChanged.emit(element.trim(), new ArrayList<String>());\r
+ }\r
+ }\r
}\r
return true;\r
}\r
currentCompleterSelection = null;\r
}\r
\r
+\r
public boolean hasChanged() {\r
return changed;\r
}\r
import java.util.HashMap;\r
import java.util.List;\r
\r
+import com.evernote.edam.type.Note;\r
import com.evernote.edam.type.Tag;\r
import com.trolltech.qt.core.QByteArray;\r
import com.trolltech.qt.core.QMimeData;\r
sortItems(0, SortOrder.AscendingOrder);\r
return true;\r
}\r
+ \r
+ // If we are dropping a note\r
if (data.hasFormat("application/x-nevernote-note")) {\r
+ String notebookGuid = db.getTagTable().getNotebookGuid(parent.text(2));\r
QByteArray d = data.data("application/x-nevernote-note");\r
String s = d.toString();\r
String noteGuidArray[] = s.split(" ");\r
for (String element : noteGuidArray) {\r
- if (!db.getNoteTable().noteTagsTable.checkNoteNoteTags(element.trim(), parent.text(2))) {\r
+ Note n = db.getNoteTable().getNote(element.trim(), false, false, false, false, false);\r
+ \r
+ // Check that...\r
+ // 1.) Check that tag isn't already assigned to that note\r
+ // 2.) Check that that tag is valid for that notebook or the tag isn't notebook specific\r
+ // 3.) Check that the notebook isn't read only.\r
+ if (!db.getNoteTable().noteTagsTable.checkNoteNoteTags(element.trim(), parent.text(2)) &&\r
+ (notebookGuid == null || n.getNotebookGuid().equalsIgnoreCase(notebookGuid) || notebookGuid.equals("")) &&\r
+ !db.getNotebookTable().isReadOnly(n.getNotebookGuid())) {\r
db.getNoteTable().noteTagsTable.saveNoteTag(element.trim(), parent.text(2));\r
noteSignal.tagsAdded.emit(element.trim(), parent.text(2));\r
}\r
executeSql("alter table notebook add column stack varchar");
executeSql("alter table notebook add column icon blob");
executeSql("alter table notebook add column readOnly boolean");
+ executeSql("alter table notebook add column linked boolean");
+
+ executeSql("alter table tag add column realname varchar");
+ executeSql("alter table tag add column linked boolean");
executeSql("alter table tag add column icon blob");
+ executeSql("alter table tag add column notebookguid varchar");
executeSql("alter table SavedSearch add column icon blob");
executeSql("create index NOTE_THUMBNAIL_INDEX on note (thumbnailneeded, guid);");
executeSql("create index NOTE_EXPUNGED_INDEX on note (isExpunged, guid);");
executeSql("create index NOTE_DUEDATE_INDEX on note (attributeSubjectDate, guid);");
executeSql("create index RESOURCES_GUID_INDEX on noteresources (noteGuid, guid);");
+ executeSql("create index TAG_NOTEBOOK_INDEX on tag (notebookGuid);");
+
executeSql("update note set thumbnailneeded=true, thumbnail=null;");
executeSql("update notebook set publishingUri='', " +
"publishingAscending=false, stack='', readonly=false, publishingOrder=1, " +
- "publishingPublicDescription=''");
+ "publishingPublicDescription='', linked=false");
+ executeSql("update tag set linked=false, realname='', notebookguid=''");
sharedNotebookTable.createTable();
linkedNotebookTable.createTable();
public InkImagesTable getInkImagesTable() {
return inkImagesTable;
}
+
}
"shareKey VarChar, " +\r
"uri VarChar, " +\r
"updateSequenceNumber Long," +\r
- "lastSequenceNumber Long," +\r
- "lastSequenceDate timestamp," +\r
- "icon blob, " +\r
+ "lastSequenceNumber Integer," +\r
+ "lastSequenceDate Long," +\r
+ "notebookGuid VarChar," +\r
"isDirty boolean)")) \r
logger.log(logger.HIGH, "Table LinkedNotebook creation FAILED!!!"); \r
}\r
query.exec("Drop table LinkedNotebook");\r
}\r
// Save an individual notebook\r
- public void addNotebook(LinkedNotebook tempNotebook, boolean isDirty) {\r
+ public void addNotebook(LinkedNotebook tempNotebook, boolean isDirty) {\r
boolean check;\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
check = query.prepare("Insert Into LinkedNotebook (guid, shareName, username, "\r
+"shardId, shareKey, uri, updateSequenceNumber, isDirty, lastSequenceNumber, "\r
- + "lastSequenceDate) " \r
+ + "lastSequenceDate, notebookGuid) " \r
+ " Values("\r
+":guid, :shareName, :username, "\r
- +":shardId, :shareKey, :uri,:usn, :isDirty, 0, '1969-12-31 19.00.00')");\r
+ +":shardId, :shareKey, :uri,:usn, :isDirty, 0, 0, :notebookGuid)");\r
query.bindValue(":guid", tempNotebook.getGuid());\r
query.bindValue(":shareName", tempNotebook.getShareName());\r
query.bindValue(":username", tempNotebook.getUsername());\r
query.bindValue(":shareKey", tempNotebook.getShareKey());\r
query.bindValue(":usn", tempNotebook.getUpdateSequenceNum());\r
query.bindValue(":uri", tempNotebook.getUri());\r
+ query.bindValue(":notebookGuid", "");\r
\r
if (isDirty)\r
query.bindValue(":isDirty", true);\r
if (!check) {\r
logger.log(logger.MEDIUM, "LinkedNotebook Table insert failed.");\r
logger.log(logger.MEDIUM, query.lastError().toString());\r
+ return;\r
}\r
}\r
// Delete the notebook based on a guid\r
public void expungeNotebook(String id, boolean needsSync) {\r
boolean check;\r
+ \r
+ // First, delete any tags associated with this notebook\r
+ String notebookGuid = getNotebookGuid(id);\r
+ db.getNotebookTable().deleteLinkedTags(notebookGuid);\r
+ \r
+ // Now, delete any notes associated with this notebook\r
+ List<String> notes = db.getNoteTable().getNotesByNotebook(notebookGuid);\r
+ for (int i=0; i<notes.size(); i++) {\r
+ db.getNoteTable().expungeNote(notes.get(i), true, needsSync);\r
+ }\r
+ \r
+ // Delete the notebook record\r
+ db.getNotebookTable().expungeNotebook(notebookGuid, needsSync);\r
+ \r
+ // Finally, delete the linked notebook object itself\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
-\r
check = query.prepare("delete from LinkedNotebook "\r
+"where guid=:guid");\r
if (!check) {\r
if (!check) \r
logger.log(logger.MEDIUM, "LinkedNotebook delete failed.");\r
\r
- // Signal the parent that work needs to be done\r
if (needsSync) {\r
DeletedTable deletedTable = new DeletedTable(logger, db);\r
deletedTable.addDeletedItem(new Long(id).toString(), "LinkedNotebook");\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
check = query.prepare("Update LinkedNotebook set guid=:guid, shareName=:shareName, " +\r
- "username=:username, shardID=:shardID, shareKey=:shareKey, uri=:uri, updateSequenceNumber=:usn, isDirty=:isDirty");\r
+ "username=:username, shardID=:shardID, shareKey=:shareKey, uri=:uri, updateSequenceNumber=:usn, isDirty=:isDirty "+\r
+ "where guid=:keyGuid");\r
query.bindValue(":guid", tempNotebook.getGuid());\r
+ query.bindValue(":keyGuid", tempNotebook.getGuid());\r
query.bindValue(":shareName", tempNotebook.getShareName());\r
query.bindValue(":username", tempNotebook.getUsername());\r
query.bindValue(":shardID", tempNotebook.getShardId());\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- check = query.exec("Select guid, shareName, username, shardID, shareKey uri, " +\r
+ check = query.exec("Select guid, shareName, username, shardID, shareKey, uri " +\r
" from LinkedNotebook");\r
if (!check)\r
logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
while (query.next()) {\r
tempNotebook = new LinkedNotebook();\r
tempNotebook.setGuid(query.valueString(0));\r
- tempNotebook.setUsername(query.valueString(1));\r
- tempNotebook.setShardId(query.valueString(2));\r
- tempNotebook.setShareKey(query.valueString(3));\r
- tempNotebook.setUri(query.valueString(4));\r
+ tempNotebook.setShareName(query.valueString(1));\r
+ tempNotebook.setUsername(query.valueString(2));\r
+ tempNotebook.setShardId(query.valueString(3));\r
+ tempNotebook.setShareKey(query.valueString(4));\r
+ tempNotebook.setUri(query.valueString(5));\r
\r
index.add(tempNotebook); \r
} \r
return index;\r
} \r
+ // Load notebooks from the database\r
+ public LinkedNotebook getNotebook(String guid) {\r
+ LinkedNotebook tempNotebook;\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid, shareName, username, shardID, shareKey, uri " +\r
+ " from LinkedNotebook where guid=:guid");\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL retrieve notebook prepare has failed.");\r
+ query.bindValue(":guid", guid);\r
+ query.exec();\r
+ while (query.next()) {\r
+ tempNotebook = new LinkedNotebook();\r
+ tempNotebook.setGuid(query.valueString(0));\r
+ tempNotebook.setShareName(query.valueString(1));\r
+ tempNotebook.setUsername(query.valueString(2));\r
+ tempNotebook.setShardId(query.valueString(3));\r
+ tempNotebook.setShareKey(query.valueString(4));\r
+ tempNotebook.setUri(query.valueString(5));\r
+ return tempNotebook;\r
+ } \r
+ return null;\r
+ } \r
+ // Load notebooks from the database\r
+ public LinkedNotebook getByNotebookGuid(String guid) {\r
+ LinkedNotebook tempNotebook;\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid, shareName, username, shardID, shareKey, uri " +\r
+ " from LinkedNotebook where notebookguid=:guid");\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL retrieve notebook prepare has failed.");\r
+ query.bindValue(":guid", guid);\r
+ query.exec();\r
+ while (query.next()) {\r
+ tempNotebook = new LinkedNotebook();\r
+ tempNotebook.setGuid(query.valueString(0));\r
+ tempNotebook.setShareName(query.valueString(1));\r
+ tempNotebook.setUsername(query.valueString(2));\r
+ tempNotebook.setShardId(query.valueString(3));\r
+ tempNotebook.setShareKey(query.valueString(4));\r
+ tempNotebook.setUri(query.valueString(5));\r
+ return tempNotebook;\r
+ } \r
+ return null;\r
+ }\r
+ // Get last sequence date for the notebook\r
+ public long getLastSequenceDate(String guid) {\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select LastSequenceDate " \r
+ +"from LinkedNotebook where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "LinkedNotebook SQL retrieve last sequence date has failed.");\r
+ if (query.next()) {\r
+ return query.valueLong(0);\r
+ } \r
+ return 0;\r
+ } \r
+ // Get a guid by uri\r
+ public String getNotebookGuid(String guid) {\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select notebookGuid " \r
+ +"from LinkedNotebook where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "LinkedNotebook SQL retrieve of notebookguid by guidhas failed.");\r
+ if (query.next()) {\r
+ return query.valueString(0);\r
+ } \r
+ return null;\r
+ } \r
+ // get last sequence numeber\r
+ public int getLastSequenceNumber(String guid) {\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select LastSequenceNumber " \r
+ +"from LinkedNotebook where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
+ while (query.next()) {\r
+ return query.valueInteger(0);\r
+ } \r
+ return 0;\r
+ } \r
\r
// does a record exist?\r
public String findNotebookByShareName(String name) {\r
return val;\r
}\r
\r
+ // does a record exist?\r
+ public String setNotebookGuid(String shareKey, String notebookGuid) {\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Update LinkedNotebook set notebookGuid=:notebookGuid where shareKey=:shareKey");\r
+ query.bindValue(":notebookGuid", notebookGuid);\r
+ query.bindValue(":shareKey", shareKey);\r
+ if (!query.exec())\r
+ logger.log(logger.EXTREME, "Linked notebook SQL retrieve by share name has failed.");\r
+ String val = null;\r
+ if (query.next())\r
+ val = query.valueString(0);\r
+ return val;\r
+ }\r
+ // set sync date\r
+ public String setLastSequenceDate(String guid, long date) {\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Update LinkedNotebook set lastsequencedate=:date where guid=:guid");\r
+ query.bindValue(":date", date);\r
+ query.bindValue(":guid", guid);\r
+ if (!query.exec())\r
+ logger.log(logger.EXTREME, "Linked notebook SQL retrieve by share name has failed.");\r
+ String val = null;\r
+ if (query.next())\r
+ val = query.valueString(0);\r
+ return val;\r
+ }\r
+ // set sync number\r
+ public String setLastSequenceNumber(String guid, int number) {\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Update LinkedNotebook set lastsequencenumber=:number where guid=:guid");\r
+ query.bindValue(":number", number);\r
+ query.bindValue(":guid", guid);\r
+ if (!query.exec())\r
+ logger.log(logger.EXTREME, "Linked notebook SQL retrieve by share name has failed.");\r
+ String val = null;\r
+ if (query.next())\r
+ val = query.valueString(0);\r
+ return val;\r
+ }\r
\r
// Get a list of linked notebooks that need to be updated\r
public List<String> getDirtyGuids() {\r
boolean check; \r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- check = query.exec("Select id from LinkedNotebook where isDirty = true");\r
+ check = query.exec("Select guid from LinkedNotebook where isDirty = true");\r
if (!check) \r
logger.log(logger.EXTREME, "LinkedNotebook SQL retrieve has failed in getdirtyIds.");\r
while (query.next()) {\r
boolean check; \r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true)");\r
+ check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true or linked = true)");\r
if (!check) \r
logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
\r
return notes; \r
}\r
// Get a list of notes that need to be updated\r
+ public List <Note> getDirtyLinked(String notebookGuid) {\r
+ String guid;\r
+ Note tempNote;\r
+ List<Note> notes = new ArrayList<Note>();\r
+ List<String> index = new ArrayList<String>();\r
+ \r
+ boolean check; \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid=:notebookGuid");\r
+ query.bindValue(":notebookGuid", notebookGuid);\r
+ check = query.exec();\r
+ if (!check) \r
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed getting dirty linked notes: " +query.lastError().toString());\r
+ \r
+ // Get a list of the notes\r
+ while (query.next()) {\r
+ guid = new String();\r
+ guid = query.valueString(0);\r
+ index.add(guid); \r
+ } \r
+ \r
+ // Start getting notes\r
+ for (int i=0; i<index.size(); i++) {\r
+ tempNote = getNote(index.get(i), true,true,false,true,true);\r
+ notes.add(tempNote);\r
+ }\r
+ return notes; \r
+ }\r
+ // Get a list of notes that need to be updated\r
+ public List <String> getNotesByNotebook(String notebookGuid) {\r
+ List<String> notes = new ArrayList<String>();\r
+ List<String> index = new ArrayList<String>();\r
+ \r
+ boolean check; \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid from Note where notebookguid=:notebookguid");\r
+ if (!check) \r
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
+ query.bindValue(":notebookguid", notebookGuid);\r
+ query. exec();\r
+ \r
+ // Get a list of the notes\r
+ while (query.next()) {\r
+ index.add(query.valueString(0)); \r
+ } \r
+ \r
+ return notes; \r
+ }\r
+ // Get a list of notes that need to be updated\r
public boolean isNoteDirty(String guid) {\r
\r
boolean check; \r
boolean check; \r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- check = query.exec("Select guid from Note where isDirty = true");\r
+ check = query.exec("Select guid from Note where isDirty=true");\r
if (!check) \r
logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
\r
// Count unsynchronized notes\r
public int getDirtyCount() {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select count(*) from note where isDirty=true and isExpunged = false");\r
+ query.exec("select count(guid) from note where isDirty=true and isExpunged = false");\r
query.next(); \r
int returnValue = new Integer(query.valueString(0));\r
return returnValue;\r
}\r
\r
\r
- \r
// Update a note content's hash. This happens if a resource is edited outside of NN\r
public void updateResourceContentHash(String guid, String oldHash, String newHash) {\r
Note n = getNote(guid, true, false, false, false,false);\r
db = d;\r
dbName = "Notebook";\r
}\r
+ // Constructor\r
+ public NotebookTable(ApplicationLogger l, DatabaseConnection d, String name) {\r
+ logger = l;\r
+ db = d;\r
+ dbName = name;\r
+ }\r
+\r
// Create the table\r
public void createTable(boolean addDefaulte) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
}\r
// Save an individual notebook\r
public void addNotebook(Notebook tempNotebook, boolean isDirty, boolean local) {\r
+ addNotebook(tempNotebook, isDirty, local, false, false);\r
+ }\r
+ // Save an individual notebook\r
+ public void addNotebook(Notebook tempNotebook, boolean isDirty, boolean local, boolean linked, boolean readOnly) {\r
boolean check;\r
\r
SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
+"serviceCreated, serviceUpdated, published, " \r
+ "publishingUri, publishingOrder, publishingAscending, publishingPublicDescription, "\r
+ "isDirty, autoEncrypt, stack, " \r
- + "local, archived, readOnly) Values("\r
+ + "local, archived, readOnly, linked) Values("\r
+":guid, :sequence, :name, :defaultNotebook, "\r
+":serviceCreated, :serviceUpdated, :published, "\r
+":publishingUri, :publishingOrder, :publishingAscending, :publishingPublicDescription, "\r
+":isDirty, :autoEncrypt, "\r
- +":stack, :local, false, false)");\r
+ +":stack, :local, false, :readOnly, :linked)");\r
query.bindValue(":guid", tempNotebook.getGuid());\r
query.bindValue(":sequence", tempNotebook.getUpdateSequenceNum());\r
query.bindValue(":name", tempNotebook.getName());\r
query.bindValue(":serviceCreated", serviceCreated.toString());\r
query.bindValue(":serviceUpdated", serviceCreated.toString());\r
query.bindValue(":published",tempNotebook.isPublished());\r
+ query.bindValue(":linked", linked);\r
+ query.bindValue(":readOnly", readOnly);\r
\r
if (tempNotebook.isPublished() && tempNotebook.getPublishing() != null) {\r
Publishing p = tempNotebook.getPublishing();\r
boolean returnValue = query.valueBoolean(0, false);\r
return returnValue;\r
}\r
+ // Check for a local/remote notebook\r
+ public boolean isNotebookLinked(String guid) {\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Select linked from "+dbName+" where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ query.exec();\r
+ if (!query.next()) {\r
+ return false;\r
+ }\r
+ boolean returnValue = query.valueBoolean(0, false);\r
+ return returnValue;\r
+ }\r
public boolean isReadOnly(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- query.prepare("Select readOnly from "+dbName+" where guid=:guid and readOnly='true'");\r
+ query.prepare("Select readOnly from "+dbName+" where guid=:guid and readOnly=true");\r
query.bindValue(":guid", guid);\r
query.exec();\r
if (!query.next()) {\r
if (!query.exec()) {\r
logger.log(logger.MEDIUM, "Update WatchFolder notebook failed.");\r
logger.log(logger.MEDIUM, query.lastError().toString());\r
- } \r
+ }\r
}\r
// Get a list of notes that need to be updated\r
public List <Notebook> getDirty() {\r
List<Notebook> index = new ArrayList<Notebook>();\r
boolean check;\r
\r
- \r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
check = query.exec("Select guid, sequence, name, defaultNotebook, " +\r
"serviceCreated, serviceUpdated, published, stack, "+\r
"publishinguri, publishingascending, publishingPublicDescription, "+\r
"publishingOrder " +\r
- "from "+dbName+" where isDirty = true and local=false");\r
+ "from "+dbName+" where isDirty=true and local=false and linked=false");\r
if (!check) \r
logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
while (query.next()) {\r
tempNotebook.setName(query.valueString(2));\r
\r
DateFormat indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
-// indfm = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");\r
try {\r
tempNotebook.setServiceCreated(indfm.parse(query.valueString(4)).getTime());\r
tempNotebook.setServiceUpdated(indfm.parse(query.valueString(5)).getTime());\r
}\r
updateNotebook(notebook, isDirty);\r
}\r
+ // This is a convience method to check if a tag exists & update/create based upon it\r
+ public void syncLinkedNotebook(Notebook notebook, boolean isDirty, boolean readOnly) {\r
+ if (!exists(notebook.getGuid())) {\r
+ addNotebook(notebook, isDirty, false, true, readOnly);\r
+ return;\r
+ }\r
+ updateNotebook(notebook, isDirty);\r
+ }\r
// does a record exist?\r
private boolean exists(String guid) {\r
\r
public void setDefaultNotebook(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- query.prepare("Update "+dbName+" set defaultNotebook=false");\r
+ query.prepare("Update "+dbName+" set defaultNotebook=false where linked=false");\r
if (!query.exec())\r
logger.log(logger.EXTREME, "Error removing default "+dbName+".");\r
- query.prepare("Update "+dbName+" set defaultNotebook=true where guid = :guid");\r
+ query.prepare("Update "+dbName+" set defaultNotebook=true where guid=:guid where linked=false");\r
query.bindValue(":guid", guid);\r
if (!query.exec())\r
logger.log(logger.EXTREME, "Error setting default "+dbName+".");\r
if (!query.exec())\r
logger.log(logger.EXTREME, "Error setting "+dbName+" stack.");\r
}\r
+ // Get a notebook by uri\r
+ public String getNotebookByUri(String uri) {\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid " \r
+ +"from "+dbName+" where publishingUri=:uri");\r
+ query.bindValue(":uri", uri);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL retrieve guid by uri has failed.");\r
+ if (query.next()) {\r
+ return query.valueString(0);\r
+ } \r
+ return null;\r
+ } \r
+ // Is a notebook a linked notebook?\r
+ public boolean isLinked(String guid) {\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid " \r
+ +"from "+dbName+" where guid=:guid and linked=true");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL isLinked failed.");\r
+ if (query.next()) {\r
+ return true;\r
+ } \r
+ return false;\r
+ }\r
+\r
+ // Given a notebook, what tags are valid for it?\r
+ public List<String> getValidLinkedTags(String guid) {\r
+ boolean check;\r
+ List<String> tags = new ArrayList<String>();\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection()); \r
+ check = query.prepare("select distinct tagGuid from noteTags " +\r
+ "where noteGuid in " +\r
+ "(SELECT guid from note where notebookguid=:guid)");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+ while (query.next()) {\r
+ tags.add(query.valueString(0));\r
+ } \r
+ return tags;\r
+ \r
+ \r
+ }\r
+ // Given a notebook, what tags are valid for it?\r
+ public void deleteLinkedTags(String guid) {\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection()); \r
+ query.prepare("select distinct tagguid from noteTags " +\r
+ "where noteGuid in " +\r
+ "(SELECT guid from note where notebookguid=:guid)");\r
+ query.bindValue(":guid", guid);\r
+ boolean check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+ while(query.next()) {\r
+ db.getTagTable().expungeTag(query.valueString(0), false);\r
+ }\r
+ \r
+ \r
+ query.prepare("delete from note " +\r
+ "where notebookguid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check)\r
+ logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+\r
+ \r
+ return;\r
+ \r
+ \r
+ }\r
}\r
\r
deletedTable.addDeletedItem(new Long(id).toString(), "SharedNotebook");\r
}\r
}\r
+ // Delete the notebook based on a id\r
+ public void expungeNotebookByGuid(String id, boolean needsSync) {\r
+ boolean check;\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+\r
+ check = query.prepare("delete from SharedNotebook "\r
+ +"where guid=:id");\r
+ if (!check) {\r
+ logger.log(logger.EXTREME, "SharedNotebook SQL delete by notebook guid prepare has failed.");\r
+ logger.log(logger.EXTREME, query.lastError().toString());\r
+ }\r
+ query.bindValue(":id", id);\r
+ check = query.exec();\r
+ if (!check) \r
+ logger.log(logger.MEDIUM, "SharedNotebook delete by notebook guid failed.");\r
+ \r
+ // Signal the parent that work needs to be done\r
+ if (needsSync) {\r
+ DeletedTable deletedTable = new DeletedTable(logger, db);\r
+ deletedTable.addDeletedItem(new Long(id).toString(), "SharedNotebook");\r
+ }\r
+ }\r
\r
\r
// Update a notebook\r
query.exec("Drop table Tag");\r
\r
}\r
+ // Get tags for a specific notebook\r
+ // get all tags\r
+ public List<Tag> getTagsForNotebook(String notebookGuid) {\r
+ \r
+ Tag tempTag;\r
+ List<Tag> index = new ArrayList<Tag>();\r
+ boolean check;\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid, parentGuid, sequence, name"\r
+ +" from Tag where notebookGuid=:notebookGuid");\r
+ if (!check) {\r
+ logger.log(logger.EXTREME, "Tag SQL prepare getTagsForNotebook has failed.");\r
+ logger.log(logger.EXTREME, query.lastError());\r
+ }\r
+ query.bindValue(":notebookGuid", notebookGuid);\r
+ query.exec();\r
+ while (query.next()) {\r
+ tempTag = new Tag();\r
+ tempTag.setGuid(query.valueString(0));\r
+ if (query.valueString(1) != null)\r
+ tempTag.setParentGuid(query.valueString(1));\r
+ else\r
+ tempTag.setParentGuid(null);\r
+ int sequence = new Integer(query.valueString(2)).intValue();\r
+ tempTag.setUpdateSequenceNum(sequence);\r
+ tempTag.setName(query.valueString(3));\r
+ index.add(tempTag); \r
+ } \r
+ \r
+ return index;\r
+ }\r
// get all tags\r
public List<Tag> getAll() {\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
check = query.exec("Select guid, parentGuid, sequence, name"\r
- +" from Tag");\r
+ +" from Tag where notebookguid not in (select guid from notebook where archived=true)");\r
if (!check) {\r
logger.log(logger.EXTREME, "Tag SQL retrieve has failed.");\r
logger.log(logger.EXTREME, query.lastError());\r
}\r
// Update a tag\r
public void updateTag(Tag tempTag, boolean isDirty) {\r
+ updateTag(tempTag, isDirty, "");\r
+ }\r
+ // Update a tag\r
+ public void updateTag(Tag tempTag, boolean isDirty, String realName) {\r
boolean check;\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
}\r
// Save a tag\r
public void addTag(Tag tempTag, boolean isDirty) {\r
+ addTag(tempTag, isDirty, false, "", "");\r
+ }\r
+ // Save a tag\r
+ public void addTag(Tag tempTag, boolean isDirty, boolean isLinked, String realName, String notebookGuid) {\r
boolean check;\r
\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
- check = query.prepare("Insert Into Tag (guid, parentGuid, sequence, hashCode, name, isDirty)"\r
- +" Values(:guid, :parentGuid, :sequence, :hashCode, :name, :isDirty)");\r
+ check = query.prepare("Insert Into Tag (guid, parentGuid, sequence, hashCode, name, isDirty, linked, realName, notebookGuid)"\r
+ +" Values(:guid, :parentGuid, :sequence, :hashCode, :name, :isDirty, :linked, :realName, :notebookGuid)");\r
if (!check) {\r
logger.log(logger.EXTREME, "Tag SQL insert prepare has failed.");\r
logger.log(logger.EXTREME, query.lastError());\r
query.bindValue(":hashCode", tempTag.hashCode());\r
query.bindValue(":name", tempTag.getName());\r
query.bindValue(":isDirty", isDirty);\r
+ query.bindValue(":linked", isLinked);\r
+ query.bindValue(":realName", realName);\r
+ query.bindValue(":notebookGuid", notebookGuid);\r
\r
check = query.exec();\r
if (!check) {\r
val = query.valueString(0);\r
return val;\r
}\r
+ // Get the linked notebook guid for this tag\r
+ public String getNotebookGuid(String guid) {\r
+ \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.prepare("Select notebookguid from tag where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ if (!query.exec())\r
+ logger.log(logger.EXTREME, "Tag SQL retrieve has failed.");\r
+ String val = null;\r
+ if (query.next())\r
+ val = query.valueString(0);\r
+ return val;\r
+ }\r
// given a guid, does the tag exist\r
public boolean exists(String guid) {\r
\r
return retval;\r
}\r
// This is a convience method to check if a tag exists & update/create based upon it\r
+ public void syncLinkedTag(Tag tag, String notebookGuid, boolean isDirty) {\r
+ if (exists(tag.getGuid())) {\r
+ Tag t = getTag(tag.getGuid());\r
+ String realName = tag.getName();\r
+ tag.setName(t.getName());\r
+ updateTag(tag, isDirty, realName);\r
+ }\r
+ else\r
+ addTag(tag, isDirty, true, tag.getName(), notebookGuid);\r
+ }\r
+\r
+ // This is a convience method to check if a tag exists & update/create based upon it\r
public void syncTag(Tag tag, boolean isDirty) {\r
if (exists(tag.getGuid()))\r
updateTag(tag, isDirty);\r
return values;\r
}\r
\r
+ // Remove unused tags that are linked tags\r
+ public void removeUnusedLinkedTags() {\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.exec("Delete from tag where linked=true and guid not in (select distinct tagguid from notetags);");\r
+ }\r
+ \r
+ public void cleanupTags() {\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ query.exec("Update tag set parentguid=null where parentguid not in (select distinct guid from tag);"); \r
+ }\r
}\r
private THttpClient userStoreTrans;\r
private TBinaryProtocol userStoreProt;\r
private AuthenticationResult authResult;\r
+ private AuthenticationResult linkedAuthResult;\r
private User user; \r
private long authTimeRemaining;\r
public long authRefreshTime;\r
if (syncInkNoteImages != null) {\r
List<String> guids = conn.getNoteTable().noteResourceTable.findInkNotes();\r
for (int i=0; i<guids.size(); i++) {\r
- downloadInkNoteImage(guids.get(i));\r
+ downloadInkNoteImage(guids.get(i), authToken);\r
}\r
conn.getSyncTable().deleteRecord("FullInkNoteImageSync");\r
}\r
syncRemoteToLocal();\r
}\r
\r
+ //*****************************************\r
+ //* Sync linked/shared notebooks \r
+ //*****************************************\r
+ syncLinkedNotebooks();\r
+ \r
if (!disableUploads) {\r
logger.log(logger.EXTREME, "Uploading changes");\r
// Synchronize remote changes\r
syncLocalTags();\r
if (!error)\r
syncLocalNotebooks();\r
+ if (!error)\r
+ syncLocalLinkedNotebooks();\r
if (!error) \r
syncDeletedNotes();\r
if (!error)\r
if (!error)\r
syncLocalSavedSearches();\r
}\r
+ \r
+ //*****************************************\r
+ //* End of synchronization\r
+ //*****************************************\r
if (refreshNeeded)\r
syncSignal.refreshLists.emit();\r
\r
List<Note> notes = conn.getNoteTable().getDirty();\r
// Sync the local notebooks with Evernote's\r
for (int i=0; i<notes.size() && keepRunning; i++) {\r
+ syncLocalNote(notes.get(i), authToken);\r
+ }\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+\r
+ }\r
+ // Sync notes with Evernote\r
+ private void syncLocalNote(Note enNote, String token) {\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+ status.message.emit(tr("Sending local notes."));\r
+\r
+ if (authRefreshNeeded)\r
+ refreshConnection();\r
\r
- if (authRefreshNeeded)\r
- refreshConnection();\r
- \r
- Note enNote = notes.get(i);\r
- if (enNote.isActive()) {\r
- try {\r
- logger.log(logger.EXTREME, "Active dirty note found - non new");\r
- if (enNote.getUpdateSequenceNum() > 0) {\r
- enNote = getNoteContent(enNote);\r
- logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- enNote = noteStore.updateNote(authToken, enNote);\r
- } else { \r
- logger.log(logger.EXTREME, "Active dirty found - new note");\r
- logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- String oldGuid = enNote.getGuid();\r
- enNote = getNoteContent(enNote);\r
- enNote = noteStore.createNote(authToken, enNote);\r
- noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());\r
- conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());\r
- }\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Saving note");\r
- conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
- List<Resource> rl = enNote.getResources();\r
- logger.log(logger.EXTREME, "Getting note resources");\r
- for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {\r
- Resource newRes = rl.get(j);\r
- Data d = newRes.getData();\r
- if (d!=null) { \r
- logger.log(logger.EXTREME, "Calculating resource hash");\r
- String hash = byteArrayToHexString(d.getBodyHash());\r
- logger.log(logger.EXTREME, "updating resources by hash");\r
- String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);\r
- conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);\r
- resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());\r
- }\r
+ if (enNote.isActive()) {\r
+ try {\r
+ logger.log(logger.EXTREME, "Active dirty note found - non new");\r
+ if (enNote.getUpdateSequenceNum() > 0) {\r
+ enNote = getNoteContent(enNote);\r
+ logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
+ enNote = noteStore.updateNote(token, enNote);\r
+ } else { \r
+ logger.log(logger.EXTREME, "Active dirty found - new note");\r
+ logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
+ String oldGuid = enNote.getGuid();\r
+ enNote = getNoteContent(enNote);\r
+ enNote = noteStore.createNote(token, enNote);\r
+ noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());\r
+ conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());\r
+ }\r
+ updateSequenceNumber = enNote.getUpdateSequenceNum();\r
+ logger.log(logger.EXTREME, "Saving note");\r
+ conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
+ List<Resource> rl = enNote.getResources();\r
+ logger.log(logger.EXTREME, "Getting note resources");\r
+ for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {\r
+ Resource newRes = rl.get(j);\r
+ Data d = newRes.getData();\r
+ if (d!=null) { \r
+ logger.log(logger.EXTREME, "Calculating resource hash");\r
+ String hash = byteArrayToHexString(d.getBodyHash());\r
+ logger.log(logger.EXTREME, "updating resources by hash");\r
+ String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);\r
+ conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);\r
+ resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());\r
}\r
- logger.log(logger.EXTREME, "Resetting note dirty flag");\r
- conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Emitting note sequence number change");\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
-\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e.getParameter());\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
}\r
+ logger.log(logger.EXTREME, "Resetting note dirty flag");\r
+ conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
+ updateSequenceNumber = enNote.getUpdateSequenceNum();\r
+ logger.log(logger.EXTREME, "Emitting note sequence number change");\r
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
+\r
+ } catch (EDAMUserException e) {\r
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error sending local note: ") +e.getParameter());\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (EDAMSystemException e) {\r
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (EDAMNotFoundException e) {\r
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
+ status.message.emit(tr("Error sending local note: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (TException e) {\r
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error sending local note: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
}\r
}\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNote");\r
\r
}\r
+\r
// Sync Notebooks with Evernote\r
private void syncLocalNotebooks() {\r
logger.log(logger.HIGH, "Entering SyncRunner.syncLocalNotebooks");\r
}\r
logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalTags");\r
}\r
- // Sync Tags with Evernote\r
+ private void syncLocalLinkedNotebooks() {\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalLinkedNotebooks");\r
+ \r
+ List<String> list = conn.getLinkedNotebookTable().getDirtyGuids();\r
+ for (int i=0; i<list.size(); i++) {\r
+ LinkedNotebook book = conn.getLinkedNotebookTable().getNotebook(list.get(i));\r
+ try {\r
+ noteStore.updateLinkedNotebook(authToken, book);\r
+ } catch (EDAMUserException e) {\r
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalLinkedNotebooks");\r
+ }\r
+ // Sync Saved Searches with Evernote\r
private void syncLocalSavedSearches() {\r
logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");\r
List<SavedSearch> remoteList = new ArrayList<SavedSearch>();\r
syncRemoteTags(chunk.getTags());\r
syncRemoteSavedSearches(chunk.getSearches());\r
syncRemoteNotebooks(chunk.getNotebooks());\r
- syncRemoteNotes(chunk.getNotes(), fullSync);\r
+ syncRemoteNotes(chunk.getNotes(), fullSync, authToken);\r
syncRemoteResources(chunk.getResources());\r
syncRemoteLinkedNotebooks(chunk.getLinkedNotebooks());\r
+ syncExpungedNotes(chunk);\r
\r
- // Do the local deletes\r
- logger.log(logger.EXTREME, "Doing local deletes");\r
- List<String> guid = chunk.getExpungedNotes();\r
- if (guid != null) {\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- String notebookGuid = "";\r
- Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);\r
- if (localNote != null) {\r
- conn.getNoteTable().updateNoteSequence(guid.get(i), 0);\r
- notebookGuid = localNote.getNotebookGuid();\r
- }\r
- if (!conn.getNotebookTable().isNotebookLocal(notebookGuid)) {\r
- logger.log(logger.EXTREME, "Expunging local note from database");\r
- conn.getNoteTable().expungeNote(guid.get(i), true, false);\r
- }\r
- }\r
- }\r
- guid = chunk.getExpungedNotebooks();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging local notebook from database");\r
- conn.getNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedTags();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging tags from local database");\r
- conn.getTagTable().expungeTag(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedSearches();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging saved search from local database");\r
- conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedLinkedNotebooks();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging linked notebook from local database");\r
- conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
-\r
\r
// Check for more notes\r
if (chunk.getChunkHighUSN() <= updateSequenceNumber) \r
\r
logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal");\r
}\r
+ // Sync expunged notes\r
+ private void syncExpungedNotes(SyncChunk chunk) {\r
+ // Do the local deletes\r
+ logger.log(logger.EXTREME, "Doing local deletes");\r
+ List<String> guid = chunk.getExpungedNotes();\r
+ if (guid != null) {\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ String notebookGuid = "";\r
+ Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);\r
+ if (localNote != null) {\r
+ conn.getNoteTable().updateNoteSequence(guid.get(i), 0);\r
+ notebookGuid = localNote.getNotebookGuid();\r
+ }\r
+ if (!conn.getNotebookTable().isNotebookLocal(notebookGuid)) {\r
+ logger.log(logger.EXTREME, "Expunging local note from database");\r
+ conn.getNoteTable().expungeNote(guid.get(i), true, false);\r
+ }\r
+ }\r
+ }\r
+ guid = chunk.getExpungedNotebooks();\r
+ if (guid != null)\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging local notebook from database");\r
+ conn.getNotebookTable().expungeNotebook(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedTags();\r
+ if (guid != null)\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging tags from local database");\r
+ conn.getTagTable().expungeTag(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedSearches();\r
+ if (guid != null) \r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging saved search from local database");\r
+ conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedLinkedNotebooks();\r
+ if (guid != null) \r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging linked notebook from local database");\r
+ conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);\r
+ }\r
+\r
+ }\r
// Sync remote tags\r
private void syncRemoteTags(List<Tag> tags) {\r
logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
}\r
// Sync remote linked notebooks\r
private void syncRemoteLinkedNotebooks(List<LinkedNotebook> books) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches");\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks");\r
if (books != null) {\r
for (int i=0; i<books.size() && keepRunning; i++) {\r
conn.getLinkedNotebookTable().updateNotebook(books.get(i), false); \r
}\r
}\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncSavedSearches");\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncLinkedNotebooks");\r
}\r
// Sync remote Notebooks 2\r
private void syncRemoteNotebooks(List<Notebook> notebooks) {\r
if (oldGuid != null && !conn.getNotebookTable().isNotebookLocal(oldGuid) && !notebooks.get(i).getGuid().equalsIgnoreCase(oldGuid))\r
conn.getNotebookTable().updateNotebookGuid(oldGuid, notebooks.get(i).getGuid());\r
conn.getNotebookTable().syncNotebook(notebooks.get(i), false); \r
+ \r
+ // Synchronize shared notebook information\r
+// if (notebooks.get(i).getSharedNotebookIdsSize() > 0) {\r
+// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false);\r
+// for (int j=0; j<notebooks.get(i).getSharedNotebookIdsSize(); j++) {\r
+// syncRemoteSharedNotebook(notebooks.get(i).getGuid(), notebooks.get(i).getSharedNotebookIds().get(j), authToken);\r
+// }\r
+// }\r
}\r
} \r
logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
}\r
+ // Sync remote shared notebook\r
+// private void syncRemoteSharedNotebook(String guid, Long id, String token) {\r
+// List<SharedNotebook> books = noteStore.getSharedNotebookByAuth(authToken);\r
+// }\r
// Sync remote Resources\r
private void syncRemoteResources(List<Resource> resource) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");\r
+ if (resource != null) {\r
+ for (int i=0; i<resource.size() && keepRunning; i++) {\r
+ syncRemoteResource(resource.get(i), authToken);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");\r
+ }\r
+ // Sync remote resource\r
+ private void syncRemoteResource(Resource resource, String authToken) {\r
// This is how the logic for this works.\r
// 1.) If the resource is not in the local database, we add it.\r
// 2.) If a copy of the resource is in the local database and the note isn't dirty, we update the local copy\r
// 3.) If a copy of the resource is in the local databbase and it is dirty and the hash doesn't match, we ignore it because there\r
// is a conflict. The note conflict should get a copy of the resource at that time.\r
\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");\r
- if (resource != null) {\r
- for (int i=0; i<resource.size() && keepRunning; i++) {\r
- boolean saveNeeded = false;\r
-/* #1 */ Resource r = getEvernoteResource(resource.get(i).getGuid(), true,true,true);\r
- Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);\r
- if (l == null) {\r
- saveNeeded = true;\r
- } else {\r
-/* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());\r
- if (!isNoteDirty)\r
- saveNeeded = true;\r
- else {\r
-/* #3 */ String remoteHash = "";\r
- if (r != null && r.getData() != null && r.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(r.getData().getBodyHash());\r
- String localHash = "";\r
- if (l != null && l.getData() != null && l.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(l.getData().getBodyHash());\r
- \r
- if (localHash.equalsIgnoreCase(remoteHash))\r
+ boolean saveNeeded = false;\r
+ /* #1 */ Resource r = getEvernoteResource(resource.getGuid(), true,true,true, authToken);\r
+ Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);\r
+ if (l == null) {\r
saveNeeded = true;\r
- }\r
- }\r
- \r
- if (saveNeeded) \r
- conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);\r
- if (r.getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
- downloadInkNoteImage(r.getGuid());\r
+ } else {\r
+ /* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());\r
+ if (!isNoteDirty)\r
+ saveNeeded = true;\r
+ else {\r
+ /* #3 */ String remoteHash = "";\r
+ if (r != null && r.getData() != null && r.getData().getBodyHash() != null)\r
+ remoteHash = byteArrayToHexString(r.getData().getBodyHash());\r
+ String localHash = "";\r
+ if (l != null && l.getData() != null && l.getData().getBodyHash() != null)\r
+ remoteHash = byteArrayToHexString(l.getData().getBodyHash());\r
+ \r
+ if (localHash.equalsIgnoreCase(remoteHash))\r
+ saveNeeded = true;\r
+ }\r
+ }\r
+ \r
+ if (saveNeeded) \r
+ conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);\r
+ if (r.getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
+ downloadInkNoteImage(r.getGuid(), authToken);\r
\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");\r
}\r
// Sync remote notes\r
- private void syncRemoteNotes(List<Note> note, boolean fullSync) {\r
+ private void syncRemoteNotes(List<Note> note, boolean fullSync, String token) {\r
logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotes");\r
if (note != null) {\r
for (int i=0; i<note.size() && keepRunning; i++) {\r
- Note n = getEvernoteNote(note.get(i).getGuid(), true, fullSync, true,true);\r
- if (n!=null) {\r
- \r
- // Basically, this is how the sync logic for a note works.\r
- // If the remote note has changed and the local has not, we\r
- // accept the change.\r
- // If both the local & remote have changed but the sequence\r
- // numbers are the same, we don't accept the change. This\r
- // seems to happen when attachments are indexed by the server.\r
- // If both the local & remote have changed and the sequence numbers\r
- // are different we move the local copy to a local notebook (making sure\r
- // to copy all resources) and we accept the new one. \r
- boolean conflictingNote = true;\r
- logger.log(logger.EXTREME, "Checking for duplicate note " +n.getGuid());\r
- if (dirtyNoteGuids.contains(n.getGuid())) { \r
- logger.log(logger.EXTREME, "Conflict check beginning");\r
- conflictingNote = checkForConflict(n);\r
- logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);\r
- if (conflictingNote)\r
- moveConflictingNote(n.getGuid());\r
- }\r
- if (conflictingNote || fullSync) {\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
- noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index\r
- logger.log(logger.EXTREME, "Note Saved");\r
- if (fullSync && n.getResources() != null) {\r
- for (int q=0; q<n.getResources().size() && keepRunning; q++) {\r
- logger.log(logger.EXTREME, "Getting note resources.");\r
- conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);\r
- if (n.getResources().get(q).getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
- downloadInkNoteImage(n.getResources().get(q).getGuid());\r
- }\r
- }\r
+ Note n = getEvernoteNote(note.get(i).getGuid(), true, fullSync, true,true, token);\r
+ syncRemoteNote(n, fullSync, token);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");\r
+ }\r
+ private void syncRemoteNote(Note n, boolean fullSync, String token) {\r
+ if (n!=null) {\r
+ \r
+ // Basically, this is how the sync logic for a note works.\r
+ // If the remote note has changed and the local has not, we\r
+ // accept the change.\r
+ // If both the local & remote have changed but the sequence\r
+ // numbers are the same, we don't accept the change. This\r
+ // seems to happen when attachments are indexed by the server.\r
+ // If both the local & remote have changed and the sequence numbers\r
+ // are different we move the local copy to a local notebook (making sure\r
+ // to copy all resources) and we accept the new one. \r
+ boolean conflictingNote = true;\r
+ logger.log(logger.EXTREME, "Checking for duplicate note " +n.getGuid());\r
+ if (dirtyNoteGuids != null && dirtyNoteGuids.contains(n.getGuid())) { \r
+ logger.log(logger.EXTREME, "Conflict check beginning");\r
+ conflictingNote = checkForConflict(n);\r
+ logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);\r
+ if (conflictingNote)\r
+ moveConflictingNote(n.getGuid());\r
+ }\r
+ if (conflictingNote || fullSync) {\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
+ noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index\r
+ logger.log(logger.EXTREME, "Note Saved");\r
+ if (fullSync && n.getResources() != null) {\r
+ for (int q=0; q<n.getResources().size() && keepRunning; q++) {\r
+ logger.log(logger.EXTREME, "Getting note resources.");\r
+ conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);\r
+ if (n.getResources().get(q).getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
+ downloadInkNoteImage(n.getResources().get(q).getGuid(), token);\r
}\r
}\r
}\r
}\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");\r
}\r
- private Note getEvernoteNote(String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData) { \r
+ private Note getEvernoteNote(String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData, String token) { \r
Note n = null;\r
try {\r
logger.log(logger.EXTREME, "Retrieving note " +guid);\r
- n = noteStore.getNote(authToken, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);\r
+ n = noteStore.getNote(token, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);\r
logger.log(logger.EXTREME, "Note " +guid +" has been retrieved.");\r
} catch (EDAMUserException e) {\r
logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
}\r
return n;\r
}\r
- private Resource getEvernoteResource(String guid, boolean withData, boolean withRecognition, boolean withAttributes) { \r
+ private Resource getEvernoteResource(String guid, boolean withData, boolean withRecognition, boolean withAttributes, String token) { \r
Resource n = null;\r
try {\r
logger.log(logger.EXTREME, "Retrieving resource " +guid);\r
- n = noteStore.getResource(authToken, guid, withData, withRecognition, withAttributes, withAttributes);\r
+ n = noteStore.getResource(token, guid, withData, withRecognition, withAttributes, withAttributes);\r
logger.log(logger.EXTREME, "Resource " +guid +" has been retrieved.");\r
} catch (EDAMUserException e) {\r
logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
noteSignal.guidChanged.emit(guid,newGuid);\r
}\r
\r
- \r
+\r
\r
\r
//******************************************************\r
\r
boolean versionOk = false;\r
try {\r
-// versionOk = userStore.checkVersion("Dave's EDAMDemo (Java)", \r
versionOk = userStore.checkVersion("NeverNote", \r
com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR, \r
com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR);\r
}\r
\r
\r
- private void downloadInkNoteImage(String guid) {\r
+ private void downloadInkNoteImage(String guid, String authToken) {\r
String urlBase = noteStoreUrl.replace("/edam/note/", "/shard/") + "/res/"+guid+".ink?slice=";\r
// urlBase = "https://www.evernote.com/shard/s1/res/52b567a9-54ae-4a08-afc5-d5bae275b2a8.ink?slice=";\r
Integer slice = 1;\r
return data;\r
}\r
\r
+ \r
+ //******************************************\r
+ //* Begin syncing shared notebooks \r
+ //******************************************\r
+ private void syncLinkedNotebooks() {\r
+ logger.log(logger.MEDIUM, "Authenticating Shared Notebooks");\r
+ status.message.emit(tr("Synchronizing shared notebooks."));\r
+ List<LinkedNotebook> books = conn.getLinkedNotebookTable().getAll();\r
+ for (int i=0; i<books.size(); i++) {\r
+ try {\r
+ long lastSyncDate = conn.getLinkedNotebookTable().getLastSequenceDate(books.get(i).getGuid());\r
+ int lastSequenceNumber = conn.getLinkedNotebookTable().getLastSequenceNumber(books.get(i).getGuid());\r
+ linkedAuthResult = noteStore.authenticateToSharedNotebook(books.get(i).getShareKey(), authToken);\r
+ SyncState linkedSyncState = \r
+ noteStore.getLinkedNotebookSyncState(linkedAuthResult.getAuthenticationToken(), books.get(i));\r
+ if (linkedSyncState.getUpdateCount() > lastSequenceNumber) {\r
+ if (lastSyncDate < linkedSyncState.getFullSyncBefore()) {\r
+ lastSequenceNumber = 0;\r
+ }\r
+ syncLinkedNotebook(books.get(i), lastSequenceNumber, linkedSyncState.getUpdateCount());\r
+ }\r
+ \r
+ // Synchronize local changes\r
+ syncLocalLinkedNoteChanges(books.get(i));\r
+ \r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ status.message.emit(tr("Error synchronizing \" " +\r
+ books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook."));\r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ // Cleanup tags\r
+ conn.getTagTable().removeUnusedLinkedTags();\r
+ conn.getTagTable().cleanupTags();\r
+ tagSignal.listChanged.emit();\r
+ }\r
+\r
+ \r
+ //**************************************************************\r
+ //* Linked notebook contents (from someone else's account)\r
+ //*************************************************************\r
+ private void syncLinkedNotebook(LinkedNotebook book, int usn, int highSequence) {\r
+ boolean fullSync = false;\r
+ if (usn == 0)\r
+ fullSync = true;\r
+ while (usn < highSequence) {\r
+ try {\r
+ SyncChunk chunk = \r
+ noteStore.getLinkedNotebookSyncChunk(authToken, book, usn, 10, fullSync);\r
+// noteStore.getLinkedNotebookSyncChunk(linkedAuthResult.getAuthenticationToken(), book, usn, 10, fullSync);\r
+\r
+ syncRemoteNotes(chunk.getNotes(), fullSync, linkedAuthResult.getAuthenticationToken());\r
+ findNewLinkedTags(chunk.getNotes(), linkedAuthResult.getAuthenticationToken());\r
+ for (int i=0; i<chunk.getResourcesSize(); i++) {\r
+ syncRemoteResource(chunk.getResources().get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ syncRemoteLinkedNotebooks(chunk.getNotebooks(), false, book);\r
+// String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());\r
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ syncLinkedTags(chunk.getTags(), s.getNotebookGuid());\r
+ \r
+ \r
+ // Expunge records\r
+ for (int i=0; i<chunk.getExpungedLinkedNotebooksSize(); i++) {\r
+ conn.getLinkedNotebookTable().expungeNotebook(chunk.getExpungedLinkedNotebooks().get(i), false);\r
+ }\r
+ usn = chunk.getChunkHighUSN();\r
+ conn.getLinkedNotebookTable().setLastSequenceDate(book.getGuid(),chunk.getCurrentTime());\r
+ conn.getLinkedNotebookTable().setLastSequenceNumber(book.getGuid(),chunk.getChunkHighUSN());\r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ // Sync remote tags\r
+ private void syncLinkedTags(List<Tag> tags, String notebookGuid) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
+ if (tags != null) {\r
+ for (int i=0; i<tags.size() && keepRunning; i++) {\r
+ conn.getTagTable().syncLinkedTag(tags.get(i), notebookGuid, false);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");\r
+ }\r
+ \r
+ // Sync notebooks from a linked notebook\r
+ private void syncRemoteLinkedNotebooks(List<Notebook> notebooks, boolean readOnly, LinkedNotebook linked) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");\r
+ if (notebooks != null) {\r
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
+ try {\r
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ conn.getLinkedNotebookTable().setNotebookGuid(s.getShareKey(), s.getNotebookGuid());\r
+ readOnly = !s.isNotebookModifiable();\r
+ notebooks.get(i).setName(linked.getShareName());\r
+ notebooks.get(i).setDefaultNotebook(false);\r
+ conn.getNotebookTable().syncLinkedNotebook(notebooks.get(i), false, readOnly); \r
+ } catch (EDAMUserException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ } \r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
+ }\r
+\r
+ private void findNewLinkedTags(List<Note> newNotes, String token) {\r
+ if (newNotes == null)\r
+ return;\r
+ for (int i=0; i<newNotes.size(); i++) {\r
+ Note n = newNotes.get(i);\r
+ for (int j=0; j<n.getTagGuidsSize(); j++) {\r
+ String tag = n.getTagGuids().get(j);\r
+ if (!conn.getTagTable().exists(tag)) {\r
+ Tag newTag;\r
+ try {\r
+ newTag = noteStore.getTag(token, tag);\r
+ conn.getTagTable().addTag(newTag, false);\r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // Synchronize changes locally done to linked notes\r
+ private void syncLocalLinkedNoteChanges(LinkedNotebook book) {\r
+ String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());\r
+ List<Note> notes = conn.getNoteTable().getDirtyLinked(notebookGuid);\r
+ for (int i=0; i<notes.size(); i++) {\r
+ syncLocalNote(notes.get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ }\r
+\r
}\r
import java.util.List;\r
import java.util.Vector;\r
\r
+import com.evernote.edam.type.LinkedNotebook;\r
import com.evernote.edam.type.Note;\r
import com.evernote.edam.type.Notebook;\r
import com.evernote.edam.type.SavedSearch;\r
private List<Notebook> notebookIndex;\r
private List<Notebook> archiveNotebookIndex;\r
private List<String> localNotebookIndex;\r
+ \r
+ private List<LinkedNotebook> linkedNotebookIndex;\r
\r
private List<SavedSearch> searchIndex;\r
\r
// thumbnailList = conn.getNoteTable().getThumbnails();\r
// thumbnailList = new HashMap<String,QImage>();\r
\r
+ linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();\r
loadNoteTitleColors();\r
\r
}\r
\r
setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
\r
+ linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();\r
+ \r
enSearchChanged = true;\r
}\r
\r
+ public void reloadTagIndex() {\r
+ setTagIndex(conn.getTagTable().getAll()); \r
+ }\r
public void reloadIndexes() {\r
setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
\r
for (int i=0; i<local.size(); i++)\r
localNotebookIndex.add(local.get(i).getGuid());\r
\r
- // Load tags\r
- setTagIndex(conn.getTagTable().getAll());\r
+ reloadTagIndex();\r
// Load notebooks\r
setNotebookIndex(conn.getNotebookTable().getAll());\r
// load archived notebooks (if note using the EN interface)\r
//* selected notebooks\r
//***************************************************************\r
//***************************************************************\r
- // Return the selected notebook(s)\r
+ // Return the selected notebook(s)\r
public List<String> getSelectedNotebooks() {\r
return selectedNotebooks;\r
}\r
return notebookIndex;\r
\r
}\r
+ public List<LinkedNotebook> getLinkedNotebookIndex() {\r
+ return linkedNotebookIndex;\r
+ }\r
public List<Notebook> getArchiveNotebookIndex() {\r
return archiveNotebookIndex;\r
}\r
private final ApplicationLogger logger;\r
private final DatabaseConnection conn;\r
public boolean resourceError = false;\r
- public boolean readOnly = false;\r
+ public boolean readOnly = false; \r
+ public boolean inkNote = false;\r
public boolean addHighlight = true;\r
private Note currentNote;\r
private String currentNoteGuid;\r
public void setNote(Note note, boolean pdfPreview) {\r
currentNote = note;\r
this.pdfPreview = pdfPreview;\r
- if (note != null)\r
- currentNoteGuid = note.getGuid();\r
- else\r
- currentNoteGuid = null;\r
readOnly = false;\r
+ currentNoteGuid = null;\r
+ if (note != null) {\r
+ currentNoteGuid = note.getGuid();\r
+ readOnly = conn.getNotebookTable().isReadOnly(note.getNotebookGuid());\r
+ } \r
resourceError = false;\r
}\r
\r
Resource r = null;\r
if (resGuid != null)\r
r = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid,true);\r
- if (r==null || r.getData() == null || r.getData().getBody().length == 0)\r
- resourceError = true;;\r
+ if (r==null || r.getData() == null || r.getData().getBody().length == 0) {\r
+ resourceError = true;\r
+ readOnly = true;\r
+ }\r
if (r!= null && r.getData() != null && r.getData().getBody().length > 0) {\r
tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
QByteArray binData = new QByteArray(r.getData().getBody());\r
private void modifyApplicationTags(QDomDocument doc, QDomElement docElem, QDomElement enmedia, QDomAttr hash, String appl) {\r
logger.log(logger.HIGH, "Entering NeverNote.modifyApplicationTags");\r
if (appl.equalsIgnoreCase("vnd.evernote.ink")) {\r
- readOnly = true;\r
+ inkNote = true;\r
if (buildInkNote(doc, docElem, enmedia, hash, appl))\r
return;\r
}\r