X-Git-Url: http://git.sourceforge.jp/view?p=neighbornote%2FNeighborNote.git;a=blobdiff_plain;f=src%2Fcx%2Ffbn%2Fnevernote%2FNeverNote.java;h=57a014a01214ced472bead8eecee20f3ca723d83;hp=bb4f48037a62df29f7b98611f32c4b2010865637;hb=8f801d9014deed810710af8a380852cbc04209cd;hpb=2583258fb708b5b1d477dd2ef09a4d7d940f46ef diff --git a/src/cx/fbn/nevernote/NeverNote.java b/src/cx/fbn/nevernote/NeverNote.java index bb4f480..57a014a 100644 --- a/src/cx/fbn/nevernote/NeverNote.java +++ b/src/cx/fbn/nevernote/NeverNote.java @@ -1,6 +1,7 @@ /* - * This file is part of NeverNote + * This file is part of NixNote/NeighborNote * Copyright 2009 Randy Baumgarte + * Copyright 2013 Yuki Takahashi * * This file may be licensed under the terms of of the * GNU General Public License Version 2 (the ``GPL''). @@ -21,6 +22,7 @@ import java.awt.Desktop; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.security.MessageDigest; @@ -75,30 +77,36 @@ import com.trolltech.qt.core.QFileSystemWatcher; import com.trolltech.qt.core.QIODevice; import com.trolltech.qt.core.QIODevice.OpenModeFlag; import com.trolltech.qt.core.QLocale; +import com.trolltech.qt.core.QMimeData; import com.trolltech.qt.core.QModelIndex; import com.trolltech.qt.core.QSize; import com.trolltech.qt.core.QTemporaryFile; import com.trolltech.qt.core.QTextCodec; +import com.trolltech.qt.core.QTextStream; import com.trolltech.qt.core.QThreadPool; import com.trolltech.qt.core.QTimer; import com.trolltech.qt.core.QTranslator; import com.trolltech.qt.core.QUrl; import com.trolltech.qt.core.Qt; import com.trolltech.qt.core.Qt.BGMode; +import com.trolltech.qt.core.Qt.DockWidgetArea; import com.trolltech.qt.core.Qt.ItemDataRole; +import com.trolltech.qt.core.Qt.KeyboardModifier; +import com.trolltech.qt.core.Qt.MouseButton; import com.trolltech.qt.core.Qt.SortOrder; import com.trolltech.qt.core.Qt.WidgetAttribute; import com.trolltech.qt.gui.QAbstractItemView; import com.trolltech.qt.gui.QAbstractItemView.ScrollHint; import com.trolltech.qt.gui.QAction; import com.trolltech.qt.gui.QApplication; +import com.trolltech.qt.gui.QClipboard; import com.trolltech.qt.gui.QCloseEvent; import com.trolltech.qt.gui.QColor; import com.trolltech.qt.gui.QComboBox; -import com.trolltech.qt.gui.QComboBox.InsertPolicy; import com.trolltech.qt.gui.QCursor; import com.trolltech.qt.gui.QDesktopServices; import com.trolltech.qt.gui.QDialog; +import com.trolltech.qt.gui.QDockWidget; import com.trolltech.qt.gui.QFileDialog; import com.trolltech.qt.gui.QFileDialog.AcceptMode; import com.trolltech.qt.gui.QFileDialog.FileMode; @@ -106,7 +114,9 @@ import com.trolltech.qt.gui.QGridLayout; import com.trolltech.qt.gui.QHBoxLayout; import com.trolltech.qt.gui.QIcon; import com.trolltech.qt.gui.QImage; +import com.trolltech.qt.gui.QKeySequence; import com.trolltech.qt.gui.QLabel; +import com.trolltech.qt.gui.QListWidgetItem; import com.trolltech.qt.gui.QMainWindow; import com.trolltech.qt.gui.QMenu; import com.trolltech.qt.gui.QMessageBox; @@ -116,6 +126,7 @@ import com.trolltech.qt.gui.QPalette.ColorRole; import com.trolltech.qt.gui.QPixmap; import com.trolltech.qt.gui.QPrintDialog; import com.trolltech.qt.gui.QPrinter; +import com.trolltech.qt.gui.QShortcut; import com.trolltech.qt.gui.QSizePolicy; import com.trolltech.qt.gui.QSizePolicy.Policy; import com.trolltech.qt.gui.QSpinBox; @@ -128,6 +139,8 @@ 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.QNetworkProxy; +import com.trolltech.qt.network.QNetworkProxy.ProxyType; import com.trolltech.qt.network.QNetworkReply; import com.trolltech.qt.network.QNetworkRequest; import com.trolltech.qt.webkit.QWebPage.WebAction; @@ -143,7 +156,6 @@ import cx.fbn.nevernote.dialog.DatabaseStatus; import cx.fbn.nevernote.dialog.FindDialog; import cx.fbn.nevernote.dialog.IgnoreSync; import cx.fbn.nevernote.dialog.LogFileDialog; -import cx.fbn.nevernote.dialog.LoginDialog; import cx.fbn.nevernote.dialog.NotebookArchive; import cx.fbn.nevernote.dialog.NotebookEdit; import cx.fbn.nevernote.dialog.OnlineNoteHistory; @@ -151,11 +163,15 @@ 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.SharedNotebookSyncError; import cx.fbn.nevernote.dialog.StackNotebook; +import cx.fbn.nevernote.dialog.SynchronizationRequiredWarning; import cx.fbn.nevernote.dialog.TagEdit; +import cx.fbn.nevernote.dialog.TagMerge; import cx.fbn.nevernote.dialog.ThumbnailViewer; import cx.fbn.nevernote.dialog.UpgradeAvailableDialog; import cx.fbn.nevernote.dialog.WatchFolder; +import cx.fbn.nevernote.evernote.NoteMetadata; import cx.fbn.nevernote.filters.FilterEditorNotebooks; import cx.fbn.nevernote.filters.FilterEditorTags; import cx.fbn.nevernote.gui.AttributeTreeWidget; @@ -164,12 +180,19 @@ import cx.fbn.nevernote.gui.DateAttributeFilterTable; import cx.fbn.nevernote.gui.ExternalBrowse; import cx.fbn.nevernote.gui.MainMenuBar; import cx.fbn.nevernote.gui.NotebookTreeWidget; +import cx.fbn.nevernote.gui.RensoNoteList; import cx.fbn.nevernote.gui.SavedSearchTreeWidget; +import cx.fbn.nevernote.gui.SearchPanel; +import cx.fbn.nevernote.gui.TabBrowse; +import cx.fbn.nevernote.gui.TabBrowserWidget; import cx.fbn.nevernote.gui.TableView; import cx.fbn.nevernote.gui.TagTreeWidget; import cx.fbn.nevernote.gui.Thumbnailer; import cx.fbn.nevernote.gui.TrashTreeWidget; import cx.fbn.nevernote.gui.controls.QuotaProgressBar; +import cx.fbn.nevernote.neighbornote.ClipBoardObserver; +import cx.fbn.nevernote.oauth.OAuthTokenizer; +import cx.fbn.nevernote.oauth.OAuthWindow; import cx.fbn.nevernote.sql.DatabaseConnection; import cx.fbn.nevernote.sql.WatchFolderRecord; import cx.fbn.nevernote.threads.IndexRunner; @@ -183,6 +206,7 @@ import cx.fbn.nevernote.utilities.ListManager; import cx.fbn.nevernote.utilities.SyncTimes; import cx.fbn.nevernote.xml.ExportData; import cx.fbn.nevernote.xml.ImportData; +import cx.fbn.nevernote.xml.ImportEnex; import cx.fbn.nevernote.xml.NoteFormatter; @@ -212,6 +236,7 @@ public class NeverNote extends QMainWindow{ public BrowserWindow browserWindow; // Window containing browser & labels public QToolBar toolBar; // The tool bar under the menu QComboBox searchField; // search filter bar on the toolbar; + QShortcut searchShortcut; // Shortcut to search bar boolean searchPerformed = false; // Search was done? QuotaProgressBar quotaBar; // The current quota usage @@ -225,9 +250,10 @@ public class NeverNote extends QMainWindow{ NoteFilter filter; // Note filter 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 readOnly; // Is this note read-only? + // ICHANGED + HashMap noteDirty; // Has the note been changed? + HashMap inkNote; // if this is an ink note, it is read only + HashMap readOnly; // Is this note read-only? ListManager listManager; // DB runnable task @@ -249,6 +275,7 @@ public class NeverNote extends QMainWindow{ QTimer authTimer; // Refresh authentication QTimer externalFileSaveTimer; // Save files altered externally QTimer thumbnailTimer; // Wakeup & scan for thumbnails + QTimer debugTimer; List externalFiles; // External files to save later List importFilesKeep; // Auto-import files to save later List importFilesDelete; // Auto-import files to save later @@ -280,6 +307,8 @@ public class NeverNote extends QMainWindow{ QSpinBox zoomSpinner; // Zoom zoom QAction searchClearButton; // Clear the search field + SearchPanel searchLayout; // Widget to hold search field, zoom, & quota + QSplitter mainLeftRightSplitter; // main splitter for left/right side QSplitter leftSplitter1; // first left hand splitter QSplitter browserIndexSplitter; // splitter between note index & note text @@ -309,16 +338,18 @@ public class NeverNote extends QMainWindow{ 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? + // ICHANGED + HashMap> historyGuids; // タブごとの以前見たノートのGUID + HashMap historyPosition; // Position within the viewed items + HashMap fromHistory; // Is this from the history queue? + String trashNoteGuid; // Guid to restore / set into or out of trash to save position List thumbGenerators; // generate preview image ThumbnailViewer thumbnailViewer; // View preview thumbnail; boolean encryptOnShutdown; // should I encrypt when I close? boolean decryptOnShutdown; // should I decrypt on shutdown; String encryptCipher; // What cipher should I use? - Signal0 minimizeToTray; + //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 @@ -326,8 +357,17 @@ public class NeverNote extends QMainWindow{ private static Logger log = Logger.getLogger(NeverNote.class); private String saveLastPath; // last path we used private final QTimer messageTimer; // Timer to clear the status message. + private QTimer blockTimer; + BrowserWindow blockingWindow; - + // ICHANGED + private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化 + private final HashMap tabWindows; // タブウィンドウ + private final RensoNoteList rensoNoteList; // 連想ノートリスト + private final QDockWidget rensoNoteListDock; // 連想ノートリストドックウィジェット + ClipBoardObserver cbObserver; + String rensoNotePressedItemGuid; + String iconPath = new String("classpath:cx/fbn/nevernote/icons/"); @@ -339,16 +379,19 @@ public class NeverNote extends QMainWindow{ // Application Constructor @SuppressWarnings("static-access") public NeverNote(DatabaseConnection dbConn) { + // ICHANGED + cbObserver = new ClipBoardObserver(); + conn = dbConn; if (conn.getConnection() == null) { String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" + - "is accessing the database or NeverNote is already running.\n\n" + - "Please end any other process or shutdown the other NeverNote before starting.\n\nExiting program.")); + "is accessing the database or NeighborNote is already running.\n\n" + + "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program.")); QMessageBox.critical(null, tr("Database Connection Error") ,msg); System.exit(16); } - + setObjectName("mainWindow"); // thread().setPriority(Thread.MAX_PRIORITY); logger = new ApplicationLogger("nevernote.log"); @@ -371,16 +414,19 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Starting GUI build"); QTranslator nevernoteTranslator = new QTranslator(); - nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("nevernote_" + QLocale.system().name() + ".qm")); + nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("neighbornote_" + QLocale.system().name() + ".qm")); QApplication.instance().installTranslator(nevernoteTranslator); Global.originalPalette = QApplication.palette(); QApplication.setStyle(Global.getStyle()); if (Global.useStandardPalette()) QApplication.setPalette(QApplication.style().standardPalette()); - setWindowTitle("NeverNote"); + setWindowTitle(tr("NeighborNote")); mainLeftRightSplitter = new QSplitter(); + // ICHANGED + mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal); + setCentralWidget(mainLeftRightSplitter); leftSplitter1 = new QSplitter(); leftSplitter1.setOrientation(Qt.Orientation.Vertical); @@ -389,19 +435,27 @@ public class NeverNote extends QMainWindow{ browserIndexSplitter.setOrientation(Qt.Orientation.Vertical); //* Setup threads & thread timers - int indexRunnerCount = Global.getIndexThreads(); - indexRunnerCount = 1; - QThreadPool.globalInstance().setMaxThreadCount(indexRunnerCount+5); // increase max thread count +// int indexRunnerCount = Global.getIndexThreads(); +// indexRunnerCount = 1; + QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount); // increase max thread count logger.log(logger.EXTREME, "Building list manager"); listManager = new ListManager(conn, logger); logger.log(logger.EXTREME, "Building index runners & timers"); - indexRunner = new IndexRunner("indexRunner.log", - Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), - Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword); + // ICHANGED Global.getBehaviorDatabaseUrl()を追加 + indexRunner = new IndexRunner("indexRunner.log", + Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), + Global.getResourceDatabaseUrl(), + Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(), + Global.getDatabaseUserPassword(), Global.cipherPassword); + indexThread = new QThread(indexRunner, "Index Thread"); indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally(); + indexRunner.indexImageRecognition = Global.indexImageRecognition(); + indexRunner.indexNoteBody = Global.indexNoteBody(); + indexRunner.indexNoteTitle = Global.indexNoteTitle(); + indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters(); indexThread.start(); synchronizeAnimationTimer = new QTimer(); @@ -416,9 +470,12 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Setting sync thread & timers"); syncThreadsReady=1; - syncRunner = new SyncRunner("syncRunner.log", - Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), - Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword); + // ICHANGED Global.getBehaviorDatabaseUrl()を追加 + syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(), + Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), + Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(), + Global.getDatabaseUserPassword(), Global.cipherPassword); + syncTime = new SyncTimes().timeValue(Global.getSyncInterval()); syncTimer = new QTimer(); syncTimer.timeout.connect(this, "syncTimer()"); @@ -440,9 +497,13 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Starting thumnail thread"); pdfReadyQueue = new ArrayList(); - thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log", - Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), - Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword); + // ICHANGED Global.getBehaviorDatabaseUrl()を追加 + thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log", + Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), + Global.getResourceDatabaseUrl(), + Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(), + Global.getDatabaseUserPassword(), Global.cipherPassword); + thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread"); thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)"); thumbnailThread.start(); @@ -453,6 +514,10 @@ public class NeverNote extends QMainWindow{ thumbnailTimer.setInterval(500*1000); // Thumbnail every minute thumbnailTimer.start(); +// debugTimer = new QTimer(); +// debugTimer.timeout.connect(this, "debugDirty()"); +// debugTimer.start(1000*60); + logger.log(logger.EXTREME, "Starting authentication timer"); authTimer = new QTimer(); authTimer.timeout.connect(this, "authTimer()"); @@ -482,40 +547,102 @@ public class NeverNote extends QMainWindow{ tagTree = new TagTreeWidget(conn); savedSearchTree = new SavedSearchTreeWidget(); trashTree = new TrashTreeWidget(); - noteTableView = new TableView(logger, listManager); + // ICHANGED + noteTableView = new TableView(logger, listManager, this); + + searchField = new QComboBox(); + searchField.setObjectName("searchField"); + //setStyleSheet("QComboBox#searchField { background-color: yellow }"); + searchField.setEditable(true); + searchField.activatedIndex.connect(this, "searchFieldChanged()"); + searchField.setDuplicatesEnabled(false); + searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)"); + searchShortcut = new QShortcut(this); + setupShortcut(searchShortcut, "Focus_Search"); + searchShortcut.activated.connect(this, "focusSearch()"); + + quotaBar = new QuotaProgressBar(); + // Setup the zoom + zoomSpinner = new QSpinBox(); + zoomSpinner.setMinimum(10); + zoomSpinner.setMaximum(1000); + zoomSpinner.setAccelerated(true); + zoomSpinner.setSingleStep(10); + zoomSpinner.setValue(100); + zoomSpinner.valueChanged.connect(this, "zoomChanged()"); + + searchLayout = new SearchPanel(searchField, quotaBar, notebookTree, zoomSpinner); + QGridLayout leftGrid = new QGridLayout(); + leftSplitter1.setContentsMargins(5, 0, 0, 7); leftSplitter1.setLayout(leftGrid); - leftGrid.addWidget(notebookTree, 1, 1); + leftGrid.addWidget(searchLayout,1,1); leftGrid.addWidget(tagTree,2,1); leftGrid.addWidget(attributeTree,3,1); leftGrid.addWidget(savedSearchTree,4,1); - leftGrid.addWidget(trashTree, 5, 1); + leftGrid.addWidget(trashTree,5, 1); // Setup the browser window noteCache = new HashMap(); readOnlyCache = new HashMap(); inkNoteCache = new HashMap(); - browserWindow = new BrowserWindow(conn); - + // ICHANGED + browserWindow = new BrowserWindow(conn, cbObserver); + + // ICHANGED 下から移動してきた。 + historyGuids = new HashMap>(); + historyPosition = new HashMap(); + fromHistory = new HashMap(); + + // ICHANGED タブブラウザ作成 + tabWindows = new HashMap(); + tabBrowser = new TabBrowserWidget(this); + tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}"); + tabBrowser.setMovable(true); + TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver); + browserWindow = tab.getBrowserWindow(); + int index = tabBrowser.addNewTab(tab, ""); + tabWindows.put(index, tab); + tabBrowser.setTabsClosable(true); + tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)"); + tabBrowser.tabCloseRequested.connect(this, "tabWindowClosing(int)"); + + noteDirty = new HashMap(); + noteDirty.put(index, false); + + inkNote = new HashMap(); + readOnly = new HashMap(); + + // ICHANGED + // 履歴記録のハッシュマップを初期化 + historyGuids.put(index, new ArrayList()); + historyPosition.put(index, 0); + fromHistory.put(index, false); + mainLeftRightSplitter.addWidget(leftSplitter1); mainLeftRightSplitter.addWidget(browserIndexSplitter); - if (Global.getListView() == Global.View_List_Wide) { - browserIndexSplitter.addWidget(noteTableView); - browserIndexSplitter.addWidget(browserWindow); - } else { - mainLeftRightSplitter.addWidget(noteTableView); - mainLeftRightSplitter.addWidget(browserWindow); - } - - searchField = new QComboBox(); - searchField.setEditable(true); - searchField.activatedIndex.connect(this, "searchFieldChanged()"); - searchField.setDuplicatesEnabled(false); - searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)"); - - quotaBar = new QuotaProgressBar(); + // ICHANGED + // 連想ノートリストをセットアップ + rensoNoteList = new RensoNoteList(conn, this); + rensoNoteList.itemPressed.connect(this, + "rensoNoteItemPressed(QListWidgetItem)"); + rensoNoteListDock = new QDockWidget(tr("Renso Note List"), this); + rensoNoteListDock.setWidget(rensoNoteList); + addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock); + + if (Global.getListView() == Global.View_List_Wide) { + browserIndexSplitter.addWidget(noteTableView); + // ICHANGED + browserIndexSplitter.addWidget(tabBrowser); + // browserIndexSplitter.addWidget(browserWindow); + } else { + mainLeftRightSplitter.addWidget(noteTableView); + // ICHANGED + mainLeftRightSplitter.addWidget(tabBrowser); + // mainLeftRightSplitter.addWidget(browserWindow); + } // Setup the thumbnail viewer thumbnailViewer = new ThumbnailViewer(); @@ -542,13 +669,20 @@ public class NeverNote extends QMainWindow{ emitLog = new ArrayList(); tagTree.setDeleteAction(menuBar.tagDeleteAction); + tagTree.setMergeAction(menuBar.tagMergeAction); tagTree.setEditAction(menuBar.tagEditAction); tagTree.setAddAction(menuBar.tagAddAction); tagTree.setIconAction(menuBar.tagIconAction); tagTree.setVisible(Global.isWindowVisible("tagTree")); + leftSplitter1.setVisible(Global.isWindowVisible("leftPanel")); tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)"); menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree")); listManager.tagSignal.listChanged.connect(this, "reloadTagTree()"); + + if (!Global.isWindowVisible("zoom")) { + searchLayout.hideZoom(); + menuBar.hideZoom.setChecked(false); + } notebookTree.setDeleteAction(menuBar.notebookDeleteAction); notebookTree.setEditAction(menuBar.notebookEditAction); @@ -570,16 +704,23 @@ public class NeverNote extends QMainWindow{ savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()"); savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree")); menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree")); + + // ICHANGED noteTableViewに新しいタブで開くを追加 + noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab); noteTableView.setAddAction(menuBar.noteAdd); + + // ICHANGED noteTableViewに新しいタブでノート追加を追加 + noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab); + noteTableView.setDeleteAction(menuBar.noteDelete); noteTableView.setRestoreAction(menuBar.noteRestoreAction); noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction); noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction); noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)"); + noteTableView.noteSignal.notePinned.connect(this, "notePinned()"); noteTableView.setMergeNotesAction(menuBar.noteMergeAction); - noteTableView.rowChanged.connect(this, "scrollToGuid(String)"); - noteTableView.resetViewport.connect(this, "scrollToCurrentGuid()"); + noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction); noteTableView.doubleClicked.connect(this, "listDoubleClick()"); listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)"); @@ -597,12 +738,35 @@ public class NeverNote extends QMainWindow{ noteTableView.setVisible(Global.isWindowVisible("noteList")); menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList")); - if (!Global.isWindowVisible("editorButtonBar")) + // ICHANGED + if (!Global.isWindowVisible("editorButtonBar")) { + menuBar.showEditorBar.setChecked(false); toggleEditorButtonBar(); + } + if (!Global.isWindowVisible("leftPanel")) menuBar.hideLeftSide.setChecked(true); - if (Global.isWindowVisible("noteInformation")) + + // ICHANGED + if (Global.isWindowVisible("noteInformation")) { + menuBar.noteAttributes.setChecked(true); toggleNoteInformation(); + } + + quotaBar.setVisible(Global.isWindowVisible("quota")); + // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota") + // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正 + if (!Global.isWindowVisible("quota")) + menuBar.hideQuota.setChecked(false); + + searchField.setVisible(Global.isWindowVisible("searchField")); + // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField") + // なぜかsearchField.isVisible()が常にfalseを返すようなので修正 + if (!Global.isWindowVisible("searchField")) + menuBar.hideSearch.setChecked(false); + + if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden()) + searchLayout.hide(); setMenuBar(menuBar); setupToolBar(); @@ -610,9 +774,9 @@ public class NeverNote extends QMainWindow{ find.getOkButton().clicked.connect(this, "doFindText()"); // Setup the tray icon menu bar - trayShowAction = new QAction("Show/Hide", this); - trayExitAction = new QAction("Exit", this); - trayAddNoteAction = new QAction("Add Note", this); + trayShowAction = new QAction(tr("Show/Hide"), this); + trayExitAction = new QAction(tr("Exit"), this); + trayAddNoteAction = new QAction(tr("Add Note"), this); trayExitAction.triggered.connect(this, "closeNeverNote()"); trayAddNoteAction.triggered.connect(this, "addNote()"); @@ -625,16 +789,22 @@ public class NeverNote extends QMainWindow{ trayIcon = new QSystemTrayIcon(this); - trayIcon.setToolTip("NeverNote"); + trayIcon.setToolTip(tr("NeighborNote")); trayIcon.setContextMenu(trayMenu); trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)"); currentNoteGuid=""; currentNoteGuid = Global.getLastViewedNoteGuid(); - historyGuids = new ArrayList(); - historyPosition = 0; - fromHistory = false; - noteDirty = false; + if (currentNoteGuid.equals("")) + currentNote = new Note(); + + // ICHANGED + /* 上に移動したので要らない + historyGuids = new ArrayList(); + historyPosition = 0; + fromHistory = false; + */ + if (!currentNoteGuid.trim().equals("")) { currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true); } @@ -657,12 +827,14 @@ public class NeverNote extends QMainWindow{ tagTree.showAllTags(true); QIcon appIcon = new QIcon(iconPath+"nevernote.png"); - setWindowIcon(appIcon); - trayIcon.setIcon(appIcon); - if (Global.showTrayIcon()) - trayIcon.show(); - else - trayIcon.hide(); + if (QSystemTrayIcon.isSystemTrayAvailable()) { + setWindowIcon(appIcon); + trayIcon.setIcon(appIcon); + if (Global.showTrayIcon() || Global.minimizeOnClose()) + trayIcon.show(); + else + trayIcon.hide(); + } scrollToGuid(currentNoteGuid); if (Global.automaticLogin()) { @@ -683,8 +855,12 @@ public class NeverNote extends QMainWindow{ threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()"); threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds; - historyGuids.add(currentNoteGuid); - historyPosition = 1; + // ICHANGED たぶんこれはいらない + // IFIXED ? + /* + historyGuids.add(currentNoteGuid); + historyPosition = 1; + */ menuBar.blockSignals(true); menuBar.narrowListView.blockSignals(true); @@ -698,14 +874,18 @@ public class NeverNote extends QMainWindow{ menuBar.blockSignals(false); menuBar.narrowListView.blockSignals(false); menuBar.wideListView.blockSignals(false); - - if (Global.getListView() == Global.View_List_Wide) { - browserIndexSplitter.addWidget(noteTableView); - browserIndexSplitter.addWidget(browserWindow); - } else { - mainLeftRightSplitter.addWidget(noteTableView); - mainLeftRightSplitter.addWidget(browserWindow); - } + + // IFIXED + // 上に同じコードがあるよね? とりあえずコメントアウト + /* + * if (Global.getListView() == Global.View_List_Wide) { + * browserIndexSplitter.addWidget(noteTableView); // ICHANGED // + * browserIndexSplitter.addWidget(tabBrowser); + * browserIndexSplitter.addWidget(browserWindow); } else { + * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED // + * mainLeftRightSplitter.addWidget(tabBrowser); + * mainLeftRightSplitter.addWidget(browserWindow); } + */ messageTimer = new QTimer(); messageTimer.timeout.connect(this, "clearMessage()"); @@ -714,9 +894,45 @@ public class NeverNote extends QMainWindow{ int sortCol = Global.getSortColumn(); int sortOrder = Global.getSortOrder(); + noteTableView.proxyModel.blocked = true; + // We sort the table twice to fix a bug. For some reaosn the table won't sort properly if it is in narrow + // list view and sorted descending on the date created. By sorting it twice it forces the proper sort. Ugly. + if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow) + noteTableView.sortByColumn(sortCol, SortOrder.resolve(0)); noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder)); - if (Global.checkVersionUpgrade()) + noteTableView.proxyModel.blocked = false; + noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)"); + + // Set the startup notebook + String defaultNotebook = Global.getStartupNotebook(); + if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) { + for (int k=0; k dirty = conn.getNoteTable().getDirty(); + logger.log(logger.LOW, "------ Dirty Notes List Begin ------"); + for (int i=0; i selections = notebookTree.selectedItems(); selectedNotebookGUIDs.clear(); String guid = ""; @@ -1312,6 +1712,21 @@ public class NeverNote extends QMainWindow{ listManager.setSelectedNotebooks(selectedNotebookGUIDs); listManager.loadNotesIndex(); noteIndexUpdated(false); + refreshEvernoteNote(true); + listManager.refreshCounters = true; + listManager.refreshCounters(); + if (selectedNotebookGUIDs.size() == 1) { + int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0)); + int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0)); + if (col != -1) { + noteTableView.proxyModel.blocked = true; + if (order == 1) + noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder); + else + noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder); + } + } + noteTableView.proxyModel.blocked = false; logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection"); } @@ -1354,17 +1769,17 @@ public class NeverNote extends QMainWindow{ if (!found) selectedNotebookGUIDs.remove(i); } + listManager.refreshCounters = true; + listManager.refreshCounters(); notebookTree.blockSignals(false); logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated"); } // Show/Hide note information + @SuppressWarnings("unused") private void toggleNotebookWindow() { logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow"); - if (notebookTree.isVisible()) - notebookTree.hide(); - else - notebookTree.show(); + searchLayout.toggleNotebook(); menuBar.hideNotebooks.setChecked(notebookTree.isVisible()); Global.saveWindowVisible("notebookTree", notebookTree.isVisible()); logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow"); @@ -1529,6 +1944,14 @@ public class NeverNote extends QMainWindow{ Iterator set = externalWindows.keySet().iterator(); while(set.hasNext()) externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks); + + // ICHANGED + Iteratorit = tabWindows.keySet().iterator(); + while (it.hasNext()) { + tabWindows.get(it.next()).getBrowserWindow() + .setNotebookList(filteredBooks); + } + logger.log(logger.HIGH, "Leaving NeverNote.editNotebook"); } // Publish a notebook @@ -1674,6 +2097,8 @@ public class NeverNote extends QMainWindow{ // A note's notebook has been updated @SuppressWarnings("unused") private void updateNoteNotebook(String guid, String notebookGuid) { + // ICHANGED 同じノートブックに入れられたノート間の履歴を登録 + conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid); // Update the list manager listManager.updateNoteNotebook(guid, notebookGuid); @@ -1767,6 +2192,14 @@ public class NeverNote extends QMainWindow{ while(set.hasNext()) externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks); + // ICHANGED + // 全てのタブウィンドウを更新 + Iterator it = tabWindows.keySet().iterator(); + while (it.hasNext()) { + tabWindows.get(it.next()).getBrowserWindow() + .setNotebookList(filteredBooks); + } + waitCursor(false); } // Change the notebook's icon @@ -1864,6 +2297,14 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Inside NeverNote.addTag"); TagEdit edit = new TagEdit(); edit.setTagList(listManager.getTagIndex()); + + List selections = tagTree.selectedItems(); + QTreeWidgetItem currentSelection = null; + if (selections.size() > 0) { + currentSelection = selections.get(0); + edit.setParentTag(currentSelection.text(0)); + } + edit.exec(); if (!edit.okPressed()) @@ -1877,6 +2318,11 @@ public class NeverNote extends QMainWindow{ newTag.setUpdateSequenceNum(0); newTag.setGuid(randint); newTag.setName(edit.getTag()); + if (edit.getParentTag().isChecked()) { + newTag.setParentGuid(currentSelection.text(2)); + newTag.setParentGuidIsSet(true); + currentSelection.setExpanded(true); + } conn.getTagTable().addTag(newTag, true); listManager.getTagIndex().add(newTag); reloadTagTree(true); @@ -1891,13 +2337,15 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree"); tagIndexUpdated(reload); boolean filter = false; - listManager.countTagResults(listManager.getNoteIndex()); + if (reload) + listManager.countTagResults(listManager.getNoteIndex()); if (notebookTree.selectedItems().size() > 0 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks")) filter = true; if (tagTree.selectedItems().size() > 0) filter = true; tagTree.showAllTags(!filter); + tagIndexUpdated(false); logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree"); } // Edit an existing tag @@ -1927,9 +2375,12 @@ public class NeverNote extends QMainWindow{ if (currentNote != null && currentNote.getTagGuids().contains(guid)) browserWindow.setTag(getTagNamesForNote(currentNote)); logger.log(logger.HIGH, "Leaving NeverNote.editTag"); - return; + //return; } } + listManager.reloadNoteTagNames(guid, edit.getTag()); + noteIndexUpdated(true); + refreshEvernoteNote(true); browserWindow.setTag(getTagNamesForNote(currentNote)); logger.log(logger.HIGH, "Leaving NeverNote.editTag..."); } @@ -1994,6 +2445,11 @@ public class NeverNote extends QMainWindow{ menuBar.noteRestoreAction.setVisible(false); + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + if (!rensoNoteListDock.isEnabled()) { + rensoNoteListDock.setEnabled(true); + } + List selections = tagTree.selectedItems(); QTreeWidgetItem currentSelection; selectedTagGUIDs.clear(); @@ -2011,9 +2467,16 @@ public class NeverNote extends QMainWindow{ menuBar.tagDeleteAction.setEnabled(false); menuBar.tagIconAction.setEnabled(true); } + if (selections.size() > 1) + menuBar.tagMergeAction.setEnabled(true); + else + menuBar.tagMergeAction.setEnabled(false); listManager.setSelectedTags(selectedTagGUIDs); listManager.loadNotesIndex(); noteIndexUpdated(false); + refreshEvernoteNote(true); + listManager.refreshCounters = true; + listManager.refreshCounters(); logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection"); } // trigger the tag index to be refreshed @@ -2033,6 +2496,7 @@ public class NeverNote extends QMainWindow{ tagTree.setIcons(conn.getTagTable().getAllIcons()); tagTree.load(listManager.getTagIndex()); } + for (int i=selectedTagGUIDs.size()-1; i>=0; i--) { boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i)); if (!found) @@ -2044,6 +2508,7 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated"); } // Show/Hide note information + @SuppressWarnings("unused") private void toggleTagWindow() { logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow"); if (tagTree.isVisible()) @@ -2064,7 +2529,7 @@ public class NeverNote extends QMainWindow{ newTags.add(tags.get(i)); } - listManager.saveNoteTags(guid, tags); + listManager.saveNoteTags(guid, tags, true); listManager.countTagResults(listManager.getNoteIndex()); StringBuffer names = new StringBuffer(""); for (int i=0; i tags = new ArrayList(); + List selections = tagTree.selectedItems(); + for (int i=0; i noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid()); + for (int j=0; j selections = savedSearchTree.selectedItems(); QTreeWidgetItem currentSelection; selectedSavedSearchGUID = ""; @@ -2383,6 +2893,7 @@ public class NeverNote extends QMainWindow{ } // Show/Hide note information + @SuppressWarnings("unused") private void toggleSavedSearchWindow() { logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow"); if (savedSearchTree.isVisible()) @@ -2452,6 +2963,7 @@ public class NeverNote extends QMainWindow{ status.setTagCount(listManager.getTagIndex().size()); status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount()); status.setWordCount(conn.getWordsTable().getWordCount()); + status.setHistoryCount(conn.getHistoryTable().getHistoryCount()); waitCursor(false); status.exec(); } @@ -2461,7 +2973,7 @@ public class NeverNote extends QMainWindow{ logger.log(logger.HIGH, "Entering NeverNote.compactDatabase"); if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+ "but please be aware that depending upon the size of your database this can be time consuming " + - "and NeverNote will be unresponsive until it is complete. Do you wish to continue?"), + "and NeighborNote 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; @@ -2488,11 +3000,16 @@ public class NeverNote extends QMainWindow{ QTextEdit textBox = new QTextEdit(); layout.addWidget(textBox); textBox.setReadOnly(true); - QFile file = new QFile(Global.getFileManager().getHomeDirPath("release.txt")); + QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt")); if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly, QIODevice.OpenModeFlag.Text))) return; - textBox.setText(file.readAll().toString()); + // ICHANGED 日本語文字化け対策 + QTextCodec codec = QTextCodec.codecForName("UTF-8"); + QTextStream textStream = new QTextStream(file); + textStream.setCodec(codec); + textBox.setText(textStream.readAll().toString()); + file.close(); dialog.setWindowTitle(tr("Release Notes")); dialog.setLayout(layout); @@ -2511,20 +3028,24 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void about() { logger.log(logger.HIGH, "Entering NeverNote.about"); + // ICHANGED based on...の記述を付加 QMessageBox.about(this, - tr("About NeverNote"), - tr("

NeverNote


Version ") - +Global.version - +tr("
Evernote" - +"An Open Source Evernote Client.

" + tr("About NeighborNote"), + tr("

NeighborNote


Version ") + +Global.version + "(based on NixNote 1.5)" + //+"1.2.120724" + +tr("
" + +"Open Source Evernote Client.

" +"Licensed under GPL v2.


" - +"Evernote is copyright 2001-2010 by Evernote Corporation
" + +"
Evernote is copyright 2001-2012 by Evernote Corporation
" +"Jambi and QT are the licensed trademark of Nokia Corporation
" +"PDFRenderer is licened under the LGPL
" +"JTidy is copyrighted under the World Wide Web Consortium
" +"Apache Common Utilities licensed under the Apache License Version 2.0
" +"Jazzy is licened under the LGPL
" - +"Java is a registered trademark of Oracle Corporation.

")); + +"Java is a registered trademark of Oracle Corporation.

" + +"Special thanks to:
BitRock InstallBuilder for the Windows installer" + +"
CodeCogs (www.codecogs.com) for the LaTeX image rendering.")); logger.log(logger.HIGH, "Leaving NeverNote.about"); } // Hide the entire left hand side @@ -2535,16 +3056,10 @@ public class NeverNote extends QMainWindow{ hidden = !menuBar.hideLeftSide.isChecked(); menuBar.hideLeftSide.setChecked(!hidden); - if (notebookTree.isVisible() != hidden) - toggleNotebookWindow(); - if (savedSearchTree.isVisible() != hidden) - toggleSavedSearchWindow(); - if (tagTree.isVisible() != hidden) - toggleTagWindow(); - if (attributeTree.isVisible() != hidden) - toggleAttributesWindow(); - if (trashTree.isVisible() != hidden) - toggleTrashWindow(); + if (!hidden) + leftSplitter1.setHidden(true); + else + leftSplitter1.setHidden(false); Global.saveWindowVisible("leftPanel", hidden); @@ -2624,7 +3139,12 @@ public class NeverNote extends QMainWindow{ //*************************************************************** //** These functions deal with the Toolbar //*************************************************************** - //*************************************************************** + //*************************************************************** + @SuppressWarnings("unused") + private void focusSearch() { + searchField.setFocus(); + } + // Text in the search bar has been cleared private void searchFieldCleared() { saveNote(); @@ -2645,8 +3165,9 @@ public class NeverNote extends QMainWindow{ currentNote = listManager.getNoteIndex().get(0); currentNoteGuid = currentNote.getGuid(); } + refreshEvernoteNote(true); if (currentNote != null) - loadNoteBrowserInformation(browserWindow); + loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote); } // text in the search bar changed. We only use this to tell if it was cleared, // otherwise we trigger off searchFieldChanged. @@ -2669,6 +3190,7 @@ public class NeverNote extends QMainWindow{ listManager.loadNotesIndex(); refreshEvernoteNote(true); noteIndexUpdated(false); + refreshEvernoteNote(true); } searchPerformed = false; } @@ -2684,10 +3206,11 @@ public class NeverNote extends QMainWindow{ String text = searchField.currentText(); listManager.setEnSearch(text.trim()); listManager.loadNotesIndex(); -//--->>> noteIndexUpdated(true); noteIndexUpdated(false); + refreshEvernoteNote(true); searchPerformed = true; + waitCursor(false); logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged"); } @@ -2695,117 +3218,115 @@ public class NeverNote extends QMainWindow{ private void setupToolBar() { logger.log(logger.HIGH, "Entering NeverNote.setupToolBar"); toolBar = addToolBar(tr("Tool Bar")); + toolBar.setObjectName("toolBar"); menuBar.setupToolBarVisible(); if (!Global.isWindowVisible("toolBar")) toolBar.setVisible(false); else toolBar.setVisible(true); - prevButton = toolBar.addAction("Previous"); +// toolBar.addWidget(menuBar); +// menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum); +// toolBar.addSeparator(); + prevButton = toolBar.addAction(tr("Previous")); QIcon prevIcon = new QIcon(iconPath+"back.png"); prevButton.setIcon(prevIcon); prevButton.triggered.connect(this, "previousViewedAction()"); togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow")); - nextButton = toolBar.addAction("Next"); + nextButton = toolBar.addAction(tr("Next")); QIcon nextIcon = new QIcon(iconPath+"forward.png"); nextButton.setIcon(nextIcon); nextButton.triggered.connect(this, "nextViewedAction()"); toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow")); - upButton = toolBar.addAction("Up"); + upButton = toolBar.addAction(tr("Up")); QIcon upIcon = new QIcon(iconPath+"up.png"); upButton.setIcon(upIcon); upButton.triggered.connect(this, "upAction()"); toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow")); - downButton = toolBar.addAction("Down"); + downButton = toolBar.addAction(tr("Down")); QIcon downIcon = new QIcon(iconPath+"down.png"); downButton.setIcon(downIcon); downButton.triggered.connect(this, "downAction()"); toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow")); - synchronizeButton = toolBar.addAction("Synchronize"); + synchronizeButton = toolBar.addAction(tr("Synchronize")); synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png")); synchronizeIconAngle = 0; synchronizeButton.triggered.connect(this, "evernoteSync()"); toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize")); - printButton = toolBar.addAction("Print"); + printButton = toolBar.addAction(tr("Print")); QIcon printIcon = new QIcon(iconPath+"print.png"); printButton.setIcon(printIcon); printButton.triggered.connect(this, "printNote()"); togglePrintButton(Global.isToolbarButtonVisible("print")); - tagButton = toolBar.addAction("Tag"); + tagButton = toolBar.addAction(tr("Tag")); QIcon tagIcon = new QIcon(iconPath+"tag.png"); tagButton.setIcon(tagIcon); tagButton.triggered.connect(browserWindow, "modifyTags()"); toggleTagButton(Global.isToolbarButtonVisible("tag")); - attributeButton = toolBar.addAction("Attributes"); + attributeButton = toolBar.addAction(tr("Attributes")); QIcon attributeIcon = new QIcon(iconPath+"attribute.png"); attributeButton.setIcon(attributeIcon); - attributeButton.triggered.connect(this, "toggleNoteInformation()"); + attributeButton.triggered.connect(this, "toggleNoteAttributes()"); toggleAttributeButton(Global.isToolbarButtonVisible("attribute")); - emailButton = toolBar.addAction("Email"); + emailButton = toolBar.addAction(tr("Email")); QIcon emailIcon = new QIcon(iconPath+"email.png"); emailButton.setIcon(emailIcon); emailButton.triggered.connect(this, "emailNote()"); toggleEmailButton(Global.isToolbarButtonVisible("email")); - deleteButton = toolBar.addAction("Delete"); + deleteButton = toolBar.addAction(tr("Delete")); QIcon deleteIcon = new QIcon(iconPath+"delete.png"); deleteButton.setIcon(deleteIcon); deleteButton.triggered.connect(this, "deleteNote()"); toggleDeleteButton(Global.isToolbarButtonVisible("delete")); - newButton = toolBar.addAction("New"); + newButton = toolBar.addAction(tr("New")); QIcon newIcon = new QIcon(iconPath+"new.png"); newButton.triggered.connect(this, "addNote()"); newButton.setIcon(newIcon); toggleNewButton(Global.isToolbarButtonVisible("new")); - allNotesButton = toolBar.addAction("All Notes"); + allNotesButton = toolBar.addAction(tr("All Notes")); QIcon allIcon = new QIcon(iconPath+"books.png"); allNotesButton.triggered.connect(this, "allNotes()"); allNotesButton.setIcon(allIcon); toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes")); - toolBar.addSeparator(); - toolBar.addWidget(new QLabel(tr("Quota:"))); - toolBar.addWidget(quotaBar); + //toolBar.addSeparator(); + //toolBar.addWidget(new QLabel(tr("Quota:"))); + //toolBar.addWidget(quotaBar); //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum); updateQuotaBar(); - toolBar.addSeparator(); + //toolBar.addSeparator(); - // Setup the zoom - zoomSpinner = new QSpinBox(); - zoomSpinner.setMinimum(10); - zoomSpinner.setMaximum(1000); - zoomSpinner.setAccelerated(true); - zoomSpinner.setSingleStep(10); - zoomSpinner.setValue(100); - zoomSpinner.valueChanged.connect(this, "zoomChanged()"); - toolBar.addWidget(new QLabel(tr("Zoom"))); - toolBar.addWidget(zoomSpinner); + //toolBar.addWidget(new QLabel(tr("Zoom"))); + //toolBar.addWidget(zoomSpinner); //toolBar.addWidget(new QLabel(" ")); - toolBar.addSeparator(); - toolBar.addWidget(new QLabel(tr(" Search:"))); - toolBar.addWidget(searchField); + //toolBar.addSeparator(); + //toolBar.addWidget(new QLabel(tr(" Search:"))); + //toolBar.addWidget(searchField); QSizePolicy sizePolicy = new QSizePolicy(); sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding); - searchField.setSizePolicy(sizePolicy); - searchField.setInsertPolicy(InsertPolicy.InsertAtTop); + QLabel spacer = new QLabel(""); + spacer.setSizePolicy(sizePolicy); + toolBar.addWidget(spacer); + //searchField.setInsertPolicy(InsertPolicy.InsertAtTop); - searchClearButton = toolBar.addAction("Search Clear"); - QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png"); - searchClearButton.setIcon(searchClearIcon); - searchClearButton.triggered.connect(this, "searchFieldCleared()"); - toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear")); + //searchClearButton = toolBar.addAction("Search Clear"); + //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png"); + //searchClearButton.setIcon(searchClearIcon); + //searchClearButton.triggered.connect(this, "searchFieldCleared()"); + //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear")); logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar"); } @@ -2925,7 +3446,8 @@ public class NeverNote extends QMainWindow{ allNotesButton.setVisible(toggle); Global.saveToolbarButtonsVisible("allNotes", toggle); } - private void toggleSearchClearButton(Boolean toggle) { + @SuppressWarnings("unused") + private void toggleSearchClearButton(Boolean toggle) { searchClearButton.setVisible(toggle); Global.saveToolbarButtonsVisible("searchClear", toggle); } @@ -2966,7 +3488,7 @@ public class NeverNote extends QMainWindow{ } // Synchronize with Evernote - @SuppressWarnings("unused") + private void evernoteSync() { logger.log(logger.HIGH, "Entering NeverNote.evernoteSync"); if (!Global.isConnected) @@ -3055,14 +3577,25 @@ public class NeverNote extends QMainWindow{ Global.showDeleted = false; menuBar.noteRestoreAction.setEnabled(false); menuBar.noteRestoreAction.setVisible(false); + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + rensoNoteListDock.setEnabled(true); } else { + trashNoteGuid = tempGuid; currentNoteGuid = trashNoteGuid; - trashNoteGuid = tempGuid; menuBar.noteRestoreAction.setEnabled(true); menuBar.noteRestoreAction.setVisible(true); + // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。 + rensoNoteListDock.setEnabled(false); + Global.showDeleted = true; } + + menuBar.noteAddNewTab.setEnabled(newButton.isEnabled()); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + menuBar.noteAddNewTab.setEnabled(false); + } + listManager.loadNotesIndex(); noteIndexUpdated(false); //// browserWindow.setEnabled(newButton.isEnabled()); @@ -3073,13 +3606,19 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void emptyTrash() { // browserWindow.clear(); + logger.log(logger.EXTREME, "Emptying Trash"); listManager.emptyTrash(); + logger.log(logger.EXTREME, "Resetting view after trash empty"); if (trashTree.selectedItems().size() > 0) { listManager.getSelectedNotebooks().clear(); listManager.getSelectedTags().clear(); listManager.setSelectedSavedSearch(""); newButton.setEnabled(!newButton.isEnabled()); menuBar.noteAdd.setEnabled(newButton.isEnabled()); + menuBar.noteAddNewTab.setEnabled(newButton.isEnabled()); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + menuBar.noteAddNewTab.setEnabled(false); + } menuBar.noteAdd.setVisible(true); browserWindow.clear(); @@ -3093,11 +3632,16 @@ public class NeverNote extends QMainWindow{ menuBar.noteRestoreAction.setVisible(false); listManager.loadNotesIndex(); -//--->>> noteIndexUpdated(true); noteIndexUpdated(false); + + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + if (!rensoNoteListDock.isEnabled()) { + rensoNoteListDock.setEnabled(true); + } } } // Show/Hide trash window + @SuppressWarnings("unused") private void toggleTrashWindow() { logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow"); if (trashTree.isVisible()) @@ -3113,6 +3657,11 @@ public class NeverNote extends QMainWindow{ Global.showDeleted = false; newButton.setEnabled(true); menuBar.noteAdd.setEnabled(true); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + menuBar.noteAddNewTab.setEnabled(false); + } else { + menuBar.noteAddNewTab.setEnabled(true); + } menuBar.noteAdd.setVisible(true); trashTree.blockSignals(true); trashTree.clearSelection(); @@ -3138,8 +3687,10 @@ public class NeverNote extends QMainWindow{ } // Do a manual connect/disconnect private void remoteConnect() { + logger.log(logger.HIGH, "Entering NeverNote.remoteConnect"); + // If we are already connected, we just disconnect if (Global.isConnected) { Global.isConnected = false; syncRunner.enDisconnect(); @@ -3148,13 +3699,15 @@ public class NeverNote extends QMainWindow{ return; } + OAuthTokenizer tokenizer = new OAuthTokenizer(); AESEncrypter aes = new AESEncrypter(); try { - aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("secure.txt"))); + aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt"))); } catch (FileNotFoundException e) { // File not found, so we'll just get empty strings anyway. } - + + if (Global.getProxyValue("url").equals("")) { System.setProperty("http.proxyHost","") ; System.setProperty("http.proxyPort", "") ; @@ -3181,43 +3734,54 @@ public class NeverNote extends QMainWindow{ syncRunner.userStoreUrl = Global.userStoreUrl; syncRunner.noteStoreUrl = Global.noteStoreUrl; syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase; - - String userid = aes.getUserid(); - String password = aes.getPassword(); - if (!userid.equals("") && !password.equals("")) { - Global.username = userid; - Global.password = password; - syncRunner.username = Global.username; - syncRunner.password = Global.password; + + + + String authString = aes.getString(); + if (!authString.equals("")) { + tokenizer.tokenize(authString); + syncRunner.authToken = tokenizer.oauth_token; syncRunner.enConnect(); } Global.isConnected = syncRunner.isConnected; if (!Global.isConnected) { - // Show the login dialog box - if (!Global.automaticLogin() || userid.equals("")|| password.equals("")) { - LoginDialog login = new LoginDialog(); - login.exec(); - - if (!login.okPressed()) { - return; - } - - Global.username = login.getUserid(); - Global.password = login.getPassword(); + OAuthWindow window = new OAuthWindow(logger); + if (window.error) { + setMessage(window.errorMessage); + return; + } + window.exec(); + if (window.error) { + setMessage(window.errorMessage); + return; + } + tokenizer.tokenize(window.response); + if (tokenizer.oauth_token.equals("")) { + setMessage(tr("Invalid authorization token received.")); + return; + } + aes.setString(window.response); + try { + aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt"))); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } - syncRunner.username = Global.username; - syncRunner.password = Global.password; + syncRunner.authToken = tokenizer.oauth_token; syncRunner.enConnect(); Global.isConnected = syncRunner.isConnected; } - +// Global.username = syncRunner.username; + if (!Global.isConnected) return; setupOnlineMenu(); setupConnectMenuOptions(); logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect"); + + } private void setupConnectMenuOptions() { logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions"); @@ -3247,6 +3811,11 @@ public class NeverNote extends QMainWindow{ // clearNotebookFilter(); clearTrashFilter(); // clearSavedSearchFilter(); + + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + if (!rensoNoteListDock.isEnabled()) { + rensoNoteListDock.setEnabled(true); + } if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) { if (item.childCount() > 0) { @@ -3301,6 +3870,7 @@ public class NeverNote extends QMainWindow{ } // Show/Hide attribute search window + @SuppressWarnings("unused") private void toggleAttributesWindow() { logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow"); if (attributeTree.isVisible()) @@ -3354,23 +3924,71 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void noteTableSelection() { logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection"); + saveNote(); - if (historyGuids.size() == 0) { - historyGuids.add(currentNoteGuid); - historyPosition = 1; + + // ICHANGED + // 右クリックだったときの処理 + if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) { + // 選択されたノートのguidをselectedNoteGUIDsにセット + List selections = noteTableView.selectionModel().selectedRows(); + if(selections.size() > 0){ + selectedNoteGUIDs.clear(); + for(int i = 0; i < selections.size(); i++){ + int row = selections.get(i).row(); + QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition); + SortedMap ix = noteTableView.proxyModel.itemData(index); + selectedNoteGUIDs.add((String) ix.values().toArray()[0]); + } + } + return; } - noteTableView.showColumn(Global.noteTableGuidPosition); - + + // If we have more than one selection, then set the merge note action to true. List selections = noteTableView.selectionModel().selectedRows(); - if (!Global.isColumnVisible("guid")) - noteTableView.hideColumn(Global.noteTableGuidPosition); - - if (selections.size() > 0) { + if (selections.size() > 1) + menuBar.noteMergeAction.setEnabled(true); + else + menuBar.noteMergeAction.setEnabled(false); + + // If the ctrl key is pressed, then they are selecting multiple + // entries and we don't want to change the currently viewed note. + // ICHANGED + // Shiftキーを押しながらの場合の処理も追加 + if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) || + QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) && + QApplication.mouseButtons().isSet(MouseButton.LeftButton)){ + selectedNoteGUIDs.clear(); + for (int i=0; i ix = noteTableView.proxyModel.itemData(index); + selectedNoteGUIDs.add((String)ix.values().toArray()[0]); + } + return; + } + + // ICHANGED たぶんこれは不要 + // IFIXED ? + /*if (historyGuids.size() == 0) { + historyGuids.add(currentNoteGuid); + historyPosition = 1; + }*/ + + noteTableView.showColumn(Global.noteTableGuidPosition); + + if (!Global.isColumnVisible("guid")) + noteTableView.hideColumn(Global.noteTableGuidPosition); + + if (selections.size() > 0) { QModelIndex index; menuBar.noteDuplicateAction.setEnabled(true); menuBar.noteOnlineHistoryAction.setEnabled(true); menuBar.noteMergeAction.setEnabled(true); selectedNoteGUIDs.clear(); + if (currentNoteGuid != null && !currentNoteGuid.equals("") && !Global.showDeleted) { + menuBar.noteAddNewTab.setEnabled(true); + } if (selections.size() != 1 || Global.showDeleted) { menuBar.noteDuplicateAction.setEnabled(false); } @@ -3392,31 +4010,87 @@ public class NeverNote extends QMainWindow{ downButton.setEnabled(false); index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition); SortedMap ix = noteTableView.proxyModel.itemData(index); - currentNoteGuid = (String)ix.values().toArray()[0]; + + currentNoteGuid = (String)ix.values().toArray()[0]; selectedNoteGUIDs.add(currentNoteGuid); } } nextButton.setEnabled(true); prevButton.setEnabled(true); - if (!fromHistory) { - int endPosition = historyGuids.size()-1; - for (int j=historyPosition; j<=endPosition; j++) { - historyGuids.remove(historyGuids.size()-1); - } - historyGuids.add(currentNoteGuid); - historyPosition = historyGuids.size(); - } - if (historyPosition <= 1) - prevButton.setEnabled(false); - if (historyPosition == historyGuids.size()) - nextButton.setEnabled(false); - - fromHistory = false; + + // ICHANGED + int currentIndex = tabBrowser.currentIndex(); + ArrayList histGuids = historyGuids.get(currentIndex); + int histPosition = historyPosition.get(currentIndex); + boolean fromHist = fromHistory.get(currentIndex); + + // ICHANGED + if (!fromHist) { + int endPosition = histGuids.size() - 1; + + for (int j = histPosition; j <= endPosition; j++) { + histGuids.remove(histGuids.size() - 1); + } + histGuids.add(currentNoteGuid); + historyPosition.put(currentIndex, histGuids.size()); + histPosition = histGuids.size(); + } + if (histPosition <= 1){ + prevButton.setEnabled(false); + } + if (histPosition == histGuids.size()) + nextButton.setEnabled(false); + fromHistory.put(currentIndex, false); + fromHist = false; + scrollToGuid(currentNoteGuid); refreshEvernoteNote(true); + + // ICHANGED + if (currentNoteGuid != null && !currentNoteGuid.equals("")) { + if (!Global.showDeleted) { // ゴミ箱じゃなければ + addBrowseHistory(); + } + } + + // ICHANGED + // 連想ノートリストを更新 + rensoNoteList.refreshRensoNoteList(currentNoteGuid); + + waitCursor(false); logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection"); - } + } + + + // ICHANGED + // 複数ノートの同時閲覧履歴をデータベースに保存 + private void addBrowseHistory() { + // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録 + if (tabWindows.size() >= 2) { + Iterator it = tabWindows.keySet().iterator(); + while (it.hasNext()) { + int tabIndex = it.next(); + String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid(); + // guid1=guid2のデータは登録しない + if (!currentNoteGuid.equals(nextGuid)) { + conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid); + } + } + } + // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録 + if (externalWindows.size() >= 1) { + Iterator it = externalWindows.keySet().iterator(); + while (it.hasNext()) { + String nextGuid = it.next(); + // guid1=guid2のデータは登録しない + if (!currentNoteGuid.equals(nextGuid)) { + conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid); + } + } + } + } + // Trigger a refresh when the note db has been updated private void noteIndexUpdated(boolean reload) { logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated"); @@ -3436,12 +4110,12 @@ public class NeverNote extends QMainWindow{ QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition); if (i!=null) { currentNoteGuid = (String)i.data(); - noteTableView.selectRow(pos-1); } } } - showColumns(); - scrollToGuid(currentNoteGuid); + if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition)) + showColumns(); + scrollToGuid(currentNoteGuid); logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated"); } // Called when the list of notes is updated @@ -3454,9 +4128,13 @@ public class NeverNote extends QMainWindow{ String saveCurrentNoteGuid = new String(); String tempNoteGuid = new String(); - - historyGuids.clear(); - historyPosition = 0; + + // ICHANGED + int currentIndex = tabBrowser.currentIndex(); + ArrayList histGuids = historyGuids.get(currentIndex); + histGuids.clear(); + historyPosition.put(currentIndex, 0); + prevButton.setEnabled(false); nextButton.setEnabled(false); @@ -3476,59 +4154,86 @@ public class NeverNote extends QMainWindow{ currentNote = null; browserWindow.clear(); browserWindow.setDisabled(true); + waitCursor(false); } + if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) { + currentNoteGuid = listManager.getNoteIndex().get(0).getGuid(); + saveCurrentNoteGuid = currentNoteGuid; + refreshEvernoteNote(true); + } + if (!saveCurrentNoteGuid.equals("")) { refreshEvernoteNote(false); } else { - currentNoteGuid = ""; + currentNoteGuid = ""; } reloadTagTree(false); logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList"); } - // Called when the previous arrow button is clicked - @SuppressWarnings("unused") + + // ICHANGED + // Called when the previous arrow button is clicked + @SuppressWarnings("unused") private void previousViewedAction() { - if (!prevButton.isEnabled()) - return; - if (historyPosition == 0) - return; - historyPosition--; - if (historyPosition <= 0) - return; - String historyGuid = historyGuids.get(historyPosition-1); - fromHistory = true; - for (int i=0; i ix = noteTableView.model().itemData(modelIndex); - String tableGuid = (String)ix.values().toArray()[0]; - if (tableGuid.equals(historyGuid)) { - noteTableView.selectRow(i); - return; - } - } - } - } + int currentIndex = tabBrowser.currentIndex(); + ArrayList histGuids = historyGuids.get(currentIndex); + int histPosition = historyPosition.get(currentIndex); + boolean fromHist = fromHistory.get(currentIndex); + if (!prevButton.isEnabled()) + return; + if (histPosition == 0) + return; + histPosition--; + historyPosition.put(currentIndex, histPosition); + if (histPosition <= 0) + return; + String historyGuid = histGuids.get(histPosition - 1); + fromHistory.put(currentIndex, true); + fromHist = true; + for (int i = 0; i < noteTableView.model().rowCount(); i++) { + QModelIndex modelIndex = noteTableView.model().index(i, + Global.noteTableGuidPosition); + if (modelIndex != null) { + SortedMap ix = noteTableView.model().itemData( + modelIndex); + String tableGuid = (String) ix.values().toArray()[0]; + if (tableGuid.equals(historyGuid)) { + noteTableView.selectRow(i); + return; + } + } + } + } + @SuppressWarnings("unused") private void nextViewedAction() { if (!nextButton.isEnabled()) return; - String historyGuid = historyGuids.get(historyPosition); - historyPosition++; - fromHistory = true; - for (int i=0; i ix = noteTableView.model().itemData(modelIndex); - String tableGuid = (String)ix.values().toArray()[0]; - if (tableGuid.equals(historyGuid)) { - noteTableView.selectRow(i); - return; - } - } - } + // ICHANGED + int currentIndex = tabBrowser.currentIndex(); + ArrayList histGuids = historyGuids.get(currentIndex); + int histPosition = historyPosition.get(currentIndex); + boolean fromHist = fromHistory.get(currentIndex); + String historyGuid = histGuids.get(histPosition); + histPosition++; + historyPosition.put(currentIndex, histPosition); + fromHistory.put(currentIndex, true); + fromHist = true; + for (int i = 0; i < noteTableView.model().rowCount(); i++) { + QModelIndex modelIndex = noteTableView.model().index(i, + Global.noteTableGuidPosition); + if (modelIndex != null) { + SortedMap ix = noteTableView.model().itemData( + modelIndex); + String tableGuid = (String) ix.values().toArray()[0]; + if (tableGuid.equals(historyGuid)) { + noteTableView.selectRow(i); + return; + } + } + } } // Called when the up arrow is clicked @SuppressWarnings("unused") @@ -3776,6 +4481,7 @@ public class NeverNote extends QMainWindow{ String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data(); scrollToGuid(guid); } + // Scroll to the current GUID in tthe list. // Scroll to a particular index item private void scrollToGuid(String guid) { if (currentNote == null || guid == null) @@ -3789,7 +4495,6 @@ public class NeverNote extends QMainWindow{ } } } - if (!currentNote.isActive() && !Global.showDeleted) { for (int i=0; i selectedNotebook = notebookTree.selectedItems(); + if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) { + QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0); + String notebook; + notebook = currentSelectedNotebook.text(2); + conn.getNotebookTable().setSortOrder(notebook, column, order); + } + } - + //*************************************************************** + @SuppressWarnings("unused") + private void evernoteLinkClick(String syncGuid, String locGuid) { + String guid = null; + if (conn.getNoteTable().guidExists(syncGuid)) { + guid = syncGuid; + } else { + // If we didn't find it via the synchronized guid, look under the local guid + // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was + // later synchronized (that causes the guid to change so we need to find the new one). + if (conn.getNoteTable().guidExists(locGuid)) + guid = locGuid; + else + guid = conn.getNoteTable().findAlternateGuid(locGuid); + } + if (guid != null) { + openExternalEditor(guid); + return; + } + + //If we've gotten this far, we can't find the note + QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+ + " seem to find that note.")); + } //*************************************************************** //*************************************************************** //** External editor window functions //*************************************************************** //*************************************************************** private void listDoubleClick() { - saveNote(); - if (externalWindows.containsKey(currentNoteGuid)) { - externalWindows.get(currentNoteGuid).raise(); + saveNote(); + openExternalEditor(currentNoteGuid); + } + private void openExternalEditor(String guid) { + + if (externalWindows.containsKey(guid)) { + externalWindows.get(guid).raise(); return; } + + Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true); // We have a new external editor to create QIcon appIcon = new QIcon(iconPath+"nevernote.png"); - ExternalBrowse newBrowser = new ExternalBrowse(conn); + // ICHANGED + ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver); + newBrowser.setWindowIcon(appIcon); - externalWindows.put(currentNoteGuid, newBrowser); + externalWindows.put(guid, newBrowser); showEditorButtons(newBrowser.getBrowserWindow()); - loadNoteBrowserInformation(newBrowser.getBrowserWindow()); + loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note); setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false); newBrowser.windowClosing.connect(this, "externalWindowClosing(String)"); - newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)"); + //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)"); newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)"); newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)"); + newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)"); + newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()"); browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)"); browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)"); @@ -3963,12 +4742,6 @@ public class NeverNote extends QMainWindow{ newBrowser.show(); } - @SuppressWarnings("unused") - private void externalWindowTitleEdited(String guid, String text) { - if (guid.equals(currentNoteGuid)) { - browserWindow.setTitle(text); - } - } @SuppressWarnings({ "rawtypes", "unused" }) private void externalWindowTagsEdited(String guid, List values) { StringBuffer line = new StringBuffer(100); @@ -3986,51 +4759,294 @@ public class NeverNote extends QMainWindow{ externalWindows.remove(guid); } - - + // *************************************************************** + // *************************************************************** + // ** タブウィンドウの機能 + // *************************************************************** + // *************************************************************** + @SuppressWarnings("unused") + private void openNewTab() { + saveNote(); + + // selectedNoteGUIDsをディープコピー + List copySelected = new ArrayList(selectedNoteGUIDs); + + for (int i=0; i < copySelected.size() ; i++) { + openTabEditor(copySelected.get(i)); + } + } + + // ICHANGED 連想ノートリストから新しいタブで開く + @SuppressWarnings("unused") + private void openNewTabFromRNL(){ + if(rensoNotePressedItemGuid != null){ + String prevCurrentNoteGuid = new String(currentNoteGuid); + + saveNote(); + openTabEditor(rensoNotePressedItemGuid); + + // 連想ノートリストアイテムクリック操作を記録 + conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid); + } + } + + // ICHANGED + private void openTabEditor(String guid) { + + Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true); + // 新しいタブエディタを作成 + TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver); + showEditorButtons(newBrowser.getBrowserWindow()); + + String noteTitle = note.getTitle(); + int index = tabBrowser.addNewTab(newBrowser, noteTitle); + tabWindows.put(index, newBrowser); + noteDirty.put(index, false); + + // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断 + noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()"); + loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note); + // 再接続 + noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()"); + + setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false); + + // ExtendedInformationを必要があれば表示する + toggleNoteInformation(); + // Sourceを必要があれば表示する + viewSource(); + // EditorButtonsBarを必要があれば表示する + toggleEditorButtonBar(); + + // 履歴記録のハッシュマップを初期化 + ArrayList histGuids = new ArrayList(); + historyGuids.put(index, histGuids); + historyPosition.put(index, 0); + fromHistory.put(index, false); + + // 履歴に今開いたノートを追加 + histGuids.add(guid); + historyPosition.put(index, histGuids.size()); + + tabBrowser.setCurrentIndex(index); + + if (guid != null && !guid.equals("")) { + if (!Global.showDeleted) { // ゴミ箱じゃなければ + addBrowseHistory(); + } + } + } + + // ICHANGED タブが閉じられた + private void tabWindowClosing(int index) { + // タブが1つしかなかったら閉じない + if (tabBrowser.count() <= 1) { + return; + } + + TabBrowse t = (TabBrowse) tabBrowser.widget(index); + String guid = t.getBrowserWindow().getNote().getGuid(); + String content = t.getBrowserWindow().getContent(); + BrowserWindow browser = t.getBrowserWindow(); + // ノートが変更されていたら保存 + if (t.getNoteDirty()) { + saveNoteTabBrowser(guid, content, true, browser); + } + + // シグナル切断 + browser.noteSignal.tagsChanged.disconnect(); + browser.noteSignal.titleChanged.disconnect(); + browser.noteSignal.noteChanged.disconnect(); + browser.noteSignal.notebookChanged.disconnect(); + browser.noteSignal.createdDateChanged.disconnect(); + browser.noteSignal.alteredDateChanged.disconnect(); + + // ノートを削除 + tabWindows.remove(index); + tabBrowser.removeTab(index); + noteDirty.remove(index); + inkNote.remove(index); + readOnly.remove(index); + + // 履歴記録のハッシュマップを削除 + historyGuids.remove(index); + historyPosition.remove(index); + fromHistory.remove(index); + + // タブのインデックスを更新(削除によって空いた部分を詰める) + for(int i = index ; tabWindows.containsKey(i + 1) ; i++){ + // tabWindows + TabBrowse tab = tabWindows.get(i + 1); + tabWindows.put(i, tab); + tabWindows.remove(i + 1); + // noteDirty + boolean isNoteDirty = noteDirty.get(i + 1); + noteDirty.put(i, isNoteDirty); + noteDirty.remove(i + 1); + // inkNote + boolean isInkNote = inkNote.get(i + 1); + inkNote.put(i, isInkNote); + inkNote.remove(i + 1); + // readOnly + boolean isReadOnly = readOnly.get(i + 1); + readOnly.put(i, isReadOnly); + readOnly.remove(i + 1); + // historyGuids + ArrayList histGuids = historyGuids.get(i + 1); + historyGuids.put(i, histGuids); + historyGuids.remove(i + 1); + // historyPosition + int histPosition = historyPosition.get(i + 1); + historyPosition.put(i, histPosition); + historyPosition.remove(i + 1); + // fromHistory + boolean fromHist = fromHistory.get(i + 1); + fromHistory.put(i, fromHist); + fromHistory.remove(i + 1); + } + + // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす + tabWindowChanged(tabBrowser.currentIndex()); + } + + @SuppressWarnings("unused") + private void noteAddNewTab() { + saveNote(); + + // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく + TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget(); + String prevTabGuid = null; + if (prevTab.getBrowserWindow() != null && prevTab.getBrowserWindow().getNote() != null) { + prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid(); + } + + openEmptyTabEditor(); + addNote(); + + // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録 + if (prevTabGuid != null && !prevTabGuid.equals("")) { + TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget(); + String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid(); + if (addedTabGuid != null && !addedTabGuid.equals("")) { + if (!prevTabGuid.equals(addedTabGuid)) { + conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid); + } + } + } + } + + // ICHANGED + private void openEmptyTabEditor() { + // 新しいタブエディタを作成 + TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver); + showEditorButtons(newBrowser.getBrowserWindow()); + + setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false); + + int index = tabBrowser.addNewTab(newBrowser, ""); + tabWindows.put(index, newBrowser); + noteDirty.put(index, false); + + // ExtendedInformationを必要があれば表示する + toggleNoteInformation(); + // Sourceを必要があれば表示する + viewSource(); + // EditorButtonsBarを必要があれば表示する + toggleEditorButtonBar(); + + // 履歴記録のハッシュマップを初期化 + ArrayList histGuids = new ArrayList(); + historyGuids.put(index, histGuids); + historyPosition.put(index, 0); + fromHistory.put(index, false); + + tabBrowser.setCurrentIndex(index); + } + //*************************************************************** //*************************************************************** //** These functions deal with Note specific things //*************************************************************** //*************************************************************** - @SuppressWarnings("unused") + // ICHANGED private void setNoteDirty() { + for (String guid: selectedNoteGUIDs) { + setNoteDirty(guid); + } + } + + // ICHANGED + private void setNoteDirty(String targetGuid) { logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()"); // Find if the note is being edited externally. If it is, update it. - if (externalWindows.containsKey(currentNoteGuid)) { + if (externalWindows.containsKey(targetGuid)) { QTextCodec codec = QTextCodec.codecForName("UTF-8"); QByteArray unicode = codec.fromUnicode(browserWindow.getContent()); - ExternalBrowse window = externalWindows.get(currentNoteGuid); - window.getBrowserWindow().getBrowser().setContent(unicode); + ExternalBrowse window = externalWindows.get(targetGuid); + window.getBrowserWindow().setContent(unicode); } + // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。 + Collection tabIndexes = tabWindows.keySet(); + Iterator indexIterator = tabIndexes.iterator(); + + for (TabBrowse tab: tabWindows.values()) { + int index = indexIterator.next(); + String guid = tab.getBrowserWindow().getNote().getGuid(); + + QTextCodec codec = QTextCodec.codecForName("UTF-8"); + QByteArray unicode = codec.fromUnicode(browserWindow.getContent()); + + if (guid.equals(guid)) { + if (index != tabBrowser.currentIndex()) { + TabBrowse window = tabWindows.get(index); + window.getBrowserWindow().setContent(unicode); + } + } + } + + // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する // If the note is dirty, then it is unsynchronized by default. - if (noteDirty) + int index = -1; + boolean isNoteDirty = false; + for (TabBrowse tab: tabWindows.values()) { + if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) { + index = tabBrowser.indexOf(tab); + isNoteDirty = noteDirty.get(index); + break; + } + } + if (isNoteDirty) { return; + } // Set the note as dirty and check if its status is synchronized in the display table - noteDirty = true; - for (int i=0; i= 0) { + noteDirty.put(index, true); + } + + if (listManager.getNoteMetadata().containsKey(targetGuid) && + listManager.getNoteMetadata().get(targetGuid).isDirty()) { return; } // If this wasn't already marked as unsynchronized, then we need to update the table - listManager.getNoteTableModel().updateNoteSyncStatus(currentNoteGuid, false); -/* listManager.getUnsynchronizedNotes().add(currentNoteGuid); + listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false); +// listManager.getUnsynchronizedNotes().add(targetGuid); for (int i=0; i ix = listManager.getNoteTableModel().itemData(modelIndex); String tableGuid = (String)ix.values().toArray()[0]; - if (tableGuid.equals(currentNoteGuid)) { - listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false"); + if (tableGuid.equals(targetGuid)) { + listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false"); return; } } } - */ + logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()"); } @SuppressWarnings("unused") @@ -4040,8 +5056,10 @@ public class NeverNote extends QMainWindow{ noteCache.remove(guid); noteCache.put(guid, unicode.toString()); if (guid.equals(currentNoteGuid)) { - noteDirty = true; - browserWindow.getBrowser().setContent(unicode); + // ICHANGED + int index = tabBrowser.currentIndex(); + noteDirty.put(index, true); + browserWindow.setContent(unicode); } if (save) { thumbnailRunner.addWork("GENERATE "+ guid); @@ -4049,16 +5067,41 @@ public class NeverNote extends QMainWindow{ } } + + // ICHANGED + private void saveNoteTabBrowser(String guid, String content, Boolean save, + BrowserWindow browser) { + QTextCodec codec = QTextCodec.codecForName("UTF-8"); + QByteArray unicode = codec.fromUnicode(content); + noteCache.remove(guid); + noteCache.put(guid, unicode.toString()); + if (save) { + thumbnailRunner.addWork("GENERATE " + guid); + saveNote(guid, browser); + } + } + private void saveNote() { - if (noteDirty) { - saveNote(currentNoteGuid, browserWindow); - thumbnailRunner.addWork("GENERATE "+ currentNoteGuid); - noteDirty = false; + // ICHANGED + // すべてのタブに対して、Dirtyを確認し、trueならセーブする + Collection dirtyIndex = noteDirty.keySet(); + Iterator indexIterator = dirtyIndex.iterator(); + for (boolean isNoteDirty: noteDirty.values()) { + int index = indexIterator.next(); + if (isNoteDirty) { + if (index < 0) { + return; + } + BrowserWindow b = tabWindows.get(index).getBrowserWindow(); + String guid = b.getNote().getGuid(); + saveNote(guid, b); + thumbnailRunner.addWork("GENERATE "+ guid); + noteDirty.put(index, false); + } } } private void saveNote(String guid, BrowserWindow window) { logger.log(logger.EXTREME, "Inside NeverNote.saveNote()"); - logger.log(logger.EXTREME, "Note is dirty."); waitCursor(true); logger.log(logger.EXTREME, "Saving to cache"); @@ -4091,14 +5134,16 @@ public class NeverNote extends QMainWindow{ browserWindow.setEnabled(false); return; } - inkNote = false; - readOnly = false; - if (Global.showDeleted) - readOnly = true; + // ICHANGED + inkNote.put(tabBrowser.currentIndex(), false); + readOnly.put(tabBrowser.currentIndex(), false); + + if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) { + readOnly.put(tabBrowser.currentIndex(), true); + } Global.cryptCounter =0; - if (currentNoteGuid.equals("")) { + if (readOnly.get(tabBrowser.currentIndex())) { browserWindow.setReadOnly(true); - return; } if (!reload) @@ -4108,69 +5153,113 @@ public class NeverNote extends QMainWindow{ browserWindow.loadingData(true); currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true); - if (currentNote == null) + if (currentNote == null) { + waitCursor(false); return; + } + + // ICHANGED + tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle()); - loadNoteBrowserInformation(browserWindow); + loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote); } - private void loadNoteBrowserInformation(BrowserWindow browser) { + // ICHANGED + private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) { NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles); - formatter.setNote(currentNote, Global.pdfPreview()); + formatter.setNote(note, Global.pdfPreview()); formatter.setHighlight(listManager.getEnSearch()); QByteArray js; - if (!noteCache.containsKey(currentNoteGuid) || conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) { + int tabIndex = -1; + + // 対象のタブインデックスを取得 + for (TabBrowse tab: tabWindows.values()) { + if (tab.getBrowserWindow() == browser) { + tabIndex = tabBrowser.indexOf(tab); + break; + } + } + + if (!noteCache.containsKey(guid)) { js = new QByteArray(); // We need to prepend the note with or encoded characters are ugly js.append(""); js.append(""); js.append(""); - js.append(""); + js.append(""); + if (Global.displayRightToLeft()) + js.append(""); js.append(""); js.append(""); - formatter.setNote(currentNote, Global.pdfPreview()); + formatter.setNote(note, Global.pdfPreview()); js.append(formatter.rebuildNoteHTML()); js.append(""); js.replace("", ""); js.replace("", ""); js.replace("", ""); - browser.getBrowser().setContent(js); - noteCache.put(currentNoteGuid, js.toString()); +// if (Global.enableHTMLEntitiesFix) { +// browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString()))); +// } else + browser.setContent(js); + noteCache.put(guid, js.toString()); if (formatter.resourceError) - resourceErrorMessage(); - readOnly = formatter.readOnly; - inkNote = formatter.inkNote; - if (readOnly) - readOnlyCache.put(currentNoteGuid, true); - if (inkNote) - inkNoteCache.put(currentNoteGuid, true); + resourceErrorMessage(tabIndex); + if (formatter.formatError) { + waitCursor(false); + QMessageBox.information(this, tr("Error"), + tr("NeighborNote had issues formatting this note." + + " To protect your data this note is being marked as read-only.")); + waitCursor(true); + } + + if (tabIndex >= 0) { + readOnly.put(tabIndex, formatter.readOnly); + inkNote.put(tabIndex, formatter.inkNote); + } + + if (tabIndex >= 0 && readOnly.get(tabIndex)) { + readOnlyCache.put(guid, true); + } + if (tabIndex >= 0 && inkNote.get(tabIndex)) { + inkNoteCache.put(guid, true); + } + } else { logger.log(logger.HIGH, "Note content is being pulled from the cache"); - String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(currentNoteGuid)); + String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid)); js = new QByteArray(cachedContent); - browser.getBrowser().setContent(js); - if (readOnlyCache.containsKey(currentNoteGuid)) - readOnly = true; - if (inkNoteCache.containsKey(currentNoteGuid)) - inkNote = true; + browser.setContent(js); + if (readOnlyCache.containsKey(guid) && tabIndex >= 0) { + readOnly.put(tabIndex, true); + } else { + readOnly.put(tabIndex, false); + } + if (inkNoteCache.containsKey(guid) && tabIndex >= 0) { + inkNote.put(tabIndex, true); + } else { + inkNote.put(tabIndex, false); + } } - if (conn.getNoteTable().isThumbnailNeeded(currentNoteGuid)) { - thumbnailHTMLReady(currentNoteGuid, js, Global.calculateThumbnailZoom(js.toString())); + if (conn.getNoteTable().isThumbnailNeeded(guid)) { + thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString())); } - - if (readOnly || inkNote) + if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) || + (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != ""))) 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())) { + if (tabIndex >= 0) { + browser.setReadOnly(readOnly.get(tabIndex)); + deleteButton.setEnabled(!readOnly.get(tabIndex)); + tagButton.setEnabled(!readOnly.get(tabIndex)); + menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex)); + menuBar.noteTags.setEnabled(!readOnly.get(tabIndex)); + } + browser.setNote(note); + + if (note != null && note.getNotebookGuid() != null && + conn.getNotebookTable().isLinked(note.getNotebookGuid())) { deleteButton.setEnabled(false); menuBar.notebookDeleteAction.setEnabled(false); } else { @@ -4190,44 +5279,72 @@ public class NeverNote extends QMainWindow{ nbooks.add(listManager.getNotebookIndex().get(i)); } - browser.setTitle(currentNote.getTitle()); - browser.setTag(getTagNamesForNote(currentNote)); - browser.setAuthor(currentNote.getAttributes().getAuthor()); - - browser.setAltered(currentNote.getUpdated()); - browser.setCreation(currentNote.getCreated()); - if (currentNote.getAttributes().getSubjectDate() > 0) - browser.setSubjectDate(currentNote.getAttributes().getSubjectDate()); + browser.setTitle(note.getTitle()); + browser.setTag(getTagNamesForNote(note)); + browser.setAuthor(note.getAttributes().getAuthor()); + + browser.setAltered(note.getUpdated()); + browser.setCreation(note.getCreated()); + if (note.getAttributes().getSubjectDate() > 0) + browser.setSubjectDate(note.getAttributes().getSubjectDate()); else - browser.setSubjectDate(currentNote.getCreated()); - browser.setUrl(currentNote.getAttributes().getSourceURL()); + browser.setSubjectDate(note.getCreated()); + browser.setUrl(note.getAttributes().getSourceURL()); FilterEditorTags tagFilter = new FilterEditorTags(conn, logger); - List tagList = tagFilter.getValidTags(currentNote); + List tagList = tagFilter.getValidTags(note); browser.setAllTags(tagList); - browser.setCurrentTags(currentNote.getTagNames()); - noteDirty = false; - scrollToGuid(currentNoteGuid); + browser.setCurrentTags(note.getTagNames()); + // ICHANGED + for (TabBrowse tab: tabWindows.values()) { + if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) { + int index = tabBrowser.indexOf(tab); + noteDirty.put(index, false); + break; + } + } + + scrollToGuid(guid); browser.loadingData(false); if (thumbnailViewer.isActiveWindow()) thumbnailView(); FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger); - browser.setNotebookList(notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex())); + browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex())); waitCursor(false); logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote"); } + + // ICHANGED + @SuppressWarnings("unused") + private void toggleNoteAttributes() { + menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked()); + toggleNoteInformation(); + } + // Save a generated thumbnail private void toggleNoteInformation() { logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation"); - browserWindow.toggleInformation(); + + // ICHANGED + boolean isChecked = menuBar.noteAttributes.isChecked(); + + for(int i = 0; i < tabBrowser.count(); i++){ + BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow(); + boolean isExtended = browser.isExtended(); + if((isChecked && !isExtended) || (!isChecked && isExtended)){ + browser.toggleInformation(); + } + } + menuBar.noteAttributes.setChecked(browserWindow.isExtended()); Global.saveWindowVisible("noteInformation", browserWindow.isExtended()); logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation"); } + // Listener triggered when a print button is pressed @SuppressWarnings("unused") private void printNote() { @@ -4310,11 +5427,23 @@ public class NeverNote extends QMainWindow{ return; if (currentNoteGuid.equals("")) return; - + String title = null; + if (selectedNoteGUIDs.size() == 1) + title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle(); + // If we are deleting non-trash notes if (currentNote.isActive()) { if (Global.verifyDelete()) { - if (QMessageBox.question(this, tr("Confirmation"), tr("Delete selected note(s)?"), + String msg; + if (selectedNoteGUIDs.size() > 1) { + msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?"); + } else { + if (title != null) + msg = new String(tr("Delete note \"") +title +"\"?"); + else + msg = new String(tr("Delete note selected note?")); + } + if (QMessageBox.question(this, tr("Confirmation"), msg, QMessageBox.StandardButton.Yes, QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) { return; @@ -4322,15 +5451,25 @@ public class NeverNote extends QMainWindow{ } if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) selectedNoteGUIDs.add(currentNoteGuid); + closeTabs(selectedNoteGUIDs); for (int i=0; i 1) { + msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?"); + } else { + if (title != null) + msg = new String(tr("Permanently delete note \"") +title +"\"?"); + else + msg = new String(tr("Permanently delete note selected note?")); + } + if (QMessageBox.question(this, "Confirmation", msg, QMessageBox.StandardButton.Yes, - QMessageBox.StandardButton.No)==StandardButton.No.value()) { + QMessageBox.StandardButton.No)==StandardButton.No.value()) { return; } } @@ -4348,18 +5487,79 @@ public class NeverNote extends QMainWindow{ } } } + closeTabs(selectedNoteGUIDs); listManager.expungeNote(selectedNoteGUIDs.get(i)); + + // ICHANGED + conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i)); + conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i)); + conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i)); + } } currentNoteGuid = ""; + closeExternalWindows(selectedNoteGUIDs); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + menuBar.noteAddNewTab.setEnabled(false); + } + listManager.loadNotesIndex(); noteIndexUpdated(false); refreshEvernoteNote(true); scrollToGuid(currentNoteGuid); logger.log(logger.HIGH, "Leaving NeverNote.deleteNote"); } + + // 対象ノートをタブで開いていたら閉じる + private void closeTabs(List noteGUIDs) { + Collection tabBrowsers = tabWindows.values(); + Iterator tabIterator = tabBrowsers.iterator(); + Collection tabIndexes = tabWindows.keySet(); + Iterator indexIterator = tabIndexes.iterator(); + List closeIndexes = new ArrayList(); //イテレータ操作中に中身をいじっちゃダメなので + + while (tabIterator.hasNext()) { + TabBrowse tab = tabIterator.next(); + int index = indexIterator.next(); + String guid = tab.getBrowserWindow().getNote().getGuid(); + + for(int i = 0; i < noteGUIDs.size(); i++){ + if(guid.equals(noteGUIDs.get(i))){ + closeIndexes.add(index); + } + } + } + + for(int i = closeIndexes.size() - 1; i >= 0; i--){ + tabWindowClosing(closeIndexes.get(i)); + } + } + + // 対象ノートを外部ウィンドウで開いていたら閉じる + private void closeExternalWindows(List noteGUIDs) { + Collection windows = externalWindows.values(); + Iterator windowIterator = windows.iterator(); + Collection guids = externalWindows.keySet(); + Iterator guidIterator = guids.iterator(); + List closeWindows = new ArrayList(); // イテレータ操作中に中身をいじっちゃダメなので + + while (windowIterator.hasNext()) { + ExternalBrowse browser = windowIterator.next(); + String guid = guidIterator.next(); + + for (int i = 0; i < noteGUIDs.size(); i++) { + if (guid.equals(noteGUIDs.get(i))) { + closeWindows.add(browser); + } + } + } + + for (int i = closeWindows.size() - 1; i >= 0; i--) { + closeWindows.get(i).close(); + } + } + // Add a new note - @SuppressWarnings("unused") private void addNote() { logger.log(logger.HIGH, "Inside NeverNote.addNote"); // browserWindow.setEnabled(true); @@ -4390,7 +5590,7 @@ public class NeverNote extends QMainWindow{ String notebook = null; listManager.getNotebookIndex().get(0).getGuid(); List selectedNotebook = notebookTree.selectedItems(); - if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks")) { + if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) { QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0); notebook = currentSelectedNotebook.text(2); } else { @@ -4429,7 +5629,7 @@ public class NeverNote extends QMainWindow{ newNote.setUpdateSequenceNum(0); newNote.setGuid(randint); newNote.setNotebookGuid(notebook); - newNote.setTitle(""); + newNote.setTitle("Untitled Note"); newNote.setContent(noteString.toString()); newNote.setDeleted(0); newNote.setCreated(System.currentTimeMillis()); @@ -4455,12 +5655,27 @@ public class NeverNote extends QMainWindow{ } conn.getNoteTable().addNote(newNote, true); - listManager.getUnsynchronizedNotes().add(newNote.getGuid()); - listManager.addNote(newNote); + NoteMetadata metadata = new NoteMetadata(); + metadata.setGuid(newNote.getGuid()); + metadata.setDirty(true); + listManager.addNote(newNote, metadata); // noteTableView.insertRow(newNote, true, -1); + // ICHANGED + String prevCurrentNoteGuid = new String(currentNoteGuid); + currentNote = newNote; currentNoteGuid = currentNote.getGuid(); + // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す + // noteTableView.clearSelection(); + + // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加 + if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) { + if (currentNoteGuid != null && !currentNoteGuid.equals("")) { + conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid); + } + } + refreshEvernoteNote(true); listManager.countNotebookResults(listManager.getNoteIndex()); browserWindow.titleLabel.setFocus(); @@ -4470,6 +5685,7 @@ public class NeverNote extends QMainWindow{ // If the window is hidden, then we want to popup this in an external window & if (!isVisible()) listDoubleClick(); + waitCursor(false); logger.log(logger.HIGH, "Leaving NeverNote.addNote"); } // Restore a note from the trash; @@ -4500,14 +5716,22 @@ public class NeverNote extends QMainWindow{ @SuppressWarnings("unused") private void updateNoteTitle(String guid, String title) { listManager.setNoteSynchronized(guid, false); + + // We do this manually because if we've edited the note in an + // external window we run into the possibility of signal recursion + // looping. + if (guid.equals(currentNoteGuid)) { + browserWindow.titleLabel.blockSignals(true); + browserWindow.titleLabel.setText(title); + browserWindow.titleLabel.blockSignals(false); + } } // Signal received that note content has changed. Normally we just need the guid to remove // it from the cache. @SuppressWarnings("unused") private void invalidateNoteCache(String guid, String content) { - String v = noteCache.remove(guid); -// if (guid.equals(currentNoteGuid) && !noteDirty) - refreshEvernoteNote(true); + noteCache.remove(guid); + refreshEvernoteNote(true); } // Signal received that a note guid has changed @SuppressWarnings("unused") @@ -4536,33 +5760,50 @@ public class NeverNote extends QMainWindow{ b.getBrowserWindow().getNote().setGuid(newGuid); externalWindows.put(newGuid, b); } + + // ICHANGED + for(int i = 0; i < tabBrowser.count(); i++){ + TabBrowse b = (TabBrowse)tabBrowser.widget(i); + if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) { + b.getBrowserWindow().getNote().setGuid(newGuid); + } + } for (int i=0; i resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true); - oldNote.setContent(conn.getNoteTable().getNoteContentBinary(guid)); + oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid)); oldNote.setResources(resList); duplicateNote(oldNote); } @@ -4662,16 +5903,28 @@ public class NeverNote extends QMainWindow{ } newNote.setResources(resList); + // ICHANGED + // 操作履歴と除外ノートとスター付きノートも複製する + if(Global.getDuplicateRensoNote()) { + conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid()); + conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid()); + conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid()); + } + // Add note to the database - listManager.addNote(newNote); conn.getNoteTable().addNote(newNote, true); - listManager.getUnsynchronizedNotes().add(newNote.getGuid()); - noteTableView.insertRow(newNote, true, -1); + NoteMetadata metaData = new NoteMetadata(); + NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid()); + metaData.copy(oldMeta); + metaData.setGuid(newNote.getGuid()); + listManager.addNote(newNote, metaData); + noteTableView.insertRow(newNote, metaData, true, -1); currentNoteGuid = newNote.getGuid(); currentNote = newNote; refreshEvernoteNote(true); listManager.countNotebookResults(listManager.getNoteIndex()); waitCursor(false); + } // View all notes @SuppressWarnings("unused") @@ -4686,6 +5939,12 @@ public class NeverNote extends QMainWindow{ notebookTree.selectGuid(""); } notebookTreeSelection(); + refreshEvernoteNote(true); + + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + if (!rensoNoteListDock.isEnabled()) { + rensoNoteListDock.setEnabled(true); + } } // Merge notes @SuppressWarnings("unused") @@ -4710,7 +5969,75 @@ public class NeverNote extends QMainWindow{ logger.log(logger.EXTREME, "Children count: "+sources.size()); mergeNoteContents(masterGuid, sources); currentNoteGuid = masterGuid; + + // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ + if(Global.getMergeRensoNote()) { + for (int i = 0; i < sources.size(); i++) { + String childGuid = sources.get(i); + if(masterGuid != null && childGuid != null) { + if(!masterGuid.equals(childGuid)) { + conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid); + conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid); + conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid); + } + } + } + } + + // ICHANGED ↓↓↓ここから↓↓↓ + // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる + Collection windows = externalWindows.values(); + Iterator windowIterator = windows.iterator(); + Collection guids = externalWindows.keySet(); + Iterator guidIterator = guids.iterator(); + List closeWindows = new ArrayList(); // イテレータ操作中に中身をいじっちゃダメなので + + while (windowIterator.hasNext()) { + ExternalBrowse browser = windowIterator.next(); + String guid = guidIterator.next(); + + for (int i = 0; i < sources.size(); i++) { + if (guid.equals(sources.get(i))) { + closeWindows.add(browser); + } + } + } + + for (int i = closeWindows.size() - 1; i >= 0; i--) { + closeWindows.get(i).close(); + } + // ICHANGED ↑↑↑ここまで↑↑↑ + + // ICHANGED ↓↓↓ここから↓↓↓ + // マージしたノート(child)をタブで開いていたら、閉じる + Collection tabBrowsers = tabWindows.values(); + Iterator tabIterator = tabBrowsers.iterator(); + Collection tabIndexes = tabWindows.keySet(); + Iterator indexIterator = tabIndexes.iterator(); + List closeIndexes = new ArrayList(); //イテレータ操作中に中身をいじっちゃダメなので + + while (tabIterator.hasNext()) { + TabBrowse tab = tabIterator.next(); + int tabIndex = indexIterator.next(); + String guid = tab.getBrowserWindow().getNote().getGuid(); + + for(int i = 0; i < sources.size(); i++){ + if(guid.equals(sources.get(i))){ + closeIndexes.add(tabIndex); + } + } + } + + for(int i = closeIndexes.size() - 1; i >= 0; i--){ + tabWindowClosing(closeIndexes.get(i)); + } + // ICHANGED ↑↑↑ここまで↑↑↑ + noteIndexUpdated(false); + // IFIXED + // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除 + noteCache.remove(masterGuid); + refreshEvernoteNote(true); waitCursor(false); } @@ -4769,7 +6096,7 @@ public class NeverNote extends QMainWindow{ // A resource within a note has had a guid change @SuppressWarnings("unused") private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) { - if (!oldGuid.equals(newGuid)) + if (oldGuid != null && !oldGuid.equals(newGuid)) Global.resourceMap.put(oldGuid, newGuid); } // View a thumbnail of the note @@ -4798,11 +6125,11 @@ public class NeverNote extends QMainWindow{ i=listManager.getMasterNoteIndex().size(); } } - msg = "An error has happened while saving the note \"" +title+ - "\".\n\nThis is probably due to a document that is too complex for Nevernote to process. "+ + msg = tr("An error has happened while saving the note \"") +title+ + tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+ "As a result, changes to the note may not be saved properly in the database."+ "\n\nA cached copy is being preserved so you can recover any data, but data may" + - "\nbe lost. Please review the note to recover any critical data before restarting."; + "\nbe lost. Please review the note to recover any critical data before restarting."); QMessageBox.information(this, tr("Error Saving Note"), tr(msg)); } @@ -4867,10 +6194,10 @@ public class NeverNote extends QMainWindow{ versions = null; try { if (Global.isPremium()) - versions = syncRunner.noteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid); + versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid); else versions = new ArrayList(); - currentOnlineNote = syncRunner.noteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false); + currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false); } catch (EDAMUserException e) { setMessage("EDAMUserException: " +e.getMessage()); return; @@ -4879,7 +6206,7 @@ public class NeverNote extends QMainWindow{ return; } catch (EDAMNotFoundException e) { setMessage(tr("Note not found on server.")); - QMessageBox.information(this, "Error", "This note could not be found on Evernote's servers."); + QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers.")); return; } catch (TException e) { setMessage("EDAMTransactionException: " +e.getMessage()); @@ -4888,7 +6215,9 @@ public class NeverNote extends QMainWindow{ // If we've gotten this far, we have a good note. if (historyWindow == null) { - historyWindow = new OnlineNoteHistory(logger, conn); + // ICHANGED + historyWindow = new OnlineNoteHistory(logger, conn, cbObserver); + historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)"); historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()"); historyWindow.restore.clicked.connect(this, "restoreHistoryNote()"); @@ -4925,9 +6254,9 @@ public class NeverNote extends QMainWindow{ try { if (index > -1) { usn = versions.get(index).getUpdateSequenceNum(); - historyNote = syncRunner.noteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true); + historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true); } else - historyNote = syncRunner.noteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true); + historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true); } catch (EDAMUserException e) { setMessage("EDAMUserException: " +e.getMessage()); waitCursor(false); @@ -4975,7 +6304,9 @@ public class NeverNote extends QMainWindow{ n.getResources().get(i).setActive(true); conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true); } - listManager.addNote(n); + NoteMetadata metadata = new NoteMetadata(); + metadata.setGuid(n.getGuid()); + listManager.addNote(n, metadata); conn.getNoteTable().addNote(n, true); refreshEvernoteNote(true); setMessage(tr("Note has been restored.")); @@ -4988,9 +6319,9 @@ public class NeverNote extends QMainWindow{ 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); + notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken); + tags = syncRunner.localNoteStore.listTags(syncRunner.authToken); + linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken); } catch (EDAMUserException e) { setMessage("EDAMUserException: " +e.getMessage()); return; @@ -5120,9 +6451,14 @@ public class NeverNote extends QMainWindow{ //********************************************************** //********************************************************** // An error has happended fetching a resource. let the user know - private void resourceErrorMessage() { - if (inkNote) + // ICHANGED + private void resourceErrorMessage(int tabIndex) { + if (tabIndex < 0) { return; + } + if (inkNote.get(tabIndex)) + return; + waitCursor(false); QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+ "\n\nSome attachments or images for this note appear to be missing from my database.\n"+ "In a perfect world this wouldn't happen, but it has.\n" + @@ -5133,8 +6469,9 @@ public class NeverNote extends QMainWindow{ "Don't get angry. I'm doing it to prevent you from messing up\n"+ "this note on the Evernote servers. Sorry."+ "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky.")); - inkNote = true; + inkNote.put(tabIndex, true); browserWindow.setReadOnly(true); + waitCursor(true); } @@ -5186,14 +6523,40 @@ public class NeverNote extends QMainWindow{ if (currentNote == null) { currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true); } - listManager.setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs()); - noteIndexUpdated(false); + listManager.refreshNoteMetadata(); + noteIndexUpdated(true); noteTableView.selectionModel().blockSignals(true); scrollToGuid(currentNoteGuid); noteTableView.selectionModel().blockSignals(false); refreshEvernoteNote(false); scrollToGuid(currentNoteGuid); waitCursor(false); + + // Check to see if there were any shared notebook errors + if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) { + String guid = syncRunner.errorSharedNotebooks.get(0); + String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid); + String localName = listManager.getNotebookNameByGuid(notebookGuid); + SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName); + syncDialog.exec(); + if (syncDialog.okPressed()) { + if (syncDialog.doNothing.isChecked()) { + syncRunner.errorSharedNotebooksIgnored.put(guid, guid); + evernoteSync(); + } + if (syncDialog.deleteNotebook.isChecked()) { + conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false); + conn.getNotebookTable().expungeNotebook(notebookGuid, false); + conn.getLinkedNotebookTable().expungeNotebook(guid, false); + conn.getLinkedNotebookTable().expungeNotebook(guid, false); + evernoteSync(); + } + refreshLists(); + return; + } + } + + // Finalize the synchronization if (!syncRunner.error) setMessage(tr("Synchronization Complete")); else @@ -5212,7 +6575,23 @@ public class NeverNote extends QMainWindow{ public void refreshLists() { logger.log(logger.EXTREME, "Entering NeverNote.refreshLists"); updateQuotaBar(); - listManager.refreshLists(currentNote, noteDirty, browserWindow.getContent()); + // ICHANGED + // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。 + Collection tabIndex = noteDirty.keySet(); + Iterator indexIterator = tabIndex.iterator(); + HashMap saveNotes = new HashMap(); + HashMap saveContents = new HashMap(); + for (boolean isNoteDirty: noteDirty.values()) { + int index = indexIterator.next(); + if (isNoteDirty) { + saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote()); + saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent()); + } + } + + listManager.saveUpdatedNotes(saveNotes, saveContents); + listManager.refreshLists(); + tagIndexUpdated(true); notebookIndexUpdated(); savedSearchIndexUpdated(); @@ -5270,7 +6649,7 @@ public class NeverNote extends QMainWindow{ thumbnailRunner.interrupt = true; indexRunner.addWork("SCAN"); } - logger.log(logger.EXTREME, "Leaving neverNote index timer"); + logger.log(logger.EXTREME, "Leaving NeighborNote index timer"); } @SuppressWarnings("unused") @@ -5303,8 +6682,8 @@ public class NeverNote extends QMainWindow{ if (!alive) { tagDeadCount++; if (tagDeadCount > MAX && !disableTagThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), tr("It appears as the tag counter thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableTagThreadCheck = true; } } else @@ -5314,8 +6693,8 @@ public class NeverNote extends QMainWindow{ if (!alive) { notebookThreadDeadCount++; if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), tr("It appears as the notebook counter thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableNotebookThreadCheck=true; } } else @@ -5325,8 +6704,8 @@ public class NeverNote extends QMainWindow{ if (!alive) { trashDeadCount++; if (trashDeadCount > MAX && !disableTrashThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), ("It appears as the trash counter thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableTrashThreadCheck = true; } } else @@ -5336,8 +6715,8 @@ public class NeverNote extends QMainWindow{ if (!alive) { saveThreadDeadCount++; if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), tr("It appears as the note saver thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableSaveThreadCheck = true; } } else @@ -5346,8 +6725,8 @@ public class NeverNote extends QMainWindow{ if (!syncThread.isAlive()) { syncThreadDeadCount++; if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), tr("It appears as the synchronization thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableSyncThreadCheck = true; } } else @@ -5356,8 +6735,8 @@ public class NeverNote extends QMainWindow{ if (!indexThread.isAlive()) { indexThreadDeadCount++; if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) { - QMessageBox.information(this, tr("A thread his died."), tr("It appears as the index thread has died. I recommend "+ - "checking stopping NeverNote, saving the logs for later viewing, and restarting. Sorry.")); + QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+ + "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry.")); disableIndexThreadCheck = true; } } else @@ -5381,7 +6760,7 @@ public class NeverNote extends QMainWindow{ fd.setFileMode(FileMode.AnyFile); fd.setConfirmOverwrite(true); fd.setWindowTitle(tr("Backup Database")); - fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); + fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptSave); if (saveLastPath == null || saveLastPath.equals("")) fd.setDirectory(System.getProperty("user.home")); @@ -5427,7 +6806,7 @@ public class NeverNote extends QMainWindow{ fd.setFileMode(FileMode.ExistingFile); fd.setConfirmOverwrite(true); fd.setWindowTitle(tr("Restore Database")); - fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); + fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptOpen); if (saveLastPath == null || saveLastPath.equals("")) fd.setDirectory(System.getProperty("user.home")); @@ -5465,7 +6844,7 @@ public class NeverNote extends QMainWindow{ fd.setFileMode(FileMode.AnyFile); fd.setConfirmOverwrite(true); fd.setWindowTitle(tr("Backup Database")); - fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); + fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptSave); fd.setDirectory(System.getProperty("user.home")); if (fd.exec() == 0 || fd.selectedFiles().size() == 0) { @@ -5498,7 +6877,7 @@ public class NeverNote extends QMainWindow{ fd.setFileMode(FileMode.ExistingFile); fd.setConfirmOverwrite(true); fd.setWindowTitle(tr("Import Notes")); - fd.setFilter(tr("NeverNote Export (*.nnex);;All Files (*.*)")); + fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)")); fd.setAcceptMode(AcceptMode.AcceptOpen); if (saveLastPath == null || saveLastPath.equals("")) fd.setDirectory(System.getProperty("user.home")); @@ -5510,30 +6889,56 @@ public class NeverNote extends QMainWindow{ waitCursor(true); - setMessage("Importing Notes"); + setMessage(tr("Importing Notes")); saveNote(); if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) selectedNoteGUIDs.add(currentNoteGuid); - ImportData noteReader = new ImportData(conn, false); String fileName = fd.selectedFiles().get(0); // saveLastPath.substring(0,fileName.lastIndexOf("/")); - if (!fileName.endsWith(".nnex")) - fileName = fileName +".nnex"; - if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0) - noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0)); - else - noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid()); + if (fileName.endsWith(".nnex")) { + ImportData noteReader = new ImportData(conn, false); + if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0) + noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0)); + else + noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid()); - noteReader.importData(fileName); + noteReader.importData(fileName); - if (noteReader.lastError != 0) { - setMessage(noteReader.getErrorMessage()); - logger.log(logger.LOW, "Import problem: " +noteReader.lastError); - waitCursor(false); - return; + if (noteReader.lastError != 0) { + setMessage(noteReader.getErrorMessage()); + logger.log(logger.LOW, "Import problem: " +noteReader.lastError); + waitCursor(false); + return; + } + } else { + if (fileName.endsWith(".enex")) { + ImportEnex noteReader = new ImportEnex(conn, false); + if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0) + noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0)); + else + noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid()); + + waitCursor(false); + if (QMessageBox.question(this, tr("Confirmation"), + tr("Create new tags from import?"), + QMessageBox.StandardButton.Yes, + QMessageBox.StandardButton.No) == StandardButton.Yes.value()) { + noteReader.createNewTags = true; + } else + noteReader.createNewTags = false; + waitCursor(true); + noteReader.importData(fileName); + + if (noteReader.lastError != 0) { + setMessage(noteReader.getErrorMessage()); + logger.log(logger.LOW, "Import problem: " +noteReader.lastError); + waitCursor(false); + return; + } + } } listManager.loadNoteTitleColors(); @@ -5542,7 +6947,7 @@ public class NeverNote extends QMainWindow{ setMessage(tr("Notes have been imported.")); waitCursor(false); - setMessage("Import completed."); + setMessage(tr("Import completed.")); waitCursor(false); @@ -5558,6 +6963,83 @@ public class NeverNote extends QMainWindow{ duplicateNote(currentNoteGuid); } + //************************************************** + //* Action from when a user clicks Copy As URL + //************************************************** + @SuppressWarnings("unused") + private void copyAsUrlClicked() { + QClipboard clipboard = QApplication.clipboard(); + QMimeData mime = new QMimeData(); + String url; + mime.setText(currentNoteGuid); + List urls = new ArrayList(); + + // Start building the URL + User user = Global.getUserInformation(); + + // Check that we have everything we need + if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) { + SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this); + warning.exec(); + if (!warning.neverSynchronize()) + return; + else { + Global.setBypassSynchronizationWarning(true); + user.setShardId("s0"); + user.setId(0); + } + } + + + // Start building a list of URLs based upon the selected notes + noteTableView.showColumn(Global.noteTableGuidPosition); + + List selections = noteTableView.selectionModel().selectedRows(); + if (!Global.isColumnVisible("guid")) + noteTableView.hideColumn(Global.noteTableGuidPosition); + + // Check that the note is either synchronized, or in a local notebook + for (int i=0; i ix = noteTableView.proxyModel.itemData(index); + String selectedGuid = (String)ix.values().toArray()[0]; + + Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false); + if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) { + QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " + + "new notes to a local notebook.")); + return; + } + } + + // Start building the URLs + for (int i=0; i ix = noteTableView.proxyModel.itemData(index); + String selectedGuid = (String)ix.values().toArray()[0]; + mime.setText(selectedGuid); + + String lid; + String gid; + Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false); + if (selectedNote.getUpdateSequenceNum() > 0) { + gid = selectedGuid; + lid = selectedGuid; + } else { + gid = "00000000-0000-0000-0000-000000000000"; + lid = selectedGuid; + } + url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/" + +gid+"/"+lid +"/"); + urls.add(new QUrl(url)); + } + mime.setUrls(urls); + clipboard.setMimeData(mime); + } //************************************************** @@ -5580,12 +7062,26 @@ public class NeverNote extends QMainWindow{ // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/')); for (int i=0; i monitorDelete = importKeepWatcher.directories(); + for (int i=0; i"); + logger.log(logger.EXTREME, "List of directories being watched (delete)..."); + monitorDelete = importDeleteWatcher.directories(); + for (int i=0; i"); + importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)"); importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)"); @@ -5602,6 +7098,8 @@ public class NeverNote extends QMainWindow{ } } } + + // Menu folderImport action triggered public void folderImport() { List recs = conn.getWatchFolderTable().getAll(); WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex()); @@ -5635,8 +7133,9 @@ public class NeverNote extends QMainWindow{ setupFolderImports(); } + public void folderImportKeep(String dirName) throws NoSuchAlgorithmException { - + logger.log(logger.LOW, "Inside folderImportKeep"); String whichOS = System.getProperty("os.name"); if (whichOS.contains("Windows")) dirName = dirName.replace('/','\\'); @@ -5648,38 +7147,44 @@ public class NeverNote extends QMainWindow{ String notebook = conn.getWatchFolderTable().getNotebook(dirName); for (int i=0; i blockingWindow.unblockTime && blockingWindow.unblockTime != -1) { + QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula.")); + blockingWindow.unblockTime = -1; + blockingWindow.awaitingHttpResponse = false; + } + blockingWindow = null; + blockSignals(false); + } + + // ICHANGED + // タブが変更された + private void tabWindowChanged(int index) { + if (index < 0 || index >= tabBrowser.count()) { + return; + } + + saveNote(); + + TabBrowse tab = (TabBrowse) tabBrowser.widget(index); + if (tab.getBrowserWindow().getNote() != null) { + currentNoteGuid = tab.getBrowserWindow().getNote().getGuid(); + currentNote = tab.getBrowserWindow().getNote(); + } else { + currentNoteGuid = ""; + currentNote = null; + } + + // 選択ノートを更新 + selectedNoteGUIDs.clear(); + if (currentNoteGuid != null && !currentNoteGuid.equals("")) { + selectedNoteGUIDs.add(currentNoteGuid); + } + + // browserWindowを更新 + browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()"); + browserWindow.focusLost.disconnect(this, "saveNote()"); + browserWindow = tab.getBrowserWindow(); + browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()"); + browserWindow.focusLost.connect(this, "saveNote()"); + // メニューバーのボタンを新しいbrowserWindowに合わせる + menuBar.refreshTargetWindow(); + + // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる + boolean nextIsActive; + if (tab.getBrowserWindow().getNote() != null) { + nextIsActive = tab.getBrowserWindow().getNote().isActive(); + } else { + nextIsActive = true; + } + if (Global.showDeleted && nextIsActive) { + switchNoteTable(false); + } else if (!Global.showDeleted && !nextIsActive) { + switchNoteTable(true); + } + + // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断 + noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()"); + scrollToGuid(currentNoteGuid); + // 再接続 + noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()"); + + menuBar.noteDuplicateAction.setEnabled(true); + menuBar.noteOnlineHistoryAction.setEnabled(true); + menuBar.noteMergeAction.setEnabled(true); + + if (Global.showDeleted) { + menuBar.noteDuplicateAction.setEnabled(false); + } + if (!Global.isConnected) { + menuBar.noteOnlineHistoryAction.setEnabled(false); + } + menuBar.noteMergeAction.setEnabled(false); + try { + int row = noteTableView.selectionModel().selectedRows().get(0).row(); + if (row == 0) + upButton.setEnabled(false); + else + upButton.setEnabled(true); + if (row < listManager.getNoteTableModel().rowCount() - 1) + downButton.setEnabled(true); + else + downButton.setEnabled(false); + } catch (Exception e) { + upButton.setEnabled(false); + downButton.setEnabled(false); + } + + int currentIndex = tabBrowser.currentIndex(); + ArrayList histGuids = historyGuids.get(currentIndex); + int histPosition = historyPosition.get(currentIndex); + + // prev, nextボタンの有効・無効化 + nextButton.setEnabled(true); + prevButton.setEnabled(true); + + if (histPosition <= 1){ + prevButton.setEnabled(false); + } + if (histPosition == histGuids.size()){ + nextButton.setEnabled(false); + } + + refreshEvernoteNote(true); + + // 連想ノートリストを更新 + rensoNoteList.refreshRensoNoteList(currentNoteGuid); + } + + // ICHANGD + // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える + private void switchNoteTable(boolean toDeleted) { + clearNotebookFilter(); + clearTagFilter(); + clearAttributeFilter(); + clearSavedSearchFilter(); + + listManager.getSelectedNotebooks().clear(); + listManager.getSelectedTags().clear(); + listManager.setSelectedSavedSearch(""); + + // toggle the add buttons + newButton.setEnabled(!newButton.isEnabled()); + menuBar.noteAdd.setEnabled(newButton.isEnabled()); + menuBar.noteAddNewTab.setEnabled(newButton.isEnabled()); + if (currentNoteGuid == null || currentNoteGuid.equals("")) { + menuBar.noteAddNewTab.setEnabled(false); + } + menuBar.noteAdd.setVisible(true); + + if (!toDeleted) { // 生存ノートテーブルへ + trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()"); + trashTree.clearSelection(); + trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()"); + Global.showDeleted = false; + menuBar.noteRestoreAction.setEnabled(false); + menuBar.noteRestoreAction.setVisible(false); + // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。 + rensoNoteListDock.setEnabled(true); + } else { // ゴミ箱へ + trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()"); + trashTree.setCurrentItem(trashTree.getTrashItem()); + trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()"); + Global.showDeleted = true; + menuBar.noteRestoreAction.setEnabled(true); + menuBar.noteRestoreAction.setVisible(true); + // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。 + rensoNoteListDock.setEnabled(false); + } + + listManager.loadNotesIndex(); + // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断 + noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()"); + noteIndexUpdated(false); + // 再接続 + noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()"); + + browserWindow.setReadOnly(!newButton.isEnabled()); + } + + // ICHANGED + // ユーザが連想ノートリストのアイテムを選択した時の処理 + @SuppressWarnings("unused") + private void rensoNoteItemPressed(QListWidgetItem current) { + logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った"); + + rensoNotePressedItemGuid = rensoNoteList.getNoteGuid(current); + + // 右クリックだったら終了 + if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) { + return; + } + + saveNote(); + + String prevCurrentNoteGuid = new String(currentNoteGuid); + + for (int i = 0; i < noteTableView.model().rowCount(); i++) { + QModelIndex modelIndex = noteTableView.model().index(i, + Global.noteTableGuidPosition); + if (modelIndex != null) { + SortedMap ix = noteTableView.model().itemData( + modelIndex); + String tableGuid = (String) ix.values().toArray()[0]; + if (tableGuid.equals(rensoNotePressedItemGuid)) { + noteTableView.selectRow(i); + break; + } + } + } + + // 連想ノートリストアイテムクリック操作を記録 + conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid); + + logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た"); + } + + // ICHANGED + // 関連ノートリストからノートを除外する + @SuppressWarnings("unused") + private void excludeNote() { + if (rensoNotePressedItemGuid != null) { + saveNote(); + excludeNote(rensoNotePressedItemGuid); + } + } + + // ICHANGED + // 関連ノートリストからノートを除外する + private void excludeNote(String guid) { + if (Global.verifyExclude()) { + String msg; + Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false); + String title = note.getTitle(); + if (title != null) { + msg = new String(tr("Exclude note \"") +title +"\"?"); + } else { + msg = new String(tr("Exclude note selected note?")); + } + + if (QMessageBox.question(this, tr("Confirmation"), msg, + QMessageBox.StandardButton.Yes, + QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) { + return; + } + } + + // Historyデータベースから除外するノートのデータを削除 + conn.getHistoryTable().expungeHistory(guid, currentNoteGuid); + + // 除外ノートテーブルに追加 + conn.getExcludedTable().addExclusion(guid, currentNoteGuid); + + rensoNoteList.refreshRensoNoteList(currentNoteGuid); + } + + // ICHANGED + // 関連ノートリストのノートにスターを付ける + @SuppressWarnings("unused") + private void starNote() { + if (rensoNotePressedItemGuid != null) { + saveNote(); + starNote(rensoNotePressedItemGuid); + } + } + + // ICHANGED + // 関連ノートリストのノートにスターを付ける + private void starNote(String guid) { + // スター付きノートテーブルに追加 + conn.getStaredTable().addStaredItem(currentNoteGuid, guid); + + rensoNoteList.refreshRensoNoteList(currentNoteGuid); + } + + // ICHANGED + // 関連ノートリストのノートからスターを外す + @SuppressWarnings("unused") + private void unstarNote() { + if (rensoNotePressedItemGuid != null) { + saveNote(); + unstarNote(rensoNotePressedItemGuid); + } + } + + // ICHANGED + // 関連ノートリストのノートからスターを外す + private void unstarNote(String guid) { + // スター付きノートテーブルから削除 + conn.getStaredTable().removeStaredItem(currentNoteGuid, guid); + + rensoNoteList.refreshRensoNoteList(currentNoteGuid); + } + + // ICHANGED + // currentNoteGuidを返す + public String getCurrentNoteGuid() { + return currentNoteGuid; + } + + @SuppressWarnings("unused") + // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える + private void tabIndexChanged(int from, int to) { + // tabWindows + TabBrowse tab = tabWindows.get(from); + tabWindows.put(from, tabWindows.get(to)); + tabWindows.put(to, tab); + // noteDirty + boolean isNoteDirty = noteDirty.get(from); + noteDirty.put(from, noteDirty.get(to)); + noteDirty.put(to, isNoteDirty); + // inkNote + boolean isInkNote = inkNote.get(from); + inkNote.put(from, inkNote.get(to)); + inkNote.put(to, isInkNote); + // readOnly + boolean isReadOnly = readOnly.get(from); + readOnly.put(from, readOnly.get(to)); + readOnly.put(to, isReadOnly); + // historyGuids + ArrayList histGuids = historyGuids.get(from); + historyGuids.put(from, historyGuids.get(to)); + historyGuids.put(to, histGuids); + // historyPosition + int histPosition = historyPosition.get(from); + historyPosition.put(from, historyPosition.get(to)); + historyPosition.put(to, histPosition); + // fromHistory + boolean fromHist = fromHistory.get(from); + fromHistory.put(from, fromHistory.get(to)); + fromHistory.put(to, fromHist); + } }