2 * This file is part of NixNote/NeighborNote
3 * Copyright 2009 Randy Baumgarte
4 * Copyright 2013 Yuki Takahashi
6 * This file may be licensed under the terms of of the
7 * GNU General Public License Version 2 (the ``GPL'').
9 * Software distributed under the License is distributed
10 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
11 * express or implied. See the GPL for the specific language
12 * governing rights and limitations.
14 * You should have received a copy of the GPL along with this
15 * program. If not, go to http://www.gnu.org/licenses/gpl.html
16 * or write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package cx.fbn.nevernote;
21 import java.awt.Desktop;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.net.Authenticator;
27 import java.net.PasswordAuthentication;
28 import java.security.MessageDigest;
29 import java.security.NoSuchAlgorithmException;
30 import java.sql.Connection;
31 import java.sql.DriverManager;
32 import java.sql.SQLException;
33 import java.sql.Statement;
34 import java.text.SimpleDateFormat;
35 import java.util.ArrayList;
36 import java.util.Calendar;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.Date;
41 import java.util.GregorianCalendar;
42 import java.util.HashMap;
43 import java.util.Iterator;
44 import java.util.List;
46 import java.util.SortedMap;
47 import java.util.Vector;
49 import org.apache.log4j.Level;
50 import org.apache.log4j.Logger;
51 import org.h2.tools.ChangeFileEncryption;
53 import com.evernote.edam.error.EDAMErrorCode;
54 import com.evernote.edam.error.EDAMNotFoundException;
55 import com.evernote.edam.error.EDAMSystemException;
56 import com.evernote.edam.error.EDAMUserException;
57 import com.evernote.edam.notestore.NoteFilter;
58 import com.evernote.edam.notestore.NoteVersionId;
59 import com.evernote.edam.type.Data;
60 import com.evernote.edam.type.LinkedNotebook;
61 import com.evernote.edam.type.Note;
62 import com.evernote.edam.type.NoteAttributes;
63 import com.evernote.edam.type.Notebook;
64 import com.evernote.edam.type.Publishing;
65 import com.evernote.edam.type.QueryFormat;
66 import com.evernote.edam.type.Resource;
67 import com.evernote.edam.type.SavedSearch;
68 import com.evernote.edam.type.Tag;
69 import com.evernote.edam.type.User;
70 import com.evernote.thrift.TException;
71 import com.trolltech.qt.QThread;
72 import com.trolltech.qt.core.QByteArray;
73 import com.trolltech.qt.core.QDateTime;
74 import com.trolltech.qt.core.QDir;
75 import com.trolltech.qt.core.QEvent;
76 import com.trolltech.qt.core.QFile;
77 import com.trolltech.qt.core.QFileInfo;
78 import com.trolltech.qt.core.QFileSystemWatcher;
79 import com.trolltech.qt.core.QIODevice;
80 import com.trolltech.qt.core.QIODevice.OpenModeFlag;
81 import com.trolltech.qt.core.QLocale;
82 import com.trolltech.qt.core.QMimeData;
83 import com.trolltech.qt.core.QModelIndex;
84 import com.trolltech.qt.core.QSize;
85 import com.trolltech.qt.core.QTemporaryFile;
86 import com.trolltech.qt.core.QTextCodec;
87 import com.trolltech.qt.core.QTextStream;
88 import com.trolltech.qt.core.QThreadPool;
89 import com.trolltech.qt.core.QTimer;
90 import com.trolltech.qt.core.QTranslator;
91 import com.trolltech.qt.core.QUrl;
92 import com.trolltech.qt.core.Qt;
93 import com.trolltech.qt.core.Qt.BGMode;
94 import com.trolltech.qt.core.Qt.DockWidgetArea;
95 import com.trolltech.qt.core.Qt.ItemDataRole;
96 import com.trolltech.qt.core.Qt.KeyboardModifier;
97 import com.trolltech.qt.core.Qt.MouseButton;
98 import com.trolltech.qt.core.Qt.SortOrder;
99 import com.trolltech.qt.core.Qt.WidgetAttribute;
100 import com.trolltech.qt.gui.QAbstractItemView;
101 import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
102 import com.trolltech.qt.gui.QAction;
103 import com.trolltech.qt.gui.QApplication;
104 import com.trolltech.qt.gui.QClipboard;
105 import com.trolltech.qt.gui.QCloseEvent;
106 import com.trolltech.qt.gui.QColor;
107 import com.trolltech.qt.gui.QCursor;
108 import com.trolltech.qt.gui.QDesktopServices;
109 import com.trolltech.qt.gui.QDialog;
110 import com.trolltech.qt.gui.QFileDialog;
111 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
112 import com.trolltech.qt.gui.QFileDialog.FileMode;
113 import com.trolltech.qt.gui.QGridLayout;
114 import com.trolltech.qt.gui.QHBoxLayout;
115 import com.trolltech.qt.gui.QIcon;
116 import com.trolltech.qt.gui.QImage;
117 import com.trolltech.qt.gui.QKeySequence;
118 import com.trolltech.qt.gui.QListWidgetItem;
119 import com.trolltech.qt.gui.QMainWindow;
120 import com.trolltech.qt.gui.QMenu;
121 import com.trolltech.qt.gui.QMessageBox;
122 import com.trolltech.qt.gui.QMessageBox.StandardButton;
123 import com.trolltech.qt.gui.QPainter;
124 import com.trolltech.qt.gui.QPalette.ColorRole;
125 import com.trolltech.qt.gui.QPixmap;
126 import com.trolltech.qt.gui.QPrintDialog;
127 import com.trolltech.qt.gui.QPrinter;
128 import com.trolltech.qt.gui.QShortcut;
129 import com.trolltech.qt.gui.QSizePolicy;
130 import com.trolltech.qt.gui.QSpinBox;
131 import com.trolltech.qt.gui.QSplashScreen;
132 import com.trolltech.qt.gui.QSplitter;
133 import com.trolltech.qt.gui.QStatusBar;
134 import com.trolltech.qt.gui.QSystemTrayIcon;
135 import com.trolltech.qt.gui.QTableWidgetItem;
136 import com.trolltech.qt.gui.QTextEdit;
137 import com.trolltech.qt.gui.QToolBar;
138 import com.trolltech.qt.gui.QTreeWidgetItem;
139 import com.trolltech.qt.gui.QWidget;
140 import com.trolltech.qt.network.QNetworkAccessManager;
141 import com.trolltech.qt.network.QNetworkProxy;
142 import com.trolltech.qt.network.QNetworkProxy.ProxyType;
143 import com.trolltech.qt.network.QNetworkReply;
144 import com.trolltech.qt.network.QNetworkRequest;
145 import com.trolltech.qt.webkit.QWebPage.WebAction;
146 import com.trolltech.qt.webkit.QWebSettings;
148 import cx.fbn.nevernote.clipboard.ClipBoardObserver;
149 import cx.fbn.nevernote.config.InitializationException;
150 import cx.fbn.nevernote.config.StartupConfig;
151 import cx.fbn.nevernote.dialog.AccountDialog;
152 import cx.fbn.nevernote.dialog.ConfigDialog;
153 import cx.fbn.nevernote.dialog.DBEncryptDialog;
154 import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
155 import cx.fbn.nevernote.dialog.DatabaseStatus;
156 import cx.fbn.nevernote.dialog.FindDialog;
157 import cx.fbn.nevernote.dialog.IgnoreSync;
158 import cx.fbn.nevernote.dialog.LogFileDialog;
159 import cx.fbn.nevernote.dialog.NotebookArchive;
160 import cx.fbn.nevernote.dialog.NotebookEdit;
161 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
162 import cx.fbn.nevernote.dialog.PublishNotebook;
163 import cx.fbn.nevernote.dialog.SavedSearchEdit;
164 import cx.fbn.nevernote.dialog.SetIcon;
165 import cx.fbn.nevernote.dialog.ShareNotebook;
166 import cx.fbn.nevernote.dialog.SharedNotebookSyncError;
167 import cx.fbn.nevernote.dialog.StackNotebook;
168 import cx.fbn.nevernote.dialog.SynchronizationRequiredWarning;
169 import cx.fbn.nevernote.dialog.TagEdit;
170 import cx.fbn.nevernote.dialog.TagMerge;
171 import cx.fbn.nevernote.dialog.ThumbnailViewer;
172 import cx.fbn.nevernote.dialog.UpgradeAvailableDialog;
173 import cx.fbn.nevernote.dialog.WatchFolder;
174 import cx.fbn.nevernote.evernote.NoteMetadata;
175 import cx.fbn.nevernote.filters.FilterEditorNotebooks;
176 import cx.fbn.nevernote.filters.FilterEditorTags;
177 import cx.fbn.nevernote.gui.AttributeTreeWidget;
178 import cx.fbn.nevernote.gui.BrowserWindow;
179 import cx.fbn.nevernote.gui.DateAttributeFilterTable;
180 import cx.fbn.nevernote.gui.ExternalBrowse;
181 import cx.fbn.nevernote.gui.MainMenuBar;
182 import cx.fbn.nevernote.gui.NotebookTreeWidget;
183 import cx.fbn.nevernote.gui.RensoNoteList;
184 import cx.fbn.nevernote.gui.RensoNoteListDock;
185 import cx.fbn.nevernote.gui.SavedSearchTreeWidget;
186 import cx.fbn.nevernote.gui.SearchEdit;
187 import cx.fbn.nevernote.gui.TabBrowse;
188 import cx.fbn.nevernote.gui.TabBrowserWidget;
189 import cx.fbn.nevernote.gui.TableView;
190 import cx.fbn.nevernote.gui.TagTreeWidget;
191 import cx.fbn.nevernote.gui.Thumbnailer;
192 import cx.fbn.nevernote.gui.TrashTreeWidget;
193 import cx.fbn.nevernote.gui.ZoomPanel;
194 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
195 import cx.fbn.nevernote.oauth.OAuthTokenizer;
196 import cx.fbn.nevernote.oauth.OAuthWindow;
197 import cx.fbn.nevernote.sql.DatabaseConnection;
198 import cx.fbn.nevernote.sql.WatchFolderRecord;
199 import cx.fbn.nevernote.threads.IndexRunner;
200 import cx.fbn.nevernote.threads.SyncRunner;
201 import cx.fbn.nevernote.threads.ThumbnailRunner;
202 import cx.fbn.nevernote.utilities.AESEncrypter;
203 import cx.fbn.nevernote.utilities.ApplicationLogger;
204 import cx.fbn.nevernote.utilities.FileImporter;
205 import cx.fbn.nevernote.utilities.FileUtils;
206 import cx.fbn.nevernote.utilities.ListManager;
207 import cx.fbn.nevernote.utilities.SyncTimes;
208 import cx.fbn.nevernote.xml.ExportData;
209 import cx.fbn.nevernote.xml.ImportData;
210 import cx.fbn.nevernote.xml.ImportEnex;
211 import cx.fbn.nevernote.xml.NoteFormatter;
214 public class NeverNote extends QMainWindow{
216 QStatusBar statusBar; // Application status bar
218 DatabaseConnection conn;
220 MainMenuBar menuBar; // Main menu bar
221 FindDialog find; // Text search in note dialog
222 List<String> emitLog; // Messages displayed in the status bar;
223 QSystemTrayIcon trayIcon; // little tray icon
224 QMenu trayMenu; // System tray menu
225 QAction trayExitAction; // Exit the application
226 QAction trayShowAction; // toggle the show/hide action
227 QAction trayAddNoteAction; // Add a note from the system tray
228 QNetworkAccessManager versionChecker; // Used when checking for new versions
230 NotebookTreeWidget notebookTree; // List of notebooks
231 AttributeTreeWidget attributeTree; // List of note attributes
232 TagTreeWidget tagTree; // list of user created tags
233 SavedSearchTreeWidget savedSearchTree; // list of saved searches
234 TrashTreeWidget trashTree; // Trashcan
235 TableView noteTableView; // List of notes (the widget).
237 public BrowserWindow browserWindow; // Window containing browser & labels
238 public QToolBar toolBar; // The tool bar under the menu
239 SearchEdit searchField; // search filter bar on the toolbar;
240 QShortcut searchShortcut; // Shortcut to search bar
241 boolean searchPerformed = false; // Search was done?
242 QuotaProgressBar quotaBar; // The current quota usage
244 ApplicationLogger logger;
245 List<String> selectedNotebookGUIDs; // List of notebook GUIDs
246 List<String> selectedTagGUIDs; // List of selected tag GUIDs
247 List<String> selectedNoteGUIDs; // List of selected notes
248 String selectedSavedSearchGUID; // Currently selected saved searches
249 private final HashMap<String, ExternalBrowse> externalWindows; // Notes being edited by an external window;
251 NoteFilter filter; // Note filter
252 String currentNoteGuid; // GUID of the current note
253 Note currentNote; // The currently viewed note
254 HashMap<Integer, Boolean> noteDirty; // Has the note been changed?
255 HashMap<Integer, Boolean> inkNote; // if this is an ink note, it is read only
256 HashMap<Integer, Boolean> readOnly; // Is this note read-only?
259 ListManager listManager; // DB runnable task
261 List<QTemporaryFile> tempFiles; // Array of temporary files;
263 QTimer indexTimer; // timer to start the index thread
264 IndexRunner indexRunner; // thread to index notes
267 QTimer syncTimer; // Sync on an interval
268 QTimer syncDelayTimer; // Sync delay to free up database
269 SyncRunner syncRunner; // thread to do a sync.
270 QThread syncThread; // Thread which talks to evernote
271 ThumbnailRunner thumbnailRunner; // Runner for thumbnail thread
272 QThread thumbnailThread; // Thread that generates pretty pictures
273 QTimer saveTimer; // Timer to save note contents
275 QTimer authTimer; // Refresh authentication
276 QTimer externalFileSaveTimer; // Save files altered externally
277 QTimer thumbnailTimer; // Wakeup & scan for thumbnails
279 List<String> externalFiles; // External files to save later
280 List<String> importFilesKeep; // Auto-import files to save later
281 List<String> importFilesDelete; // Auto-import files to save later
283 int indexTime; // how often to try and index
284 boolean indexRunning; // Is indexing running?
285 boolean indexDisabled; // Is indexing disabled?
287 int syncThreadsReady; // number of sync threads that are free
288 int syncTime; // Sync interval
289 boolean syncRunning; // Is sync running?
290 boolean automaticSync; // do sync automatically?
291 QTreeWidgetItem attributeTreeSelected;
293 QAction prevButton; // Go to the previous item viewed
294 QAction nextButton; // Go to the next item in the history
295 QAction downButton; // Go to the next item in the list
296 QAction upButton; // Go to the prev. item in the list;
297 QAction synchronizeButton; // Synchronize with Evernote
298 QAction allNotesButton; // Reset & view all notes
299 QTimer synchronizeAnimationTimer; // Timer to change animation button
300 int synchronizeIconAngle; // Used to rotate sync icon
301 QAction printButton; // Print Button
302 QAction tagButton; // Tag edit button
303 QAction attributeButton; // Attribute information button
304 QAction emailButton; // Email button
305 QAction deleteButton; // Delete button
306 QAction newButton; // new Note Button;
307 QSpinBox zoomSpinner; // Zoom zoom
308 QAction searchClearButton; // Clear the search field
310 ZoomPanel zoomLayout; // Widget to hold search field, zoom, & quota
312 QSplitter mainLeftRightSplitter; // main splitter for left/right side
313 QSplitter leftSplitter1; // first left hand splitter
314 QSplitter browserIndexSplitter; // splitter between note index & note text
316 QFileSystemWatcher importKeepWatcher; // Watch & keep auto-import
317 QFileSystemWatcher importDeleteWatcher; // Watch & Delete auto-import
318 List<String> importedFiles; // History of imported files (so we don't import twice)
320 OnlineNoteHistory historyWindow; // online history window
321 List<NoteVersionId> versions; // history versions
323 QTimer threadMonitorTimer; // Timer to watch threads.
324 int dbThreadDeadCount=0; // number of consecutive dead times for the db thread
325 int syncThreadDeadCount=0; // number of consecutive dead times for the sync thread
326 int indexThreadDeadCount=0; // number of consecutive dead times for the index thread
327 int notebookThreadDeadCount=0; // number of consecutive dead times for the notebook thread
328 int tagDeadCount=0; // number of consecutive dead times for the tag thread
329 int trashDeadCount=0; // number of consecutive dead times for the trash thread
330 int saveThreadDeadCount=0; // number of consecutive dead times for the save thread
331 int enRelatedNotesThreadDeadCount=0; // number of consecutive dead times for the EvernoteRelatedNotes Thread
332 boolean disableTagThreadCheck=false;
333 boolean disableNotebookThreadCheck=false;
334 boolean disableTrashThreadCheck=false;
335 boolean disableSaveThreadCheck=false;
336 boolean disableSyncThreadCheck=false;
337 boolean disableIndexThreadCheck=false;
338 boolean disableENRelatedNotesThreadCheck=false;
340 HashMap<String, String> noteCache; // Cash of note content
341 HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
342 HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
343 HashMap<Integer, ArrayList<String>> historyGuids; // タブごとの以前見たノートのGUID
344 HashMap<Integer, Integer> historyPosition; // Position within the viewed items
345 HashMap<Integer, Boolean> fromHistory; // Is this from the history queue?
347 String trashNoteGuid; // Guid to restore / set into or out of trash to save position
348 List<Thumbnailer> thumbGenerators; // generate preview image
349 ThumbnailViewer thumbnailViewer; // View preview thumbnail;
350 boolean encryptOnShutdown; // should I encrypt when I close?
351 boolean decryptOnShutdown; // should I decrypt on shutdown;
352 String encryptCipher; // What cipher should I use?
353 //Signal0 minimizeToTray;
354 boolean windowMaximized = false; // Keep track of the window state for restores
355 List<String> pdfReadyQueue; // Queue of PDFs that are ready to be rendered.
356 List<QPixmap> syncIcons; // Array of icons used in sync animation
357 private boolean closeAction = false; // Used to say when to close or when to minimize
358 private static Logger log = Logger.getLogger(NeverNote.class);
359 private String saveLastPath; // last path we used
360 private final QTimer messageTimer; // Timer to clear the status message.
361 private QTimer blockTimer;
362 BrowserWindow blockingWindow;
364 private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
365 private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
366 private final RensoNoteListDock rensoNoteListDock; // 連想ノートリストドックウィジェット
367 ClipBoardObserver cbObserver;
368 String rensoNotePressedItemGuid;
370 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
373 //***************************************************************
374 //***************************************************************
375 //** Constructor & main entry point
376 //***************************************************************
377 //***************************************************************
378 // Application Constructor
379 @SuppressWarnings("static-access")
380 public NeverNote(DatabaseConnection dbConn) {
381 cbObserver = new ClipBoardObserver();
384 if (conn.getConnection() == null) {
385 String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
386 "is accessing the database or NeighborNote is already running.\n\n" +
387 "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
389 QMessageBox.critical(null, tr("Database Connection Error") ,msg);
392 setObjectName("mainWindow");
393 // thread().setPriority(Thread.MAX_PRIORITY);
395 logger = new ApplicationLogger("nevernote.log");
396 logger.log(logger.HIGH, "Starting Application");
398 decryptOnShutdown = false;
399 encryptOnShutdown = false;
400 conn.checkDatabaseVersion();
404 // Start building the invalid XML tables
405 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
406 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
408 for (int i=0; i<elements.size(); i++) {
409 Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
412 logger.log(logger.EXTREME, "Starting GUI build");
414 QTranslator nevernoteTranslator = new QTranslator();
415 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("neighbornote_" + QLocale.system().name() + ".qm"));
416 QApplication.instance().installTranslator(nevernoteTranslator);
418 Global.originalPalette = QApplication.palette();
419 QApplication.setStyle(Global.getStyle());
420 if (Global.useStandardPalette())
421 QApplication.setPalette(QApplication.style().standardPalette());
422 setWindowTitle(tr("NeighborNote"));
424 mainLeftRightSplitter = new QSplitter();
425 mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
427 setCentralWidget(mainLeftRightSplitter);
428 leftSplitter1 = new QSplitter();
429 leftSplitter1.setOrientation(Qt.Orientation.Vertical);
431 browserIndexSplitter = new QSplitter();
432 browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
434 //* Setup threads & thread timers
435 // int indexRunnerCount = Global.getIndexThreads();
436 // indexRunnerCount = 1;
437 QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount); // increase max thread count
439 logger.log(logger.EXTREME, "Building list manager");
440 listManager = new ListManager(conn, logger);
442 logger.log(logger.EXTREME, "Building index runners & timers");
443 indexRunner = new IndexRunner("indexRunner.log",
444 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
445 Global.getResourceDatabaseUrl(),
446 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
447 Global.getDatabaseUserPassword(), Global.cipherPassword);
449 indexThread = new QThread(indexRunner, "Index Thread");
450 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
451 indexRunner.indexImageRecognition = Global.indexImageRecognition();
452 // indexRunner.indexNoteBody = Global.indexNoteBody();
453 // indexRunner.indexNoteTitle = Global.indexNoteTitle();
454 // indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
457 synchronizeAnimationTimer = new QTimer();
458 synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
460 indexTimer = new QTimer();
461 indexTime = 1000*Global.getIndexThreadSleepInterval();
462 indexTimer.start(indexTime); // Start indexing timer
463 indexTimer.timeout.connect(this, "indexTimer()");
464 indexDisabled = false;
465 indexRunning = false;
467 logger.log(logger.EXTREME, "Setting sync thread & timers");
469 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
470 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
471 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
472 Global.getDatabaseUserPassword(), Global.cipherPassword);
474 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
475 syncTimer = new QTimer();
476 syncTimer.timeout.connect(this, "syncTimer()");
477 syncRunner.status.message.connect(this, "setMessage(String)");
478 syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
479 syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
480 syncRunner.limitSignal.rateLimitReached.connect(this, "informRateLimit(Integer)");
483 automaticSync = true;
484 syncTimer.start(syncTime*60*1000);
486 automaticSync = false;
489 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
490 syncThread = new QThread(syncRunner, "Synchronization Thread");
494 logger.log(logger.EXTREME, "Starting thumnail thread");
495 pdfReadyQueue = new ArrayList<String>();
496 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
497 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
498 Global.getResourceDatabaseUrl(),
499 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
500 Global.getDatabaseUserPassword(), Global.cipherPassword);
502 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
503 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
504 thumbnailThread.start();
505 thumbGenerators = new ArrayList<Thumbnailer>();
506 thumbnailTimer = new QTimer();
507 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
509 thumbnailTimer.setInterval(500*1000); // Thumbnail every minute
510 thumbnailTimer.start();
512 // debugTimer = new QTimer();
513 // debugTimer.timeout.connect(this, "debugDirty()");
514 // debugTimer.start(1000*60);
516 logger.log(logger.EXTREME, "Starting authentication timer");
517 authTimer = new QTimer();
518 authTimer.timeout.connect(this, "authTimer()");
519 authTimer.start(1000*60*15);
520 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
522 logger.log(logger.EXTREME, "Setting save note timer");
523 saveTimer = new QTimer();
524 saveTimer.timeout.connect(this, "saveNote()");
525 if (Global.getAutoSaveInterval() > 0) {
526 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
529 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
531 logger.log(logger.EXTREME, "Starting external file monitor timer");
532 externalFileSaveTimer = new QTimer();
533 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
534 externalFileSaveTimer.setInterval(1000*5); // save every 5 seconds;
535 externalFiles = new ArrayList<String>();
536 importFilesDelete = new ArrayList<String>();
537 importFilesKeep = new ArrayList<String>();
538 externalFileSaveTimer.start();
540 notebookTree = new NotebookTreeWidget(conn);
541 attributeTree = new AttributeTreeWidget();
542 tagTree = new TagTreeWidget(conn);
543 savedSearchTree = new SavedSearchTreeWidget();
544 trashTree = new TrashTreeWidget();
545 noteTableView = new TableView(logger, listManager, this);
547 quotaBar = new QuotaProgressBar();
549 zoomSpinner = new QSpinBox();
550 zoomSpinner.setMinimum(10);
551 zoomSpinner.setMaximum(1000);
552 zoomSpinner.setAccelerated(true);
553 zoomSpinner.setSingleStep(10);
554 zoomSpinner.setValue(100);
555 zoomSpinner.valueChanged.connect(this, "zoomChanged()");
557 zoomLayout = new ZoomPanel(quotaBar, notebookTree, zoomSpinner);
560 QGridLayout leftGrid = new QGridLayout();
561 leftSplitter1.setContentsMargins(5, 0, 0, 7);
562 leftSplitter1.setLayout(leftGrid);
563 leftGrid.addWidget(zoomLayout,1,1);
564 leftGrid.addWidget(tagTree,2,1);
565 leftGrid.addWidget(attributeTree,3,1);
566 leftGrid.addWidget(savedSearchTree,4,1);
567 leftGrid.addWidget(trashTree,5, 1);
569 // Setup the browser window
570 noteCache = new HashMap<String,String>();
571 readOnlyCache = new HashMap<String, Boolean>();
572 inkNoteCache = new HashMap<String, Boolean>();
573 browserWindow = new BrowserWindow(conn, cbObserver);
576 historyGuids = new HashMap<Integer, ArrayList<String>>();
577 historyPosition = new HashMap<Integer, Integer>();
578 fromHistory = new HashMap<Integer, Boolean>();
581 tabWindows = new HashMap<Integer, TabBrowse>();
582 tabBrowser = new TabBrowserWidget(this);
583 tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
584 tabBrowser.setMovable(true);
585 tabBrowser.setTabsClosable(true);
586 TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver);
587 browserWindow = tab.getBrowserWindow();
588 int index = tabBrowser.addNewTab(tab, "");
589 tabWindows.put(index, tab);
590 tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)");
591 tabBrowser.tabCloseRequested.connect(this, "tabCloseRequested(int)");
593 noteDirty = new HashMap<Integer, Boolean>();
594 noteDirty.put(index, false);
596 inkNote = new HashMap<Integer, Boolean>();
597 readOnly = new HashMap<Integer, Boolean>();
600 historyGuids.put(index, new ArrayList<String>());
601 historyPosition.put(index, 0);
602 fromHistory.put(index, false);
604 mainLeftRightSplitter.addWidget(leftSplitter1);
605 mainLeftRightSplitter.addWidget(browserIndexSplitter);
608 rensoNoteListDock = new RensoNoteListDock(conn, this, syncRunner, iconPath, tr("Renso Note List"));
609 addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
611 if (Global.getListView() == Global.View_List_Wide) {
612 browserIndexSplitter.addWidget(noteTableView);
613 browserIndexSplitter.addWidget(tabBrowser);
615 mainLeftRightSplitter.addWidget(noteTableView);
616 mainLeftRightSplitter.addWidget(tabBrowser);
619 // Setup the thumbnail viewer
620 thumbnailViewer = new ThumbnailViewer();
621 thumbnailViewer.upArrow.connect(this, "upAction()");
622 thumbnailViewer.downArrow.connect(this, "downAction()");
623 thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
624 thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
626 //Setup external browser manager
627 externalWindows = new HashMap<String, ExternalBrowse>();
629 listManager.loadNotesIndex();
630 initializeNotebookTree();
632 initializeSavedSearchTree();
633 attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
634 attributeTreeSelected = null;
635 initializeNoteTable();
637 selectedNoteGUIDs = new ArrayList<String>();
638 statusBar = new QStatusBar();
639 setStatusBar(statusBar);
640 menuBar = new MainMenuBar(this);
641 emitLog = new ArrayList<String>();
643 tagTree.setDeleteAction(menuBar.tagDeleteAction);
644 tagTree.setMergeAction(menuBar.tagMergeAction);
645 tagTree.setEditAction(menuBar.tagEditAction);
646 tagTree.setAddAction(menuBar.tagAddAction);
647 tagTree.setIconAction(menuBar.tagIconAction);
648 tagTree.setVisible(Global.isWindowVisible("tagTree"));
649 leftSplitter1.setVisible(Global.isWindowVisible("leftPanel"));
650 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
651 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
652 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
654 if (!Global.isWindowVisible("zoom")) {
655 zoomLayout.hideZoom();
656 menuBar.hideZoom.setChecked(false);
659 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
660 notebookTree.setEditAction(menuBar.notebookEditAction);
661 notebookTree.setAddAction(menuBar.notebookAddAction);
662 notebookTree.setIconAction(menuBar.notebookIconAction);
663 notebookTree.setStackAction(menuBar.notebookStackAction);
664 notebookTree.setPublishAction(menuBar.notebookPublishAction);
665 notebookTree.setShareAction(menuBar.notebookShareAction);
666 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
667 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
668 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
669 notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
670 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
672 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
673 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
674 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
675 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
676 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
677 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
678 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
680 // noteTableViewに新しいタブで開くを追加
681 noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
683 noteTableView.setAddAction(menuBar.noteAdd);
685 // noteTableViewに新しいタブでノート追加を追加
686 noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
688 noteTableView.setDeleteAction(menuBar.noteDelete);
689 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
690 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
691 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
692 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
693 noteTableView.noteSignal.notePinned.connect(this, "notePinned()");
694 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
695 noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction);
696 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
697 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
699 quotaBar.setMouseClickAction(menuBar.accountAction);
702 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
703 trashTree.setEmptyAction(menuBar.emptyTrashAction);
704 trashTree.setVisible(Global.isWindowVisible("trashTree"));
705 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
706 trashTree.updateCounts(listManager.getTrashCount());
707 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
708 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
710 noteTableView.setVisible(Global.isWindowVisible("noteList"));
711 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
713 if (!Global.isWindowVisible("editorButtonBar")) {
714 menuBar.showEditorBar.setChecked(false);
715 toggleEditorButtonBar();
718 if (!Global.isWindowVisible("leftPanel"))
719 menuBar.hideLeftSide.setChecked(true);
721 if (Global.isWindowVisible("noteInformation")) {
722 menuBar.noteAttributes.setChecked(true);
723 toggleNoteInformation();
726 quotaBar.setVisible(Global.isWindowVisible("quota"));
727 // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
728 // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
729 if (!Global.isWindowVisible("quota"))
730 menuBar.hideQuota.setChecked(false);
732 if (quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
737 find = new FindDialog();
738 find.getOkButton().clicked.connect(this, "doFindText()");
740 // Setup the tray icon menu bar
741 trayShowAction = new QAction(tr("Show/Hide"), this);
742 trayExitAction = new QAction(tr("Exit"), this);
743 trayAddNoteAction = new QAction(tr("Add Note"), this);
745 trayExitAction.triggered.connect(this, "closeNeverNote()");
746 trayAddNoteAction.triggered.connect(this, "addNote()");
747 trayShowAction.triggered.connect(this, "trayToggleVisible()");
749 trayMenu = new QMenu(this);
750 trayMenu.addAction(trayAddNoteAction);
751 trayMenu.addAction(trayShowAction);
752 trayMenu.addAction(trayExitAction);
755 trayIcon = new QSystemTrayIcon(this);
756 trayIcon.setToolTip(tr("NeighborNote"));
757 trayIcon.setContextMenu(trayMenu);
758 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
761 currentNoteGuid = Global.getLastViewedNoteGuid();
762 if (currentNoteGuid.equals(""))
763 currentNote = new Note();
766 * historyGuids = new ArrayList<String>();
767 * historyPosition = 0;
768 * fromHistory = false;
771 if (!currentNoteGuid.trim().equals("")) {
772 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
775 noteIndexUpdated(true);
777 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
778 if (menuBar.showEditorBar.isChecked())
779 showEditorButtons(browserWindow);
780 tagIndexUpdated(true);
781 savedSearchIndexUpdated();
782 notebookIndexUpdated();
784 setupSyncSignalListeners();
785 setupBrowserSignalListeners();
786 setupIndexListeners();
789 tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
790 tagTree.showAllTags(true);
792 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
793 if (QSystemTrayIcon.isSystemTrayAvailable()) {
794 setWindowIcon(appIcon);
795 trayIcon.setIcon(appIcon);
796 if (Global.showTrayIcon() || Global.minimizeOnClose())
802 scrollToGuid(currentNoteGuid);
803 if (Global.automaticLogin()) {
805 if (Global.isConnected)
808 setupFolderImports();
811 restoreWindowState(true);
813 if (Global.mimicEvernoteInterface) {
814 notebookTree.selectGuid("");
817 threadMonitorTimer = new QTimer();
818 threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
819 threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
821 // IFIXED 恐らく不要なのでコメントアウト
823 * historyGuids.add(currentNoteGuid);
824 * historyPosition = 1;
827 menuBar.blockSignals(true);
828 menuBar.narrowListView.blockSignals(true);
829 menuBar.wideListView.blockSignals(true);
830 if (Global.getListView() == Global.View_List_Narrow) {
831 menuBar.narrowListView.setChecked(true);
834 menuBar.wideListView.setChecked(true);
836 menuBar.blockSignals(false);
837 menuBar.narrowListView.blockSignals(false);
838 menuBar.wideListView.blockSignals(false);
840 // IFIXED 上に同じコードがあるのでコメントアウト
842 * if (Global.getListView() == Global.View_List_Wide) {
843 * browserIndexSplitter.addWidget(noteTableView);
844 * browserIndexSplitter.addWidget(tabBrowser);
845 * browserIndexSplitter.addWidget(browserWindow); } else {
846 * mainLeftRightSplitter.addWidget(noteTableView);
847 * mainLeftRightSplitter.addWidget(tabBrowser);
848 * mainLeftRightSplitter.addWidget(browserWindow); }
851 messageTimer = new QTimer();
852 messageTimer.timeout.connect(this, "clearMessage()");
853 messageTimer.setInterval(1000*15);
856 int sortCol = Global.getSortColumn();
857 int sortOrder = Global.getSortOrder();
858 noteTableView.proxyModel.blocked = true;
859 // We sort the table twice to fix a bug. For some reaosn the table won't sort properly if it is in narrow
860 // list view and sorted descending on the date created. By sorting it twice it forces the proper sort. Ugly.
861 if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow)
862 noteTableView.sortByColumn(sortCol, SortOrder.resolve(0));
863 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
864 noteTableView.proxyModel.blocked = false;
865 noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)");
867 // Set the startup notebook
868 String defaultNotebook = Global.getStartupNotebook();
869 if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) {
870 for (int k=0; k<listManager.getNotebookIndex().size(); k++) {
871 if (listManager.getNotebookIndex().get(k).isDefaultNotebook()) {
872 notebookTree.clearSelection();
873 notebookTree.selectGuid(listManager.getNotebookIndex().get(k).getGuid());
874 notebookTree.selectionSignal.emit();
879 if (Global.checkVersionUpgrade()) {
883 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
884 menuBar.noteAddNewTab.setEnabled(false);
889 public void debugDirty() {
890 List<Note> dirty = conn.getNoteTable().getDirty();
891 logger.log(logger.LOW, "------ Dirty Notes List Begin ------");
892 for (int i=0; i<dirty.size(); i++) {
893 logger.log(logger.LOW, "GUID: " +dirty.get(i).getGuid() + " Title:" + dirty.get(i).getTitle());
895 logger.log(logger.LOW, "------ Dirty Notes List End ------");
899 public static void main(String[] args) {
900 log.setLevel(Level.FATAL);
901 QApplication.initialize(args);
902 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
903 QSplashScreen splash = new QSplashScreen(pixmap);
906 DatabaseConnection dbConn;
909 initializeGlobalSettings(args);
911 showSplash = Global.isWindowVisible("SplashScreen");
915 dbConn = setupDatabaseConnection();
917 // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
918 Global.getFileManager().purgeResDirectory(true);
920 } catch (InitializationException e) {
923 QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
928 String proxyUrl = Global.getProxyValue("url");
929 String proxyPort = Global.getProxyValue("port");
930 String proxyUserid = Global.getProxyValue("userid");
931 String proxyPassword = Global.getProxyValue("password");
932 boolean proxySet = false;
933 QNetworkProxy proxy = new QNetworkProxy();
934 proxy.setType(ProxyType.HttpProxy);
935 if (!proxyUrl.trim().equals("")) {
936 System.out.println("Proxy URL found: " +proxyUrl);
938 proxy.setHostName(proxyUrl);
940 if (!proxyPort.trim().equals("")) {
941 System.out.println("Proxy Port found: " +proxyPort);
943 proxy.setPort(Integer.parseInt(proxyPort));
945 if (!proxyUserid.trim().equals("")) {
946 System.out.println("Proxy Userid found: " +proxyUserid);
948 proxy.setUser(proxyUserid);
950 if (!proxyPassword.trim().equals("")) {
951 System.out.println("Proxy URL found: " +proxyPassword);
953 proxy.setPassword(proxyPassword);
956 QNetworkProxy.setApplicationProxy(proxy);
960 NeverNote application = new NeverNote(dbConn);
961 if (Global.syncOnly) {
962 System.out.println("Performing synchronization only.");
963 application.remoteConnect();
964 if (Global.isConnected) {
965 application.syncRunner.syncNeeded = true;
966 application.syncRunner.addWork("SYNC");
967 application.syncRunner.addWork("STOP");
968 while(!application.syncRunner.isIdle());
969 application.closeNeverNote();
974 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
975 if (Global.startMinimized())
976 application.showMinimized();
978 if (Global.wasWindowMaximized())
979 application.showMaximized();
985 splash.finish(application);
987 System.out.println("Goodbye.");
992 * Open the internal database, or create if not present
994 * @throws InitializationException when opening the database fails, e.g. because another process has it locked
996 private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
997 ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
999 File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
1000 File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
1001 // IFIXED resourceDatabaseNameになっていたので修正
1002 File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
1003 File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
1006 Global.setDatabaseUrl("");
1008 Global.setResourceDatabaseUrl("");
1010 Global.setIndexDatabaseUrl("");
1012 Global.setBehaviorDatabaseUrl("");
1014 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
1015 boolean goodCheck = false;
1016 while (!goodCheck) {
1017 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
1019 if (!dialog.okPressed())
1021 Global.cipherPassword = dialog.getPassword();
1022 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
1023 Global.getDatabaseUserPassword(), Global.cipherPassword);
1026 DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(),
1027 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
1028 Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
1032 // Encrypt the database upon shutdown
1033 private void encryptOnShutdown() {
1034 String dbPath= Global.getFileManager().getDbDirPath("");
1037 Statement st = conn.getConnection().createStatement();
1038 st.execute("shutdown");
1039 st = conn.getResourceConnection().createStatement();
1040 st.execute("shutdown");
1041 st = conn.getIndexConnection().createStatement();
1042 st.execute("shutdown");
1043 st = conn.getBehaviorConnection().createStatement();
1044 st.execute("shutdown");
1046 if (QMessageBox.question(this, tr("Are you sure"),
1047 tr("Are you sure you wish to encrypt the database?"),
1048 QMessageBox.StandardButton.Yes,
1049 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1050 ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1051 ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1052 ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1053 ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1055 Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
1056 Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
1057 Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
1058 Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
1060 QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
1062 } catch (SQLException e) {
1063 e.printStackTrace();
1067 // Decrypt the database upon shutdown
1068 private void decryptOnShutdown() {
1069 String dbPath= Global.getFileManager().getDbDirPath("");
1070 String dbName = "NeverNote";
1072 Statement st = conn.getConnection().createStatement();
1073 st.execute("shutdown");
1074 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
1075 encryptCipher = "AES";
1077 encryptCipher = "XTEA";
1078 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
1079 "Are you sure you wish to decrypt the database?"),
1080 QMessageBox.StandardButton.Yes,
1081 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1083 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
1084 Global.setDatabaseUrl("");
1085 Global.setResourceDatabaseUrl("");
1086 Global.setIndexDatabaseUrl("");
1087 QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
1089 } catch (SQLException e) {
1090 e.printStackTrace();
1094 * Encrypt/Decrypt the local database
1096 public void doDatabaseEncrypt() {
1097 // The database is not currently encrypted
1098 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
1099 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
1100 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
1101 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
1102 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
1103 "Do you wish to proceed?"),
1104 QMessageBox.StandardButton.Yes,
1105 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1108 DBEncryptDialog dialog = new DBEncryptDialog();
1110 if (dialog.okPressed()) {
1111 Global.cipherPassword = dialog.getPassword();
1112 encryptOnShutdown = true;
1113 encryptCipher = dialog.getEncryptionMethod();
1116 DBEncryptDialog dialog = new DBEncryptDialog();
1117 dialog.setWindowTitle(tr("Database Decryption"));
1118 dialog.hideEncryption();
1120 if (dialog.okPressed()) {
1121 if (!dialog.getPassword().equals(Global.cipherPassword)) {
1122 QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
1125 decryptOnShutdown = true;
1132 private static void initializeGlobalSettings(String[] args) throws InitializationException {
1133 StartupConfig startupConfig = new StartupConfig();
1135 for (String arg : args) {
1136 String lower = arg.toLowerCase();
1137 if (lower.startsWith("--name="))
1138 startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
1139 if (lower.startsWith("--home="))
1140 startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
1141 if (lower.startsWith("--disable-viewing"))
1142 startupConfig.setDisableViewing(true);
1143 if (lower.startsWith("--sync-only=true"))
1144 startupConfig.setSyncOnly(true);
1146 Global.setup(startupConfig);
1152 public void closeEvent(QCloseEvent event) {
1153 if (Global.minimizeOnClose() && !closeAction) {
1158 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
1161 if (currentNote != null & browserWindow != null) {
1162 if (currentNote.getTitle() != null && browserWindow != null
1163 && !currentNote.getTitle().equals(browserWindow.getTitle()))
1164 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
1165 browserWindow.getTitle());
1169 setMessage(tr("Beginning shutdown."));
1171 // Close down external windows
1172 Collection<ExternalBrowse> windows = externalWindows.values();
1173 Iterator<ExternalBrowse> iterator = windows.iterator();
1174 while (iterator.hasNext()) {
1175 ExternalBrowse browser = iterator.next();
1176 browser.windowClosing.disconnect();
1180 // タブブラウザに対してクローズ処理を行う
1181 Collection<TabBrowse> win = tabWindows.values();
1182 Iterator<TabBrowse> it = win.iterator();
1183 tabBrowser.currentChanged.disconnect();
1184 tabBrowser.tabCloseRequested.disconnect();
1185 while (it.hasNext()) {
1186 TabBrowse browser = it.next();
1190 externalFileEditedSaver();
1191 if (Global.isConnected && Global.synchronizeOnClose()) {
1192 setMessage(tr("Performing synchronization before closing."));
1193 syncRunner.syncNeeded = true;
1194 syncRunner.addWork("SYNC");
1196 syncRunner.keepRunning = false;
1198 syncRunner.addWork("STOP");
1199 setMessage("Closing Program.");
1200 threadMonitorTimer.stop();
1202 thumbnailRunner.addWork("STOP");
1203 indexRunner.addWork("STOP");
1208 // 連想ノートリストのEvernote関連ノート取得スレッドを終了
1209 rensoNoteListDock.getRensoNoteList().stopThread();
1211 if (tempFiles != null)
1214 browserWindow.noteSignal.tagsChanged.disconnect();
1215 browserWindow.noteSignal.titleChanged.disconnect();
1216 browserWindow.noteSignal.noteChanged.disconnect();
1217 browserWindow.noteSignal.notebookChanged.disconnect();
1218 browserWindow.noteSignal.createdDateChanged.disconnect();
1219 browserWindow.noteSignal.alteredDateChanged.disconnect();
1220 syncRunner.searchSignal.listChanged.disconnect();
1221 syncRunner.tagSignal.listChanged.disconnect();
1222 syncRunner.notebookSignal.listChanged.disconnect();
1223 syncRunner.noteIndexSignal.listChanged.disconnect();
1226 Global.saveWindowVisible("toolBar", toolBar.isVisible());
1227 saveNoteColumnPositions();
1228 saveNoteIndexWidth();
1230 int width = notebookTree.columnWidth(0);
1231 Global.setColumnWidth("notebookTreeName", width);
1232 width = tagTree.columnWidth(0);
1233 Global.setColumnWidth("tagTreeName", width);
1235 Global.saveWindowMaximized(isMaximized());
1236 Global.saveCurrentNoteGuid(currentNoteGuid);
1238 int sortCol = noteTableView.proxyModel.sortColumn();
1239 int sortOrder = noteTableView.proxyModel.sortOrder().value();
1240 Global.setSortColumn(sortCol);
1241 Global.setSortOrder(sortOrder);
1245 Global.keepRunning = false;
1247 logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
1248 if (indexRunner.thread().isAlive())
1249 indexRunner.thread().join(50);
1250 if (!indexRunner.thread().isAlive())
1251 logger.log(logger.MEDIUM, "Index thread has stopped");
1253 logger.log(logger.MEDIUM, "Index thread still running - interrupting");
1254 indexRunner.thread().interrupt();
1256 } catch (InterruptedException e1) {
1257 e1.printStackTrace();
1260 if (!syncRunner.thread().isAlive()) {
1261 logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
1262 if (syncRunner.thread().isAlive()) {
1263 System.out.println(tr("Synchronizing. Please be patient."));
1264 for(;syncRunner.thread().isAlive();) {
1267 } catch (InterruptedException e) {
1268 e.printStackTrace();
1272 logger.log(logger.MEDIUM, "Sync thread has stopped");
1275 if (encryptOnShutdown) {
1276 encryptOnShutdown();
1278 if (decryptOnShutdown) {
1279 decryptOnShutdown();
1282 Global.getFileManager().purgeResDirectory(false);
1283 } catch (InitializationException e) {
1284 System.out.println(tr("Empty res directory purge failed"));
1285 e.printStackTrace();
1287 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
1291 private void closeNeverNote() {
1295 public void setMessage(String s) {
1297 logger.log(logger.HIGH, "Entering NeverNote.setMessage");
1299 System.out.println("*** ERROR *** " +s);
1301 if (statusBar != null) {
1304 logger.log(logger.HIGH, "Message: " +s);
1305 statusBar.showMessage(s);
1306 if (emitLog != null)
1309 if (messageTimer != null) {
1310 messageTimer.stop();
1311 messageTimer.setSingleShot(true);
1312 messageTimer.start();
1317 logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
1320 private void clearMessage() {
1321 statusBar.clearMessage();
1325 private void waitCursor(boolean wait) {
1327 if (QApplication.overrideCursor() == null)
1328 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1331 if (QApplication.overrideCursor() != null)
1332 QApplication.restoreOverrideCursor();
1334 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.ArrowCursor));
1336 listManager.refreshCounters();
1339 private void setupIndexListeners() {
1340 // indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1341 // indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1342 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1343 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1345 private void setupSyncSignalListeners() {
1346 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1347 syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1348 syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1349 syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1350 syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1352 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1353 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1354 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1356 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1357 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1358 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1359 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1360 syncRunner.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1362 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1365 private void setupBrowserSignalListeners() {
1366 setupBrowserWindowListeners(browserWindow, true);
1369 private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1370 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1371 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1372 browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1373 if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1374 browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1375 browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1376 browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1377 browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1378 browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1379 browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1380 browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1381 browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1382 browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1383 browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1384 browser.blockApplication.connect(this, "blockApplication(BrowserWindow)");
1385 browser.unblockApplication.connect(this, "unblockApplication()");
1386 if (master) browser.focusLost.connect(this, "saveNote()");
1387 browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1388 browser.evernoteLinkClicked.connect(this, "evernoteLinkClick(String, String)");
1391 //**************************************************
1393 //**************************************************
1394 private void setupShortcut(QShortcut action, String text) {
1395 if (!Global.shortcutKeys.containsAction(text))
1397 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
1400 //***************************************************************
1401 //***************************************************************
1402 //* Settings and look & feel
1403 //***************************************************************
1404 //***************************************************************
1405 @SuppressWarnings("unused")
1406 private void settings() {
1407 logger.log(logger.HIGH, "Entering NeverNote.settings");
1409 saveNoteColumnPositions();
1410 saveNoteIndexWidth();
1412 ConfigDialog settings = new ConfigDialog(this, conn);
1413 String dateFormat = Global.getDateFormat();
1414 String timeFormat = Global.getTimeFormat();
1416 indexTime = 1000*Global.getIndexThreadSleepInterval();
1417 indexTimer.start(indexTime); // reset indexing timer
1420 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1421 // indexRunner.indexNoteBody = Global.indexNoteBody();
1422 // indexRunner.indexNoteTitle = Global.indexNoteTitle();
1423 // indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
1424 indexRunner.indexImageRecognition = Global.indexImageRecognition();
1425 if (Global.showTrayIcon() || Global.minimizeOnClose())
1430 if (menuBar.showEditorBar.isChecked()){
1431 for(int i = 0; i < tabBrowser.count(); i++){
1432 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
1433 showEditorButtons(browser);
1438 // Reset the save timer
1439 if (Global.getAutoSaveInterval() > 0)
1440 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1445 // Set special reloads
1446 if (settings.getDebugPage().reloadSharedNotebooksClicked()) {
1447 conn.executeSql("Delete from LinkedNotebook");
1448 conn.executeSql("delete from SharedNotebook");
1449 conn.executeSql("Delete from Notebook where linked=true");
1450 conn.executeSql("Insert into Sync (key, value) values ('FullLinkedNotebookSync', 'true')");
1451 conn.executeSql("Insert into Sync (key, value) values ('FullSharedNotebookSync', 'true')");
1456 readOnlyCache.clear();
1457 inkNoteCache.clear();
1458 noteIndexUpdated(true);
1460 logger.log(logger.HIGH, "Leaving NeverNote.settings");
1462 // Restore things to the way they were
1463 private void restoreWindowState(boolean mainWindow) {
1464 // We need to name things or this doesn't work.
1465 setObjectName("NeverNote");
1466 restoreState(Global.restoreState(objectName()));
1467 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1468 browserIndexSplitter.setObjectName("browserIndexSplitter");
1469 leftSplitter1.setObjectName("leftSplitter1");
1470 rensoNoteListDock.setObjectName("rensoNoteListDock");
1472 // Restore the actual positions.
1474 restoreGeometry(Global.restoreGeometry(objectName()));
1475 mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1476 browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1477 leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1478 rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
1481 // Save window positions for the next start
1482 private void saveWindowState() {
1483 Global.saveGeometry(objectName(), saveGeometry());
1484 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1485 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1486 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1487 Global.saveState(objectName(), saveState());
1488 Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
1490 // Load the style sheet
1491 private void loadStyleSheet() {
1492 String styleSheetName = "default.qss";
1493 if (Global.getStyle().equalsIgnoreCase("cleanlooks"))
1494 styleSheetName = "default-cleanlooks.qss";
1495 String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
1496 QFile file = new QFile(fileName);
1498 // If a user default.qss doesn't exist, we use the one shipped with NeverNote
1499 if (!file.exists()) {
1500 fileName = Global.getFileManager().getQssDirPath(styleSheetName);
1501 file = new QFile(fileName);
1503 file.open(OpenModeFlag.ReadOnly);
1504 String styleSheet = file.readAll().toString();
1506 setStyleSheet(styleSheet);
1508 // Save column positions for the next time
1509 private void saveNoteColumnPositions() {
1510 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1511 Global.setColumnPosition("noteTableCreationPosition", position);
1512 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1513 Global.setColumnPosition("noteTableTagPosition", position);
1514 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1515 Global.setColumnPosition("noteTableNotebookPosition", position);
1516 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1517 Global.setColumnPosition("noteTableChangedPosition", position);
1518 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1519 Global.setColumnPosition("noteTableAuthorPosition", position);
1520 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1521 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1522 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1523 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1524 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1525 Global.setColumnPosition("noteTableTitlePosition", position);
1526 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1527 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1528 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1529 Global.setColumnPosition("noteTableGuidPosition", position);
1530 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1531 Global.setColumnPosition("noteTableThumbnailPosition", position);
1532 position = noteTableView.header.visualIndex(Global.noteTablePinnedPosition);
1533 Global.setColumnPosition("noteTablePinnedPosition", position);
1536 // Save column widths for the next time
1537 private void saveNoteIndexWidth() {
1539 width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1540 Global.setColumnWidth("noteTableCreationPosition", width);
1541 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1542 Global.setColumnWidth("noteTableChangedPosition", width);
1543 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1544 Global.setColumnWidth("noteTableGuidPosition", width);
1545 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1546 Global.setColumnWidth("noteTableNotebookPosition", width);
1547 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1548 Global.setColumnWidth("noteTableTagPosition", width);
1549 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1550 Global.setColumnWidth("noteTableTitlePosition", width);
1551 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1552 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1553 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1554 Global.setColumnWidth("noteTableAuthorPosition", width);
1555 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1556 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1557 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1558 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1559 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1560 Global.setColumnWidth("noteTableThumbnailPosition", width);
1561 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1562 Global.setColumnWidth("noteTableGuidPosition", width);
1563 width = noteTableView.getColumnWidth(Global.noteTablePinnedPosition);
1564 Global.setColumnWidth("noteTablePinnedPosition", width);
1567 @SuppressWarnings("unused")
1568 private void toggleSearchWindow() {
1569 logger.log(logger.HIGH, "Entering NeverNote.toggleSearchWindow");
1570 toggleSearchField();
1571 menuBar.hideSearch.setChecked(searchField.isVisible());
1572 Global.saveWindowVisible("searchField", searchField.isVisible());
1573 logger.log(logger.HIGH, "Leaving NeverNote.toggleSearchWindow");
1575 private void toggleSearchField() {
1576 if (searchField.isVisible())
1582 @SuppressWarnings("unused")
1583 private void toggleQuotaWindow() {
1584 logger.log(logger.HIGH, "Entering NeverNote.toggleQuotaWindow");
1585 zoomLayout.toggleQuotaBar();
1586 menuBar.hideQuota.setChecked(quotaBar.isVisible());
1587 Global.saveWindowVisible("quota", quotaBar.isVisible());
1588 logger.log(logger.HIGH, "Leaving NeverNote.toggleQuotaWindow");
1590 @SuppressWarnings("unused")
1591 private void toggleZoomWindow() {
1592 logger.log(logger.HIGH, "Entering NeverNote.toggleZoomWindow");
1593 zoomLayout.toggleZoom();
1594 menuBar.hideZoom.setChecked(zoomSpinner.isVisible());
1595 Global.saveWindowVisible("zoom", zoomSpinner.isVisible());
1596 logger.log(logger.HIGH, "Leaving NeverNote.toggleZoomWindow");
1601 //***************************************************************
1602 //***************************************************************
1603 //** These functions deal with Notebook menu items
1604 //***************************************************************
1605 //***************************************************************
1606 // Setup the tree containing the user's notebooks.
1607 private void initializeNotebookTree() {
1608 logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1609 // notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1610 notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
1611 listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1612 logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1614 // Listener when a notebook is selected
1615 private void notebookTreeSelection() {
1616 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1617 noteTableView.proxyModel.blocked = true;
1620 clearAttributeFilter();
1621 clearSavedSearchFilter();
1622 if (Global.mimicEvernoteInterface) {
1624 searchField.clear();
1626 menuBar.noteRestoreAction.setVisible(false);
1627 menuBar.notebookEditAction.setEnabled(true);
1628 menuBar.notebookDeleteAction.setEnabled(true);
1629 menuBar.notebookPublishAction.setEnabled(true);
1630 menuBar.notebookShareAction.setEnabled(true);
1631 menuBar.notebookIconAction.setEnabled(true);
1632 menuBar.notebookStackAction.setEnabled(true);
1634 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
1635 if (!rensoNoteListDock.isEnabled()) {
1636 rensoNoteListDock.setEnabled(true);
1639 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1640 selectedNotebookGUIDs.clear();
1641 searchField.setTargetNotebook("");
1642 searchField.setTargetStack("");
1644 String stackName = "";
1645 if (selections.size() > 0) {
1646 guid = (selections.get(0).text(2));
1647 stackName = selections.get(0).text(0);
1649 if (!Global.mimicEvernoteInterface) {
1650 // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1651 if (selections.size()==0) {
1652 selectedNotebookGUIDs.clear();
1653 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1654 selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1656 menuBar.notebookEditAction.setEnabled(false);
1657 menuBar.notebookDeleteAction.setEnabled(false);
1658 menuBar.notebookStackAction.setEnabled(false);
1659 menuBar.notebookIconAction.setEnabled(false);
1662 if (!guid.equals("") && !guid.equals("STACK")) {
1663 selectedNotebookGUIDs.add(stackName);
1664 searchField.setTargetNotebook(guid);
1665 menuBar.notebookIconAction.setEnabled(true);
1667 searchField.setTargetStack(guid);
1668 menuBar.notebookIconAction.setEnabled(true);
1669 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1670 Notebook book = listManager.getNotebookIndex().get(j);
1671 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName)) {
1672 selectedNotebookGUIDs.add(book.getGuid());
1676 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1677 listManager.loadNotesIndex();
1678 noteIndexUpdated(false);
1679 refreshEvernoteNote(true);
1680 listManager.refreshCounters = true;
1681 listManager.refreshCounters();
1682 if (selectedNotebookGUIDs.size() == 1) {
1683 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1684 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1686 noteTableView.proxyModel.blocked = true;
1688 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1690 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1693 noteTableView.proxyModel.blocked = false;
1694 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1697 private void clearNotebookFilter() {
1698 notebookTree.blockSignals(true);
1699 notebookTree.clearSelection();
1700 menuBar.noteRestoreAction.setVisible(false);
1701 menuBar.notebookEditAction.setEnabled(false);
1702 menuBar.notebookDeleteAction.setEnabled(false);
1703 selectedNotebookGUIDs.clear();
1704 searchField.setTargetNotebook("");
1705 searchField.setTargetStack("");
1706 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1707 notebookTree.blockSignals(false);
1709 // Triggered when the notebook DB has been updated
1710 private void notebookIndexUpdated() {
1711 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1713 // Get the possible icons
1714 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1715 notebookTree.setIcons(icons);
1717 if (selectedNotebookGUIDs == null)
1718 selectedNotebookGUIDs = new ArrayList<String>();
1719 List<Notebook> books = conn.getNotebookTable().getAll();
1720 for (int i=books.size()-1; i>=0; i--) {
1721 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1722 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1724 j=listManager.getArchiveNotebookIndex().size();
1730 listManager.countNotebookResults(listManager.getNoteIndex());
1731 notebookTree.blockSignals(true);
1732 notebookTree.load(books, listManager.getLocalNotebooks());
1733 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1734 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1736 selectedNotebookGUIDs.remove(i);
1737 searchField.setTargetNotebook("");
1738 searchField.setTargetStack("");
1741 listManager.refreshCounters = true;
1742 listManager.refreshCounters();
1743 notebookTree.blockSignals(false);
1745 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1747 // Show/Hide note information
1748 @SuppressWarnings("unused")
1749 private void toggleNotebookWindow() {
1750 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1751 zoomLayout.toggleNotebook();
1752 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1753 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1754 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1756 // Add a new notebook
1757 @SuppressWarnings("unused")
1758 private void addNotebook() {
1759 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1760 NotebookEdit edit = new NotebookEdit();
1761 edit.setNotebooks(listManager.getNotebookIndex());
1764 if (!edit.okPressed())
1767 Calendar currentTime = new GregorianCalendar();
1768 Long l = new Long(currentTime.getTimeInMillis());
1769 String randint = new String(Long.toString(l));
1771 Notebook newBook = new Notebook();
1772 newBook.setUpdateSequenceNum(0);
1773 newBook.setGuid(randint);
1774 newBook.setName(edit.getNotebook());
1775 newBook.setServiceCreated(new Date().getTime());
1776 newBook.setServiceUpdated(new Date().getTime());
1777 newBook.setDefaultNotebook(false);
1778 newBook.setPublished(false);
1780 listManager.getNotebookIndex().add(newBook);
1782 listManager.getLocalNotebooks().add(newBook.getGuid());
1783 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1784 notebookIndexUpdated();
1785 listManager.countNotebookResults(listManager.getNoteIndex());
1786 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1787 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1789 // Edit an existing notebook
1790 @SuppressWarnings("unused")
1791 private void stackNotebook() {
1792 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1793 StackNotebook edit = new StackNotebook();
1795 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1796 QTreeWidgetItem currentSelection;
1797 for (int i=0; i<selections.size(); i++) {
1798 currentSelection = selections.get(0);
1799 String guid = currentSelection.text(2);
1800 if (guid.equalsIgnoreCase("")) {
1801 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1804 if (guid.equalsIgnoreCase("STACK")) {
1805 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1810 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1815 if (!edit.okPressed())
1818 String stack = edit.getStackName();
1820 for (int i=0; i<selections.size(); i++) {
1821 currentSelection = selections.get(i);
1822 String guid = currentSelection.text(2);
1823 listManager.updateNotebookStack(guid, stack);
1825 notebookIndexUpdated();
1826 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1828 // Edit an existing notebook
1829 @SuppressWarnings("unused")
1830 private void editNotebook() {
1831 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1832 NotebookEdit edit = new NotebookEdit();
1834 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1835 QTreeWidgetItem currentSelection;
1836 currentSelection = selections.get(0);
1837 edit.setNotebook(currentSelection.text(0));
1839 String guid = currentSelection.text(2);
1840 if (!guid.equalsIgnoreCase("STACK")) {
1841 edit.setTitle(tr("Edit Notebook"));
1842 edit.setNotebooks(listManager.getNotebookIndex());
1843 edit.setLocalCheckboxEnabled(false);
1844 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1845 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1846 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1847 i=listManager.getNotebookIndex().size();
1851 edit.setTitle(tr("Edit Stack"));
1852 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1853 edit.hideLocalCheckbox();
1854 edit.hideDefaultCheckbox();
1859 if (!edit.okPressed())
1863 if (guid.equalsIgnoreCase("STACK")) {
1864 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1865 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1866 if (listManager.getNotebookIndex().get(j).getStack() != null &&
1867 listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1868 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1870 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1871 currentSelection.setText(0, edit.getNotebook());
1875 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1876 currentSelection.setText(0, edit.getNotebook());
1878 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1879 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1880 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1881 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1882 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1883 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1884 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1885 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1887 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1888 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1889 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1890 linkedNotebook.setShareName(edit.getNotebook());
1891 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1893 i=listManager.getNotebookIndex().size();
1897 // Build a list of non-closed notebooks
1898 List<Notebook> nbooks = new ArrayList<Notebook>();
1899 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1900 boolean found=false;
1901 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1902 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1906 nbooks.add(listManager.getNotebookIndex().get(i));
1910 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1911 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1912 browserWindow.setNotebookList(filteredBooks);
1913 Iterator<String> set = externalWindows.keySet().iterator();
1914 while(set.hasNext())
1915 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1917 Iterator<Integer>it = tabWindows.keySet().iterator();
1918 while (it.hasNext()) {
1919 tabWindows.get(it.next()).getBrowserWindow()
1920 .setNotebookList(filteredBooks);
1923 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1925 // Publish a notebook
1926 @SuppressWarnings("unused")
1927 private void publishNotebook() {
1928 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1929 QTreeWidgetItem currentSelection;
1930 currentSelection = selections.get(0);
1931 String guid = currentSelection.text(2);
1933 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1938 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1939 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1940 n = listManager.getNotebookIndex().get(i);
1942 i = listManager.getNotebookIndex().size();
1948 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1951 if (!publish.okClicked())
1954 Publishing p = publish.getPublishing();
1955 boolean isPublished = !publish.isStopPressed();
1956 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1957 n.setPublished(isPublished);
1959 listManager.getNotebookIndex().set(position, n);
1960 notebookIndexUpdated();
1962 // Publish a notebook
1963 @SuppressWarnings("unused")
1964 private void shareNotebook() {
1965 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1966 QTreeWidgetItem currentSelection;
1967 currentSelection = selections.get(0);
1968 String guid = currentSelection.text(2);
1970 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1974 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1975 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1976 n = listManager.getNotebookIndex().get(i);
1977 i = listManager.getNotebookIndex().size();
1981 String authToken = null;
1982 if (syncRunner.isConnected)
1983 authToken = syncRunner.authToken;
1984 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
1989 // Delete an existing notebook
1990 @SuppressWarnings("unused")
1991 private void deleteNotebook() {
1992 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
1993 boolean stacksFound = false;
1994 boolean notebooksFound = false;
1995 boolean assigned = false;
1996 // Check if any notes have this notebook
1997 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1998 for (int i=0; i<selections.size(); i++) {
1999 QTreeWidgetItem currentSelection;
2000 currentSelection = selections.get(i);
2001 String guid = currentSelection.text(2);
2002 if (!guid.equalsIgnoreCase("STACK")) {
2003 notebooksFound = true;
2004 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
2005 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
2006 if (noteGuid.equals(guid)) {
2008 j=listManager.getNoteIndex().size();
2009 i=selections.size();
2017 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2018 "Please delete the notes or move them to another notebook before deleting any notebooks."));
2022 if (conn.getNotebookTable().getAll().size() == 1) {
2023 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2027 // If all notebooks are clear, verify the delete
2028 String msg1 = new String(tr("Delete selected notebooks?"));
2029 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2030 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2031 " not deleted unless selected?"));
2033 if (stacksFound && notebooksFound)
2035 if (!stacksFound && notebooksFound)
2037 if (stacksFound && !notebooksFound)
2039 if (QMessageBox.question(this, tr("Confirmation"), msg,
2040 QMessageBox.StandardButton.Yes,
2041 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2045 // If confirmed, delete the notebook
2046 for (int i=selections.size()-1; i>=0; i--) {
2047 QTreeWidgetItem currentSelection;
2048 currentSelection = selections.get(i);
2049 String guid = currentSelection.text(2);
2050 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2051 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2052 listManager.renameStack(currentSelection.text(0), "");
2054 conn.getNotebookTable().expungeNotebook(guid, true);
2055 listManager.deleteNotebook(guid);
2059 notebookIndexUpdated();
2060 // notebookTreeSelection();
2061 // notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2062 // listManager.countNotebookResults(listManager.getNoteIndex());
2063 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2065 // A note's notebook has been updated
2066 @SuppressWarnings("unused")
2067 private void updateNoteNotebook(String guid, String notebookGuid) {
2068 // 同じノートブックに入れられたノート間の履歴を登録
2069 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2071 // Update the list manager
2072 listManager.updateNoteNotebook(guid, notebookGuid);
2073 listManager.countNotebookResults(listManager.getNoteIndex());
2074 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
2076 // Find the name of the notebook
2077 String notebookName = null;
2078 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2079 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2080 notebookName = listManager.getNotebookIndex().get(i).getName();
2085 // If we found the name, update the browser window
2086 if (notebookName != null) {
2087 updateListNoteNotebook(guid, notebookName);
2088 if (guid.equals(currentNoteGuid)) {
2089 int pos = browserWindow.notebookBox.findText(notebookName);
2091 browserWindow.notebookBox.setCurrentIndex(pos);
2095 // If we're dealing with the current note, then we need to be sure and update the notebook there
2096 if (guid.equals(currentNoteGuid)) {
2097 if (currentNote != null) {
2098 currentNote.setNotebookGuid(notebookGuid);
2102 // Open/close notebooks
2103 @SuppressWarnings("unused")
2104 private void closeNotebooks() {
2105 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2107 if (!na.okClicked())
2111 listManager.getArchiveNotebookIndex().clear();
2113 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2114 String text = na.getClosedBookList().takeItem(i).text();
2115 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2116 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2117 Notebook n = listManager.getNotebookIndex().get(j);
2118 conn.getNotebookTable().setArchived(n.getGuid(),true);
2119 listManager.getArchiveNotebookIndex().add(n);
2120 j=listManager.getNotebookIndex().size();
2125 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2126 String text = na.getOpenBookList().takeItem(i).text();
2127 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2128 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2129 Notebook n = listManager.getNotebookIndex().get(j);
2130 conn.getNotebookTable().setArchived(n.getGuid(),false);
2131 j=listManager.getNotebookIndex().size();
2135 notebookTreeSelection();
2136 listManager.loadNotesIndex();
2137 notebookIndexUpdated();
2138 noteIndexUpdated(false);
2139 reloadTagTree(true);
2140 // noteIndexUpdated(false);
2142 // Build a list of non-closed notebooks
2143 List<Notebook> nbooks = new ArrayList<Notebook>();
2144 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2145 boolean found=false;
2146 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2147 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2151 nbooks.add(listManager.getNotebookIndex().get(i));
2154 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2155 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2156 browserWindow.setNotebookList(filteredBooks);
2158 // Update any external windows
2159 Iterator<String> set = externalWindows.keySet().iterator();
2160 while(set.hasNext())
2161 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2164 Iterator<Integer> it = tabWindows.keySet().iterator();
2165 while (it.hasNext()) {
2166 tabWindows.get(it.next()).getBrowserWindow()
2167 .setNotebookList(filteredBooks);
2172 // Change the notebook's icon
2173 @SuppressWarnings("unused")
2174 private void setNotebookIcon() {
2175 boolean stackSelected = false;
2176 boolean allNotebookSelected = false;
2178 QTreeWidgetItem currentSelection;
2179 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2180 if (selections.size() == 0)
2183 currentSelection = selections.get(0);
2184 String guid = currentSelection.text(2);
2185 if (guid.equalsIgnoreCase(""))
2186 allNotebookSelected = true;
2187 if (guid.equalsIgnoreCase("STACK"))
2188 stackSelected = true;
2190 QIcon currentIcon = currentSelection.icon(0);
2194 if (!stackSelected && !allNotebookSelected) {
2195 icon = conn.getNotebookTable().getIcon(guid);
2197 dialog = new SetIcon(currentIcon, saveLastPath);
2198 dialog.setUseDefaultIcon(true);
2200 dialog = new SetIcon(icon, saveLastPath);
2201 dialog.setUseDefaultIcon(false);
2204 if (stackSelected) {
2205 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2207 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
2210 dialog = new SetIcon(currentIcon, saveLastPath);
2211 dialog.setUseDefaultIcon(true);
2213 dialog = new SetIcon(icon, saveLastPath);
2214 dialog.setUseDefaultIcon(false);
2218 if (dialog.okPressed()) {
2219 saveLastPath = dialog.getPath();
2221 QIcon newIcon = dialog.getIcon();
2222 if (stackSelected) {
2223 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2224 if (newIcon == null) {
2225 newIcon = new QIcon(iconPath+"books2.png");
2227 currentSelection.setIcon(0,newIcon);
2230 if (allNotebookSelected) {
2231 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2232 if (newIcon == null) {
2233 newIcon = new QIcon(iconPath+"notebook-green.png");
2235 currentSelection.setIcon(0,newIcon);
2238 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2239 if (newIcon == null) {
2240 boolean isPublished = false;;
2241 boolean found = false;
2242 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2243 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2244 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2248 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2250 currentSelection.setIcon(0, newIcon);
2256 //***************************************************************
2257 //***************************************************************
2258 //** These functions deal with Tag menu items
2259 //***************************************************************
2260 //***************************************************************
2261 // Add a new notebook
2262 @SuppressWarnings("unused")
2263 private void addTag() {
2264 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2265 TagEdit edit = new TagEdit();
2266 edit.setTagList(listManager.getTagIndex());
2268 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2269 QTreeWidgetItem currentSelection = null;
2270 if (selections.size() > 0) {
2271 currentSelection = selections.get(0);
2272 edit.setParentTag(currentSelection.text(0));
2277 if (!edit.okPressed())
2280 Calendar currentTime = new GregorianCalendar();
2281 Long l = new Long(currentTime.getTimeInMillis());
2282 String randint = new String(Long.toString(l));
2284 Tag newTag = new Tag();
2285 newTag.setUpdateSequenceNum(0);
2286 newTag.setGuid(randint);
2287 newTag.setName(edit.getTag());
2288 if (edit.getParentTag().isChecked()) {
2289 newTag.setParentGuid(currentSelection.text(2));
2290 newTag.setParentGuidIsSet(true);
2291 currentSelection.setExpanded(true);
2293 conn.getTagTable().addTag(newTag, true);
2294 listManager.getTagIndex().add(newTag);
2295 reloadTagTree(true);
2297 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2299 @SuppressWarnings("unused")
2300 private void reloadTagTree() {
2301 reloadTagTree(false);
2303 private void reloadTagTree(boolean reload) {
2304 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2305 tagIndexUpdated(reload);
2306 boolean filter = false;
2308 listManager.countTagResults(listManager.getNoteIndex());
2309 if (notebookTree.selectedItems().size() > 0
2310 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2312 if (tagTree.selectedItems().size() > 0)
2314 tagTree.showAllTags(!filter);
2315 tagIndexUpdated(false);
2316 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2318 // Edit an existing tag
2319 @SuppressWarnings("unused")
2320 private void editTag() {
2321 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2322 TagEdit edit = new TagEdit();
2323 edit.setTitle("Edit Tag");
2324 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2325 QTreeWidgetItem currentSelection;
2326 currentSelection = selections.get(0);
2327 edit.setTag(currentSelection.text(0));
2328 edit.setTagList(listManager.getTagIndex());
2331 if (!edit.okPressed())
2334 String guid = currentSelection.text(2);
2335 currentSelection.setText(0,edit.getTag());
2337 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2338 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2339 listManager.getTagIndex().get(i).setName(edit.getTag());
2340 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2341 updateListTagName(guid);
2342 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2343 browserWindow.setTag(getTagNamesForNote(currentNote));
2344 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2348 listManager.reloadNoteTagNames(guid, edit.getTag());
2349 noteIndexUpdated(true);
2350 refreshEvernoteNote(true);
2351 browserWindow.setTag(getTagNamesForNote(currentNote));
2352 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2354 // Delete an existing tag
2355 @SuppressWarnings("unused")
2356 private void deleteTag() {
2357 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2359 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2360 QMessageBox.StandardButton.Yes,
2361 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2365 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2366 for (int i=selections.size()-1; i>=0; i--) {
2367 QTreeWidgetItem currentSelection;
2368 currentSelection = selections.get(i);
2369 removeTagItem(currentSelection.text(2));
2371 tagIndexUpdated(true);
2373 listManager.countTagResults(listManager.getNoteIndex());
2374 // tagTree.updateCounts(listManager.getTagCounter());
2375 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2377 // Remove a tag tree item. Go recursively down & remove the children too
2378 private void removeTagItem(String guid) {
2379 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
2380 String parent = listManager.getTagIndex().get(j).getParentGuid();
2381 if (parent != null && parent.equals(guid)) {
2382 //Remove this tag's children
2383 removeTagItem(listManager.getTagIndex().get(j).getGuid());
2386 //Now, remove this tag
2387 removeListTagName(guid);
2388 conn.getTagTable().expungeTag(guid, true);
2389 for (int a=0; a<listManager.getTagIndex().size(); a++) {
2390 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2391 listManager.getTagIndex().remove(a);
2396 // Setup the tree containing the user's tags
2397 private void initializeTagTree() {
2398 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2399 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2400 // tagTree.itemClicked.connect(this, "tagTreeSelection()");
2401 tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2402 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2403 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2405 // Listener when a tag is selected
2406 private void tagTreeSelection() {
2407 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2410 clearAttributeFilter();
2411 clearSavedSearchFilter();
2413 menuBar.noteRestoreAction.setVisible(false);
2415 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2416 if (!rensoNoteListDock.isEnabled()) {
2417 rensoNoteListDock.setEnabled(true);
2420 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2421 QTreeWidgetItem currentSelection;
2422 selectedTagGUIDs.clear();
2423 searchField.getTargetTags().clear();
2424 for (int i=0; i<selections.size(); i++) {
2425 currentSelection = selections.get(i);
2426 selectedTagGUIDs.add(currentSelection.text(2));
2427 searchField.addTargetTag(currentSelection.text(2));
2429 if (selections.size() > 0) {
2430 menuBar.tagEditAction.setEnabled(true);
2431 menuBar.tagDeleteAction.setEnabled(true);
2432 menuBar.tagIconAction.setEnabled(true);
2435 menuBar.tagEditAction.setEnabled(false);
2436 menuBar.tagDeleteAction.setEnabled(false);
2437 menuBar.tagIconAction.setEnabled(true);
2439 if (selections.size() > 1)
2440 menuBar.tagMergeAction.setEnabled(true);
2442 menuBar.tagMergeAction.setEnabled(false);
2443 listManager.setSelectedTags(selectedTagGUIDs);
2444 listManager.loadNotesIndex();
2445 noteIndexUpdated(false);
2446 refreshEvernoteNote(true);
2447 listManager.refreshCounters = true;
2448 listManager.refreshCounters();
2449 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2451 // trigger the tag index to be refreshed
2452 @SuppressWarnings("unused")
2453 private void tagIndexUpdated() {
2454 tagIndexUpdated(true);
2456 private void tagIndexUpdated(boolean reload) {
2457 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2458 if (selectedTagGUIDs == null)
2459 selectedTagGUIDs = new ArrayList<String>();
2461 listManager.reloadTagIndex();
2463 tagTree.blockSignals(true);
2465 tagTree.setIcons(conn.getTagTable().getAllIcons());
2466 tagTree.load(listManager.getTagIndex());
2469 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2470 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2472 selectedTagGUIDs.remove(i);
2473 searchField.getTargetTags().remove(i);
2476 tagTree.blockSignals(false);
2478 browserWindow.setTag(getTagNamesForNote(currentNote));
2479 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2481 // Show/Hide note information
2482 @SuppressWarnings("unused")
2483 private void toggleTagWindow() {
2484 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2485 if (tagTree.isVisible())
2489 menuBar.hideTags.setChecked(tagTree.isVisible());
2490 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2491 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2493 // A note's tags have been updated
2494 @SuppressWarnings("unused")
2495 private void updateNoteTags(String guid, List<String> tags) {
2496 // Save any new tags. We'll need them later.
2497 List<String> newTags = new ArrayList<String>();
2498 for (int i=0; i<tags.size(); i++) {
2499 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2500 newTags.add(tags.get(i));
2503 listManager.saveNoteTags(guid, tags, true);
2504 listManager.countTagResults(listManager.getNoteIndex());
2505 StringBuffer names = new StringBuffer("");
2506 for (int i=0; i<tags.size(); i++) {
2507 names = names.append(tags.get(i));
2508 if (i<tags.size()-1) {
2509 names.append(Global.tagDelimeter + " ");
2512 browserWindow.setTag(names.toString());
2514 for (TabBrowse tab: tabWindows.values()) {
2515 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
2516 int index = tabBrowser.indexOf(tab);
2517 noteDirty.put(index, true);
2522 // Now, we need to add any new tags to the tag tree
2523 for (int i=0; i<newTags.size(); i++)
2524 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2526 // Get a string containing all tag names for a note
2527 private String getTagNamesForNote(Note n) {
2528 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2529 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2531 StringBuffer buffer = new StringBuffer(100);
2532 Vector<String> v = new Vector<String>();
2533 List<String> guids = n.getTagGuids();
2538 for (int i=0; i<guids.size(); i++) {
2539 v.add(listManager.getTagNameByGuid(guids.get(i)));
2541 Comparator<String> comparator = Collections.reverseOrder();
2542 Collections.sort(v,comparator);
2543 Collections.reverse(v);
2545 for (int i = 0; i<v.size(); i++) {
2547 buffer.append(", ");
2548 buffer.append(v.get(i));
2551 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2552 return buffer.toString();
2554 // Tags were added via dropping notes from the note list
2555 @SuppressWarnings("unused")
2556 private void tagsAdded(String noteGuid, String tagGuid) {
2557 String tagName = null;
2558 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2559 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2560 tagName = listManager.getTagIndex().get(i).getName();
2561 i=listManager.getTagIndex().size();
2564 if (tagName == null)
2567 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2568 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2569 List<String> tagNames = new ArrayList<String>();
2570 tagNames.add(new String(tagName));
2571 Note n = listManager.getMasterNoteIndex().get(i);
2572 for (int j=0; j<n.getTagNames().size(); j++) {
2573 tagNames.add(new String(n.getTagNames().get(j)));
2575 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2576 if (n.getGuid().equals(currentNoteGuid)) {
2577 Collections.sort(tagNames);
2578 String display = "";
2579 for (int j=0; j<tagNames.size(); j++) {
2580 display = display+tagNames.get(j);
2581 if (j+2<tagNames.size())
2582 display = display+Global.tagDelimeter+" ";
2584 browserWindow.setTag(display);
2586 i=listManager.getMasterNoteIndex().size();
2591 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2593 private void clearTagFilter() {
2594 tagTree.blockSignals(true);
2595 tagTree.clearSelection();
2596 menuBar.noteRestoreAction.setVisible(false);
2597 menuBar.tagEditAction.setEnabled(false);
2598 menuBar.tagMergeAction.setEnabled(false);
2599 menuBar.tagDeleteAction.setEnabled(false);
2600 menuBar.tagIconAction.setEnabled(false);
2601 selectedTagGUIDs.clear();
2602 searchField.getTargetTags().clear();
2603 listManager.setSelectedTags(selectedTagGUIDs);
2604 tagTree.blockSignals(false);
2606 // Change the icon for a tag
2607 @SuppressWarnings("unused")
2608 private void setTagIcon() {
2609 QTreeWidgetItem currentSelection;
2610 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2611 if (selections.size() == 0)
2614 currentSelection = selections.get(0);
2615 String guid = currentSelection.text(2);
2617 QIcon currentIcon = currentSelection.icon(0);
2618 QIcon icon = conn.getTagTable().getIcon(guid);
2621 dialog = new SetIcon(currentIcon, saveLastPath);
2622 dialog.setUseDefaultIcon(true);
2624 dialog = new SetIcon(icon, saveLastPath);
2625 dialog.setUseDefaultIcon(false);
2628 if (dialog.okPressed()) {
2629 saveLastPath = dialog.getPath();
2630 QIcon newIcon = dialog.getIcon();
2631 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2632 if (newIcon == null)
2633 newIcon = new QIcon(iconPath+"tag.png");
2634 currentSelection.setIcon(0, newIcon);
2639 @SuppressWarnings("unused")
2640 private void mergeTags() {
2641 List<Tag> tags = new ArrayList<Tag>();
2642 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2643 for (int i=0; i<selections.size(); i++) {
2644 Tag record = new Tag();
2645 record.setGuid(selections.get(i).text(2));
2646 record.setName(selections.get(i).text(0));
2650 TagMerge mergeDialog = new TagMerge(tags);
2652 if (!mergeDialog.okClicked())
2654 String newGuid = mergeDialog.getNewTagGuid();
2656 for (int i=0; i<tags.size(); i++) {
2657 if (!tags.get(i).getGuid().equals(newGuid)) {
2658 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2659 for (int j=0; j<noteGuids.size(); j++) {
2660 String noteGuid = noteGuids.get(j);
2661 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2662 if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2663 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2667 listManager.reloadIndexes();
2670 //***************************************************************
2671 //***************************************************************
2672 //** These functions deal with Saved Search menu items
2673 //***************************************************************
2674 //***************************************************************
2675 // Add a new notebook
2676 @SuppressWarnings("unused")
2677 private void addSavedSearch() {
2678 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2679 SavedSearchEdit edit = new SavedSearchEdit();
2680 edit.setSearchList(listManager.getSavedSearchIndex());
2683 if (!edit.okPressed())
2686 Calendar currentTime = new GregorianCalendar();
2687 Long l = new Long(currentTime.getTimeInMillis());
2688 String randint = new String(Long.toString(l));
2690 SavedSearch search = new SavedSearch();
2691 search.setUpdateSequenceNum(0);
2692 search.setGuid(randint);
2693 search.setName(edit.getName());
2694 search.setQuery(edit.getQuery());
2695 search.setFormat(QueryFormat.USER);
2696 listManager.getSavedSearchIndex().add(search);
2697 conn.getSavedSearchTable().addSavedSearch(search, true);
2698 savedSearchIndexUpdated();
2699 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2701 // Edit an existing tag
2702 @SuppressWarnings("unused")
2703 private void editSavedSearch() {
2704 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2705 SavedSearchEdit edit = new SavedSearchEdit();
2706 edit.setTitle(tr("Edit Search"));
2707 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2708 QTreeWidgetItem currentSelection;
2709 currentSelection = selections.get(0);
2710 String guid = currentSelection.text(1);
2711 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2712 edit.setName(currentSelection.text(0));
2713 edit.setQuery(s.getQuery());
2714 edit.setSearchList(listManager.getSavedSearchIndex());
2717 if (!edit.okPressed())
2720 List<SavedSearch> list = listManager.getSavedSearchIndex();
2721 SavedSearch search = null;
2722 boolean found = false;
2723 for (int i=0; i<list.size(); i++) {
2724 search = list.get(i);
2725 if (search.getGuid().equals(guid)) {
2732 search.setName(edit.getName());
2733 search.setQuery(edit.getQuery());
2734 conn.getSavedSearchTable().updateSavedSearch(search, true);
2735 savedSearchIndexUpdated();
2736 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2738 // Delete an existing tag
2739 @SuppressWarnings("unused")
2740 private void deleteSavedSearch() {
2741 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2743 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2744 QMessageBox.StandardButton.Yes,
2745 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2749 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2750 for (int i=selections.size()-1; i>=0; i--) {
2751 QTreeWidgetItem currentSelection;
2752 currentSelection = selections.get(i);
2753 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2754 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2755 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2756 listManager.getSavedSearchIndex().remove(j);
2757 j=listManager.getSavedSearchIndex().size()+1;
2760 selections.remove(i);
2762 savedSearchIndexUpdated();
2763 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2765 // Setup the tree containing the user's tags
2766 private void initializeSavedSearchTree() {
2767 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2768 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2769 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2771 // Listener when a tag is selected
2772 @SuppressWarnings("unused")
2773 private void savedSearchTreeSelection() {
2774 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2776 clearNotebookFilter();
2779 clearAttributeFilter();
2781 String currentGuid = selectedSavedSearchGUID;
2782 menuBar.savedSearchEditAction.setEnabled(true);
2783 menuBar.savedSearchDeleteAction.setEnabled(true);
2784 menuBar.savedSearchIconAction.setEnabled(true);
2786 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2787 if (!rensoNoteListDock.isEnabled()) {
2788 rensoNoteListDock.setEnabled(true);
2791 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2792 QTreeWidgetItem currentSelection;
2793 selectedSavedSearchGUID = "";
2794 for (int i=0; i<selections.size(); i++) {
2795 currentSelection = selections.get(i);
2796 if (currentSelection.text(1).equals(currentGuid)) {
2797 currentSelection.setSelected(false);
2799 selectedSavedSearchGUID = currentSelection.text(1);
2801 // i = selections.size() +1;
2804 // There is the potential for no notebooks to be selected if this
2805 // happens then we make it look like all notebooks were selecetd.
2806 // If that happens, just select the "all notebooks"
2807 if (selections.size()==0) {
2808 clearSavedSearchFilter();
2810 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2812 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2814 private void clearSavedSearchFilter() {
2815 menuBar.savedSearchEditAction.setEnabled(false);
2816 menuBar.savedSearchDeleteAction.setEnabled(false);
2817 menuBar.savedSearchIconAction.setEnabled(false);
2818 savedSearchTree.blockSignals(true);
2819 savedSearchTree.clearSelection();
2820 savedSearchTree.blockSignals(false);
2821 selectedSavedSearchGUID = "";
2822 searchField.setText("");
2823 searchPerformed = false;
2824 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2826 // trigger the tag index to be refreshed
2827 private void savedSearchIndexUpdated() {
2828 if (selectedSavedSearchGUID == null)
2829 selectedSavedSearchGUID = new String();
2830 savedSearchTree.blockSignals(true);
2831 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2832 savedSearchTree.load(listManager.getSavedSearchIndex());
2833 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2834 savedSearchTree.blockSignals(false);
2836 // trigger when the saved search selection changes
2837 @SuppressWarnings("unused")
2838 private void updateSavedSearchSelection() {
2839 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2841 menuBar.savedSearchEditAction.setEnabled(true);
2842 menuBar.savedSearchDeleteAction.setEnabled(true);
2843 menuBar.savedSearchIconAction.setEnabled(true);
2844 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2846 if (selections.size() > 0) {
2847 menuBar.savedSearchEditAction.setEnabled(true);
2848 menuBar.savedSearchDeleteAction.setEnabled(true);
2849 menuBar.savedSearchIconAction.setEnabled(true);
2850 selectedSavedSearchGUID = selections.get(0).text(1);
2851 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2852 searchField.setText(s.getQuery());
2854 menuBar.savedSearchEditAction.setEnabled(false);
2855 menuBar.savedSearchDeleteAction.setEnabled(false);
2856 menuBar.savedSearchIconAction.setEnabled(false);
2857 selectedSavedSearchGUID = "";
2858 searchField.setText("");
2860 searchFieldChanged();
2862 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2866 // Show/Hide note information
2867 @SuppressWarnings("unused")
2868 private void toggleSavedSearchWindow() {
2869 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2870 if (savedSearchTree.isVisible())
2871 savedSearchTree.hide();
2873 savedSearchTree.show();
2874 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2876 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2877 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2879 // Change the icon for a saved search
2880 @SuppressWarnings("unused")
2881 private void setSavedSearchIcon() {
2882 QTreeWidgetItem currentSelection;
2883 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2884 if (selections.size() == 0)
2887 currentSelection = selections.get(0);
2888 String guid = currentSelection.text(1);
2890 QIcon currentIcon = currentSelection.icon(0);
2891 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2894 dialog = new SetIcon(currentIcon, saveLastPath);
2895 dialog.setUseDefaultIcon(true);
2897 dialog = new SetIcon(icon, saveLastPath);
2898 dialog.setUseDefaultIcon(false);
2901 if (dialog.okPressed()) {
2902 saveLastPath = dialog.getPath();
2903 QIcon newIcon = dialog.getIcon();
2904 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2905 if (newIcon == null)
2906 newIcon = new QIcon(iconPath+"search.png");
2907 currentSelection.setIcon(0, newIcon);
2915 //***************************************************************
2916 //***************************************************************
2917 //** These functions deal with Help menu & tool menu items
2918 //***************************************************************
2919 //***************************************************************
2920 // Show database status
2921 @SuppressWarnings("unused")
2922 private void databaseStatus() {
2924 indexRunner.interrupt = true;
2925 int dirty = conn.getNoteTable().getDirtyCount();
2926 int unindexed = conn.getNoteTable().getUnindexedCount();
2927 DatabaseStatus status = new DatabaseStatus();
2928 status.setUnsynchronized(dirty);
2929 status.setUnindexed(unindexed);
2930 status.setNoteCount(conn.getNoteTable().getNoteCount());
2931 status.setNotebookCount(listManager.getNotebookIndex().size());
2932 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2933 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2934 status.setTagCount(listManager.getTagIndex().size());
2935 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2936 status.setWordCount(conn.getWordsTable().getWordCount());
2937 status.setHistoryCount(conn.getHistoryTable().getHistoryCount());
2938 status.setRensoClickCount(conn.getHistoryTable().getRensoClickCount());
2942 // Compact the database
2943 @SuppressWarnings("unused")
2944 private void compactDatabase() {
2945 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2946 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2947 "but please be aware that depending upon the size of your database this can be time consuming " +
2948 "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
2949 QMessageBox.StandardButton.Yes,
2950 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2953 setMessage("Compacting database.");
2955 listManager.compactDatabase();
2957 setMessage("Database compact is complete.");
2958 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2960 @SuppressWarnings("unused")
2961 private void accountInformation() {
2962 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2963 AccountDialog dialog = new AccountDialog();
2965 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2967 @SuppressWarnings("unused")
2968 private void releaseNotes() {
2969 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
2970 QDialog dialog = new QDialog(this);
2971 QHBoxLayout layout = new QHBoxLayout();
2972 QTextEdit textBox = new QTextEdit();
2973 layout.addWidget(textBox);
2974 textBox.setReadOnly(true);
2975 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
2976 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
2977 QIODevice.OpenModeFlag.Text)))
2980 QTextCodec codec = QTextCodec.codecForName("UTF-8");
2981 QTextStream textStream = new QTextStream(file);
2982 textStream.setCodec(codec);
2983 textBox.setText(textStream.readAll().toString());
2986 dialog.setWindowTitle(tr("Release Notes"));
2987 dialog.setLayout(layout);
2989 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
2991 // Called when user picks Log from the help menu
2992 @SuppressWarnings("unused")
2993 private void logger() {
2994 logger.log(logger.HIGH, "Entering NeverNote.logger");
2995 LogFileDialog dialog = new LogFileDialog(emitLog);
2997 logger.log(logger.HIGH, "Leaving NeverNote.logger");
2999 // Menu option "help/about" was selected
3000 @SuppressWarnings("unused")
3001 private void about() {
3002 logger.log(logger.HIGH, "Entering NeverNote.about");
3003 QMessageBox.about(this,
3004 tr("About NeighborNote"),
3005 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
3006 +Global.version + "(based on NixNote 1.6)"
3009 +"Open Source Evernote Client.<br><br>"
3010 +"Licensed under GPL v2. <br><hr><br>"
3011 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
3012 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
3013 +"PDFRenderer is licened under the LGPL<br>"
3014 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3015 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3016 +"Jazzy is licened under the LGPL<br>"
3017 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3018 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3019 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3020 logger.log(logger.HIGH, "Leaving NeverNote.about");
3022 // Hide the entire left hand side
3023 @SuppressWarnings("unused")
3024 private void toggleLeftSide() {
3027 hidden = !menuBar.hideLeftSide.isChecked();
3028 menuBar.hideLeftSide.setChecked(!hidden);
3031 leftSplitter1.setHidden(true);
3033 leftSplitter1.setHidden(false);
3035 Global.saveWindowVisible("leftPanel", hidden);
3038 public void checkForUpdates() {
3039 // Send off thread to check for a new version
3040 versionChecker = new QNetworkAccessManager(this);
3041 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3042 QNetworkRequest request = new QNetworkRequest();
3043 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3044 versionChecker.get(request);
3046 @SuppressWarnings("unused")
3047 private void upgradeFileRead(QNetworkReply reply) {
3048 if (!reply.isReadable())
3051 String winVersion = Global.version;
3052 String osxVersion = Global.version;
3053 String linuxVersion = Global.version;
3054 String linux64Version = Global.version;
3055 String version = Global.version;
3057 // Determine the versions available
3058 QByteArray data = reply.readLine();
3059 while (data != null && !reply.atEnd()) {
3060 String line = data.toString();
3062 if (line.contains(":"))
3063 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3066 if (line.toLowerCase().contains("windows"))
3067 winVersion = lineVersion;
3068 else if (line.toLowerCase().contains("os-x"))
3069 osxVersion = lineVersion;
3070 else if (line.toLowerCase().contains("linux amd64"))
3071 linux64Version = lineVersion;
3072 else if (line.toLowerCase().contains("linux i386"))
3073 linuxVersion = lineVersion;
3074 else if (line.toLowerCase().contains("default"))
3075 version = lineVersion;
3077 // Read the next line
3078 data = reply.readLine();
3081 // Now we need to determine what system we are on.
3082 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3083 version = winVersion;
3084 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3085 version = osxVersion;
3086 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3087 if (System.getProperty("os.arch").contains("amd64") ||
3088 System.getProperty("os.arch").contains("x86_64"))
3089 version = linux64Version;
3091 version = linuxVersion;
3095 for (String validVersion : Global.validVersions) {
3096 if (version.equals(validVersion))
3100 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3102 if (dialog.remindMe())
3103 Global.setCheckVersionUpgrade(true);
3105 Global.setCheckVersionUpgrade(false);
3109 //***************************************************************
3110 //***************************************************************
3111 //** These functions deal with the Toolbar
3112 //***************************************************************
3113 //***************************************************************
3114 @SuppressWarnings("unused")
3115 private void focusSearch() {
3116 searchField.setFocus();
3119 // Text in the search bar has been cleared
3120 private void searchFieldCleared() {
3123 // This is done because we want to force a reload of
3124 // images. Some images we may want to highlight the text.
3125 readOnlyCache.clear();
3126 inkNoteCache.clear();
3128 QWebSettings.setMaximumPagesInCache(0);
3129 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3131 searchField.setDefaultText();
3132 saveNoteColumnPositions();
3133 saveNoteIndexWidth();
3134 noteIndexUpdated(true);
3135 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3136 currentNote = listManager.getNoteIndex().get(0);
3137 currentNoteGuid = currentNote.getGuid();
3139 refreshEvernoteNote(true);
3140 if (currentNote != null)
3141 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3143 // text in the search bar changed. We only use this to tell if it was cleared,
3144 // otherwise we trigger off searchFieldChanged.
3145 @SuppressWarnings("unused")
3146 private void searchFieldTextChanged(String text) {
3147 QWebSettings.setMaximumPagesInCache(0);
3148 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3150 if (text.trim().equals("") && !searchField.hasFocus()) {
3151 searchFieldCleared();
3152 if (searchPerformed) {
3154 // This is done because we want to force a reload of
3155 // images. Some images we may want to highlight the text.
3157 readOnlyCache.clear();
3158 inkNoteCache.clear();
3160 listManager.setEnSearch("");
3161 listManager.loadNotesIndex();
3162 refreshEvernoteNote(true);
3163 noteIndexUpdated(false);
3164 refreshEvernoteNote(true);
3166 searchPerformed = false;
3169 // Text in the toolbar has changed
3170 private void searchFieldChanged() {
3171 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3173 readOnlyCache.clear();
3174 inkNoteCache.clear();
3175 saveNoteColumnPositions();
3176 saveNoteIndexWidth();
3177 String query = searchField.getSearchQuery();
3178 listManager.setEnSearch(query.trim());
3179 listManager.loadNotesIndex();
3180 noteIndexUpdated(false);
3182 refreshEvernoteNote(true);
3183 searchPerformed = true;
3185 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3188 // Build the window tool bar
3189 private void setupToolBar() {
3190 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3191 toolBar = addToolBar(tr("Tool Bar"));
3192 toolBar.setObjectName("toolBar");
3193 toolBar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon);
3194 menuBar.setupToolBarVisible();
3195 if (!Global.isWindowVisible("toolBar"))
3196 toolBar.setVisible(false);
3198 toolBar.setVisible(true);
3200 // toolBar.addWidget(menuBar);
3201 // menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3202 // toolBar.addSeparator();
3203 prevButton = toolBar.addAction(tr(""));
3204 prevButton.setToolTip(tr("Previous"));
3205 QIcon prevIcon = new QIcon(iconPath+"back.png");
3206 prevButton.setIcon(prevIcon);
3207 prevButton.triggered.connect(this, "previousViewedAction()");
3208 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow", true));
3210 nextButton = toolBar.addAction(tr(""));
3211 nextButton.setToolTip(tr("Next"));
3212 QIcon nextIcon = new QIcon(iconPath+"forward.png");
3213 nextButton.setIcon(nextIcon);
3214 nextButton.triggered.connect(this, "nextViewedAction()");
3215 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow", true));
3217 toolBar.addSeparator();
3219 upButton = toolBar.addAction(tr("Up"));
3220 QIcon upIcon = new QIcon(iconPath+"up.png");
3221 upButton.setIcon(upIcon);
3222 upButton.triggered.connect(this, "upAction()");
3223 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow", false));
3226 downButton = toolBar.addAction(tr("Down"));
3227 QIcon downIcon = new QIcon(iconPath+"down.png");
3228 downButton.setIcon(downIcon);
3229 downButton.triggered.connect(this, "downAction()");
3230 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow", false));
3232 synchronizeButton = toolBar.addAction(tr("Synchronize"));
3233 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3234 synchronizeIconAngle = 0;
3235 synchronizeButton.triggered.connect(this, "evernoteSync()");
3236 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize", true));
3238 printButton = toolBar.addAction(tr("Print"));
3239 QIcon printIcon = new QIcon(iconPath+"print.png");
3240 printButton.setIcon(printIcon);
3241 printButton.triggered.connect(this, "printNote()");
3242 togglePrintButton(Global.isToolbarButtonVisible("print", false));
3244 tagButton = toolBar.addAction(tr("Tag"));
3245 QIcon tagIcon = new QIcon(iconPath+"tag.png");
3246 tagButton.setIcon(tagIcon);
3247 tagButton.triggered.connect(browserWindow, "modifyTags()");
3248 toggleTagButton(Global.isToolbarButtonVisible("tag", false));
3250 attributeButton = toolBar.addAction(tr("Attributes"));
3251 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3252 attributeButton.setIcon(attributeIcon);
3253 attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3254 toggleAttributeButton(Global.isToolbarButtonVisible("attribute", true));
3256 emailButton = toolBar.addAction(tr("Email"));
3257 QIcon emailIcon = new QIcon(iconPath+"email.png");
3258 emailButton.setIcon(emailIcon);
3259 emailButton.triggered.connect(this, "emailNote()");
3260 toggleEmailButton(Global.isToolbarButtonVisible("email", false));
3262 deleteButton = toolBar.addAction(tr("Delete"));
3263 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3264 deleteButton.setIcon(deleteIcon);
3265 deleteButton.triggered.connect(this, "deleteNote()");
3266 toggleDeleteButton(Global.isToolbarButtonVisible("delete", true));
3268 newButton = toolBar.addAction(tr("New"));
3269 QIcon newIcon = new QIcon(iconPath+"new.png");
3270 if (Global.toolBarNewAction()) {
3271 newButton.triggered.connect(this, "noteAddNewTab()");
3273 newButton.triggered.connect(this, "addNote()");
3276 newButton.setIcon(newIcon);
3277 toggleNewButton(Global.isToolbarButtonVisible("new", true));
3279 allNotesButton = toolBar.addAction(tr("All Notes"));
3280 QIcon allIcon = new QIcon(iconPath+"books.png");
3281 allNotesButton.triggered.connect(this, "allNotes()");
3282 allNotesButton.setIcon(allIcon);
3283 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes", true));
3285 //toolBar.addSeparator();
3286 //toolBar.addWidget(new QLabel(tr("Quota:")));
3287 //toolBar.addWidget(quotaBar);
3288 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3290 //toolBar.addSeparator();
3292 //toolBar.addWidget(new QLabel(tr("Zoom")));
3293 //toolBar.addWidget(zoomSpinner);
3295 //toolBar.addWidget(new QLabel(" "));
3296 //toolBar.addSeparator();
3298 // 検索ボックスを右寄せするためのスペーサ
3299 QWidget spacerWidget = new QWidget();
3300 spacerWidget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred);
3301 toolBar.addWidget(spacerWidget);
3302 spacerWidget.setVisible(true);
3304 searchField = new SearchEdit(iconPath, conn);
3305 searchField.setObjectName("searchField");
3306 searchField.returnPressed.connect(this, "searchFieldChanged()");
3307 searchField.textChanged.connect(this,"searchFieldTextChanged(String)");
3308 searchField.setMaximumWidth(400);
3309 searchField.setMinimumWidth(80);
3310 searchField.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed);
3311 searchShortcut = new QShortcut(this);
3312 setupShortcut(searchShortcut, "Focus_Search");
3313 searchShortcut.activated.connect(this, "focusSearch()");
3314 toolBar.addWidget(searchField);
3316 searchField.setVisible(Global.isWindowVisible("searchField"));
3317 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
3318 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
3319 if (!Global.isWindowVisible("searchField"))
3320 menuBar.hideSearch.setChecked(false);
3322 // QSizePolicy sizePolicy = new QSizePolicy();
3323 // sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3324 // QLabel spacer = new QLabel("");
3325 // spacer.setSizePolicy(sizePolicy);
3326 // toolBar.addWidget(spacer);
3328 //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3330 //searchClearButton = toolBar.addAction("Search Clear");
3331 //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3332 //searchClearButton.setIcon(searchClearIcon);
3333 //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3334 //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3336 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3338 // Update the sychronize button picture
3340 public QMenu createPopupMenu() {
3341 QMenu contextMenu = super.createPopupMenu();
3343 contextMenu.addSeparator();
3344 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3345 contextMenu.addAction(prevAction);
3346 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3348 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3349 contextMenu.addAction(nextAction);
3350 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3352 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3353 contextMenu.addAction(upAction);
3354 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3356 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3357 contextMenu.addAction(downAction);
3358 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3360 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3361 contextMenu.addAction(synchronizeAction);
3362 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3364 QAction printAction = addContextAction("print", tr("Print"));
3365 contextMenu.addAction(printAction);
3366 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3368 QAction tagAction = addContextAction("tag", tr("Tag"));
3369 contextMenu.addAction(tagAction);
3370 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3372 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3373 contextMenu.addAction(attributeAction);
3374 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3376 QAction emailAction = addContextAction("email", tr("Email"));
3377 contextMenu.addAction(emailAction);
3378 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3380 QAction deleteAction = addContextAction("delete", tr("Delete"));
3381 contextMenu.addAction(deleteAction);
3382 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3384 QAction newAction = addContextAction("new", tr("Add"));
3385 contextMenu.addAction(newAction);
3386 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3388 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3389 contextMenu.addAction(allNotesAction);
3390 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3392 // QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3393 // contextMenu.addAction(searchClearAction);
3394 // searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3399 private QAction addContextAction(String config, String name) {
3400 QAction newAction = new QAction(this);
3401 newAction.setText(name);
3402 newAction.setCheckable(true);
3403 newAction.setChecked(Global.isToolbarButtonVisible(config, true));
3406 private void togglePrevArrowButton(Boolean toggle) {
3407 prevButton.setVisible(toggle);
3408 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3410 private void toggleNextArrowButton(Boolean toggle) {
3411 nextButton.setVisible(toggle);
3412 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3414 private void toggleUpArrowButton(Boolean toggle) {
3415 upButton.setVisible(toggle);
3416 Global.saveToolbarButtonsVisible("upArrow", toggle);
3418 private void toggleDownArrowButton(Boolean toggle) {
3419 downButton.setVisible(toggle);
3420 Global.saveToolbarButtonsVisible("downArrow", toggle);
3422 private void toggleSynchronizeButton(Boolean toggle) {
3423 synchronizeButton.setVisible(toggle);
3424 Global.saveToolbarButtonsVisible("synchronize", toggle);
3426 private void togglePrintButton(Boolean toggle) {
3427 printButton.setVisible(toggle);
3428 Global.saveToolbarButtonsVisible("print", toggle);
3430 private void toggleTagButton(Boolean toggle) {
3431 tagButton.setVisible(toggle);
3432 Global.saveToolbarButtonsVisible("tag", toggle);
3434 private void toggleAttributeButton(Boolean toggle) {
3435 attributeButton.setVisible(toggle);
3436 Global.saveToolbarButtonsVisible("attribute", toggle);
3438 private void toggleEmailButton(Boolean toggle) {
3439 emailButton.setVisible(toggle);
3440 Global.saveToolbarButtonsVisible("email", toggle);
3442 private void toggleDeleteButton(Boolean toggle) {
3443 deleteButton.setVisible(toggle);
3444 Global.saveToolbarButtonsVisible("delete", toggle);
3446 private void toggleNewButton(Boolean toggle) {
3447 newButton.setVisible(toggle);
3448 Global.saveToolbarButtonsVisible("new", toggle);
3450 private void toggleAllNotesButton(Boolean toggle) {
3451 allNotesButton.setVisible(toggle);
3452 Global.saveToolbarButtonsVisible("allNotes", toggle);
3454 // @SuppressWarnings("unused")
3455 // private void toggleSearchClearButton(Boolean toggle) {
3456 // searchClearButton.setVisible(toggle);
3457 // Global.saveToolbarButtonsVisible("searchClear", toggle);
3464 @SuppressWarnings("unused")
3465 private void updateSyncButton() {
3467 if (syncIcons == null) {
3468 syncIcons = new ArrayList<QPixmap>();
3470 synchronizeIconAngle = 0;
3471 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3473 for (int i=0; i<=360; i++) {
3474 QPixmap rotatedPix = new QPixmap(pix.size());
3475 QPainter p = new QPainter(rotatedPix);
3476 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3477 QSize size = pix.size();
3478 p.translate(size.width()/2, size.height()/2);
3481 p.setBackgroundMode(BGMode.OpaqueMode);
3482 p.translate(-size.width()/2, -size.height()/2);
3483 p.drawPixmap(0,0, pix);
3485 syncIcons.add(rotatedPix);
3489 synchronizeIconAngle++;
3490 if (synchronizeIconAngle > 359)
3491 synchronizeIconAngle=0;
3492 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3495 // Synchronize with Evernote
3497 private void evernoteSync() {
3498 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3499 if (!Global.isConnected)
3501 if (Global.isConnected)
3502 synchronizeAnimationTimer.start(5);
3503 // synchronizeAnimationTimer.start(200);
3505 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3507 private void updateQuotaBar() {
3508 long limit = Global.getUploadLimit();
3509 long amount = Global.getUploadAmount();
3510 if (amount>0 && limit>0) {
3511 int percent =(int)(amount*100/limit);
3512 quotaBar.setValue(percent);
3514 quotaBar.setValue(0);
3517 @SuppressWarnings("unused")
3518 private void zoomChanged() {
3519 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3522 //****************************************************************
3523 //****************************************************************
3524 //* System Tray functions
3525 //****************************************************************
3526 //****************************************************************
3527 private void trayToggleVisible() {
3532 if (windowMaximized)
3539 @SuppressWarnings("unused")
3540 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3541 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3542 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3543 trayToggleVisible();
3548 //***************************************************************
3549 //***************************************************************
3550 //** These functions deal with the trash tree
3551 //***************************************************************
3552 //***************************************************************
3553 // Setup the tree containing the trash.
3554 @SuppressWarnings("unused")
3555 private void trashTreeSelection() {
3556 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3558 clearNotebookFilter();
3560 clearAttributeFilter();
3561 clearSavedSearchFilter();
3563 String tempGuid = currentNoteGuid;
3565 // currentNoteGuid = "";
3566 currentNote = new Note();
3567 selectedNoteGUIDs.clear();
3568 listManager.getSelectedNotebooks().clear();
3569 listManager.getSelectedTags().clear();
3570 listManager.setSelectedSavedSearch("");
3571 browserWindow.clear();
3573 // toggle the add buttons
3574 newButton.setEnabled(!newButton.isEnabled());
3575 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3576 menuBar.noteAdd.setVisible(true);
3578 List<QTreeWidgetItem> selections = trashTree.selectedItems();
3579 if (selections.size() == 0) {
3580 currentNoteGuid = trashNoteGuid;
3581 trashNoteGuid = tempGuid;
3582 Global.showDeleted = false;
3583 menuBar.noteRestoreAction.setEnabled(false);
3584 menuBar.noteRestoreAction.setVisible(false);
3585 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3586 rensoNoteListDock.setEnabled(true);
3589 trashNoteGuid = tempGuid;
3590 currentNoteGuid = trashNoteGuid;
3591 menuBar.noteRestoreAction.setEnabled(true);
3592 menuBar.noteRestoreAction.setVisible(true);
3593 // ゴミ箱を開く。連想ノートリストをOFFに。
3594 rensoNoteListDock.setEnabled(false);
3596 Global.showDeleted = true;
3599 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3600 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3601 menuBar.noteAddNewTab.setEnabled(false);
3604 listManager.loadNotesIndex();
3605 noteIndexUpdated(false);
3606 //// browserWindow.setEnabled(newButton.isEnabled());
3607 browserWindow.setReadOnly(!newButton.isEnabled());
3608 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3610 // Empty the trash file
3611 @SuppressWarnings("unused")
3612 private void emptyTrash() {
3613 // browserWindow.clear();
3614 logger.log(logger.EXTREME, "Emptying Trash");
3615 listManager.emptyTrash();
3616 logger.log(logger.EXTREME, "Resetting view after trash empty");
3617 if (trashTree.selectedItems().size() > 0) {
3618 listManager.getSelectedNotebooks().clear();
3619 listManager.getSelectedTags().clear();
3620 listManager.setSelectedSavedSearch("");
3621 newButton.setEnabled(!newButton.isEnabled());
3622 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3623 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3624 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3625 menuBar.noteAddNewTab.setEnabled(false);
3627 menuBar.noteAdd.setVisible(true);
3628 browserWindow.clear();
3631 clearNotebookFilter();
3632 clearSavedSearchFilter();
3633 clearAttributeFilter();
3635 Global.showDeleted = false;
3636 menuBar.noteRestoreAction.setEnabled(false);
3637 menuBar.noteRestoreAction.setVisible(false);
3639 listManager.loadNotesIndex();
3640 noteIndexUpdated(false);
3642 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3643 if (!rensoNoteListDock.isEnabled()) {
3644 rensoNoteListDock.setEnabled(true);
3648 // Show/Hide trash window
3649 @SuppressWarnings("unused")
3650 private void toggleTrashWindow() {
3651 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3652 if (trashTree.isVisible())
3656 menuBar.hideTrash.setChecked(trashTree.isVisible());
3658 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3659 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3661 private void clearTrashFilter() {
3662 Global.showDeleted = false;
3663 newButton.setEnabled(true);
3664 menuBar.noteAdd.setEnabled(true);
3665 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3666 menuBar.noteAddNewTab.setEnabled(false);
3668 menuBar.noteAddNewTab.setEnabled(true);
3670 menuBar.noteAdd.setVisible(true);
3671 trashTree.blockSignals(true);
3672 trashTree.clearSelection();
3673 trashTree.blockSignals(false);
3678 //***************************************************************
3679 //***************************************************************
3680 //** These functions deal with connection settings
3681 //***************************************************************
3682 //***************************************************************
3683 // SyncRunner had a problem and things are disconnected
3684 @SuppressWarnings("unused")
3685 private void remoteErrorDisconnect() {
3686 menuBar.connectAction.setText(tr("Connect"));
3687 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3688 menuBar.synchronizeAction.setEnabled(false);
3689 Global.isConnected = false;
3690 synchronizeAnimationTimer.stop();
3693 // Do a manual connect/disconnect
3694 private void remoteConnect() {
3696 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3698 // If we are already connected, we just disconnect
3699 if (Global.isConnected) {
3700 Global.isConnected = false;
3701 syncRunner.enDisconnect();
3702 setupConnectMenuOptions();
3707 OAuthTokenizer tokenizer = new OAuthTokenizer();
3708 AESEncrypter aes = new AESEncrypter();
3710 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauthkey.txt")));
3711 } catch (FileNotFoundException e) {
3712 // File not found, so we'll just get empty strings anyway.
3716 if (Global.getProxyValue("url").equals("")) {
3717 System.setProperty("http.proxyHost","") ;
3718 System.setProperty("http.proxyPort", "") ;
3719 System.setProperty("https.proxyHost","") ;
3720 System.setProperty("https.proxyPort", "") ;
3723 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3724 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3725 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3726 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3728 if (Global.getProxyValue("userid").equals("")) {
3729 Authenticator.setDefault(new Authenticator() {
3731 protected PasswordAuthentication getPasswordAuthentication() {
3733 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3739 syncRunner.userStoreUrl = Global.userStoreUrl;
3740 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3741 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3745 String authString = aes.getString();
3746 if (!authString.equals("")) {
3747 tokenizer.tokenize(authString);
3748 syncRunner.authToken = tokenizer.oauth_token;
3749 syncRunner.enConnect();
3752 Global.isConnected = syncRunner.isConnected;
3754 boolean autoLoginMessageFlag = false;
3755 if (!Global.isConnected) {
3756 OAuthWindow window = new OAuthWindow(logger);
3758 setMessage(window.errorMessage);
3763 setMessage(window.errorMessage);
3766 tokenizer.tokenize(window.response);
3767 if (tokenizer.oauth_token.equals("")) {
3768 setMessage(tr("Invalid authorization token received."));
3771 aes.setString(window.response);
3773 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauthkey.txt")));
3774 } catch (FileNotFoundException e) {
3775 // TODO Auto-generated catch block
3776 e.printStackTrace();
3778 syncRunner.authToken = tokenizer.oauth_token;
3779 syncRunner.enConnect();
3780 Global.isConnected = syncRunner.isConnected;
3781 autoLoginMessageFlag = true;
3783 // Global.username = syncRunner.username;
3785 if (!Global.isConnected)
3788 setupConnectMenuOptions();
3790 // 初回ログイン時に自動ログインが無効だったら、有効化するか確認する
3791 if (autoLoginMessageFlag && !Global.automaticLogin()) {
3792 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure you want to enable the auto-login feature?"),
3793 QMessageBox.StandardButton.Yes, QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
3794 Global.setAutomaticLogin(true);
3798 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3800 private void setupConnectMenuOptions() {
3801 logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3802 if (!Global.isConnected) {
3803 menuBar.connectAction.setText(tr("Connect"));
3804 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3805 menuBar.synchronizeAction.setEnabled(false);
3807 menuBar.connectAction.setText(tr("Disconnect"));
3808 menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3809 menuBar.synchronizeAction.setEnabled(true);
3811 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3816 //***************************************************************
3817 //***************************************************************
3818 //** These functions deal with the GUI Attribute tree
3819 //***************************************************************
3820 //***************************************************************
3821 @SuppressWarnings("unused")
3822 private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3824 // clearTagFilter();
3825 // clearNotebookFilter();
3827 // clearSavedSearchFilter();
3829 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3830 if (!rensoNoteListDock.isEnabled()) {
3831 rensoNoteListDock.setEnabled(true);
3834 if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3835 if (item.childCount() > 0) {
3836 item.setSelected(false);
3838 Global.createdBeforeFilter.reset();
3839 Global.createdSinceFilter.reset();
3840 Global.changedBeforeFilter.reset();
3841 Global.changedSinceFilter.reset();
3842 Global.containsFilter.reset();
3843 attributeTreeSelected = item;
3844 DateAttributeFilterTable f = null;
3845 f = findDateAttributeFilterTable(item.parent());
3847 f.select(item.parent().indexOfChild(item));
3849 Global.containsFilter.select(item.parent().indexOfChild(item));
3852 listManager.loadNotesIndex();
3853 noteIndexUpdated(false);
3856 attributeTreeSelected = null;
3857 item.setSelected(false);
3858 Global.createdBeforeFilter.reset();
3859 Global.createdSinceFilter.reset();
3860 Global.changedBeforeFilter.reset();
3861 Global.changedSinceFilter.reset();
3862 Global.containsFilter.reset();
3863 listManager.loadNotesIndex();
3864 noteIndexUpdated(false);
3866 // This determines what attribute filter we need, depending upon the selection
3867 private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3868 if (w.parent() != null && w.childCount() > 0) {
3869 QTreeWidgetItem parent = w.parent();
3870 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3871 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3872 return Global.createdSinceFilter;
3873 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3874 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3875 return Global.createdBeforeFilter;
3876 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3877 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3878 return Global.changedSinceFilter;
3879 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3880 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3881 return Global.changedBeforeFilter;
3886 // Show/Hide attribute search window
3887 @SuppressWarnings("unused")
3888 private void toggleAttributesWindow() {
3889 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3890 if (attributeTree.isVisible())
3891 attributeTree.hide();
3893 attributeTree.show();
3894 menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3896 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3897 logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3899 private void clearAttributeFilter() {
3900 Global.createdBeforeFilter.reset();
3901 Global.createdSinceFilter.reset();
3902 Global.changedBeforeFilter.reset();
3903 Global.changedSinceFilter.reset();
3904 Global.containsFilter.reset();
3905 attributeTreeSelected = null;
3906 attributeTree.blockSignals(true);
3907 attributeTree.clearSelection();
3908 attributeTree.blockSignals(false);
3912 //***************************************************************
3913 //***************************************************************
3914 //** These functions deal with the GUI Note index table
3915 //***************************************************************
3916 //***************************************************************
3917 // Initialize the note list table
3918 private void initializeNoteTable() {
3919 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3920 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3921 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3922 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3924 // Show/Hide trash window
3925 @SuppressWarnings("unused")
3926 private void toggleNoteListWindow() {
3927 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3928 if (noteTableView.isVisible())
3929 noteTableView.hide();
3931 noteTableView.show();
3932 menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3934 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3935 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3937 // Handle the event that a user selects a note from the table
3938 @SuppressWarnings("unused")
3939 private void noteTableSelection() {
3940 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3945 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3946 // 選択されたノートのguidをselectedNoteGUIDsにセット
3947 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3948 if(selections.size() > 0){
3949 selectedNoteGUIDs.clear();
3950 for(int i = 0; i < selections.size(); i++){
3951 int row = selections.get(i).row();
3952 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3953 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3954 selectedNoteGUIDs.add((String) ix.values().toArray()[0]);
3960 // If we have more than one selection, then set the merge note action to true.
3961 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3962 if (selections.size() > 1)
3963 menuBar.noteMergeAction.setEnabled(true);
3965 menuBar.noteMergeAction.setEnabled(false);
3967 // If the ctrl key is pressed, then they are selecting multiple
3968 // entries and we don't want to change the currently viewed note.
3969 // Shiftキーを押しながらの場合の処理も追加
3970 if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) ||
3971 QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) &&
3972 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3973 selectedNoteGUIDs.clear();
3974 for (int i=0; i<selections.size(); i++) {
3975 int row = selections.get(i).row();
3976 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3977 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3978 selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3983 // IFIXED 恐らく不要なのでコメントアウト
3984 // if (historyGuids.size() == 0) {
3985 // historyGuids.add(currentNoteGuid);
3986 // historyPosition = 1;
3989 noteTableView.showColumn(Global.noteTableGuidPosition);
3991 if (!Global.isColumnVisible("guid"))
3992 noteTableView.hideColumn(Global.noteTableGuidPosition);
3994 if (selections.size() > 0) {
3996 menuBar.noteDuplicateAction.setEnabled(true);
3997 menuBar.noteOnlineHistoryAction.setEnabled(true);
3998 menuBar.noteMergeAction.setEnabled(true);
3999 selectedNoteGUIDs.clear();
4000 if (currentNoteGuid != null && !currentNoteGuid.equals("") && !Global.showDeleted) {
4001 menuBar.noteAddNewTab.setEnabled(true);
4003 if (selections.size() != 1 || Global.showDeleted) {
4004 menuBar.noteDuplicateAction.setEnabled(false);
4006 if (selections.size() != 1 || !Global.isConnected) {
4007 menuBar.noteOnlineHistoryAction.setEnabled(false);
4009 if (selections.size() == 1) {
4010 menuBar.noteMergeAction.setEnabled(false);
4012 for (int i=0; i<selections.size(); i++) {
4013 int row = selections.get(i).row();
4015 upButton.setEnabled(false);
4017 upButton.setEnabled(true);
4018 if (row < listManager.getNoteTableModel().rowCount()-1)
4019 downButton.setEnabled(true);
4021 downButton.setEnabled(false);
4022 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
4023 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
4025 currentNoteGuid = (String)ix.values().toArray()[0];
4026 selectedNoteGUIDs.add(currentNoteGuid);
4030 nextButton.setEnabled(true);
4031 prevButton.setEnabled(true);
4033 int currentIndex = tabBrowser.currentIndex();
4034 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4035 int histPosition = historyPosition.get(currentIndex);
4036 boolean fromHist = fromHistory.get(currentIndex);
4039 int endPosition = histGuids.size() - 1;
4041 for (int j = histPosition; j <= endPosition; j++) {
4042 histGuids.remove(histGuids.size() - 1);
4044 histGuids.add(currentNoteGuid);
4045 historyPosition.put(currentIndex, histGuids.size());
4046 histPosition = histGuids.size();
4048 if (histPosition <= 1){
4049 prevButton.setEnabled(false);
4051 if (histPosition == histGuids.size())
4052 nextButton.setEnabled(false);
4053 fromHistory.put(currentIndex, false);
4056 scrollToGuid(currentNoteGuid);
4057 refreshEvernoteNote(true);
4059 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4060 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4066 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
4069 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4072 // 複数ノートの同時閲覧履歴をデータベースに保存
4073 private void addBrowseHistory() {
4074 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4075 if (tabWindows.size() >= 2) {
4076 Iterator<Integer> it = tabWindows.keySet().iterator();
4077 while (it.hasNext()) {
4078 int tabIndex = it.next();
4079 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4080 // guid1=guid2のデータは登録しない
4081 if (!currentNoteGuid.equals(nextGuid)) {
4082 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4086 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4087 if (externalWindows.size() >= 1) {
4088 Iterator<String> it = externalWindows.keySet().iterator();
4089 while (it.hasNext()) {
4090 String nextGuid = it.next();
4091 // guid1=guid2のデータは登録しない
4092 if (!currentNoteGuid.equals(nextGuid)) {
4093 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4099 // Trigger a refresh when the note db has been updated
4100 private void noteIndexUpdated(boolean reload) {
4101 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4103 refreshEvernoteNoteList();
4104 logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4105 noteTableView.load(reload);
4106 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4108 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4109 pos = noteTableView.proxyModel.rowCount();
4112 if (noteTableView.proxyModel.rowCount() == 0)
4115 QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4117 currentNoteGuid = (String)i.data();
4121 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4123 scrollToGuid(currentNoteGuid);
4124 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4126 // Called when the list of notes is updated
4127 private void refreshEvernoteNoteList() {
4128 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4129 browserWindow.setDisabled(false);
4130 if (selectedNoteGUIDs == null)
4131 selectedNoteGUIDs = new ArrayList<String>();
4132 selectedNoteGUIDs.clear(); // clear out old entries
4134 String saveCurrentNoteGuid = new String();
4135 String tempNoteGuid = new String();
4137 int currentIndex = tabBrowser.currentIndex();
4138 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4140 historyPosition.put(currentIndex, 0);
4142 prevButton.setEnabled(false);
4143 nextButton.setEnabled(false);
4145 if (currentNoteGuid == null)
4146 currentNoteGuid = new String();
4148 //determine current note guid
4149 for (Note note : listManager.getNoteIndex()) {
4150 tempNoteGuid = note.getGuid();
4151 if (currentNoteGuid.equals(tempNoteGuid)) {
4152 saveCurrentNoteGuid = tempNoteGuid;
4156 if (listManager.getNoteIndex().size() == 0) {
4157 currentNoteGuid = "";
4159 browserWindow.clear();
4160 browserWindow.setDisabled(true);
4164 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4165 currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4166 saveCurrentNoteGuid = currentNoteGuid;
4167 refreshEvernoteNote(true);
4170 if (!saveCurrentNoteGuid.equals("")) {
4171 refreshEvernoteNote(false);
4173 currentNoteGuid = "";
4175 reloadTagTree(false);
4177 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4180 // Called when the previous arrow button is clicked
4181 @SuppressWarnings("unused")
4182 private void previousViewedAction() {
4183 int currentIndex = tabBrowser.currentIndex();
4184 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4185 int histPosition = historyPosition.get(currentIndex);
4186 boolean fromHist = fromHistory.get(currentIndex);
4187 if (!prevButton.isEnabled())
4189 if (histPosition == 0)
4192 historyPosition.put(currentIndex, histPosition);
4193 if (histPosition <= 0)
4195 String historyGuid = histGuids.get(histPosition - 1);
4196 fromHistory.put(currentIndex, true);
4198 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4199 QModelIndex modelIndex = noteTableView.model().index(i,
4200 Global.noteTableGuidPosition);
4201 if (modelIndex != null) {
4202 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4204 String tableGuid = (String) ix.values().toArray()[0];
4205 if (tableGuid.equals(historyGuid)) {
4206 noteTableView.selectRow(i);
4213 @SuppressWarnings("unused")
4214 private void nextViewedAction() {
4215 if (!nextButton.isEnabled())
4218 int currentIndex = tabBrowser.currentIndex();
4219 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4220 int histPosition = historyPosition.get(currentIndex);
4221 boolean fromHist = fromHistory.get(currentIndex);
4222 String historyGuid = histGuids.get(histPosition);
4224 historyPosition.put(currentIndex, histPosition);
4225 fromHistory.put(currentIndex, true);
4227 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4228 QModelIndex modelIndex = noteTableView.model().index(i,
4229 Global.noteTableGuidPosition);
4230 if (modelIndex != null) {
4231 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4233 String tableGuid = (String) ix.values().toArray()[0];
4234 if (tableGuid.equals(historyGuid)) {
4235 noteTableView.selectRow(i);
4241 // Called when the up arrow is clicked
4242 @SuppressWarnings("unused")
4243 private void upAction() {
4244 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4245 int row = selections.get(0).row();
4247 noteTableView.selectRow(row-1);
4250 // Called when the down arrow is clicked
4251 @SuppressWarnings("unused")
4252 private void downAction() {
4253 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4254 int row = selections.get(0).row();
4255 int max = listManager.getNoteTableModel().rowCount();
4257 noteTableView.selectRow(row+1);
4260 // Update a tag string for a specific note in the list
4261 @SuppressWarnings("unused")
4262 private void updateListTags(String guid, List<String> tags) {
4263 logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4264 StringBuffer tagBuffer = new StringBuffer();
4265 for (int i=0; i<tags.size(); i++) {
4266 tagBuffer.append(tags.get(i));
4267 if (i<tags.size()-1)
4268 tagBuffer.append(", ");
4271 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4272 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4273 if (modelIndex != null) {
4274 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4275 String tableGuid = (String)ix.values().toArray()[0];
4276 if (tableGuid.equals(guid)) {
4277 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4278 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4279 noteTableView.proxyModel.invalidate();
4284 logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4286 // Update a title for a specific note in the list
4287 @SuppressWarnings("unused")
4288 private void updateListAuthor(String guid, String author) {
4289 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4291 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4292 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4293 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4294 if (modelIndex != null) {
4295 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4296 String tableGuid = (String)ix.values().toArray()[0];
4297 if (tableGuid.equals(guid)) {
4298 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4299 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4300 noteTableView.proxyModel.invalidate();
4306 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4308 private void updateListNoteNotebook(String guid, String notebook) {
4309 logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4310 listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4311 logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4313 // Update a title for a specific note in the list
4314 @SuppressWarnings("unused")
4315 private void updateListSourceUrl(String guid, String url) {
4316 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4318 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4319 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4320 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4321 if (modelIndex != null) {
4322 // SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4323 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4324 String tableGuid = (String)ix.values().toArray()[0];
4325 if (tableGuid.equals(guid)) {
4326 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4327 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4328 noteTableView.proxyModel.invalidate();
4333 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4335 @SuppressWarnings("unused")
4336 private void updateListGuid(String oldGuid, String newGuid) {
4337 logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4339 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4340 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4341 if (modelIndex != null) {
4342 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4343 String tableGuid = (String)ix.values().toArray()[0];
4344 if (tableGuid.equals(oldGuid)) {
4345 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4346 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4351 logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4353 private void updateListTagName(String guid) {
4354 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4356 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4357 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4358 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4360 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4361 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4362 if (modelIndex != null) {
4363 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4364 String noteGuid = (String)ix.values().toArray()[0];
4365 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4366 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4367 i=listManager.getNoteTableModel().rowCount();
4373 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4375 private void removeListTagName(String guid) {
4376 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4378 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4379 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4380 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4381 if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4382 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4385 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4386 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4387 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4388 if (modelIndex != null) {
4389 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4390 String noteGuid = (String)ix.values().toArray()[0];
4391 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4392 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4393 i=listManager.getNoteTableModel().rowCount();
4399 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4401 private void updateListNotebookName(String oldName, String newName) {
4402 logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4404 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4405 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition);
4406 if (modelIndex != null) {
4407 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4408 String tableName = (String)ix.values().toArray()[0];
4409 if (tableName.equalsIgnoreCase(oldName)) {
4410 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4414 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4416 @SuppressWarnings("unused")
4417 private void updateListDateCreated(String guid, QDateTime date) {
4418 logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
4420 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4421 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4422 if (modelIndex != null) {
4423 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4424 String tableGuid = (String)ix.values().toArray()[0];
4425 if (tableGuid.equals(guid)) {
4426 listManager.getNoteTableModel().setData(i, Global.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4427 noteTableView.proxyModel.invalidate();
4432 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4434 @SuppressWarnings("unused")
4435 private void updateListDateSubject(String guid, QDateTime date) {
4436 logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
4438 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4439 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4440 if (modelIndex != null) {
4441 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4442 String tableGuid = (String)ix.values().toArray()[0];
4443 if (tableGuid.equals(guid)) {
4444 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4445 listManager.getNoteTableModel().setData(i, Global.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4446 noteTableView.proxyModel.invalidate();
4451 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4453 private void updateListDateChanged(String guid, QDateTime date) {
4454 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4456 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4457 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4458 if (modelIndex != null) {
4459 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4460 String tableGuid = (String)ix.values().toArray()[0];
4461 if (tableGuid.equals(guid)) {
4462 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4463 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4468 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4470 private void updateListDateChanged() {
4471 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4472 QDateTime date = new QDateTime(QDateTime.currentDateTime());
4473 updateListDateChanged(currentNoteGuid, date);
4474 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4477 private void scrollToCurrentGuid() {
4478 //scrollToGuid(currentNoteGuid);
4479 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4480 if (selections.size() == 0)
4482 QModelIndex index = selections.get(0);
4483 int row = selections.get(0).row();
4484 String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4487 // Scroll to the current GUID in tthe list.
4488 // Scroll to a particular index item
4489 private void scrollToGuid(String guid) {
4490 if (currentNote == null || guid == null)
4492 if (currentNote.isActive() && Global.showDeleted) {
4493 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4494 if (!listManager.getNoteIndex().get(i).isActive()) {
4495 currentNote = listManager.getNoteIndex().get(i);
4496 currentNoteGuid = currentNote.getGuid();
4497 i = listManager.getNoteIndex().size();
4501 if (!currentNote.isActive() && !Global.showDeleted) {
4502 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4503 if (listManager.getNoteIndex().get(i).isActive()) {
4504 currentNote = listManager.getNoteIndex().get(i);
4505 currentNoteGuid = currentNote.getGuid();
4506 i = listManager.getNoteIndex().size();
4511 for (int i=0; i<noteTableView.model().rowCount(); i++) {
4512 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4513 if (currentNoteGuid.equals(index.data())) {
4514 // noteTableView.selectionModel().blockSignals(true);
4515 noteTableView.selectRow(i);
4516 // noteTableView.selectionModel().blockSignals(false);
4517 noteTableView.scrollTo(index, ScrollHint.EnsureVisible); // This should work, but it doesn't
4518 i=listManager.getNoteTableModel().rowCount();
4521 noteTableView.repaint();
4523 // Show/Hide columns
4524 private void showColumns() {
4525 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4526 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4527 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4528 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4529 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4530 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4531 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4532 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4533 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4534 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4535 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));
4536 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned"));
4538 // Title color has changed
4539 @SuppressWarnings("unused")
4540 private void titleColorChanged(Integer color) {
4541 logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4544 QColor backgroundColor = new QColor();
4545 QColor foregroundColor = new QColor(QColor.black);
4546 backgroundColor.setRgb(color);
4548 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4549 foregroundColor.setRgb(QColor.white.rgb());
4551 if (selectedNoteGUIDs.size() == 0)
4552 selectedNoteGUIDs.add(currentNoteGuid);
4554 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4555 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4556 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4557 if (modelIndex != null) {
4558 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4559 String tableGuid = (String)ix.values().toArray()[0];
4560 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4561 for (int k=0; k<Global.noteTableColumnCount; k++) {
4562 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4563 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4564 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4566 i=listManager.getNoteTableModel().rowCount();
4571 logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4573 // A note has been pinned or unpinned
4574 @SuppressWarnings("unused")
4575 private void notePinned() {
4576 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4579 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4580 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4581 boolean pinned = !meta.isPinned();
4582 meta.setPinned(pinned); // Toggle the pinned/unpinned
4584 // Update the list & table
4585 listManager.updateNoteMetadata(meta);
4586 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4588 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4590 // Wide list was chosen
4591 public void narrowListView() {
4592 saveNoteColumnPositions();
4593 saveNoteIndexWidth();
4595 int sortCol = noteTableView.proxyModel.sortColumn();
4596 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4597 Global.setSortColumn(sortCol);
4598 Global.setSortOrder(sortOrder);
4600 Global.setListView(Global.View_List_Narrow);
4602 menuBar.wideListView.blockSignals(true);
4603 menuBar.narrowListView.blockSignals(true);
4605 menuBar.wideListView.setChecked(false);
4606 menuBar.narrowListView.setChecked(true);
4608 menuBar.wideListView.blockSignals(false);
4609 menuBar.narrowListView.blockSignals(false);
4611 mainLeftRightSplitter.addWidget(noteTableView);
4612 mainLeftRightSplitter.addWidget(tabBrowser);
4614 restoreWindowState(false);
4615 noteTableView.repositionColumns();
4616 noteTableView.resizeColumnWidths();
4617 noteTableView.resizeRowHeights();
4619 sortCol = Global.getSortColumn();
4620 sortOrder = Global.getSortOrder();
4621 noteTableView.proxyModel.blocked = true;
4622 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4623 noteTableView.proxyModel.blocked = false;
4627 noteTableView.load(false);
4628 refreshEvernoteNote(true);
4629 scrollToCurrentGuid();
4631 public void wideListView() {
4632 int sortCol = noteTableView.proxyModel.sortColumn();
4633 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4634 Global.setSortColumn(sortCol);
4635 Global.setSortOrder(sortOrder);
4638 saveNoteColumnPositions();
4639 saveNoteIndexWidth();
4640 Global.setListView(Global.View_List_Wide);
4642 menuBar.wideListView.blockSignals(true);
4643 menuBar.narrowListView.blockSignals(true);
4645 menuBar.wideListView.setChecked(true);
4646 menuBar.narrowListView.setChecked(false);
4648 menuBar.wideListView.blockSignals(false);
4649 menuBar.narrowListView.blockSignals(false);
4650 browserIndexSplitter.setVisible(true);
4651 browserIndexSplitter.addWidget(noteTableView);
4652 browserIndexSplitter.addWidget(tabBrowser);
4654 restoreWindowState(false);
4655 noteTableView.repositionColumns();
4656 noteTableView.resizeColumnWidths();
4657 noteTableView.resizeRowHeights();
4659 sortCol = Global.getSortColumn();
4660 sortOrder = Global.getSortOrder();
4661 noteTableView.proxyModel.blocked = true;
4662 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4663 noteTableView.proxyModel.blocked = false;
4666 noteTableView.load(false);
4667 scrollToCurrentGuid();
4669 // Sort order for the notebook has changed
4670 public void tableSortOrderChanged(Integer column, Integer order) {
4672 // Find what notebook (if any) is selected. We ignore stacks & the "All Notebooks".
4673 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4674 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4675 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4677 notebook = currentSelectedNotebook.text(2);
4678 conn.getNotebookTable().setSortOrder(notebook, column, order);
4682 //***************************************************************
4683 @SuppressWarnings("unused")
4684 private void evernoteLinkClick(String syncGuid, String locGuid) {
4686 if (conn.getNoteTable().guidExists(syncGuid)) {
4689 // If we didn't find it via the synchronized guid, look under the local guid
4690 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was
4691 // later synchronized (that causes the guid to change so we need to find the new one).
4692 if (conn.getNoteTable().guidExists(locGuid))
4695 guid = conn.getNoteTable().findAlternateGuid(locGuid);
4698 openExternalEditor(guid);
4702 //If we've gotten this far, we can't find the note
4703 QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4704 " seem to find that note."));
4706 //***************************************************************
4707 //***************************************************************
4708 //** External editor window functions
4709 //***************************************************************
4710 //***************************************************************
4711 private void listDoubleClick() {
4713 openExternalEditor(currentNoteGuid);
4715 private void openExternalEditor(String guid) {
4717 if (externalWindows.containsKey(guid)) {
4718 externalWindows.get(guid).raise();
4722 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4723 // We have a new external editor to create
4724 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4725 ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4727 newBrowser.setWindowIcon(appIcon);
4728 externalWindows.put(guid, newBrowser);
4729 showEditorButtons(newBrowser.getBrowserWindow());
4730 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4731 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4732 newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4733 //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4734 newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4735 newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4736 newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4737 newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4739 browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4740 browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4741 browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4745 @SuppressWarnings({ "rawtypes", "unused" })
4746 private void externalWindowTagsEdited(String guid, List values) {
4747 StringBuffer line = new StringBuffer(100);
4748 for (int i=0; i<values.size(); i++) {
4750 line.append(Global.tagDelimeter+" ");
4751 line.append(values.get(i));
4753 if (guid.equals(currentNoteGuid)) {
4754 browserWindow.setTag(line.toString());
4757 @SuppressWarnings("unused")
4758 private void externalWindowClosing(String guid) {
4759 externalWindows.remove(guid);
4762 // ***************************************************************
4763 // ***************************************************************
4765 // ***************************************************************
4766 // ***************************************************************
4767 @SuppressWarnings("unused")
4768 private void openNewTab() {
4771 // selectedNoteGUIDsをディープコピー
4772 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4774 for (int i=0; i < copySelected.size() ; i++) {
4775 openTabEditor(copySelected.get(i));
4779 // 連想ノートリストから新しいタブで開く
4780 @SuppressWarnings("unused")
4781 private void openNewTabFromRNL(){
4782 if(rensoNotePressedItemGuid != null){
4783 String prevCurrentNoteGuid = new String(currentNoteGuid);
4786 openTabEditor(rensoNotePressedItemGuid);
4788 // 連想ノートリストアイテムクリック操作を記録
4789 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4793 private void openTabEditor(String guid) {
4795 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4797 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4798 showEditorButtons(newBrowser.getBrowserWindow());
4800 String noteTitle = note.getTitle();
4801 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4802 tabWindows.put(index, newBrowser);
4803 noteDirty.put(index, false);
4805 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4806 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4807 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4809 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4811 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4813 // ExtendedInformationを必要があれば表示する
4814 toggleNoteInformation();
4815 // Sourceを必要があれば表示する
4817 // EditorButtonsBarを必要があれば表示する
4818 toggleEditorButtonBar();
4821 ArrayList<String> histGuids = new ArrayList<String>();
4822 historyGuids.put(index, histGuids);
4823 historyPosition.put(index, 0);
4824 fromHistory.put(index, false);
4827 histGuids.add(guid);
4828 historyPosition.put(index, histGuids.size());
4830 tabBrowser.setCurrentIndex(index);
4832 if (guid != null && !guid.equals("")) {
4833 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4840 @SuppressWarnings("unused")
4841 private void tabCloseRequested(int index) {
4842 tabWindowClosing((TabBrowse)tabBrowser.widget(index));
4846 private void tabWindowClosing(TabBrowse tab) {
4848 if (tabBrowser.count() <= 1) {
4852 int index = tabBrowser.indexOf(tab);
4853 // String guid = tab.getBrowserWindow().getNote().getGuid();
4854 // String content = tab.getBrowserWindow().getContent();
4855 BrowserWindow browser = tab.getBrowserWindow();
4856 // // ノートが変更されていたら保存
4857 // if (tab.getNoteDirty()) {
4858 // saveNoteTabBrowser(guid, content, true, browser);
4862 browser.noteSignal.tagsChanged.disconnect();
4863 browser.noteSignal.titleChanged.disconnect();
4864 browser.noteSignal.noteChanged.disconnect();
4865 browser.noteSignal.notebookChanged.disconnect();
4866 browser.noteSignal.createdDateChanged.disconnect();
4867 browser.noteSignal.alteredDateChanged.disconnect();
4870 tabBrowser.removeTab(index);
4871 tabWindows.remove(index);
4872 noteDirty.remove(index);
4873 inkNote.remove(index);
4874 readOnly.remove(index);
4877 historyGuids.remove(index);
4878 historyPosition.remove(index);
4879 fromHistory.remove(index);
4881 // タブのインデックスを更新(削除によって空いた部分を詰める)
4882 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4884 TabBrowse nextTab = tabWindows.get(i + 1);
4885 tabWindows.put(i, nextTab);
4886 tabWindows.remove(i + 1);
4888 boolean isNoteDirty = noteDirty.get(i + 1);
4889 noteDirty.put(i, isNoteDirty);
4890 noteDirty.remove(i + 1);
4892 boolean isInkNote = inkNote.get(i + 1);
4893 inkNote.put(i, isInkNote);
4894 inkNote.remove(i + 1);
4896 boolean isReadOnly = readOnly.get(i + 1);
4897 readOnly.put(i, isReadOnly);
4898 readOnly.remove(i + 1);
4900 ArrayList<String> histGuids = historyGuids.get(i + 1);
4901 historyGuids.put(i, histGuids);
4902 historyGuids.remove(i + 1);
4904 int histPosition = historyPosition.get(i + 1);
4905 historyPosition.put(i, histPosition);
4906 historyPosition.remove(i + 1);
4908 boolean fromHist = fromHistory.get(i + 1);
4909 fromHistory.put(i, fromHist);
4910 fromHistory.remove(i + 1);
4913 // タブが残り1つになったら、閉じるボタンを消す
4914 if (tabBrowser.count() == 1) {
4915 tabBrowser.hideTabCloseButton(0);
4918 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4919 tabWindowChanged(tabBrowser.currentIndex());
4922 @SuppressWarnings("unused")
4923 private void noteAddNewTab() {
4926 // ノートを何も開いていないときは現在のタブにノート追加
4927 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4932 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4933 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4934 String prevTabGuid = null;
4935 if (prevTab.getBrowserWindow() != null && prevTab.getBrowserWindow().getNote() != null) {
4936 prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4939 openEmptyTabEditor();
4942 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4943 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4944 TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4945 String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4946 if (addedTabGuid != null && !addedTabGuid.equals("")) {
4947 if (!prevTabGuid.equals(addedTabGuid)) {
4948 conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4954 private void openEmptyTabEditor() {
4956 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4957 showEditorButtons(newBrowser.getBrowserWindow());
4959 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4961 int index = tabBrowser.addNewTab(newBrowser, "");
4962 tabWindows.put(index, newBrowser);
4963 noteDirty.put(index, false);
4965 // ExtendedInformationを必要があれば表示する
4966 toggleNoteInformation();
4967 // Sourceを必要があれば表示する
4969 // EditorButtonsBarを必要があれば表示する
4970 toggleEditorButtonBar();
4973 ArrayList<String> histGuids = new ArrayList<String>();
4974 historyGuids.put(index, histGuids);
4975 historyPosition.put(index, 0);
4976 fromHistory.put(index, false);
4978 tabBrowser.setCurrentIndex(index);
4981 //***************************************************************
4982 //***************************************************************
4983 //** These functions deal with Note specific things
4984 //***************************************************************
4985 //***************************************************************
4986 private void setNoteDirty() {
4987 for (String guid: selectedNoteGUIDs) {
4992 private void setNoteDirty(String targetGuid) {
4993 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
4995 // Find if the note is being edited externally. If it is, update it.
4996 if (externalWindows.containsKey(targetGuid)) {
4997 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4998 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4999 ExternalBrowse window = externalWindows.get(targetGuid);
5000 window.getBrowserWindow().setContent(unicode);
5003 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
5004 Collection<Integer> tabIndexes = tabWindows.keySet();
5005 Iterator<Integer> indexIterator = tabIndexes.iterator();
5007 for (TabBrowse tab: tabWindows.values()) {
5008 int index = indexIterator.next();
5009 String guid = tab.getBrowserWindow().getNote().getGuid();
5011 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5012 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
5014 if (guid.equals(guid)) {
5015 if (index != tabBrowser.currentIndex()) {
5016 TabBrowse window = tabWindows.get(index);
5017 window.getBrowserWindow().setContent(unicode);
5022 // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する
5023 // If the note is dirty, then it is unsynchronized by default.
5025 boolean isNoteDirty = false;
5026 for (TabBrowse tab: tabWindows.values()) {
5027 if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) {
5028 index = tabBrowser.indexOf(tab);
5029 isNoteDirty = noteDirty.get(index);
5037 // Set the note as dirty and check if its status is synchronized in the display table
5038 // まだダーティでなく、かつタブで開かれている場合にnoteDirty = trueにする
5040 noteDirty.put(index, true);
5043 if (listManager.getNoteMetadata().containsKey(targetGuid) &&
5044 listManager.getNoteMetadata().get(targetGuid).isDirty()) {
5048 // If this wasn't already marked as unsynchronized, then we need to update the table
5049 listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false);
5050 // listManager.getUnsynchronizedNotes().add(targetGuid);
5051 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
5052 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
5053 if (modelIndex != null) {
5054 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5055 String tableGuid = (String)ix.values().toArray()[0];
5056 if (tableGuid.equals(targetGuid)) {
5057 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
5063 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
5065 @SuppressWarnings("unused")
5066 private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
5067 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5068 QByteArray unicode = codec.fromUnicode(content);
5069 noteCache.remove(guid);
5070 noteCache.put(guid, unicode.toString());
5071 if (guid.equals(currentNoteGuid)) {
5072 int index = tabBrowser.currentIndex();
5073 noteDirty.put(index, true);
5074 browserWindow.setContent(unicode);
5077 thumbnailRunner.addWork("GENERATE "+ guid);
5078 saveNote(guid, browser);
5083 // private void saveNoteTabBrowser(String guid, String content, Boolean save,
5084 // BrowserWindow browser) {
5085 // QTextCodec codec = QTextCodec.codecForName("UTF-8");
5086 // QByteArray unicode = codec.fromUnicode(content);
5087 // noteCache.remove(guid);
5088 // noteCache.put(guid, unicode.toString());
5090 // thumbnailRunner.addWork("GENERATE " + guid);
5091 // saveNote(guid, browser);
5095 private void saveNote() {
5096 // すべてのタブに対して、Dirtyを確認し、trueならセーブする
5097 Collection<Integer> dirtyIndex = noteDirty.keySet();
5098 Iterator<Integer> indexIterator = dirtyIndex.iterator();
5099 for (boolean isNoteDirty: noteDirty.values()) {
5100 int index = indexIterator.next();
5105 BrowserWindow b = tabWindows.get(index).getBrowserWindow();
5106 String guid = b.getNote().getGuid();
5108 thumbnailRunner.addWork("GENERATE "+ guid);
5109 noteDirty.put(index, false);
5113 private void saveNote(String guid, BrowserWindow window) {
5114 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5117 logger.log(logger.EXTREME, "Saving to cache");
5118 QTextCodec codec = QTextCodec.codecForLocale();
5119 // QTextDecoder decoder = codec.makeDecoder();
5120 codec = QTextCodec.codecForName("UTF-8");
5121 QByteArray unicode = codec.fromUnicode(window.getContent());
5122 noteCache.put(guid, unicode.toString());
5124 logger.log(logger.EXTREME, "updating list manager");
5125 listManager.updateNoteContent(guid, window.getContent());
5126 logger.log(logger.EXTREME, "Updating title");
5127 listManager.updateNoteTitle(guid, window.getTitle());
5128 updateListDateChanged();
5130 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5131 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5132 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5133 currentNote = listManager.getNoteIndex().get(i);
5134 i = listManager.getNoteIndex().size();
5139 // Get a note from Evernote (and put it in the browser)
5140 private void refreshEvernoteNote(boolean reload) {
5141 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5143 if (Global.disableViewing) {
5144 browserWindow.setEnabled(false);
5147 inkNote.put(tabBrowser.currentIndex(), false);
5148 readOnly.put(tabBrowser.currentIndex(), false);
5150 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) {
5151 readOnly.put(tabBrowser.currentIndex(), true);
5153 Global.cryptCounter =0;
5154 if (readOnly.get(tabBrowser.currentIndex())) {
5155 browserWindow.setReadOnly(true);
5162 browserWindow.loadingData(true);
5164 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5165 if (currentNote == null) {
5170 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5172 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5175 private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5176 NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
5177 formatter.setNote(note, Global.pdfPreview());
5178 formatter.setHighlight(listManager.getEnSearch());
5183 for (TabBrowse tab: tabWindows.values()) {
5184 if (tab.getBrowserWindow() == browser) {
5185 tabIndex = tabBrowser.indexOf(tab);
5190 if (!noteCache.containsKey(guid)) {
5191 js = new QByteArray();
5192 // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
5193 js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
5194 js.append("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>");
5195 js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5196 js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5197 if (Global.displayRightToLeft())
5198 js.append("<style> body { direction:rtl; }</style>");
5199 js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5200 js.append("</head>");
5201 formatter.setNote(note, Global.pdfPreview());
5202 js.append(formatter.rebuildNoteHTML());
5203 js.append("</HTML>");
5204 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5205 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5206 js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5207 // if (Global.enableHTMLEntitiesFix) {
5208 // browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5210 browser.setContent(js);
5211 noteCache.put(guid, js.toString());
5213 if (formatter.resourceError)
5214 resourceErrorMessage(tabIndex);
5215 if (formatter.formatError) {
5217 QMessageBox.information(this, tr("Error"),
5218 tr("NeighborNote had issues formatting this note." +
5219 " To protect your data this note is being marked as read-only."));
5223 if (tabIndex >= 0) {
5224 readOnly.put(tabIndex, formatter.readOnly);
5225 inkNote.put(tabIndex, formatter.inkNote);
5228 if (tabIndex >= 0 && readOnly.get(tabIndex)) {
5229 readOnlyCache.put(guid, true);
5231 if (tabIndex >= 0 && inkNote.get(tabIndex)) {
5232 inkNoteCache.put(guid, true);
5236 logger.log(logger.HIGH, "Note content is being pulled from the cache");
5237 String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5238 js = new QByteArray(cachedContent);
5239 browser.setContent(js);
5240 if (readOnlyCache.containsKey(guid) && tabIndex >= 0) {
5241 readOnly.put(tabIndex, true);
5243 readOnly.put(tabIndex, false);
5245 if (inkNoteCache.containsKey(guid) && tabIndex >= 0) {
5246 inkNote.put(tabIndex, true);
5248 inkNote.put(tabIndex, false);
5251 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5252 thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5254 if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) ||
5255 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != "")))
5256 browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
5258 browser.getBrowser().page().setContentEditable(true);
5259 if (tabIndex >= 0) {
5260 browser.setReadOnly(readOnly.get(tabIndex));
5261 deleteButton.setEnabled(!readOnly.get(tabIndex));
5262 tagButton.setEnabled(!readOnly.get(tabIndex));
5263 menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex));
5264 menuBar.noteTags.setEnabled(!readOnly.get(tabIndex));
5266 browser.setNote(note);
5268 if (note != null && note.getNotebookGuid() != null &&
5269 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5270 deleteButton.setEnabled(false);
5271 menuBar.notebookDeleteAction.setEnabled(false);
5273 deleteButton.setEnabled(true);
5274 menuBar.notebookDeleteAction.setEnabled(true);
5277 // Build a list of non-closed notebooks
5278 List<Notebook> nbooks = new ArrayList<Notebook>();
5279 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5280 boolean found=false;
5281 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5282 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
5286 nbooks.add(listManager.getNotebookIndex().get(i));
5289 browser.setTitle(note.getTitle());
5290 browser.setTag(getTagNamesForNote(note));
5291 browser.setAuthor(note.getAttributes().getAuthor());
5293 browser.setAltered(note.getUpdated());
5294 browser.setCreation(note.getCreated());
5295 if (note.getAttributes().getSubjectDate() > 0)
5296 browser.setSubjectDate(note.getAttributes().getSubjectDate());
5298 browser.setSubjectDate(note.getCreated());
5299 browser.setUrl(note.getAttributes().getSourceURL());
5301 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5302 List<Tag> tagList = tagFilter.getValidTags(note);
5303 browser.setAllTags(tagList);
5305 browser.setCurrentTags(note.getTagNames());
5306 for (TabBrowse tab: tabWindows.values()) {
5307 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
5308 int index = tabBrowser.indexOf(tab);
5309 noteDirty.put(index, false);
5316 browser.loadingData(false);
5317 if (thumbnailViewer.isActiveWindow())
5320 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5321 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5324 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5327 @SuppressWarnings("unused")
5328 private void toggleNoteAttributes() {
5329 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5330 toggleNoteInformation();
5333 // Save a generated thumbnail
5334 private void toggleNoteInformation() {
5335 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5337 boolean isChecked = menuBar.noteAttributes.isChecked();
5339 for(int i = 0; i < tabBrowser.count(); i++){
5340 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5341 boolean isExtended = browser.isExtended();
5342 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5343 browser.toggleInformation();
5347 menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5348 Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5349 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5352 // Listener triggered when a print button is pressed
5353 @SuppressWarnings("unused")
5354 private void printNote() {
5355 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5357 QPrintDialog dialog = new QPrintDialog();
5358 if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5359 QPrinter printer = dialog.printer();
5360 browserWindow.getBrowser().print(printer);
5362 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5365 // Listener triggered when the email button is pressed
5366 @SuppressWarnings("unused")
5367 private void emailNote() {
5368 logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5370 if (Desktop.isDesktopSupported()) {
5371 Desktop desktop = Desktop.getDesktop();
5373 String text2 = browserWindow.getContentsToEmail();
5374 QUrl url = new QUrl("mailto:");
5375 url.addQueryItem("subject", currentNote.getTitle());
5376 // url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5377 url.addQueryItem("body", text2);
5378 QDesktopServices.openUrl(url);
5382 if (desktop.isSupported(Desktop.Action.MAIL)) {
5383 URI uriMailTo = null;
5385 //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5386 String text = browserWindow.getContentsToEmail();
5387 //text = "<b>" +text +"</b>";
5388 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5389 +"&BODY=" +text, null);
5390 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5391 +"&ATTACHMENT=d:/test.pdf", null);
5392 desktop.mail(uriMailTo);
5393 } catch (URISyntaxException e) {
5394 e.printStackTrace();
5395 } catch (IOException e) {
5396 e.printStackTrace();
5403 logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5405 // Reindex all notes
5406 @SuppressWarnings("unused")
5407 private void fullReindex() {
5408 logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5409 indexRunner.addWork("REINDEXALL");
5410 setMessage(tr("Database will be reindexed."));
5411 logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5413 // Listener when a user wants to reindex a specific note
5414 @SuppressWarnings("unused")
5415 private void reindexNote() {
5416 logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5417 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5418 indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5420 if (selectedNotebookGUIDs.size() > 1)
5421 setMessage(tr("Notes will be reindexed."));
5423 setMessage(tr("Note will be reindexed."));
5424 logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5427 @SuppressWarnings("unused")
5428 private void deleteNote() {
5429 logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5430 if (currentNote == null)
5432 if (currentNoteGuid.equals(""))
5435 String title = null;
5436 if (selectedNoteGUIDs.size() == 1)
5437 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5439 // If we are deleting non-trash notes
5440 if (currentNote.isActive()) {
5441 if (Global.verifyDelete()) {
5443 if (selectedNoteGUIDs.size() > 1) {
5444 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5447 msg = new String(tr("Delete note \"") +title +"\"?");
5449 msg = new String(tr("Delete note selected note?"));
5451 if (QMessageBox.question(this, tr("Confirmation"), msg,
5452 QMessageBox.StandardButton.Yes,
5453 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5457 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) {
5458 selectedNoteGUIDs.add(currentNoteGuid);
5461 List<String> deleteNoteGUIDs = new ArrayList<String>(selectedNoteGUIDs); // タブを閉じるとselectedNoteGUIDsが変わってしまうのでその前にコピー
5462 closeTabs(selectedNoteGUIDs);
5463 for (String guid : deleteNoteGUIDs) {
5464 listManager.deleteNote(guid);
5467 closeExternalWindows(deleteNoteGUIDs);
5469 // If we are deleting from the trash.
5470 if (Global.verifyDelete()) {
5472 if (selectedNoteGUIDs.size() > 1) {
5473 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5476 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5478 msg = new String(tr("Permanently delete note selected note?"));
5480 if (QMessageBox.question(this, "Confirmation", msg,
5481 QMessageBox.StandardButton.Yes,
5482 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
5486 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5487 selectedNoteGUIDs.add(currentNoteGuid);
5489 List<String> deleteNoteGUIDs = new ArrayList<String>(selectedNoteGUIDs); // タブを閉じるとselectedNoteGUIDsが変わってしまうのでその前にコピー
5490 for (int i=deleteNoteGUIDs.size()-1; i>=0; i--) {
5491 for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5492 QModelIndex modelIndex = listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5493 if (modelIndex != null) {
5494 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5495 String tableGuid = (String)ix.values().toArray()[0];
5496 if (tableGuid.equals(deleteNoteGUIDs.get(i))) {
5497 listManager.getNoteTableModel().removeRow(j);
5502 closeTab(deleteNoteGUIDs.get(i));
5503 listManager.expungeNote(deleteNoteGUIDs.get(i));
5505 conn.getHistoryTable().expungeHistory(deleteNoteGUIDs.get(i));
5506 conn.getExcludedTable().expungeExcludedNote(deleteNoteGUIDs.get(i));
5507 conn.getStaredTable().expungeStaredNote(deleteNoteGUIDs.get(i));
5510 closeExternalWindows(deleteNoteGUIDs);
5513 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
5514 menuBar.noteAddNewTab.setEnabled(false);
5517 listManager.loadNotesIndex();
5518 noteIndexUpdated(false);
5519 refreshEvernoteNote(true);
5520 scrollToGuid(currentNoteGuid);
5521 logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5524 // 対象ノートをタブで開いていたら閉じる
5525 private void closeTabs(List<String> noteGUIDs) {
5526 for (String guid : noteGUIDs) {
5531 // 対象ノートをタブで開いていたら閉じる
5532 private void closeTab(String noteGUID) {
5533 List<TabBrowse> closeTabs = new ArrayList<TabBrowse>();
5535 for (TabBrowse tab : tabWindows.values()) {
5536 String guid = tab.getBrowserWindow().getNote().getGuid();
5538 if (guid.equals(noteGUID)) {
5543 for (TabBrowse tab : closeTabs) {
5544 tabWindowClosing(tab);
5548 // 対象ノートを外部ウィンドウで開いていたら閉じる
5549 private void closeExternalWindows(List<String> noteGUIDs) {
5550 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>();
5552 for (Map.Entry<String, ExternalBrowse> e : externalWindows.entrySet()) {
5553 for (String guid : noteGUIDs) {
5554 if (guid.equals(e.getKey())) {
5555 closeWindows.add(e.getValue());
5560 for (ExternalBrowse externalBrowse : closeWindows) {
5561 externalBrowse.close();
5566 private void addNote() {
5567 logger.log(logger.HIGH, "Inside NeverNote.addNote");
5568 // browserWindow.setEnabled(true);
5569 browserWindow.setReadOnly(false);
5571 Calendar currentTime = new GregorianCalendar();
5572 StringBuffer noteString = new StringBuffer(100);
5573 noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5574 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5577 if (Global.overrideDefaultFont()) {
5578 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5579 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5580 noteString.append("<br clear=\"none\" />\n");
5581 noteString.append("</span>\n</font>\n");
5583 noteString.append("<br clear=\"none\" />\n");
5584 noteString.append("</en-note>");
5586 Long l = new Long(currentTime.getTimeInMillis());
5587 String randint = new String(Long.toString(l));
5589 // Find a notebook. We first look for a selected notebook (the "All Notebooks" one doesn't count).
5591 // for the first non-archived notebook. Finally, if nothing else we
5592 // pick the first notebook in the list.
5593 String notebook = null;
5594 listManager.getNotebookIndex().get(0).getGuid();
5595 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5596 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5597 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5598 notebook = currentSelectedNotebook.text(2);
5600 boolean found = false;
5601 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5602 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5603 boolean match = false;
5604 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5605 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5607 j = listManager.getArchiveNotebookIndex().size();
5611 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5612 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5614 // Now we have a list of good notebooks, so we can look for the default
5616 for (int i=0; i<goodNotebooks.size(); i++) {
5617 if (goodNotebooks.get(i).isDefaultNotebook()) {
5618 notebook = goodNotebooks.get(i).getGuid();
5620 i = goodNotebooks.size();
5624 if (goodNotebooks.size() > 0 && !found)
5625 notebook = goodNotebooks.get(0).getGuid();
5628 notebook = listManager.getNotebookIndex().get(0).getGuid();
5631 Note newNote = new Note();
5632 newNote.setUpdateSequenceNum(0);
5633 newNote.setGuid(randint);
5634 newNote.setNotebookGuid(notebook);
5635 newNote.setTitle("Untitled Note");
5636 newNote.setContent(noteString.toString());
5637 newNote.setDeleted(0);
5638 newNote.setCreated(System.currentTimeMillis());
5639 newNote.setUpdated(System.currentTimeMillis());
5640 newNote.setActive(true);
5641 NoteAttributes na = new NoteAttributes();
5642 na.setLatitude(0.0);
5643 na.setLongitude(0.0);
5644 na.setAltitude(0.0);
5645 newNote.setAttributes(new NoteAttributes());
5646 newNote.setTagGuids(new ArrayList<String>());
5647 newNote.setTagNames(new ArrayList<String>());
5649 // If new notes are to be created based upon the selected tags, then we need to assign the tags
5650 if (Global.newNoteWithSelectedTags()) {
5651 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5652 QTreeWidgetItem currentSelection;
5653 for (int i=0; i<selections.size(); i++) {
5654 currentSelection = selections.get(i);
5655 newNote.getTagGuids().add(currentSelection.text(2));
5656 newNote.getTagNames().add(currentSelection.text(0));
5660 conn.getNoteTable().addNote(newNote, true);
5661 NoteMetadata metadata = new NoteMetadata();
5662 metadata.setGuid(newNote.getGuid());
5663 metadata.setDirty(true);
5664 listManager.addNote(newNote, metadata);
5665 // noteTableView.insertRow(newNote, true, -1);
5667 String prevCurrentNoteGuid = new String(currentNoteGuid);
5669 currentNote = newNote;
5670 currentNoteGuid = currentNote.getGuid();
5671 // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5672 // noteTableView.clearSelection();
5674 // 新規に作成したノートとそれまで開いていたノートの関連性を追加
5675 if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5676 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5677 conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5681 refreshEvernoteNote(true);
5682 listManager.countNotebookResults(listManager.getNoteIndex());
5683 browserWindow.titleLabel.setFocus();
5684 browserWindow.titleLabel.selectAll();
5685 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5687 // If the window is hidden, then we want to popup this in an external window &
5691 logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5693 // Restore a note from the trash;
5694 @SuppressWarnings("unused")
5695 private void restoreNote() {
5697 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5698 selectedNoteGUIDs.add(currentNoteGuid);
5699 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5700 listManager.restoreNote(selectedNoteGUIDs.get(i));
5702 currentNoteGuid = "";
5703 listManager.loadNotesIndex();
5704 noteIndexUpdated(false);
5707 // Search a note for specific txt
5708 @SuppressWarnings("unused")
5709 private void findText() {
5711 find.setFocusOnTextField();
5713 @SuppressWarnings("unused")
5714 private void doFindText() {
5715 browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5718 @SuppressWarnings("unused")
5719 private void updateNoteTitle(String guid, String title) {
5720 listManager.setNoteSynchronized(guid, false);
5722 // We do this manually because if we've edited the note in an
5723 // external window we run into the possibility of signal recursion
5725 if (guid.equals(currentNoteGuid)) {
5726 browserWindow.titleLabel.blockSignals(true);
5727 browserWindow.titleLabel.setText(title);
5728 browserWindow.titleLabel.blockSignals(false);
5731 // Signal received that note content has changed. Normally we just need the guid to remove
5732 // it from the cache.
5733 @SuppressWarnings("unused")
5734 private void invalidateNoteCache(String guid, String content) {
5735 noteCache.remove(guid);
5736 refreshEvernoteNote(true);
5738 // Signal received that a note guid has changed
5739 @SuppressWarnings("unused")
5740 private void noteGuidChanged(String oldGuid, String newGuid) {
5741 if (noteCache.containsKey(oldGuid)) {
5742 if (!oldGuid.equals(currentNoteGuid)) {
5743 String cache = noteCache.get(oldGuid);
5744 noteCache.put(newGuid, cache);
5745 noteCache.remove(oldGuid);
5747 noteCache.remove(oldGuid);
5748 noteCache.put(newGuid, browserWindow.getContent());
5752 listManager.updateNoteGuid(oldGuid, newGuid, false);
5753 if (currentNoteGuid.equals(oldGuid)) {
5754 if (currentNote != null)
5755 currentNote.setGuid(newGuid);
5756 currentNoteGuid = newGuid;
5759 if (externalWindows.containsKey(oldGuid)) {
5760 ExternalBrowse b = externalWindows.get(oldGuid);
5761 externalWindows.remove(oldGuid);
5762 b.getBrowserWindow().getNote().setGuid(newGuid);
5763 externalWindows.put(newGuid, b);
5766 for(int i = 0; i < tabBrowser.count(); i++){
5767 TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5768 if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) {
5769 b.getBrowserWindow().getNote().setGuid(newGuid);
5773 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5774 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5775 noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5776 i=listManager.getNoteIndex().size();
5780 if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5781 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5782 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5783 listManager.getNoteTableModel().metaData.remove(oldGuid);
5788 // Toggle the note editor button bar
5790 private void toggleEditorButtonBar() {
5791 boolean isChecked = menuBar.showEditorBar.isChecked();
5793 for(int i = 0; i < tabBrowser.count(); i++){
5794 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5795 boolean isVisible = browser.buttonsVisible;
5797 if (isChecked && !isVisible) {
5798 browser.buttonsVisible = true;
5799 showEditorButtons(browser);
5800 } else if(!isChecked && isVisible) {
5801 browser.hideButtons();
5805 Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5808 // Show editor buttons
5809 private void showEditorButtons(BrowserWindow browser) {
5810 browser.buttonLayout.setVisible(true);
5811 browser.undoAction.setVisible(false);
5813 browser.undoButton.setVisible(false);
5815 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5816 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5817 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5818 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5819 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5820 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5821 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5822 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5823 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5824 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5825 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5826 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5827 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5828 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5829 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5830 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5831 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5832 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5833 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5834 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5835 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5836 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5837 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5839 private void duplicateNote(String guid) {
5841 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5842 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5843 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5844 oldNote.setResources(resList);
5845 duplicateNote(oldNote);
5847 private void duplicateNote(Note oldNote) {
5849 // Now that we have a good notebook guid, we need to move the conflicting note
5850 // to the local notebook
5851 Calendar currentTime = new GregorianCalendar();
5852 Long l = new Long(currentTime.getTimeInMillis());
5853 String newGuid = new String(Long.toString(l));
5855 // Note newNote = oldNote.deepCopy();
5856 Note newNote = (Note)Global.deepCopy(oldNote);
5857 newNote.setUpdateSequenceNum(0);
5858 newNote.setGuid(newGuid);
5859 newNote.setDeleted(0);
5860 newNote.setActive(true);
5863 List<String> tagNames = new ArrayList<String>();
5864 List<String> tagGuids = new ArrayList<String>();;
5865 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5866 tagNames.add(oldNote.getTagNames().get(i));
5867 tagGuids.add(oldNote.getTagGuids().get(i));
5870 // Sort note Tags to make them look nice
5871 for (int i=0; i<tagNames.size()-1; i++) {
5872 if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5873 String n1 = tagNames.get(i);
5874 String n2 = tagNames.get(i+1);
5875 tagNames.set(i, n2);
5876 tagNames.set(i+1, n1);
5879 newNote.setTagGuids(tagGuids);
5880 newNote.setTagNames(tagNames);
5882 // Add tag guids to note
5885 // Duplicate resources
5886 List<Resource> resList = oldNote.getResources();
5887 if (resList == null)
5888 resList = new ArrayList<Resource>();
5890 for (int i=0; i<resList.size(); i++) {
5892 while (l == prevGuid) {
5893 currentTime = new GregorianCalendar();
5894 l = new Long(currentTime.getTimeInMillis());
5897 String newResGuid = new String(Long.toString(l));
5898 resList.get(i).setNoteGuid(newGuid);
5899 resList.get(i).setGuid(newResGuid);
5900 resList.get(i).setUpdateSequenceNum(0);
5901 resList.get(i).setActive(true);
5902 conn.getNoteTable().noteResourceTable.saveNoteResource(
5903 (Resource)Global.deepCopy(resList.get(i)), true);
5905 newNote.setResources(resList);
5907 // 操作履歴と除外ノートとスター付きノートも複製する
5908 if(Global.getDuplicateRensoNote()) {
5909 conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5910 conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5911 conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5914 // Add note to the database
5915 conn.getNoteTable().addNote(newNote, true);
5916 NoteMetadata metaData = new NoteMetadata();
5917 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5918 metaData.copy(oldMeta);
5919 metaData.setGuid(newNote.getGuid());
5920 listManager.addNote(newNote, metaData);
5921 noteTableView.insertRow(newNote, metaData, true, -1);
5922 currentNoteGuid = newNote.getGuid();
5923 currentNote = newNote;
5924 refreshEvernoteNote(true);
5925 listManager.countNotebookResults(listManager.getNoteIndex());
5930 @SuppressWarnings("unused")
5931 private void allNotes() {
5932 clearAttributeFilter();
5933 clearNotebookFilter();
5934 clearSavedSearchFilter();
5937 searchField.clear();
5938 if (Global.mimicEvernoteInterface) {
5939 notebookTree.selectGuid("");
5941 notebookTreeSelection();
5942 refreshEvernoteNote(true);
5944 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5945 if (!rensoNoteListDock.isEnabled()) {
5946 rensoNoteListDock.setEnabled(true);
5950 @SuppressWarnings("unused")
5951 private void mergeNotes() {
5952 logger.log(logger.HIGH, "Merging notes");
5955 String masterGuid = null;
5956 List<String> sources = new ArrayList<String>();
5958 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5959 int r = noteTableView.selectionModel().selectedRows().get(i).row();
5960 index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5961 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5963 masterGuid = (String)ix.values().toArray()[0];
5965 sources.add((String)ix.values().toArray()[0]);
5968 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5969 logger.log(logger.EXTREME, "Children count: "+sources.size());
5970 mergeNoteContents(masterGuid, sources);
5971 currentNoteGuid = masterGuid;
5973 // 操作履歴と除外ノートとスター付きノートをマージ
5974 if(Global.getMergeRensoNote()) {
5975 for (int i = 0; i < sources.size(); i++) {
5976 String childGuid = sources.get(i);
5977 if(masterGuid != null && childGuid != null) {
5978 if(!masterGuid.equals(childGuid)) {
5979 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
5980 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
5981 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
5987 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
5988 Collection<ExternalBrowse> windows = externalWindows.values();
5989 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5990 Collection<String> guids = externalWindows.keySet();
5991 Iterator<String> guidIterator = guids.iterator();
5992 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>();
5994 while (windowIterator.hasNext()) {
5995 ExternalBrowse browser = windowIterator.next();
5996 String guid = guidIterator.next();
5998 for (int i = 0; i < sources.size(); i++) {
5999 if (guid.equals(sources.get(i))) {
6000 closeWindows.add(browser);
6005 for (int i = closeWindows.size() - 1; i >= 0; i--) {
6006 closeWindows.get(i).close();
6009 // マージしたノート(child)をタブで開いていたら、閉じる
6010 List<TabBrowse> closeTabs = new ArrayList<TabBrowse>();
6011 for (TabBrowse tab : tabWindows.values()) {
6012 String guid = tab.getBrowserWindow().getNote().getGuid();
6014 for (String source : sources) {
6015 if (guid.equals(source)) {
6020 for (TabBrowse tab : closeTabs) {
6021 tabWindowClosing(tab);
6024 noteIndexUpdated(false);
6026 // マージ後の新しいノートコンテンツを表示するためキャッシュを削除
6027 noteCache.remove(masterGuid);
6029 refreshEvernoteNote(true);
6032 private void mergeNoteContents(String targetGuid, List<String> sources) {
6033 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
6034 String newContent = target.getContent();
6035 newContent = newContent.replace("</en-note>", "<br></br>");
6037 for (int i=0; i<sources.size(); i++) {
6038 Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
6039 if (source.isSetTitle()) {
6040 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
6042 String sourceContent = source.getContent();
6043 logger.log(logger.EXTREME, "Merging contents into note");
6044 logger.log(logger.EXTREME, sourceContent);
6045 logger.log(logger.EXTREME, "End of content");
6046 int startOfNote = sourceContent.indexOf("<en-note>");
6047 sourceContent = sourceContent.substring(startOfNote+9);
6048 int endOfNote = sourceContent.indexOf("</en-note>");
6049 sourceContent = sourceContent.substring(0,endOfNote);
6050 newContent = newContent + sourceContent;
6051 logger.log(logger.EXTREME, "New note content");
6052 logger.log(logger.EXTREME, newContent);
6053 logger.log(logger.EXTREME, "End of content");
6054 for (int j=0; j<source.getResourcesSize(); j++) {
6055 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
6056 Resource r = source.getResources().get(j);
6057 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
6059 Calendar currentTime = new GregorianCalendar();
6060 Long l = new Long(currentTime.getTimeInMillis());
6064 while (l == prevGuid) {
6065 currentTime = new GregorianCalendar();
6066 l = new Long(currentTime.getTimeInMillis());
6068 String newResGuid = new String(Long.toString(l));
6069 newRes.setNoteGuid(targetGuid);
6070 newRes.setGuid(newResGuid);
6071 newRes.setUpdateSequenceNum(0);
6072 newRes.setActive(true);
6073 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
6076 logger.log(logger.EXTREME, "Updating note");
6077 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
6078 for (int i=0; i<sources.size(); i++) {
6079 logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
6080 listManager.deleteNote(sources.get(i));
6082 logger.log(logger.EXTREME, "Exiting merge note");
6084 // A resource within a note has had a guid change
6085 @SuppressWarnings("unused")
6086 private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
6087 if (oldGuid != null && !oldGuid.equals(newGuid))
6088 Global.resourceMap.put(oldGuid, newGuid);
6090 // View a thumbnail of the note
6091 public void thumbnailView() {
6093 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
6094 QFile thumbnail = new QFile(thumbnailName);
6095 if (!thumbnail.exists()) {
6097 QImage img = new QImage();
6098 img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
6099 thumbnailViewer.setThumbnail(img);
6101 thumbnailViewer.setThumbnail(thumbnailName);
6102 if (!thumbnailViewer.isVisible())
6103 thumbnailViewer.showFullScreen();
6105 // An error happened while saving a note. Inform the user
6106 @SuppressWarnings("unused")
6107 private void saveRunnerError(String guid, String msg) {
6109 String title = "*Unknown*";
6110 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6111 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6112 title = listManager.getMasterNoteIndex().get(i).getTitle();
6113 i=listManager.getMasterNoteIndex().size();
6116 msg = tr("An error has happened while saving the note \"") +title+
6117 tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
6118 "As a result, changes to the note may not be saved properly in the database."+
6119 "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6120 "\nbe lost. Please review the note to recover any critical data before restarting.");
6122 QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6125 private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6126 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6127 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6128 // Find an idle preview object
6129 for (int i=0; i<thumbGenerators.size(); i++) {
6130 if (thumbGenerators.get(i).mutex.tryLock()) {
6131 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6132 thumbGenerators.get(i).loadContent(guid, html, zoom);
6136 if (thumbGenerators.size() >= 1) {
6137 logger.log(logger.EXTREME, "No available thumbnail generators. Aborting " +guid);
6141 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6142 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6143 thumbGenerators.add(preview);
6145 if (preview.mutex.tryLock()) {
6146 logger.log(logger.EXTREME, "Loading thumbnail for " +guid);
6147 preview.loadContent(guid, html, zoom);
6149 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6154 //**********************************************************
6155 //**********************************************************
6156 //* Online user actions
6157 //**********************************************************
6158 //**********************************************************
6159 private void setupOnlineMenu() {
6160 if (!Global.isConnected) {
6161 menuBar.noteOnlineHistoryAction.setEnabled(false);
6162 menuBar.selectiveSyncAction.setEnabled(false);
6165 menuBar.noteOnlineHistoryAction.setEnabled(true);
6166 menuBar.selectiveSyncAction.setEnabled(true);
6169 @SuppressWarnings("unused")
6170 private void viewNoteHistory() {
6171 if (currentNoteGuid == null || currentNoteGuid.equals(""))
6173 if (currentNote.getUpdateSequenceNum() == 0) {
6174 setMessage(tr("Note has never been synchronized."));
6175 QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6179 setMessage(tr("Getting Note History"));
6181 Note currentOnlineNote = null;
6184 if (Global.isPremium())
6185 versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6187 versions = new ArrayList<NoteVersionId>();
6188 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6189 } catch (EDAMUserException e) {
6190 setMessage("EDAMUserException: " +e.getMessage());
6192 } catch (EDAMSystemException e) {
6193 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6194 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6196 setMessage("EDAMSystemException: " +e.getMessage());
6198 } catch (EDAMNotFoundException e) {
6199 setMessage(tr("Note not found on server."));
6200 QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6202 } catch (TException e) {
6203 setMessage("EDAMTransactionException: " +e.getMessage());
6207 // If we've gotten this far, we have a good note.
6208 if (historyWindow == null) {
6209 historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6211 historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6212 historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6213 historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6215 historyWindow.historyCombo.clear();
6217 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6218 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6220 historyWindow.setCurrent(isDirty);
6222 loadHistoryWindowContent(currentOnlineNote);
6223 historyWindow.load(versions);
6224 setMessage(tr("History retrieved"));
6226 historyWindow.exec();
6228 private Note reloadHistoryWindow(String selection) {
6230 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6231 String dateTimeFormat = new String(fmt);
6232 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6236 for (int i=0; i<versions.size(); i++) {
6237 StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6238 if (versionDate.toString().equals(selection))
6242 if (index > -1 || selection.indexOf("Current") > -1) {
6243 Note historyNote = null;
6246 usn = versions.get(index).getUpdateSequenceNum();
6247 historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6249 historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6250 } catch (EDAMUserException e) {
6251 setMessage("EDAMUserException: " +e.getMessage());
6254 } catch (EDAMSystemException e) {
6255 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6256 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6258 setMessage("EDAMSystemException: " +e.getMessage());
6261 } catch (EDAMNotFoundException e) {
6262 setMessage("EDAMNotFoundException: " +e.getMessage());
6265 } catch (TException e) {
6266 setMessage("EDAMTransactionException: " +e.getMessage());
6272 if (historyNote != null)
6273 historyWindow.setContent(historyNote);
6279 private void loadHistoryWindowContent(Note note) {
6280 note.setUpdateSequenceNum(0);
6281 historyWindow.setContent(note);
6283 @SuppressWarnings("unused")
6284 private void restoreHistoryNoteAsNew() {
6285 setMessage(tr("Restoring as new note."));
6286 duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6287 setMessage(tr("Note has been restored as a new note."));
6289 @SuppressWarnings("unused")
6290 private void restoreHistoryNote() {
6291 setMessage(tr("Restoring note."));
6292 Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6293 conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6296 for (int i=0; i<n.getResourcesSize(); i++) {
6297 n.getResources().get(i).setActive(true);
6298 conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6300 NoteMetadata metadata = new NoteMetadata();
6301 metadata.setGuid(n.getGuid());
6302 listManager.addNote(n, metadata);
6303 conn.getNoteTable().addNote(n, true);
6304 refreshEvernoteNote(true);
6305 setMessage(tr("Note has been restored."));
6307 @SuppressWarnings("unused")
6308 private void setupSelectiveSync() {
6310 // Get a list of valid notebooks
6311 List<Notebook> notebooks = null;
6312 List<Tag> tags = null;
6313 List<LinkedNotebook> linkedNotebooks = null;
6315 notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6316 tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6317 linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6318 } catch (EDAMUserException e) {
6319 setMessage("EDAMUserException: " +e.getMessage());
6321 } catch (EDAMSystemException e) {
6322 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6323 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6325 setMessage("EDAMSystemException: " +e.getMessage());
6327 } catch (TException e) {
6328 setMessage("EDAMTransactionException: " +e.getMessage());
6330 } catch (EDAMNotFoundException e) {
6331 setMessage("EDAMNotFoundException: " +e.getMessage());
6335 // Split up notebooks into synchronized & non-synchronized
6336 List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6337 List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6339 for (int i=notebooks.size()-1; i>=0; i--) {
6340 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6341 if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6342 ignoredBooks.add(notebooks.get(i));
6343 j=dbIgnoredNotebooks.size();
6348 // split up tags into synchronized & non-synchronized
6349 List<Tag> ignoredTags = new ArrayList<Tag>();
6350 List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6352 for (int i=tags.size()-1; i>=0; i--) {
6353 for (int j=0; j<dbIgnoredTags.size(); j++) {
6354 if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6355 ignoredTags.add(tags.get(i));
6356 j=dbIgnoredTags.size();
6361 // split up linked notebooks into synchronized & non-synchronized
6362 List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6363 List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6364 for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6365 String notebookGuid = linkedNotebooks.get(i).getGuid();
6366 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6367 if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6368 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6369 j=dbIgnoredLinkedNotebooks.size();
6374 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6376 if (!ignore.okClicked())
6381 // Clear out old notebooks & add the new ones
6382 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6383 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6384 conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6387 List<String> newNotebooks = new ArrayList<String>();
6388 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6389 String text = ignore.getIgnoredBookList().takeItem(i).text();
6390 for (int j=0; j<notebooks.size(); j++) {
6391 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6392 Notebook n = notebooks.get(j);
6393 conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6395 newNotebooks.add(n.getGuid());
6400 // Clear out old tags & add new ones
6401 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6402 for (int i=0; i<oldIgnoreTags.size(); i++) {
6403 conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6406 List<String> newTags = new ArrayList<String>();
6407 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6408 String text = ignore.getIgnoredTagList().takeItem(i).text();
6409 for (int j=0; j<tags.size(); j++) {
6410 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6411 Tag t = tags.get(j);
6412 conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6413 newTags.add(t.getGuid());
6419 // Clear out old tags & add new ones
6420 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6421 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6422 conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6425 List<String> newLinked = new ArrayList<String>();
6426 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6427 String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6428 for (int j=0; j<linkedNotebooks.size(); j++) {
6429 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6430 LinkedNotebook t = linkedNotebooks.get(j);
6431 conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6432 newLinked.add(t.getGuid());
6433 j=linkedNotebooks.size();
6438 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6444 //**********************************************************
6445 //**********************************************************
6446 //* XML Modifying methods
6447 //**********************************************************
6448 //**********************************************************
6449 // An error has happended fetching a resource. let the user know
6450 private void resourceErrorMessage(int tabIndex) {
6454 if (inkNote.get(tabIndex))
6457 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6458 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6459 "In a perfect world this wouldn't happen, but it has.\n" +
6460 "It is embarasing when a program like me, designed to save all your\n"+
6461 "precious data, has a problem finding data.\n\n" +
6462 "I guess life isn't fair, but I'll survive. Somehow...\n\n" +
6463 "In the mean time, I'm not going to let you make changes to this note.\n" +
6464 "Don't get angry. I'm doing it to prevent you from messing up\n"+
6465 "this note on the Evernote servers. Sorry."+
6466 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6467 inkNote.put(tabIndex, true);
6468 browserWindow.setReadOnly(true);
6475 //**********************************************************
6476 //**********************************************************
6478 //**********************************************************
6479 //**********************************************************
6480 // We should now do a sync with Evernote
6481 private void syncTimer() {
6482 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6483 syncRunner.syncNeeded = true;
6484 syncRunner.disableUploads = Global.disableUploads;
6486 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6488 private void syncStart() {
6489 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6491 if (!syncRunning && Global.isConnected) {
6492 syncRunner.setConnected(true);
6493 syncRunner.setKeepRunning(Global.keepRunning);
6494 syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6496 if (syncThreadsReady > 0) {
6497 thumbnailRunner.interrupt = true;
6498 saveNoteIndexWidth();
6499 saveNoteColumnPositions();
6500 if (syncRunner.addWork("SYNC")) {
6502 syncRunner.syncNeeded = true;
6507 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6509 @SuppressWarnings("unused")
6510 private void syncThreadComplete(Boolean refreshNeeded) {
6511 setMessage(tr("Finalizing Synchronization"));
6513 syncRunning = false;
6514 syncRunner.syncNeeded = false;
6515 synchronizeAnimationTimer.stop();
6516 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6518 if (currentNote == null) {
6519 currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6521 listManager.refreshNoteMetadata();
6522 noteIndexUpdated(true);
6523 noteTableView.selectionModel().blockSignals(true);
6524 scrollToGuid(currentNoteGuid);
6525 noteTableView.selectionModel().blockSignals(false);
6526 refreshEvernoteNote(false);
6527 scrollToGuid(currentNoteGuid);
6530 // Check to see if there were any shared notebook errors
6531 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6532 String guid = syncRunner.errorSharedNotebooks.get(0);
6533 String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6534 String localName = listManager.getNotebookNameByGuid(notebookGuid);
6535 SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6537 if (syncDialog.okPressed()) {
6538 if (syncDialog.doNothing.isChecked()) {
6539 syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6542 if (syncDialog.deleteNotebook.isChecked()) {
6543 conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6544 conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6545 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6546 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6554 // Finalize the synchronization
6555 if (!syncRunner.error)
6556 setMessage(tr("Synchronization Complete"));
6558 setMessage(tr("Synchronization completed with errors. Please check the log for details."));
6559 logger.log(logger.MEDIUM, "Sync complete.");
6561 public void saveUploadAmount(long t) {
6562 Global.saveUploadAmount(t);
6564 public void saveUserInformation(User user) {
6565 Global.saveUserInformation(user);
6567 public void saveEvernoteUpdateCount(int i) {
6568 Global.saveEvernoteUpdateCount(i);
6570 public void refreshLists() {
6571 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6573 // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。
6574 Collection<Integer> tabIndex = noteDirty.keySet();
6575 Iterator<Integer> indexIterator = tabIndex.iterator();
6576 HashMap<Integer, Note> saveNotes = new HashMap<Integer, Note>();
6577 HashMap<Integer, String> saveContents = new HashMap<Integer, String>();
6578 for (boolean isNoteDirty: noteDirty.values()) {
6579 int index = indexIterator.next();
6581 saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote());
6582 saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent());
6586 listManager.saveUpdatedNotes(saveNotes, saveContents);
6587 listManager.refreshLists();
6589 tagIndexUpdated(true);
6590 notebookIndexUpdated();
6591 savedSearchIndexUpdated();
6592 listManager.loadNotesIndex();
6594 noteTableView.selectionModel().blockSignals(true);
6595 noteIndexUpdated(true);
6596 noteTableView.selectionModel().blockSignals(false);
6597 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6601 @SuppressWarnings("unused")
6602 private void authTimer() {
6603 Calendar cal = Calendar.getInstance();
6605 // If we are not connected let's get out of here
6606 if (!Global.isConnected)
6609 // If this is the first time through, then we need to set this
6610 // if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime)
6611 // syncRunner.authRefreshTime = cal.getTimeInMillis();
6613 // long now = new Date().getTime();
6614 // if (now > Global.authRefreshTime && Global.isConnected) {
6615 syncRunner.authRefreshNeeded = true;
6619 @SuppressWarnings("unused")
6620 private void authRefreshComplete(boolean goodSync) {
6621 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6622 Global.isConnected = syncRunner.isConnected;
6624 // authTimer.start((int)syncRunner.authTimeRemaining/4);
6625 authTimer.start(1000*60*15);
6626 logger.log(logger.LOW, "Authentication token has been renewed");
6627 // setMessage("Authentication token has been renewed.");
6629 authTimer.start(1000*60*5);
6630 logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6631 // setMessage("Authentication token renew has failed - retry in 5 minutes.");
6633 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6637 @SuppressWarnings("unused")
6638 private synchronized void indexTimer() {
6639 logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning);
6642 if (!indexDisabled && indexRunner.idle) {
6643 thumbnailRunner.interrupt = true;
6644 indexRunner.addWork("SCAN");
6646 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6649 @SuppressWarnings("unused")
6650 private void indexStarted() {
6651 setMessage(tr("Indexing notes"));
6653 @SuppressWarnings("unused")
6654 private void indexComplete() {
6655 setMessage(tr("Index complete"));
6657 @SuppressWarnings("unused")
6658 private synchronized void toggleNoteIndexing() {
6659 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6660 indexDisabled = !indexDisabled;
6662 setMessage(tr("Indexing is now enabled."));
6664 setMessage(tr("Indexing is now disabled."));
6665 menuBar.disableIndexing.setChecked(indexDisabled);
6666 logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6669 @SuppressWarnings("unused")
6670 private void threadMonitorCheck() {
6675 alive = listManager.threadCheck(Global.tagCounterThreadId);
6678 if (tagDeadCount > MAX && !disableTagThreadCheck) {
6679 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
6680 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6681 disableTagThreadCheck = true;
6686 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6688 notebookThreadDeadCount++;
6689 if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6690 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
6691 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6692 disableNotebookThreadCheck=true;
6695 notebookThreadDeadCount=0;
6697 alive = listManager.threadCheck(Global.trashCounterThreadId);
6700 if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6701 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
6702 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6703 disableTrashThreadCheck = true;
6708 alive = listManager.threadCheck(Global.saveThreadId);
6710 saveThreadDeadCount++;
6711 if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6712 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
6713 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6714 disableSaveThreadCheck = true;
6717 saveThreadDeadCount=0;
6719 if (!syncThread.isAlive()) {
6720 syncThreadDeadCount++;
6721 if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6722 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
6723 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6724 disableSyncThreadCheck = true;
6727 syncThreadDeadCount=0;
6729 if (!indexThread.isAlive()) {
6730 indexThreadDeadCount++;
6731 if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6732 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
6733 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6734 disableIndexThreadCheck = true;
6737 indexThreadDeadCount=0;
6739 if (!rensoNoteListDock.getRensoNoteList().getEnRelatedNotesThread().isAlive()) {
6740 enRelatedNotesThreadDeadCount++;
6741 if (enRelatedNotesThreadDeadCount > MAX && !disableENRelatedNotesThreadCheck) {
6742 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the Evernote Related Notes thread has died. I recommend "+
6743 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6744 disableENRelatedNotesThreadCheck = true;
6747 enRelatedNotesThreadDeadCount=0;
6750 private void thumbnailTimer() {
6751 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6752 thumbnailRunner.addWork("SCAN");
6756 //**************************************************
6757 //* Backup & Restore
6758 //**************************************************
6759 @SuppressWarnings("unused")
6760 private void databaseBackup() {
6761 QFileDialog fd = new QFileDialog(this);
6762 fd.setFileMode(FileMode.AnyFile);
6763 fd.setConfirmOverwrite(true);
6764 fd.setWindowTitle(tr("Backup Database"));
6765 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6766 fd.setAcceptMode(AcceptMode.AcceptSave);
6767 if (saveLastPath == null || saveLastPath.equals(""))
6768 fd.setDirectory(System.getProperty("user.home"));
6770 fd.setDirectory(saveLastPath);
6771 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6777 saveLastPath = fd.selectedFiles().get(0);
6778 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6779 setMessage(tr("Backing up database"));
6781 // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6783 ExportData noteWriter = new ExportData(conn, true);
6784 String fileName = fd.selectedFiles().get(0);
6786 if (!fileName.endsWith(".nnex"))
6787 fileName = fileName +".nnex";
6788 noteWriter.exportData(fileName);
6789 setMessage(tr("Database backup completed."));
6794 @SuppressWarnings("unused")
6795 private void databaseRestore() {
6796 if (QMessageBox.question(this, tr("Confirmation"),
6797 tr("This is used to restore a database from backups.\n" +
6798 "It is HIGHLY recommened that this only be used to populate\n" +
6799 "an empty database. Restoring into a database that\n already has data" +
6800 " can cause problems.\n\nAre you sure you want to continue?"),
6801 QMessageBox.StandardButton.Yes,
6802 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6807 QFileDialog fd = new QFileDialog(this);
6808 fd.setFileMode(FileMode.ExistingFile);
6809 fd.setConfirmOverwrite(true);
6810 fd.setWindowTitle(tr("Restore Database"));
6811 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6812 fd.setAcceptMode(AcceptMode.AcceptOpen);
6813 if (saveLastPath == null || saveLastPath.equals(""))
6814 fd.setDirectory(System.getProperty("user.home"));
6816 fd.setDirectory(saveLastPath);
6817 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6823 saveLastPath = fd.selectedFiles().get(0);
6824 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6826 setMessage(tr("Restoring database"));
6827 ImportData noteReader = new ImportData(conn, true);
6828 noteReader.importData(fd.selectedFiles().get(0));
6830 if (noteReader.lastError != 0) {
6831 setMessage(noteReader.getErrorMessage());
6832 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6837 listManager.loadNoteTitleColors();
6839 refreshEvernoteNote(true);
6840 setMessage(tr("Database has been restored."));
6843 @SuppressWarnings("unused")
6844 private void exportNotes() {
6845 QFileDialog fd = new QFileDialog(this);
6846 fd.setFileMode(FileMode.AnyFile);
6847 fd.setConfirmOverwrite(true);
6848 fd.setWindowTitle(tr("Backup Database"));
6849 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6850 fd.setAcceptMode(AcceptMode.AcceptSave);
6851 fd.setDirectory(System.getProperty("user.home"));
6852 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6858 setMessage(tr("Exporting Notes"));
6861 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6862 selectedNoteGUIDs.add(currentNoteGuid);
6864 ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6865 String fileName = fd.selectedFiles().get(0);
6867 if (!fileName.endsWith(".nnex"))
6868 fileName = fileName +".nnex";
6869 noteWriter.exportData(fileName);
6870 setMessage(tr("Export completed."));
6876 @SuppressWarnings("unused")
6877 private void importNotes() {
6878 QFileDialog fd = new QFileDialog(this);
6879 fd.setFileMode(FileMode.ExistingFile);
6880 fd.setConfirmOverwrite(true);
6881 fd.setWindowTitle(tr("Import Notes"));
6882 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6883 fd.setAcceptMode(AcceptMode.AcceptOpen);
6884 if (saveLastPath == null || saveLastPath.equals(""))
6885 fd.setDirectory(System.getProperty("user.home"));
6887 fd.setDirectory(saveLastPath);
6888 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6894 setMessage(tr("Importing Notes"));
6897 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6898 selectedNoteGUIDs.add(currentNoteGuid);
6900 String fileName = fd.selectedFiles().get(0);
6901 // saveLastPath.substring(0,fileName.lastIndexOf("/"));
6903 if (fileName.endsWith(".nnex")) {
6904 ImportData noteReader = new ImportData(conn, false);
6905 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6906 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6908 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6910 noteReader.importData(fileName);
6912 if (noteReader.lastError != 0) {
6913 setMessage(noteReader.getErrorMessage());
6914 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6919 if (fileName.endsWith(".enex")) {
6920 ImportEnex noteReader = new ImportEnex(conn, false);
6921 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6922 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6924 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6927 if (QMessageBox.question(this, tr("Confirmation"),
6928 tr("Create new tags from import?"),
6929 QMessageBox.StandardButton.Yes,
6930 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6931 noteReader.createNewTags = true;
6933 noteReader.createNewTags = false;
6935 noteReader.importData(fileName);
6937 if (noteReader.lastError != 0) {
6938 setMessage(noteReader.getErrorMessage());
6939 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6946 listManager.loadNoteTitleColors();
6948 refreshEvernoteNote(false);
6949 setMessage(tr("Notes have been imported."));
6952 setMessage(tr("Import completed."));
6959 //**************************************************
6960 //* Duplicate a note
6961 //**************************************************
6962 @SuppressWarnings("unused")
6963 private void duplicateNote() {
6965 duplicateNote(currentNoteGuid);
6968 //**************************************************
6969 //* Action from when a user clicks Copy As URL
6970 //**************************************************
6971 @SuppressWarnings("unused")
6972 private void copyAsUrlClicked() {
6973 QClipboard clipboard = QApplication.clipboard();
6974 QMimeData mime = new QMimeData();
6976 mime.setText(currentNoteGuid);
6977 List<QUrl> urls = new ArrayList<QUrl>();
6979 // Start building the URL
6980 User user = Global.getUserInformation();
6982 // Check that we have everything we need
6983 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
6984 SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
6986 if (!warning.neverSynchronize())
6989 Global.setBypassSynchronizationWarning(true);
6990 user.setShardId("s0");
6996 // Start building a list of URLs based upon the selected notes
6997 noteTableView.showColumn(Global.noteTableGuidPosition);
6999 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
7000 if (!Global.isColumnVisible("guid"))
7001 noteTableView.hideColumn(Global.noteTableGuidPosition);
7003 // Check that the note is either synchronized, or in a local notebook
7004 for (int i=0; i<selections.size(); i++) {
7006 int row = selections.get(i).row();
7007 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7008 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7009 String selectedGuid = (String)ix.values().toArray()[0];
7011 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7012 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
7013 QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
7014 "new notes to a local notebook."));
7019 // Start building the URLs
7020 for (int i=0; i<selections.size(); i++) {
7022 int row = selections.get(i).row();
7023 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7024 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7025 String selectedGuid = (String)ix.values().toArray()[0];
7026 mime.setText(selectedGuid);
7030 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7031 if (selectedNote.getUpdateSequenceNum() > 0) {
7035 gid = "00000000-0000-0000-0000-000000000000";
7038 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
7040 urls.add(new QUrl(url));
7043 clipboard.setMimeData(mime);
7047 //**************************************************
7049 //**************************************************
7050 public void setupFolderImports() {
7051 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
7053 if (importKeepWatcher == null)
7054 importKeepWatcher = new QFileSystemWatcher();
7055 if (importDeleteWatcher == null) {
7056 importDeleteWatcher = new QFileSystemWatcher();
7057 for (int i=0; i<records.size(); i++) {
7058 if (!records.get(i).keep)
7059 folderImportDelete(records.get(i).folder);
7065 // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
7066 for (int i=0; i<records.size(); i++) {
7067 logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
7068 if (records.get(i).keep)
7069 importKeepWatcher.addPath(records.get(i).folder);
7071 importDeleteWatcher.addPath(records.get(i).folder);
7074 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
7075 List<String> monitorDelete = importKeepWatcher.directories();
7076 for (int i=0; i<monitorDelete.size(); i++) {
7077 logger.log(logger.EXTREME, monitorDelete.get(i));
7079 logger.log(logger.EXTREME, "<end of list>");
7080 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
7081 monitorDelete = importDeleteWatcher.directories();
7082 for (int i=0; i<monitorDelete.size(); i++) {
7083 logger.log(logger.EXTREME, monitorDelete.get(i));
7085 logger.log(logger.EXTREME, "<end of list>");
7087 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
7088 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
7090 // Look at the files already there so we don't import them again if a new file is created
7091 if (importedFiles == null) {
7092 importedFiles = new ArrayList<String>();
7093 for (int j=0; j<records.size(); j++) {
7094 QDir dir = new QDir(records.get(j).folder);
7095 List<QFileInfo> list = dir.entryInfoList();
7096 for (int k=0; k<list.size(); k++) {
7097 if (list.get(k).isFile())
7098 importedFiles.add(list.get(k).absoluteFilePath());
7104 // Menu folderImport action triggered
7105 public void folderImport() {
7106 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
7107 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
7109 if (!dialog.okClicked())
7112 // We have some sort of update.
7113 if (importKeepWatcher.directories().size() > 0)
7114 importKeepWatcher.removePaths(importKeepWatcher.directories());
7115 if (importDeleteWatcher.directories().size() > 0)
7116 importDeleteWatcher.removePaths(importDeleteWatcher.directories());
7118 conn.getWatchFolderTable().expungeAll();
7119 // Start building from the table
7120 for (int i=0; i<dialog.table.rowCount(); i++) {
7121 QTableWidgetItem item = dialog.table.item(i, 0);
7122 String dir = item.text();
7123 item = dialog.table.item(i, 1);
7124 String notebook = item.text();
7125 item = dialog.table.item(i, 2);
7127 if (item.text().equalsIgnoreCase("Keep"))
7132 String guid = conn.getNotebookTable().findNotebookByName(notebook);
7133 conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
7135 setupFolderImports();
7139 public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
7140 logger.log(logger.LOW, "Inside folderImportKeep");
7141 String whichOS = System.getProperty("os.name");
7142 if (whichOS.contains("Windows"))
7143 dirName = dirName.replace('/','\\');
7145 FileImporter importer = new FileImporter(logger, conn);
7147 QDir dir = new QDir(dirName);
7148 List<QFileInfo> list = dir.entryInfoList();
7149 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7151 for (int i=0; i<list.size(); i++){
7152 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7153 boolean redundant = false;
7154 // Check if we've already imported this one or if it existed before
7155 for (int j=0; j<importedFiles.size(); j++) {
7156 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7157 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7161 logger.log(logger.LOW, "Checking if redundant: " +redundant);
7163 importer.setFileInfo(list.get(i));
7164 importer.setFileName(list.get(i).absoluteFilePath());
7167 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7168 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7169 if (list.get(i).isFile() && importer.isValidType()) {
7171 if (!importer.importFile()) {
7172 // If we can't get to the file, it is probably locked. We'll try again later.
7173 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7174 importFilesKeep.add(list.get(i).absoluteFilePath());
7177 Note newNote = importer.getNote();
7178 newNote.setNotebookGuid(notebook);
7179 newNote.setTitle(dir.at(i));
7180 NoteMetadata metadata = new NoteMetadata();
7181 metadata.setDirty(true);
7182 metadata.setGuid(newNote.getGuid());
7183 listManager.addNote(newNote, metadata);
7184 conn.getNoteTable().addNote(newNote, true);
7185 noteTableView.insertRow(newNote, metadata, true, -1);
7186 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7187 listManager.countNotebookResults(listManager.getNoteIndex());
7188 importedFiles.add(list.get(i).absoluteFilePath());
7197 public void folderImportDelete(String dirName) {
7198 logger.log(logger.LOW, "Inside folderImportDelete");
7199 String whichOS = System.getProperty("os.name");
7200 if (whichOS.contains("Windows"))
7201 dirName = dirName.replace('/','\\');
7203 FileImporter importer = new FileImporter(logger, conn);
7204 QDir dir = new QDir(dirName);
7205 List<QFileInfo> list = dir.entryInfoList();
7206 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7208 for (int i=0; i<list.size(); i++){
7209 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7210 importer.setFileInfo(list.get(i));
7211 importer.setFileName(list.get(i).absoluteFilePath());
7213 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7214 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7215 if (list.get(i).isFile() && importer.isValidType()) {
7217 if (!importer.importFile()) {
7218 // If we can't get to the file, it is probably locked. We'll try again later.
7219 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7220 importFilesKeep.add(list.get(i).absoluteFilePath());
7223 Note newNote = importer.getNote();
7224 newNote.setNotebookGuid(notebook);
7225 newNote.setTitle(dir.at(i));
7226 NoteMetadata metadata = new NoteMetadata();
7227 metadata.setDirty(true);
7228 metadata.setGuid(newNote.getGuid());
7229 listManager.addNote(newNote, metadata);
7230 conn.getNoteTable().addNote(newNote, true);
7231 noteTableView.insertRow(newNote, metadata, true, -1);
7232 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7233 listManager.countNotebookResults(listManager.getNoteIndex());
7234 dir.remove(dir.at(i));
7241 //**************************************************
7243 //**************************************************
7244 private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7245 logger.log(logger.HIGH, "Entering exernalFileEdited");
7247 // Strip URL prefix and base dir path
7248 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7249 String name = fileName.replace(dPath, "");
7250 int pos = name.lastIndexOf('.');
7253 guid = guid.substring(0,pos);
7255 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7257 guid = name.substring(0, pos);
7260 QFile file = new QFile(fileName);
7261 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
7262 // If we can't get to the file, it is probably locked. We'll try again later.
7263 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7264 externalFiles.add(fileName);
7267 QByteArray binData = file.readAll();
7269 if (binData.size() == 0) {
7270 // If we can't get to the file, it is probably locked. We'll try again later.
7271 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7272 externalFiles.add(fileName);
7276 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7278 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7279 if (r == null || r.getData() == null || r.getData().getBody() == null)
7281 String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7282 MessageDigest md = MessageDigest.getInstance("MD5");
7283 md.update(binData.toByteArray());
7284 byte[] hash = md.digest();
7285 String newHash = Global.byteArrayToHexString(hash);
7286 if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7287 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7289 if (externalWindows.containsKey(r.getNoteGuid())) {
7290 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(),
7291 r.getGuid(), oldHash, newHash);
7293 conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7294 Data data = r.getData();
7295 data.setBody(binData.toByteArray());
7296 data.setBodyHash(hash);
7297 logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7299 conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7301 if (r.getNoteGuid().equals(currentNoteGuid)) {
7302 QWebSettings.setMaximumPagesInCache(0);
7303 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7304 refreshEvernoteNote(true);
7305 browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7308 if (externalWindows.containsKey(r.getNoteGuid())) {
7309 QWebSettings.setMaximumPagesInCache(0);
7310 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7311 externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7315 logger.log(logger.HIGH, "Exiting externalFielEdited");
7317 // This is a timer event that tries to save any external files that were edited. This
7318 // is only needed if we couldn't save a file earlier.
7319 public void externalFileEditedSaver() {
7320 for (int i=externalFiles.size()-1; i>=0; i--) {
7322 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7323 externalFileEdited(externalFiles.get(i));
7324 externalFiles.remove(i);
7325 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7327 for (int i=0; i<importFilesKeep.size(); i++) {
7329 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7330 folderImportKeep(importFilesKeep.get(i));
7331 importFilesKeep.remove(i);
7332 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7334 for (int i=0; i<importFilesDelete.size(); i++) {
7335 logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7336 folderImportDelete(importFilesDelete.get(i));
7337 importFilesDelete.remove(i);
7344 // If an attachment on the current note was edited, we need to update the current notes's hash
7345 // Update a note content's hash. This happens if a resource is edited outside of NN
7346 public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7347 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7349 for (;position>-1;) {
7350 endPos = browser.getContent().indexOf(">", position+1);
7351 String oldSegment = browser.getContent().substring(position,endPos);
7352 int hashPos = oldSegment.indexOf("hash=\"");
7353 int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7354 String hash = oldSegment.substring(hashPos+6, hashEnd);
7355 if (hash.equalsIgnoreCase(oldHash)) {
7356 String newSegment = oldSegment.replace(oldHash, newHash);
7357 String content = browser.getContent().substring(0,position) +
7359 browser.getContent().substring(endPos);
7360 browser.setContent(new QByteArray(content));;
7363 position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7368 //*************************************************
7369 //* Minimize to tray
7370 //*************************************************
7372 public void changeEvent(QEvent e) {
7373 if (e.type() == QEvent.Type.WindowStateChange) {
7374 if (QSystemTrayIcon.isSystemTrayAvailable()) {
7375 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7377 QTimer.singleShot(10, this, "hide()");
7381 windowMaximized = true;
7383 windowMaximized = false;
7388 //*************************************************
7389 //* Check database userid & passwords
7390 //*************************************************
7391 private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7392 Connection connection;
7395 Class.forName("org.h2.Driver");
7396 } catch (ClassNotFoundException e1) {
7397 e1.printStackTrace();
7402 String passwordString = null;
7403 if (cypherPassword==null || cypherPassword.trim().equals(""))
7404 passwordString = userPassword;
7406 passwordString = cypherPassword+" "+userPassword;
7407 connection = DriverManager.getConnection(url,userid,passwordString);
7408 } catch (SQLException e) {
7413 } catch (SQLException e) {
7414 e.printStackTrace();
7419 //*************************************************
7420 //* View / Hide source HTML for a note
7421 //*************************************************
7422 public void viewSource() {
7424 for(int i = 0; i < tabBrowser.count(); i++){
7425 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7426 browser.showSource(menuBar.viewSource.isChecked());
7429 //*************************************************
7430 // Block the program. This is used for things
7431 // like async web calls.
7432 //*************************************************
7433 @SuppressWarnings("unused")
7434 private void blockApplication(BrowserWindow b) {
7435 // Block all signals
7439 blockTimer = new QTimer();
7440 blockTimer.setSingleShot(true);
7441 blockTimer.setInterval(15000);
7442 blockTimer.timeout.connect(this, "unblockApplication()");
7447 @SuppressWarnings("unused")
7448 private void unblockApplication() {
7450 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7451 QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7452 blockingWindow.unblockTime = -1;
7453 blockingWindow.awaitingHttpResponse = false;
7455 blockingWindow = null;
7456 blockSignals(false);
7460 private void tabWindowChanged(int index) {
7461 if (index < 0 || index >= tabBrowser.count()) {
7467 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7468 if (tab.getBrowserWindow().getNote() != null) {
7469 currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7470 currentNote = tab.getBrowserWindow().getNote();
7472 currentNoteGuid = "";
7477 selectedNoteGUIDs.clear();
7478 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7479 selectedNoteGUIDs.add(currentNoteGuid);
7483 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7484 browserWindow.focusLost.disconnect(this, "saveNote()");
7485 browserWindow = tab.getBrowserWindow();
7486 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7487 browserWindow.focusLost.connect(this, "saveNote()");
7488 // メニューバーのボタンを新しいbrowserWindowに合わせる
7489 menuBar.refreshTargetWindow();
7491 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7492 boolean nextIsActive;
7493 if (tab.getBrowserWindow().getNote() != null) {
7494 nextIsActive = tab.getBrowserWindow().getNote().isActive();
7496 nextIsActive = true;
7498 if (Global.showDeleted && nextIsActive) {
7499 switchNoteTable(false);
7500 } else if (!Global.showDeleted && !nextIsActive) {
7501 switchNoteTable(true);
7504 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7505 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7506 scrollToGuid(currentNoteGuid);
7508 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7510 menuBar.noteDuplicateAction.setEnabled(true);
7511 menuBar.noteOnlineHistoryAction.setEnabled(true);
7512 menuBar.noteMergeAction.setEnabled(true);
7514 if (Global.showDeleted) {
7515 menuBar.noteDuplicateAction.setEnabled(false);
7517 if (!Global.isConnected) {
7518 menuBar.noteOnlineHistoryAction.setEnabled(false);
7520 menuBar.noteMergeAction.setEnabled(false);
7522 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7524 upButton.setEnabled(false);
7526 upButton.setEnabled(true);
7527 if (row < listManager.getNoteTableModel().rowCount() - 1)
7528 downButton.setEnabled(true);
7530 downButton.setEnabled(false);
7531 } catch (Exception e) {
7532 upButton.setEnabled(false);
7533 downButton.setEnabled(false);
7536 int currentIndex = tabBrowser.currentIndex();
7537 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7538 int histPosition = historyPosition.get(currentIndex);
7540 // prev, nextボタンの有効・無効化
7541 nextButton.setEnabled(true);
7542 prevButton.setEnabled(true);
7544 if (histPosition <= 1){
7545 prevButton.setEnabled(false);
7547 if (histPosition == histGuids.size()){
7548 nextButton.setEnabled(false);
7551 refreshEvernoteNote(true);
7554 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7557 // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7558 private void switchNoteTable(boolean toDeleted) {
7559 clearNotebookFilter();
7561 clearAttributeFilter();
7562 clearSavedSearchFilter();
7564 listManager.getSelectedNotebooks().clear();
7565 listManager.getSelectedTags().clear();
7566 listManager.setSelectedSavedSearch("");
7568 // toggle the add buttons
7569 newButton.setEnabled(!newButton.isEnabled());
7570 menuBar.noteAdd.setEnabled(newButton.isEnabled());
7571 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
7572 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
7573 menuBar.noteAddNewTab.setEnabled(false);
7575 menuBar.noteAdd.setVisible(true);
7577 if (!toDeleted) { // 生存ノートテーブルへ
7578 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7579 trashTree.clearSelection();
7580 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7581 Global.showDeleted = false;
7582 menuBar.noteRestoreAction.setEnabled(false);
7583 menuBar.noteRestoreAction.setVisible(false);
7584 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7585 rensoNoteListDock.setEnabled(true);
7587 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7588 trashTree.setCurrentItem(trashTree.getTrashItem());
7589 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7590 Global.showDeleted = true;
7591 menuBar.noteRestoreAction.setEnabled(true);
7592 menuBar.noteRestoreAction.setVisible(true);
7593 // ゴミ箱を開く。連想ノートリストをOFFに。
7594 rensoNoteListDock.setEnabled(false);
7597 listManager.loadNotesIndex();
7598 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7599 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7600 noteIndexUpdated(false);
7602 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7604 browserWindow.setReadOnly(!newButton.isEnabled());
7607 // ユーザが連想ノートリストのアイテムを選択した時の処理
7608 @SuppressWarnings("unused")
7609 private void rensoNoteItemPressed(QListWidgetItem current) {
7610 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7612 rensoNotePressedItemGuid = rensoNoteListDock.getRensoNoteList().getNoteGuid(current);
7615 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7621 String prevCurrentNoteGuid = new String(currentNoteGuid);
7623 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
7624 QModelIndex modelIndex = noteTableView.model().index(i,
7625 Global.noteTableGuidPosition);
7626 if (modelIndex != null) {
7627 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
7629 String tableGuid = (String) ix.values().toArray()[0];
7630 if (tableGuid.equals(rensoNotePressedItemGuid)) {
7631 noteTableView.selectRow(i);
7637 // 連想ノートリストアイテムクリック操作を記録
7638 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7640 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7643 // 関連ノートリストからノートを除外する
7644 @SuppressWarnings("unused")
7645 private void excludeNote() {
7646 if (rensoNotePressedItemGuid != null) {
7648 excludeNote(rensoNotePressedItemGuid);
7652 // 関連ノートリストからノートを除外する
7653 private void excludeNote(String guid) {
7654 if (Global.verifyExclude()) {
7656 Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7657 String title = note.getTitle();
7658 if (title != null) {
7659 msg = new String(tr("Exclude note \"") +title +"\"?");
7661 msg = new String(tr("Exclude note selected note?"));
7664 if (QMessageBox.question(this, tr("Confirmation"), msg,
7665 QMessageBox.StandardButton.Yes,
7666 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7671 // Historyデータベースから除外するノートのデータを削除
7672 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7675 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7677 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7680 // 関連ノートリストのノートにスターを付ける
7681 @SuppressWarnings("unused")
7682 private void starNote() {
7683 if (rensoNotePressedItemGuid != null) {
7685 starNote(rensoNotePressedItemGuid);
7689 // 関連ノートリストのノートにスターを付ける
7690 private void starNote(String guid) {
7692 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7694 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7697 // 関連ノートリストのノートからスターを外す
7698 @SuppressWarnings("unused")
7699 private void unstarNote() {
7700 if (rensoNotePressedItemGuid != null) {
7702 unstarNote(rensoNotePressedItemGuid);
7706 // 関連ノートリストのノートからスターを外す
7707 private void unstarNote(String guid) {
7709 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7711 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7714 // currentNoteGuidを返す
7715 public String getCurrentNoteGuid() {
7716 return currentNoteGuid;
7719 @SuppressWarnings("unused")
7720 // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える
7721 private void tabIndexChanged(int from, int to) {
7723 TabBrowse tab = tabWindows.get(from);
7724 tabWindows.put(from, tabWindows.get(to));
7725 tabWindows.put(to, tab);
7727 boolean isNoteDirty = noteDirty.get(from);
7728 noteDirty.put(from, noteDirty.get(to));
7729 noteDirty.put(to, isNoteDirty);
7731 boolean isInkNote = inkNote.get(from);
7732 inkNote.put(from, inkNote.get(to));
7733 inkNote.put(to, isInkNote);
7735 boolean isReadOnly = readOnly.get(from);
7736 readOnly.put(from, readOnly.get(to));
7737 readOnly.put(to, isReadOnly);
7739 ArrayList<String> histGuids = historyGuids.get(from);
7740 historyGuids.put(from, historyGuids.get(to));
7741 historyGuids.put(to, histGuids);
7743 int histPosition = historyPosition.get(from);
7744 historyPosition.put(from, historyPosition.get(to));
7745 historyPosition.put(to, histPosition);
7747 boolean fromHist = fromHistory.get(from);
7748 fromHistory.put(from, fromHistory.get(to));
7749 fromHistory.put(to, fromHist);
7753 public RensoNoteList getRensoNoteList() {
7754 return rensoNoteListDock.getRensoNoteList();
7758 @SuppressWarnings("unused")
7759 private void informRateLimit(Integer rateLimitDuration) {
7760 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + rateLimitDuration + tr(" seconds."));
7763 // ツールバーの「新規」ボタンの接続スロットを設定
7764 public void connectNewButtonSlot(String slot) {
7765 newButton.triggered.disconnect();
7766 newButton.triggered.connect(this, slot);