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();
1642 String stackName = "";
1643 if (selections.size() > 0) {
1644 guid = (selections.get(0).text(2));
1645 stackName = selections.get(0).text(0);
1647 if (!Global.mimicEvernoteInterface) {
1648 // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1649 if (selections.size()==0) {
1650 selectedNotebookGUIDs.clear();
1651 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1652 selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1654 menuBar.notebookEditAction.setEnabled(false);
1655 menuBar.notebookDeleteAction.setEnabled(false);
1656 menuBar.notebookStackAction.setEnabled(false);
1657 menuBar.notebookIconAction.setEnabled(false);
1660 if (!guid.equals("") && !guid.equals("STACK")) {
1661 selectedNotebookGUIDs.add(guid);
1662 menuBar.notebookIconAction.setEnabled(true);
1664 menuBar.notebookIconAction.setEnabled(true);
1665 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1666 Notebook book = listManager.getNotebookIndex().get(j);
1667 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1668 selectedNotebookGUIDs.add(book.getGuid());
1671 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1672 listManager.loadNotesIndex();
1673 noteIndexUpdated(false);
1674 refreshEvernoteNote(true);
1675 listManager.refreshCounters = true;
1676 listManager.refreshCounters();
1677 if (selectedNotebookGUIDs.size() == 1) {
1678 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1679 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1681 noteTableView.proxyModel.blocked = true;
1683 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1685 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1688 noteTableView.proxyModel.blocked = false;
1689 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1692 private void clearNotebookFilter() {
1693 notebookTree.blockSignals(true);
1694 notebookTree.clearSelection();
1695 menuBar.noteRestoreAction.setVisible(false);
1696 menuBar.notebookEditAction.setEnabled(false);
1697 menuBar.notebookDeleteAction.setEnabled(false);
1698 selectedNotebookGUIDs.clear();
1699 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1700 notebookTree.blockSignals(false);
1702 // Triggered when the notebook DB has been updated
1703 private void notebookIndexUpdated() {
1704 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1706 // Get the possible icons
1707 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1708 notebookTree.setIcons(icons);
1710 if (selectedNotebookGUIDs == null)
1711 selectedNotebookGUIDs = new ArrayList<String>();
1712 List<Notebook> books = conn.getNotebookTable().getAll();
1713 for (int i=books.size()-1; i>=0; i--) {
1714 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1715 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1717 j=listManager.getArchiveNotebookIndex().size();
1723 listManager.countNotebookResults(listManager.getNoteIndex());
1724 notebookTree.blockSignals(true);
1725 notebookTree.load(books, listManager.getLocalNotebooks());
1726 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1727 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1729 selectedNotebookGUIDs.remove(i);
1731 listManager.refreshCounters = true;
1732 listManager.refreshCounters();
1733 notebookTree.blockSignals(false);
1735 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1737 // Show/Hide note information
1738 @SuppressWarnings("unused")
1739 private void toggleNotebookWindow() {
1740 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1741 zoomLayout.toggleNotebook();
1742 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1743 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1744 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1746 // Add a new notebook
1747 @SuppressWarnings("unused")
1748 private void addNotebook() {
1749 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1750 NotebookEdit edit = new NotebookEdit();
1751 edit.setNotebooks(listManager.getNotebookIndex());
1754 if (!edit.okPressed())
1757 Calendar currentTime = new GregorianCalendar();
1758 Long l = new Long(currentTime.getTimeInMillis());
1759 String randint = new String(Long.toString(l));
1761 Notebook newBook = new Notebook();
1762 newBook.setUpdateSequenceNum(0);
1763 newBook.setGuid(randint);
1764 newBook.setName(edit.getNotebook());
1765 newBook.setServiceCreated(new Date().getTime());
1766 newBook.setServiceUpdated(new Date().getTime());
1767 newBook.setDefaultNotebook(false);
1768 newBook.setPublished(false);
1770 listManager.getNotebookIndex().add(newBook);
1772 listManager.getLocalNotebooks().add(newBook.getGuid());
1773 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1774 notebookIndexUpdated();
1775 listManager.countNotebookResults(listManager.getNoteIndex());
1776 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1777 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1779 // Edit an existing notebook
1780 @SuppressWarnings("unused")
1781 private void stackNotebook() {
1782 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1783 StackNotebook edit = new StackNotebook();
1785 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1786 QTreeWidgetItem currentSelection;
1787 for (int i=0; i<selections.size(); i++) {
1788 currentSelection = selections.get(0);
1789 String guid = currentSelection.text(2);
1790 if (guid.equalsIgnoreCase("")) {
1791 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1794 if (guid.equalsIgnoreCase("STACK")) {
1795 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1800 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1805 if (!edit.okPressed())
1808 String stack = edit.getStackName();
1810 for (int i=0; i<selections.size(); i++) {
1811 currentSelection = selections.get(i);
1812 String guid = currentSelection.text(2);
1813 listManager.updateNotebookStack(guid, stack);
1815 notebookIndexUpdated();
1816 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1818 // Edit an existing notebook
1819 @SuppressWarnings("unused")
1820 private void editNotebook() {
1821 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1822 NotebookEdit edit = new NotebookEdit();
1824 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1825 QTreeWidgetItem currentSelection;
1826 currentSelection = selections.get(0);
1827 edit.setNotebook(currentSelection.text(0));
1829 String guid = currentSelection.text(2);
1830 if (!guid.equalsIgnoreCase("STACK")) {
1831 edit.setTitle(tr("Edit Notebook"));
1832 edit.setNotebooks(listManager.getNotebookIndex());
1833 edit.setLocalCheckboxEnabled(false);
1834 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1835 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1836 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1837 i=listManager.getNotebookIndex().size();
1841 edit.setTitle(tr("Edit Stack"));
1842 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1843 edit.hideLocalCheckbox();
1844 edit.hideDefaultCheckbox();
1849 if (!edit.okPressed())
1853 if (guid.equalsIgnoreCase("STACK")) {
1854 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1855 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1856 if (listManager.getNotebookIndex().get(j).getStack() != null &&
1857 listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1858 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1860 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1861 currentSelection.setText(0, edit.getNotebook());
1865 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1866 currentSelection.setText(0, edit.getNotebook());
1868 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1869 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1870 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1871 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1872 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1873 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1874 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1875 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1877 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1878 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1879 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1880 linkedNotebook.setShareName(edit.getNotebook());
1881 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1883 i=listManager.getNotebookIndex().size();
1887 // Build a list of non-closed notebooks
1888 List<Notebook> nbooks = new ArrayList<Notebook>();
1889 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1890 boolean found=false;
1891 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1892 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1896 nbooks.add(listManager.getNotebookIndex().get(i));
1900 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1901 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1902 browserWindow.setNotebookList(filteredBooks);
1903 Iterator<String> set = externalWindows.keySet().iterator();
1904 while(set.hasNext())
1905 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1907 Iterator<Integer>it = tabWindows.keySet().iterator();
1908 while (it.hasNext()) {
1909 tabWindows.get(it.next()).getBrowserWindow()
1910 .setNotebookList(filteredBooks);
1913 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1915 // Publish a notebook
1916 @SuppressWarnings("unused")
1917 private void publishNotebook() {
1918 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1919 QTreeWidgetItem currentSelection;
1920 currentSelection = selections.get(0);
1921 String guid = currentSelection.text(2);
1923 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1928 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1929 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1930 n = listManager.getNotebookIndex().get(i);
1932 i = listManager.getNotebookIndex().size();
1938 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1941 if (!publish.okClicked())
1944 Publishing p = publish.getPublishing();
1945 boolean isPublished = !publish.isStopPressed();
1946 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1947 n.setPublished(isPublished);
1949 listManager.getNotebookIndex().set(position, n);
1950 notebookIndexUpdated();
1952 // Publish a notebook
1953 @SuppressWarnings("unused")
1954 private void shareNotebook() {
1955 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1956 QTreeWidgetItem currentSelection;
1957 currentSelection = selections.get(0);
1958 String guid = currentSelection.text(2);
1960 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1964 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1965 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1966 n = listManager.getNotebookIndex().get(i);
1967 i = listManager.getNotebookIndex().size();
1971 String authToken = null;
1972 if (syncRunner.isConnected)
1973 authToken = syncRunner.authToken;
1974 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
1979 // Delete an existing notebook
1980 @SuppressWarnings("unused")
1981 private void deleteNotebook() {
1982 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
1983 boolean stacksFound = false;
1984 boolean notebooksFound = false;
1985 boolean assigned = false;
1986 // Check if any notes have this notebook
1987 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1988 for (int i=0; i<selections.size(); i++) {
1989 QTreeWidgetItem currentSelection;
1990 currentSelection = selections.get(i);
1991 String guid = currentSelection.text(2);
1992 if (!guid.equalsIgnoreCase("STACK")) {
1993 notebooksFound = true;
1994 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
1995 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
1996 if (noteGuid.equals(guid)) {
1998 j=listManager.getNoteIndex().size();
1999 i=selections.size();
2007 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2008 "Please delete the notes or move them to another notebook before deleting any notebooks."));
2012 if (conn.getNotebookTable().getAll().size() == 1) {
2013 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2017 // If all notebooks are clear, verify the delete
2018 String msg1 = new String(tr("Delete selected notebooks?"));
2019 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2020 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2021 " not deleted unless selected?"));
2023 if (stacksFound && notebooksFound)
2025 if (!stacksFound && notebooksFound)
2027 if (stacksFound && !notebooksFound)
2029 if (QMessageBox.question(this, tr("Confirmation"), msg,
2030 QMessageBox.StandardButton.Yes,
2031 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2035 // If confirmed, delete the notebook
2036 for (int i=selections.size()-1; i>=0; i--) {
2037 QTreeWidgetItem currentSelection;
2038 currentSelection = selections.get(i);
2039 String guid = currentSelection.text(2);
2040 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2041 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2042 listManager.renameStack(currentSelection.text(0), "");
2044 conn.getNotebookTable().expungeNotebook(guid, true);
2045 listManager.deleteNotebook(guid);
2049 notebookIndexUpdated();
2050 // notebookTreeSelection();
2051 // notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2052 // listManager.countNotebookResults(listManager.getNoteIndex());
2053 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2055 // A note's notebook has been updated
2056 @SuppressWarnings("unused")
2057 private void updateNoteNotebook(String guid, String notebookGuid) {
2058 // 同じノートブックに入れられたノート間の履歴を登録
2059 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2061 // Update the list manager
2062 listManager.updateNoteNotebook(guid, notebookGuid);
2063 listManager.countNotebookResults(listManager.getNoteIndex());
2064 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
2066 // Find the name of the notebook
2067 String notebookName = null;
2068 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2069 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2070 notebookName = listManager.getNotebookIndex().get(i).getName();
2075 // If we found the name, update the browser window
2076 if (notebookName != null) {
2077 updateListNoteNotebook(guid, notebookName);
2078 if (guid.equals(currentNoteGuid)) {
2079 int pos = browserWindow.notebookBox.findText(notebookName);
2081 browserWindow.notebookBox.setCurrentIndex(pos);
2085 // If we're dealing with the current note, then we need to be sure and update the notebook there
2086 if (guid.equals(currentNoteGuid)) {
2087 if (currentNote != null) {
2088 currentNote.setNotebookGuid(notebookGuid);
2092 // Open/close notebooks
2093 @SuppressWarnings("unused")
2094 private void closeNotebooks() {
2095 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2097 if (!na.okClicked())
2101 listManager.getArchiveNotebookIndex().clear();
2103 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2104 String text = na.getClosedBookList().takeItem(i).text();
2105 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2106 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2107 Notebook n = listManager.getNotebookIndex().get(j);
2108 conn.getNotebookTable().setArchived(n.getGuid(),true);
2109 listManager.getArchiveNotebookIndex().add(n);
2110 j=listManager.getNotebookIndex().size();
2115 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2116 String text = na.getOpenBookList().takeItem(i).text();
2117 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2118 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2119 Notebook n = listManager.getNotebookIndex().get(j);
2120 conn.getNotebookTable().setArchived(n.getGuid(),false);
2121 j=listManager.getNotebookIndex().size();
2125 notebookTreeSelection();
2126 listManager.loadNotesIndex();
2127 notebookIndexUpdated();
2128 noteIndexUpdated(false);
2129 reloadTagTree(true);
2130 // noteIndexUpdated(false);
2132 // Build a list of non-closed notebooks
2133 List<Notebook> nbooks = new ArrayList<Notebook>();
2134 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2135 boolean found=false;
2136 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2137 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2141 nbooks.add(listManager.getNotebookIndex().get(i));
2144 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2145 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2146 browserWindow.setNotebookList(filteredBooks);
2148 // Update any external windows
2149 Iterator<String> set = externalWindows.keySet().iterator();
2150 while(set.hasNext())
2151 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2154 Iterator<Integer> it = tabWindows.keySet().iterator();
2155 while (it.hasNext()) {
2156 tabWindows.get(it.next()).getBrowserWindow()
2157 .setNotebookList(filteredBooks);
2162 // Change the notebook's icon
2163 @SuppressWarnings("unused")
2164 private void setNotebookIcon() {
2165 boolean stackSelected = false;
2166 boolean allNotebookSelected = false;
2168 QTreeWidgetItem currentSelection;
2169 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2170 if (selections.size() == 0)
2173 currentSelection = selections.get(0);
2174 String guid = currentSelection.text(2);
2175 if (guid.equalsIgnoreCase(""))
2176 allNotebookSelected = true;
2177 if (guid.equalsIgnoreCase("STACK"))
2178 stackSelected = true;
2180 QIcon currentIcon = currentSelection.icon(0);
2184 if (!stackSelected && !allNotebookSelected) {
2185 icon = conn.getNotebookTable().getIcon(guid);
2187 dialog = new SetIcon(currentIcon, saveLastPath);
2188 dialog.setUseDefaultIcon(true);
2190 dialog = new SetIcon(icon, saveLastPath);
2191 dialog.setUseDefaultIcon(false);
2194 if (stackSelected) {
2195 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2197 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
2200 dialog = new SetIcon(currentIcon, saveLastPath);
2201 dialog.setUseDefaultIcon(true);
2203 dialog = new SetIcon(icon, saveLastPath);
2204 dialog.setUseDefaultIcon(false);
2208 if (dialog.okPressed()) {
2209 saveLastPath = dialog.getPath();
2211 QIcon newIcon = dialog.getIcon();
2212 if (stackSelected) {
2213 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2214 if (newIcon == null) {
2215 newIcon = new QIcon(iconPath+"books2.png");
2217 currentSelection.setIcon(0,newIcon);
2220 if (allNotebookSelected) {
2221 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2222 if (newIcon == null) {
2223 newIcon = new QIcon(iconPath+"notebook-green.png");
2225 currentSelection.setIcon(0,newIcon);
2228 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2229 if (newIcon == null) {
2230 boolean isPublished = false;;
2231 boolean found = false;
2232 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2233 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2234 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2238 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2240 currentSelection.setIcon(0, newIcon);
2246 //***************************************************************
2247 //***************************************************************
2248 //** These functions deal with Tag menu items
2249 //***************************************************************
2250 //***************************************************************
2251 // Add a new notebook
2252 @SuppressWarnings("unused")
2253 private void addTag() {
2254 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2255 TagEdit edit = new TagEdit();
2256 edit.setTagList(listManager.getTagIndex());
2258 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2259 QTreeWidgetItem currentSelection = null;
2260 if (selections.size() > 0) {
2261 currentSelection = selections.get(0);
2262 edit.setParentTag(currentSelection.text(0));
2267 if (!edit.okPressed())
2270 Calendar currentTime = new GregorianCalendar();
2271 Long l = new Long(currentTime.getTimeInMillis());
2272 String randint = new String(Long.toString(l));
2274 Tag newTag = new Tag();
2275 newTag.setUpdateSequenceNum(0);
2276 newTag.setGuid(randint);
2277 newTag.setName(edit.getTag());
2278 if (edit.getParentTag().isChecked()) {
2279 newTag.setParentGuid(currentSelection.text(2));
2280 newTag.setParentGuidIsSet(true);
2281 currentSelection.setExpanded(true);
2283 conn.getTagTable().addTag(newTag, true);
2284 listManager.getTagIndex().add(newTag);
2285 reloadTagTree(true);
2287 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2289 @SuppressWarnings("unused")
2290 private void reloadTagTree() {
2291 reloadTagTree(false);
2293 private void reloadTagTree(boolean reload) {
2294 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2295 tagIndexUpdated(reload);
2296 boolean filter = false;
2298 listManager.countTagResults(listManager.getNoteIndex());
2299 if (notebookTree.selectedItems().size() > 0
2300 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2302 if (tagTree.selectedItems().size() > 0)
2304 tagTree.showAllTags(!filter);
2305 tagIndexUpdated(false);
2306 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2308 // Edit an existing tag
2309 @SuppressWarnings("unused")
2310 private void editTag() {
2311 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2312 TagEdit edit = new TagEdit();
2313 edit.setTitle("Edit Tag");
2314 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2315 QTreeWidgetItem currentSelection;
2316 currentSelection = selections.get(0);
2317 edit.setTag(currentSelection.text(0));
2318 edit.setTagList(listManager.getTagIndex());
2321 if (!edit.okPressed())
2324 String guid = currentSelection.text(2);
2325 currentSelection.setText(0,edit.getTag());
2327 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2328 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2329 listManager.getTagIndex().get(i).setName(edit.getTag());
2330 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2331 updateListTagName(guid);
2332 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2333 browserWindow.setTag(getTagNamesForNote(currentNote));
2334 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2338 listManager.reloadNoteTagNames(guid, edit.getTag());
2339 noteIndexUpdated(true);
2340 refreshEvernoteNote(true);
2341 browserWindow.setTag(getTagNamesForNote(currentNote));
2342 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2344 // Delete an existing tag
2345 @SuppressWarnings("unused")
2346 private void deleteTag() {
2347 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2349 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2350 QMessageBox.StandardButton.Yes,
2351 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2355 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2356 for (int i=selections.size()-1; i>=0; i--) {
2357 QTreeWidgetItem currentSelection;
2358 currentSelection = selections.get(i);
2359 removeTagItem(currentSelection.text(2));
2361 tagIndexUpdated(true);
2363 listManager.countTagResults(listManager.getNoteIndex());
2364 // tagTree.updateCounts(listManager.getTagCounter());
2365 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2367 // Remove a tag tree item. Go recursively down & remove the children too
2368 private void removeTagItem(String guid) {
2369 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
2370 String parent = listManager.getTagIndex().get(j).getParentGuid();
2371 if (parent != null && parent.equals(guid)) {
2372 //Remove this tag's children
2373 removeTagItem(listManager.getTagIndex().get(j).getGuid());
2376 //Now, remove this tag
2377 removeListTagName(guid);
2378 conn.getTagTable().expungeTag(guid, true);
2379 for (int a=0; a<listManager.getTagIndex().size(); a++) {
2380 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2381 listManager.getTagIndex().remove(a);
2386 // Setup the tree containing the user's tags
2387 private void initializeTagTree() {
2388 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2389 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2390 // tagTree.itemClicked.connect(this, "tagTreeSelection()");
2391 tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2392 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2393 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2395 // Listener when a tag is selected
2396 private void tagTreeSelection() {
2397 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2400 clearAttributeFilter();
2401 clearSavedSearchFilter();
2403 menuBar.noteRestoreAction.setVisible(false);
2405 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2406 if (!rensoNoteListDock.isEnabled()) {
2407 rensoNoteListDock.setEnabled(true);
2410 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2411 QTreeWidgetItem currentSelection;
2412 selectedTagGUIDs.clear();
2413 for (int i=0; i<selections.size(); i++) {
2414 currentSelection = selections.get(i);
2415 selectedTagGUIDs.add(currentSelection.text(2));
2417 if (selections.size() > 0) {
2418 menuBar.tagEditAction.setEnabled(true);
2419 menuBar.tagDeleteAction.setEnabled(true);
2420 menuBar.tagIconAction.setEnabled(true);
2423 menuBar.tagEditAction.setEnabled(false);
2424 menuBar.tagDeleteAction.setEnabled(false);
2425 menuBar.tagIconAction.setEnabled(true);
2427 if (selections.size() > 1)
2428 menuBar.tagMergeAction.setEnabled(true);
2430 menuBar.tagMergeAction.setEnabled(false);
2431 listManager.setSelectedTags(selectedTagGUIDs);
2432 listManager.loadNotesIndex();
2433 noteIndexUpdated(false);
2434 refreshEvernoteNote(true);
2435 listManager.refreshCounters = true;
2436 listManager.refreshCounters();
2437 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2439 // trigger the tag index to be refreshed
2440 @SuppressWarnings("unused")
2441 private void tagIndexUpdated() {
2442 tagIndexUpdated(true);
2444 private void tagIndexUpdated(boolean reload) {
2445 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2446 if (selectedTagGUIDs == null)
2447 selectedTagGUIDs = new ArrayList<String>();
2449 listManager.reloadTagIndex();
2451 tagTree.blockSignals(true);
2453 tagTree.setIcons(conn.getTagTable().getAllIcons());
2454 tagTree.load(listManager.getTagIndex());
2457 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2458 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2460 selectedTagGUIDs.remove(i);
2462 tagTree.blockSignals(false);
2464 browserWindow.setTag(getTagNamesForNote(currentNote));
2465 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2467 // Show/Hide note information
2468 @SuppressWarnings("unused")
2469 private void toggleTagWindow() {
2470 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2471 if (tagTree.isVisible())
2475 menuBar.hideTags.setChecked(tagTree.isVisible());
2476 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2477 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2479 // A note's tags have been updated
2480 @SuppressWarnings("unused")
2481 private void updateNoteTags(String guid, List<String> tags) {
2482 // Save any new tags. We'll need them later.
2483 List<String> newTags = new ArrayList<String>();
2484 for (int i=0; i<tags.size(); i++) {
2485 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2486 newTags.add(tags.get(i));
2489 listManager.saveNoteTags(guid, tags, true);
2490 listManager.countTagResults(listManager.getNoteIndex());
2491 StringBuffer names = new StringBuffer("");
2492 for (int i=0; i<tags.size(); i++) {
2493 names = names.append(tags.get(i));
2494 if (i<tags.size()-1) {
2495 names.append(Global.tagDelimeter + " ");
2498 browserWindow.setTag(names.toString());
2500 for (TabBrowse tab: tabWindows.values()) {
2501 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
2502 int index = tabBrowser.indexOf(tab);
2503 noteDirty.put(index, true);
2508 // Now, we need to add any new tags to the tag tree
2509 for (int i=0; i<newTags.size(); i++)
2510 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2512 // Get a string containing all tag names for a note
2513 private String getTagNamesForNote(Note n) {
2514 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2515 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2517 StringBuffer buffer = new StringBuffer(100);
2518 Vector<String> v = new Vector<String>();
2519 List<String> guids = n.getTagGuids();
2524 for (int i=0; i<guids.size(); i++) {
2525 v.add(listManager.getTagNameByGuid(guids.get(i)));
2527 Comparator<String> comparator = Collections.reverseOrder();
2528 Collections.sort(v,comparator);
2529 Collections.reverse(v);
2531 for (int i = 0; i<v.size(); i++) {
2533 buffer.append(", ");
2534 buffer.append(v.get(i));
2537 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2538 return buffer.toString();
2540 // Tags were added via dropping notes from the note list
2541 @SuppressWarnings("unused")
2542 private void tagsAdded(String noteGuid, String tagGuid) {
2543 String tagName = null;
2544 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2545 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2546 tagName = listManager.getTagIndex().get(i).getName();
2547 i=listManager.getTagIndex().size();
2550 if (tagName == null)
2553 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2554 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2555 List<String> tagNames = new ArrayList<String>();
2556 tagNames.add(new String(tagName));
2557 Note n = listManager.getMasterNoteIndex().get(i);
2558 for (int j=0; j<n.getTagNames().size(); j++) {
2559 tagNames.add(new String(n.getTagNames().get(j)));
2561 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2562 if (n.getGuid().equals(currentNoteGuid)) {
2563 Collections.sort(tagNames);
2564 String display = "";
2565 for (int j=0; j<tagNames.size(); j++) {
2566 display = display+tagNames.get(j);
2567 if (j+2<tagNames.size())
2568 display = display+Global.tagDelimeter+" ";
2570 browserWindow.setTag(display);
2572 i=listManager.getMasterNoteIndex().size();
2577 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2579 private void clearTagFilter() {
2580 tagTree.blockSignals(true);
2581 tagTree.clearSelection();
2582 menuBar.noteRestoreAction.setVisible(false);
2583 menuBar.tagEditAction.setEnabled(false);
2584 menuBar.tagMergeAction.setEnabled(false);
2585 menuBar.tagDeleteAction.setEnabled(false);
2586 menuBar.tagIconAction.setEnabled(false);
2587 selectedTagGUIDs.clear();
2588 listManager.setSelectedTags(selectedTagGUIDs);
2589 tagTree.blockSignals(false);
2591 // Change the icon for a tag
2592 @SuppressWarnings("unused")
2593 private void setTagIcon() {
2594 QTreeWidgetItem currentSelection;
2595 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2596 if (selections.size() == 0)
2599 currentSelection = selections.get(0);
2600 String guid = currentSelection.text(2);
2602 QIcon currentIcon = currentSelection.icon(0);
2603 QIcon icon = conn.getTagTable().getIcon(guid);
2606 dialog = new SetIcon(currentIcon, saveLastPath);
2607 dialog.setUseDefaultIcon(true);
2609 dialog = new SetIcon(icon, saveLastPath);
2610 dialog.setUseDefaultIcon(false);
2613 if (dialog.okPressed()) {
2614 saveLastPath = dialog.getPath();
2615 QIcon newIcon = dialog.getIcon();
2616 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2617 if (newIcon == null)
2618 newIcon = new QIcon(iconPath+"tag.png");
2619 currentSelection.setIcon(0, newIcon);
2624 @SuppressWarnings("unused")
2625 private void mergeTags() {
2626 List<Tag> tags = new ArrayList<Tag>();
2627 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2628 for (int i=0; i<selections.size(); i++) {
2629 Tag record = new Tag();
2630 record.setGuid(selections.get(i).text(2));
2631 record.setName(selections.get(i).text(0));
2635 TagMerge mergeDialog = new TagMerge(tags);
2637 if (!mergeDialog.okClicked())
2639 String newGuid = mergeDialog.getNewTagGuid();
2641 for (int i=0; i<tags.size(); i++) {
2642 if (!tags.get(i).getGuid().equals(newGuid)) {
2643 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2644 for (int j=0; j<noteGuids.size(); j++) {
2645 String noteGuid = noteGuids.get(j);
2646 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2647 if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2648 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2652 listManager.reloadIndexes();
2655 //***************************************************************
2656 //***************************************************************
2657 //** These functions deal with Saved Search menu items
2658 //***************************************************************
2659 //***************************************************************
2660 // Add a new notebook
2661 @SuppressWarnings("unused")
2662 private void addSavedSearch() {
2663 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2664 SavedSearchEdit edit = new SavedSearchEdit();
2665 edit.setSearchList(listManager.getSavedSearchIndex());
2668 if (!edit.okPressed())
2671 Calendar currentTime = new GregorianCalendar();
2672 Long l = new Long(currentTime.getTimeInMillis());
2673 String randint = new String(Long.toString(l));
2675 SavedSearch search = new SavedSearch();
2676 search.setUpdateSequenceNum(0);
2677 search.setGuid(randint);
2678 search.setName(edit.getName());
2679 search.setQuery(edit.getQuery());
2680 search.setFormat(QueryFormat.USER);
2681 listManager.getSavedSearchIndex().add(search);
2682 conn.getSavedSearchTable().addSavedSearch(search, true);
2683 savedSearchIndexUpdated();
2684 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2686 // Edit an existing tag
2687 @SuppressWarnings("unused")
2688 private void editSavedSearch() {
2689 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2690 SavedSearchEdit edit = new SavedSearchEdit();
2691 edit.setTitle(tr("Edit Search"));
2692 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2693 QTreeWidgetItem currentSelection;
2694 currentSelection = selections.get(0);
2695 String guid = currentSelection.text(1);
2696 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2697 edit.setName(currentSelection.text(0));
2698 edit.setQuery(s.getQuery());
2699 edit.setSearchList(listManager.getSavedSearchIndex());
2702 if (!edit.okPressed())
2705 List<SavedSearch> list = listManager.getSavedSearchIndex();
2706 SavedSearch search = null;
2707 boolean found = false;
2708 for (int i=0; i<list.size(); i++) {
2709 search = list.get(i);
2710 if (search.getGuid().equals(guid)) {
2717 search.setName(edit.getName());
2718 search.setQuery(edit.getQuery());
2719 conn.getSavedSearchTable().updateSavedSearch(search, true);
2720 savedSearchIndexUpdated();
2721 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2723 // Delete an existing tag
2724 @SuppressWarnings("unused")
2725 private void deleteSavedSearch() {
2726 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2728 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2729 QMessageBox.StandardButton.Yes,
2730 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2734 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2735 for (int i=selections.size()-1; i>=0; i--) {
2736 QTreeWidgetItem currentSelection;
2737 currentSelection = selections.get(i);
2738 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2739 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2740 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2741 listManager.getSavedSearchIndex().remove(j);
2742 j=listManager.getSavedSearchIndex().size()+1;
2745 selections.remove(i);
2747 savedSearchIndexUpdated();
2748 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2750 // Setup the tree containing the user's tags
2751 private void initializeSavedSearchTree() {
2752 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2753 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2754 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2756 // Listener when a tag is selected
2757 @SuppressWarnings("unused")
2758 private void savedSearchTreeSelection() {
2759 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2761 clearNotebookFilter();
2764 clearAttributeFilter();
2766 String currentGuid = selectedSavedSearchGUID;
2767 menuBar.savedSearchEditAction.setEnabled(true);
2768 menuBar.savedSearchDeleteAction.setEnabled(true);
2769 menuBar.savedSearchIconAction.setEnabled(true);
2771 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2772 if (!rensoNoteListDock.isEnabled()) {
2773 rensoNoteListDock.setEnabled(true);
2776 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2777 QTreeWidgetItem currentSelection;
2778 selectedSavedSearchGUID = "";
2779 for (int i=0; i<selections.size(); i++) {
2780 currentSelection = selections.get(i);
2781 if (currentSelection.text(1).equals(currentGuid)) {
2782 currentSelection.setSelected(false);
2784 selectedSavedSearchGUID = currentSelection.text(1);
2786 // i = selections.size() +1;
2789 // There is the potential for no notebooks to be selected if this
2790 // happens then we make it look like all notebooks were selecetd.
2791 // If that happens, just select the "all notebooks"
2792 if (selections.size()==0) {
2793 clearSavedSearchFilter();
2795 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2797 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2799 private void clearSavedSearchFilter() {
2800 menuBar.savedSearchEditAction.setEnabled(false);
2801 menuBar.savedSearchDeleteAction.setEnabled(false);
2802 menuBar.savedSearchIconAction.setEnabled(false);
2803 savedSearchTree.blockSignals(true);
2804 savedSearchTree.clearSelection();
2805 savedSearchTree.blockSignals(false);
2806 selectedSavedSearchGUID = "";
2807 searchField.setText("");
2808 searchPerformed = false;
2809 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2811 // trigger the tag index to be refreshed
2812 private void savedSearchIndexUpdated() {
2813 if (selectedSavedSearchGUID == null)
2814 selectedSavedSearchGUID = new String();
2815 savedSearchTree.blockSignals(true);
2816 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2817 savedSearchTree.load(listManager.getSavedSearchIndex());
2818 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2819 savedSearchTree.blockSignals(false);
2821 // trigger when the saved search selection changes
2822 @SuppressWarnings("unused")
2823 private void updateSavedSearchSelection() {
2824 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2826 menuBar.savedSearchEditAction.setEnabled(true);
2827 menuBar.savedSearchDeleteAction.setEnabled(true);
2828 menuBar.savedSearchIconAction.setEnabled(true);
2829 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2831 if (selections.size() > 0) {
2832 menuBar.savedSearchEditAction.setEnabled(true);
2833 menuBar.savedSearchDeleteAction.setEnabled(true);
2834 menuBar.savedSearchIconAction.setEnabled(true);
2835 selectedSavedSearchGUID = selections.get(0).text(1);
2836 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2837 searchField.setText(s.getQuery());
2839 menuBar.savedSearchEditAction.setEnabled(false);
2840 menuBar.savedSearchDeleteAction.setEnabled(false);
2841 menuBar.savedSearchIconAction.setEnabled(false);
2842 selectedSavedSearchGUID = "";
2843 searchField.setText("");
2845 searchFieldChanged();
2847 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2851 // Show/Hide note information
2852 @SuppressWarnings("unused")
2853 private void toggleSavedSearchWindow() {
2854 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2855 if (savedSearchTree.isVisible())
2856 savedSearchTree.hide();
2858 savedSearchTree.show();
2859 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2861 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2862 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2864 // Change the icon for a saved search
2865 @SuppressWarnings("unused")
2866 private void setSavedSearchIcon() {
2867 QTreeWidgetItem currentSelection;
2868 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2869 if (selections.size() == 0)
2872 currentSelection = selections.get(0);
2873 String guid = currentSelection.text(1);
2875 QIcon currentIcon = currentSelection.icon(0);
2876 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2879 dialog = new SetIcon(currentIcon, saveLastPath);
2880 dialog.setUseDefaultIcon(true);
2882 dialog = new SetIcon(icon, saveLastPath);
2883 dialog.setUseDefaultIcon(false);
2886 if (dialog.okPressed()) {
2887 saveLastPath = dialog.getPath();
2888 QIcon newIcon = dialog.getIcon();
2889 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2890 if (newIcon == null)
2891 newIcon = new QIcon(iconPath+"search.png");
2892 currentSelection.setIcon(0, newIcon);
2900 //***************************************************************
2901 //***************************************************************
2902 //** These functions deal with Help menu & tool menu items
2903 //***************************************************************
2904 //***************************************************************
2905 // Show database status
2906 @SuppressWarnings("unused")
2907 private void databaseStatus() {
2909 indexRunner.interrupt = true;
2910 int dirty = conn.getNoteTable().getDirtyCount();
2911 int unindexed = conn.getNoteTable().getUnindexedCount();
2912 DatabaseStatus status = new DatabaseStatus();
2913 status.setUnsynchronized(dirty);
2914 status.setUnindexed(unindexed);
2915 status.setNoteCount(conn.getNoteTable().getNoteCount());
2916 status.setNotebookCount(listManager.getNotebookIndex().size());
2917 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2918 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2919 status.setTagCount(listManager.getTagIndex().size());
2920 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2921 status.setWordCount(conn.getWordsTable().getWordCount());
2922 status.setHistoryCount(conn.getHistoryTable().getHistoryCount());
2923 status.setRensoClickCount(conn.getHistoryTable().getRensoClickCount());
2927 // Compact the database
2928 @SuppressWarnings("unused")
2929 private void compactDatabase() {
2930 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2931 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2932 "but please be aware that depending upon the size of your database this can be time consuming " +
2933 "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
2934 QMessageBox.StandardButton.Yes,
2935 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2938 setMessage("Compacting database.");
2940 listManager.compactDatabase();
2942 setMessage("Database compact is complete.");
2943 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2945 @SuppressWarnings("unused")
2946 private void accountInformation() {
2947 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2948 AccountDialog dialog = new AccountDialog();
2950 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2952 @SuppressWarnings("unused")
2953 private void releaseNotes() {
2954 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
2955 QDialog dialog = new QDialog(this);
2956 QHBoxLayout layout = new QHBoxLayout();
2957 QTextEdit textBox = new QTextEdit();
2958 layout.addWidget(textBox);
2959 textBox.setReadOnly(true);
2960 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
2961 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
2962 QIODevice.OpenModeFlag.Text)))
2965 QTextCodec codec = QTextCodec.codecForName("UTF-8");
2966 QTextStream textStream = new QTextStream(file);
2967 textStream.setCodec(codec);
2968 textBox.setText(textStream.readAll().toString());
2971 dialog.setWindowTitle(tr("Release Notes"));
2972 dialog.setLayout(layout);
2974 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
2976 // Called when user picks Log from the help menu
2977 @SuppressWarnings("unused")
2978 private void logger() {
2979 logger.log(logger.HIGH, "Entering NeverNote.logger");
2980 LogFileDialog dialog = new LogFileDialog(emitLog);
2982 logger.log(logger.HIGH, "Leaving NeverNote.logger");
2984 // Menu option "help/about" was selected
2985 @SuppressWarnings("unused")
2986 private void about() {
2987 logger.log(logger.HIGH, "Entering NeverNote.about");
2988 QMessageBox.about(this,
2989 tr("About NeighborNote"),
2990 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
2991 +Global.version + "(based on NixNote 1.6)"
2994 +"Open Source Evernote Client.<br><br>"
2995 +"Licensed under GPL v2. <br><hr><br>"
2996 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
2997 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
2998 +"PDFRenderer is licened under the LGPL<br>"
2999 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3000 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3001 +"Jazzy is licened under the LGPL<br>"
3002 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3003 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3004 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3005 logger.log(logger.HIGH, "Leaving NeverNote.about");
3007 // Hide the entire left hand side
3008 @SuppressWarnings("unused")
3009 private void toggleLeftSide() {
3012 hidden = !menuBar.hideLeftSide.isChecked();
3013 menuBar.hideLeftSide.setChecked(!hidden);
3016 leftSplitter1.setHidden(true);
3018 leftSplitter1.setHidden(false);
3020 Global.saveWindowVisible("leftPanel", hidden);
3023 public void checkForUpdates() {
3024 // Send off thread to check for a new version
3025 versionChecker = new QNetworkAccessManager(this);
3026 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3027 QNetworkRequest request = new QNetworkRequest();
3028 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3029 versionChecker.get(request);
3031 @SuppressWarnings("unused")
3032 private void upgradeFileRead(QNetworkReply reply) {
3033 if (!reply.isReadable())
3036 String winVersion = Global.version;
3037 String osxVersion = Global.version;
3038 String linuxVersion = Global.version;
3039 String linux64Version = Global.version;
3040 String version = Global.version;
3042 // Determine the versions available
3043 QByteArray data = reply.readLine();
3044 while (data != null && !reply.atEnd()) {
3045 String line = data.toString();
3047 if (line.contains(":"))
3048 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3051 if (line.toLowerCase().contains("windows"))
3052 winVersion = lineVersion;
3053 else if (line.toLowerCase().contains("os-x"))
3054 osxVersion = lineVersion;
3055 else if (line.toLowerCase().contains("linux amd64"))
3056 linux64Version = lineVersion;
3057 else if (line.toLowerCase().contains("linux i386"))
3058 linuxVersion = lineVersion;
3059 else if (line.toLowerCase().contains("default"))
3060 version = lineVersion;
3062 // Read the next line
3063 data = reply.readLine();
3066 // Now we need to determine what system we are on.
3067 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3068 version = winVersion;
3069 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3070 version = osxVersion;
3071 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3072 if (System.getProperty("os.arch").contains("amd64") ||
3073 System.getProperty("os.arch").contains("x86_64"))
3074 version = linux64Version;
3076 version = linuxVersion;
3080 for (String validVersion : Global.validVersions) {
3081 if (version.equals(validVersion))
3085 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3087 if (dialog.remindMe())
3088 Global.setCheckVersionUpgrade(true);
3090 Global.setCheckVersionUpgrade(false);
3094 //***************************************************************
3095 //***************************************************************
3096 //** These functions deal with the Toolbar
3097 //***************************************************************
3098 //***************************************************************
3099 @SuppressWarnings("unused")
3100 private void focusSearch() {
3101 searchField.setFocus();
3104 // Text in the search bar has been cleared
3105 private void searchFieldCleared() {
3108 // This is done because we want to force a reload of
3109 // images. Some images we may want to highlight the text.
3110 readOnlyCache.clear();
3111 inkNoteCache.clear();
3113 QWebSettings.setMaximumPagesInCache(0);
3114 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3116 searchField.setdefaultText();
3117 saveNoteColumnPositions();
3118 saveNoteIndexWidth();
3119 noteIndexUpdated(true);
3120 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3121 currentNote = listManager.getNoteIndex().get(0);
3122 currentNoteGuid = currentNote.getGuid();
3124 refreshEvernoteNote(true);
3125 if (currentNote != null)
3126 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3128 // text in the search bar changed. We only use this to tell if it was cleared,
3129 // otherwise we trigger off searchFieldChanged.
3130 @SuppressWarnings("unused")
3131 private void searchFieldTextChanged(String text) {
3132 QWebSettings.setMaximumPagesInCache(0);
3133 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3135 if (text.trim().equals("") && !searchField.hasFocus()) {
3136 searchFieldCleared();
3137 if (searchPerformed) {
3139 // This is done because we want to force a reload of
3140 // images. Some images we may want to highlight the text.
3142 readOnlyCache.clear();
3143 inkNoteCache.clear();
3145 listManager.setEnSearch("");
3146 listManager.loadNotesIndex();
3147 refreshEvernoteNote(true);
3148 noteIndexUpdated(false);
3149 refreshEvernoteNote(true);
3151 searchPerformed = false;
3154 // Text in the toolbar has changed
3155 private void searchFieldChanged() {
3156 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3158 readOnlyCache.clear();
3159 inkNoteCache.clear();
3160 saveNoteColumnPositions();
3161 saveNoteIndexWidth();
3162 String text = searchField.text();
3163 listManager.setEnSearch(text.trim());
3164 listManager.loadNotesIndex();
3165 noteIndexUpdated(false);
3167 refreshEvernoteNote(true);
3168 searchPerformed = true;
3170 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3173 // Build the window tool bar
3174 private void setupToolBar() {
3175 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3176 toolBar = addToolBar(tr("Tool Bar"));
3177 toolBar.setObjectName("toolBar");
3178 toolBar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon);
3179 menuBar.setupToolBarVisible();
3180 if (!Global.isWindowVisible("toolBar"))
3181 toolBar.setVisible(false);
3183 toolBar.setVisible(true);
3185 // toolBar.addWidget(menuBar);
3186 // menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3187 // toolBar.addSeparator();
3188 prevButton = toolBar.addAction(tr(""));
3189 prevButton.setToolTip(tr("Previous"));
3190 QIcon prevIcon = new QIcon(iconPath+"back.png");
3191 prevButton.setIcon(prevIcon);
3192 prevButton.triggered.connect(this, "previousViewedAction()");
3193 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow", true));
3195 nextButton = toolBar.addAction(tr(""));
3196 nextButton.setToolTip(tr("Next"));
3197 QIcon nextIcon = new QIcon(iconPath+"forward.png");
3198 nextButton.setIcon(nextIcon);
3199 nextButton.triggered.connect(this, "nextViewedAction()");
3200 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow", true));
3202 toolBar.addSeparator();
3204 upButton = toolBar.addAction(tr("Up"));
3205 QIcon upIcon = new QIcon(iconPath+"up.png");
3206 upButton.setIcon(upIcon);
3207 upButton.triggered.connect(this, "upAction()");
3208 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow", false));
3211 downButton = toolBar.addAction(tr("Down"));
3212 QIcon downIcon = new QIcon(iconPath+"down.png");
3213 downButton.setIcon(downIcon);
3214 downButton.triggered.connect(this, "downAction()");
3215 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow", false));
3217 synchronizeButton = toolBar.addAction(tr("Synchronize"));
3218 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3219 synchronizeIconAngle = 0;
3220 synchronizeButton.triggered.connect(this, "evernoteSync()");
3221 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize", true));
3223 printButton = toolBar.addAction(tr("Print"));
3224 QIcon printIcon = new QIcon(iconPath+"print.png");
3225 printButton.setIcon(printIcon);
3226 printButton.triggered.connect(this, "printNote()");
3227 togglePrintButton(Global.isToolbarButtonVisible("print", false));
3229 tagButton = toolBar.addAction(tr("Tag"));
3230 QIcon tagIcon = new QIcon(iconPath+"tag.png");
3231 tagButton.setIcon(tagIcon);
3232 tagButton.triggered.connect(browserWindow, "modifyTags()");
3233 toggleTagButton(Global.isToolbarButtonVisible("tag", false));
3235 attributeButton = toolBar.addAction(tr("Attributes"));
3236 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3237 attributeButton.setIcon(attributeIcon);
3238 attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3239 toggleAttributeButton(Global.isToolbarButtonVisible("attribute", true));
3241 emailButton = toolBar.addAction(tr("Email"));
3242 QIcon emailIcon = new QIcon(iconPath+"email.png");
3243 emailButton.setIcon(emailIcon);
3244 emailButton.triggered.connect(this, "emailNote()");
3245 toggleEmailButton(Global.isToolbarButtonVisible("email", false));
3247 deleteButton = toolBar.addAction(tr("Delete"));
3248 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3249 deleteButton.setIcon(deleteIcon);
3250 deleteButton.triggered.connect(this, "deleteNote()");
3251 toggleDeleteButton(Global.isToolbarButtonVisible("delete", true));
3253 newButton = toolBar.addAction(tr("New"));
3254 QIcon newIcon = new QIcon(iconPath+"new.png");
3255 if (Global.toolBarNewAction()) {
3256 newButton.triggered.connect(this, "noteAddNewTab()");
3258 newButton.triggered.connect(this, "addNote()");
3261 newButton.setIcon(newIcon);
3262 toggleNewButton(Global.isToolbarButtonVisible("new", true));
3264 allNotesButton = toolBar.addAction(tr("All Notes"));
3265 QIcon allIcon = new QIcon(iconPath+"books.png");
3266 allNotesButton.triggered.connect(this, "allNotes()");
3267 allNotesButton.setIcon(allIcon);
3268 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes", true));
3270 //toolBar.addSeparator();
3271 //toolBar.addWidget(new QLabel(tr("Quota:")));
3272 //toolBar.addWidget(quotaBar);
3273 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3275 //toolBar.addSeparator();
3277 //toolBar.addWidget(new QLabel(tr("Zoom")));
3278 //toolBar.addWidget(zoomSpinner);
3280 //toolBar.addWidget(new QLabel(" "));
3281 //toolBar.addSeparator();
3283 // 検索ボックスを右寄せするためのスペーサ
3284 QWidget spacerWidget = new QWidget();
3285 spacerWidget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred);
3286 toolBar.addWidget(spacerWidget);
3287 spacerWidget.setVisible(true);
3289 searchField = new SearchEdit(iconPath);
3290 searchField.setObjectName("searchField");
3291 searchField.returnPressed.connect(this, "searchFieldChanged()");
3292 searchField.textChanged.connect(this,"searchFieldTextChanged(String)");
3293 searchField.setFixedWidth(300);
3294 searchShortcut = new QShortcut(this);
3295 setupShortcut(searchShortcut, "Focus_Search");
3296 searchShortcut.activated.connect(this, "focusSearch()");
3297 toolBar.addWidget(searchField);
3299 searchField.setVisible(Global.isWindowVisible("searchField"));
3300 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
3301 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
3302 if (!Global.isWindowVisible("searchField"))
3303 menuBar.hideSearch.setChecked(false);
3305 // QSizePolicy sizePolicy = new QSizePolicy();
3306 // sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3307 // QLabel spacer = new QLabel("");
3308 // spacer.setSizePolicy(sizePolicy);
3309 // toolBar.addWidget(spacer);
3311 //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3313 //searchClearButton = toolBar.addAction("Search Clear");
3314 //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3315 //searchClearButton.setIcon(searchClearIcon);
3316 //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3317 //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3319 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3321 // Update the sychronize button picture
3323 public QMenu createPopupMenu() {
3324 QMenu contextMenu = super.createPopupMenu();
3326 contextMenu.addSeparator();
3327 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3328 contextMenu.addAction(prevAction);
3329 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3331 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3332 contextMenu.addAction(nextAction);
3333 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3335 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3336 contextMenu.addAction(upAction);
3337 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3339 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3340 contextMenu.addAction(downAction);
3341 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3343 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3344 contextMenu.addAction(synchronizeAction);
3345 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3347 QAction printAction = addContextAction("print", tr("Print"));
3348 contextMenu.addAction(printAction);
3349 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3351 QAction tagAction = addContextAction("tag", tr("Tag"));
3352 contextMenu.addAction(tagAction);
3353 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3355 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3356 contextMenu.addAction(attributeAction);
3357 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3359 QAction emailAction = addContextAction("email", tr("Email"));
3360 contextMenu.addAction(emailAction);
3361 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3363 QAction deleteAction = addContextAction("delete", tr("Delete"));
3364 contextMenu.addAction(deleteAction);
3365 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3367 QAction newAction = addContextAction("new", tr("Add"));
3368 contextMenu.addAction(newAction);
3369 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3371 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3372 contextMenu.addAction(allNotesAction);
3373 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3375 // QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3376 // contextMenu.addAction(searchClearAction);
3377 // searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3382 private QAction addContextAction(String config, String name) {
3383 QAction newAction = new QAction(this);
3384 newAction.setText(name);
3385 newAction.setCheckable(true);
3386 newAction.setChecked(Global.isToolbarButtonVisible(config, true));
3389 private void togglePrevArrowButton(Boolean toggle) {
3390 prevButton.setVisible(toggle);
3391 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3393 private void toggleNextArrowButton(Boolean toggle) {
3394 nextButton.setVisible(toggle);
3395 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3397 private void toggleUpArrowButton(Boolean toggle) {
3398 upButton.setVisible(toggle);
3399 Global.saveToolbarButtonsVisible("upArrow", toggle);
3401 private void toggleDownArrowButton(Boolean toggle) {
3402 downButton.setVisible(toggle);
3403 Global.saveToolbarButtonsVisible("downArrow", toggle);
3405 private void toggleSynchronizeButton(Boolean toggle) {
3406 synchronizeButton.setVisible(toggle);
3407 Global.saveToolbarButtonsVisible("synchronize", toggle);
3409 private void togglePrintButton(Boolean toggle) {
3410 printButton.setVisible(toggle);
3411 Global.saveToolbarButtonsVisible("print", toggle);
3413 private void toggleTagButton(Boolean toggle) {
3414 tagButton.setVisible(toggle);
3415 Global.saveToolbarButtonsVisible("tag", toggle);
3417 private void toggleAttributeButton(Boolean toggle) {
3418 attributeButton.setVisible(toggle);
3419 Global.saveToolbarButtonsVisible("attribute", toggle);
3421 private void toggleEmailButton(Boolean toggle) {
3422 emailButton.setVisible(toggle);
3423 Global.saveToolbarButtonsVisible("email", toggle);
3425 private void toggleDeleteButton(Boolean toggle) {
3426 deleteButton.setVisible(toggle);
3427 Global.saveToolbarButtonsVisible("delete", toggle);
3429 private void toggleNewButton(Boolean toggle) {
3430 newButton.setVisible(toggle);
3431 Global.saveToolbarButtonsVisible("new", toggle);
3433 private void toggleAllNotesButton(Boolean toggle) {
3434 allNotesButton.setVisible(toggle);
3435 Global.saveToolbarButtonsVisible("allNotes", toggle);
3437 // @SuppressWarnings("unused")
3438 // private void toggleSearchClearButton(Boolean toggle) {
3439 // searchClearButton.setVisible(toggle);
3440 // Global.saveToolbarButtonsVisible("searchClear", toggle);
3447 @SuppressWarnings("unused")
3448 private void updateSyncButton() {
3450 if (syncIcons == null) {
3451 syncIcons = new ArrayList<QPixmap>();
3453 synchronizeIconAngle = 0;
3454 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3456 for (int i=0; i<=360; i++) {
3457 QPixmap rotatedPix = new QPixmap(pix.size());
3458 QPainter p = new QPainter(rotatedPix);
3459 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3460 QSize size = pix.size();
3461 p.translate(size.width()/2, size.height()/2);
3464 p.setBackgroundMode(BGMode.OpaqueMode);
3465 p.translate(-size.width()/2, -size.height()/2);
3466 p.drawPixmap(0,0, pix);
3468 syncIcons.add(rotatedPix);
3472 synchronizeIconAngle++;
3473 if (synchronizeIconAngle > 359)
3474 synchronizeIconAngle=0;
3475 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3478 // Synchronize with Evernote
3480 private void evernoteSync() {
3481 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3482 if (!Global.isConnected)
3484 if (Global.isConnected)
3485 synchronizeAnimationTimer.start(5);
3486 // synchronizeAnimationTimer.start(200);
3488 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3490 private void updateQuotaBar() {
3491 long limit = Global.getUploadLimit();
3492 long amount = Global.getUploadAmount();
3493 if (amount>0 && limit>0) {
3494 int percent =(int)(amount*100/limit);
3495 quotaBar.setValue(percent);
3497 quotaBar.setValue(0);
3500 @SuppressWarnings("unused")
3501 private void zoomChanged() {
3502 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3505 //****************************************************************
3506 //****************************************************************
3507 //* System Tray functions
3508 //****************************************************************
3509 //****************************************************************
3510 private void trayToggleVisible() {
3515 if (windowMaximized)
3522 @SuppressWarnings("unused")
3523 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3524 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3525 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3526 trayToggleVisible();
3531 //***************************************************************
3532 //***************************************************************
3533 //** These functions deal with the trash tree
3534 //***************************************************************
3535 //***************************************************************
3536 // Setup the tree containing the trash.
3537 @SuppressWarnings("unused")
3538 private void trashTreeSelection() {
3539 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3541 clearNotebookFilter();
3543 clearAttributeFilter();
3544 clearSavedSearchFilter();
3546 String tempGuid = currentNoteGuid;
3548 // currentNoteGuid = "";
3549 currentNote = new Note();
3550 selectedNoteGUIDs.clear();
3551 listManager.getSelectedNotebooks().clear();
3552 listManager.getSelectedTags().clear();
3553 listManager.setSelectedSavedSearch("");
3554 browserWindow.clear();
3556 // toggle the add buttons
3557 newButton.setEnabled(!newButton.isEnabled());
3558 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3559 menuBar.noteAdd.setVisible(true);
3561 List<QTreeWidgetItem> selections = trashTree.selectedItems();
3562 if (selections.size() == 0) {
3563 currentNoteGuid = trashNoteGuid;
3564 trashNoteGuid = tempGuid;
3565 Global.showDeleted = false;
3566 menuBar.noteRestoreAction.setEnabled(false);
3567 menuBar.noteRestoreAction.setVisible(false);
3568 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3569 rensoNoteListDock.setEnabled(true);
3572 trashNoteGuid = tempGuid;
3573 currentNoteGuid = trashNoteGuid;
3574 menuBar.noteRestoreAction.setEnabled(true);
3575 menuBar.noteRestoreAction.setVisible(true);
3576 // ゴミ箱を開く。連想ノートリストをOFFに。
3577 rensoNoteListDock.setEnabled(false);
3579 Global.showDeleted = true;
3582 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3583 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3584 menuBar.noteAddNewTab.setEnabled(false);
3587 listManager.loadNotesIndex();
3588 noteIndexUpdated(false);
3589 //// browserWindow.setEnabled(newButton.isEnabled());
3590 browserWindow.setReadOnly(!newButton.isEnabled());
3591 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3593 // Empty the trash file
3594 @SuppressWarnings("unused")
3595 private void emptyTrash() {
3596 // browserWindow.clear();
3597 logger.log(logger.EXTREME, "Emptying Trash");
3598 listManager.emptyTrash();
3599 logger.log(logger.EXTREME, "Resetting view after trash empty");
3600 if (trashTree.selectedItems().size() > 0) {
3601 listManager.getSelectedNotebooks().clear();
3602 listManager.getSelectedTags().clear();
3603 listManager.setSelectedSavedSearch("");
3604 newButton.setEnabled(!newButton.isEnabled());
3605 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3606 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3607 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3608 menuBar.noteAddNewTab.setEnabled(false);
3610 menuBar.noteAdd.setVisible(true);
3611 browserWindow.clear();
3614 clearNotebookFilter();
3615 clearSavedSearchFilter();
3616 clearAttributeFilter();
3618 Global.showDeleted = false;
3619 menuBar.noteRestoreAction.setEnabled(false);
3620 menuBar.noteRestoreAction.setVisible(false);
3622 listManager.loadNotesIndex();
3623 noteIndexUpdated(false);
3625 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3626 if (!rensoNoteListDock.isEnabled()) {
3627 rensoNoteListDock.setEnabled(true);
3631 // Show/Hide trash window
3632 @SuppressWarnings("unused")
3633 private void toggleTrashWindow() {
3634 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3635 if (trashTree.isVisible())
3639 menuBar.hideTrash.setChecked(trashTree.isVisible());
3641 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3642 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3644 private void clearTrashFilter() {
3645 Global.showDeleted = false;
3646 newButton.setEnabled(true);
3647 menuBar.noteAdd.setEnabled(true);
3648 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3649 menuBar.noteAddNewTab.setEnabled(false);
3651 menuBar.noteAddNewTab.setEnabled(true);
3653 menuBar.noteAdd.setVisible(true);
3654 trashTree.blockSignals(true);
3655 trashTree.clearSelection();
3656 trashTree.blockSignals(false);
3661 //***************************************************************
3662 //***************************************************************
3663 //** These functions deal with connection settings
3664 //***************************************************************
3665 //***************************************************************
3666 // SyncRunner had a problem and things are disconnected
3667 @SuppressWarnings("unused")
3668 private void remoteErrorDisconnect() {
3669 menuBar.connectAction.setText(tr("Connect"));
3670 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3671 menuBar.synchronizeAction.setEnabled(false);
3672 Global.isConnected = false;
3673 synchronizeAnimationTimer.stop();
3676 // Do a manual connect/disconnect
3677 private void remoteConnect() {
3679 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3681 // If we are already connected, we just disconnect
3682 if (Global.isConnected) {
3683 Global.isConnected = false;
3684 syncRunner.enDisconnect();
3685 setupConnectMenuOptions();
3690 OAuthTokenizer tokenizer = new OAuthTokenizer();
3691 AESEncrypter aes = new AESEncrypter();
3693 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauthkey.txt")));
3694 } catch (FileNotFoundException e) {
3695 // File not found, so we'll just get empty strings anyway.
3699 if (Global.getProxyValue("url").equals("")) {
3700 System.setProperty("http.proxyHost","") ;
3701 System.setProperty("http.proxyPort", "") ;
3702 System.setProperty("https.proxyHost","") ;
3703 System.setProperty("https.proxyPort", "") ;
3706 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3707 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3708 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3709 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3711 if (Global.getProxyValue("userid").equals("")) {
3712 Authenticator.setDefault(new Authenticator() {
3714 protected PasswordAuthentication getPasswordAuthentication() {
3716 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3722 syncRunner.userStoreUrl = Global.userStoreUrl;
3723 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3724 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3728 String authString = aes.getString();
3729 if (!authString.equals("")) {
3730 tokenizer.tokenize(authString);
3731 syncRunner.authToken = tokenizer.oauth_token;
3732 syncRunner.enConnect();
3735 Global.isConnected = syncRunner.isConnected;
3737 boolean autoLoginMessageFlag = false;
3738 if (!Global.isConnected) {
3739 OAuthWindow window = new OAuthWindow(logger);
3741 setMessage(window.errorMessage);
3746 setMessage(window.errorMessage);
3749 tokenizer.tokenize(window.response);
3750 if (tokenizer.oauth_token.equals("")) {
3751 setMessage(tr("Invalid authorization token received."));
3754 aes.setString(window.response);
3756 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauthkey.txt")));
3757 } catch (FileNotFoundException e) {
3758 // TODO Auto-generated catch block
3759 e.printStackTrace();
3761 syncRunner.authToken = tokenizer.oauth_token;
3762 syncRunner.enConnect();
3763 Global.isConnected = syncRunner.isConnected;
3764 autoLoginMessageFlag = true;
3766 // Global.username = syncRunner.username;
3768 if (!Global.isConnected)
3771 setupConnectMenuOptions();
3773 // 初回ログイン時に自動ログインが無効だったら、有効化するか確認する
3774 if (autoLoginMessageFlag && !Global.automaticLogin()) {
3775 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure you want to enable the auto-login feature?"),
3776 QMessageBox.StandardButton.Yes, QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
3777 Global.setAutomaticLogin(true);
3781 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3783 private void setupConnectMenuOptions() {
3784 logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3785 if (!Global.isConnected) {
3786 menuBar.connectAction.setText(tr("Connect"));
3787 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3788 menuBar.synchronizeAction.setEnabled(false);
3790 menuBar.connectAction.setText(tr("Disconnect"));
3791 menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3792 menuBar.synchronizeAction.setEnabled(true);
3794 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3799 //***************************************************************
3800 //***************************************************************
3801 //** These functions deal with the GUI Attribute tree
3802 //***************************************************************
3803 //***************************************************************
3804 @SuppressWarnings("unused")
3805 private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3807 // clearTagFilter();
3808 // clearNotebookFilter();
3810 // clearSavedSearchFilter();
3812 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3813 if (!rensoNoteListDock.isEnabled()) {
3814 rensoNoteListDock.setEnabled(true);
3817 if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3818 if (item.childCount() > 0) {
3819 item.setSelected(false);
3821 Global.createdBeforeFilter.reset();
3822 Global.createdSinceFilter.reset();
3823 Global.changedBeforeFilter.reset();
3824 Global.changedSinceFilter.reset();
3825 Global.containsFilter.reset();
3826 attributeTreeSelected = item;
3827 DateAttributeFilterTable f = null;
3828 f = findDateAttributeFilterTable(item.parent());
3830 f.select(item.parent().indexOfChild(item));
3832 Global.containsFilter.select(item.parent().indexOfChild(item));
3835 listManager.loadNotesIndex();
3836 noteIndexUpdated(false);
3839 attributeTreeSelected = null;
3840 item.setSelected(false);
3841 Global.createdBeforeFilter.reset();
3842 Global.createdSinceFilter.reset();
3843 Global.changedBeforeFilter.reset();
3844 Global.changedSinceFilter.reset();
3845 Global.containsFilter.reset();
3846 listManager.loadNotesIndex();
3847 noteIndexUpdated(false);
3849 // This determines what attribute filter we need, depending upon the selection
3850 private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3851 if (w.parent() != null && w.childCount() > 0) {
3852 QTreeWidgetItem parent = w.parent();
3853 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3854 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3855 return Global.createdSinceFilter;
3856 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3857 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3858 return Global.createdBeforeFilter;
3859 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3860 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3861 return Global.changedSinceFilter;
3862 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3863 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3864 return Global.changedBeforeFilter;
3869 // Show/Hide attribute search window
3870 @SuppressWarnings("unused")
3871 private void toggleAttributesWindow() {
3872 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3873 if (attributeTree.isVisible())
3874 attributeTree.hide();
3876 attributeTree.show();
3877 menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3879 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3880 logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3882 private void clearAttributeFilter() {
3883 Global.createdBeforeFilter.reset();
3884 Global.createdSinceFilter.reset();
3885 Global.changedBeforeFilter.reset();
3886 Global.changedSinceFilter.reset();
3887 Global.containsFilter.reset();
3888 attributeTreeSelected = null;
3889 attributeTree.blockSignals(true);
3890 attributeTree.clearSelection();
3891 attributeTree.blockSignals(false);
3895 //***************************************************************
3896 //***************************************************************
3897 //** These functions deal with the GUI Note index table
3898 //***************************************************************
3899 //***************************************************************
3900 // Initialize the note list table
3901 private void initializeNoteTable() {
3902 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3903 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3904 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3905 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3907 // Show/Hide trash window
3908 @SuppressWarnings("unused")
3909 private void toggleNoteListWindow() {
3910 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3911 if (noteTableView.isVisible())
3912 noteTableView.hide();
3914 noteTableView.show();
3915 menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3917 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3918 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3920 // Handle the event that a user selects a note from the table
3921 @SuppressWarnings("unused")
3922 private void noteTableSelection() {
3923 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3928 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3929 // 選択されたノートのguidをselectedNoteGUIDsにセット
3930 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3931 if(selections.size() > 0){
3932 selectedNoteGUIDs.clear();
3933 for(int i = 0; i < selections.size(); i++){
3934 int row = selections.get(i).row();
3935 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3936 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3937 selectedNoteGUIDs.add((String) ix.values().toArray()[0]);
3943 // If we have more than one selection, then set the merge note action to true.
3944 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3945 if (selections.size() > 1)
3946 menuBar.noteMergeAction.setEnabled(true);
3948 menuBar.noteMergeAction.setEnabled(false);
3950 // If the ctrl key is pressed, then they are selecting multiple
3951 // entries and we don't want to change the currently viewed note.
3952 // Shiftキーを押しながらの場合の処理も追加
3953 if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) ||
3954 QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) &&
3955 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3956 selectedNoteGUIDs.clear();
3957 for (int i=0; i<selections.size(); i++) {
3958 int row = selections.get(i).row();
3959 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3960 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3961 selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3966 // IFIXED 恐らく不要なのでコメントアウト
3967 // if (historyGuids.size() == 0) {
3968 // historyGuids.add(currentNoteGuid);
3969 // historyPosition = 1;
3972 noteTableView.showColumn(Global.noteTableGuidPosition);
3974 if (!Global.isColumnVisible("guid"))
3975 noteTableView.hideColumn(Global.noteTableGuidPosition);
3977 if (selections.size() > 0) {
3979 menuBar.noteDuplicateAction.setEnabled(true);
3980 menuBar.noteOnlineHistoryAction.setEnabled(true);
3981 menuBar.noteMergeAction.setEnabled(true);
3982 selectedNoteGUIDs.clear();
3983 if (currentNoteGuid != null && !currentNoteGuid.equals("") && !Global.showDeleted) {
3984 menuBar.noteAddNewTab.setEnabled(true);
3986 if (selections.size() != 1 || Global.showDeleted) {
3987 menuBar.noteDuplicateAction.setEnabled(false);
3989 if (selections.size() != 1 || !Global.isConnected) {
3990 menuBar.noteOnlineHistoryAction.setEnabled(false);
3992 if (selections.size() == 1) {
3993 menuBar.noteMergeAction.setEnabled(false);
3995 for (int i=0; i<selections.size(); i++) {
3996 int row = selections.get(i).row();
3998 upButton.setEnabled(false);
4000 upButton.setEnabled(true);
4001 if (row < listManager.getNoteTableModel().rowCount()-1)
4002 downButton.setEnabled(true);
4004 downButton.setEnabled(false);
4005 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
4006 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
4008 currentNoteGuid = (String)ix.values().toArray()[0];
4009 selectedNoteGUIDs.add(currentNoteGuid);
4013 nextButton.setEnabled(true);
4014 prevButton.setEnabled(true);
4016 int currentIndex = tabBrowser.currentIndex();
4017 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4018 int histPosition = historyPosition.get(currentIndex);
4019 boolean fromHist = fromHistory.get(currentIndex);
4022 int endPosition = histGuids.size() - 1;
4024 for (int j = histPosition; j <= endPosition; j++) {
4025 histGuids.remove(histGuids.size() - 1);
4027 histGuids.add(currentNoteGuid);
4028 historyPosition.put(currentIndex, histGuids.size());
4029 histPosition = histGuids.size();
4031 if (histPosition <= 1){
4032 prevButton.setEnabled(false);
4034 if (histPosition == histGuids.size())
4035 nextButton.setEnabled(false);
4036 fromHistory.put(currentIndex, false);
4039 scrollToGuid(currentNoteGuid);
4040 refreshEvernoteNote(true);
4042 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4043 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4049 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
4052 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4055 // 複数ノートの同時閲覧履歴をデータベースに保存
4056 private void addBrowseHistory() {
4057 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4058 if (tabWindows.size() >= 2) {
4059 Iterator<Integer> it = tabWindows.keySet().iterator();
4060 while (it.hasNext()) {
4061 int tabIndex = it.next();
4062 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4063 // guid1=guid2のデータは登録しない
4064 if (!currentNoteGuid.equals(nextGuid)) {
4065 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4069 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4070 if (externalWindows.size() >= 1) {
4071 Iterator<String> it = externalWindows.keySet().iterator();
4072 while (it.hasNext()) {
4073 String nextGuid = it.next();
4074 // guid1=guid2のデータは登録しない
4075 if (!currentNoteGuid.equals(nextGuid)) {
4076 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4082 // Trigger a refresh when the note db has been updated
4083 private void noteIndexUpdated(boolean reload) {
4084 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4086 refreshEvernoteNoteList();
4087 logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4088 noteTableView.load(reload);
4089 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4091 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4092 pos = noteTableView.proxyModel.rowCount();
4095 if (noteTableView.proxyModel.rowCount() == 0)
4098 QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4100 currentNoteGuid = (String)i.data();
4104 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4106 scrollToGuid(currentNoteGuid);
4107 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4109 // Called when the list of notes is updated
4110 private void refreshEvernoteNoteList() {
4111 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4112 browserWindow.setDisabled(false);
4113 if (selectedNoteGUIDs == null)
4114 selectedNoteGUIDs = new ArrayList<String>();
4115 selectedNoteGUIDs.clear(); // clear out old entries
4117 String saveCurrentNoteGuid = new String();
4118 String tempNoteGuid = new String();
4120 int currentIndex = tabBrowser.currentIndex();
4121 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4123 historyPosition.put(currentIndex, 0);
4125 prevButton.setEnabled(false);
4126 nextButton.setEnabled(false);
4128 if (currentNoteGuid == null)
4129 currentNoteGuid = new String();
4131 //determine current note guid
4132 for (Note note : listManager.getNoteIndex()) {
4133 tempNoteGuid = note.getGuid();
4134 if (currentNoteGuid.equals(tempNoteGuid)) {
4135 saveCurrentNoteGuid = tempNoteGuid;
4139 if (listManager.getNoteIndex().size() == 0) {
4140 currentNoteGuid = "";
4142 browserWindow.clear();
4143 browserWindow.setDisabled(true);
4147 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4148 currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4149 saveCurrentNoteGuid = currentNoteGuid;
4150 refreshEvernoteNote(true);
4153 if (!saveCurrentNoteGuid.equals("")) {
4154 refreshEvernoteNote(false);
4156 currentNoteGuid = "";
4158 reloadTagTree(false);
4160 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4163 // Called when the previous arrow button is clicked
4164 @SuppressWarnings("unused")
4165 private void previousViewedAction() {
4166 int currentIndex = tabBrowser.currentIndex();
4167 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4168 int histPosition = historyPosition.get(currentIndex);
4169 boolean fromHist = fromHistory.get(currentIndex);
4170 if (!prevButton.isEnabled())
4172 if (histPosition == 0)
4175 historyPosition.put(currentIndex, histPosition);
4176 if (histPosition <= 0)
4178 String historyGuid = histGuids.get(histPosition - 1);
4179 fromHistory.put(currentIndex, true);
4181 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4182 QModelIndex modelIndex = noteTableView.model().index(i,
4183 Global.noteTableGuidPosition);
4184 if (modelIndex != null) {
4185 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4187 String tableGuid = (String) ix.values().toArray()[0];
4188 if (tableGuid.equals(historyGuid)) {
4189 noteTableView.selectRow(i);
4196 @SuppressWarnings("unused")
4197 private void nextViewedAction() {
4198 if (!nextButton.isEnabled())
4201 int currentIndex = tabBrowser.currentIndex();
4202 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4203 int histPosition = historyPosition.get(currentIndex);
4204 boolean fromHist = fromHistory.get(currentIndex);
4205 String historyGuid = histGuids.get(histPosition);
4207 historyPosition.put(currentIndex, histPosition);
4208 fromHistory.put(currentIndex, true);
4210 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4211 QModelIndex modelIndex = noteTableView.model().index(i,
4212 Global.noteTableGuidPosition);
4213 if (modelIndex != null) {
4214 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4216 String tableGuid = (String) ix.values().toArray()[0];
4217 if (tableGuid.equals(historyGuid)) {
4218 noteTableView.selectRow(i);
4224 // Called when the up arrow is clicked
4225 @SuppressWarnings("unused")
4226 private void upAction() {
4227 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4228 int row = selections.get(0).row();
4230 noteTableView.selectRow(row-1);
4233 // Called when the down arrow is clicked
4234 @SuppressWarnings("unused")
4235 private void downAction() {
4236 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4237 int row = selections.get(0).row();
4238 int max = listManager.getNoteTableModel().rowCount();
4240 noteTableView.selectRow(row+1);
4243 // Update a tag string for a specific note in the list
4244 @SuppressWarnings("unused")
4245 private void updateListTags(String guid, List<String> tags) {
4246 logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4247 StringBuffer tagBuffer = new StringBuffer();
4248 for (int i=0; i<tags.size(); i++) {
4249 tagBuffer.append(tags.get(i));
4250 if (i<tags.size()-1)
4251 tagBuffer.append(", ");
4254 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4255 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4256 if (modelIndex != null) {
4257 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4258 String tableGuid = (String)ix.values().toArray()[0];
4259 if (tableGuid.equals(guid)) {
4260 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4261 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4262 noteTableView.proxyModel.invalidate();
4267 logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4269 // Update a title for a specific note in the list
4270 @SuppressWarnings("unused")
4271 private void updateListAuthor(String guid, String author) {
4272 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4274 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4275 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4276 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4277 if (modelIndex != null) {
4278 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4279 String tableGuid = (String)ix.values().toArray()[0];
4280 if (tableGuid.equals(guid)) {
4281 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4282 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4283 noteTableView.proxyModel.invalidate();
4289 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4291 private void updateListNoteNotebook(String guid, String notebook) {
4292 logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4293 listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4294 logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4296 // Update a title for a specific note in the list
4297 @SuppressWarnings("unused")
4298 private void updateListSourceUrl(String guid, String url) {
4299 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4301 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4302 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4303 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4304 if (modelIndex != null) {
4305 // SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4306 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4307 String tableGuid = (String)ix.values().toArray()[0];
4308 if (tableGuid.equals(guid)) {
4309 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4310 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4311 noteTableView.proxyModel.invalidate();
4316 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4318 @SuppressWarnings("unused")
4319 private void updateListGuid(String oldGuid, String newGuid) {
4320 logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4322 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4323 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4324 if (modelIndex != null) {
4325 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4326 String tableGuid = (String)ix.values().toArray()[0];
4327 if (tableGuid.equals(oldGuid)) {
4328 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4329 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4334 logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4336 private void updateListTagName(String guid) {
4337 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4339 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4340 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4341 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4343 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4344 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4345 if (modelIndex != null) {
4346 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4347 String noteGuid = (String)ix.values().toArray()[0];
4348 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4349 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4350 i=listManager.getNoteTableModel().rowCount();
4356 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4358 private void removeListTagName(String guid) {
4359 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4361 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4362 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4363 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4364 if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4365 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4368 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4369 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4370 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4371 if (modelIndex != null) {
4372 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4373 String noteGuid = (String)ix.values().toArray()[0];
4374 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4375 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4376 i=listManager.getNoteTableModel().rowCount();
4382 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4384 private void updateListNotebookName(String oldName, String newName) {
4385 logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4387 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4388 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition);
4389 if (modelIndex != null) {
4390 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4391 String tableName = (String)ix.values().toArray()[0];
4392 if (tableName.equalsIgnoreCase(oldName)) {
4393 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4397 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4399 @SuppressWarnings("unused")
4400 private void updateListDateCreated(String guid, QDateTime date) {
4401 logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
4403 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4404 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4405 if (modelIndex != null) {
4406 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4407 String tableGuid = (String)ix.values().toArray()[0];
4408 if (tableGuid.equals(guid)) {
4409 listManager.getNoteTableModel().setData(i, Global.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4410 noteTableView.proxyModel.invalidate();
4415 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4417 @SuppressWarnings("unused")
4418 private void updateListDateSubject(String guid, QDateTime date) {
4419 logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
4421 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4422 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4423 if (modelIndex != null) {
4424 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4425 String tableGuid = (String)ix.values().toArray()[0];
4426 if (tableGuid.equals(guid)) {
4427 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4428 listManager.getNoteTableModel().setData(i, Global.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4429 noteTableView.proxyModel.invalidate();
4434 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4436 private void updateListDateChanged(String guid, QDateTime date) {
4437 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4439 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4440 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4441 if (modelIndex != null) {
4442 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4443 String tableGuid = (String)ix.values().toArray()[0];
4444 if (tableGuid.equals(guid)) {
4445 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4446 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4451 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4453 private void updateListDateChanged() {
4454 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4455 QDateTime date = new QDateTime(QDateTime.currentDateTime());
4456 updateListDateChanged(currentNoteGuid, date);
4457 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4460 private void scrollToCurrentGuid() {
4461 //scrollToGuid(currentNoteGuid);
4462 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4463 if (selections.size() == 0)
4465 QModelIndex index = selections.get(0);
4466 int row = selections.get(0).row();
4467 String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4470 // Scroll to the current GUID in tthe list.
4471 // Scroll to a particular index item
4472 private void scrollToGuid(String guid) {
4473 if (currentNote == null || guid == null)
4475 if (currentNote.isActive() && Global.showDeleted) {
4476 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4477 if (!listManager.getNoteIndex().get(i).isActive()) {
4478 currentNote = listManager.getNoteIndex().get(i);
4479 currentNoteGuid = currentNote.getGuid();
4480 i = listManager.getNoteIndex().size();
4484 if (!currentNote.isActive() && !Global.showDeleted) {
4485 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4486 if (listManager.getNoteIndex().get(i).isActive()) {
4487 currentNote = listManager.getNoteIndex().get(i);
4488 currentNoteGuid = currentNote.getGuid();
4489 i = listManager.getNoteIndex().size();
4494 for (int i=0; i<noteTableView.model().rowCount(); i++) {
4495 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4496 if (currentNoteGuid.equals(index.data())) {
4497 // noteTableView.selectionModel().blockSignals(true);
4498 noteTableView.selectRow(i);
4499 // noteTableView.selectionModel().blockSignals(false);
4500 noteTableView.scrollTo(index, ScrollHint.EnsureVisible); // This should work, but it doesn't
4501 i=listManager.getNoteTableModel().rowCount();
4504 noteTableView.repaint();
4506 // Show/Hide columns
4507 private void showColumns() {
4508 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4509 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4510 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4511 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4512 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4513 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4514 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4515 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4516 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4517 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4518 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));
4519 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned"));
4521 // Title color has changed
4522 @SuppressWarnings("unused")
4523 private void titleColorChanged(Integer color) {
4524 logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4527 QColor backgroundColor = new QColor();
4528 QColor foregroundColor = new QColor(QColor.black);
4529 backgroundColor.setRgb(color);
4531 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4532 foregroundColor.setRgb(QColor.white.rgb());
4534 if (selectedNoteGUIDs.size() == 0)
4535 selectedNoteGUIDs.add(currentNoteGuid);
4537 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4538 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4539 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4540 if (modelIndex != null) {
4541 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4542 String tableGuid = (String)ix.values().toArray()[0];
4543 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4544 for (int k=0; k<Global.noteTableColumnCount; k++) {
4545 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4546 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4547 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4549 i=listManager.getNoteTableModel().rowCount();
4554 logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4556 // A note has been pinned or unpinned
4557 @SuppressWarnings("unused")
4558 private void notePinned() {
4559 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4562 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4563 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4564 boolean pinned = !meta.isPinned();
4565 meta.setPinned(pinned); // Toggle the pinned/unpinned
4567 // Update the list & table
4568 listManager.updateNoteMetadata(meta);
4569 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4571 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4573 // Wide list was chosen
4574 public void narrowListView() {
4575 saveNoteColumnPositions();
4576 saveNoteIndexWidth();
4578 int sortCol = noteTableView.proxyModel.sortColumn();
4579 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4580 Global.setSortColumn(sortCol);
4581 Global.setSortOrder(sortOrder);
4583 Global.setListView(Global.View_List_Narrow);
4585 menuBar.wideListView.blockSignals(true);
4586 menuBar.narrowListView.blockSignals(true);
4588 menuBar.wideListView.setChecked(false);
4589 menuBar.narrowListView.setChecked(true);
4591 menuBar.wideListView.blockSignals(false);
4592 menuBar.narrowListView.blockSignals(false);
4594 mainLeftRightSplitter.addWidget(noteTableView);
4595 mainLeftRightSplitter.addWidget(tabBrowser);
4597 restoreWindowState(false);
4598 noteTableView.repositionColumns();
4599 noteTableView.resizeColumnWidths();
4600 noteTableView.resizeRowHeights();
4602 sortCol = Global.getSortColumn();
4603 sortOrder = Global.getSortOrder();
4604 noteTableView.proxyModel.blocked = true;
4605 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4606 noteTableView.proxyModel.blocked = false;
4610 noteTableView.load(false);
4611 refreshEvernoteNote(true);
4612 scrollToCurrentGuid();
4614 public void wideListView() {
4615 int sortCol = noteTableView.proxyModel.sortColumn();
4616 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4617 Global.setSortColumn(sortCol);
4618 Global.setSortOrder(sortOrder);
4621 saveNoteColumnPositions();
4622 saveNoteIndexWidth();
4623 Global.setListView(Global.View_List_Wide);
4625 menuBar.wideListView.blockSignals(true);
4626 menuBar.narrowListView.blockSignals(true);
4628 menuBar.wideListView.setChecked(true);
4629 menuBar.narrowListView.setChecked(false);
4631 menuBar.wideListView.blockSignals(false);
4632 menuBar.narrowListView.blockSignals(false);
4633 browserIndexSplitter.setVisible(true);
4634 browserIndexSplitter.addWidget(noteTableView);
4635 browserIndexSplitter.addWidget(tabBrowser);
4637 restoreWindowState(false);
4638 noteTableView.repositionColumns();
4639 noteTableView.resizeColumnWidths();
4640 noteTableView.resizeRowHeights();
4642 sortCol = Global.getSortColumn();
4643 sortOrder = Global.getSortOrder();
4644 noteTableView.proxyModel.blocked = true;
4645 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4646 noteTableView.proxyModel.blocked = false;
4649 noteTableView.load(false);
4650 scrollToCurrentGuid();
4652 // Sort order for the notebook has changed
4653 public void tableSortOrderChanged(Integer column, Integer order) {
4655 // Find what notebook (if any) is selected. We ignore stacks & the "All Notebooks".
4656 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4657 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4658 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4660 notebook = currentSelectedNotebook.text(2);
4661 conn.getNotebookTable().setSortOrder(notebook, column, order);
4665 //***************************************************************
4666 @SuppressWarnings("unused")
4667 private void evernoteLinkClick(String syncGuid, String locGuid) {
4669 if (conn.getNoteTable().guidExists(syncGuid)) {
4672 // If we didn't find it via the synchronized guid, look under the local guid
4673 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was
4674 // later synchronized (that causes the guid to change so we need to find the new one).
4675 if (conn.getNoteTable().guidExists(locGuid))
4678 guid = conn.getNoteTable().findAlternateGuid(locGuid);
4681 openExternalEditor(guid);
4685 //If we've gotten this far, we can't find the note
4686 QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4687 " seem to find that note."));
4689 //***************************************************************
4690 //***************************************************************
4691 //** External editor window functions
4692 //***************************************************************
4693 //***************************************************************
4694 private void listDoubleClick() {
4696 openExternalEditor(currentNoteGuid);
4698 private void openExternalEditor(String guid) {
4700 if (externalWindows.containsKey(guid)) {
4701 externalWindows.get(guid).raise();
4705 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4706 // We have a new external editor to create
4707 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4708 ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4710 newBrowser.setWindowIcon(appIcon);
4711 externalWindows.put(guid, newBrowser);
4712 showEditorButtons(newBrowser.getBrowserWindow());
4713 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4714 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4715 newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4716 //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4717 newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4718 newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4719 newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4720 newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4722 browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4723 browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4724 browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4728 @SuppressWarnings({ "rawtypes", "unused" })
4729 private void externalWindowTagsEdited(String guid, List values) {
4730 StringBuffer line = new StringBuffer(100);
4731 for (int i=0; i<values.size(); i++) {
4733 line.append(Global.tagDelimeter+" ");
4734 line.append(values.get(i));
4736 if (guid.equals(currentNoteGuid)) {
4737 browserWindow.setTag(line.toString());
4740 @SuppressWarnings("unused")
4741 private void externalWindowClosing(String guid) {
4742 externalWindows.remove(guid);
4745 // ***************************************************************
4746 // ***************************************************************
4748 // ***************************************************************
4749 // ***************************************************************
4750 @SuppressWarnings("unused")
4751 private void openNewTab() {
4754 // selectedNoteGUIDsをディープコピー
4755 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4757 for (int i=0; i < copySelected.size() ; i++) {
4758 openTabEditor(copySelected.get(i));
4762 // 連想ノートリストから新しいタブで開く
4763 @SuppressWarnings("unused")
4764 private void openNewTabFromRNL(){
4765 if(rensoNotePressedItemGuid != null){
4766 String prevCurrentNoteGuid = new String(currentNoteGuid);
4769 openTabEditor(rensoNotePressedItemGuid);
4771 // 連想ノートリストアイテムクリック操作を記録
4772 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4776 private void openTabEditor(String guid) {
4778 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4780 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4781 showEditorButtons(newBrowser.getBrowserWindow());
4783 String noteTitle = note.getTitle();
4784 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4785 tabWindows.put(index, newBrowser);
4786 noteDirty.put(index, false);
4788 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4789 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4790 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4792 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4794 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4796 // ExtendedInformationを必要があれば表示する
4797 toggleNoteInformation();
4798 // Sourceを必要があれば表示する
4800 // EditorButtonsBarを必要があれば表示する
4801 toggleEditorButtonBar();
4804 ArrayList<String> histGuids = new ArrayList<String>();
4805 historyGuids.put(index, histGuids);
4806 historyPosition.put(index, 0);
4807 fromHistory.put(index, false);
4810 histGuids.add(guid);
4811 historyPosition.put(index, histGuids.size());
4813 tabBrowser.setCurrentIndex(index);
4815 if (guid != null && !guid.equals("")) {
4816 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4823 @SuppressWarnings("unused")
4824 private void tabCloseRequested(int index) {
4825 tabWindowClosing((TabBrowse)tabBrowser.widget(index));
4829 private void tabWindowClosing(TabBrowse tab) {
4831 if (tabBrowser.count() <= 1) {
4835 int index = tabBrowser.indexOf(tab);
4836 // String guid = tab.getBrowserWindow().getNote().getGuid();
4837 // String content = tab.getBrowserWindow().getContent();
4838 BrowserWindow browser = tab.getBrowserWindow();
4839 // // ノートが変更されていたら保存
4840 // if (tab.getNoteDirty()) {
4841 // saveNoteTabBrowser(guid, content, true, browser);
4845 browser.noteSignal.tagsChanged.disconnect();
4846 browser.noteSignal.titleChanged.disconnect();
4847 browser.noteSignal.noteChanged.disconnect();
4848 browser.noteSignal.notebookChanged.disconnect();
4849 browser.noteSignal.createdDateChanged.disconnect();
4850 browser.noteSignal.alteredDateChanged.disconnect();
4853 tabWindows.remove(index);
4854 tabBrowser.removeTab(index);
4855 noteDirty.remove(index);
4856 inkNote.remove(index);
4857 readOnly.remove(index);
4860 historyGuids.remove(index);
4861 historyPosition.remove(index);
4862 fromHistory.remove(index);
4864 // タブのインデックスを更新(削除によって空いた部分を詰める)
4865 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4867 TabBrowse nextTab = tabWindows.get(i + 1);
4868 tabWindows.put(i, nextTab);
4869 tabWindows.remove(i + 1);
4871 boolean isNoteDirty = noteDirty.get(i + 1);
4872 noteDirty.put(i, isNoteDirty);
4873 noteDirty.remove(i + 1);
4875 boolean isInkNote = inkNote.get(i + 1);
4876 inkNote.put(i, isInkNote);
4877 inkNote.remove(i + 1);
4879 boolean isReadOnly = readOnly.get(i + 1);
4880 readOnly.put(i, isReadOnly);
4881 readOnly.remove(i + 1);
4883 ArrayList<String> histGuids = historyGuids.get(i + 1);
4884 historyGuids.put(i, histGuids);
4885 historyGuids.remove(i + 1);
4887 int histPosition = historyPosition.get(i + 1);
4888 historyPosition.put(i, histPosition);
4889 historyPosition.remove(i + 1);
4891 boolean fromHist = fromHistory.get(i + 1);
4892 fromHistory.put(i, fromHist);
4893 fromHistory.remove(i + 1);
4896 // タブが残り1つになったら、閉じるボタンを消す
4897 if (tabBrowser.count() == 1) {
4898 tabBrowser.hideTabCloseButton(0);
4901 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4902 tabWindowChanged(tabBrowser.currentIndex());
4905 @SuppressWarnings("unused")
4906 private void noteAddNewTab() {
4909 // ノートを何も開いていないときは現在のタブにノート追加
4910 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4915 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4916 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4917 String prevTabGuid = null;
4918 if (prevTab.getBrowserWindow() != null && prevTab.getBrowserWindow().getNote() != null) {
4919 prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4922 openEmptyTabEditor();
4925 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4926 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4927 TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4928 String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4929 if (addedTabGuid != null && !addedTabGuid.equals("")) {
4930 if (!prevTabGuid.equals(addedTabGuid)) {
4931 conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4937 private void openEmptyTabEditor() {
4939 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4940 showEditorButtons(newBrowser.getBrowserWindow());
4942 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4944 int index = tabBrowser.addNewTab(newBrowser, "");
4945 tabWindows.put(index, newBrowser);
4946 noteDirty.put(index, false);
4948 // ExtendedInformationを必要があれば表示する
4949 toggleNoteInformation();
4950 // Sourceを必要があれば表示する
4952 // EditorButtonsBarを必要があれば表示する
4953 toggleEditorButtonBar();
4956 ArrayList<String> histGuids = new ArrayList<String>();
4957 historyGuids.put(index, histGuids);
4958 historyPosition.put(index, 0);
4959 fromHistory.put(index, false);
4961 tabBrowser.setCurrentIndex(index);
4964 //***************************************************************
4965 //***************************************************************
4966 //** These functions deal with Note specific things
4967 //***************************************************************
4968 //***************************************************************
4969 private void setNoteDirty() {
4970 for (String guid: selectedNoteGUIDs) {
4975 private void setNoteDirty(String targetGuid) {
4976 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
4978 // Find if the note is being edited externally. If it is, update it.
4979 if (externalWindows.containsKey(targetGuid)) {
4980 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4981 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4982 ExternalBrowse window = externalWindows.get(targetGuid);
4983 window.getBrowserWindow().setContent(unicode);
4986 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
4987 Collection<Integer> tabIndexes = tabWindows.keySet();
4988 Iterator<Integer> indexIterator = tabIndexes.iterator();
4990 for (TabBrowse tab: tabWindows.values()) {
4991 int index = indexIterator.next();
4992 String guid = tab.getBrowserWindow().getNote().getGuid();
4994 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4995 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4997 if (guid.equals(guid)) {
4998 if (index != tabBrowser.currentIndex()) {
4999 TabBrowse window = tabWindows.get(index);
5000 window.getBrowserWindow().setContent(unicode);
5005 // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する
5006 // If the note is dirty, then it is unsynchronized by default.
5008 boolean isNoteDirty = false;
5009 for (TabBrowse tab: tabWindows.values()) {
5010 if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) {
5011 index = tabBrowser.indexOf(tab);
5012 isNoteDirty = noteDirty.get(index);
5020 // Set the note as dirty and check if its status is synchronized in the display table
5021 // まだダーティでなく、かつタブで開かれている場合にnoteDirty = trueにする
5023 noteDirty.put(index, true);
5026 if (listManager.getNoteMetadata().containsKey(targetGuid) &&
5027 listManager.getNoteMetadata().get(targetGuid).isDirty()) {
5031 // If this wasn't already marked as unsynchronized, then we need to update the table
5032 listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false);
5033 // listManager.getUnsynchronizedNotes().add(targetGuid);
5034 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
5035 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
5036 if (modelIndex != null) {
5037 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5038 String tableGuid = (String)ix.values().toArray()[0];
5039 if (tableGuid.equals(targetGuid)) {
5040 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
5046 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
5048 @SuppressWarnings("unused")
5049 private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
5050 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5051 QByteArray unicode = codec.fromUnicode(content);
5052 noteCache.remove(guid);
5053 noteCache.put(guid, unicode.toString());
5054 if (guid.equals(currentNoteGuid)) {
5055 int index = tabBrowser.currentIndex();
5056 noteDirty.put(index, true);
5057 browserWindow.setContent(unicode);
5060 thumbnailRunner.addWork("GENERATE "+ guid);
5061 saveNote(guid, browser);
5066 // private void saveNoteTabBrowser(String guid, String content, Boolean save,
5067 // BrowserWindow browser) {
5068 // QTextCodec codec = QTextCodec.codecForName("UTF-8");
5069 // QByteArray unicode = codec.fromUnicode(content);
5070 // noteCache.remove(guid);
5071 // noteCache.put(guid, unicode.toString());
5073 // thumbnailRunner.addWork("GENERATE " + guid);
5074 // saveNote(guid, browser);
5078 private void saveNote() {
5079 // すべてのタブに対して、Dirtyを確認し、trueならセーブする
5080 Collection<Integer> dirtyIndex = noteDirty.keySet();
5081 Iterator<Integer> indexIterator = dirtyIndex.iterator();
5082 for (boolean isNoteDirty: noteDirty.values()) {
5083 int index = indexIterator.next();
5088 BrowserWindow b = tabWindows.get(index).getBrowserWindow();
5089 String guid = b.getNote().getGuid();
5091 thumbnailRunner.addWork("GENERATE "+ guid);
5092 noteDirty.put(index, false);
5096 private void saveNote(String guid, BrowserWindow window) {
5097 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5100 logger.log(logger.EXTREME, "Saving to cache");
5101 QTextCodec codec = QTextCodec.codecForLocale();
5102 // QTextDecoder decoder = codec.makeDecoder();
5103 codec = QTextCodec.codecForName("UTF-8");
5104 QByteArray unicode = codec.fromUnicode(window.getContent());
5105 noteCache.put(guid, unicode.toString());
5107 logger.log(logger.EXTREME, "updating list manager");
5108 listManager.updateNoteContent(guid, window.getContent());
5109 logger.log(logger.EXTREME, "Updating title");
5110 listManager.updateNoteTitle(guid, window.getTitle());
5111 updateListDateChanged();
5113 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5114 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5115 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5116 currentNote = listManager.getNoteIndex().get(i);
5117 i = listManager.getNoteIndex().size();
5122 // Get a note from Evernote (and put it in the browser)
5123 private void refreshEvernoteNote(boolean reload) {
5124 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5126 if (Global.disableViewing) {
5127 browserWindow.setEnabled(false);
5130 inkNote.put(tabBrowser.currentIndex(), false);
5131 readOnly.put(tabBrowser.currentIndex(), false);
5133 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) {
5134 readOnly.put(tabBrowser.currentIndex(), true);
5136 Global.cryptCounter =0;
5137 if (readOnly.get(tabBrowser.currentIndex())) {
5138 browserWindow.setReadOnly(true);
5145 browserWindow.loadingData(true);
5147 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5148 if (currentNote == null) {
5153 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5155 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5158 private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5159 NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
5160 formatter.setNote(note, Global.pdfPreview());
5161 formatter.setHighlight(listManager.getEnSearch());
5166 for (TabBrowse tab: tabWindows.values()) {
5167 if (tab.getBrowserWindow() == browser) {
5168 tabIndex = tabBrowser.indexOf(tab);
5173 if (!noteCache.containsKey(guid)) {
5174 js = new QByteArray();
5175 // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
5176 js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
5177 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>");
5178 js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5179 js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5180 if (Global.displayRightToLeft())
5181 js.append("<style> body { direction:rtl; }</style>");
5182 js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5183 js.append("</head>");
5184 formatter.setNote(note, Global.pdfPreview());
5185 js.append(formatter.rebuildNoteHTML());
5186 js.append("</HTML>");
5187 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5188 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5189 js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5190 // if (Global.enableHTMLEntitiesFix) {
5191 // browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5193 browser.setContent(js);
5194 noteCache.put(guid, js.toString());
5196 if (formatter.resourceError)
5197 resourceErrorMessage(tabIndex);
5198 if (formatter.formatError) {
5200 QMessageBox.information(this, tr("Error"),
5201 tr("NeighborNote had issues formatting this note." +
5202 " To protect your data this note is being marked as read-only."));
5206 if (tabIndex >= 0) {
5207 readOnly.put(tabIndex, formatter.readOnly);
5208 inkNote.put(tabIndex, formatter.inkNote);
5211 if (tabIndex >= 0 && readOnly.get(tabIndex)) {
5212 readOnlyCache.put(guid, true);
5214 if (tabIndex >= 0 && inkNote.get(tabIndex)) {
5215 inkNoteCache.put(guid, true);
5219 logger.log(logger.HIGH, "Note content is being pulled from the cache");
5220 String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5221 js = new QByteArray(cachedContent);
5222 browser.setContent(js);
5223 if (readOnlyCache.containsKey(guid) && tabIndex >= 0) {
5224 readOnly.put(tabIndex, true);
5226 readOnly.put(tabIndex, false);
5228 if (inkNoteCache.containsKey(guid) && tabIndex >= 0) {
5229 inkNote.put(tabIndex, true);
5231 inkNote.put(tabIndex, false);
5234 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5235 thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5237 if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) ||
5238 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != "")))
5239 browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
5241 browser.getBrowser().page().setContentEditable(true);
5242 if (tabIndex >= 0) {
5243 browser.setReadOnly(readOnly.get(tabIndex));
5244 deleteButton.setEnabled(!readOnly.get(tabIndex));
5245 tagButton.setEnabled(!readOnly.get(tabIndex));
5246 menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex));
5247 menuBar.noteTags.setEnabled(!readOnly.get(tabIndex));
5249 browser.setNote(note);
5251 if (note != null && note.getNotebookGuid() != null &&
5252 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5253 deleteButton.setEnabled(false);
5254 menuBar.notebookDeleteAction.setEnabled(false);
5256 deleteButton.setEnabled(true);
5257 menuBar.notebookDeleteAction.setEnabled(true);
5260 // Build a list of non-closed notebooks
5261 List<Notebook> nbooks = new ArrayList<Notebook>();
5262 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5263 boolean found=false;
5264 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5265 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
5269 nbooks.add(listManager.getNotebookIndex().get(i));
5272 browser.setTitle(note.getTitle());
5273 browser.setTag(getTagNamesForNote(note));
5274 browser.setAuthor(note.getAttributes().getAuthor());
5276 browser.setAltered(note.getUpdated());
5277 browser.setCreation(note.getCreated());
5278 if (note.getAttributes().getSubjectDate() > 0)
5279 browser.setSubjectDate(note.getAttributes().getSubjectDate());
5281 browser.setSubjectDate(note.getCreated());
5282 browser.setUrl(note.getAttributes().getSourceURL());
5284 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5285 List<Tag> tagList = tagFilter.getValidTags(note);
5286 browser.setAllTags(tagList);
5288 browser.setCurrentTags(note.getTagNames());
5289 for (TabBrowse tab: tabWindows.values()) {
5290 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
5291 int index = tabBrowser.indexOf(tab);
5292 noteDirty.put(index, false);
5299 browser.loadingData(false);
5300 if (thumbnailViewer.isActiveWindow())
5303 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5304 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5307 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5310 @SuppressWarnings("unused")
5311 private void toggleNoteAttributes() {
5312 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5313 toggleNoteInformation();
5316 // Save a generated thumbnail
5317 private void toggleNoteInformation() {
5318 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5320 boolean isChecked = menuBar.noteAttributes.isChecked();
5322 for(int i = 0; i < tabBrowser.count(); i++){
5323 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5324 boolean isExtended = browser.isExtended();
5325 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5326 browser.toggleInformation();
5330 menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5331 Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5332 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5335 // Listener triggered when a print button is pressed
5336 @SuppressWarnings("unused")
5337 private void printNote() {
5338 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5340 QPrintDialog dialog = new QPrintDialog();
5341 if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5342 QPrinter printer = dialog.printer();
5343 browserWindow.getBrowser().print(printer);
5345 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5348 // Listener triggered when the email button is pressed
5349 @SuppressWarnings("unused")
5350 private void emailNote() {
5351 logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5353 if (Desktop.isDesktopSupported()) {
5354 Desktop desktop = Desktop.getDesktop();
5356 String text2 = browserWindow.getContentsToEmail();
5357 QUrl url = new QUrl("mailto:");
5358 url.addQueryItem("subject", currentNote.getTitle());
5359 // url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5360 url.addQueryItem("body", text2);
5361 QDesktopServices.openUrl(url);
5365 if (desktop.isSupported(Desktop.Action.MAIL)) {
5366 URI uriMailTo = null;
5368 //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5369 String text = browserWindow.getContentsToEmail();
5370 //text = "<b>" +text +"</b>";
5371 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5372 +"&BODY=" +text, null);
5373 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5374 +"&ATTACHMENT=d:/test.pdf", null);
5375 desktop.mail(uriMailTo);
5376 } catch (URISyntaxException e) {
5377 e.printStackTrace();
5378 } catch (IOException e) {
5379 e.printStackTrace();
5386 logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5388 // Reindex all notes
5389 @SuppressWarnings("unused")
5390 private void fullReindex() {
5391 logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5392 indexRunner.addWork("REINDEXALL");
5393 setMessage(tr("Database will be reindexed."));
5394 logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5396 // Listener when a user wants to reindex a specific note
5397 @SuppressWarnings("unused")
5398 private void reindexNote() {
5399 logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5400 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5401 indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5403 if (selectedNotebookGUIDs.size() > 1)
5404 setMessage(tr("Notes will be reindexed."));
5406 setMessage(tr("Note will be reindexed."));
5407 logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5410 @SuppressWarnings("unused")
5411 private void deleteNote() {
5412 logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5413 if (currentNote == null)
5415 if (currentNoteGuid.equals(""))
5418 String title = null;
5419 if (selectedNoteGUIDs.size() == 1)
5420 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5422 // If we are deleting non-trash notes
5423 if (currentNote.isActive()) {
5424 if (Global.verifyDelete()) {
5426 if (selectedNoteGUIDs.size() > 1) {
5427 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5430 msg = new String(tr("Delete note \"") +title +"\"?");
5432 msg = new String(tr("Delete note selected note?"));
5434 if (QMessageBox.question(this, tr("Confirmation"), msg,
5435 QMessageBox.StandardButton.Yes,
5436 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5440 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) {
5441 selectedNoteGUIDs.add(currentNoteGuid);
5444 List<String> deleteNoteGUIDs = new ArrayList<String>(selectedNoteGUIDs); // タブを閉じるとselectedNoteGUIDsが変わってしまうのでその前にコピー
5445 closeTabs(selectedNoteGUIDs);
5446 for (String guid : deleteNoteGUIDs) {
5447 listManager.deleteNote(guid);
5450 closeExternalWindows(deleteNoteGUIDs);
5452 // If we are deleting from the trash.
5453 if (Global.verifyDelete()) {
5455 if (selectedNoteGUIDs.size() > 1) {
5456 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5459 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5461 msg = new String(tr("Permanently delete note selected note?"));
5463 if (QMessageBox.question(this, "Confirmation", msg,
5464 QMessageBox.StandardButton.Yes,
5465 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
5469 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5470 selectedNoteGUIDs.add(currentNoteGuid);
5472 List<String> deleteNoteGUIDs = new ArrayList<String>(selectedNoteGUIDs); // タブを閉じるとselectedNoteGUIDsが変わってしまうのでその前にコピー
5473 for (int i=deleteNoteGUIDs.size()-1; i>=0; i--) {
5474 for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5475 QModelIndex modelIndex = listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5476 if (modelIndex != null) {
5477 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5478 String tableGuid = (String)ix.values().toArray()[0];
5479 if (tableGuid.equals(deleteNoteGUIDs.get(i))) {
5480 listManager.getNoteTableModel().removeRow(j);
5485 closeTab(deleteNoteGUIDs.get(i));
5486 listManager.expungeNote(deleteNoteGUIDs.get(i));
5488 conn.getHistoryTable().expungeHistory(deleteNoteGUIDs.get(i));
5489 conn.getExcludedTable().expungeExcludedNote(deleteNoteGUIDs.get(i));
5490 conn.getStaredTable().expungeStaredNote(deleteNoteGUIDs.get(i));
5493 closeExternalWindows(deleteNoteGUIDs);
5496 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
5497 menuBar.noteAddNewTab.setEnabled(false);
5500 listManager.loadNotesIndex();
5501 noteIndexUpdated(false);
5502 refreshEvernoteNote(true);
5503 scrollToGuid(currentNoteGuid);
5504 logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5507 // 対象ノートをタブで開いていたら閉じる
5508 private void closeTabs(List<String> noteGUIDs) {
5509 for (String guid : noteGUIDs) {
5514 // 対象ノートをタブで開いていたら閉じる
5515 private void closeTab(String noteGUID) {
5516 List<TabBrowse> closeTabs = new ArrayList<TabBrowse>();
5518 for (TabBrowse tab : tabWindows.values()) {
5519 String guid = tab.getBrowserWindow().getNote().getGuid();
5521 if (guid.equals(noteGUID)) {
5526 for (TabBrowse tab : closeTabs) {
5527 tabWindowClosing(tab);
5531 // 対象ノートを外部ウィンドウで開いていたら閉じる
5532 private void closeExternalWindows(List<String> noteGUIDs) {
5533 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>();
5535 for (Map.Entry<String, ExternalBrowse> e : externalWindows.entrySet()) {
5536 for (String guid : noteGUIDs) {
5537 if (guid.equals(e.getKey())) {
5538 closeWindows.add(e.getValue());
5543 for (ExternalBrowse externalBrowse : closeWindows) {
5544 externalBrowse.close();
5549 private void addNote() {
5550 logger.log(logger.HIGH, "Inside NeverNote.addNote");
5551 // browserWindow.setEnabled(true);
5552 browserWindow.setReadOnly(false);
5554 Calendar currentTime = new GregorianCalendar();
5555 StringBuffer noteString = new StringBuffer(100);
5556 noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5557 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5560 if (Global.overrideDefaultFont()) {
5561 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5562 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5563 noteString.append("<br clear=\"none\" />\n");
5564 noteString.append("</span>\n</font>\n");
5566 noteString.append("<br clear=\"none\" />\n");
5567 noteString.append("</en-note>");
5569 Long l = new Long(currentTime.getTimeInMillis());
5570 String randint = new String(Long.toString(l));
5572 // Find a notebook. We first look for a selected notebook (the "All Notebooks" one doesn't count).
5574 // for the first non-archived notebook. Finally, if nothing else we
5575 // pick the first notebook in the list.
5576 String notebook = null;
5577 listManager.getNotebookIndex().get(0).getGuid();
5578 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5579 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5580 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5581 notebook = currentSelectedNotebook.text(2);
5583 boolean found = false;
5584 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5585 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5586 boolean match = false;
5587 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5588 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5590 j = listManager.getArchiveNotebookIndex().size();
5594 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5595 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5597 // Now we have a list of good notebooks, so we can look for the default
5599 for (int i=0; i<goodNotebooks.size(); i++) {
5600 if (goodNotebooks.get(i).isDefaultNotebook()) {
5601 notebook = goodNotebooks.get(i).getGuid();
5603 i = goodNotebooks.size();
5607 if (goodNotebooks.size() > 0 && !found)
5608 notebook = goodNotebooks.get(0).getGuid();
5611 notebook = listManager.getNotebookIndex().get(0).getGuid();
5614 Note newNote = new Note();
5615 newNote.setUpdateSequenceNum(0);
5616 newNote.setGuid(randint);
5617 newNote.setNotebookGuid(notebook);
5618 newNote.setTitle("Untitled Note");
5619 newNote.setContent(noteString.toString());
5620 newNote.setDeleted(0);
5621 newNote.setCreated(System.currentTimeMillis());
5622 newNote.setUpdated(System.currentTimeMillis());
5623 newNote.setActive(true);
5624 NoteAttributes na = new NoteAttributes();
5625 na.setLatitude(0.0);
5626 na.setLongitude(0.0);
5627 na.setAltitude(0.0);
5628 newNote.setAttributes(new NoteAttributes());
5629 newNote.setTagGuids(new ArrayList<String>());
5630 newNote.setTagNames(new ArrayList<String>());
5632 // If new notes are to be created based upon the selected tags, then we need to assign the tags
5633 if (Global.newNoteWithSelectedTags()) {
5634 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5635 QTreeWidgetItem currentSelection;
5636 for (int i=0; i<selections.size(); i++) {
5637 currentSelection = selections.get(i);
5638 newNote.getTagGuids().add(currentSelection.text(2));
5639 newNote.getTagNames().add(currentSelection.text(0));
5643 conn.getNoteTable().addNote(newNote, true);
5644 NoteMetadata metadata = new NoteMetadata();
5645 metadata.setGuid(newNote.getGuid());
5646 metadata.setDirty(true);
5647 listManager.addNote(newNote, metadata);
5648 // noteTableView.insertRow(newNote, true, -1);
5650 String prevCurrentNoteGuid = new String(currentNoteGuid);
5652 currentNote = newNote;
5653 currentNoteGuid = currentNote.getGuid();
5654 // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5655 // noteTableView.clearSelection();
5657 // 新規に作成したノートとそれまで開いていたノートの関連性を追加
5658 if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5659 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5660 conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5664 refreshEvernoteNote(true);
5665 listManager.countNotebookResults(listManager.getNoteIndex());
5666 browserWindow.titleLabel.setFocus();
5667 browserWindow.titleLabel.selectAll();
5668 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5670 // If the window is hidden, then we want to popup this in an external window &
5674 logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5676 // Restore a note from the trash;
5677 @SuppressWarnings("unused")
5678 private void restoreNote() {
5680 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5681 selectedNoteGUIDs.add(currentNoteGuid);
5682 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5683 listManager.restoreNote(selectedNoteGUIDs.get(i));
5685 currentNoteGuid = "";
5686 listManager.loadNotesIndex();
5687 noteIndexUpdated(false);
5690 // Search a note for specific txt
5691 @SuppressWarnings("unused")
5692 private void findText() {
5694 find.setFocusOnTextField();
5696 @SuppressWarnings("unused")
5697 private void doFindText() {
5698 browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5701 @SuppressWarnings("unused")
5702 private void updateNoteTitle(String guid, String title) {
5703 listManager.setNoteSynchronized(guid, false);
5705 // We do this manually because if we've edited the note in an
5706 // external window we run into the possibility of signal recursion
5708 if (guid.equals(currentNoteGuid)) {
5709 browserWindow.titleLabel.blockSignals(true);
5710 browserWindow.titleLabel.setText(title);
5711 browserWindow.titleLabel.blockSignals(false);
5714 // Signal received that note content has changed. Normally we just need the guid to remove
5715 // it from the cache.
5716 @SuppressWarnings("unused")
5717 private void invalidateNoteCache(String guid, String content) {
5718 noteCache.remove(guid);
5719 refreshEvernoteNote(true);
5721 // Signal received that a note guid has changed
5722 @SuppressWarnings("unused")
5723 private void noteGuidChanged(String oldGuid, String newGuid) {
5724 if (noteCache.containsKey(oldGuid)) {
5725 if (!oldGuid.equals(currentNoteGuid)) {
5726 String cache = noteCache.get(oldGuid);
5727 noteCache.put(newGuid, cache);
5728 noteCache.remove(oldGuid);
5730 noteCache.remove(oldGuid);
5731 noteCache.put(newGuid, browserWindow.getContent());
5735 listManager.updateNoteGuid(oldGuid, newGuid, false);
5736 if (currentNoteGuid.equals(oldGuid)) {
5737 if (currentNote != null)
5738 currentNote.setGuid(newGuid);
5739 currentNoteGuid = newGuid;
5742 if (externalWindows.containsKey(oldGuid)) {
5743 ExternalBrowse b = externalWindows.get(oldGuid);
5744 externalWindows.remove(oldGuid);
5745 b.getBrowserWindow().getNote().setGuid(newGuid);
5746 externalWindows.put(newGuid, b);
5749 for(int i = 0; i < tabBrowser.count(); i++){
5750 TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5751 if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) {
5752 b.getBrowserWindow().getNote().setGuid(newGuid);
5756 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5757 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5758 noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5759 i=listManager.getNoteIndex().size();
5763 if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5764 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5765 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5766 listManager.getNoteTableModel().metaData.remove(oldGuid);
5771 // Toggle the note editor button bar
5773 private void toggleEditorButtonBar() {
5774 boolean isChecked = menuBar.showEditorBar.isChecked();
5776 for(int i = 0; i < tabBrowser.count(); i++){
5777 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5778 boolean isVisible = browser.buttonsVisible;
5780 if (isChecked && !isVisible) {
5781 browser.buttonsVisible = true;
5782 showEditorButtons(browser);
5783 } else if(!isChecked && isVisible) {
5784 browser.hideButtons();
5788 Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5791 // Show editor buttons
5792 private void showEditorButtons(BrowserWindow browser) {
5793 browser.buttonLayout.setVisible(true);
5794 browser.undoAction.setVisible(false);
5796 browser.undoButton.setVisible(false);
5798 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5799 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5800 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5801 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5802 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5803 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5804 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5805 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5806 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5807 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5808 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5809 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5810 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5811 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5812 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5813 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5814 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5815 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5816 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5817 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5818 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5819 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5820 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5822 private void duplicateNote(String guid) {
5824 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5825 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5826 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5827 oldNote.setResources(resList);
5828 duplicateNote(oldNote);
5830 private void duplicateNote(Note oldNote) {
5832 // Now that we have a good notebook guid, we need to move the conflicting note
5833 // to the local notebook
5834 Calendar currentTime = new GregorianCalendar();
5835 Long l = new Long(currentTime.getTimeInMillis());
5836 String newGuid = new String(Long.toString(l));
5838 // Note newNote = oldNote.deepCopy();
5839 Note newNote = (Note)Global.deepCopy(oldNote);
5840 newNote.setUpdateSequenceNum(0);
5841 newNote.setGuid(newGuid);
5842 newNote.setDeleted(0);
5843 newNote.setActive(true);
5846 List<String> tagNames = new ArrayList<String>();
5847 List<String> tagGuids = new ArrayList<String>();;
5848 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5849 tagNames.add(oldNote.getTagNames().get(i));
5850 tagGuids.add(oldNote.getTagGuids().get(i));
5853 // Sort note Tags to make them look nice
5854 for (int i=0; i<tagNames.size()-1; i++) {
5855 if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5856 String n1 = tagNames.get(i);
5857 String n2 = tagNames.get(i+1);
5858 tagNames.set(i, n2);
5859 tagNames.set(i+1, n1);
5862 newNote.setTagGuids(tagGuids);
5863 newNote.setTagNames(tagNames);
5865 // Add tag guids to note
5868 // Duplicate resources
5869 List<Resource> resList = oldNote.getResources();
5870 if (resList == null)
5871 resList = new ArrayList<Resource>();
5873 for (int i=0; i<resList.size(); i++) {
5875 while (l == prevGuid) {
5876 currentTime = new GregorianCalendar();
5877 l = new Long(currentTime.getTimeInMillis());
5880 String newResGuid = new String(Long.toString(l));
5881 resList.get(i).setNoteGuid(newGuid);
5882 resList.get(i).setGuid(newResGuid);
5883 resList.get(i).setUpdateSequenceNum(0);
5884 resList.get(i).setActive(true);
5885 conn.getNoteTable().noteResourceTable.saveNoteResource(
5886 (Resource)Global.deepCopy(resList.get(i)), true);
5888 newNote.setResources(resList);
5890 // 操作履歴と除外ノートとスター付きノートも複製する
5891 if(Global.getDuplicateRensoNote()) {
5892 conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5893 conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5894 conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5897 // Add note to the database
5898 conn.getNoteTable().addNote(newNote, true);
5899 NoteMetadata metaData = new NoteMetadata();
5900 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5901 metaData.copy(oldMeta);
5902 metaData.setGuid(newNote.getGuid());
5903 listManager.addNote(newNote, metaData);
5904 noteTableView.insertRow(newNote, metaData, true, -1);
5905 currentNoteGuid = newNote.getGuid();
5906 currentNote = newNote;
5907 refreshEvernoteNote(true);
5908 listManager.countNotebookResults(listManager.getNoteIndex());
5913 @SuppressWarnings("unused")
5914 private void allNotes() {
5915 clearAttributeFilter();
5916 clearNotebookFilter();
5917 clearSavedSearchFilter();
5920 searchField.clear();
5921 if (Global.mimicEvernoteInterface) {
5922 notebookTree.selectGuid("");
5924 notebookTreeSelection();
5925 refreshEvernoteNote(true);
5927 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5928 if (!rensoNoteListDock.isEnabled()) {
5929 rensoNoteListDock.setEnabled(true);
5933 @SuppressWarnings("unused")
5934 private void mergeNotes() {
5935 logger.log(logger.HIGH, "Merging notes");
5938 String masterGuid = null;
5939 List<String> sources = new ArrayList<String>();
5941 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5942 int r = noteTableView.selectionModel().selectedRows().get(i).row();
5943 index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5944 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5946 masterGuid = (String)ix.values().toArray()[0];
5948 sources.add((String)ix.values().toArray()[0]);
5951 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5952 logger.log(logger.EXTREME, "Children count: "+sources.size());
5953 mergeNoteContents(masterGuid, sources);
5954 currentNoteGuid = masterGuid;
5956 // 操作履歴と除外ノートとスター付きノートをマージ
5957 if(Global.getMergeRensoNote()) {
5958 for (int i = 0; i < sources.size(); i++) {
5959 String childGuid = sources.get(i);
5960 if(masterGuid != null && childGuid != null) {
5961 if(!masterGuid.equals(childGuid)) {
5962 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
5963 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
5964 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
5970 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
5971 Collection<ExternalBrowse> windows = externalWindows.values();
5972 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5973 Collection<String> guids = externalWindows.keySet();
5974 Iterator<String> guidIterator = guids.iterator();
5975 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>();
5977 while (windowIterator.hasNext()) {
5978 ExternalBrowse browser = windowIterator.next();
5979 String guid = guidIterator.next();
5981 for (int i = 0; i < sources.size(); i++) {
5982 if (guid.equals(sources.get(i))) {
5983 closeWindows.add(browser);
5988 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5989 closeWindows.get(i).close();
5992 // マージしたノート(child)をタブで開いていたら、閉じる
5993 List<TabBrowse> closeTabs = new ArrayList<TabBrowse>();
5994 for (TabBrowse tab : tabWindows.values()) {
5995 String guid = tab.getBrowserWindow().getNote().getGuid();
5997 for (String source : sources) {
5998 if (guid.equals(source)) {
6003 for (TabBrowse tab : closeTabs) {
6004 tabWindowClosing(tab);
6007 noteIndexUpdated(false);
6009 // マージ後の新しいノートコンテンツを表示するためキャッシュを削除
6010 noteCache.remove(masterGuid);
6012 refreshEvernoteNote(true);
6015 private void mergeNoteContents(String targetGuid, List<String> sources) {
6016 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
6017 String newContent = target.getContent();
6018 newContent = newContent.replace("</en-note>", "<br></br>");
6020 for (int i=0; i<sources.size(); i++) {
6021 Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
6022 if (source.isSetTitle()) {
6023 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
6025 String sourceContent = source.getContent();
6026 logger.log(logger.EXTREME, "Merging contents into note");
6027 logger.log(logger.EXTREME, sourceContent);
6028 logger.log(logger.EXTREME, "End of content");
6029 int startOfNote = sourceContent.indexOf("<en-note>");
6030 sourceContent = sourceContent.substring(startOfNote+9);
6031 int endOfNote = sourceContent.indexOf("</en-note>");
6032 sourceContent = sourceContent.substring(0,endOfNote);
6033 newContent = newContent + sourceContent;
6034 logger.log(logger.EXTREME, "New note content");
6035 logger.log(logger.EXTREME, newContent);
6036 logger.log(logger.EXTREME, "End of content");
6037 for (int j=0; j<source.getResourcesSize(); j++) {
6038 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
6039 Resource r = source.getResources().get(j);
6040 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
6042 Calendar currentTime = new GregorianCalendar();
6043 Long l = new Long(currentTime.getTimeInMillis());
6047 while (l == prevGuid) {
6048 currentTime = new GregorianCalendar();
6049 l = new Long(currentTime.getTimeInMillis());
6051 String newResGuid = new String(Long.toString(l));
6052 newRes.setNoteGuid(targetGuid);
6053 newRes.setGuid(newResGuid);
6054 newRes.setUpdateSequenceNum(0);
6055 newRes.setActive(true);
6056 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
6059 logger.log(logger.EXTREME, "Updating note");
6060 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
6061 for (int i=0; i<sources.size(); i++) {
6062 logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
6063 listManager.deleteNote(sources.get(i));
6065 logger.log(logger.EXTREME, "Exiting merge note");
6067 // A resource within a note has had a guid change
6068 @SuppressWarnings("unused")
6069 private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
6070 if (oldGuid != null && !oldGuid.equals(newGuid))
6071 Global.resourceMap.put(oldGuid, newGuid);
6073 // View a thumbnail of the note
6074 public void thumbnailView() {
6076 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
6077 QFile thumbnail = new QFile(thumbnailName);
6078 if (!thumbnail.exists()) {
6080 QImage img = new QImage();
6081 img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
6082 thumbnailViewer.setThumbnail(img);
6084 thumbnailViewer.setThumbnail(thumbnailName);
6085 if (!thumbnailViewer.isVisible())
6086 thumbnailViewer.showFullScreen();
6088 // An error happened while saving a note. Inform the user
6089 @SuppressWarnings("unused")
6090 private void saveRunnerError(String guid, String msg) {
6092 String title = "*Unknown*";
6093 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6094 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6095 title = listManager.getMasterNoteIndex().get(i).getTitle();
6096 i=listManager.getMasterNoteIndex().size();
6099 msg = tr("An error has happened while saving the note \"") +title+
6100 tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
6101 "As a result, changes to the note may not be saved properly in the database."+
6102 "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6103 "\nbe lost. Please review the note to recover any critical data before restarting.");
6105 QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6108 private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6109 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6110 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6111 // Find an idle preview object
6112 for (int i=0; i<thumbGenerators.size(); i++) {
6113 if (thumbGenerators.get(i).mutex.tryLock()) {
6114 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6115 thumbGenerators.get(i).loadContent(guid, html, zoom);
6119 if (thumbGenerators.size() >= 1) {
6120 logger.log(logger.EXTREME, "No available thumbnail generators. Aborting " +guid);
6124 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6125 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6126 thumbGenerators.add(preview);
6128 if (preview.mutex.tryLock()) {
6129 logger.log(logger.EXTREME, "Loading thumbnail for " +guid);
6130 preview.loadContent(guid, html, zoom);
6132 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6137 //**********************************************************
6138 //**********************************************************
6139 //* Online user actions
6140 //**********************************************************
6141 //**********************************************************
6142 private void setupOnlineMenu() {
6143 if (!Global.isConnected) {
6144 menuBar.noteOnlineHistoryAction.setEnabled(false);
6145 menuBar.selectiveSyncAction.setEnabled(false);
6148 menuBar.noteOnlineHistoryAction.setEnabled(true);
6149 menuBar.selectiveSyncAction.setEnabled(true);
6152 @SuppressWarnings("unused")
6153 private void viewNoteHistory() {
6154 if (currentNoteGuid == null || currentNoteGuid.equals(""))
6156 if (currentNote.getUpdateSequenceNum() == 0) {
6157 setMessage(tr("Note has never been synchronized."));
6158 QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6162 setMessage(tr("Getting Note History"));
6164 Note currentOnlineNote = null;
6167 if (Global.isPremium())
6168 versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6170 versions = new ArrayList<NoteVersionId>();
6171 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6172 } catch (EDAMUserException e) {
6173 setMessage("EDAMUserException: " +e.getMessage());
6175 } catch (EDAMSystemException e) {
6176 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6177 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6179 setMessage("EDAMSystemException: " +e.getMessage());
6181 } catch (EDAMNotFoundException e) {
6182 setMessage(tr("Note not found on server."));
6183 QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6185 } catch (TException e) {
6186 setMessage("EDAMTransactionException: " +e.getMessage());
6190 // If we've gotten this far, we have a good note.
6191 if (historyWindow == null) {
6192 historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6194 historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6195 historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6196 historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6198 historyWindow.historyCombo.clear();
6200 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6201 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6203 historyWindow.setCurrent(isDirty);
6205 loadHistoryWindowContent(currentOnlineNote);
6206 historyWindow.load(versions);
6207 setMessage(tr("History retrieved"));
6209 historyWindow.exec();
6211 private Note reloadHistoryWindow(String selection) {
6213 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6214 String dateTimeFormat = new String(fmt);
6215 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6219 for (int i=0; i<versions.size(); i++) {
6220 StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6221 if (versionDate.toString().equals(selection))
6225 if (index > -1 || selection.indexOf("Current") > -1) {
6226 Note historyNote = null;
6229 usn = versions.get(index).getUpdateSequenceNum();
6230 historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6232 historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6233 } catch (EDAMUserException e) {
6234 setMessage("EDAMUserException: " +e.getMessage());
6237 } catch (EDAMSystemException e) {
6238 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6239 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6241 setMessage("EDAMSystemException: " +e.getMessage());
6244 } catch (EDAMNotFoundException e) {
6245 setMessage("EDAMNotFoundException: " +e.getMessage());
6248 } catch (TException e) {
6249 setMessage("EDAMTransactionException: " +e.getMessage());
6255 if (historyNote != null)
6256 historyWindow.setContent(historyNote);
6262 private void loadHistoryWindowContent(Note note) {
6263 note.setUpdateSequenceNum(0);
6264 historyWindow.setContent(note);
6266 @SuppressWarnings("unused")
6267 private void restoreHistoryNoteAsNew() {
6268 setMessage(tr("Restoring as new note."));
6269 duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6270 setMessage(tr("Note has been restored as a new note."));
6272 @SuppressWarnings("unused")
6273 private void restoreHistoryNote() {
6274 setMessage(tr("Restoring note."));
6275 Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6276 conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6279 for (int i=0; i<n.getResourcesSize(); i++) {
6280 n.getResources().get(i).setActive(true);
6281 conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6283 NoteMetadata metadata = new NoteMetadata();
6284 metadata.setGuid(n.getGuid());
6285 listManager.addNote(n, metadata);
6286 conn.getNoteTable().addNote(n, true);
6287 refreshEvernoteNote(true);
6288 setMessage(tr("Note has been restored."));
6290 @SuppressWarnings("unused")
6291 private void setupSelectiveSync() {
6293 // Get a list of valid notebooks
6294 List<Notebook> notebooks = null;
6295 List<Tag> tags = null;
6296 List<LinkedNotebook> linkedNotebooks = null;
6298 notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6299 tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6300 linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6301 } catch (EDAMUserException e) {
6302 setMessage("EDAMUserException: " +e.getMessage());
6304 } catch (EDAMSystemException e) {
6305 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6306 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + e.getRateLimitDuration() + tr(" seconds."));
6308 setMessage("EDAMSystemException: " +e.getMessage());
6310 } catch (TException e) {
6311 setMessage("EDAMTransactionException: " +e.getMessage());
6313 } catch (EDAMNotFoundException e) {
6314 setMessage("EDAMNotFoundException: " +e.getMessage());
6318 // Split up notebooks into synchronized & non-synchronized
6319 List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6320 List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6322 for (int i=notebooks.size()-1; i>=0; i--) {
6323 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6324 if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6325 ignoredBooks.add(notebooks.get(i));
6326 j=dbIgnoredNotebooks.size();
6331 // split up tags into synchronized & non-synchronized
6332 List<Tag> ignoredTags = new ArrayList<Tag>();
6333 List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6335 for (int i=tags.size()-1; i>=0; i--) {
6336 for (int j=0; j<dbIgnoredTags.size(); j++) {
6337 if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6338 ignoredTags.add(tags.get(i));
6339 j=dbIgnoredTags.size();
6344 // split up linked notebooks into synchronized & non-synchronized
6345 List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6346 List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6347 for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6348 String notebookGuid = linkedNotebooks.get(i).getGuid();
6349 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6350 if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6351 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6352 j=dbIgnoredLinkedNotebooks.size();
6357 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6359 if (!ignore.okClicked())
6364 // Clear out old notebooks & add the new ones
6365 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6366 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6367 conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6370 List<String> newNotebooks = new ArrayList<String>();
6371 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6372 String text = ignore.getIgnoredBookList().takeItem(i).text();
6373 for (int j=0; j<notebooks.size(); j++) {
6374 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6375 Notebook n = notebooks.get(j);
6376 conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6378 newNotebooks.add(n.getGuid());
6383 // Clear out old tags & add new ones
6384 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6385 for (int i=0; i<oldIgnoreTags.size(); i++) {
6386 conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6389 List<String> newTags = new ArrayList<String>();
6390 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6391 String text = ignore.getIgnoredTagList().takeItem(i).text();
6392 for (int j=0; j<tags.size(); j++) {
6393 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6394 Tag t = tags.get(j);
6395 conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6396 newTags.add(t.getGuid());
6402 // Clear out old tags & add new ones
6403 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6404 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6405 conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6408 List<String> newLinked = new ArrayList<String>();
6409 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6410 String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6411 for (int j=0; j<linkedNotebooks.size(); j++) {
6412 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6413 LinkedNotebook t = linkedNotebooks.get(j);
6414 conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6415 newLinked.add(t.getGuid());
6416 j=linkedNotebooks.size();
6421 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6427 //**********************************************************
6428 //**********************************************************
6429 //* XML Modifying methods
6430 //**********************************************************
6431 //**********************************************************
6432 // An error has happended fetching a resource. let the user know
6433 private void resourceErrorMessage(int tabIndex) {
6437 if (inkNote.get(tabIndex))
6440 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6441 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6442 "In a perfect world this wouldn't happen, but it has.\n" +
6443 "It is embarasing when a program like me, designed to save all your\n"+
6444 "precious data, has a problem finding data.\n\n" +
6445 "I guess life isn't fair, but I'll survive. Somehow...\n\n" +
6446 "In the mean time, I'm not going to let you make changes to this note.\n" +
6447 "Don't get angry. I'm doing it to prevent you from messing up\n"+
6448 "this note on the Evernote servers. Sorry."+
6449 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6450 inkNote.put(tabIndex, true);
6451 browserWindow.setReadOnly(true);
6458 //**********************************************************
6459 //**********************************************************
6461 //**********************************************************
6462 //**********************************************************
6463 // We should now do a sync with Evernote
6464 private void syncTimer() {
6465 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6466 syncRunner.syncNeeded = true;
6467 syncRunner.disableUploads = Global.disableUploads;
6469 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6471 private void syncStart() {
6472 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6474 if (!syncRunning && Global.isConnected) {
6475 syncRunner.setConnected(true);
6476 syncRunner.setKeepRunning(Global.keepRunning);
6477 syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6479 if (syncThreadsReady > 0) {
6480 thumbnailRunner.interrupt = true;
6481 saveNoteIndexWidth();
6482 saveNoteColumnPositions();
6483 if (syncRunner.addWork("SYNC")) {
6485 syncRunner.syncNeeded = true;
6490 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6492 @SuppressWarnings("unused")
6493 private void syncThreadComplete(Boolean refreshNeeded) {
6494 setMessage(tr("Finalizing Synchronization"));
6496 syncRunning = false;
6497 syncRunner.syncNeeded = false;
6498 synchronizeAnimationTimer.stop();
6499 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6501 if (currentNote == null) {
6502 currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6504 listManager.refreshNoteMetadata();
6505 noteIndexUpdated(true);
6506 noteTableView.selectionModel().blockSignals(true);
6507 scrollToGuid(currentNoteGuid);
6508 noteTableView.selectionModel().blockSignals(false);
6509 refreshEvernoteNote(false);
6510 scrollToGuid(currentNoteGuid);
6513 // Check to see if there were any shared notebook errors
6514 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6515 String guid = syncRunner.errorSharedNotebooks.get(0);
6516 String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6517 String localName = listManager.getNotebookNameByGuid(notebookGuid);
6518 SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6520 if (syncDialog.okPressed()) {
6521 if (syncDialog.doNothing.isChecked()) {
6522 syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6525 if (syncDialog.deleteNotebook.isChecked()) {
6526 conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6527 conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6528 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6529 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6537 // Finalize the synchronization
6538 if (!syncRunner.error)
6539 setMessage(tr("Synchronization Complete"));
6541 setMessage(tr("Synchronization completed with errors. Please check the log for details."));
6542 logger.log(logger.MEDIUM, "Sync complete.");
6544 public void saveUploadAmount(long t) {
6545 Global.saveUploadAmount(t);
6547 public void saveUserInformation(User user) {
6548 Global.saveUserInformation(user);
6550 public void saveEvernoteUpdateCount(int i) {
6551 Global.saveEvernoteUpdateCount(i);
6553 public void refreshLists() {
6554 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6556 // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。
6557 Collection<Integer> tabIndex = noteDirty.keySet();
6558 Iterator<Integer> indexIterator = tabIndex.iterator();
6559 HashMap<Integer, Note> saveNotes = new HashMap<Integer, Note>();
6560 HashMap<Integer, String> saveContents = new HashMap<Integer, String>();
6561 for (boolean isNoteDirty: noteDirty.values()) {
6562 int index = indexIterator.next();
6564 saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote());
6565 saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent());
6569 listManager.saveUpdatedNotes(saveNotes, saveContents);
6570 listManager.refreshLists();
6572 tagIndexUpdated(true);
6573 notebookIndexUpdated();
6574 savedSearchIndexUpdated();
6575 listManager.loadNotesIndex();
6577 noteTableView.selectionModel().blockSignals(true);
6578 noteIndexUpdated(true);
6579 noteTableView.selectionModel().blockSignals(false);
6580 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6584 @SuppressWarnings("unused")
6585 private void authTimer() {
6586 Calendar cal = Calendar.getInstance();
6588 // If we are not connected let's get out of here
6589 if (!Global.isConnected)
6592 // If this is the first time through, then we need to set this
6593 // if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime)
6594 // syncRunner.authRefreshTime = cal.getTimeInMillis();
6596 // long now = new Date().getTime();
6597 // if (now > Global.authRefreshTime && Global.isConnected) {
6598 syncRunner.authRefreshNeeded = true;
6602 @SuppressWarnings("unused")
6603 private void authRefreshComplete(boolean goodSync) {
6604 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6605 Global.isConnected = syncRunner.isConnected;
6607 // authTimer.start((int)syncRunner.authTimeRemaining/4);
6608 authTimer.start(1000*60*15);
6609 logger.log(logger.LOW, "Authentication token has been renewed");
6610 // setMessage("Authentication token has been renewed.");
6612 authTimer.start(1000*60*5);
6613 logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6614 // setMessage("Authentication token renew has failed - retry in 5 minutes.");
6616 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6620 @SuppressWarnings("unused")
6621 private synchronized void indexTimer() {
6622 logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning);
6625 if (!indexDisabled && indexRunner.idle) {
6626 thumbnailRunner.interrupt = true;
6627 indexRunner.addWork("SCAN");
6629 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6632 @SuppressWarnings("unused")
6633 private void indexStarted() {
6634 setMessage(tr("Indexing notes"));
6636 @SuppressWarnings("unused")
6637 private void indexComplete() {
6638 setMessage(tr("Index complete"));
6640 @SuppressWarnings("unused")
6641 private synchronized void toggleNoteIndexing() {
6642 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6643 indexDisabled = !indexDisabled;
6645 setMessage(tr("Indexing is now enabled."));
6647 setMessage(tr("Indexing is now disabled."));
6648 menuBar.disableIndexing.setChecked(indexDisabled);
6649 logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6652 @SuppressWarnings("unused")
6653 private void threadMonitorCheck() {
6658 alive = listManager.threadCheck(Global.tagCounterThreadId);
6661 if (tagDeadCount > MAX && !disableTagThreadCheck) {
6662 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
6663 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6664 disableTagThreadCheck = true;
6669 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6671 notebookThreadDeadCount++;
6672 if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6673 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
6674 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6675 disableNotebookThreadCheck=true;
6678 notebookThreadDeadCount=0;
6680 alive = listManager.threadCheck(Global.trashCounterThreadId);
6683 if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6684 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
6685 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6686 disableTrashThreadCheck = true;
6691 alive = listManager.threadCheck(Global.saveThreadId);
6693 saveThreadDeadCount++;
6694 if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6695 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
6696 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6697 disableSaveThreadCheck = true;
6700 saveThreadDeadCount=0;
6702 if (!syncThread.isAlive()) {
6703 syncThreadDeadCount++;
6704 if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6705 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
6706 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6707 disableSyncThreadCheck = true;
6710 syncThreadDeadCount=0;
6712 if (!indexThread.isAlive()) {
6713 indexThreadDeadCount++;
6714 if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6715 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
6716 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6717 disableIndexThreadCheck = true;
6720 indexThreadDeadCount=0;
6722 if (!rensoNoteListDock.getRensoNoteList().getEnRelatedNotesThread().isAlive()) {
6723 enRelatedNotesThreadDeadCount++;
6724 if (enRelatedNotesThreadDeadCount > MAX && !disableENRelatedNotesThreadCheck) {
6725 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the Evernote Related Notes thread has died. I recommend "+
6726 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6727 disableENRelatedNotesThreadCheck = true;
6730 enRelatedNotesThreadDeadCount=0;
6733 private void thumbnailTimer() {
6734 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6735 thumbnailRunner.addWork("SCAN");
6739 //**************************************************
6740 //* Backup & Restore
6741 //**************************************************
6742 @SuppressWarnings("unused")
6743 private void databaseBackup() {
6744 QFileDialog fd = new QFileDialog(this);
6745 fd.setFileMode(FileMode.AnyFile);
6746 fd.setConfirmOverwrite(true);
6747 fd.setWindowTitle(tr("Backup Database"));
6748 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6749 fd.setAcceptMode(AcceptMode.AcceptSave);
6750 if (saveLastPath == null || saveLastPath.equals(""))
6751 fd.setDirectory(System.getProperty("user.home"));
6753 fd.setDirectory(saveLastPath);
6754 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6760 saveLastPath = fd.selectedFiles().get(0);
6761 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6762 setMessage(tr("Backing up database"));
6764 // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6766 ExportData noteWriter = new ExportData(conn, true);
6767 String fileName = fd.selectedFiles().get(0);
6769 if (!fileName.endsWith(".nnex"))
6770 fileName = fileName +".nnex";
6771 noteWriter.exportData(fileName);
6772 setMessage(tr("Database backup completed."));
6777 @SuppressWarnings("unused")
6778 private void databaseRestore() {
6779 if (QMessageBox.question(this, tr("Confirmation"),
6780 tr("This is used to restore a database from backups.\n" +
6781 "It is HIGHLY recommened that this only be used to populate\n" +
6782 "an empty database. Restoring into a database that\n already has data" +
6783 " can cause problems.\n\nAre you sure you want to continue?"),
6784 QMessageBox.StandardButton.Yes,
6785 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6790 QFileDialog fd = new QFileDialog(this);
6791 fd.setFileMode(FileMode.ExistingFile);
6792 fd.setConfirmOverwrite(true);
6793 fd.setWindowTitle(tr("Restore Database"));
6794 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6795 fd.setAcceptMode(AcceptMode.AcceptOpen);
6796 if (saveLastPath == null || saveLastPath.equals(""))
6797 fd.setDirectory(System.getProperty("user.home"));
6799 fd.setDirectory(saveLastPath);
6800 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6806 saveLastPath = fd.selectedFiles().get(0);
6807 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6809 setMessage(tr("Restoring database"));
6810 ImportData noteReader = new ImportData(conn, true);
6811 noteReader.importData(fd.selectedFiles().get(0));
6813 if (noteReader.lastError != 0) {
6814 setMessage(noteReader.getErrorMessage());
6815 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6820 listManager.loadNoteTitleColors();
6822 refreshEvernoteNote(true);
6823 setMessage(tr("Database has been restored."));
6826 @SuppressWarnings("unused")
6827 private void exportNotes() {
6828 QFileDialog fd = new QFileDialog(this);
6829 fd.setFileMode(FileMode.AnyFile);
6830 fd.setConfirmOverwrite(true);
6831 fd.setWindowTitle(tr("Backup Database"));
6832 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6833 fd.setAcceptMode(AcceptMode.AcceptSave);
6834 fd.setDirectory(System.getProperty("user.home"));
6835 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6841 setMessage(tr("Exporting Notes"));
6844 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6845 selectedNoteGUIDs.add(currentNoteGuid);
6847 ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6848 String fileName = fd.selectedFiles().get(0);
6850 if (!fileName.endsWith(".nnex"))
6851 fileName = fileName +".nnex";
6852 noteWriter.exportData(fileName);
6853 setMessage(tr("Export completed."));
6859 @SuppressWarnings("unused")
6860 private void importNotes() {
6861 QFileDialog fd = new QFileDialog(this);
6862 fd.setFileMode(FileMode.ExistingFile);
6863 fd.setConfirmOverwrite(true);
6864 fd.setWindowTitle(tr("Import Notes"));
6865 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6866 fd.setAcceptMode(AcceptMode.AcceptOpen);
6867 if (saveLastPath == null || saveLastPath.equals(""))
6868 fd.setDirectory(System.getProperty("user.home"));
6870 fd.setDirectory(saveLastPath);
6871 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6877 setMessage(tr("Importing Notes"));
6880 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6881 selectedNoteGUIDs.add(currentNoteGuid);
6883 String fileName = fd.selectedFiles().get(0);
6884 // saveLastPath.substring(0,fileName.lastIndexOf("/"));
6886 if (fileName.endsWith(".nnex")) {
6887 ImportData noteReader = new ImportData(conn, false);
6888 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6889 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6891 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6893 noteReader.importData(fileName);
6895 if (noteReader.lastError != 0) {
6896 setMessage(noteReader.getErrorMessage());
6897 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6902 if (fileName.endsWith(".enex")) {
6903 ImportEnex noteReader = new ImportEnex(conn, false);
6904 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6905 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6907 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6910 if (QMessageBox.question(this, tr("Confirmation"),
6911 tr("Create new tags from import?"),
6912 QMessageBox.StandardButton.Yes,
6913 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6914 noteReader.createNewTags = true;
6916 noteReader.createNewTags = false;
6918 noteReader.importData(fileName);
6920 if (noteReader.lastError != 0) {
6921 setMessage(noteReader.getErrorMessage());
6922 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6929 listManager.loadNoteTitleColors();
6931 refreshEvernoteNote(false);
6932 setMessage(tr("Notes have been imported."));
6935 setMessage(tr("Import completed."));
6942 //**************************************************
6943 //* Duplicate a note
6944 //**************************************************
6945 @SuppressWarnings("unused")
6946 private void duplicateNote() {
6948 duplicateNote(currentNoteGuid);
6951 //**************************************************
6952 //* Action from when a user clicks Copy As URL
6953 //**************************************************
6954 @SuppressWarnings("unused")
6955 private void copyAsUrlClicked() {
6956 QClipboard clipboard = QApplication.clipboard();
6957 QMimeData mime = new QMimeData();
6959 mime.setText(currentNoteGuid);
6960 List<QUrl> urls = new ArrayList<QUrl>();
6962 // Start building the URL
6963 User user = Global.getUserInformation();
6965 // Check that we have everything we need
6966 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
6967 SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
6969 if (!warning.neverSynchronize())
6972 Global.setBypassSynchronizationWarning(true);
6973 user.setShardId("s0");
6979 // Start building a list of URLs based upon the selected notes
6980 noteTableView.showColumn(Global.noteTableGuidPosition);
6982 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
6983 if (!Global.isColumnVisible("guid"))
6984 noteTableView.hideColumn(Global.noteTableGuidPosition);
6986 // Check that the note is either synchronized, or in a local notebook
6987 for (int i=0; i<selections.size(); i++) {
6989 int row = selections.get(i).row();
6990 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
6991 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
6992 String selectedGuid = (String)ix.values().toArray()[0];
6994 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
6995 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
6996 QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
6997 "new notes to a local notebook."));
7002 // Start building the URLs
7003 for (int i=0; i<selections.size(); i++) {
7005 int row = selections.get(i).row();
7006 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7007 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7008 String selectedGuid = (String)ix.values().toArray()[0];
7009 mime.setText(selectedGuid);
7013 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7014 if (selectedNote.getUpdateSequenceNum() > 0) {
7018 gid = "00000000-0000-0000-0000-000000000000";
7021 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
7023 urls.add(new QUrl(url));
7026 clipboard.setMimeData(mime);
7030 //**************************************************
7032 //**************************************************
7033 public void setupFolderImports() {
7034 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
7036 if (importKeepWatcher == null)
7037 importKeepWatcher = new QFileSystemWatcher();
7038 if (importDeleteWatcher == null) {
7039 importDeleteWatcher = new QFileSystemWatcher();
7040 for (int i=0; i<records.size(); i++) {
7041 if (!records.get(i).keep)
7042 folderImportDelete(records.get(i).folder);
7048 // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
7049 for (int i=0; i<records.size(); i++) {
7050 logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
7051 if (records.get(i).keep)
7052 importKeepWatcher.addPath(records.get(i).folder);
7054 importDeleteWatcher.addPath(records.get(i).folder);
7057 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
7058 List<String> monitorDelete = importKeepWatcher.directories();
7059 for (int i=0; i<monitorDelete.size(); i++) {
7060 logger.log(logger.EXTREME, monitorDelete.get(i));
7062 logger.log(logger.EXTREME, "<end of list>");
7063 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
7064 monitorDelete = importDeleteWatcher.directories();
7065 for (int i=0; i<monitorDelete.size(); i++) {
7066 logger.log(logger.EXTREME, monitorDelete.get(i));
7068 logger.log(logger.EXTREME, "<end of list>");
7070 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
7071 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
7073 // Look at the files already there so we don't import them again if a new file is created
7074 if (importedFiles == null) {
7075 importedFiles = new ArrayList<String>();
7076 for (int j=0; j<records.size(); j++) {
7077 QDir dir = new QDir(records.get(j).folder);
7078 List<QFileInfo> list = dir.entryInfoList();
7079 for (int k=0; k<list.size(); k++) {
7080 if (list.get(k).isFile())
7081 importedFiles.add(list.get(k).absoluteFilePath());
7087 // Menu folderImport action triggered
7088 public void folderImport() {
7089 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
7090 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
7092 if (!dialog.okClicked())
7095 // We have some sort of update.
7096 if (importKeepWatcher.directories().size() > 0)
7097 importKeepWatcher.removePaths(importKeepWatcher.directories());
7098 if (importDeleteWatcher.directories().size() > 0)
7099 importDeleteWatcher.removePaths(importDeleteWatcher.directories());
7101 conn.getWatchFolderTable().expungeAll();
7102 // Start building from the table
7103 for (int i=0; i<dialog.table.rowCount(); i++) {
7104 QTableWidgetItem item = dialog.table.item(i, 0);
7105 String dir = item.text();
7106 item = dialog.table.item(i, 1);
7107 String notebook = item.text();
7108 item = dialog.table.item(i, 2);
7110 if (item.text().equalsIgnoreCase("Keep"))
7115 String guid = conn.getNotebookTable().findNotebookByName(notebook);
7116 conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
7118 setupFolderImports();
7122 public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
7123 logger.log(logger.LOW, "Inside folderImportKeep");
7124 String whichOS = System.getProperty("os.name");
7125 if (whichOS.contains("Windows"))
7126 dirName = dirName.replace('/','\\');
7128 FileImporter importer = new FileImporter(logger, conn);
7130 QDir dir = new QDir(dirName);
7131 List<QFileInfo> list = dir.entryInfoList();
7132 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7134 for (int i=0; i<list.size(); i++){
7135 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7136 boolean redundant = false;
7137 // Check if we've already imported this one or if it existed before
7138 for (int j=0; j<importedFiles.size(); j++) {
7139 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7140 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7144 logger.log(logger.LOW, "Checking if redundant: " +redundant);
7146 importer.setFileInfo(list.get(i));
7147 importer.setFileName(list.get(i).absoluteFilePath());
7150 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7151 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7152 if (list.get(i).isFile() && importer.isValidType()) {
7154 if (!importer.importFile()) {
7155 // If we can't get to the file, it is probably locked. We'll try again later.
7156 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7157 importFilesKeep.add(list.get(i).absoluteFilePath());
7160 Note newNote = importer.getNote();
7161 newNote.setNotebookGuid(notebook);
7162 newNote.setTitle(dir.at(i));
7163 NoteMetadata metadata = new NoteMetadata();
7164 metadata.setDirty(true);
7165 metadata.setGuid(newNote.getGuid());
7166 listManager.addNote(newNote, metadata);
7167 conn.getNoteTable().addNote(newNote, true);
7168 noteTableView.insertRow(newNote, metadata, true, -1);
7169 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7170 listManager.countNotebookResults(listManager.getNoteIndex());
7171 importedFiles.add(list.get(i).absoluteFilePath());
7180 public void folderImportDelete(String dirName) {
7181 logger.log(logger.LOW, "Inside folderImportDelete");
7182 String whichOS = System.getProperty("os.name");
7183 if (whichOS.contains("Windows"))
7184 dirName = dirName.replace('/','\\');
7186 FileImporter importer = new FileImporter(logger, conn);
7187 QDir dir = new QDir(dirName);
7188 List<QFileInfo> list = dir.entryInfoList();
7189 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7191 for (int i=0; i<list.size(); i++){
7192 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7193 importer.setFileInfo(list.get(i));
7194 importer.setFileName(list.get(i).absoluteFilePath());
7196 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7197 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7198 if (list.get(i).isFile() && importer.isValidType()) {
7200 if (!importer.importFile()) {
7201 // If we can't get to the file, it is probably locked. We'll try again later.
7202 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7203 importFilesKeep.add(list.get(i).absoluteFilePath());
7206 Note newNote = importer.getNote();
7207 newNote.setNotebookGuid(notebook);
7208 newNote.setTitle(dir.at(i));
7209 NoteMetadata metadata = new NoteMetadata();
7210 metadata.setDirty(true);
7211 metadata.setGuid(newNote.getGuid());
7212 listManager.addNote(newNote, metadata);
7213 conn.getNoteTable().addNote(newNote, true);
7214 noteTableView.insertRow(newNote, metadata, true, -1);
7215 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7216 listManager.countNotebookResults(listManager.getNoteIndex());
7217 dir.remove(dir.at(i));
7224 //**************************************************
7226 //**************************************************
7227 private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7228 logger.log(logger.HIGH, "Entering exernalFileEdited");
7230 // Strip URL prefix and base dir path
7231 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7232 String name = fileName.replace(dPath, "");
7233 int pos = name.lastIndexOf('.');
7236 guid = guid.substring(0,pos);
7238 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7240 guid = name.substring(0, pos);
7243 QFile file = new QFile(fileName);
7244 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
7245 // If we can't get to the file, it is probably locked. We'll try again later.
7246 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7247 externalFiles.add(fileName);
7250 QByteArray binData = file.readAll();
7252 if (binData.size() == 0) {
7253 // If we can't get to the file, it is probably locked. We'll try again later.
7254 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7255 externalFiles.add(fileName);
7259 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7261 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7262 if (r == null || r.getData() == null || r.getData().getBody() == null)
7264 String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7265 MessageDigest md = MessageDigest.getInstance("MD5");
7266 md.update(binData.toByteArray());
7267 byte[] hash = md.digest();
7268 String newHash = Global.byteArrayToHexString(hash);
7269 if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7270 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7272 if (externalWindows.containsKey(r.getNoteGuid())) {
7273 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(),
7274 r.getGuid(), oldHash, newHash);
7276 conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7277 Data data = r.getData();
7278 data.setBody(binData.toByteArray());
7279 data.setBodyHash(hash);
7280 logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7282 conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7284 if (r.getNoteGuid().equals(currentNoteGuid)) {
7285 QWebSettings.setMaximumPagesInCache(0);
7286 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7287 refreshEvernoteNote(true);
7288 browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7291 if (externalWindows.containsKey(r.getNoteGuid())) {
7292 QWebSettings.setMaximumPagesInCache(0);
7293 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7294 externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7298 logger.log(logger.HIGH, "Exiting externalFielEdited");
7300 // This is a timer event that tries to save any external files that were edited. This
7301 // is only needed if we couldn't save a file earlier.
7302 public void externalFileEditedSaver() {
7303 for (int i=externalFiles.size()-1; i>=0; i--) {
7305 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7306 externalFileEdited(externalFiles.get(i));
7307 externalFiles.remove(i);
7308 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7310 for (int i=0; i<importFilesKeep.size(); i++) {
7312 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7313 folderImportKeep(importFilesKeep.get(i));
7314 importFilesKeep.remove(i);
7315 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7317 for (int i=0; i<importFilesDelete.size(); i++) {
7318 logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7319 folderImportDelete(importFilesDelete.get(i));
7320 importFilesDelete.remove(i);
7327 // If an attachment on the current note was edited, we need to update the current notes's hash
7328 // Update a note content's hash. This happens if a resource is edited outside of NN
7329 public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7330 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7332 for (;position>-1;) {
7333 endPos = browser.getContent().indexOf(">", position+1);
7334 String oldSegment = browser.getContent().substring(position,endPos);
7335 int hashPos = oldSegment.indexOf("hash=\"");
7336 int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7337 String hash = oldSegment.substring(hashPos+6, hashEnd);
7338 if (hash.equalsIgnoreCase(oldHash)) {
7339 String newSegment = oldSegment.replace(oldHash, newHash);
7340 String content = browser.getContent().substring(0,position) +
7342 browser.getContent().substring(endPos);
7343 browser.setContent(new QByteArray(content));;
7346 position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7351 //*************************************************
7352 //* Minimize to tray
7353 //*************************************************
7355 public void changeEvent(QEvent e) {
7356 if (e.type() == QEvent.Type.WindowStateChange) {
7357 if (QSystemTrayIcon.isSystemTrayAvailable()) {
7358 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7360 QTimer.singleShot(10, this, "hide()");
7364 windowMaximized = true;
7366 windowMaximized = false;
7371 //*************************************************
7372 //* Check database userid & passwords
7373 //*************************************************
7374 private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7375 Connection connection;
7378 Class.forName("org.h2.Driver");
7379 } catch (ClassNotFoundException e1) {
7380 e1.printStackTrace();
7385 String passwordString = null;
7386 if (cypherPassword==null || cypherPassword.trim().equals(""))
7387 passwordString = userPassword;
7389 passwordString = cypherPassword+" "+userPassword;
7390 connection = DriverManager.getConnection(url,userid,passwordString);
7391 } catch (SQLException e) {
7396 } catch (SQLException e) {
7397 e.printStackTrace();
7402 //*************************************************
7403 //* View / Hide source HTML for a note
7404 //*************************************************
7405 public void viewSource() {
7407 for(int i = 0; i < tabBrowser.count(); i++){
7408 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7409 browser.showSource(menuBar.viewSource.isChecked());
7412 //*************************************************
7413 // Block the program. This is used for things
7414 // like async web calls.
7415 //*************************************************
7416 @SuppressWarnings("unused")
7417 private void blockApplication(BrowserWindow b) {
7418 // Block all signals
7422 blockTimer = new QTimer();
7423 blockTimer.setSingleShot(true);
7424 blockTimer.setInterval(15000);
7425 blockTimer.timeout.connect(this, "unblockApplication()");
7430 @SuppressWarnings("unused")
7431 private void unblockApplication() {
7433 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7434 QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7435 blockingWindow.unblockTime = -1;
7436 blockingWindow.awaitingHttpResponse = false;
7438 blockingWindow = null;
7439 blockSignals(false);
7443 private void tabWindowChanged(int index) {
7444 if (index < 0 || index >= tabBrowser.count()) {
7450 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7451 if (tab.getBrowserWindow().getNote() != null) {
7452 currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7453 currentNote = tab.getBrowserWindow().getNote();
7455 currentNoteGuid = "";
7460 selectedNoteGUIDs.clear();
7461 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7462 selectedNoteGUIDs.add(currentNoteGuid);
7466 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7467 browserWindow.focusLost.disconnect(this, "saveNote()");
7468 browserWindow = tab.getBrowserWindow();
7469 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7470 browserWindow.focusLost.connect(this, "saveNote()");
7471 // メニューバーのボタンを新しいbrowserWindowに合わせる
7472 menuBar.refreshTargetWindow();
7474 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7475 boolean nextIsActive;
7476 if (tab.getBrowserWindow().getNote() != null) {
7477 nextIsActive = tab.getBrowserWindow().getNote().isActive();
7479 nextIsActive = true;
7481 if (Global.showDeleted && nextIsActive) {
7482 switchNoteTable(false);
7483 } else if (!Global.showDeleted && !nextIsActive) {
7484 switchNoteTable(true);
7487 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7488 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7489 scrollToGuid(currentNoteGuid);
7491 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7493 menuBar.noteDuplicateAction.setEnabled(true);
7494 menuBar.noteOnlineHistoryAction.setEnabled(true);
7495 menuBar.noteMergeAction.setEnabled(true);
7497 if (Global.showDeleted) {
7498 menuBar.noteDuplicateAction.setEnabled(false);
7500 if (!Global.isConnected) {
7501 menuBar.noteOnlineHistoryAction.setEnabled(false);
7503 menuBar.noteMergeAction.setEnabled(false);
7505 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7507 upButton.setEnabled(false);
7509 upButton.setEnabled(true);
7510 if (row < listManager.getNoteTableModel().rowCount() - 1)
7511 downButton.setEnabled(true);
7513 downButton.setEnabled(false);
7514 } catch (Exception e) {
7515 upButton.setEnabled(false);
7516 downButton.setEnabled(false);
7519 int currentIndex = tabBrowser.currentIndex();
7520 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7521 int histPosition = historyPosition.get(currentIndex);
7523 // prev, nextボタンの有効・無効化
7524 nextButton.setEnabled(true);
7525 prevButton.setEnabled(true);
7527 if (histPosition <= 1){
7528 prevButton.setEnabled(false);
7530 if (histPosition == histGuids.size()){
7531 nextButton.setEnabled(false);
7534 refreshEvernoteNote(true);
7537 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7540 // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7541 private void switchNoteTable(boolean toDeleted) {
7542 clearNotebookFilter();
7544 clearAttributeFilter();
7545 clearSavedSearchFilter();
7547 listManager.getSelectedNotebooks().clear();
7548 listManager.getSelectedTags().clear();
7549 listManager.setSelectedSavedSearch("");
7551 // toggle the add buttons
7552 newButton.setEnabled(!newButton.isEnabled());
7553 menuBar.noteAdd.setEnabled(newButton.isEnabled());
7554 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
7555 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
7556 menuBar.noteAddNewTab.setEnabled(false);
7558 menuBar.noteAdd.setVisible(true);
7560 if (!toDeleted) { // 生存ノートテーブルへ
7561 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7562 trashTree.clearSelection();
7563 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7564 Global.showDeleted = false;
7565 menuBar.noteRestoreAction.setEnabled(false);
7566 menuBar.noteRestoreAction.setVisible(false);
7567 // ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7568 rensoNoteListDock.setEnabled(true);
7570 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7571 trashTree.setCurrentItem(trashTree.getTrashItem());
7572 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7573 Global.showDeleted = true;
7574 menuBar.noteRestoreAction.setEnabled(true);
7575 menuBar.noteRestoreAction.setVisible(true);
7576 // ゴミ箱を開く。連想ノートリストをOFFに。
7577 rensoNoteListDock.setEnabled(false);
7580 listManager.loadNotesIndex();
7581 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7582 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7583 noteIndexUpdated(false);
7585 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7587 browserWindow.setReadOnly(!newButton.isEnabled());
7590 // ユーザが連想ノートリストのアイテムを選択した時の処理
7591 @SuppressWarnings("unused")
7592 private void rensoNoteItemPressed(QListWidgetItem current) {
7593 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7595 rensoNotePressedItemGuid = rensoNoteListDock.getRensoNoteList().getNoteGuid(current);
7598 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7604 String prevCurrentNoteGuid = new String(currentNoteGuid);
7606 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
7607 QModelIndex modelIndex = noteTableView.model().index(i,
7608 Global.noteTableGuidPosition);
7609 if (modelIndex != null) {
7610 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
7612 String tableGuid = (String) ix.values().toArray()[0];
7613 if (tableGuid.equals(rensoNotePressedItemGuid)) {
7614 noteTableView.selectRow(i);
7620 // 連想ノートリストアイテムクリック操作を記録
7621 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7623 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7626 // 関連ノートリストからノートを除外する
7627 @SuppressWarnings("unused")
7628 private void excludeNote() {
7629 if (rensoNotePressedItemGuid != null) {
7631 excludeNote(rensoNotePressedItemGuid);
7635 // 関連ノートリストからノートを除外する
7636 private void excludeNote(String guid) {
7637 if (Global.verifyExclude()) {
7639 Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7640 String title = note.getTitle();
7641 if (title != null) {
7642 msg = new String(tr("Exclude note \"") +title +"\"?");
7644 msg = new String(tr("Exclude note selected note?"));
7647 if (QMessageBox.question(this, tr("Confirmation"), msg,
7648 QMessageBox.StandardButton.Yes,
7649 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7654 // Historyデータベースから除外するノートのデータを削除
7655 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7658 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7660 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7663 // 関連ノートリストのノートにスターを付ける
7664 @SuppressWarnings("unused")
7665 private void starNote() {
7666 if (rensoNotePressedItemGuid != null) {
7668 starNote(rensoNotePressedItemGuid);
7672 // 関連ノートリストのノートにスターを付ける
7673 private void starNote(String guid) {
7675 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7677 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7680 // 関連ノートリストのノートからスターを外す
7681 @SuppressWarnings("unused")
7682 private void unstarNote() {
7683 if (rensoNotePressedItemGuid != null) {
7685 unstarNote(rensoNotePressedItemGuid);
7689 // 関連ノートリストのノートからスターを外す
7690 private void unstarNote(String guid) {
7692 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7694 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7697 // currentNoteGuidを返す
7698 public String getCurrentNoteGuid() {
7699 return currentNoteGuid;
7702 @SuppressWarnings("unused")
7703 // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える
7704 private void tabIndexChanged(int from, int to) {
7706 TabBrowse tab = tabWindows.get(from);
7707 tabWindows.put(from, tabWindows.get(to));
7708 tabWindows.put(to, tab);
7710 boolean isNoteDirty = noteDirty.get(from);
7711 noteDirty.put(from, noteDirty.get(to));
7712 noteDirty.put(to, isNoteDirty);
7714 boolean isInkNote = inkNote.get(from);
7715 inkNote.put(from, inkNote.get(to));
7716 inkNote.put(to, isInkNote);
7718 boolean isReadOnly = readOnly.get(from);
7719 readOnly.put(from, readOnly.get(to));
7720 readOnly.put(to, isReadOnly);
7722 ArrayList<String> histGuids = historyGuids.get(from);
7723 historyGuids.put(from, historyGuids.get(to));
7724 historyGuids.put(to, histGuids);
7726 int histPosition = historyPosition.get(from);
7727 historyPosition.put(from, historyPosition.get(to));
7728 historyPosition.put(to, histPosition);
7730 boolean fromHist = fromHistory.get(from);
7731 fromHistory.put(from, fromHistory.get(to));
7732 fromHistory.put(to, fromHist);
7736 public RensoNoteList getRensoNoteList() {
7737 return rensoNoteListDock.getRensoNoteList();
7741 @SuppressWarnings("unused")
7742 private void informRateLimit(Integer rateLimitDuration) {
7743 QMessageBox.warning(this, tr("Rate limit reached"), tr("Evernote usage has been temporarily exceeded. Please try again in ") + + rateLimitDuration + tr(" seconds."));
7746 // ツールバーの「新規」ボタンの接続スロットを設定
7747 public void connectNewButtonSlot(String slot) {
7748 newButton.triggered.disconnect();
7749 newButton.triggered.connect(this, slot);