X-Git-Url: http://git.sourceforge.jp/view?p=neighbornote%2FNeighborNote.git;a=blobdiff_plain;f=src%2Fcx%2Ffbn%2Fnevernote%2FNeverNote.java;h=988ae34025d8156e999dddd161eb3df486a87b82;hp=49505d175dbfc72a91e956bdc8ceabfe35a10f33;hb=84959c05f9a192c5e94acfa3c0738c79ccf306d8;hpb=421ecf1316e636317bc64dd3d283e1dce1bcfff9 diff --git a/src/cx/fbn/nevernote/NeverNote.java b/src/cx/fbn/nevernote/NeverNote.java index 49505d1..988ae34 100644 --- a/src/cx/fbn/nevernote/NeverNote.java +++ b/src/cx/fbn/nevernote/NeverNote.java @@ -43,6 +43,8 @@ import java.util.List; import java.util.SortedMap; import java.util.Vector; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.h2.tools.ChangeFileEncryption; @@ -52,9 +54,11 @@ import com.evernote.edam.error.EDAMUserException; 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 com.evernote.edam.type.Publishing; import com.evernote.edam.type.QueryFormat; import com.evernote.edam.type.Resource; import com.evernote.edam.type.SavedSearch; @@ -124,6 +128,9 @@ import com.trolltech.qt.gui.QTableWidgetItem; import com.trolltech.qt.gui.QTextEdit; import com.trolltech.qt.gui.QToolBar; import com.trolltech.qt.gui.QTreeWidgetItem; +import com.trolltech.qt.network.QNetworkAccessManager; +import com.trolltech.qt.network.QNetworkReply; +import com.trolltech.qt.network.QNetworkRequest; import com.trolltech.qt.webkit.QWebPage.WebAction; import com.trolltech.qt.webkit.QWebSettings; @@ -135,16 +142,22 @@ 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; import cx.fbn.nevernote.dialog.OnlineNoteHistory; +import cx.fbn.nevernote.dialog.PublishNotebook; import cx.fbn.nevernote.dialog.SavedSearchEdit; import cx.fbn.nevernote.dialog.SetIcon; +import cx.fbn.nevernote.dialog.ShareNotebook; import cx.fbn.nevernote.dialog.StackNotebook; import cx.fbn.nevernote.dialog.TagEdit; import cx.fbn.nevernote.dialog.ThumbnailViewer; +import cx.fbn.nevernote.dialog.UpgradeAvailableDialog; 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; @@ -187,6 +200,7 @@ public class NeverNote extends QMainWindow{ QAction trayExitAction; // Exit the application QAction trayShowAction; // toggle the show/hide action QAction trayAddNoteAction; // Add a note from the system tray + QNetworkAccessManager versionChecker; // Used when checking for new versions NotebookTreeWidget notebookTree; // List of notebooks AttributeTreeWidget attributeTree; // List of note attributes @@ -204,9 +218,7 @@ public class NeverNote extends QMainWindow{ ApplicationLogger logger; List selectedNotebookGUIDs; // List of notebook GUIDs List selectedTagGUIDs; // List of selected tag GUIDs - String previousSelectedTag; // Tag that was selected last time List selectedNoteGUIDs; // List of selected notes - String previousSelectedNotebook; // Notebook selected last time String selectedSavedSearchGUID; // Currently selected saved searches private final HashMap externalWindows; // Notes being edited by an external window; @@ -214,7 +226,9 @@ public class NeverNote extends QMainWindow{ 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 @@ -256,7 +270,7 @@ public class NeverNote extends QMainWindow{ QAction synchronizeButton; // Synchronize with Evernote QAction allNotesButton; // Reset & view all notes QTimer synchronizeAnimationTimer; // Timer to change animation button - double synchronizeIconAngle; // Used to rotate sync icon + int synchronizeIconAngle; // Used to rotate sync icon QAction printButton; // Print Button QAction tagButton; // Tag edit button QAction attributeButton; // Attribute information button @@ -287,6 +301,8 @@ public class NeverNote extends QMainWindow{ int saveThreadDeadCount=0; // number of consecutive dead times for the save thread HashMap noteCache; // Cash of note content + HashMap readOnlyCache; // List of cashe notes that are read-only + HashMap inkNoteCache; // List of cache notes that are ink notes List historyGuids; // GUIDs of previously viewed items int historyPosition; // Position within the viewed items boolean fromHistory; // Is this from the history queue? @@ -299,6 +315,10 @@ public class NeverNote extends QMainWindow{ Signal0 minimizeToTray; boolean windowMaximized = false; // Keep track of the window state for restores List pdfReadyQueue; // Queue of PDFs that are ready to be rendered. + List syncIcons; // Array of icons used in sync animation + private boolean closeAction = false; // Used to say when to close or when to minimize + private static Logger log = Logger.getLogger(NeverNote.class); + private String saveLastPath; // last path we used String iconPath = new String("classpath:cx/fbn/nevernote/icons/"); @@ -372,6 +392,7 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Building index runners & timers"); indexRunner = new IndexRunner("indexRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword); indexThread = new QThread(indexRunner, "Index Thread"); + indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally(); indexThread.start(); synchronizeAnimationTimer = new QTimer(); @@ -460,6 +481,8 @@ public class NeverNote extends QMainWindow{ // Setup the browser window noteCache = new HashMap(); + readOnlyCache = new HashMap(); + inkNoteCache = new HashMap(); browserWindow = new BrowserWindow(conn); mainLeftRightSplitter.addWidget(leftSplitter1); @@ -519,8 +542,12 @@ public class NeverNote extends QMainWindow{ notebookTree.setAddAction(menuBar.notebookAddAction); notebookTree.setIconAction(menuBar.notebookIconAction); notebookTree.setStackAction(menuBar.notebookStackAction); + notebookTree.setPublishAction(menuBar.notebookPublishAction); + notebookTree.setShareAction(menuBar.notebookShareAction); notebookTree.setVisible(Global.isWindowVisible("notebookTree")); notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)"); + 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); @@ -574,7 +601,7 @@ public class NeverNote extends QMainWindow{ trayExitAction = new QAction("Exit", this); trayAddNoteAction = new QAction("Add Note", this); - trayExitAction.triggered.connect(this, "close()"); + trayExitAction.triggered.connect(this, "closeNeverNote()"); trayAddNoteAction.triggered.connect(this, "addNote()"); trayShowAction.triggered.connect(this, "trayToggleVisible()"); @@ -646,14 +673,18 @@ public class NeverNote extends QMainWindow{ historyGuids.add(currentNoteGuid); historyPosition = 1; + menuBar.blockSignals(true); + menuBar.narrowListView.blockSignals(true); + menuBar.wideListView.blockSignals(true); if (Global.getListView() == Global.View_List_Narrow) { menuBar.narrowListView.setChecked(true); -// narrowListView(); } else{ menuBar.wideListView.setChecked(true); -// wideListView(); } + menuBar.blockSignals(false); + menuBar.narrowListView.blockSignals(false); + menuBar.wideListView.blockSignals(false); if (Global.getListView() == Global.View_List_Wide) { browserIndexSplitter.addWidget(noteTableView); @@ -666,12 +697,13 @@ public class NeverNote extends QMainWindow{ int sortCol = Global.getSortColumn(); int sortOrder = Global.getSortOrder(); noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder)); - + if (Global.checkVersionUpgrade()) + checkForUpdates(); } - - + // Main entry point public static void main(String[] args) { + log.setLevel(Level.FATAL); QApplication.initialize(args); QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png"); QSplashScreen splash = new QSplashScreen(pixmap); @@ -689,7 +721,7 @@ public class NeverNote extends QMainWindow{ dbConn = setupDatabaseConnection(); // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running - Global.getFileManager().purgeResDirectory(); + Global.getFileManager().purgeResDirectory(true); } catch (InitializationException e) { // Fatal @@ -847,6 +879,11 @@ public class NeverNote extends QMainWindow{ // Exit point @Override public void closeEvent(QCloseEvent event) { + if (Global.minimizeOnClose() && !closeAction && Global.showTrayIcon()) { + event.ignore(); + hide(); + return; + } logger.log(logger.HIGH, "Entering NeverNote.closeEvent"); waitCursor(true); @@ -922,8 +959,14 @@ public class NeverNote extends QMainWindow{ Global.keepRunning = false; try { logger.log(logger.MEDIUM, "Waiting for indexThread to stop"); - indexRunner.thread().join(50); - logger.log(logger.MEDIUM, "Index thread has stopped"); + if (indexRunner.thread().isAlive()) + indexRunner.thread().join(50); + if (!indexRunner.thread().isAlive()) + logger.log(logger.MEDIUM, "Index thread has stopped"); + else { + logger.log(logger.MEDIUM, "Index thread still running - interrupting"); + indexRunner.thread().interrupt(); + } } catch (InterruptedException e1) { e1.printStackTrace(); } @@ -946,6 +989,11 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Leaving NeverNote.closeEvent"); } + @SuppressWarnings("unused") + private void closeNeverNote() { + closeAction = true; + close(); + } public void setMessage(String s) { logger.log(logger.HIGH, "Entering NeverNote.setMessage"); logger.log(logger.HIGH, "Message: " +s); @@ -966,9 +1014,10 @@ public class NeverNote extends QMainWindow{ } private void setupIndexListeners() { - indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)"); - indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)"); -// indexRunner.threadSignal.indexNeeded.connect(listManager, "setIndexNeeded(String, String, Boolean)"); +// indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)"); +// indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)"); + indexRunner.signal.indexStarted.connect(this, "indexStarted()"); + indexRunner.signal.indexFinished.connect(this, "indexComplete()"); } private void setupSyncSignalListeners() { syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()"); @@ -1031,6 +1080,7 @@ public class NeverNote extends QMainWindow{ indexTimer.start(indexTime); // reset indexing timer settings.exec(); + indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally(); if (Global.showTrayIcon()) trayIcon.show(); else @@ -1049,6 +1099,8 @@ public class NeverNote extends QMainWindow{ // if (!dateFormat.equals(Global.getDateFormat()) || // !timeFormat.equals(Global.getTimeFormat())) { noteCache.clear(); + readOnlyCache.clear(); + inkNoteCache.clear(); noteIndexUpdated(true); // } @@ -1079,8 +1131,15 @@ public class NeverNote extends QMainWindow{ } // Load the style sheet private void loadStyleSheet() { - String fileName = Global.getFileManager().getQssDirPath("default.qss"); + String fileName = Global.getFileManager().getQssDirPathUser("default.qss"); + fileName = Global.getFileManager().getQssDirPath("default.qss"); QFile file = new QFile(fileName); + + // If a user default.qss doesn't exist, we use the one shipped with NeverNote + if (!file.exists()) { + fileName = Global.getFileManager().getQssDirPath("default.qss"); + file = new QFile(fileName); + } file.open(OpenModeFlag.ReadOnly); String styleSheet = file.readAll().toString(); file.close(); @@ -1150,7 +1209,8 @@ public class NeverNote extends QMainWindow{ // Setup the tree containing the user's notebooks. private void initializeNotebookTree() { logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree"); - notebookTree.itemClicked.connect(this, "notebookTreeSelection()"); +// notebookTree.itemClicked.connect(this, "notebookTreeSelection()"); + notebookTree.selectionSignal.connect(this, "notebookTreeSelection()"); listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)"); logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree"); } @@ -1168,68 +1228,41 @@ public class NeverNote extends QMainWindow{ menuBar.noteRestoreAction.setVisible(false); menuBar.notebookEditAction.setEnabled(true); menuBar.notebookDeleteAction.setEnabled(true); + menuBar.notebookPublishAction.setEnabled(true); + menuBar.notebookShareAction.setEnabled(true); menuBar.notebookIconAction.setEnabled(true); menuBar.notebookStackAction.setEnabled(true); List selections = notebookTree.selectedItems(); - QTreeWidgetItem currentSelection; selectedNotebookGUIDs.clear(); - if (!Global.mimicEvernoteInterface) { - for (int i=0; i 1) - previousSelectedNotebook = ""; + String guid = ""; + String stackName = ""; + if (selections.size() > 0) { + guid = (selections.get(0).text(2)); + stackName = selections.get(0).text(0); + } + if (!Global.mimicEvernoteInterface) { + // If no notebooks are selected, we make it look like the "all notebooks" one was selected + if (selections.size()==0) { + selectedNotebookGUIDs.clear(); + for (int i=0; i < listManager.getNotebookIndex().size(); i++) { + selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid()); + } + menuBar.notebookEditAction.setEnabled(false); + menuBar.notebookDeleteAction.setEnabled(false); + menuBar.notebookStackAction.setEnabled(false); + menuBar.notebookIconAction.setEnabled(false); + } + } + if (!guid.equals("") && !guid.equals("STACK")) { + selectedNotebookGUIDs.add(guid); + menuBar.notebookIconAction.setEnabled(true); } else { - String guid = ""; - String stackName = ""; - if (selections.size() > 0) { - guid = (selections.get(0).text(2)); - stackName = selections.get(0).text(0); - } - if (!guid.equals("") && !guid.equals("STACK")) { - selectedNotebookGUIDs.add(guid); - menuBar.notebookIconAction.setEnabled(true); - } - else { - menuBar.notebookIconAction.setEnabled(true); - for (int j=0; j filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex()); + browserWindow.setNotebookList(filteredBooks); + Iterator set = externalWindows.keySet().iterator(); + while(set.hasNext()) + externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks); logger.log(logger.HIGH, "Leaving NeverNote.editNotebook"); } + // Publish a notebook + @SuppressWarnings("unused") + private void publishNotebook() { + List selections = notebookTree.selectedItems(); + QTreeWidgetItem currentSelection; + currentSelection = selections.get(0); + String guid = currentSelection.text(2); + + if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase("")) + return; + + Notebook n = null; + int position = 0; + for (int i=0; i selections = notebookTree.selectedItems(); + QTreeWidgetItem currentSelection; + currentSelection = selections.get(0); + String guid = currentSelection.text(2); + + if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase("")) + return; + + Notebook n = null;; + for (int i=0; i filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex()); + browserWindow.setNotebookList(filteredBooks); + + // Update any external windows + Iterator set = externalWindows.keySet().iterator(); + while(set.hasNext()) + externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks); + waitCursor(false); - browserWindow.setNotebookList(nbooks); } // Change the notebook's icon @SuppressWarnings("unused") @@ -1629,10 +1748,10 @@ public class NeverNote extends QMainWindow{ if (!stackSelected && !allNotebookSelected) { icon = conn.getNotebookTable().getIcon(guid); if (icon == null) { - dialog = new SetIcon(currentIcon); + dialog = new SetIcon(currentIcon, saveLastPath); dialog.setUseDefaultIcon(true); } else { - dialog = new SetIcon(icon); + dialog = new SetIcon(icon, saveLastPath); dialog.setUseDefaultIcon(false); } } else { @@ -1642,15 +1761,17 @@ public class NeverNote extends QMainWindow{ icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK"); } if (icon == null) { - dialog = new SetIcon(currentIcon); + dialog = new SetIcon(currentIcon, saveLastPath); dialog.setUseDefaultIcon(true); } else { - dialog = new SetIcon(icon); + dialog = new SetIcon(icon, saveLastPath); dialog.setUseDefaultIcon(false); } } dialog.exec(); if (dialog.okPressed()) { + saveLastPath = dialog.getPath(); + QIcon newIcon = dialog.getIcon(); if (stackSelected) { conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType()); @@ -1812,7 +1933,8 @@ public class NeverNote extends QMainWindow{ private void initializeTagTree() { logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree"); // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()"); - tagTree.itemClicked.connect(this, "tagTreeSelection()"); +// tagTree.itemClicked.connect(this, "tagTreeSelection()"); + tagTree.selectionSignal.connect(this, "tagTreeSelection()"); listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)"); logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree"); } @@ -1843,17 +1965,6 @@ public class NeverNote extends QMainWindow{ menuBar.tagDeleteAction.setEnabled(false); menuBar.tagIconAction.setEnabled(true); } - if (selectedTagGUIDs.size() == 1 && selectedTagGUIDs.get(0).equals(previousSelectedTag)) { - previousSelectedTag = selectedTagGUIDs.get(0); - previousSelectedTag = ""; - tagTree.clearSelection(); - tagTreeSelection(); - return; - } - if (selectedTagGUIDs.size() == 1) - previousSelectedTag = selectedTagGUIDs.get(0); - if (selectedTagGUIDs.size() > 1) - previousSelectedTag = ""; listManager.setSelectedTags(selectedTagGUIDs); listManager.loadNotesIndex(); noteIndexUpdated(false); @@ -1868,7 +1979,8 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated"); if (selectedTagGUIDs == null) selectedTagGUIDs = new ArrayList(); -// selectedTagGUIDs.clear(); // clear out old entries + if (reload) + listManager.reloadTagIndex(); tagTree.blockSignals(true); if (reload) { @@ -2015,14 +2127,15 @@ public class NeverNote extends QMainWindow{ QIcon icon = conn.getTagTable().getIcon(guid); SetIcon dialog; if (icon == null) { - dialog = new SetIcon(currentIcon); + dialog = new SetIcon(currentIcon, saveLastPath); dialog.setUseDefaultIcon(true); } else { - dialog = new SetIcon(icon); + dialog = new SetIcon(icon, saveLastPath); dialog.setUseDefaultIcon(false); } dialog.exec(); if (dialog.okPressed()) { + saveLastPath = dialog.getPath(); QIcon newIcon = dialog.getIcon(); conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType()); if (newIcon == null) @@ -2250,14 +2363,15 @@ public class NeverNote extends QMainWindow{ QIcon icon = conn.getSavedSearchTable().getIcon(guid); SetIcon dialog; if (icon == null) { - dialog = new SetIcon(currentIcon); + dialog = new SetIcon(currentIcon, saveLastPath); dialog.setUseDefaultIcon(true); } else { - dialog = new SetIcon(icon); + dialog = new SetIcon(icon, saveLastPath); dialog.setUseDefaultIcon(false); } dialog.exec(); if (dialog.okPressed()) { + saveLastPath = dialog.getPath(); QIcon newIcon = dialog.getIcon(); conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType()); if (newIcon == null) @@ -2286,6 +2400,7 @@ public class NeverNote extends QMainWindow{ status.setUnindexed(unindexed); status.setNoteCount(conn.getNoteTable().getNoteCount()); status.setNotebookCount(listManager.getNotebookIndex().size()); + status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount()); status.setSavedSearchCount(listManager.getSavedSearchIndex().size()); status.setTagCount(listManager.getTagIndex().size()); status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount()); @@ -2394,7 +2509,74 @@ public class NeverNote extends QMainWindow{ Global.saveWindowVisible("leftPanel", hidden); } + public void checkForUpdates() { + // Send off thread to check for a new version + versionChecker = new QNetworkAccessManager(this); + versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)"); + QNetworkRequest request = new QNetworkRequest(); + request.setUrl(new QUrl(Global.getUpdatesAvailableUrl())); + versionChecker.get(request); + } + @SuppressWarnings("unused") + private void upgradeFileRead(QNetworkReply reply) { + if (!reply.isReadable()) + return; + + String winVersion = Global.version; + String osxVersion = Global.version; + String linuxVersion = Global.version; + String linux64Version = Global.version; + String version = Global.version; + + // Determine the versions available + QByteArray data = reply.readLine(); + while (data != null && !reply.atEnd()) { + String line = data.toString(); + String lineVersion; + if (line.contains(":")) + lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", ""); + else + lineVersion = ""; + if (line.toLowerCase().contains("windows")) + winVersion = lineVersion; + else if (line.toLowerCase().contains("os-x")) + osxVersion = lineVersion; + else if (line.toLowerCase().contains("linux amd64")) + linux64Version = lineVersion; + else if (line.toLowerCase().contains("linux i386")) + linuxVersion = lineVersion; + else if (line.toLowerCase().contains("default")) + version = lineVersion; + // Read the next line + data = reply.readLine(); + } + + // Now we need to determine what system we are on. + if (System.getProperty("os.name").toLowerCase().contains("windows")) + version = winVersion; + if (System.getProperty("os.name").toLowerCase().contains("mac os")) + version = osxVersion; + if (System.getProperty("os.name").toLowerCase().contains("Linux")) { + if (System.getProperty("os.arch").contains("amd64") || + System.getProperty("os.arch").contains("x86_64")) + version = linux64Version; + else + version = linuxVersion; + } + + + if (Global.version.equals(version)) + return; + + UpgradeAvailableDialog dialog = new UpgradeAvailableDialog(); + dialog.exec(); + if (dialog.remindMe()) + Global.setCheckVersionUpgrade(true); + else + Global.setCheckVersionUpgrade(false); + } + //*************************************************************** //*************************************************************** @@ -2404,21 +2586,44 @@ public class NeverNote extends QMainWindow{ // Text in the search bar has been cleared private void searchFieldCleared() { saveNote(); + + // This is done because we want to force a reload of + // images. Some images we may want to highlight the text. + readOnlyCache.clear(); + inkNoteCache.clear(); + noteCache.clear(); + QWebSettings.setMaximumPagesInCache(0); + QWebSettings.setObjectCacheCapacities(0, 0, 0); + searchField.setEditText(""); saveNoteColumnPositions(); saveNoteIndexWidth(); + noteIndexUpdated(true); + if (currentNote == null && listManager.getNoteIndex().size() > 0) { + currentNote = listManager.getNoteIndex().get(0); + currentNoteGuid = currentNote.getGuid(); + } + if (currentNote != null) + loadNoteBrowserInformation(browserWindow); } // text in the search bar changed. We only use this to tell if it was cleared, // otherwise we trigger off searchFieldChanged. @SuppressWarnings("unused") private void searchFieldTextChanged(String text) { + QWebSettings.setMaximumPagesInCache(0); + QWebSettings.setObjectCacheCapacities(0, 0, 0); + if (text.trim().equals("")) { searchFieldCleared(); if (searchPerformed) { + + // This is done because we want to force a reload of + // images. Some images we may want to highlight the text. noteCache.clear(); + readOnlyCache.clear(); + inkNoteCache.clear(); + listManager.setEnSearch(""); -///// listManager.clearNoteIndexSearch(); - //noteIndexUpdated(true); listManager.loadNotesIndex(); refreshEvernoteNote(true); noteIndexUpdated(false); @@ -2430,6 +2635,8 @@ public class NeverNote extends QMainWindow{ private void searchFieldChanged() { logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged"); noteCache.clear(); + readOnlyCache.clear(); + inkNoteCache.clear(); saveNoteColumnPositions(); saveNoteIndexWidth(); String text = searchField.currentText(); @@ -2687,41 +2894,33 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void updateSyncButton() { - /* synchronizeFrame++; - if (synchronizeFrame == 4) - synchronizeFrame = 0; - synchronizeButton.setIcon(synchronizeAnimation.get(synchronizeFrame)); - */ -/* - QPixmap pix = new QPixmap(iconPath+"synchronize.png"); - QMatrix matrix = new QMatrix(); - synchronizeIconAngle = synchronizeIconAngle + 1.0; - if (synchronizeIconAngle >= 365.0) - synchronizeIconAngle = 0.0; - matrix.translate(pix.size().width()/2, pix.size().height()/2); - matrix.rotate( synchronizeIconAngle ); - matrix.translate(-pix.size().width()/2, -pix.size().height()/2); - pix = pix.transformed(matrix, TransformationMode.SmoothTransformation); - synchronizeButton.setIcon(pix); -*/ - - - QPixmap pix = new QPixmap(iconPath+"synchronize.png"); - QPixmap rotatedPix = new QPixmap(pix.size()); - QPainter p = new QPainter(rotatedPix); - - rotatedPix.fill(toolBar.palette().color(ColorRole.Button)); - QSize size = pix.size(); - p.translate(size.width()/2, size.height()/2); - synchronizeIconAngle = synchronizeIconAngle+1.0; - if (synchronizeIconAngle >= 359.0) - synchronizeIconAngle = 0.0; - p.rotate(synchronizeIconAngle); - p.setBackgroundMode(BGMode.OpaqueMode); - p.translate(-size.width()/2, -size.height()/2); - p.drawPixmap(0,0, pix); - p.end(); - synchronizeButton.setIcon(rotatedPix); + + if (syncIcons == null) { + syncIcons = new ArrayList(); + double angle = 0.0; + synchronizeIconAngle = 0; + QPixmap pix = new QPixmap(iconPath+"synchronize.png"); + syncIcons.add(pix); + for (int i=0; i<=360; i++) { + QPixmap rotatedPix = new QPixmap(pix.size()); + QPainter p = new QPainter(rotatedPix); + rotatedPix.fill(toolBar.palette().color(ColorRole.Button)); + QSize size = pix.size(); + p.translate(size.width()/2, size.height()/2); + angle = angle+1.0; + p.rotate(angle); + p.setBackgroundMode(BGMode.OpaqueMode); + p.translate(-size.width()/2, -size.height()/2); + p.drawPixmap(0,0, pix); + p.end(); + syncIcons.add(rotatedPix); + } + } + + synchronizeIconAngle++; + if (synchronizeIconAngle > 359) + synchronizeIconAngle=0; + synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle)); } // Synchronize with Evernote @@ -2731,7 +2930,7 @@ public class NeverNote extends QMainWindow{ if (!Global.isConnected) remoteConnect(); if (Global.isConnected) - synchronizeAnimationTimer.start(10); + synchronizeAnimationTimer.start(5); // synchronizeAnimationTimer.start(200); syncTimer(); logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync"); @@ -2891,6 +3090,7 @@ public class NeverNote extends QMainWindow{ menuBar.connectAction.setText(tr("Connect")); menuBar.connectAction.setToolTip(tr("Connect to Evernote")); menuBar.synchronizeAction.setEnabled(false); + Global.isConnected = false; synchronizeAnimationTimer.stop(); return; } @@ -3171,6 +3371,22 @@ public class NeverNote extends QMainWindow{ refreshEvernoteNoteList(); logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload); noteTableView.load(reload); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + int pos; + if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder) + pos = noteTableView.proxyModel.rowCount(); + else + pos = 1; + if (noteTableView.proxyModel.rowCount() == 0) + pos = 0; + if (pos>0) { + QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition); + if (i!=null) { + currentNoteGuid = (String)i.data(); + noteTableView.selectRow(pos-1); + } + } + } scrollToGuid(currentNoteGuid); logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated"); } @@ -3208,13 +3424,10 @@ public class NeverNote extends QMainWindow{ browserWindow.setDisabled(true); } - if (saveCurrentNoteGuid.equals("") && listManager.getNoteIndex().size() > 0) { - currentNote = listManager.getNoteIndex().get(listManager.getNoteIndex().size()-1); - currentNoteGuid = currentNote.getGuid(); - refreshEvernoteNote(true); + if (!saveCurrentNoteGuid.equals("")) { + refreshEvernoteNote(false); } else { - //we can reload if note not dirty - refreshEvernoteNote(!noteDirty); + currentNoteGuid = ""; } reloadTagTree(false); @@ -3598,7 +3811,12 @@ public class NeverNote extends QMainWindow{ saveNoteColumnPositions(); saveNoteIndexWidth(); saveWindowState(); - Global.setListView(Global.View_List_Narrow); + int sortCol = noteTableView.proxyModel.sortColumn(); + int sortOrder = noteTableView.proxyModel.sortOrder().value(); + Global.setSortColumn(sortCol); + Global.setSortOrder(sortOrder); + + Global.setListView(Global.View_List_Narrow); menuBar.wideListView.blockSignals(true); menuBar.narrowListView.blockSignals(true); @@ -3615,12 +3833,22 @@ public class NeverNote extends QMainWindow{ noteTableView.repositionColumns(); noteTableView.resizeColumnWidths(); noteTableView.resizeRowHeights(); + + sortCol = Global.getSortColumn(); + sortOrder = Global.getSortOrder(); + noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder)); + showColumns(); noteTableView.load(false); scrollToCurrentGuid(); } public void wideListView() { - saveWindowState(); + int sortCol = noteTableView.proxyModel.sortColumn(); + int sortOrder = noteTableView.proxyModel.sortOrder().value(); + Global.setSortColumn(sortCol); + Global.setSortOrder(sortOrder); + + saveWindowState(); saveNoteColumnPositions(); saveNoteIndexWidth(); Global.setListView(Global.View_List_Wide); @@ -3640,6 +3868,11 @@ public class NeverNote extends QMainWindow{ noteTableView.repositionColumns(); noteTableView.resizeColumnWidths(); noteTableView.resizeRowHeights(); + + sortCol = Global.getSortColumn(); + sortOrder = Global.getSortOrder(); + noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder)); + showColumns(); noteTableView.load(false); scrollToCurrentGuid(); @@ -3798,13 +4031,15 @@ public class NeverNote extends QMainWindow{ // 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); @@ -3825,7 +4060,7 @@ public class NeverNote extends QMainWindow{ } private void loadNoteBrowserInformation(BrowserWindow browser) { - NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles); + NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles); formatter.setNote(currentNote, Global.pdfPreview()); formatter.setHighlight(listManager.getEnSearch()); QByteArray js; @@ -3846,23 +4081,48 @@ public class NeverNote extends QMainWindow{ js.replace("", ""); browser.getBrowser().setContent(js); noteCache.put(currentNoteGuid, js.toString()); + + if (formatter.resourceError) + resourceErrorMessage(); + 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())); } - if (formatter.resourceError) - resourceErrorMessage(); - inkNote = formatter.readOnly; - - 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 nbooks = new ArrayList(); for (int i=0; i tagList = tagFilter.getValidTags(currentNote); + browser.setAllTags(tagList); + browser.setCurrentTags(currentNote.getTagNames()); noteDirty = false; scrollToGuid(currentNoteGuid); @@ -3895,6 +4158,10 @@ public class NeverNote extends QMainWindow{ browser.loadingData(false); if (thumbnailViewer.isActiveWindow()) thumbnailView(); + + FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger); + browser.setNotebookList(notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex())); + waitCursor(false); logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote"); } @@ -3963,31 +4230,16 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void fullReindex() { logger.log(logger.HIGH, "Entering NeverNote.fullReindex"); - // If we are deleting non-trash notes - if (currentNote == null) return; - if (currentNote.getDeleted() == 0) { - if (QMessageBox.question(this, tr("Confirmation"), tr("This will cause all notes & attachments to be reindexed, "+ - "but please be aware that depending upon the size of your database updating all these records " + - "can be time consuming and NeverNote will be unresponsive until it is complete. Do you wish to continue?"), - QMessageBox.StandardButton.Yes, - QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) { - return; - } - } - waitCursor(true); - setMessage(tr("Marking notes for reindex.")); - conn.getNoteTable().reindexAllNotes(); - conn.getNoteTable().noteResourceTable.reindexAll(); + indexRunner.addWork("REINDEXALL"); setMessage(tr("Database will be reindexed.")); - waitCursor(false); - logger.log(logger.HIGH, "Leaving NeverNote.fullRefresh"); + logger.log(logger.HIGH, "Leaving NeverNote.fullReindex"); } // Listener when a user wants to reindex a specific note @SuppressWarnings("unused") private void reindexNote() { logger.log(logger.HIGH, "Entering NeverNote.reindexNote"); for (int i=0; i 1) setMessage(tr("Notes will be reindexed.")); @@ -4198,36 +4450,44 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void invalidateNoteCache(String guid, String content) { String v = noteCache.remove(guid); - if (content != null) { - //noteCache.put(guid, content); - } +// if (guid.equals(currentNoteGuid) && !noteDirty) + refreshEvernoteNote(true); } // Signal received that a note guid has changed @SuppressWarnings("unused") private void noteGuidChanged(String oldGuid, String newGuid) { if (noteCache.containsKey(oldGuid)) { - String cache = noteCache.get(oldGuid); - noteCache.put(newGuid, cache); - noteCache.remove(oldGuid); + if (!oldGuid.equals(currentNoteGuid)) { + String cache = noteCache.get(oldGuid); + noteCache.put(newGuid, cache); + noteCache.remove(oldGuid); + } else { + noteCache.remove(oldGuid); + noteCache.put(newGuid, browserWindow.getContent()); + } } + listManager.updateNoteGuid(oldGuid, newGuid, false); if (currentNoteGuid.equals(oldGuid)) { if (currentNote != null) currentNote.setGuid(newGuid); currentNoteGuid = newGuid; } - if (externalWindows.containsKey(oldGuid)) { + + if (externalWindows.containsKey(oldGuid)) { ExternalBrowse b = externalWindows.get(oldGuid); externalWindows.remove(oldGuid); b.getBrowserWindow().getNote().setGuid(newGuid); externalWindows.put(newGuid, b); } + for (int i=0; i notebooks = null; + List tags = null; + List linkedNotebooks = null; + try { + notebooks = syncRunner.noteStore.listNotebooks(syncRunner.authToken); + tags = syncRunner.noteStore.listTags(syncRunner.authToken); + linkedNotebooks = syncRunner.noteStore.listLinkedNotebooks(syncRunner.authToken); + } catch (EDAMUserException e) { + setMessage("EDAMUserException: " +e.getMessage()); + return; + } catch (EDAMSystemException e) { + setMessage("EDAMSystemException: " +e.getMessage()); + return; + } catch (TException e) { + setMessage("EDAMTransactionException: " +e.getMessage()); + return; + } catch (EDAMNotFoundException e) { + setMessage("EDAMNotFoundException: " +e.getMessage()); + return; + } + + // Split up notebooks into synchronized & non-synchronized + List ignoredBooks = new ArrayList(); + List dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK"); + + for (int i=notebooks.size()-1; i>=0; i--) { + for (int j=0; j ignoredTags = new ArrayList(); + List dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG"); + + for (int i=tags.size()-1; i>=0; i--) { + for (int j=0; j ignoredLinkedNotebooks = new ArrayList(); + List dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK"); + for (int i=linkedNotebooks.size()-1; i>=0; i--) { + String notebookGuid = linkedNotebooks.get(i).getGuid(); + for (int j=0; j oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK"); + for (int i=0; i newNotebooks = new ArrayList(); + for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) { + String text = ignore.getIgnoredBookList().takeItem(i).text(); + for (int j=0; j oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG"); + for (int i=0; i newTags = new ArrayList(); + for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) { + String text = ignore.getIgnoredTagList().takeItem(i).text(); + for (int j=0; j oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK"); + for (int i=0; i newLinked = new ArrayList(); + for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) { + String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text(); + for (int j=0; j 0) { + indexRunner.interrupt = true; saveNoteIndexWidth(); saveNoteColumnPositions(); if (syncRunner.addWork("SYNC")) { @@ -4784,66 +5178,19 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning); if (syncRunning) return; - // Look for any unindexed notes. We only refresh occasionally - // and do one at a time to keep overhead down. - if (!indexDisabled && indexRunner.getWorkQueueSize() == 0) { - List notes = conn.getNoteTable().getNextUnindexed(1); - String unindexedNote = null; - if (notes.size() > 0) - unindexedNote = notes.get(0); - if (unindexedNote != null && Global.keepRunning) { - indexNoteContent(unindexedNote); - } - if (notes.size()>0) { - indexTimer.setInterval(100); - return; - } - List unindexedResources = conn.getNoteTable().noteResourceTable.getNextUnindexed(1); - if (unindexedResources.size() > 0 && indexRunner.getWorkQueueSize() == 0) { - String unindexedResource = unindexedResources.get(0); - if (unindexedResource != null && Global.keepRunning) { - indexNoteResource(unindexedResource); - } - } - if (unindexedResources.size() > 0) { - indexTimer.setInterval(100); - return; - } else { - indexTimer.setInterval(indexTime); - } - if (indexRunning) { - setMessage(tr("Index completed.")); - logger.log(logger.LOW, "Indexing has completed."); - indexRunning = false; - indexTimer.setInterval(indexTime); - } + if (!indexDisabled && indexRunner.idle) { + indexRunner.addWork("SCAN"); } logger.log(logger.EXTREME, "Leaving neverNote index timer"); } - private synchronized void indexNoteContent(String unindexedNote) { - logger.log(logger.EXTREME, "Entering NeverNote.indexNoteContent()"); - logger.log(logger.MEDIUM, "Unindexed Note found: "+unindexedNote); - indexRunner.setIndexType(indexRunner.CONTENT); - indexRunner.addWork("CONTENT "+unindexedNote); - if (!indexRunning) { - setMessage(tr("Indexing notes.")); - logger.log(logger.LOW, "Beginning to index note contents."); - indexRunning = true; - } - logger.log(logger.EXTREME, "Leaving NeverNote.indexNoteContent()"); - } - private synchronized void indexNoteResource(String unindexedResource) { - logger.log(logger.EXTREME, "Leaving NeverNote.indexNoteResource()"); - indexRunner.addWork(new String("RESOURCE "+unindexedResource)); - if (!indexRunning) { - setMessage(tr("Indexing notes.")); - indexRunning = true; - } - logger.log(logger.EXTREME, "Leaving NeverNote.indexNoteResource()"); + + @SuppressWarnings("unused") + private void indexStarted() { + setMessage(tr("Indexing notes")); } @SuppressWarnings("unused") - private void indexThreadComplete(String guid) { - logger.log(logger.MEDIUM, "Index complete for "+guid); + private void indexComplete() { + setMessage(tr("Index complete")); } @SuppressWarnings("unused") private synchronized void toggleNoteIndexing() { @@ -4933,13 +5280,18 @@ public class NeverNote extends QMainWindow{ fd.setWindowTitle(tr("Backup Database")); fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptSave); - fd.setDirectory(System.getProperty("user.home")); + if (saveLastPath == null || saveLastPath.equals("")) + fd.setDirectory(System.getProperty("user.home")); + else + fd.setDirectory(saveLastPath); if (fd.exec() == 0 || fd.selectedFiles().size() == 0) { return; } waitCursor(true); + saveLastPath = fd.selectedFiles().get(0); + saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/")); setMessage(tr("Backing up database")); saveNote(); // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate()); @@ -4974,13 +5326,19 @@ public class NeverNote extends QMainWindow{ fd.setWindowTitle(tr("Restore Database")); fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptOpen); - fd.setDirectory(System.getProperty("user.home")); + if (saveLastPath == null || saveLastPath.equals("")) + fd.setDirectory(System.getProperty("user.home")); + else + fd.setDirectory(saveLastPath); if (fd.exec() == 0 || fd.selectedFiles().size() == 0) { return; } waitCursor(true); + saveLastPath = fd.selectedFiles().get(0); + saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/")); + setMessage(tr("Restoring database")); ImportData noteReader = new ImportData(conn, true); noteReader.importData(fd.selectedFiles().get(0)); @@ -5039,7 +5397,10 @@ public class NeverNote extends QMainWindow{ fd.setWindowTitle(tr("Import Notes")); fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptOpen); - fd.setDirectory(System.getProperty("user.home")); + if (saveLastPath == null || saveLastPath.equals("")) + fd.setDirectory(System.getProperty("user.home")); + else + fd.setDirectory(saveLastPath); if (fd.exec() == 0 || fd.selectedFiles().size() == 0) { return; } @@ -5054,6 +5415,7 @@ public class NeverNote extends QMainWindow{ ImportData noteReader = new ImportData(conn, false); String fileName = fd.selectedFiles().get(0); + saveLastPath.substring(0,fileName.lastIndexOf("/")); if (!fileName.endsWith(".nnex")) fileName = fileName +".nnex";