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;
45 import java.util.SortedMap;
46 import java.util.Vector;
48 import org.apache.log4j.Level;
49 import org.apache.log4j.Logger;
50 import org.h2.tools.ChangeFileEncryption;
52 import com.evernote.edam.error.EDAMNotFoundException;
53 import com.evernote.edam.error.EDAMSystemException;
54 import com.evernote.edam.error.EDAMUserException;
55 import com.evernote.edam.notestore.NoteFilter;
56 import com.evernote.edam.notestore.NoteVersionId;
57 import com.evernote.edam.type.Data;
58 import com.evernote.edam.type.LinkedNotebook;
59 import com.evernote.edam.type.Note;
60 import com.evernote.edam.type.NoteAttributes;
61 import com.evernote.edam.type.Notebook;
62 import com.evernote.edam.type.Publishing;
63 import com.evernote.edam.type.QueryFormat;
64 import com.evernote.edam.type.Resource;
65 import com.evernote.edam.type.SavedSearch;
66 import com.evernote.edam.type.Tag;
67 import com.evernote.edam.type.User;
68 import com.evernote.thrift.TException;
69 import com.trolltech.qt.QThread;
70 import com.trolltech.qt.core.QByteArray;
71 import com.trolltech.qt.core.QDateTime;
72 import com.trolltech.qt.core.QDir;
73 import com.trolltech.qt.core.QEvent;
74 import com.trolltech.qt.core.QFile;
75 import com.trolltech.qt.core.QFileInfo;
76 import com.trolltech.qt.core.QFileSystemWatcher;
77 import com.trolltech.qt.core.QIODevice;
78 import com.trolltech.qt.core.QIODevice.OpenModeFlag;
79 import com.trolltech.qt.core.QLocale;
80 import com.trolltech.qt.core.QMimeData;
81 import com.trolltech.qt.core.QModelIndex;
82 import com.trolltech.qt.core.QSize;
83 import com.trolltech.qt.core.QTemporaryFile;
84 import com.trolltech.qt.core.QTextCodec;
85 import com.trolltech.qt.core.QTextStream;
86 import com.trolltech.qt.core.QThreadPool;
87 import com.trolltech.qt.core.QTimer;
88 import com.trolltech.qt.core.QTranslator;
89 import com.trolltech.qt.core.QUrl;
90 import com.trolltech.qt.core.Qt;
91 import com.trolltech.qt.core.Qt.BGMode;
92 import com.trolltech.qt.core.Qt.DockWidgetArea;
93 import com.trolltech.qt.core.Qt.ItemDataRole;
94 import com.trolltech.qt.core.Qt.KeyboardModifier;
95 import com.trolltech.qt.core.Qt.MouseButton;
96 import com.trolltech.qt.core.Qt.SortOrder;
97 import com.trolltech.qt.core.Qt.WidgetAttribute;
98 import com.trolltech.qt.gui.QAbstractItemView;
99 import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
100 import com.trolltech.qt.gui.QAction;
101 import com.trolltech.qt.gui.QApplication;
102 import com.trolltech.qt.gui.QClipboard;
103 import com.trolltech.qt.gui.QCloseEvent;
104 import com.trolltech.qt.gui.QColor;
105 import com.trolltech.qt.gui.QComboBox;
106 import com.trolltech.qt.gui.QCursor;
107 import com.trolltech.qt.gui.QDesktopServices;
108 import com.trolltech.qt.gui.QDialog;
109 import com.trolltech.qt.gui.QDockWidget;
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.QLabel;
119 import com.trolltech.qt.gui.QListWidgetItem;
120 import com.trolltech.qt.gui.QMainWindow;
121 import com.trolltech.qt.gui.QMenu;
122 import com.trolltech.qt.gui.QMessageBox;
123 import com.trolltech.qt.gui.QMessageBox.StandardButton;
124 import com.trolltech.qt.gui.QPainter;
125 import com.trolltech.qt.gui.QPalette.ColorRole;
126 import com.trolltech.qt.gui.QPixmap;
127 import com.trolltech.qt.gui.QPrintDialog;
128 import com.trolltech.qt.gui.QPrinter;
129 import com.trolltech.qt.gui.QShortcut;
130 import com.trolltech.qt.gui.QSizePolicy;
131 import com.trolltech.qt.gui.QSizePolicy.Policy;
132 import com.trolltech.qt.gui.QSpinBox;
133 import com.trolltech.qt.gui.QSplashScreen;
134 import com.trolltech.qt.gui.QSplitter;
135 import com.trolltech.qt.gui.QStatusBar;
136 import com.trolltech.qt.gui.QSystemTrayIcon;
137 import com.trolltech.qt.gui.QTableWidgetItem;
138 import com.trolltech.qt.gui.QTextEdit;
139 import com.trolltech.qt.gui.QToolBar;
140 import com.trolltech.qt.gui.QTreeWidgetItem;
141 import com.trolltech.qt.network.QNetworkAccessManager;
142 import com.trolltech.qt.network.QNetworkProxy;
143 import com.trolltech.qt.network.QNetworkProxy.ProxyType;
144 import com.trolltech.qt.network.QNetworkReply;
145 import com.trolltech.qt.network.QNetworkRequest;
146 import com.trolltech.qt.webkit.QWebPage.WebAction;
147 import com.trolltech.qt.webkit.QWebSettings;
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.SavedSearchTreeWidget;
185 import cx.fbn.nevernote.gui.SearchPanel;
186 import cx.fbn.nevernote.gui.TabBrowse;
187 import cx.fbn.nevernote.gui.TabBrowserWidget;
188 import cx.fbn.nevernote.gui.TableView;
189 import cx.fbn.nevernote.gui.TagTreeWidget;
190 import cx.fbn.nevernote.gui.Thumbnailer;
191 import cx.fbn.nevernote.gui.TrashTreeWidget;
192 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
193 import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
194 import cx.fbn.nevernote.oauth.OAuthTokenizer;
195 import cx.fbn.nevernote.oauth.OAuthWindow;
196 import cx.fbn.nevernote.sql.DatabaseConnection;
197 import cx.fbn.nevernote.sql.WatchFolderRecord;
198 import cx.fbn.nevernote.threads.IndexRunner;
199 import cx.fbn.nevernote.threads.SyncRunner;
200 import cx.fbn.nevernote.threads.ThumbnailRunner;
201 import cx.fbn.nevernote.utilities.AESEncrypter;
202 import cx.fbn.nevernote.utilities.ApplicationLogger;
203 import cx.fbn.nevernote.utilities.FileImporter;
204 import cx.fbn.nevernote.utilities.FileUtils;
205 import cx.fbn.nevernote.utilities.ListManager;
206 import cx.fbn.nevernote.utilities.SyncTimes;
207 import cx.fbn.nevernote.xml.ExportData;
208 import cx.fbn.nevernote.xml.ImportData;
209 import cx.fbn.nevernote.xml.ImportEnex;
210 import cx.fbn.nevernote.xml.NoteFormatter;
211 //import org.apache.thrift.TException;
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 QComboBox 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
255 HashMap<Integer, Boolean> noteDirty; // Has the note been changed?
256 HashMap<Integer, Boolean> inkNote; // if this is an ink note, it is read only
257 HashMap<Integer, Boolean> readOnly; // Is this note read-only?
260 ListManager listManager; // DB runnable task
262 List<QTemporaryFile> tempFiles; // Array of temporary files;
264 QTimer indexTimer; // timer to start the index thread
265 IndexRunner indexRunner; // thread to index notes
268 QTimer syncTimer; // Sync on an interval
269 QTimer syncDelayTimer; // Sync delay to free up database
270 SyncRunner syncRunner; // thread to do a sync.
271 QThread syncThread; // Thread which talks to evernote
272 ThumbnailRunner thumbnailRunner; // Runner for thumbnail thread
273 QThread thumbnailThread; // Thread that generates pretty pictures
274 QTimer saveTimer; // Timer to save note contents
276 QTimer authTimer; // Refresh authentication
277 QTimer externalFileSaveTimer; // Save files altered externally
278 QTimer thumbnailTimer; // Wakeup & scan for thumbnails
280 List<String> externalFiles; // External files to save later
281 List<String> importFilesKeep; // Auto-import files to save later
282 List<String> importFilesDelete; // Auto-import files to save later
284 int indexTime; // how often to try and index
285 boolean indexRunning; // Is indexing running?
286 boolean indexDisabled; // Is indexing disabled?
288 int syncThreadsReady; // number of sync threads that are free
289 int syncTime; // Sync interval
290 boolean syncRunning; // Is sync running?
291 boolean automaticSync; // do sync automatically?
292 QTreeWidgetItem attributeTreeSelected;
294 QAction prevButton; // Go to the previous item viewed
295 QAction nextButton; // Go to the next item in the history
296 QAction downButton; // Go to the next item in the list
297 QAction upButton; // Go to the prev. item in the list;
298 QAction synchronizeButton; // Synchronize with Evernote
299 QAction allNotesButton; // Reset & view all notes
300 QTimer synchronizeAnimationTimer; // Timer to change animation button
301 int synchronizeIconAngle; // Used to rotate sync icon
302 QAction printButton; // Print Button
303 QAction tagButton; // Tag edit button
304 QAction attributeButton; // Attribute information button
305 QAction emailButton; // Email button
306 QAction deleteButton; // Delete button
307 QAction newButton; // new Note Button;
308 QSpinBox zoomSpinner; // Zoom zoom
309 QAction searchClearButton; // Clear the search field
311 SearchPanel searchLayout; // Widget to hold search field, zoom, & quota
313 QSplitter mainLeftRightSplitter; // main splitter for left/right side
314 QSplitter leftSplitter1; // first left hand splitter
315 QSplitter browserIndexSplitter; // splitter between note index & note text
317 QFileSystemWatcher importKeepWatcher; // Watch & keep auto-import
318 QFileSystemWatcher importDeleteWatcher; // Watch & Delete auto-import
319 List<String> importedFiles; // History of imported files (so we don't import twice)
321 OnlineNoteHistory historyWindow; // online history window
322 List<NoteVersionId> versions; // history versions
324 QTimer threadMonitorTimer; // Timer to watch threads.
325 int dbThreadDeadCount=0; // number of consecutive dead times for the db thread
326 int syncThreadDeadCount=0; // number of consecutive dead times for the sync thread
327 int indexThreadDeadCount=0; // number of consecutive dead times for the index thread
328 int notebookThreadDeadCount=0; // number of consecutive dead times for the notebook thread
329 int tagDeadCount=0; // number of consecutive dead times for the tag thread
330 int trashDeadCount=0; // number of consecutive dead times for the trash thread
331 int saveThreadDeadCount=0; // number of consecutive dead times for the save 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;
339 HashMap<String, String> noteCache; // Cash of note content
340 HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
341 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;
365 private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
366 private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
367 private final RensoNoteList rensoNoteList; // 連想ノートリスト
368 private final QDockWidget rensoNoteListDock; // 連想ノートリストドックウィジェット
369 ClipBoardObserver cbObserver;
370 String rensoNotePressedItemGuid;
372 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
375 //***************************************************************
376 //***************************************************************
377 //** Constructor & main entry point
378 //***************************************************************
379 //***************************************************************
380 // Application Constructor
381 @SuppressWarnings("static-access")
382 public NeverNote(DatabaseConnection dbConn) {
384 cbObserver = new ClipBoardObserver();
387 if (conn.getConnection() == null) {
388 String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
389 "is accessing the database or NeighborNote is already running.\n\n" +
390 "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
392 QMessageBox.critical(null, tr("Database Connection Error") ,msg);
395 setObjectName("mainWindow");
396 // thread().setPriority(Thread.MAX_PRIORITY);
398 logger = new ApplicationLogger("nevernote.log");
399 logger.log(logger.HIGH, "Starting Application");
401 decryptOnShutdown = false;
402 encryptOnShutdown = false;
403 conn.checkDatabaseVersion();
407 // Start building the invalid XML tables
408 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
409 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
411 for (int i=0; i<elements.size(); i++) {
412 Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
415 logger.log(logger.EXTREME, "Starting GUI build");
417 QTranslator nevernoteTranslator = new QTranslator();
418 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("neighbornote_" + QLocale.system().name() + ".qm"));
419 QApplication.instance().installTranslator(nevernoteTranslator);
421 Global.originalPalette = QApplication.palette();
422 QApplication.setStyle(Global.getStyle());
423 if (Global.useStandardPalette())
424 QApplication.setPalette(QApplication.style().standardPalette());
425 setWindowTitle(tr("NeighborNote"));
427 mainLeftRightSplitter = new QSplitter();
429 mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
431 setCentralWidget(mainLeftRightSplitter);
432 leftSplitter1 = new QSplitter();
433 leftSplitter1.setOrientation(Qt.Orientation.Vertical);
435 browserIndexSplitter = new QSplitter();
436 browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
438 //* Setup threads & thread timers
439 // int indexRunnerCount = Global.getIndexThreads();
440 // indexRunnerCount = 1;
441 QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount); // increase max thread count
443 logger.log(logger.EXTREME, "Building list manager");
444 listManager = new ListManager(conn, logger);
446 logger.log(logger.EXTREME, "Building index runners & timers");
447 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
448 indexRunner = new IndexRunner("indexRunner.log",
449 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
450 Global.getResourceDatabaseUrl(),
451 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
452 Global.getDatabaseUserPassword(), Global.cipherPassword);
454 indexThread = new QThread(indexRunner, "Index Thread");
455 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
456 indexRunner.indexImageRecognition = Global.indexImageRecognition();
457 indexRunner.indexNoteBody = Global.indexNoteBody();
458 indexRunner.indexNoteTitle = Global.indexNoteTitle();
459 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
462 synchronizeAnimationTimer = new QTimer();
463 synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
465 indexTimer = new QTimer();
466 indexTime = 1000*Global.getIndexThreadSleepInterval();
467 indexTimer.start(indexTime); // Start indexing timer
468 indexTimer.timeout.connect(this, "indexTimer()");
469 indexDisabled = false;
470 indexRunning = false;
472 logger.log(logger.EXTREME, "Setting sync thread & timers");
474 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
475 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
476 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
477 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
478 Global.getDatabaseUserPassword(), Global.cipherPassword);
480 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
481 syncTimer = new QTimer();
482 syncTimer.timeout.connect(this, "syncTimer()");
483 syncRunner.status.message.connect(this, "setMessage(String)");
484 syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
485 syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
488 automaticSync = true;
489 syncTimer.start(syncTime*60*1000);
491 automaticSync = false;
494 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
495 syncThread = new QThread(syncRunner, "Synchronization Thread");
499 logger.log(logger.EXTREME, "Starting thumnail thread");
500 pdfReadyQueue = new ArrayList<String>();
501 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
502 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
503 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
504 Global.getResourceDatabaseUrl(),
505 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
506 Global.getDatabaseUserPassword(), Global.cipherPassword);
508 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
509 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
510 thumbnailThread.start();
511 thumbGenerators = new ArrayList<Thumbnailer>();
512 thumbnailTimer = new QTimer();
513 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
515 thumbnailTimer.setInterval(500*1000); // Thumbnail every minute
516 thumbnailTimer.start();
518 // debugTimer = new QTimer();
519 // debugTimer.timeout.connect(this, "debugDirty()");
520 // debugTimer.start(1000*60);
522 logger.log(logger.EXTREME, "Starting authentication timer");
523 authTimer = new QTimer();
524 authTimer.timeout.connect(this, "authTimer()");
525 authTimer.start(1000*60*15);
526 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
528 logger.log(logger.EXTREME, "Setting save note timer");
529 saveTimer = new QTimer();
530 saveTimer.timeout.connect(this, "saveNote()");
531 if (Global.getAutoSaveInterval() > 0) {
532 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
535 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
537 logger.log(logger.EXTREME, "Starting external file monitor timer");
538 externalFileSaveTimer = new QTimer();
539 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
540 externalFileSaveTimer.setInterval(1000*5); // save every 5 seconds;
541 externalFiles = new ArrayList<String>();
542 importFilesDelete = new ArrayList<String>();
543 importFilesKeep = new ArrayList<String>();
544 externalFileSaveTimer.start();
546 notebookTree = new NotebookTreeWidget(conn);
547 attributeTree = new AttributeTreeWidget();
548 tagTree = new TagTreeWidget(conn);
549 savedSearchTree = new SavedSearchTreeWidget();
550 trashTree = new TrashTreeWidget();
552 noteTableView = new TableView(logger, listManager, this);
554 searchField = new QComboBox();
555 searchField.setObjectName("searchField");
556 //setStyleSheet("QComboBox#searchField { background-color: yellow }");
557 searchField.setEditable(true);
558 searchField.activatedIndex.connect(this, "searchFieldChanged()");
559 searchField.setDuplicatesEnabled(false);
560 searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
561 searchShortcut = new QShortcut(this);
562 setupShortcut(searchShortcut, "Focus_Search");
563 searchShortcut.activated.connect(this, "focusSearch()");
565 quotaBar = new QuotaProgressBar();
567 zoomSpinner = new QSpinBox();
568 zoomSpinner.setMinimum(10);
569 zoomSpinner.setMaximum(1000);
570 zoomSpinner.setAccelerated(true);
571 zoomSpinner.setSingleStep(10);
572 zoomSpinner.setValue(100);
573 zoomSpinner.valueChanged.connect(this, "zoomChanged()");
575 searchLayout = new SearchPanel(searchField, quotaBar, notebookTree, zoomSpinner);
578 QGridLayout leftGrid = new QGridLayout();
579 leftSplitter1.setContentsMargins(5, 0, 0, 7);
580 leftSplitter1.setLayout(leftGrid);
581 leftGrid.addWidget(searchLayout,1,1);
582 leftGrid.addWidget(tagTree,2,1);
583 leftGrid.addWidget(attributeTree,3,1);
584 leftGrid.addWidget(savedSearchTree,4,1);
585 leftGrid.addWidget(trashTree,5, 1);
587 // Setup the browser window
588 noteCache = new HashMap<String,String>();
589 readOnlyCache = new HashMap<String, Boolean>();
590 inkNoteCache = new HashMap<String, Boolean>();
592 browserWindow = new BrowserWindow(conn, cbObserver);
594 // ICHANGED 下から移動してきた。
595 historyGuids = new HashMap<Integer, ArrayList<String>>();
596 historyPosition = new HashMap<Integer, Integer>();
597 fromHistory = new HashMap<Integer, Boolean>();
600 tabWindows = new HashMap<Integer, TabBrowse>();
601 tabBrowser = new TabBrowserWidget(this);
602 tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
603 tabBrowser.setMovable(true);
604 TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver);
605 browserWindow = tab.getBrowserWindow();
606 int index = tabBrowser.addNewTab(tab, "");
607 tabWindows.put(index, tab);
608 tabBrowser.setTabsClosable(true);
609 tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)");
610 tabBrowser.tabCloseRequested.connect(this, "tabWindowClosing(int)");
612 noteDirty = new HashMap<Integer, Boolean>();
613 noteDirty.put(index, false);
615 inkNote = new HashMap<Integer, Boolean>();
616 readOnly = new HashMap<Integer, Boolean>();
620 historyGuids.put(index, new ArrayList<String>());
621 historyPosition.put(index, 0);
622 fromHistory.put(index, false);
624 mainLeftRightSplitter.addWidget(leftSplitter1);
625 mainLeftRightSplitter.addWidget(browserIndexSplitter);
629 rensoNoteList = new RensoNoteList(conn, this, syncRunner);
630 rensoNoteList.itemPressed.connect(this,
631 "rensoNoteItemPressed(QListWidgetItem)");
632 rensoNoteListDock = new QDockWidget(tr("Renso Note List"), this);
633 rensoNoteListDock.setWidget(rensoNoteList);
634 addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
636 if (Global.getListView() == Global.View_List_Wide) {
637 browserIndexSplitter.addWidget(noteTableView);
639 browserIndexSplitter.addWidget(tabBrowser);
640 // browserIndexSplitter.addWidget(browserWindow);
642 mainLeftRightSplitter.addWidget(noteTableView);
644 mainLeftRightSplitter.addWidget(tabBrowser);
645 // mainLeftRightSplitter.addWidget(browserWindow);
648 // Setup the thumbnail viewer
649 thumbnailViewer = new ThumbnailViewer();
650 thumbnailViewer.upArrow.connect(this, "upAction()");
651 thumbnailViewer.downArrow.connect(this, "downAction()");
652 thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
653 thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
655 //Setup external browser manager
656 externalWindows = new HashMap<String, ExternalBrowse>();
658 listManager.loadNotesIndex();
659 initializeNotebookTree();
661 initializeSavedSearchTree();
662 attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
663 attributeTreeSelected = null;
664 initializeNoteTable();
666 selectedNoteGUIDs = new ArrayList<String>();
667 statusBar = new QStatusBar();
668 setStatusBar(statusBar);
669 menuBar = new MainMenuBar(this);
670 emitLog = new ArrayList<String>();
672 tagTree.setDeleteAction(menuBar.tagDeleteAction);
673 tagTree.setMergeAction(menuBar.tagMergeAction);
674 tagTree.setEditAction(menuBar.tagEditAction);
675 tagTree.setAddAction(menuBar.tagAddAction);
676 tagTree.setIconAction(menuBar.tagIconAction);
677 tagTree.setVisible(Global.isWindowVisible("tagTree"));
678 leftSplitter1.setVisible(Global.isWindowVisible("leftPanel"));
679 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
680 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
681 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
683 if (!Global.isWindowVisible("zoom")) {
684 searchLayout.hideZoom();
685 menuBar.hideZoom.setChecked(false);
688 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
689 notebookTree.setEditAction(menuBar.notebookEditAction);
690 notebookTree.setAddAction(menuBar.notebookAddAction);
691 notebookTree.setIconAction(menuBar.notebookIconAction);
692 notebookTree.setStackAction(menuBar.notebookStackAction);
693 notebookTree.setPublishAction(menuBar.notebookPublishAction);
694 notebookTree.setShareAction(menuBar.notebookShareAction);
695 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
696 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
697 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
698 notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
699 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
701 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
702 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
703 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
704 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
705 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
706 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
707 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
709 // ICHANGED noteTableViewに新しいタブで開くを追加
710 noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
712 noteTableView.setAddAction(menuBar.noteAdd);
714 // ICHANGED noteTableViewに新しいタブでノート追加を追加
715 noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
717 noteTableView.setDeleteAction(menuBar.noteDelete);
718 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
719 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
720 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
721 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
722 noteTableView.noteSignal.notePinned.connect(this, "notePinned()");
723 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
724 noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction);
725 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
726 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
728 quotaBar.setMouseClickAction(menuBar.accountAction);
731 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
732 trashTree.setEmptyAction(menuBar.emptyTrashAction);
733 trashTree.setVisible(Global.isWindowVisible("trashTree"));
734 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
735 trashTree.updateCounts(listManager.getTrashCount());
736 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
737 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
739 noteTableView.setVisible(Global.isWindowVisible("noteList"));
740 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
743 if (!Global.isWindowVisible("editorButtonBar")) {
744 menuBar.showEditorBar.setChecked(false);
745 toggleEditorButtonBar();
748 if (!Global.isWindowVisible("leftPanel"))
749 menuBar.hideLeftSide.setChecked(true);
752 if (Global.isWindowVisible("noteInformation")) {
753 menuBar.noteAttributes.setChecked(true);
754 toggleNoteInformation();
757 quotaBar.setVisible(Global.isWindowVisible("quota"));
758 // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
759 // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
760 if (!Global.isWindowVisible("quota"))
761 menuBar.hideQuota.setChecked(false);
763 searchField.setVisible(Global.isWindowVisible("searchField"));
764 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
765 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
766 if (!Global.isWindowVisible("searchField"))
767 menuBar.hideSearch.setChecked(false);
769 if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
774 find = new FindDialog();
775 find.getOkButton().clicked.connect(this, "doFindText()");
777 // Setup the tray icon menu bar
778 trayShowAction = new QAction(tr("Show/Hide"), this);
779 trayExitAction = new QAction(tr("Exit"), this);
780 trayAddNoteAction = new QAction(tr("Add Note"), this);
782 trayExitAction.triggered.connect(this, "closeNeverNote()");
783 trayAddNoteAction.triggered.connect(this, "addNote()");
784 trayShowAction.triggered.connect(this, "trayToggleVisible()");
786 trayMenu = new QMenu(this);
787 trayMenu.addAction(trayAddNoteAction);
788 trayMenu.addAction(trayShowAction);
789 trayMenu.addAction(trayExitAction);
792 trayIcon = new QSystemTrayIcon(this);
793 trayIcon.setToolTip(tr("NeighborNote"));
794 trayIcon.setContextMenu(trayMenu);
795 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
798 currentNoteGuid = Global.getLastViewedNoteGuid();
799 if (currentNoteGuid.equals(""))
800 currentNote = new Note();
804 historyGuids = new ArrayList<String>();
809 if (!currentNoteGuid.trim().equals("")) {
810 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
813 noteIndexUpdated(true);
815 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
816 if (menuBar.showEditorBar.isChecked())
817 showEditorButtons(browserWindow);
818 tagIndexUpdated(true);
819 savedSearchIndexUpdated();
820 notebookIndexUpdated();
822 setupSyncSignalListeners();
823 setupBrowserSignalListeners();
824 setupIndexListeners();
827 tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
828 tagTree.showAllTags(true);
830 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
831 if (QSystemTrayIcon.isSystemTrayAvailable()) {
832 setWindowIcon(appIcon);
833 trayIcon.setIcon(appIcon);
834 if (Global.showTrayIcon() || Global.minimizeOnClose())
840 scrollToGuid(currentNoteGuid);
841 if (Global.automaticLogin()) {
843 if (Global.isConnected)
846 setupFolderImports();
849 restoreWindowState(true);
851 if (Global.mimicEvernoteInterface) {
852 notebookTree.selectGuid("");
855 threadMonitorTimer = new QTimer();
856 threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
857 threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
859 // ICHANGED たぶんこれはいらない
862 historyGuids.add(currentNoteGuid);
866 menuBar.blockSignals(true);
867 menuBar.narrowListView.blockSignals(true);
868 menuBar.wideListView.blockSignals(true);
869 if (Global.getListView() == Global.View_List_Narrow) {
870 menuBar.narrowListView.setChecked(true);
873 menuBar.wideListView.setChecked(true);
875 menuBar.blockSignals(false);
876 menuBar.narrowListView.blockSignals(false);
877 menuBar.wideListView.blockSignals(false);
880 // 上に同じコードがあるよね? とりあえずコメントアウト
882 * if (Global.getListView() == Global.View_List_Wide) {
883 * browserIndexSplitter.addWidget(noteTableView); // ICHANGED //
884 * browserIndexSplitter.addWidget(tabBrowser);
885 * browserIndexSplitter.addWidget(browserWindow); } else {
886 * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED //
887 * mainLeftRightSplitter.addWidget(tabBrowser);
888 * mainLeftRightSplitter.addWidget(browserWindow); }
891 messageTimer = new QTimer();
892 messageTimer.timeout.connect(this, "clearMessage()");
893 messageTimer.setInterval(1000*15);
896 int sortCol = Global.getSortColumn();
897 int sortOrder = Global.getSortOrder();
898 noteTableView.proxyModel.blocked = true;
899 // We sort the table twice to fix a bug. For some reaosn the table won't sort properly if it is in narrow
900 // list view and sorted descending on the date created. By sorting it twice it forces the proper sort. Ugly.
901 if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow)
902 noteTableView.sortByColumn(sortCol, SortOrder.resolve(0));
903 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
904 noteTableView.proxyModel.blocked = false;
905 noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)");
907 // Set the startup notebook
908 String defaultNotebook = Global.getStartupNotebook();
909 if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) {
910 for (int k=0; k<listManager.getNotebookIndex().size(); k++) {
911 if (listManager.getNotebookIndex().get(k).isDefaultNotebook()) {
912 notebookTree.clearSelection();
913 notebookTree.selectGuid(listManager.getNotebookIndex().get(k).getGuid());
914 notebookTree.selectionSignal.emit();
919 if (Global.checkVersionUpgrade()) {
924 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
925 menuBar.noteAddNewTab.setEnabled(false);
930 public void debugDirty() {
931 List<Note> dirty = conn.getNoteTable().getDirty();
932 logger.log(logger.LOW, "------ Dirty Notes List Begin ------");
933 for (int i=0; i<dirty.size(); i++) {
934 logger.log(logger.LOW, "GUID: " +dirty.get(i).getGuid() + " Title:" + dirty.get(i).getTitle());
936 logger.log(logger.LOW, "------ Dirty Notes List End ------");
940 public static void main(String[] args) {
941 log.setLevel(Level.FATAL);
942 QApplication.initialize(args);
943 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
944 QSplashScreen splash = new QSplashScreen(pixmap);
947 DatabaseConnection dbConn;
950 initializeGlobalSettings(args);
952 showSplash = Global.isWindowVisible("SplashScreen");
956 dbConn = setupDatabaseConnection();
958 // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
959 Global.getFileManager().purgeResDirectory(true);
961 } catch (InitializationException e) {
964 QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
969 String proxyUrl = Global.getProxyValue("url");
970 String proxyPort = Global.getProxyValue("port");
971 String proxyUserid = Global.getProxyValue("userid");
972 String proxyPassword = Global.getProxyValue("password");
973 boolean proxySet = false;
974 QNetworkProxy proxy = new QNetworkProxy();
975 proxy.setType(ProxyType.HttpProxy);
976 if (!proxyUrl.trim().equals("")) {
977 System.out.println("Proxy URL found: " +proxyUrl);
979 proxy.setHostName(proxyUrl);
981 if (!proxyPort.trim().equals("")) {
982 System.out.println("Proxy Port found: " +proxyPort);
984 proxy.setPort(Integer.parseInt(proxyPort));
986 if (!proxyUserid.trim().equals("")) {
987 System.out.println("Proxy Userid found: " +proxyUserid);
989 proxy.setUser(proxyUserid);
991 if (!proxyPassword.trim().equals("")) {
992 System.out.println("Proxy URL found: " +proxyPassword);
994 proxy.setPassword(proxyPassword);
997 QNetworkProxy.setApplicationProxy(proxy);
1001 NeverNote application = new NeverNote(dbConn);
1002 if (Global.syncOnly) {
1003 System.out.println("Performing synchronization only.");
1004 application.remoteConnect();
1005 if (Global.isConnected) {
1006 application.syncRunner.syncNeeded = true;
1007 application.syncRunner.addWork("SYNC");
1008 application.syncRunner.addWork("STOP");
1009 while(!application.syncRunner.isIdle());
1010 application.closeNeverNote();
1015 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
1016 if (Global.startMinimized())
1017 application.showMinimized();
1019 if (Global.wasWindowMaximized())
1020 application.showMaximized();
1026 splash.finish(application);
1027 QApplication.exec();
1028 System.out.println("Goodbye.");
1029 QApplication.exit();
1033 * Open the internal database, or create if not present
1035 * @throws InitializationException when opening the database fails, e.g. because another process has it locked
1037 private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
1038 ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
1040 File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
1041 File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
1042 // IFIXED resourceDatabaseNameになっていたので修正
1043 File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
1045 File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
1048 Global.setDatabaseUrl("");
1050 Global.setResourceDatabaseUrl("");
1052 Global.setIndexDatabaseUrl("");
1055 Global.setBehaviorDatabaseUrl("");
1057 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
1058 boolean goodCheck = false;
1059 while (!goodCheck) {
1060 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
1062 if (!dialog.okPressed())
1064 Global.cipherPassword = dialog.getPassword();
1065 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
1066 Global.getDatabaseUserPassword(), Global.cipherPassword);
1069 // ICHANGED Global.getBehaviorDatabaserUrl()を追加
1070 DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(),
1071 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
1072 Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
1076 // Encrypt the database upon shutdown
1077 private void encryptOnShutdown() {
1078 String dbPath= Global.getFileManager().getDbDirPath("");
1081 Statement st = conn.getConnection().createStatement();
1082 st.execute("shutdown");
1083 st = conn.getResourceConnection().createStatement();
1084 st.execute("shutdown");
1085 st = conn.getIndexConnection().createStatement();
1086 st.execute("shutdown");
1088 st = conn.getBehaviorConnection().createStatement();
1089 st.execute("shutdown");
1091 if (QMessageBox.question(this, tr("Are you sure"),
1092 tr("Are you sure you wish to encrypt the database?"),
1093 QMessageBox.StandardButton.Yes,
1094 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1095 ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1096 ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1097 ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1099 ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1101 Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
1102 Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
1103 Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
1105 Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
1107 QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
1109 } catch (SQLException e) {
1110 e.printStackTrace();
1114 // Decrypt the database upon shutdown
1115 private void decryptOnShutdown() {
1116 String dbPath= Global.getFileManager().getDbDirPath("");
1117 String dbName = "NeverNote";
1119 Statement st = conn.getConnection().createStatement();
1120 st.execute("shutdown");
1121 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
1122 encryptCipher = "AES";
1124 encryptCipher = "XTEA";
1125 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
1126 "Are you sure you wish to decrypt the database?"),
1127 QMessageBox.StandardButton.Yes,
1128 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1130 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
1131 Global.setDatabaseUrl("");
1132 Global.setResourceDatabaseUrl("");
1133 Global.setIndexDatabaseUrl("");
1134 QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
1136 } catch (SQLException e) {
1137 e.printStackTrace();
1141 * Encrypt/Decrypt the local database
1143 public void doDatabaseEncrypt() {
1144 // The database is not currently encrypted
1145 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
1146 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
1147 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
1148 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
1149 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
1150 "Do you wish to proceed?"),
1151 QMessageBox.StandardButton.Yes,
1152 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1155 DBEncryptDialog dialog = new DBEncryptDialog();
1157 if (dialog.okPressed()) {
1158 Global.cipherPassword = dialog.getPassword();
1159 encryptOnShutdown = true;
1160 encryptCipher = dialog.getEncryptionMethod();
1163 DBEncryptDialog dialog = new DBEncryptDialog();
1164 dialog.setWindowTitle(tr("Database Decryption"));
1165 dialog.hideEncryption();
1167 if (dialog.okPressed()) {
1168 if (!dialog.getPassword().equals(Global.cipherPassword)) {
1169 QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
1172 decryptOnShutdown = true;
1179 private static void initializeGlobalSettings(String[] args) throws InitializationException {
1180 StartupConfig startupConfig = new StartupConfig();
1182 for (String arg : args) {
1183 String lower = arg.toLowerCase();
1184 if (lower.startsWith("--name="))
1185 startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
1186 if (lower.startsWith("--home="))
1187 startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
1188 if (lower.startsWith("--disable-viewing"))
1189 startupConfig.setDisableViewing(true);
1190 if (lower.startsWith("--sync-only=true"))
1191 startupConfig.setSyncOnly(true);
1193 Global.setup(startupConfig);
1199 public void closeEvent(QCloseEvent event) {
1200 if (Global.minimizeOnClose() && !closeAction) {
1205 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
1208 if (currentNote != null & browserWindow != null) {
1209 if (currentNote.getTitle() != null && browserWindow != null
1210 && !currentNote.getTitle().equals(browserWindow.getTitle()))
1211 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
1212 browserWindow.getTitle());
1216 setMessage(tr("Beginning shutdown."));
1218 // Close down external windows
1219 Collection<ExternalBrowse> windows = externalWindows.values();
1220 Iterator<ExternalBrowse> iterator = windows.iterator();
1221 while (iterator.hasNext()) {
1222 ExternalBrowse browser = iterator.next();
1223 browser.windowClosing.disconnect();
1227 // ICHANGED タブブラウザに対してクローズ処理を行う
1228 Collection<TabBrowse> win = tabWindows.values();
1229 Iterator<TabBrowse> it = win.iterator();
1230 tabBrowser.currentChanged.disconnect();
1231 tabBrowser.tabCloseRequested.disconnect();
1232 while (it.hasNext()) {
1233 TabBrowse browser = it.next();
1237 externalFileEditedSaver();
1238 if (Global.isConnected && Global.synchronizeOnClose()) {
1239 setMessage(tr("Performing synchronization before closing."));
1240 syncRunner.syncNeeded = true;
1241 syncRunner.addWork("SYNC");
1243 syncRunner.keepRunning = false;
1245 syncRunner.addWork("STOP");
1246 setMessage("Closing Program.");
1247 threadMonitorTimer.stop();
1249 thumbnailRunner.addWork("STOP");
1250 indexRunner.addWork("STOP");
1255 // 連想ノートリストのEvernote関連ノート取得スレッドを終了
1256 rensoNoteList.stopThread();
1258 if (tempFiles != null)
1261 browserWindow.noteSignal.tagsChanged.disconnect();
1262 browserWindow.noteSignal.titleChanged.disconnect();
1263 browserWindow.noteSignal.noteChanged.disconnect();
1264 browserWindow.noteSignal.notebookChanged.disconnect();
1265 browserWindow.noteSignal.createdDateChanged.disconnect();
1266 browserWindow.noteSignal.alteredDateChanged.disconnect();
1267 syncRunner.searchSignal.listChanged.disconnect();
1268 syncRunner.tagSignal.listChanged.disconnect();
1269 syncRunner.notebookSignal.listChanged.disconnect();
1270 syncRunner.noteIndexSignal.listChanged.disconnect();
1273 Global.saveWindowVisible("toolBar", toolBar.isVisible());
1274 saveNoteColumnPositions();
1275 saveNoteIndexWidth();
1277 int width = notebookTree.columnWidth(0);
1278 Global.setColumnWidth("notebookTreeName", width);
1279 width = tagTree.columnWidth(0);
1280 Global.setColumnWidth("tagTreeName", width);
1282 Global.saveWindowMaximized(isMaximized());
1283 Global.saveCurrentNoteGuid(currentNoteGuid);
1285 int sortCol = noteTableView.proxyModel.sortColumn();
1286 int sortOrder = noteTableView.proxyModel.sortOrder().value();
1287 Global.setSortColumn(sortCol);
1288 Global.setSortOrder(sortOrder);
1292 Global.keepRunning = false;
1294 logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
1295 if (indexRunner.thread().isAlive())
1296 indexRunner.thread().join(50);
1297 if (!indexRunner.thread().isAlive())
1298 logger.log(logger.MEDIUM, "Index thread has stopped");
1300 logger.log(logger.MEDIUM, "Index thread still running - interrupting");
1301 indexRunner.thread().interrupt();
1303 } catch (InterruptedException e1) {
1304 e1.printStackTrace();
1307 if (!syncRunner.thread().isAlive()) {
1308 logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
1309 if (syncRunner.thread().isAlive()) {
1310 System.out.println(tr("Synchronizing. Please be patient."));
1311 for(;syncRunner.thread().isAlive();) {
1314 } catch (InterruptedException e) {
1315 e.printStackTrace();
1319 logger.log(logger.MEDIUM, "Sync thread has stopped");
1322 if (encryptOnShutdown) {
1323 encryptOnShutdown();
1325 if (decryptOnShutdown) {
1326 decryptOnShutdown();
1329 Global.getFileManager().purgeResDirectory(false);
1330 } catch (InitializationException e) {
1331 System.out.println(tr("Empty res directory purge failed"));
1332 e.printStackTrace();
1334 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
1338 private void closeNeverNote() {
1342 public void setMessage(String s) {
1344 logger.log(logger.HIGH, "Entering NeverNote.setMessage");
1346 System.out.println("*** ERROR *** " +s);
1348 if (statusBar != null) {
1351 logger.log(logger.HIGH, "Message: " +s);
1352 statusBar.showMessage(s);
1353 if (emitLog != null)
1356 if (messageTimer != null) {
1357 messageTimer.stop();
1358 messageTimer.setSingleShot(true);
1359 messageTimer.start();
1364 logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
1367 private void clearMessage() {
1368 statusBar.clearMessage();
1372 private void waitCursor(boolean wait) {
1374 if (QApplication.overrideCursor() == null)
1375 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1378 if (QApplication.overrideCursor() != null)
1379 QApplication.restoreOverrideCursor();
1381 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.ArrowCursor));
1383 listManager.refreshCounters();
1386 private void setupIndexListeners() {
1387 // indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1388 // indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1389 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1390 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1392 private void setupSyncSignalListeners() {
1393 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1394 syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1395 syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1396 syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1397 syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1399 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1400 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1401 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1403 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1404 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1405 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1406 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1407 syncRunner.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1409 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1412 private void setupBrowserSignalListeners() {
1413 setupBrowserWindowListeners(browserWindow, true);
1416 private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1417 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1418 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1419 browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1420 if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1421 browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1422 browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1423 browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1424 browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1425 browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1426 browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1427 browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1428 browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1429 browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1430 browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1431 browser.blockApplication.connect(this, "blockApplication(BrowserWindow)");
1432 browser.unblockApplication.connect(this, "unblockApplication()");
1433 if (master) browser.focusLost.connect(this, "saveNote()");
1434 browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1435 browser.evernoteLinkClicked.connect(this, "evernoteLinkClick(String, String)");
1438 //**************************************************
1440 //**************************************************
1441 private void setupShortcut(QShortcut action, String text) {
1442 if (!Global.shortcutKeys.containsAction(text))
1444 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
1447 //***************************************************************
1448 //***************************************************************
1449 //* Settings and look & feel
1450 //***************************************************************
1451 //***************************************************************
1452 @SuppressWarnings("unused")
1453 private void settings() {
1454 logger.log(logger.HIGH, "Entering NeverNote.settings");
1456 saveNoteColumnPositions();
1457 saveNoteIndexWidth();
1459 ConfigDialog settings = new ConfigDialog(this);
1460 String dateFormat = Global.getDateFormat();
1461 String timeFormat = Global.getTimeFormat();
1463 indexTime = 1000*Global.getIndexThreadSleepInterval();
1464 indexTimer.start(indexTime); // reset indexing timer
1467 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1468 indexRunner.indexNoteBody = Global.indexNoteBody();
1469 indexRunner.indexNoteTitle = Global.indexNoteTitle();
1470 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
1471 indexRunner.indexImageRecognition = Global.indexImageRecognition();
1472 if (Global.showTrayIcon() || Global.minimizeOnClose())
1477 if (menuBar.showEditorBar.isChecked()){
1479 for(int i = 0; i < tabBrowser.count(); i++){
1480 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
1481 showEditorButtons(browser);
1486 // Reset the save timer
1487 if (Global.getAutoSaveInterval() > 0)
1488 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1493 // Set special reloads
1494 if (settings.getDebugPage().reloadSharedNotebooksClicked()) {
1495 conn.executeSql("Delete from LinkedNotebook");
1496 conn.executeSql("delete from SharedNotebook");
1497 conn.executeSql("Delete from Notebook where linked=true");
1498 conn.executeSql("Insert into Sync (key, value) values ('FullLinkedNotebookSync', 'true')");
1499 conn.executeSql("Insert into Sync (key, value) values ('FullSharedNotebookSync', 'true')");
1504 readOnlyCache.clear();
1505 inkNoteCache.clear();
1506 noteIndexUpdated(true);
1508 logger.log(logger.HIGH, "Leaving NeverNote.settings");
1510 // Restore things to the way they were
1511 private void restoreWindowState(boolean mainWindow) {
1512 // We need to name things or this doesn't work.
1513 setObjectName("NeverNote");
1514 restoreState(Global.restoreState(objectName()));
1515 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1516 browserIndexSplitter.setObjectName("browserIndexSplitter");
1517 leftSplitter1.setObjectName("leftSplitter1");
1519 rensoNoteListDock.setObjectName("rensoNoteListDock");
1521 // Restore the actual positions.
1523 restoreGeometry(Global.restoreGeometry(objectName()));
1524 mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1525 browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1526 leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1528 rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
1531 // Save window positions for the next start
1532 private void saveWindowState() {
1533 Global.saveGeometry(objectName(), saveGeometry());
1534 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1535 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1536 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1537 Global.saveState(objectName(), saveState());
1539 Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
1541 // Load the style sheet
1542 private void loadStyleSheet() {
1543 String styleSheetName = "default.qss";
1544 if (Global.getStyle().equalsIgnoreCase("cleanlooks"))
1545 styleSheetName = "default-cleanlooks.qss";
1546 String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
1547 QFile file = new QFile(fileName);
1549 // If a user default.qss doesn't exist, we use the one shipped with NeverNote
1550 if (!file.exists()) {
1551 fileName = Global.getFileManager().getQssDirPath(styleSheetName);
1552 file = new QFile(fileName);
1554 file.open(OpenModeFlag.ReadOnly);
1555 String styleSheet = file.readAll().toString();
1557 setStyleSheet(styleSheet);
1559 // Save column positions for the next time
1560 private void saveNoteColumnPositions() {
1561 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1562 Global.setColumnPosition("noteTableCreationPosition", position);
1563 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1564 Global.setColumnPosition("noteTableTagPosition", position);
1565 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1566 Global.setColumnPosition("noteTableNotebookPosition", position);
1567 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1568 Global.setColumnPosition("noteTableChangedPosition", position);
1569 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1570 Global.setColumnPosition("noteTableAuthorPosition", position);
1571 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1572 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1573 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1574 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1575 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1576 Global.setColumnPosition("noteTableTitlePosition", position);
1577 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1578 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1579 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1580 Global.setColumnPosition("noteTableGuidPosition", position);
1581 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1582 Global.setColumnPosition("noteTableThumbnailPosition", position);
1583 position = noteTableView.header.visualIndex(Global.noteTablePinnedPosition);
1584 Global.setColumnPosition("noteTablePinnedPosition", position);
1587 // Save column widths for the next time
1588 private void saveNoteIndexWidth() {
1590 width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1591 Global.setColumnWidth("noteTableCreationPosition", width);
1592 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1593 Global.setColumnWidth("noteTableChangedPosition", width);
1594 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1595 Global.setColumnWidth("noteTableGuidPosition", width);
1596 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1597 Global.setColumnWidth("noteTableNotebookPosition", width);
1598 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1599 Global.setColumnWidth("noteTableTagPosition", width);
1600 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1601 Global.setColumnWidth("noteTableTitlePosition", width);
1602 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1603 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1604 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1605 Global.setColumnWidth("noteTableAuthorPosition", width);
1606 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1607 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1608 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1609 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1610 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1611 Global.setColumnWidth("noteTableThumbnailPosition", width);
1612 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1613 Global.setColumnWidth("noteTableGuidPosition", width);
1614 width = noteTableView.getColumnWidth(Global.noteTablePinnedPosition);
1615 Global.setColumnWidth("noteTablePinnedPosition", width);
1618 @SuppressWarnings("unused")
1619 private void toggleSearchWindow() {
1620 logger.log(logger.HIGH, "Entering NeverNote.toggleSearchWindow");
1621 searchLayout.toggleSearchField();
1622 menuBar.hideSearch.setChecked(searchField.isVisible());
1623 Global.saveWindowVisible("searchField", searchField.isVisible());
1624 logger.log(logger.HIGH, "Leaving NeverNote.toggleSearchWindow");
1626 @SuppressWarnings("unused")
1627 private void toggleQuotaWindow() {
1628 logger.log(logger.HIGH, "Entering NeverNote.toggleQuotaWindow");
1629 searchLayout.toggleQuotaBar();
1630 menuBar.hideQuota.setChecked(quotaBar.isVisible());
1631 Global.saveWindowVisible("quota", quotaBar.isVisible());
1632 logger.log(logger.HIGH, "Leaving NeverNote.toggleQuotaWindow");
1634 @SuppressWarnings("unused")
1635 private void toggleZoomWindow() {
1636 logger.log(logger.HIGH, "Entering NeverNote.toggleZoomWindow");
1637 searchLayout.toggleZoom();
1638 menuBar.hideZoom.setChecked(zoomSpinner.isVisible());
1639 Global.saveWindowVisible("zoom", zoomSpinner.isVisible());
1640 logger.log(logger.HIGH, "Leaving NeverNote.toggleZoomWindow");
1645 //***************************************************************
1646 //***************************************************************
1647 //** These functions deal with Notebook menu items
1648 //***************************************************************
1649 //***************************************************************
1650 // Setup the tree containing the user's notebooks.
1651 private void initializeNotebookTree() {
1652 logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1653 // notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1654 notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
1655 listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1656 logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1658 // Listener when a notebook is selected
1659 private void notebookTreeSelection() {
1660 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1661 noteTableView.proxyModel.blocked = true;
1664 clearAttributeFilter();
1665 clearSavedSearchFilter();
1666 if (Global.mimicEvernoteInterface) {
1668 //searchField.clear();
1669 searchField.clearEditText();
1671 menuBar.noteRestoreAction.setVisible(false);
1672 menuBar.notebookEditAction.setEnabled(true);
1673 menuBar.notebookDeleteAction.setEnabled(true);
1674 menuBar.notebookPublishAction.setEnabled(true);
1675 menuBar.notebookShareAction.setEnabled(true);
1676 menuBar.notebookIconAction.setEnabled(true);
1677 menuBar.notebookStackAction.setEnabled(true);
1679 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
1680 if (!rensoNoteListDock.isEnabled()) {
1681 rensoNoteListDock.setEnabled(true);
1684 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1685 selectedNotebookGUIDs.clear();
1687 String stackName = "";
1688 if (selections.size() > 0) {
1689 guid = (selections.get(0).text(2));
1690 stackName = selections.get(0).text(0);
1692 if (!Global.mimicEvernoteInterface) {
1693 // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1694 if (selections.size()==0) {
1695 selectedNotebookGUIDs.clear();
1696 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1697 selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1699 menuBar.notebookEditAction.setEnabled(false);
1700 menuBar.notebookDeleteAction.setEnabled(false);
1701 menuBar.notebookStackAction.setEnabled(false);
1702 menuBar.notebookIconAction.setEnabled(false);
1705 if (!guid.equals("") && !guid.equals("STACK")) {
1706 selectedNotebookGUIDs.add(guid);
1707 menuBar.notebookIconAction.setEnabled(true);
1709 menuBar.notebookIconAction.setEnabled(true);
1710 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1711 Notebook book = listManager.getNotebookIndex().get(j);
1712 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1713 selectedNotebookGUIDs.add(book.getGuid());
1716 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1717 listManager.loadNotesIndex();
1718 noteIndexUpdated(false);
1719 refreshEvernoteNote(true);
1720 listManager.refreshCounters = true;
1721 listManager.refreshCounters();
1722 if (selectedNotebookGUIDs.size() == 1) {
1723 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1724 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1726 noteTableView.proxyModel.blocked = true;
1728 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1730 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1733 noteTableView.proxyModel.blocked = false;
1734 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1737 private void clearNotebookFilter() {
1738 notebookTree.blockSignals(true);
1739 notebookTree.clearSelection();
1740 menuBar.noteRestoreAction.setVisible(false);
1741 menuBar.notebookEditAction.setEnabled(false);
1742 menuBar.notebookDeleteAction.setEnabled(false);
1743 selectedNotebookGUIDs.clear();
1744 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1745 notebookTree.blockSignals(false);
1747 // Triggered when the notebook DB has been updated
1748 private void notebookIndexUpdated() {
1749 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1751 // Get the possible icons
1752 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1753 notebookTree.setIcons(icons);
1755 if (selectedNotebookGUIDs == null)
1756 selectedNotebookGUIDs = new ArrayList<String>();
1757 List<Notebook> books = conn.getNotebookTable().getAll();
1758 for (int i=books.size()-1; i>=0; i--) {
1759 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1760 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1762 j=listManager.getArchiveNotebookIndex().size();
1768 listManager.countNotebookResults(listManager.getNoteIndex());
1769 notebookTree.blockSignals(true);
1770 notebookTree.load(books, listManager.getLocalNotebooks());
1771 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1772 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1774 selectedNotebookGUIDs.remove(i);
1776 listManager.refreshCounters = true;
1777 listManager.refreshCounters();
1778 notebookTree.blockSignals(false);
1780 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1782 // Show/Hide note information
1783 @SuppressWarnings("unused")
1784 private void toggleNotebookWindow() {
1785 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1786 searchLayout.toggleNotebook();
1787 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1788 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1789 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1791 // Add a new notebook
1792 @SuppressWarnings("unused")
1793 private void addNotebook() {
1794 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1795 NotebookEdit edit = new NotebookEdit();
1796 edit.setNotebooks(listManager.getNotebookIndex());
1799 if (!edit.okPressed())
1802 Calendar currentTime = new GregorianCalendar();
1803 Long l = new Long(currentTime.getTimeInMillis());
1804 String randint = new String(Long.toString(l));
1806 Notebook newBook = new Notebook();
1807 newBook.setUpdateSequenceNum(0);
1808 newBook.setGuid(randint);
1809 newBook.setName(edit.getNotebook());
1810 newBook.setServiceCreated(new Date().getTime());
1811 newBook.setServiceUpdated(new Date().getTime());
1812 newBook.setDefaultNotebook(false);
1813 newBook.setPublished(false);
1815 listManager.getNotebookIndex().add(newBook);
1817 listManager.getLocalNotebooks().add(newBook.getGuid());
1818 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1819 notebookIndexUpdated();
1820 listManager.countNotebookResults(listManager.getNoteIndex());
1821 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1822 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1824 // Edit an existing notebook
1825 @SuppressWarnings("unused")
1826 private void stackNotebook() {
1827 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1828 StackNotebook edit = new StackNotebook();
1830 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1831 QTreeWidgetItem currentSelection;
1832 for (int i=0; i<selections.size(); i++) {
1833 currentSelection = selections.get(0);
1834 String guid = currentSelection.text(2);
1835 if (guid.equalsIgnoreCase("")) {
1836 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1839 if (guid.equalsIgnoreCase("STACK")) {
1840 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1845 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1850 if (!edit.okPressed())
1853 String stack = edit.getStackName();
1855 for (int i=0; i<selections.size(); i++) {
1856 currentSelection = selections.get(i);
1857 String guid = currentSelection.text(2);
1858 listManager.updateNotebookStack(guid, stack);
1860 notebookIndexUpdated();
1861 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1863 // Edit an existing notebook
1864 @SuppressWarnings("unused")
1865 private void editNotebook() {
1866 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1867 NotebookEdit edit = new NotebookEdit();
1869 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1870 QTreeWidgetItem currentSelection;
1871 currentSelection = selections.get(0);
1872 edit.setNotebook(currentSelection.text(0));
1874 String guid = currentSelection.text(2);
1875 if (!guid.equalsIgnoreCase("STACK")) {
1876 edit.setTitle(tr("Edit Notebook"));
1877 edit.setNotebooks(listManager.getNotebookIndex());
1878 edit.setLocalCheckboxEnabled(false);
1879 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1880 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1881 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1882 i=listManager.getNotebookIndex().size();
1886 edit.setTitle(tr("Edit Stack"));
1887 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1888 edit.hideLocalCheckbox();
1889 edit.hideDefaultCheckbox();
1894 if (!edit.okPressed())
1898 if (guid.equalsIgnoreCase("STACK")) {
1899 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1900 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1901 if (listManager.getNotebookIndex().get(j).getStack() != null &&
1902 listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1903 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1905 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1906 currentSelection.setText(0, edit.getNotebook());
1910 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1911 currentSelection.setText(0, edit.getNotebook());
1913 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1914 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1915 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1916 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1917 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1918 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1919 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1920 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1922 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1923 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1924 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1925 linkedNotebook.setShareName(edit.getNotebook());
1926 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1928 i=listManager.getNotebookIndex().size();
1932 // Build a list of non-closed notebooks
1933 List<Notebook> nbooks = new ArrayList<Notebook>();
1934 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1935 boolean found=false;
1936 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1937 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1941 nbooks.add(listManager.getNotebookIndex().get(i));
1945 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1946 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1947 browserWindow.setNotebookList(filteredBooks);
1948 Iterator<String> set = externalWindows.keySet().iterator();
1949 while(set.hasNext())
1950 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1953 Iterator<Integer>it = tabWindows.keySet().iterator();
1954 while (it.hasNext()) {
1955 tabWindows.get(it.next()).getBrowserWindow()
1956 .setNotebookList(filteredBooks);
1959 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1961 // Publish a notebook
1962 @SuppressWarnings("unused")
1963 private void publishNotebook() {
1964 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1965 QTreeWidgetItem currentSelection;
1966 currentSelection = selections.get(0);
1967 String guid = currentSelection.text(2);
1969 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1974 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1975 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1976 n = listManager.getNotebookIndex().get(i);
1978 i = listManager.getNotebookIndex().size();
1984 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1987 if (!publish.okClicked())
1990 Publishing p = publish.getPublishing();
1991 boolean isPublished = !publish.isStopPressed();
1992 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1993 n.setPublished(isPublished);
1995 listManager.getNotebookIndex().set(position, n);
1996 notebookIndexUpdated();
1998 // Publish a notebook
1999 @SuppressWarnings("unused")
2000 private void shareNotebook() {
2001 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2002 QTreeWidgetItem currentSelection;
2003 currentSelection = selections.get(0);
2004 String guid = currentSelection.text(2);
2006 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
2010 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2011 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
2012 n = listManager.getNotebookIndex().get(i);
2013 i = listManager.getNotebookIndex().size();
2017 String authToken = null;
2018 if (syncRunner.isConnected)
2019 authToken = syncRunner.authToken;
2020 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
2025 // Delete an existing notebook
2026 @SuppressWarnings("unused")
2027 private void deleteNotebook() {
2028 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2029 boolean stacksFound = false;
2030 boolean notebooksFound = false;
2031 boolean assigned = false;
2032 // Check if any notes have this notebook
2033 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2034 for (int i=0; i<selections.size(); i++) {
2035 QTreeWidgetItem currentSelection;
2036 currentSelection = selections.get(i);
2037 String guid = currentSelection.text(2);
2038 if (!guid.equalsIgnoreCase("STACK")) {
2039 notebooksFound = true;
2040 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
2041 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
2042 if (noteGuid.equals(guid)) {
2044 j=listManager.getNoteIndex().size();
2045 i=selections.size();
2053 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2054 "Please delete the notes or move them to another notebook before deleting any notebooks."));
2058 if (conn.getNotebookTable().getAll().size() == 1) {
2059 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2063 // If all notebooks are clear, verify the delete
2064 String msg1 = new String(tr("Delete selected notebooks?"));
2065 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2066 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2067 " not deleted unless selected?"));
2069 if (stacksFound && notebooksFound)
2071 if (!stacksFound && notebooksFound)
2073 if (stacksFound && !notebooksFound)
2075 if (QMessageBox.question(this, tr("Confirmation"), msg,
2076 QMessageBox.StandardButton.Yes,
2077 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2081 // If confirmed, delete the notebook
2082 for (int i=selections.size()-1; i>=0; i--) {
2083 QTreeWidgetItem currentSelection;
2084 currentSelection = selections.get(i);
2085 String guid = currentSelection.text(2);
2086 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2087 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2088 listManager.renameStack(currentSelection.text(0), "");
2090 conn.getNotebookTable().expungeNotebook(guid, true);
2091 listManager.deleteNotebook(guid);
2095 notebookIndexUpdated();
2096 // notebookTreeSelection();
2097 // notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2098 // listManager.countNotebookResults(listManager.getNoteIndex());
2099 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2101 // A note's notebook has been updated
2102 @SuppressWarnings("unused")
2103 private void updateNoteNotebook(String guid, String notebookGuid) {
2104 // ICHANGED 同じノートブックに入れられたノート間の履歴を登録
2105 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2107 // Update the list manager
2108 listManager.updateNoteNotebook(guid, notebookGuid);
2109 listManager.countNotebookResults(listManager.getNoteIndex());
2110 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
2112 // Find the name of the notebook
2113 String notebookName = null;
2114 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2115 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2116 notebookName = listManager.getNotebookIndex().get(i).getName();
2121 // If we found the name, update the browser window
2122 if (notebookName != null) {
2123 updateListNoteNotebook(guid, notebookName);
2124 if (guid.equals(currentNoteGuid)) {
2125 int pos = browserWindow.notebookBox.findText(notebookName);
2127 browserWindow.notebookBox.setCurrentIndex(pos);
2131 // If we're dealing with the current note, then we need to be sure and update the notebook there
2132 if (guid.equals(currentNoteGuid)) {
2133 if (currentNote != null) {
2134 currentNote.setNotebookGuid(notebookGuid);
2138 // Open/close notebooks
2139 @SuppressWarnings("unused")
2140 private void closeNotebooks() {
2141 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2143 if (!na.okClicked())
2147 listManager.getArchiveNotebookIndex().clear();
2149 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2150 String text = na.getClosedBookList().takeItem(i).text();
2151 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2152 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2153 Notebook n = listManager.getNotebookIndex().get(j);
2154 conn.getNotebookTable().setArchived(n.getGuid(),true);
2155 listManager.getArchiveNotebookIndex().add(n);
2156 j=listManager.getNotebookIndex().size();
2161 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2162 String text = na.getOpenBookList().takeItem(i).text();
2163 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2164 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2165 Notebook n = listManager.getNotebookIndex().get(j);
2166 conn.getNotebookTable().setArchived(n.getGuid(),false);
2167 j=listManager.getNotebookIndex().size();
2171 notebookTreeSelection();
2172 listManager.loadNotesIndex();
2173 notebookIndexUpdated();
2174 noteIndexUpdated(false);
2175 reloadTagTree(true);
2176 // noteIndexUpdated(false);
2178 // Build a list of non-closed notebooks
2179 List<Notebook> nbooks = new ArrayList<Notebook>();
2180 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2181 boolean found=false;
2182 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2183 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2187 nbooks.add(listManager.getNotebookIndex().get(i));
2190 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2191 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2192 browserWindow.setNotebookList(filteredBooks);
2194 // Update any external windows
2195 Iterator<String> set = externalWindows.keySet().iterator();
2196 while(set.hasNext())
2197 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2201 Iterator<Integer> it = tabWindows.keySet().iterator();
2202 while (it.hasNext()) {
2203 tabWindows.get(it.next()).getBrowserWindow()
2204 .setNotebookList(filteredBooks);
2209 // Change the notebook's icon
2210 @SuppressWarnings("unused")
2211 private void setNotebookIcon() {
2212 boolean stackSelected = false;
2213 boolean allNotebookSelected = false;
2215 QTreeWidgetItem currentSelection;
2216 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2217 if (selections.size() == 0)
2220 currentSelection = selections.get(0);
2221 String guid = currentSelection.text(2);
2222 if (guid.equalsIgnoreCase(""))
2223 allNotebookSelected = true;
2224 if (guid.equalsIgnoreCase("STACK"))
2225 stackSelected = true;
2227 QIcon currentIcon = currentSelection.icon(0);
2231 if (!stackSelected && !allNotebookSelected) {
2232 icon = conn.getNotebookTable().getIcon(guid);
2234 dialog = new SetIcon(currentIcon, saveLastPath);
2235 dialog.setUseDefaultIcon(true);
2237 dialog = new SetIcon(icon, saveLastPath);
2238 dialog.setUseDefaultIcon(false);
2241 if (stackSelected) {
2242 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2244 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
2247 dialog = new SetIcon(currentIcon, saveLastPath);
2248 dialog.setUseDefaultIcon(true);
2250 dialog = new SetIcon(icon, saveLastPath);
2251 dialog.setUseDefaultIcon(false);
2255 if (dialog.okPressed()) {
2256 saveLastPath = dialog.getPath();
2258 QIcon newIcon = dialog.getIcon();
2259 if (stackSelected) {
2260 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2261 if (newIcon == null) {
2262 newIcon = new QIcon(iconPath+"books2.png");
2264 currentSelection.setIcon(0,newIcon);
2267 if (allNotebookSelected) {
2268 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2269 if (newIcon == null) {
2270 newIcon = new QIcon(iconPath+"notebook-green.png");
2272 currentSelection.setIcon(0,newIcon);
2275 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2276 if (newIcon == null) {
2277 boolean isPublished = false;;
2278 boolean found = false;
2279 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2280 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2281 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2285 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2287 currentSelection.setIcon(0, newIcon);
2293 //***************************************************************
2294 //***************************************************************
2295 //** These functions deal with Tag menu items
2296 //***************************************************************
2297 //***************************************************************
2298 // Add a new notebook
2299 @SuppressWarnings("unused")
2300 private void addTag() {
2301 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2302 TagEdit edit = new TagEdit();
2303 edit.setTagList(listManager.getTagIndex());
2305 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2306 QTreeWidgetItem currentSelection = null;
2307 if (selections.size() > 0) {
2308 currentSelection = selections.get(0);
2309 edit.setParentTag(currentSelection.text(0));
2314 if (!edit.okPressed())
2317 Calendar currentTime = new GregorianCalendar();
2318 Long l = new Long(currentTime.getTimeInMillis());
2319 String randint = new String(Long.toString(l));
2321 Tag newTag = new Tag();
2322 newTag.setUpdateSequenceNum(0);
2323 newTag.setGuid(randint);
2324 newTag.setName(edit.getTag());
2325 if (edit.getParentTag().isChecked()) {
2326 newTag.setParentGuid(currentSelection.text(2));
2327 newTag.setParentGuidIsSet(true);
2328 currentSelection.setExpanded(true);
2330 conn.getTagTable().addTag(newTag, true);
2331 listManager.getTagIndex().add(newTag);
2332 reloadTagTree(true);
2334 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2336 @SuppressWarnings("unused")
2337 private void reloadTagTree() {
2338 reloadTagTree(false);
2340 private void reloadTagTree(boolean reload) {
2341 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2342 tagIndexUpdated(reload);
2343 boolean filter = false;
2345 listManager.countTagResults(listManager.getNoteIndex());
2346 if (notebookTree.selectedItems().size() > 0
2347 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2349 if (tagTree.selectedItems().size() > 0)
2351 tagTree.showAllTags(!filter);
2352 tagIndexUpdated(false);
2353 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2355 // Edit an existing tag
2356 @SuppressWarnings("unused")
2357 private void editTag() {
2358 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2359 TagEdit edit = new TagEdit();
2360 edit.setTitle("Edit Tag");
2361 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2362 QTreeWidgetItem currentSelection;
2363 currentSelection = selections.get(0);
2364 edit.setTag(currentSelection.text(0));
2365 edit.setTagList(listManager.getTagIndex());
2368 if (!edit.okPressed())
2371 String guid = currentSelection.text(2);
2372 currentSelection.setText(0,edit.getTag());
2374 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2375 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2376 listManager.getTagIndex().get(i).setName(edit.getTag());
2377 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2378 updateListTagName(guid);
2379 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2380 browserWindow.setTag(getTagNamesForNote(currentNote));
2381 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2385 listManager.reloadNoteTagNames(guid, edit.getTag());
2386 noteIndexUpdated(true);
2387 refreshEvernoteNote(true);
2388 browserWindow.setTag(getTagNamesForNote(currentNote));
2389 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2391 // Delete an existing tag
2392 @SuppressWarnings("unused")
2393 private void deleteTag() {
2394 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2396 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2397 QMessageBox.StandardButton.Yes,
2398 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2402 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2403 for (int i=selections.size()-1; i>=0; i--) {
2404 QTreeWidgetItem currentSelection;
2405 currentSelection = selections.get(i);
2406 removeTagItem(currentSelection.text(2));
2408 tagIndexUpdated(true);
2410 listManager.countTagResults(listManager.getNoteIndex());
2411 // tagTree.updateCounts(listManager.getTagCounter());
2412 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2414 // Remove a tag tree item. Go recursively down & remove the children too
2415 private void removeTagItem(String guid) {
2416 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
2417 String parent = listManager.getTagIndex().get(j).getParentGuid();
2418 if (parent != null && parent.equals(guid)) {
2419 //Remove this tag's children
2420 removeTagItem(listManager.getTagIndex().get(j).getGuid());
2423 //Now, remove this tag
2424 removeListTagName(guid);
2425 conn.getTagTable().expungeTag(guid, true);
2426 for (int a=0; a<listManager.getTagIndex().size(); a++) {
2427 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2428 listManager.getTagIndex().remove(a);
2433 // Setup the tree containing the user's tags
2434 private void initializeTagTree() {
2435 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2436 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2437 // tagTree.itemClicked.connect(this, "tagTreeSelection()");
2438 tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2439 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2440 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2442 // Listener when a tag is selected
2443 private void tagTreeSelection() {
2444 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2447 clearAttributeFilter();
2448 clearSavedSearchFilter();
2450 menuBar.noteRestoreAction.setVisible(false);
2452 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2453 if (!rensoNoteListDock.isEnabled()) {
2454 rensoNoteListDock.setEnabled(true);
2457 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2458 QTreeWidgetItem currentSelection;
2459 selectedTagGUIDs.clear();
2460 for (int i=0; i<selections.size(); i++) {
2461 currentSelection = selections.get(i);
2462 selectedTagGUIDs.add(currentSelection.text(2));
2464 if (selections.size() > 0) {
2465 menuBar.tagEditAction.setEnabled(true);
2466 menuBar.tagDeleteAction.setEnabled(true);
2467 menuBar.tagIconAction.setEnabled(true);
2470 menuBar.tagEditAction.setEnabled(false);
2471 menuBar.tagDeleteAction.setEnabled(false);
2472 menuBar.tagIconAction.setEnabled(true);
2474 if (selections.size() > 1)
2475 menuBar.tagMergeAction.setEnabled(true);
2477 menuBar.tagMergeAction.setEnabled(false);
2478 listManager.setSelectedTags(selectedTagGUIDs);
2479 listManager.loadNotesIndex();
2480 noteIndexUpdated(false);
2481 refreshEvernoteNote(true);
2482 listManager.refreshCounters = true;
2483 listManager.refreshCounters();
2484 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2486 // trigger the tag index to be refreshed
2487 @SuppressWarnings("unused")
2488 private void tagIndexUpdated() {
2489 tagIndexUpdated(true);
2491 private void tagIndexUpdated(boolean reload) {
2492 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2493 if (selectedTagGUIDs == null)
2494 selectedTagGUIDs = new ArrayList<String>();
2496 listManager.reloadTagIndex();
2498 tagTree.blockSignals(true);
2500 tagTree.setIcons(conn.getTagTable().getAllIcons());
2501 tagTree.load(listManager.getTagIndex());
2504 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2505 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2507 selectedTagGUIDs.remove(i);
2509 tagTree.blockSignals(false);
2511 browserWindow.setTag(getTagNamesForNote(currentNote));
2512 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2514 // Show/Hide note information
2515 @SuppressWarnings("unused")
2516 private void toggleTagWindow() {
2517 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2518 if (tagTree.isVisible())
2522 menuBar.hideTags.setChecked(tagTree.isVisible());
2523 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2524 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2526 // A note's tags have been updated
2527 @SuppressWarnings("unused")
2528 private void updateNoteTags(String guid, List<String> tags) {
2529 // Save any new tags. We'll need them later.
2530 List<String> newTags = new ArrayList<String>();
2531 for (int i=0; i<tags.size(); i++) {
2532 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2533 newTags.add(tags.get(i));
2536 listManager.saveNoteTags(guid, tags, true);
2537 listManager.countTagResults(listManager.getNoteIndex());
2538 StringBuffer names = new StringBuffer("");
2539 for (int i=0; i<tags.size(); i++) {
2540 names = names.append(tags.get(i));
2541 if (i<tags.size()-1) {
2542 names.append(Global.tagDelimeter + " ");
2545 browserWindow.setTag(names.toString());
2548 for (TabBrowse tab: tabWindows.values()) {
2549 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
2550 int index = tabBrowser.indexOf(tab);
2551 noteDirty.put(index, true);
2556 // Now, we need to add any new tags to the tag tree
2557 for (int i=0; i<newTags.size(); i++)
2558 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2560 // Get a string containing all tag names for a note
2561 private String getTagNamesForNote(Note n) {
2562 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2563 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2565 StringBuffer buffer = new StringBuffer(100);
2566 Vector<String> v = new Vector<String>();
2567 List<String> guids = n.getTagGuids();
2572 for (int i=0; i<guids.size(); i++) {
2573 v.add(listManager.getTagNameByGuid(guids.get(i)));
2575 Comparator<String> comparator = Collections.reverseOrder();
2576 Collections.sort(v,comparator);
2577 Collections.reverse(v);
2579 for (int i = 0; i<v.size(); i++) {
2581 buffer.append(", ");
2582 buffer.append(v.get(i));
2585 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2586 return buffer.toString();
2588 // Tags were added via dropping notes from the note list
2589 @SuppressWarnings("unused")
2590 private void tagsAdded(String noteGuid, String tagGuid) {
2591 String tagName = null;
2592 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2593 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2594 tagName = listManager.getTagIndex().get(i).getName();
2595 i=listManager.getTagIndex().size();
2598 if (tagName == null)
2601 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2602 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2603 List<String> tagNames = new ArrayList<String>();
2604 tagNames.add(new String(tagName));
2605 Note n = listManager.getMasterNoteIndex().get(i);
2606 for (int j=0; j<n.getTagNames().size(); j++) {
2607 tagNames.add(new String(n.getTagNames().get(j)));
2609 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2610 if (n.getGuid().equals(currentNoteGuid)) {
2611 Collections.sort(tagNames);
2612 String display = "";
2613 for (int j=0; j<tagNames.size(); j++) {
2614 display = display+tagNames.get(j);
2615 if (j+2<tagNames.size())
2616 display = display+Global.tagDelimeter+" ";
2618 browserWindow.setTag(display);
2620 i=listManager.getMasterNoteIndex().size();
2625 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2627 private void clearTagFilter() {
2628 tagTree.blockSignals(true);
2629 tagTree.clearSelection();
2630 menuBar.noteRestoreAction.setVisible(false);
2631 menuBar.tagEditAction.setEnabled(false);
2632 menuBar.tagMergeAction.setEnabled(false);
2633 menuBar.tagDeleteAction.setEnabled(false);
2634 menuBar.tagIconAction.setEnabled(false);
2635 selectedTagGUIDs.clear();
2636 listManager.setSelectedTags(selectedTagGUIDs);
2637 tagTree.blockSignals(false);
2639 // Change the icon for a tag
2640 @SuppressWarnings("unused")
2641 private void setTagIcon() {
2642 QTreeWidgetItem currentSelection;
2643 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2644 if (selections.size() == 0)
2647 currentSelection = selections.get(0);
2648 String guid = currentSelection.text(2);
2650 QIcon currentIcon = currentSelection.icon(0);
2651 QIcon icon = conn.getTagTable().getIcon(guid);
2654 dialog = new SetIcon(currentIcon, saveLastPath);
2655 dialog.setUseDefaultIcon(true);
2657 dialog = new SetIcon(icon, saveLastPath);
2658 dialog.setUseDefaultIcon(false);
2661 if (dialog.okPressed()) {
2662 saveLastPath = dialog.getPath();
2663 QIcon newIcon = dialog.getIcon();
2664 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2665 if (newIcon == null)
2666 newIcon = new QIcon(iconPath+"tag.png");
2667 currentSelection.setIcon(0, newIcon);
2672 @SuppressWarnings("unused")
2673 private void mergeTags() {
2674 List<Tag> tags = new ArrayList<Tag>();
2675 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2676 for (int i=0; i<selections.size(); i++) {
2677 Tag record = new Tag();
2678 record.setGuid(selections.get(i).text(2));
2679 record.setName(selections.get(i).text(0));
2683 TagMerge mergeDialog = new TagMerge(tags);
2685 if (!mergeDialog.okClicked())
2687 String newGuid = mergeDialog.getNewTagGuid();
2689 for (int i=0; i<tags.size(); i++) {
2690 if (!tags.get(i).getGuid().equals(newGuid)) {
2691 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2692 for (int j=0; j<noteGuids.size(); j++) {
2693 String noteGuid = noteGuids.get(j);
2694 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2695 if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2696 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2700 listManager.reloadIndexes();
2703 //***************************************************************
2704 //***************************************************************
2705 //** These functions deal with Saved Search menu items
2706 //***************************************************************
2707 //***************************************************************
2708 // Add a new notebook
2709 @SuppressWarnings("unused")
2710 private void addSavedSearch() {
2711 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2712 SavedSearchEdit edit = new SavedSearchEdit();
2713 edit.setSearchList(listManager.getSavedSearchIndex());
2716 if (!edit.okPressed())
2719 Calendar currentTime = new GregorianCalendar();
2720 Long l = new Long(currentTime.getTimeInMillis());
2721 String randint = new String(Long.toString(l));
2723 SavedSearch search = new SavedSearch();
2724 search.setUpdateSequenceNum(0);
2725 search.setGuid(randint);
2726 search.setName(edit.getName());
2727 search.setQuery(edit.getQuery());
2728 search.setFormat(QueryFormat.USER);
2729 listManager.getSavedSearchIndex().add(search);
2730 conn.getSavedSearchTable().addSavedSearch(search, true);
2731 savedSearchIndexUpdated();
2732 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2734 // Edit an existing tag
2735 @SuppressWarnings("unused")
2736 private void editSavedSearch() {
2737 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2738 SavedSearchEdit edit = new SavedSearchEdit();
2739 edit.setTitle(tr("Edit Search"));
2740 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2741 QTreeWidgetItem currentSelection;
2742 currentSelection = selections.get(0);
2743 String guid = currentSelection.text(1);
2744 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2745 edit.setName(currentSelection.text(0));
2746 edit.setQuery(s.getQuery());
2747 edit.setSearchList(listManager.getSavedSearchIndex());
2750 if (!edit.okPressed())
2753 List<SavedSearch> list = listManager.getSavedSearchIndex();
2754 SavedSearch search = null;
2755 boolean found = false;
2756 for (int i=0; i<list.size(); i++) {
2757 search = list.get(i);
2758 if (search.getGuid().equals(guid)) {
2765 search.setName(edit.getName());
2766 search.setQuery(edit.getQuery());
2767 conn.getSavedSearchTable().updateSavedSearch(search, true);
2768 savedSearchIndexUpdated();
2769 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2771 // Delete an existing tag
2772 @SuppressWarnings("unused")
2773 private void deleteSavedSearch() {
2774 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2776 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2777 QMessageBox.StandardButton.Yes,
2778 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2782 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2783 for (int i=selections.size()-1; i>=0; i--) {
2784 QTreeWidgetItem currentSelection;
2785 currentSelection = selections.get(i);
2786 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2787 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2788 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2789 listManager.getSavedSearchIndex().remove(j);
2790 j=listManager.getSavedSearchIndex().size()+1;
2793 selections.remove(i);
2795 savedSearchIndexUpdated();
2796 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2798 // Setup the tree containing the user's tags
2799 private void initializeSavedSearchTree() {
2800 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2801 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2802 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2804 // Listener when a tag is selected
2805 @SuppressWarnings("unused")
2806 private void savedSearchTreeSelection() {
2807 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2809 clearNotebookFilter();
2812 clearAttributeFilter();
2814 String currentGuid = selectedSavedSearchGUID;
2815 menuBar.savedSearchEditAction.setEnabled(true);
2816 menuBar.savedSearchDeleteAction.setEnabled(true);
2817 menuBar.savedSearchIconAction.setEnabled(true);
2819 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2820 if (!rensoNoteListDock.isEnabled()) {
2821 rensoNoteListDock.setEnabled(true);
2824 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2825 QTreeWidgetItem currentSelection;
2826 selectedSavedSearchGUID = "";
2827 for (int i=0; i<selections.size(); i++) {
2828 currentSelection = selections.get(i);
2829 if (currentSelection.text(1).equals(currentGuid)) {
2830 currentSelection.setSelected(false);
2832 selectedSavedSearchGUID = currentSelection.text(1);
2834 // i = selections.size() +1;
2837 // There is the potential for no notebooks to be selected if this
2838 // happens then we make it look like all notebooks were selecetd.
2839 // If that happens, just select the "all notebooks"
2840 if (selections.size()==0) {
2841 clearSavedSearchFilter();
2843 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2845 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2847 private void clearSavedSearchFilter() {
2848 menuBar.savedSearchEditAction.setEnabled(false);
2849 menuBar.savedSearchDeleteAction.setEnabled(false);
2850 menuBar.savedSearchIconAction.setEnabled(false);
2851 savedSearchTree.blockSignals(true);
2852 savedSearchTree.clearSelection();
2853 savedSearchTree.blockSignals(false);
2854 selectedSavedSearchGUID = "";
2855 searchField.setEditText("");
2856 searchPerformed = false;
2857 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2859 // trigger the tag index to be refreshed
2860 private void savedSearchIndexUpdated() {
2861 if (selectedSavedSearchGUID == null)
2862 selectedSavedSearchGUID = new String();
2863 savedSearchTree.blockSignals(true);
2864 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2865 savedSearchTree.load(listManager.getSavedSearchIndex());
2866 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2867 savedSearchTree.blockSignals(false);
2869 // trigger when the saved search selection changes
2870 @SuppressWarnings("unused")
2871 private void updateSavedSearchSelection() {
2872 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2874 menuBar.savedSearchEditAction.setEnabled(true);
2875 menuBar.savedSearchDeleteAction.setEnabled(true);
2876 menuBar.savedSearchIconAction.setEnabled(true);
2877 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2879 if (selections.size() > 0) {
2880 menuBar.savedSearchEditAction.setEnabled(true);
2881 menuBar.savedSearchDeleteAction.setEnabled(true);
2882 menuBar.savedSearchIconAction.setEnabled(true);
2883 selectedSavedSearchGUID = selections.get(0).text(1);
2884 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2885 searchField.setEditText(s.getQuery());
2887 menuBar.savedSearchEditAction.setEnabled(false);
2888 menuBar.savedSearchDeleteAction.setEnabled(false);
2889 menuBar.savedSearchIconAction.setEnabled(false);
2890 selectedSavedSearchGUID = "";
2891 searchField.setEditText("");
2893 searchFieldChanged();
2895 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2899 // Show/Hide note information
2900 @SuppressWarnings("unused")
2901 private void toggleSavedSearchWindow() {
2902 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2903 if (savedSearchTree.isVisible())
2904 savedSearchTree.hide();
2906 savedSearchTree.show();
2907 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2909 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2910 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2912 // Change the icon for a saved search
2913 @SuppressWarnings("unused")
2914 private void setSavedSearchIcon() {
2915 QTreeWidgetItem currentSelection;
2916 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2917 if (selections.size() == 0)
2920 currentSelection = selections.get(0);
2921 String guid = currentSelection.text(1);
2923 QIcon currentIcon = currentSelection.icon(0);
2924 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2927 dialog = new SetIcon(currentIcon, saveLastPath);
2928 dialog.setUseDefaultIcon(true);
2930 dialog = new SetIcon(icon, saveLastPath);
2931 dialog.setUseDefaultIcon(false);
2934 if (dialog.okPressed()) {
2935 saveLastPath = dialog.getPath();
2936 QIcon newIcon = dialog.getIcon();
2937 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2938 if (newIcon == null)
2939 newIcon = new QIcon(iconPath+"search.png");
2940 currentSelection.setIcon(0, newIcon);
2948 //***************************************************************
2949 //***************************************************************
2950 //** These functions deal with Help menu & tool menu items
2951 //***************************************************************
2952 //***************************************************************
2953 // Show database status
2954 @SuppressWarnings("unused")
2955 private void databaseStatus() {
2957 indexRunner.interrupt = true;
2958 int dirty = conn.getNoteTable().getDirtyCount();
2959 int unindexed = conn.getNoteTable().getUnindexedCount();
2960 DatabaseStatus status = new DatabaseStatus();
2961 status.setUnsynchronized(dirty);
2962 status.setUnindexed(unindexed);
2963 status.setNoteCount(conn.getNoteTable().getNoteCount());
2964 status.setNotebookCount(listManager.getNotebookIndex().size());
2965 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2966 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2967 status.setTagCount(listManager.getTagIndex().size());
2968 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2969 status.setWordCount(conn.getWordsTable().getWordCount());
2970 status.setHistoryCount(conn.getHistoryTable().getHistoryCount());
2974 // Compact the database
2975 @SuppressWarnings("unused")
2976 private void compactDatabase() {
2977 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2978 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2979 "but please be aware that depending upon the size of your database this can be time consuming " +
2980 "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
2981 QMessageBox.StandardButton.Yes,
2982 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2985 setMessage("Compacting database.");
2987 listManager.compactDatabase();
2989 setMessage("Database compact is complete.");
2990 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2992 @SuppressWarnings("unused")
2993 private void accountInformation() {
2994 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2995 AccountDialog dialog = new AccountDialog();
2997 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2999 @SuppressWarnings("unused")
3000 private void releaseNotes() {
3001 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
3002 QDialog dialog = new QDialog(this);
3003 QHBoxLayout layout = new QHBoxLayout();
3004 QTextEdit textBox = new QTextEdit();
3005 layout.addWidget(textBox);
3006 textBox.setReadOnly(true);
3007 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
3008 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
3009 QIODevice.OpenModeFlag.Text)))
3011 // ICHANGED 日本語文字化け対策
3012 QTextCodec codec = QTextCodec.codecForName("UTF-8");
3013 QTextStream textStream = new QTextStream(file);
3014 textStream.setCodec(codec);
3015 textBox.setText(textStream.readAll().toString());
3018 dialog.setWindowTitle(tr("Release Notes"));
3019 dialog.setLayout(layout);
3021 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
3023 // Called when user picks Log from the help menu
3024 @SuppressWarnings("unused")
3025 private void logger() {
3026 logger.log(logger.HIGH, "Entering NeverNote.logger");
3027 LogFileDialog dialog = new LogFileDialog(emitLog);
3029 logger.log(logger.HIGH, "Leaving NeverNote.logger");
3031 // Menu option "help/about" was selected
3032 @SuppressWarnings("unused")
3033 private void about() {
3034 logger.log(logger.HIGH, "Entering NeverNote.about");
3035 // ICHANGED based on...の記述を付加
3036 QMessageBox.about(this,
3037 tr("About NeighborNote"),
3038 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
3039 +Global.version + "(based on NixNote 1.5)"
3042 +"Open Source Evernote Client.<br><br>"
3043 +"Licensed under GPL v2. <br><hr><br>"
3044 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
3045 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
3046 +"PDFRenderer is licened under the LGPL<br>"
3047 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3048 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3049 +"Jazzy is licened under the LGPL<br>"
3050 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3051 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3052 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3053 logger.log(logger.HIGH, "Leaving NeverNote.about");
3055 // Hide the entire left hand side
3056 @SuppressWarnings("unused")
3057 private void toggleLeftSide() {
3060 hidden = !menuBar.hideLeftSide.isChecked();
3061 menuBar.hideLeftSide.setChecked(!hidden);
3064 leftSplitter1.setHidden(true);
3066 leftSplitter1.setHidden(false);
3068 Global.saveWindowVisible("leftPanel", hidden);
3071 public void checkForUpdates() {
3072 // Send off thread to check for a new version
3073 versionChecker = new QNetworkAccessManager(this);
3074 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3075 QNetworkRequest request = new QNetworkRequest();
3076 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3077 versionChecker.get(request);
3079 @SuppressWarnings("unused")
3080 private void upgradeFileRead(QNetworkReply reply) {
3081 if (!reply.isReadable())
3084 String winVersion = Global.version;
3085 String osxVersion = Global.version;
3086 String linuxVersion = Global.version;
3087 String linux64Version = Global.version;
3088 String version = Global.version;
3090 // Determine the versions available
3091 QByteArray data = reply.readLine();
3092 while (data != null && !reply.atEnd()) {
3093 String line = data.toString();
3095 if (line.contains(":"))
3096 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3099 if (line.toLowerCase().contains("windows"))
3100 winVersion = lineVersion;
3101 else if (line.toLowerCase().contains("os-x"))
3102 osxVersion = lineVersion;
3103 else if (line.toLowerCase().contains("linux amd64"))
3104 linux64Version = lineVersion;
3105 else if (line.toLowerCase().contains("linux i386"))
3106 linuxVersion = lineVersion;
3107 else if (line.toLowerCase().contains("default"))
3108 version = lineVersion;
3110 // Read the next line
3111 data = reply.readLine();
3114 // Now we need to determine what system we are on.
3115 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3116 version = winVersion;
3117 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3118 version = osxVersion;
3119 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3120 if (System.getProperty("os.arch").contains("amd64") ||
3121 System.getProperty("os.arch").contains("x86_64"))
3122 version = linux64Version;
3124 version = linuxVersion;
3128 for (String validVersion : Global.validVersions) {
3129 if (version.equals(validVersion))
3133 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3135 if (dialog.remindMe())
3136 Global.setCheckVersionUpgrade(true);
3138 Global.setCheckVersionUpgrade(false);
3142 //***************************************************************
3143 //***************************************************************
3144 //** These functions deal with the Toolbar
3145 //***************************************************************
3146 //***************************************************************
3147 @SuppressWarnings("unused")
3148 private void focusSearch() {
3149 searchField.setFocus();
3152 // Text in the search bar has been cleared
3153 private void searchFieldCleared() {
3156 // This is done because we want to force a reload of
3157 // images. Some images we may want to highlight the text.
3158 readOnlyCache.clear();
3159 inkNoteCache.clear();
3161 QWebSettings.setMaximumPagesInCache(0);
3162 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3164 searchField.setEditText("");
3165 saveNoteColumnPositions();
3166 saveNoteIndexWidth();
3167 noteIndexUpdated(true);
3168 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3169 currentNote = listManager.getNoteIndex().get(0);
3170 currentNoteGuid = currentNote.getGuid();
3172 refreshEvernoteNote(true);
3173 if (currentNote != null)
3174 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3176 // text in the search bar changed. We only use this to tell if it was cleared,
3177 // otherwise we trigger off searchFieldChanged.
3178 @SuppressWarnings("unused")
3179 private void searchFieldTextChanged(String text) {
3180 QWebSettings.setMaximumPagesInCache(0);
3181 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3183 if (text.trim().equals("")) {
3184 searchFieldCleared();
3185 if (searchPerformed) {
3187 // This is done because we want to force a reload of
3188 // images. Some images we may want to highlight the text.
3190 readOnlyCache.clear();
3191 inkNoteCache.clear();
3193 listManager.setEnSearch("");
3194 listManager.loadNotesIndex();
3195 refreshEvernoteNote(true);
3196 noteIndexUpdated(false);
3197 refreshEvernoteNote(true);
3199 searchPerformed = false;
3202 // Text in the toolbar has changed
3203 private void searchFieldChanged() {
3204 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3206 readOnlyCache.clear();
3207 inkNoteCache.clear();
3208 saveNoteColumnPositions();
3209 saveNoteIndexWidth();
3210 String text = searchField.currentText();
3211 listManager.setEnSearch(text.trim());
3212 listManager.loadNotesIndex();
3213 noteIndexUpdated(false);
3215 refreshEvernoteNote(true);
3216 searchPerformed = true;
3218 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3221 // Build the window tool bar
3222 private void setupToolBar() {
3223 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3224 toolBar = addToolBar(tr("Tool Bar"));
3225 toolBar.setObjectName("toolBar");
3226 menuBar.setupToolBarVisible();
3227 if (!Global.isWindowVisible("toolBar"))
3228 toolBar.setVisible(false);
3230 toolBar.setVisible(true);
3232 // toolBar.addWidget(menuBar);
3233 // menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3234 // toolBar.addSeparator();
3235 prevButton = toolBar.addAction(tr("Previous"));
3236 QIcon prevIcon = new QIcon(iconPath+"back.png");
3237 prevButton.setIcon(prevIcon);
3238 prevButton.triggered.connect(this, "previousViewedAction()");
3239 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow"));
3241 nextButton = toolBar.addAction(tr("Next"));
3242 QIcon nextIcon = new QIcon(iconPath+"forward.png");
3243 nextButton.setIcon(nextIcon);
3244 nextButton.triggered.connect(this, "nextViewedAction()");
3245 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow"));
3247 upButton = toolBar.addAction(tr("Up"));
3248 QIcon upIcon = new QIcon(iconPath+"up.png");
3249 upButton.setIcon(upIcon);
3250 upButton.triggered.connect(this, "upAction()");
3251 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow"));
3254 downButton = toolBar.addAction(tr("Down"));
3255 QIcon downIcon = new QIcon(iconPath+"down.png");
3256 downButton.setIcon(downIcon);
3257 downButton.triggered.connect(this, "downAction()");
3258 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow"));
3260 synchronizeButton = toolBar.addAction(tr("Synchronize"));
3261 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3262 synchronizeIconAngle = 0;
3263 synchronizeButton.triggered.connect(this, "evernoteSync()");
3264 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize"));
3266 printButton = toolBar.addAction(tr("Print"));
3267 QIcon printIcon = new QIcon(iconPath+"print.png");
3268 printButton.setIcon(printIcon);
3269 printButton.triggered.connect(this, "printNote()");
3270 togglePrintButton(Global.isToolbarButtonVisible("print"));
3272 tagButton = toolBar.addAction(tr("Tag"));
3273 QIcon tagIcon = new QIcon(iconPath+"tag.png");
3274 tagButton.setIcon(tagIcon);
3275 tagButton.triggered.connect(browserWindow, "modifyTags()");
3276 toggleTagButton(Global.isToolbarButtonVisible("tag"));
3278 attributeButton = toolBar.addAction(tr("Attributes"));
3279 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3280 attributeButton.setIcon(attributeIcon);
3281 attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3282 toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
3284 emailButton = toolBar.addAction(tr("Email"));
3285 QIcon emailIcon = new QIcon(iconPath+"email.png");
3286 emailButton.setIcon(emailIcon);
3287 emailButton.triggered.connect(this, "emailNote()");
3288 toggleEmailButton(Global.isToolbarButtonVisible("email"));
3290 deleteButton = toolBar.addAction(tr("Delete"));
3291 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3292 deleteButton.setIcon(deleteIcon);
3293 deleteButton.triggered.connect(this, "deleteNote()");
3294 toggleDeleteButton(Global.isToolbarButtonVisible("delete"));
3296 newButton = toolBar.addAction(tr("New"));
3297 QIcon newIcon = new QIcon(iconPath+"new.png");
3298 newButton.triggered.connect(this, "addNote()");
3299 newButton.setIcon(newIcon);
3300 toggleNewButton(Global.isToolbarButtonVisible("new"));
3302 allNotesButton = toolBar.addAction(tr("All Notes"));
3303 QIcon allIcon = new QIcon(iconPath+"books.png");
3304 allNotesButton.triggered.connect(this, "allNotes()");
3305 allNotesButton.setIcon(allIcon);
3306 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
3308 //toolBar.addSeparator();
3309 //toolBar.addWidget(new QLabel(tr("Quota:")));
3310 //toolBar.addWidget(quotaBar);
3311 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3313 //toolBar.addSeparator();
3315 //toolBar.addWidget(new QLabel(tr("Zoom")));
3316 //toolBar.addWidget(zoomSpinner);
3318 //toolBar.addWidget(new QLabel(" "));
3319 //toolBar.addSeparator();
3320 //toolBar.addWidget(new QLabel(tr(" Search:")));
3321 //toolBar.addWidget(searchField);
3322 QSizePolicy sizePolicy = new QSizePolicy();
3323 sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3324 QLabel spacer = new QLabel("");
3325 spacer.setSizePolicy(sizePolicy);
3326 toolBar.addWidget(spacer);
3327 //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3329 //searchClearButton = toolBar.addAction("Search Clear");
3330 //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3331 //searchClearButton.setIcon(searchClearIcon);
3332 //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3333 //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3335 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3337 // Update the sychronize button picture
3339 public QMenu createPopupMenu() {
3340 QMenu contextMenu = super.createPopupMenu();
3342 contextMenu.addSeparator();
3343 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3344 contextMenu.addAction(prevAction);
3345 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3347 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3348 contextMenu.addAction(nextAction);
3349 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3351 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3352 contextMenu.addAction(upAction);
3353 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3355 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3356 contextMenu.addAction(downAction);
3357 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3359 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3360 contextMenu.addAction(synchronizeAction);
3361 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3363 QAction printAction = addContextAction("print", tr("Print"));
3364 contextMenu.addAction(printAction);
3365 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3367 QAction tagAction = addContextAction("tag", tr("Tag"));
3368 contextMenu.addAction(tagAction);
3369 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3371 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3372 contextMenu.addAction(attributeAction);
3373 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3375 QAction emailAction = addContextAction("email", tr("Email"));
3376 contextMenu.addAction(emailAction);
3377 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3379 QAction deleteAction = addContextAction("delete", tr("Delete"));
3380 contextMenu.addAction(deleteAction);
3381 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3383 QAction newAction = addContextAction("new", tr("Add"));
3384 contextMenu.addAction(newAction);
3385 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3387 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3388 contextMenu.addAction(allNotesAction);
3389 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3391 QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3392 contextMenu.addAction(searchClearAction);
3393 searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3398 private QAction addContextAction(String config, String name) {
3399 QAction newAction = new QAction(this);
3400 newAction.setText(name);
3401 newAction.setCheckable(true);
3402 newAction.setChecked(Global.isToolbarButtonVisible(config));
3405 private void togglePrevArrowButton(Boolean toggle) {
3406 prevButton.setVisible(toggle);
3407 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3409 private void toggleNextArrowButton(Boolean toggle) {
3410 nextButton.setVisible(toggle);
3411 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3413 private void toggleUpArrowButton(Boolean toggle) {
3414 upButton.setVisible(toggle);
3415 Global.saveToolbarButtonsVisible("upArrow", toggle);
3417 private void toggleDownArrowButton(Boolean toggle) {
3418 downButton.setVisible(toggle);
3419 Global.saveToolbarButtonsVisible("downArrow", toggle);
3421 private void toggleSynchronizeButton(Boolean toggle) {
3422 synchronizeButton.setVisible(toggle);
3423 Global.saveToolbarButtonsVisible("synchronize", toggle);
3425 private void togglePrintButton(Boolean toggle) {
3426 printButton.setVisible(toggle);
3427 Global.saveToolbarButtonsVisible("print", toggle);
3429 private void toggleTagButton(Boolean toggle) {
3430 tagButton.setVisible(toggle);
3431 Global.saveToolbarButtonsVisible("tag", toggle);
3433 private void toggleAttributeButton(Boolean toggle) {
3434 attributeButton.setVisible(toggle);
3435 Global.saveToolbarButtonsVisible("attribute", toggle);
3437 private void toggleEmailButton(Boolean toggle) {
3438 emailButton.setVisible(toggle);
3439 Global.saveToolbarButtonsVisible("email", toggle);
3441 private void toggleDeleteButton(Boolean toggle) {
3442 deleteButton.setVisible(toggle);
3443 Global.saveToolbarButtonsVisible("delete", toggle);
3445 private void toggleNewButton(Boolean toggle) {
3446 newButton.setVisible(toggle);
3447 Global.saveToolbarButtonsVisible("new", toggle);
3449 private void toggleAllNotesButton(Boolean toggle) {
3450 allNotesButton.setVisible(toggle);
3451 Global.saveToolbarButtonsVisible("allNotes", toggle);
3453 @SuppressWarnings("unused")
3454 private void toggleSearchClearButton(Boolean toggle) {
3455 searchClearButton.setVisible(toggle);
3456 Global.saveToolbarButtonsVisible("searchClear", toggle);
3463 @SuppressWarnings("unused")
3464 private void updateSyncButton() {
3466 if (syncIcons == null) {
3467 syncIcons = new ArrayList<QPixmap>();
3469 synchronizeIconAngle = 0;
3470 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3472 for (int i=0; i<=360; i++) {
3473 QPixmap rotatedPix = new QPixmap(pix.size());
3474 QPainter p = new QPainter(rotatedPix);
3475 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3476 QSize size = pix.size();
3477 p.translate(size.width()/2, size.height()/2);
3480 p.setBackgroundMode(BGMode.OpaqueMode);
3481 p.translate(-size.width()/2, -size.height()/2);
3482 p.drawPixmap(0,0, pix);
3484 syncIcons.add(rotatedPix);
3488 synchronizeIconAngle++;
3489 if (synchronizeIconAngle > 359)
3490 synchronizeIconAngle=0;
3491 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3494 // Synchronize with Evernote
3496 private void evernoteSync() {
3497 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3498 if (!Global.isConnected)
3500 if (Global.isConnected)
3501 synchronizeAnimationTimer.start(5);
3502 // synchronizeAnimationTimer.start(200);
3504 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3506 private void updateQuotaBar() {
3507 long limit = Global.getUploadLimit();
3508 long amount = Global.getUploadAmount();
3509 if (amount>0 && limit>0) {
3510 int percent =(int)(amount*100/limit);
3511 quotaBar.setValue(percent);
3513 quotaBar.setValue(0);
3516 @SuppressWarnings("unused")
3517 private void zoomChanged() {
3518 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3521 //****************************************************************
3522 //****************************************************************
3523 //* System Tray functions
3524 //****************************************************************
3525 //****************************************************************
3526 private void trayToggleVisible() {
3531 if (windowMaximized)
3538 @SuppressWarnings("unused")
3539 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3540 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3541 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3542 trayToggleVisible();
3547 //***************************************************************
3548 //***************************************************************
3549 //** These functions deal with the trash tree
3550 //***************************************************************
3551 //***************************************************************
3552 // Setup the tree containing the trash.
3553 @SuppressWarnings("unused")
3554 private void trashTreeSelection() {
3555 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3557 clearNotebookFilter();
3559 clearAttributeFilter();
3560 clearSavedSearchFilter();
3562 String tempGuid = currentNoteGuid;
3564 // currentNoteGuid = "";
3565 currentNote = new Note();
3566 selectedNoteGUIDs.clear();
3567 listManager.getSelectedNotebooks().clear();
3568 listManager.getSelectedTags().clear();
3569 listManager.setSelectedSavedSearch("");
3570 browserWindow.clear();
3572 // toggle the add buttons
3573 newButton.setEnabled(!newButton.isEnabled());
3574 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3575 menuBar.noteAdd.setVisible(true);
3577 List<QTreeWidgetItem> selections = trashTree.selectedItems();
3578 if (selections.size() == 0) {
3579 currentNoteGuid = trashNoteGuid;
3580 trashNoteGuid = tempGuid;
3581 Global.showDeleted = false;
3582 menuBar.noteRestoreAction.setEnabled(false);
3583 menuBar.noteRestoreAction.setVisible(false);
3584 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3585 rensoNoteListDock.setEnabled(true);
3588 trashNoteGuid = tempGuid;
3589 currentNoteGuid = trashNoteGuid;
3590 menuBar.noteRestoreAction.setEnabled(true);
3591 menuBar.noteRestoreAction.setVisible(true);
3592 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
3593 rensoNoteListDock.setEnabled(false);
3595 Global.showDeleted = true;
3598 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3599 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3600 menuBar.noteAddNewTab.setEnabled(false);
3603 listManager.loadNotesIndex();
3604 noteIndexUpdated(false);
3605 //// browserWindow.setEnabled(newButton.isEnabled());
3606 browserWindow.setReadOnly(!newButton.isEnabled());
3607 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3609 // Empty the trash file
3610 @SuppressWarnings("unused")
3611 private void emptyTrash() {
3612 // browserWindow.clear();
3613 logger.log(logger.EXTREME, "Emptying Trash");
3614 listManager.emptyTrash();
3615 logger.log(logger.EXTREME, "Resetting view after trash empty");
3616 if (trashTree.selectedItems().size() > 0) {
3617 listManager.getSelectedNotebooks().clear();
3618 listManager.getSelectedTags().clear();
3619 listManager.setSelectedSavedSearch("");
3620 newButton.setEnabled(!newButton.isEnabled());
3621 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3622 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3623 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3624 menuBar.noteAddNewTab.setEnabled(false);
3626 menuBar.noteAdd.setVisible(true);
3627 browserWindow.clear();
3630 clearNotebookFilter();
3631 clearSavedSearchFilter();
3632 clearAttributeFilter();
3634 Global.showDeleted = false;
3635 menuBar.noteRestoreAction.setEnabled(false);
3636 menuBar.noteRestoreAction.setVisible(false);
3638 listManager.loadNotesIndex();
3639 noteIndexUpdated(false);
3641 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3642 if (!rensoNoteListDock.isEnabled()) {
3643 rensoNoteListDock.setEnabled(true);
3647 // Show/Hide trash window
3648 @SuppressWarnings("unused")
3649 private void toggleTrashWindow() {
3650 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3651 if (trashTree.isVisible())
3655 menuBar.hideTrash.setChecked(trashTree.isVisible());
3657 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3658 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3660 private void clearTrashFilter() {
3661 Global.showDeleted = false;
3662 newButton.setEnabled(true);
3663 menuBar.noteAdd.setEnabled(true);
3664 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3665 menuBar.noteAddNewTab.setEnabled(false);
3667 menuBar.noteAddNewTab.setEnabled(true);
3669 menuBar.noteAdd.setVisible(true);
3670 trashTree.blockSignals(true);
3671 trashTree.clearSelection();
3672 trashTree.blockSignals(false);
3677 //***************************************************************
3678 //***************************************************************
3679 //** These functions deal with connection settings
3680 //***************************************************************
3681 //***************************************************************
3682 // SyncRunner had a problem and things are disconnected
3683 @SuppressWarnings("unused")
3684 private void remoteErrorDisconnect() {
3685 menuBar.connectAction.setText(tr("Connect"));
3686 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3687 menuBar.synchronizeAction.setEnabled(false);
3688 Global.isConnected = false;
3689 synchronizeAnimationTimer.stop();
3692 // Do a manual connect/disconnect
3693 private void remoteConnect() {
3695 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3697 // If we are already connected, we just disconnect
3698 if (Global.isConnected) {
3699 Global.isConnected = false;
3700 syncRunner.enDisconnect();
3701 setupConnectMenuOptions();
3706 OAuthTokenizer tokenizer = new OAuthTokenizer();
3707 AESEncrypter aes = new AESEncrypter();
3709 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3710 } catch (FileNotFoundException e) {
3711 // File not found, so we'll just get empty strings anyway.
3715 if (Global.getProxyValue("url").equals("")) {
3716 System.setProperty("http.proxyHost","") ;
3717 System.setProperty("http.proxyPort", "") ;
3718 System.setProperty("https.proxyHost","") ;
3719 System.setProperty("https.proxyPort", "") ;
3722 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3723 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3724 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3725 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3727 if (Global.getProxyValue("userid").equals("")) {
3728 Authenticator.setDefault(new Authenticator() {
3730 protected PasswordAuthentication getPasswordAuthentication() {
3732 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3738 syncRunner.userStoreUrl = Global.userStoreUrl;
3739 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3740 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3744 String authString = aes.getString();
3745 if (!authString.equals("")) {
3746 tokenizer.tokenize(authString);
3747 syncRunner.authToken = tokenizer.oauth_token;
3748 syncRunner.enConnect();
3751 Global.isConnected = syncRunner.isConnected;
3753 if (!Global.isConnected) {
3754 OAuthWindow window = new OAuthWindow(logger);
3756 setMessage(window.errorMessage);
3761 setMessage(window.errorMessage);
3764 tokenizer.tokenize(window.response);
3765 if (tokenizer.oauth_token.equals("")) {
3766 setMessage(tr("Invalid authorization token received."));
3769 aes.setString(window.response);
3771 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3772 } catch (FileNotFoundException e) {
3773 // TODO Auto-generated catch block
3774 e.printStackTrace();
3776 syncRunner.authToken = tokenizer.oauth_token;
3777 syncRunner.enConnect();
3778 Global.isConnected = syncRunner.isConnected;
3780 // Global.username = syncRunner.username;
3782 if (!Global.isConnected)
3785 setupConnectMenuOptions();
3786 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3790 private void setupConnectMenuOptions() {
3791 logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3792 if (!Global.isConnected) {
3793 menuBar.connectAction.setText(tr("Connect"));
3794 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3795 menuBar.synchronizeAction.setEnabled(false);
3797 menuBar.connectAction.setText(tr("Disconnect"));
3798 menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3799 menuBar.synchronizeAction.setEnabled(true);
3801 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3806 //***************************************************************
3807 //***************************************************************
3808 //** These functions deal with the GUI Attribute tree
3809 //***************************************************************
3810 //***************************************************************
3811 @SuppressWarnings("unused")
3812 private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3814 // clearTagFilter();
3815 // clearNotebookFilter();
3817 // clearSavedSearchFilter();
3819 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3820 if (!rensoNoteListDock.isEnabled()) {
3821 rensoNoteListDock.setEnabled(true);
3824 if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3825 if (item.childCount() > 0) {
3826 item.setSelected(false);
3828 Global.createdBeforeFilter.reset();
3829 Global.createdSinceFilter.reset();
3830 Global.changedBeforeFilter.reset();
3831 Global.changedSinceFilter.reset();
3832 Global.containsFilter.reset();
3833 attributeTreeSelected = item;
3834 DateAttributeFilterTable f = null;
3835 f = findDateAttributeFilterTable(item.parent());
3837 f.select(item.parent().indexOfChild(item));
3839 Global.containsFilter.select(item.parent().indexOfChild(item));
3842 listManager.loadNotesIndex();
3843 noteIndexUpdated(false);
3846 attributeTreeSelected = null;
3847 item.setSelected(false);
3848 Global.createdBeforeFilter.reset();
3849 Global.createdSinceFilter.reset();
3850 Global.changedBeforeFilter.reset();
3851 Global.changedSinceFilter.reset();
3852 Global.containsFilter.reset();
3853 listManager.loadNotesIndex();
3854 noteIndexUpdated(false);
3856 // This determines what attribute filter we need, depending upon the selection
3857 private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3858 if (w.parent() != null && w.childCount() > 0) {
3859 QTreeWidgetItem parent = w.parent();
3860 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3861 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3862 return Global.createdSinceFilter;
3863 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3864 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3865 return Global.createdBeforeFilter;
3866 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3867 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3868 return Global.changedSinceFilter;
3869 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3870 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3871 return Global.changedBeforeFilter;
3876 // Show/Hide attribute search window
3877 @SuppressWarnings("unused")
3878 private void toggleAttributesWindow() {
3879 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3880 if (attributeTree.isVisible())
3881 attributeTree.hide();
3883 attributeTree.show();
3884 menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3886 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3887 logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3889 private void clearAttributeFilter() {
3890 Global.createdBeforeFilter.reset();
3891 Global.createdSinceFilter.reset();
3892 Global.changedBeforeFilter.reset();
3893 Global.changedSinceFilter.reset();
3894 Global.containsFilter.reset();
3895 attributeTreeSelected = null;
3896 attributeTree.blockSignals(true);
3897 attributeTree.clearSelection();
3898 attributeTree.blockSignals(false);
3902 //***************************************************************
3903 //***************************************************************
3904 //** These functions deal with the GUI Note index table
3905 //***************************************************************
3906 //***************************************************************
3907 // Initialize the note list table
3908 private void initializeNoteTable() {
3909 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3910 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3911 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3912 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3914 // Show/Hide trash window
3915 @SuppressWarnings("unused")
3916 private void toggleNoteListWindow() {
3917 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3918 if (noteTableView.isVisible())
3919 noteTableView.hide();
3921 noteTableView.show();
3922 menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3924 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3925 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3927 // Handle the event that a user selects a note from the table
3928 @SuppressWarnings("unused")
3929 private void noteTableSelection() {
3930 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3936 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3937 // 選択されたノートのguidをselectedNoteGUIDsにセット
3938 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3939 if(selections.size() > 0){
3940 selectedNoteGUIDs.clear();
3941 for(int i = 0; i < selections.size(); i++){
3942 int row = selections.get(i).row();
3943 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3944 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3945 selectedNoteGUIDs.add((String) ix.values().toArray()[0]);
3951 // If we have more than one selection, then set the merge note action to true.
3952 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3953 if (selections.size() > 1)
3954 menuBar.noteMergeAction.setEnabled(true);
3956 menuBar.noteMergeAction.setEnabled(false);
3958 // If the ctrl key is pressed, then they are selecting multiple
3959 // entries and we don't want to change the currently viewed note.
3961 // Shiftキーを押しながらの場合の処理も追加
3962 if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) ||
3963 QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) &&
3964 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3965 selectedNoteGUIDs.clear();
3966 for (int i=0; i<selections.size(); i++) {
3967 int row = selections.get(i).row();
3968 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3969 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3970 selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3975 // ICHANGED たぶんこれは不要
3977 /*if (historyGuids.size() == 0) {
3978 historyGuids.add(currentNoteGuid);
3979 historyPosition = 1;
3982 noteTableView.showColumn(Global.noteTableGuidPosition);
3984 if (!Global.isColumnVisible("guid"))
3985 noteTableView.hideColumn(Global.noteTableGuidPosition);
3987 if (selections.size() > 0) {
3989 menuBar.noteDuplicateAction.setEnabled(true);
3990 menuBar.noteOnlineHistoryAction.setEnabled(true);
3991 menuBar.noteMergeAction.setEnabled(true);
3992 selectedNoteGUIDs.clear();
3993 if (currentNoteGuid != null && !currentNoteGuid.equals("") && !Global.showDeleted) {
3994 menuBar.noteAddNewTab.setEnabled(true);
3996 if (selections.size() != 1 || Global.showDeleted) {
3997 menuBar.noteDuplicateAction.setEnabled(false);
3999 if (selections.size() != 1 || !Global.isConnected) {
4000 menuBar.noteOnlineHistoryAction.setEnabled(false);
4002 if (selections.size() == 1) {
4003 menuBar.noteMergeAction.setEnabled(false);
4005 for (int i=0; i<selections.size(); i++) {
4006 int row = selections.get(i).row();
4008 upButton.setEnabled(false);
4010 upButton.setEnabled(true);
4011 if (row < listManager.getNoteTableModel().rowCount()-1)
4012 downButton.setEnabled(true);
4014 downButton.setEnabled(false);
4015 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
4016 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
4018 currentNoteGuid = (String)ix.values().toArray()[0];
4019 selectedNoteGUIDs.add(currentNoteGuid);
4023 nextButton.setEnabled(true);
4024 prevButton.setEnabled(true);
4027 int currentIndex = tabBrowser.currentIndex();
4028 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4029 int histPosition = historyPosition.get(currentIndex);
4030 boolean fromHist = fromHistory.get(currentIndex);
4034 int endPosition = histGuids.size() - 1;
4036 for (int j = histPosition; j <= endPosition; j++) {
4037 histGuids.remove(histGuids.size() - 1);
4039 histGuids.add(currentNoteGuid);
4040 historyPosition.put(currentIndex, histGuids.size());
4041 histPosition = histGuids.size();
4043 if (histPosition <= 1){
4044 prevButton.setEnabled(false);
4046 if (histPosition == histGuids.size())
4047 nextButton.setEnabled(false);
4048 fromHistory.put(currentIndex, false);
4051 scrollToGuid(currentNoteGuid);
4052 refreshEvernoteNote(true);
4055 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4056 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4063 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
4066 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4071 // 複数ノートの同時閲覧履歴をデータベースに保存
4072 private void addBrowseHistory() {
4073 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4074 if (tabWindows.size() >= 2) {
4075 Iterator<Integer> it = tabWindows.keySet().iterator();
4076 while (it.hasNext()) {
4077 int tabIndex = it.next();
4078 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4079 // guid1=guid2のデータは登録しない
4080 if (!currentNoteGuid.equals(nextGuid)) {
4081 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4085 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4086 if (externalWindows.size() >= 1) {
4087 Iterator<String> it = externalWindows.keySet().iterator();
4088 while (it.hasNext()) {
4089 String nextGuid = it.next();
4090 // guid1=guid2のデータは登録しない
4091 if (!currentNoteGuid.equals(nextGuid)) {
4092 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4098 // Trigger a refresh when the note db has been updated
4099 private void noteIndexUpdated(boolean reload) {
4100 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4102 refreshEvernoteNoteList();
4103 logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4104 noteTableView.load(reload);
4105 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4107 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4108 pos = noteTableView.proxyModel.rowCount();
4111 if (noteTableView.proxyModel.rowCount() == 0)
4114 QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4116 currentNoteGuid = (String)i.data();
4120 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4122 scrollToGuid(currentNoteGuid);
4123 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4125 // Called when the list of notes is updated
4126 private void refreshEvernoteNoteList() {
4127 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4128 browserWindow.setDisabled(false);
4129 if (selectedNoteGUIDs == null)
4130 selectedNoteGUIDs = new ArrayList<String>();
4131 selectedNoteGUIDs.clear(); // clear out old entries
4133 String saveCurrentNoteGuid = new String();
4134 String tempNoteGuid = new String();
4137 int currentIndex = tabBrowser.currentIndex();
4138 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4140 historyPosition.put(currentIndex, 0);
4142 prevButton.setEnabled(false);
4143 nextButton.setEnabled(false);
4145 if (currentNoteGuid == null)
4146 currentNoteGuid = new String();
4148 //determine current note guid
4149 for (Note note : listManager.getNoteIndex()) {
4150 tempNoteGuid = note.getGuid();
4151 if (currentNoteGuid.equals(tempNoteGuid)) {
4152 saveCurrentNoteGuid = tempNoteGuid;
4156 if (listManager.getNoteIndex().size() == 0) {
4157 currentNoteGuid = "";
4159 browserWindow.clear();
4160 browserWindow.setDisabled(true);
4164 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4165 currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4166 saveCurrentNoteGuid = currentNoteGuid;
4167 refreshEvernoteNote(true);
4170 if (!saveCurrentNoteGuid.equals("")) {
4171 refreshEvernoteNote(false);
4173 currentNoteGuid = "";
4175 reloadTagTree(false);
4177 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4181 // Called when the previous arrow button is clicked
4182 @SuppressWarnings("unused")
4183 private void previousViewedAction() {
4184 int currentIndex = tabBrowser.currentIndex();
4185 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4186 int histPosition = historyPosition.get(currentIndex);
4187 boolean fromHist = fromHistory.get(currentIndex);
4188 if (!prevButton.isEnabled())
4190 if (histPosition == 0)
4193 historyPosition.put(currentIndex, histPosition);
4194 if (histPosition <= 0)
4196 String historyGuid = histGuids.get(histPosition - 1);
4197 fromHistory.put(currentIndex, true);
4199 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4200 QModelIndex modelIndex = noteTableView.model().index(i,
4201 Global.noteTableGuidPosition);
4202 if (modelIndex != null) {
4203 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4205 String tableGuid = (String) ix.values().toArray()[0];
4206 if (tableGuid.equals(historyGuid)) {
4207 noteTableView.selectRow(i);
4214 @SuppressWarnings("unused")
4215 private void nextViewedAction() {
4216 if (!nextButton.isEnabled())
4219 int currentIndex = tabBrowser.currentIndex();
4220 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4221 int histPosition = historyPosition.get(currentIndex);
4222 boolean fromHist = fromHistory.get(currentIndex);
4223 String historyGuid = histGuids.get(histPosition);
4225 historyPosition.put(currentIndex, histPosition);
4226 fromHistory.put(currentIndex, true);
4228 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4229 QModelIndex modelIndex = noteTableView.model().index(i,
4230 Global.noteTableGuidPosition);
4231 if (modelIndex != null) {
4232 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4234 String tableGuid = (String) ix.values().toArray()[0];
4235 if (tableGuid.equals(historyGuid)) {
4236 noteTableView.selectRow(i);
4242 // Called when the up arrow is clicked
4243 @SuppressWarnings("unused")
4244 private void upAction() {
4245 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4246 int row = selections.get(0).row();
4248 noteTableView.selectRow(row-1);
4251 // Called when the down arrow is clicked
4252 @SuppressWarnings("unused")
4253 private void downAction() {
4254 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4255 int row = selections.get(0).row();
4256 int max = listManager.getNoteTableModel().rowCount();
4258 noteTableView.selectRow(row+1);
4261 // Update a tag string for a specific note in the list
4262 @SuppressWarnings("unused")
4263 private void updateListTags(String guid, List<String> tags) {
4264 logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4265 StringBuffer tagBuffer = new StringBuffer();
4266 for (int i=0; i<tags.size(); i++) {
4267 tagBuffer.append(tags.get(i));
4268 if (i<tags.size()-1)
4269 tagBuffer.append(", ");
4272 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4273 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4274 if (modelIndex != null) {
4275 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4276 String tableGuid = (String)ix.values().toArray()[0];
4277 if (tableGuid.equals(guid)) {
4278 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4279 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4280 noteTableView.proxyModel.invalidate();
4285 logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4287 // Update a title for a specific note in the list
4288 @SuppressWarnings("unused")
4289 private void updateListAuthor(String guid, String author) {
4290 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4292 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4293 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4294 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4295 if (modelIndex != null) {
4296 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4297 String tableGuid = (String)ix.values().toArray()[0];
4298 if (tableGuid.equals(guid)) {
4299 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4300 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4301 noteTableView.proxyModel.invalidate();
4307 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4309 private void updateListNoteNotebook(String guid, String notebook) {
4310 logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4311 listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4312 logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4314 // Update a title for a specific note in the list
4315 @SuppressWarnings("unused")
4316 private void updateListSourceUrl(String guid, String url) {
4317 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4319 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4320 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4321 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4322 if (modelIndex != null) {
4323 // SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4324 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4325 String tableGuid = (String)ix.values().toArray()[0];
4326 if (tableGuid.equals(guid)) {
4327 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4328 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4329 noteTableView.proxyModel.invalidate();
4334 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4336 @SuppressWarnings("unused")
4337 private void updateListGuid(String oldGuid, String newGuid) {
4338 logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4340 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4341 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4342 if (modelIndex != null) {
4343 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4344 String tableGuid = (String)ix.values().toArray()[0];
4345 if (tableGuid.equals(oldGuid)) {
4346 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4347 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4352 logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4354 private void updateListTagName(String guid) {
4355 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4357 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4358 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4359 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4361 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4362 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4363 if (modelIndex != null) {
4364 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4365 String noteGuid = (String)ix.values().toArray()[0];
4366 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4367 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4368 i=listManager.getNoteTableModel().rowCount();
4374 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4376 private void removeListTagName(String guid) {
4377 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4379 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4380 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4381 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4382 if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4383 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4386 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4387 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4388 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4389 if (modelIndex != null) {
4390 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4391 String noteGuid = (String)ix.values().toArray()[0];
4392 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4393 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4394 i=listManager.getNoteTableModel().rowCount();
4400 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4402 private void updateListNotebookName(String oldName, String newName) {
4403 logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4405 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4406 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition);
4407 if (modelIndex != null) {
4408 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4409 String tableName = (String)ix.values().toArray()[0];
4410 if (tableName.equalsIgnoreCase(oldName)) {
4411 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4415 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4417 @SuppressWarnings("unused")
4418 private void updateListDateCreated(String guid, QDateTime date) {
4419 logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
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.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4428 noteTableView.proxyModel.invalidate();
4433 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4435 @SuppressWarnings("unused")
4436 private void updateListDateSubject(String guid, QDateTime date) {
4437 logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
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.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4447 noteTableView.proxyModel.invalidate();
4452 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4454 private void updateListDateChanged(String guid, QDateTime date) {
4455 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4457 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4458 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4459 if (modelIndex != null) {
4460 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4461 String tableGuid = (String)ix.values().toArray()[0];
4462 if (tableGuid.equals(guid)) {
4463 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4464 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4469 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4471 private void updateListDateChanged() {
4472 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4473 QDateTime date = new QDateTime(QDateTime.currentDateTime());
4474 updateListDateChanged(currentNoteGuid, date);
4475 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4478 private void scrollToCurrentGuid() {
4479 //scrollToGuid(currentNoteGuid);
4480 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4481 if (selections.size() == 0)
4483 QModelIndex index = selections.get(0);
4484 int row = selections.get(0).row();
4485 String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4488 // Scroll to the current GUID in tthe list.
4489 // Scroll to a particular index item
4490 private void scrollToGuid(String guid) {
4491 if (currentNote == null || guid == null)
4493 if (currentNote.isActive() && Global.showDeleted) {
4494 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4495 if (!listManager.getNoteIndex().get(i).isActive()) {
4496 currentNote = listManager.getNoteIndex().get(i);
4497 currentNoteGuid = currentNote.getGuid();
4498 i = listManager.getNoteIndex().size();
4502 if (!currentNote.isActive() && !Global.showDeleted) {
4503 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4504 if (listManager.getNoteIndex().get(i).isActive()) {
4505 currentNote = listManager.getNoteIndex().get(i);
4506 currentNoteGuid = currentNote.getGuid();
4507 i = listManager.getNoteIndex().size();
4512 for (int i=0; i<noteTableView.model().rowCount(); i++) {
4513 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4514 if (currentNoteGuid.equals(index.data())) {
4515 // noteTableView.selectionModel().blockSignals(true);
4516 noteTableView.selectRow(i);
4517 // noteTableView.selectionModel().blockSignals(false);
4518 noteTableView.scrollTo(index, ScrollHint.EnsureVisible); // This should work, but it doesn't
4519 i=listManager.getNoteTableModel().rowCount();
4522 noteTableView.repaint();
4524 // Show/Hide columns
4525 private void showColumns() {
4526 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4527 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4528 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4529 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4530 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4531 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4532 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4533 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4534 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4535 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4536 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));
4537 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned"));
4539 // Title color has changed
4540 @SuppressWarnings("unused")
4541 private void titleColorChanged(Integer color) {
4542 logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4545 QColor backgroundColor = new QColor();
4546 QColor foregroundColor = new QColor(QColor.black);
4547 backgroundColor.setRgb(color);
4549 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4550 foregroundColor.setRgb(QColor.white.rgb());
4552 if (selectedNoteGUIDs.size() == 0)
4553 selectedNoteGUIDs.add(currentNoteGuid);
4555 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4556 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4557 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4558 if (modelIndex != null) {
4559 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4560 String tableGuid = (String)ix.values().toArray()[0];
4561 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4562 for (int k=0; k<Global.noteTableColumnCount; k++) {
4563 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4564 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4565 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4567 i=listManager.getNoteTableModel().rowCount();
4572 logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4574 // A note has been pinned or unpinned
4575 @SuppressWarnings("unused")
4576 private void notePinned() {
4577 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4580 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4581 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4582 boolean pinned = !meta.isPinned();
4583 meta.setPinned(pinned); // Toggle the pinned/unpinned
4585 // Update the list & table
4586 listManager.updateNoteMetadata(meta);
4587 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4589 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4591 // Wide list was chosen
4592 public void narrowListView() {
4593 saveNoteColumnPositions();
4594 saveNoteIndexWidth();
4596 int sortCol = noteTableView.proxyModel.sortColumn();
4597 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4598 Global.setSortColumn(sortCol);
4599 Global.setSortOrder(sortOrder);
4601 Global.setListView(Global.View_List_Narrow);
4603 menuBar.wideListView.blockSignals(true);
4604 menuBar.narrowListView.blockSignals(true);
4606 menuBar.wideListView.setChecked(false);
4607 menuBar.narrowListView.setChecked(true);
4609 menuBar.wideListView.blockSignals(false);
4610 menuBar.narrowListView.blockSignals(false);
4612 mainLeftRightSplitter.addWidget(noteTableView);
4613 // ICHANGED browserWindow → tabBrowser
4614 mainLeftRightSplitter.addWidget(tabBrowser);
4616 restoreWindowState(false);
4617 noteTableView.repositionColumns();
4618 noteTableView.resizeColumnWidths();
4619 noteTableView.resizeRowHeights();
4621 sortCol = Global.getSortColumn();
4622 sortOrder = Global.getSortOrder();
4623 noteTableView.proxyModel.blocked = true;
4624 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4625 noteTableView.proxyModel.blocked = false;
4629 noteTableView.load(false);
4630 refreshEvernoteNote(true);
4631 scrollToCurrentGuid();
4633 public void wideListView() {
4634 int sortCol = noteTableView.proxyModel.sortColumn();
4635 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4636 Global.setSortColumn(sortCol);
4637 Global.setSortOrder(sortOrder);
4640 saveNoteColumnPositions();
4641 saveNoteIndexWidth();
4642 Global.setListView(Global.View_List_Wide);
4644 menuBar.wideListView.blockSignals(true);
4645 menuBar.narrowListView.blockSignals(true);
4647 menuBar.wideListView.setChecked(true);
4648 menuBar.narrowListView.setChecked(false);
4650 menuBar.wideListView.blockSignals(false);
4651 menuBar.narrowListView.blockSignals(false);
4652 browserIndexSplitter.setVisible(true);
4653 browserIndexSplitter.addWidget(noteTableView);
4654 // ICHANGED browserWindow → tabBrowser
4655 browserIndexSplitter.addWidget(tabBrowser);
4657 restoreWindowState(false);
4658 noteTableView.repositionColumns();
4659 noteTableView.resizeColumnWidths();
4660 noteTableView.resizeRowHeights();
4662 sortCol = Global.getSortColumn();
4663 sortOrder = Global.getSortOrder();
4664 noteTableView.proxyModel.blocked = true;
4665 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4666 noteTableView.proxyModel.blocked = false;
4669 noteTableView.load(false);
4670 scrollToCurrentGuid();
4672 // Sort order for the notebook has changed
4673 public void tableSortOrderChanged(Integer column, Integer order) {
4675 // Find what notebook (if any) is selected. We ignore stacks & the "All Notebooks".
4676 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4677 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4678 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4680 notebook = currentSelectedNotebook.text(2);
4681 conn.getNotebookTable().setSortOrder(notebook, column, order);
4685 //***************************************************************
4686 @SuppressWarnings("unused")
4687 private void evernoteLinkClick(String syncGuid, String locGuid) {
4689 if (conn.getNoteTable().guidExists(syncGuid)) {
4692 // If we didn't find it via the synchronized guid, look under the local guid
4693 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was
4694 // later synchronized (that causes the guid to change so we need to find the new one).
4695 if (conn.getNoteTable().guidExists(locGuid))
4698 guid = conn.getNoteTable().findAlternateGuid(locGuid);
4701 openExternalEditor(guid);
4705 //If we've gotten this far, we can't find the note
4706 QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4707 " seem to find that note."));
4709 //***************************************************************
4710 //***************************************************************
4711 //** External editor window functions
4712 //***************************************************************
4713 //***************************************************************
4714 private void listDoubleClick() {
4716 openExternalEditor(currentNoteGuid);
4718 private void openExternalEditor(String guid) {
4720 if (externalWindows.containsKey(guid)) {
4721 externalWindows.get(guid).raise();
4725 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4726 // We have a new external editor to create
4727 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4729 ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4731 newBrowser.setWindowIcon(appIcon);
4732 externalWindows.put(guid, newBrowser);
4733 showEditorButtons(newBrowser.getBrowserWindow());
4734 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4735 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4736 newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4737 //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4738 newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4739 newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4740 newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4741 newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4743 browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4744 browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4745 browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4749 @SuppressWarnings({ "rawtypes", "unused" })
4750 private void externalWindowTagsEdited(String guid, List values) {
4751 StringBuffer line = new StringBuffer(100);
4752 for (int i=0; i<values.size(); i++) {
4754 line.append(Global.tagDelimeter+" ");
4755 line.append(values.get(i));
4757 if (guid.equals(currentNoteGuid)) {
4758 browserWindow.setTag(line.toString());
4761 @SuppressWarnings("unused")
4762 private void externalWindowClosing(String guid) {
4763 externalWindows.remove(guid);
4766 // ***************************************************************
4767 // ***************************************************************
4769 // ***************************************************************
4770 // ***************************************************************
4771 @SuppressWarnings("unused")
4772 private void openNewTab() {
4775 // selectedNoteGUIDsをディープコピー
4776 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4778 for (int i=0; i < copySelected.size() ; i++) {
4779 openTabEditor(copySelected.get(i));
4783 // ICHANGED 連想ノートリストから新しいタブで開く
4784 @SuppressWarnings("unused")
4785 private void openNewTabFromRNL(){
4786 if(rensoNotePressedItemGuid != null){
4787 String prevCurrentNoteGuid = new String(currentNoteGuid);
4790 openTabEditor(rensoNotePressedItemGuid);
4792 // 連想ノートリストアイテムクリック操作を記録
4793 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4798 private void openTabEditor(String guid) {
4800 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4802 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4803 showEditorButtons(newBrowser.getBrowserWindow());
4805 String noteTitle = note.getTitle();
4806 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4807 tabWindows.put(index, newBrowser);
4808 noteDirty.put(index, false);
4810 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4811 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4812 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4814 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4816 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4818 // ExtendedInformationを必要があれば表示する
4819 toggleNoteInformation();
4820 // Sourceを必要があれば表示する
4822 // EditorButtonsBarを必要があれば表示する
4823 toggleEditorButtonBar();
4826 ArrayList<String> histGuids = new ArrayList<String>();
4827 historyGuids.put(index, histGuids);
4828 historyPosition.put(index, 0);
4829 fromHistory.put(index, false);
4832 histGuids.add(guid);
4833 historyPosition.put(index, histGuids.size());
4835 tabBrowser.setCurrentIndex(index);
4837 if (guid != null && !guid.equals("")) {
4838 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4844 // ICHANGED タブが閉じられた
4845 private void tabWindowClosing(int index) {
4847 if (tabBrowser.count() <= 1) {
4851 TabBrowse t = (TabBrowse) tabBrowser.widget(index);
4852 String guid = t.getBrowserWindow().getNote().getGuid();
4853 String content = t.getBrowserWindow().getContent();
4854 BrowserWindow browser = t.getBrowserWindow();
4856 if (t.getNoteDirty()) {
4857 saveNoteTabBrowser(guid, content, true, browser);
4861 browser.noteSignal.tagsChanged.disconnect();
4862 browser.noteSignal.titleChanged.disconnect();
4863 browser.noteSignal.noteChanged.disconnect();
4864 browser.noteSignal.notebookChanged.disconnect();
4865 browser.noteSignal.createdDateChanged.disconnect();
4866 browser.noteSignal.alteredDateChanged.disconnect();
4869 tabWindows.remove(index);
4870 tabBrowser.removeTab(index);
4871 noteDirty.remove(index);
4872 inkNote.remove(index);
4873 readOnly.remove(index);
4876 historyGuids.remove(index);
4877 historyPosition.remove(index);
4878 fromHistory.remove(index);
4880 // タブのインデックスを更新(削除によって空いた部分を詰める)
4881 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4883 TabBrowse tab = tabWindows.get(i + 1);
4884 tabWindows.put(i, tab);
4885 tabWindows.remove(i + 1);
4887 boolean isNoteDirty = noteDirty.get(i + 1);
4888 noteDirty.put(i, isNoteDirty);
4889 noteDirty.remove(i + 1);
4891 boolean isInkNote = inkNote.get(i + 1);
4892 inkNote.put(i, isInkNote);
4893 inkNote.remove(i + 1);
4895 boolean isReadOnly = readOnly.get(i + 1);
4896 readOnly.put(i, isReadOnly);
4897 readOnly.remove(i + 1);
4899 ArrayList<String> histGuids = historyGuids.get(i + 1);
4900 historyGuids.put(i, histGuids);
4901 historyGuids.remove(i + 1);
4903 int histPosition = historyPosition.get(i + 1);
4904 historyPosition.put(i, histPosition);
4905 historyPosition.remove(i + 1);
4907 boolean fromHist = fromHistory.get(i + 1);
4908 fromHistory.put(i, fromHist);
4909 fromHistory.remove(i + 1);
4912 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4913 tabWindowChanged(tabBrowser.currentIndex());
4916 @SuppressWarnings("unused")
4917 private void noteAddNewTab() {
4920 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4921 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4922 String prevTabGuid = null;
4923 if (prevTab.getBrowserWindow() != null && prevTab.getBrowserWindow().getNote() != null) {
4924 prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4927 openEmptyTabEditor();
4930 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4931 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4932 TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4933 String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4934 if (addedTabGuid != null && !addedTabGuid.equals("")) {
4935 if (!prevTabGuid.equals(addedTabGuid)) {
4936 conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4943 private void openEmptyTabEditor() {
4945 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4946 showEditorButtons(newBrowser.getBrowserWindow());
4948 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4950 int index = tabBrowser.addNewTab(newBrowser, "");
4951 tabWindows.put(index, newBrowser);
4952 noteDirty.put(index, false);
4954 // ExtendedInformationを必要があれば表示する
4955 toggleNoteInformation();
4956 // Sourceを必要があれば表示する
4958 // EditorButtonsBarを必要があれば表示する
4959 toggleEditorButtonBar();
4962 ArrayList<String> histGuids = new ArrayList<String>();
4963 historyGuids.put(index, histGuids);
4964 historyPosition.put(index, 0);
4965 fromHistory.put(index, false);
4967 tabBrowser.setCurrentIndex(index);
4970 //***************************************************************
4971 //***************************************************************
4972 //** These functions deal with Note specific things
4973 //***************************************************************
4974 //***************************************************************
4976 private void setNoteDirty() {
4977 for (String guid: selectedNoteGUIDs) {
4983 private void setNoteDirty(String targetGuid) {
4984 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
4986 // Find if the note is being edited externally. If it is, update it.
4987 if (externalWindows.containsKey(targetGuid)) {
4988 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4989 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4990 ExternalBrowse window = externalWindows.get(targetGuid);
4991 window.getBrowserWindow().setContent(unicode);
4994 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
4995 Collection<Integer> tabIndexes = tabWindows.keySet();
4996 Iterator<Integer> indexIterator = tabIndexes.iterator();
4998 for (TabBrowse tab: tabWindows.values()) {
4999 int index = indexIterator.next();
5000 String guid = tab.getBrowserWindow().getNote().getGuid();
5002 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5003 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
5005 if (guid.equals(guid)) {
5006 if (index != tabBrowser.currentIndex()) {
5007 TabBrowse window = tabWindows.get(index);
5008 window.getBrowserWindow().setContent(unicode);
5013 // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する
5014 // If the note is dirty, then it is unsynchronized by default.
5016 boolean isNoteDirty = false;
5017 for (TabBrowse tab: tabWindows.values()) {
5018 if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) {
5019 index = tabBrowser.indexOf(tab);
5020 isNoteDirty = noteDirty.get(index);
5028 // Set the note as dirty and check if its status is synchronized in the display table
5029 // まだダーティでなく、かつタブで開かれている場合にnoteDirty = trueにする
5031 noteDirty.put(index, true);
5034 if (listManager.getNoteMetadata().containsKey(targetGuid) &&
5035 listManager.getNoteMetadata().get(targetGuid).isDirty()) {
5039 // If this wasn't already marked as unsynchronized, then we need to update the table
5040 listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false);
5041 // listManager.getUnsynchronizedNotes().add(targetGuid);
5042 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
5043 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
5044 if (modelIndex != null) {
5045 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5046 String tableGuid = (String)ix.values().toArray()[0];
5047 if (tableGuid.equals(targetGuid)) {
5048 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
5054 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
5056 @SuppressWarnings("unused")
5057 private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
5058 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5059 QByteArray unicode = codec.fromUnicode(content);
5060 noteCache.remove(guid);
5061 noteCache.put(guid, unicode.toString());
5062 if (guid.equals(currentNoteGuid)) {
5064 int index = tabBrowser.currentIndex();
5065 noteDirty.put(index, true);
5066 browserWindow.setContent(unicode);
5069 thumbnailRunner.addWork("GENERATE "+ guid);
5070 saveNote(guid, browser);
5076 private void saveNoteTabBrowser(String guid, String content, Boolean save,
5077 BrowserWindow browser) {
5078 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5079 QByteArray unicode = codec.fromUnicode(content);
5080 noteCache.remove(guid);
5081 noteCache.put(guid, unicode.toString());
5083 thumbnailRunner.addWork("GENERATE " + guid);
5084 saveNote(guid, browser);
5088 private void saveNote() {
5090 // すべてのタブに対して、Dirtyを確認し、trueならセーブする
5091 Collection<Integer> dirtyIndex = noteDirty.keySet();
5092 Iterator<Integer> indexIterator = dirtyIndex.iterator();
5093 for (boolean isNoteDirty: noteDirty.values()) {
5094 int index = indexIterator.next();
5099 BrowserWindow b = tabWindows.get(index).getBrowserWindow();
5100 String guid = b.getNote().getGuid();
5102 thumbnailRunner.addWork("GENERATE "+ guid);
5103 noteDirty.put(index, false);
5107 private void saveNote(String guid, BrowserWindow window) {
5108 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5111 logger.log(logger.EXTREME, "Saving to cache");
5112 QTextCodec codec = QTextCodec.codecForLocale();
5113 // QTextDecoder decoder = codec.makeDecoder();
5114 codec = QTextCodec.codecForName("UTF-8");
5115 QByteArray unicode = codec.fromUnicode(window.getContent());
5116 noteCache.put(guid, unicode.toString());
5118 logger.log(logger.EXTREME, "updating list manager");
5119 listManager.updateNoteContent(guid, window.getContent());
5120 logger.log(logger.EXTREME, "Updating title");
5121 listManager.updateNoteTitle(guid, window.getTitle());
5122 updateListDateChanged();
5124 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5125 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5126 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5127 currentNote = listManager.getNoteIndex().get(i);
5128 i = listManager.getNoteIndex().size();
5133 // Get a note from Evernote (and put it in the browser)
5134 private void refreshEvernoteNote(boolean reload) {
5135 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5137 if (Global.disableViewing) {
5138 browserWindow.setEnabled(false);
5142 inkNote.put(tabBrowser.currentIndex(), false);
5143 readOnly.put(tabBrowser.currentIndex(), false);
5145 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) {
5146 readOnly.put(tabBrowser.currentIndex(), true);
5148 Global.cryptCounter =0;
5149 if (readOnly.get(tabBrowser.currentIndex())) {
5150 browserWindow.setReadOnly(true);
5157 browserWindow.loadingData(true);
5159 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5160 if (currentNote == null) {
5166 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5168 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5172 private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5173 NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
5174 formatter.setNote(note, Global.pdfPreview());
5175 formatter.setHighlight(listManager.getEnSearch());
5180 for (TabBrowse tab: tabWindows.values()) {
5181 if (tab.getBrowserWindow() == browser) {
5182 tabIndex = tabBrowser.indexOf(tab);
5187 if (!noteCache.containsKey(guid)) {
5188 js = new QByteArray();
5189 // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
5190 js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
5191 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>");
5192 js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5193 js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5194 if (Global.displayRightToLeft())
5195 js.append("<style> body { direction:rtl; }</style>");
5196 js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5197 js.append("</head>");
5198 formatter.setNote(note, Global.pdfPreview());
5199 js.append(formatter.rebuildNoteHTML());
5200 js.append("</HTML>");
5201 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5202 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5203 js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5204 // if (Global.enableHTMLEntitiesFix) {
5205 // browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5207 browser.setContent(js);
5208 noteCache.put(guid, js.toString());
5210 if (formatter.resourceError)
5211 resourceErrorMessage(tabIndex);
5212 if (formatter.formatError) {
5214 QMessageBox.information(this, tr("Error"),
5215 tr("NeighborNote had issues formatting this note." +
5216 " To protect your data this note is being marked as read-only."));
5220 if (tabIndex >= 0) {
5221 readOnly.put(tabIndex, formatter.readOnly);
5222 inkNote.put(tabIndex, formatter.inkNote);
5225 if (tabIndex >= 0 && readOnly.get(tabIndex)) {
5226 readOnlyCache.put(guid, true);
5228 if (tabIndex >= 0 && inkNote.get(tabIndex)) {
5229 inkNoteCache.put(guid, true);
5233 logger.log(logger.HIGH, "Note content is being pulled from the cache");
5234 String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5235 js = new QByteArray(cachedContent);
5236 browser.setContent(js);
5237 if (readOnlyCache.containsKey(guid) && tabIndex >= 0) {
5238 readOnly.put(tabIndex, true);
5240 readOnly.put(tabIndex, false);
5242 if (inkNoteCache.containsKey(guid) && tabIndex >= 0) {
5243 inkNote.put(tabIndex, true);
5245 inkNote.put(tabIndex, false);
5248 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5249 thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5251 if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) ||
5252 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != "")))
5253 browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
5255 browser.getBrowser().page().setContentEditable(true);
5256 if (tabIndex >= 0) {
5257 browser.setReadOnly(readOnly.get(tabIndex));
5258 deleteButton.setEnabled(!readOnly.get(tabIndex));
5259 tagButton.setEnabled(!readOnly.get(tabIndex));
5260 menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex));
5261 menuBar.noteTags.setEnabled(!readOnly.get(tabIndex));
5263 browser.setNote(note);
5265 if (note != null && note.getNotebookGuid() != null &&
5266 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5267 deleteButton.setEnabled(false);
5268 menuBar.notebookDeleteAction.setEnabled(false);
5270 deleteButton.setEnabled(true);
5271 menuBar.notebookDeleteAction.setEnabled(true);
5274 // Build a list of non-closed notebooks
5275 List<Notebook> nbooks = new ArrayList<Notebook>();
5276 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5277 boolean found=false;
5278 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5279 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
5283 nbooks.add(listManager.getNotebookIndex().get(i));
5286 browser.setTitle(note.getTitle());
5287 browser.setTag(getTagNamesForNote(note));
5288 browser.setAuthor(note.getAttributes().getAuthor());
5290 browser.setAltered(note.getUpdated());
5291 browser.setCreation(note.getCreated());
5292 if (note.getAttributes().getSubjectDate() > 0)
5293 browser.setSubjectDate(note.getAttributes().getSubjectDate());
5295 browser.setSubjectDate(note.getCreated());
5296 browser.setUrl(note.getAttributes().getSourceURL());
5298 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5299 List<Tag> tagList = tagFilter.getValidTags(note);
5300 browser.setAllTags(tagList);
5302 browser.setCurrentTags(note.getTagNames());
5304 for (TabBrowse tab: tabWindows.values()) {
5305 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
5306 int index = tabBrowser.indexOf(tab);
5307 noteDirty.put(index, false);
5314 browser.loadingData(false);
5315 if (thumbnailViewer.isActiveWindow())
5318 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5319 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5322 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5326 @SuppressWarnings("unused")
5327 private void toggleNoteAttributes() {
5328 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5329 toggleNoteInformation();
5332 // Save a generated thumbnail
5333 private void toggleNoteInformation() {
5334 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5337 boolean isChecked = menuBar.noteAttributes.isChecked();
5339 for(int i = 0; i < tabBrowser.count(); i++){
5340 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5341 boolean isExtended = browser.isExtended();
5342 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5343 browser.toggleInformation();
5347 menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5348 Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5349 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5352 // Listener triggered when a print button is pressed
5353 @SuppressWarnings("unused")
5354 private void printNote() {
5355 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5357 QPrintDialog dialog = new QPrintDialog();
5358 if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5359 QPrinter printer = dialog.printer();
5360 browserWindow.getBrowser().print(printer);
5362 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5365 // Listener triggered when the email button is pressed
5366 @SuppressWarnings("unused")
5367 private void emailNote() {
5368 logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5370 if (Desktop.isDesktopSupported()) {
5371 Desktop desktop = Desktop.getDesktop();
5373 String text2 = browserWindow.getContentsToEmail();
5374 QUrl url = new QUrl("mailto:");
5375 url.addQueryItem("subject", currentNote.getTitle());
5376 // url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5377 url.addQueryItem("body", text2);
5378 QDesktopServices.openUrl(url);
5382 if (desktop.isSupported(Desktop.Action.MAIL)) {
5383 URI uriMailTo = null;
5385 //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5386 String text = browserWindow.getContentsToEmail();
5387 //text = "<b>" +text +"</b>";
5388 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5389 +"&BODY=" +text, null);
5390 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5391 +"&ATTACHMENT=d:/test.pdf", null);
5392 desktop.mail(uriMailTo);
5393 } catch (URISyntaxException e) {
5394 e.printStackTrace();
5395 } catch (IOException e) {
5396 e.printStackTrace();
5403 logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5405 // Reindex all notes
5406 @SuppressWarnings("unused")
5407 private void fullReindex() {
5408 logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5409 indexRunner.addWork("REINDEXALL");
5410 setMessage(tr("Database will be reindexed."));
5411 logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5413 // Listener when a user wants to reindex a specific note
5414 @SuppressWarnings("unused")
5415 private void reindexNote() {
5416 logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5417 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5418 indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5420 if (selectedNotebookGUIDs.size() > 1)
5421 setMessage(tr("Notes will be reindexed."));
5423 setMessage(tr("Note will be reindexed."));
5424 logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5427 @SuppressWarnings("unused")
5428 private void deleteNote() {
5429 logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5430 if (currentNote == null)
5432 if (currentNoteGuid.equals(""))
5434 String title = null;
5435 if (selectedNoteGUIDs.size() == 1)
5436 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5438 // If we are deleting non-trash notes
5439 if (currentNote.isActive()) {
5440 if (Global.verifyDelete()) {
5442 if (selectedNoteGUIDs.size() > 1) {
5443 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5446 msg = new String(tr("Delete note \"") +title +"\"?");
5448 msg = new String(tr("Delete note selected note?"));
5450 if (QMessageBox.question(this, tr("Confirmation"), msg,
5451 QMessageBox.StandardButton.Yes,
5452 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5456 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5457 selectedNoteGUIDs.add(currentNoteGuid);
5458 closeTabs(selectedNoteGUIDs);
5459 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5460 listManager.deleteNote(selectedNoteGUIDs.get(i));
5463 // If we are deleting from the trash.
5464 if (Global.verifyDelete()) {
5466 if (selectedNoteGUIDs.size() > 1) {
5467 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5470 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5472 msg = new String(tr("Permanently delete note selected note?"));
5474 if (QMessageBox.question(this, "Confirmation", msg,
5475 QMessageBox.StandardButton.Yes,
5476 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
5480 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5481 selectedNoteGUIDs.add(currentNoteGuid);
5482 for (int i=selectedNoteGUIDs.size()-1; i>=0; i--) {
5483 for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5484 QModelIndex modelIndex = listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5485 if (modelIndex != null) {
5486 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5487 String tableGuid = (String)ix.values().toArray()[0];
5488 if (tableGuid.equals(selectedNoteGUIDs.get(i))) {
5489 listManager.getNoteTableModel().removeRow(j);
5494 closeTabs(selectedNoteGUIDs);
5495 listManager.expungeNote(selectedNoteGUIDs.get(i));
5498 conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i));
5499 conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i));
5500 conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i));
5504 currentNoteGuid = "";
5505 closeExternalWindows(selectedNoteGUIDs);
5506 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
5507 menuBar.noteAddNewTab.setEnabled(false);
5510 listManager.loadNotesIndex();
5511 noteIndexUpdated(false);
5512 refreshEvernoteNote(true);
5513 scrollToGuid(currentNoteGuid);
5514 logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5517 // 対象ノートをタブで開いていたら閉じる
5518 private void closeTabs(List<String> noteGUIDs) {
5519 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5520 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5521 Collection<Integer> tabIndexes = tabWindows.keySet();
5522 Iterator<Integer> indexIterator = tabIndexes.iterator();
5523 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
5525 while (tabIterator.hasNext()) {
5526 TabBrowse tab = tabIterator.next();
5527 int index = indexIterator.next();
5528 String guid = tab.getBrowserWindow().getNote().getGuid();
5530 for(int i = 0; i < noteGUIDs.size(); i++){
5531 if(guid.equals(noteGUIDs.get(i))){
5532 closeIndexes.add(index);
5537 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5538 tabWindowClosing(closeIndexes.get(i));
5542 // 対象ノートを外部ウィンドウで開いていたら閉じる
5543 private void closeExternalWindows(List<String> noteGUIDs) {
5544 Collection<ExternalBrowse> windows = externalWindows.values();
5545 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5546 Collection<String> guids = externalWindows.keySet();
5547 Iterator<String> guidIterator = guids.iterator();
5548 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5550 while (windowIterator.hasNext()) {
5551 ExternalBrowse browser = windowIterator.next();
5552 String guid = guidIterator.next();
5554 for (int i = 0; i < noteGUIDs.size(); i++) {
5555 if (guid.equals(noteGUIDs.get(i))) {
5556 closeWindows.add(browser);
5561 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5562 closeWindows.get(i).close();
5567 private void addNote() {
5568 logger.log(logger.HIGH, "Inside NeverNote.addNote");
5569 // browserWindow.setEnabled(true);
5570 browserWindow.setReadOnly(false);
5572 Calendar currentTime = new GregorianCalendar();
5573 StringBuffer noteString = new StringBuffer(100);
5574 noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5575 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5578 if (Global.overrideDefaultFont()) {
5579 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5580 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5581 noteString.append("<br clear=\"none\" />\n");
5582 noteString.append("</span>\n</font>\n");
5584 noteString.append("<br clear=\"none\" />\n");
5585 noteString.append("</en-note>");
5587 Long l = new Long(currentTime.getTimeInMillis());
5588 String randint = new String(Long.toString(l));
5590 // Find a notebook. We first look for a selected notebook (the "All Notebooks" one doesn't count).
5592 // for the first non-archived notebook. Finally, if nothing else we
5593 // pick the first notebook in the list.
5594 String notebook = null;
5595 listManager.getNotebookIndex().get(0).getGuid();
5596 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5597 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5598 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5599 notebook = currentSelectedNotebook.text(2);
5601 boolean found = false;
5602 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5603 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5604 boolean match = false;
5605 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5606 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5608 j = listManager.getArchiveNotebookIndex().size();
5612 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5613 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5615 // Now we have a list of good notebooks, so we can look for the default
5617 for (int i=0; i<goodNotebooks.size(); i++) {
5618 if (goodNotebooks.get(i).isDefaultNotebook()) {
5619 notebook = goodNotebooks.get(i).getGuid();
5621 i = goodNotebooks.size();
5625 if (goodNotebooks.size() > 0 && !found)
5626 notebook = goodNotebooks.get(0).getGuid();
5629 notebook = listManager.getNotebookIndex().get(0).getGuid();
5632 Note newNote = new Note();
5633 newNote.setUpdateSequenceNum(0);
5634 newNote.setGuid(randint);
5635 newNote.setNotebookGuid(notebook);
5636 newNote.setTitle("Untitled Note");
5637 newNote.setContent(noteString.toString());
5638 newNote.setDeleted(0);
5639 newNote.setCreated(System.currentTimeMillis());
5640 newNote.setUpdated(System.currentTimeMillis());
5641 newNote.setActive(true);
5642 NoteAttributes na = new NoteAttributes();
5643 na.setLatitude(0.0);
5644 na.setLongitude(0.0);
5645 na.setAltitude(0.0);
5646 newNote.setAttributes(new NoteAttributes());
5647 newNote.setTagGuids(new ArrayList<String>());
5648 newNote.setTagNames(new ArrayList<String>());
5650 // If new notes are to be created based upon the selected tags, then we need to assign the tags
5651 if (Global.newNoteWithSelectedTags()) {
5652 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5653 QTreeWidgetItem currentSelection;
5654 for (int i=0; i<selections.size(); i++) {
5655 currentSelection = selections.get(i);
5656 newNote.getTagGuids().add(currentSelection.text(2));
5657 newNote.getTagNames().add(currentSelection.text(0));
5661 conn.getNoteTable().addNote(newNote, true);
5662 NoteMetadata metadata = new NoteMetadata();
5663 metadata.setGuid(newNote.getGuid());
5664 metadata.setDirty(true);
5665 listManager.addNote(newNote, metadata);
5666 // noteTableView.insertRow(newNote, true, -1);
5669 String prevCurrentNoteGuid = new String(currentNoteGuid);
5671 currentNote = newNote;
5672 currentNoteGuid = currentNote.getGuid();
5673 // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5674 // noteTableView.clearSelection();
5676 // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加
5677 if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5678 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5679 conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5683 refreshEvernoteNote(true);
5684 listManager.countNotebookResults(listManager.getNoteIndex());
5685 browserWindow.titleLabel.setFocus();
5686 browserWindow.titleLabel.selectAll();
5687 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5689 // If the window is hidden, then we want to popup this in an external window &
5693 logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5695 // Restore a note from the trash;
5696 @SuppressWarnings("unused")
5697 private void restoreNote() {
5699 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5700 selectedNoteGUIDs.add(currentNoteGuid);
5701 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5702 listManager.restoreNote(selectedNoteGUIDs.get(i));
5704 currentNoteGuid = "";
5705 listManager.loadNotesIndex();
5706 noteIndexUpdated(false);
5709 // Search a note for specific txt
5710 @SuppressWarnings("unused")
5711 private void findText() {
5713 find.setFocusOnTextField();
5715 @SuppressWarnings("unused")
5716 private void doFindText() {
5717 browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5720 @SuppressWarnings("unused")
5721 private void updateNoteTitle(String guid, String title) {
5722 listManager.setNoteSynchronized(guid, false);
5724 // We do this manually because if we've edited the note in an
5725 // external window we run into the possibility of signal recursion
5727 if (guid.equals(currentNoteGuid)) {
5728 browserWindow.titleLabel.blockSignals(true);
5729 browserWindow.titleLabel.setText(title);
5730 browserWindow.titleLabel.blockSignals(false);
5733 // Signal received that note content has changed. Normally we just need the guid to remove
5734 // it from the cache.
5735 @SuppressWarnings("unused")
5736 private void invalidateNoteCache(String guid, String content) {
5737 noteCache.remove(guid);
5738 refreshEvernoteNote(true);
5740 // Signal received that a note guid has changed
5741 @SuppressWarnings("unused")
5742 private void noteGuidChanged(String oldGuid, String newGuid) {
5743 if (noteCache.containsKey(oldGuid)) {
5744 if (!oldGuid.equals(currentNoteGuid)) {
5745 String cache = noteCache.get(oldGuid);
5746 noteCache.put(newGuid, cache);
5747 noteCache.remove(oldGuid);
5749 noteCache.remove(oldGuid);
5750 noteCache.put(newGuid, browserWindow.getContent());
5754 listManager.updateNoteGuid(oldGuid, newGuid, false);
5755 if (currentNoteGuid.equals(oldGuid)) {
5756 if (currentNote != null)
5757 currentNote.setGuid(newGuid);
5758 currentNoteGuid = newGuid;
5761 if (externalWindows.containsKey(oldGuid)) {
5762 ExternalBrowse b = externalWindows.get(oldGuid);
5763 externalWindows.remove(oldGuid);
5764 b.getBrowserWindow().getNote().setGuid(newGuid);
5765 externalWindows.put(newGuid, b);
5769 for(int i = 0; i < tabBrowser.count(); i++){
5770 TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5771 if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) {
5772 b.getBrowserWindow().getNote().setGuid(newGuid);
5776 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5777 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5778 noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5779 i=listManager.getNoteIndex().size();
5783 if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5784 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5785 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5786 listManager.getNoteTableModel().metaData.remove(oldGuid);
5791 // Toggle the note editor button bar
5793 private void toggleEditorButtonBar() {
5794 boolean isChecked = menuBar.showEditorBar.isChecked();
5796 for(int i = 0; i < tabBrowser.count(); i++){
5797 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5798 boolean isVisible = browser.buttonsVisible;
5800 if (isChecked && !isVisible) {
5801 browser.buttonsVisible = true;
5802 showEditorButtons(browser);
5803 } else if(!isChecked && isVisible) {
5804 browser.hideButtons();
5808 Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5811 // Show editor buttons
5812 private void showEditorButtons(BrowserWindow browser) {
5813 browser.buttonLayout.setVisible(true);
5814 browser.undoAction.setVisible(false);
5816 browser.undoButton.setVisible(false);
5818 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5819 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5820 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5821 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5822 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5823 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5824 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5825 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5826 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5827 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5828 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5829 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5830 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5831 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5832 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5833 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5834 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5835 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5836 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5837 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5838 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5839 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5840 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5842 private void duplicateNote(String guid) {
5844 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5845 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5846 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5847 oldNote.setResources(resList);
5848 duplicateNote(oldNote);
5850 private void duplicateNote(Note oldNote) {
5852 // Now that we have a good notebook guid, we need to move the conflicting note
5853 // to the local notebook
5854 Calendar currentTime = new GregorianCalendar();
5855 Long l = new Long(currentTime.getTimeInMillis());
5856 String newGuid = new String(Long.toString(l));
5858 // Note newNote = oldNote.deepCopy();
5859 Note newNote = (Note)Global.deepCopy(oldNote);
5860 newNote.setUpdateSequenceNum(0);
5861 newNote.setGuid(newGuid);
5862 newNote.setDeleted(0);
5863 newNote.setActive(true);
5866 List<String> tagNames = new ArrayList<String>();
5867 List<String> tagGuids = new ArrayList<String>();;
5868 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5869 tagNames.add(oldNote.getTagNames().get(i));
5870 tagGuids.add(oldNote.getTagGuids().get(i));
5873 // Sort note Tags to make them look nice
5874 for (int i=0; i<tagNames.size()-1; i++) {
5875 if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5876 String n1 = tagNames.get(i);
5877 String n2 = tagNames.get(i+1);
5878 tagNames.set(i, n2);
5879 tagNames.set(i+1, n1);
5882 newNote.setTagGuids(tagGuids);
5883 newNote.setTagNames(tagNames);
5885 // Add tag guids to note
5888 // Duplicate resources
5889 List<Resource> resList = oldNote.getResources();
5890 if (resList == null)
5891 resList = new ArrayList<Resource>();
5893 for (int i=0; i<resList.size(); i++) {
5895 while (l == prevGuid) {
5896 currentTime = new GregorianCalendar();
5897 l = new Long(currentTime.getTimeInMillis());
5900 String newResGuid = new String(Long.toString(l));
5901 resList.get(i).setNoteGuid(newGuid);
5902 resList.get(i).setGuid(newResGuid);
5903 resList.get(i).setUpdateSequenceNum(0);
5904 resList.get(i).setActive(true);
5905 conn.getNoteTable().noteResourceTable.saveNoteResource(
5906 (Resource)Global.deepCopy(resList.get(i)), true);
5908 newNote.setResources(resList);
5911 // 操作履歴と除外ノートとスター付きノートも複製する
5912 if(Global.getDuplicateRensoNote()) {
5913 conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5914 conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5915 conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5918 // Add note to the database
5919 conn.getNoteTable().addNote(newNote, true);
5920 NoteMetadata metaData = new NoteMetadata();
5921 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5922 metaData.copy(oldMeta);
5923 metaData.setGuid(newNote.getGuid());
5924 listManager.addNote(newNote, metaData);
5925 noteTableView.insertRow(newNote, metaData, true, -1);
5926 currentNoteGuid = newNote.getGuid();
5927 currentNote = newNote;
5928 refreshEvernoteNote(true);
5929 listManager.countNotebookResults(listManager.getNoteIndex());
5934 @SuppressWarnings("unused")
5935 private void allNotes() {
5936 clearAttributeFilter();
5937 clearNotebookFilter();
5938 clearSavedSearchFilter();
5941 searchField.clear();
5942 if (Global.mimicEvernoteInterface) {
5943 notebookTree.selectGuid("");
5945 notebookTreeSelection();
5946 refreshEvernoteNote(true);
5948 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5949 if (!rensoNoteListDock.isEnabled()) {
5950 rensoNoteListDock.setEnabled(true);
5954 @SuppressWarnings("unused")
5955 private void mergeNotes() {
5956 logger.log(logger.HIGH, "Merging notes");
5959 String masterGuid = null;
5960 List<String> sources = new ArrayList<String>();
5962 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5963 int r = noteTableView.selectionModel().selectedRows().get(i).row();
5964 index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5965 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5967 masterGuid = (String)ix.values().toArray()[0];
5969 sources.add((String)ix.values().toArray()[0]);
5972 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5973 logger.log(logger.EXTREME, "Children count: "+sources.size());
5974 mergeNoteContents(masterGuid, sources);
5975 currentNoteGuid = masterGuid;
5977 // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ
5978 if(Global.getMergeRensoNote()) {
5979 for (int i = 0; i < sources.size(); i++) {
5980 String childGuid = sources.get(i);
5981 if(masterGuid != null && childGuid != null) {
5982 if(!masterGuid.equals(childGuid)) {
5983 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
5984 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
5985 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
5991 // ICHANGED ↓↓↓ここから↓↓↓
5992 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
5993 Collection<ExternalBrowse> windows = externalWindows.values();
5994 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5995 Collection<String> guids = externalWindows.keySet();
5996 Iterator<String> guidIterator = guids.iterator();
5997 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5999 while (windowIterator.hasNext()) {
6000 ExternalBrowse browser = windowIterator.next();
6001 String guid = guidIterator.next();
6003 for (int i = 0; i < sources.size(); i++) {
6004 if (guid.equals(sources.get(i))) {
6005 closeWindows.add(browser);
6010 for (int i = closeWindows.size() - 1; i >= 0; i--) {
6011 closeWindows.get(i).close();
6013 // ICHANGED ↑↑↑ここまで↑↑↑
6015 // ICHANGED ↓↓↓ここから↓↓↓
6016 // マージしたノート(child)をタブで開いていたら、閉じる
6017 Collection<TabBrowse> tabBrowsers = tabWindows.values();
6018 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
6019 Collection<Integer> tabIndexes = tabWindows.keySet();
6020 Iterator<Integer> indexIterator = tabIndexes.iterator();
6021 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
6023 while (tabIterator.hasNext()) {
6024 TabBrowse tab = tabIterator.next();
6025 int tabIndex = indexIterator.next();
6026 String guid = tab.getBrowserWindow().getNote().getGuid();
6028 for(int i = 0; i < sources.size(); i++){
6029 if(guid.equals(sources.get(i))){
6030 closeIndexes.add(tabIndex);
6035 for(int i = closeIndexes.size() - 1; i >= 0; i--){
6036 tabWindowClosing(closeIndexes.get(i));
6038 // ICHANGED ↑↑↑ここまで↑↑↑
6040 noteIndexUpdated(false);
6042 // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除
6043 noteCache.remove(masterGuid);
6045 refreshEvernoteNote(true);
6048 private void mergeNoteContents(String targetGuid, List<String> sources) {
6049 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
6050 String newContent = target.getContent();
6051 newContent = newContent.replace("</en-note>", "<br></br>");
6053 for (int i=0; i<sources.size(); i++) {
6054 Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
6055 if (source.isSetTitle()) {
6056 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
6058 String sourceContent = source.getContent();
6059 logger.log(logger.EXTREME, "Merging contents into note");
6060 logger.log(logger.EXTREME, sourceContent);
6061 logger.log(logger.EXTREME, "End of content");
6062 int startOfNote = sourceContent.indexOf("<en-note>");
6063 sourceContent = sourceContent.substring(startOfNote+9);
6064 int endOfNote = sourceContent.indexOf("</en-note>");
6065 sourceContent = sourceContent.substring(0,endOfNote);
6066 newContent = newContent + sourceContent;
6067 logger.log(logger.EXTREME, "New note content");
6068 logger.log(logger.EXTREME, newContent);
6069 logger.log(logger.EXTREME, "End of content");
6070 for (int j=0; j<source.getResourcesSize(); j++) {
6071 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
6072 Resource r = source.getResources().get(j);
6073 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
6075 Calendar currentTime = new GregorianCalendar();
6076 Long l = new Long(currentTime.getTimeInMillis());
6080 while (l == prevGuid) {
6081 currentTime = new GregorianCalendar();
6082 l = new Long(currentTime.getTimeInMillis());
6084 String newResGuid = new String(Long.toString(l));
6085 newRes.setNoteGuid(targetGuid);
6086 newRes.setGuid(newResGuid);
6087 newRes.setUpdateSequenceNum(0);
6088 newRes.setActive(true);
6089 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
6092 logger.log(logger.EXTREME, "Updating note");
6093 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
6094 for (int i=0; i<sources.size(); i++) {
6095 logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
6096 listManager.deleteNote(sources.get(i));
6098 logger.log(logger.EXTREME, "Exiting merge note");
6100 // A resource within a note has had a guid change
6101 @SuppressWarnings("unused")
6102 private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
6103 if (oldGuid != null && !oldGuid.equals(newGuid))
6104 Global.resourceMap.put(oldGuid, newGuid);
6106 // View a thumbnail of the note
6107 public void thumbnailView() {
6109 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
6110 QFile thumbnail = new QFile(thumbnailName);
6111 if (!thumbnail.exists()) {
6113 QImage img = new QImage();
6114 img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
6115 thumbnailViewer.setThumbnail(img);
6117 thumbnailViewer.setThumbnail(thumbnailName);
6118 if (!thumbnailViewer.isVisible())
6119 thumbnailViewer.showFullScreen();
6121 // An error happened while saving a note. Inform the user
6122 @SuppressWarnings("unused")
6123 private void saveRunnerError(String guid, String msg) {
6125 String title = "*Unknown*";
6126 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6127 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6128 title = listManager.getMasterNoteIndex().get(i).getTitle();
6129 i=listManager.getMasterNoteIndex().size();
6132 msg = tr("An error has happened while saving the note \"") +title+
6133 tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
6134 "As a result, changes to the note may not be saved properly in the database."+
6135 "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6136 "\nbe lost. Please review the note to recover any critical data before restarting.");
6138 QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6141 private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6142 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6143 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6144 // Find an idle preview object
6145 for (int i=0; i<thumbGenerators.size(); i++) {
6146 if (thumbGenerators.get(i).mutex.tryLock()) {
6147 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6148 thumbGenerators.get(i).loadContent(guid, html, zoom);
6152 if (thumbGenerators.size() >= 1) {
6153 logger.log(logger.EXTREME, "No available thumbnail generators. Aborting " +guid);
6157 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6158 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6159 thumbGenerators.add(preview);
6161 if (preview.mutex.tryLock()) {
6162 logger.log(logger.EXTREME, "Loading thumbnail for " +guid);
6163 preview.loadContent(guid, html, zoom);
6165 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6170 //**********************************************************
6171 //**********************************************************
6172 //* Online user actions
6173 //**********************************************************
6174 //**********************************************************
6175 private void setupOnlineMenu() {
6176 if (!Global.isConnected) {
6177 menuBar.noteOnlineHistoryAction.setEnabled(false);
6178 menuBar.selectiveSyncAction.setEnabled(false);
6181 menuBar.noteOnlineHistoryAction.setEnabled(true);
6182 menuBar.selectiveSyncAction.setEnabled(true);
6185 @SuppressWarnings("unused")
6186 private void viewNoteHistory() {
6187 if (currentNoteGuid == null || currentNoteGuid.equals(""))
6189 if (currentNote.getUpdateSequenceNum() == 0) {
6190 setMessage(tr("Note has never been synchronized."));
6191 QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6195 setMessage(tr("Getting Note History"));
6197 Note currentOnlineNote = null;
6200 if (Global.isPremium())
6201 versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6203 versions = new ArrayList<NoteVersionId>();
6204 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6205 } catch (EDAMUserException e) {
6206 setMessage("EDAMUserException: " +e.getMessage());
6208 } catch (EDAMSystemException e) {
6209 setMessage("EDAMSystemException: " +e.getMessage());
6211 } catch (EDAMNotFoundException e) {
6212 setMessage(tr("Note not found on server."));
6213 QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6215 } catch (TException e) {
6216 setMessage("EDAMTransactionException: " +e.getMessage());
6220 // If we've gotten this far, we have a good note.
6221 if (historyWindow == null) {
6223 historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6225 historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6226 historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6227 historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6229 historyWindow.historyCombo.clear();
6231 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6232 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6234 historyWindow.setCurrent(isDirty);
6236 loadHistoryWindowContent(currentOnlineNote);
6237 historyWindow.load(versions);
6238 setMessage(tr("History retrieved"));
6240 historyWindow.exec();
6242 private Note reloadHistoryWindow(String selection) {
6244 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6245 String dateTimeFormat = new String(fmt);
6246 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6250 for (int i=0; i<versions.size(); i++) {
6251 StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6252 if (versionDate.toString().equals(selection))
6256 if (index > -1 || selection.indexOf("Current") > -1) {
6257 Note historyNote = null;
6260 usn = versions.get(index).getUpdateSequenceNum();
6261 historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6263 historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6264 } catch (EDAMUserException e) {
6265 setMessage("EDAMUserException: " +e.getMessage());
6268 } catch (EDAMSystemException e) {
6269 setMessage("EDAMSystemException: " +e.getMessage());
6272 } catch (EDAMNotFoundException e) {
6273 setMessage("EDAMNotFoundException: " +e.getMessage());
6276 } catch (TException e) {
6277 setMessage("EDAMTransactionException: " +e.getMessage());
6283 if (historyNote != null)
6284 historyWindow.setContent(historyNote);
6290 private void loadHistoryWindowContent(Note note) {
6291 note.setUpdateSequenceNum(0);
6292 historyWindow.setContent(note);
6294 @SuppressWarnings("unused")
6295 private void restoreHistoryNoteAsNew() {
6296 setMessage(tr("Restoring as new note."));
6297 duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6298 setMessage(tr("Note has been restored as a new note."));
6300 @SuppressWarnings("unused")
6301 private void restoreHistoryNote() {
6302 setMessage(tr("Restoring note."));
6303 Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6304 conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6307 for (int i=0; i<n.getResourcesSize(); i++) {
6308 n.getResources().get(i).setActive(true);
6309 conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6311 NoteMetadata metadata = new NoteMetadata();
6312 metadata.setGuid(n.getGuid());
6313 listManager.addNote(n, metadata);
6314 conn.getNoteTable().addNote(n, true);
6315 refreshEvernoteNote(true);
6316 setMessage(tr("Note has been restored."));
6318 @SuppressWarnings("unused")
6319 private void setupSelectiveSync() {
6321 // Get a list of valid notebooks
6322 List<Notebook> notebooks = null;
6323 List<Tag> tags = null;
6324 List<LinkedNotebook> linkedNotebooks = null;
6326 notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6327 tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6328 linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6329 } catch (EDAMUserException e) {
6330 setMessage("EDAMUserException: " +e.getMessage());
6332 } catch (EDAMSystemException e) {
6333 setMessage("EDAMSystemException: " +e.getMessage());
6335 } catch (TException e) {
6336 setMessage("EDAMTransactionException: " +e.getMessage());
6338 } catch (EDAMNotFoundException e) {
6339 setMessage("EDAMNotFoundException: " +e.getMessage());
6343 // Split up notebooks into synchronized & non-synchronized
6344 List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6345 List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6347 for (int i=notebooks.size()-1; i>=0; i--) {
6348 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6349 if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6350 ignoredBooks.add(notebooks.get(i));
6351 j=dbIgnoredNotebooks.size();
6356 // split up tags into synchronized & non-synchronized
6357 List<Tag> ignoredTags = new ArrayList<Tag>();
6358 List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6360 for (int i=tags.size()-1; i>=0; i--) {
6361 for (int j=0; j<dbIgnoredTags.size(); j++) {
6362 if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6363 ignoredTags.add(tags.get(i));
6364 j=dbIgnoredTags.size();
6369 // split up linked notebooks into synchronized & non-synchronized
6370 List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6371 List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6372 for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6373 String notebookGuid = linkedNotebooks.get(i).getGuid();
6374 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6375 if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6376 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6377 j=dbIgnoredLinkedNotebooks.size();
6382 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6384 if (!ignore.okClicked())
6389 // Clear out old notebooks & add the new ones
6390 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6391 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6392 conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6395 List<String> newNotebooks = new ArrayList<String>();
6396 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6397 String text = ignore.getIgnoredBookList().takeItem(i).text();
6398 for (int j=0; j<notebooks.size(); j++) {
6399 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6400 Notebook n = notebooks.get(j);
6401 conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6403 newNotebooks.add(n.getGuid());
6408 // Clear out old tags & add new ones
6409 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6410 for (int i=0; i<oldIgnoreTags.size(); i++) {
6411 conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6414 List<String> newTags = new ArrayList<String>();
6415 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6416 String text = ignore.getIgnoredTagList().takeItem(i).text();
6417 for (int j=0; j<tags.size(); j++) {
6418 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6419 Tag t = tags.get(j);
6420 conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6421 newTags.add(t.getGuid());
6427 // Clear out old tags & add new ones
6428 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6429 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6430 conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6433 List<String> newLinked = new ArrayList<String>();
6434 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6435 String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6436 for (int j=0; j<linkedNotebooks.size(); j++) {
6437 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6438 LinkedNotebook t = linkedNotebooks.get(j);
6439 conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6440 newLinked.add(t.getGuid());
6441 j=linkedNotebooks.size();
6446 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6452 //**********************************************************
6453 //**********************************************************
6454 //* XML Modifying methods
6455 //**********************************************************
6456 //**********************************************************
6457 // An error has happended fetching a resource. let the user know
6459 private void resourceErrorMessage(int tabIndex) {
6463 if (inkNote.get(tabIndex))
6466 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6467 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6468 "In a perfect world this wouldn't happen, but it has.\n" +
6469 "It is embarasing when a program like me, designed to save all your\n"+
6470 "precious data, has a problem finding data.\n\n" +
6471 "I guess life isn't fair, but I'll survive. Somehow...\n\n" +
6472 "In the mean time, I'm not going to let you make changes to this note.\n" +
6473 "Don't get angry. I'm doing it to prevent you from messing up\n"+
6474 "this note on the Evernote servers. Sorry."+
6475 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6476 inkNote.put(tabIndex, true);
6477 browserWindow.setReadOnly(true);
6484 //**********************************************************
6485 //**********************************************************
6487 //**********************************************************
6488 //**********************************************************
6489 // We should now do a sync with Evernote
6490 private void syncTimer() {
6491 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6492 syncRunner.syncNeeded = true;
6493 syncRunner.disableUploads = Global.disableUploads;
6495 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6497 private void syncStart() {
6498 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6500 if (!syncRunning && Global.isConnected) {
6501 syncRunner.setConnected(true);
6502 syncRunner.setKeepRunning(Global.keepRunning);
6503 syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6505 if (syncThreadsReady > 0) {
6506 thumbnailRunner.interrupt = true;
6507 saveNoteIndexWidth();
6508 saveNoteColumnPositions();
6509 if (syncRunner.addWork("SYNC")) {
6511 syncRunner.syncNeeded = true;
6516 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6518 @SuppressWarnings("unused")
6519 private void syncThreadComplete(Boolean refreshNeeded) {
6520 setMessage(tr("Finalizing Synchronization"));
6522 syncRunning = false;
6523 syncRunner.syncNeeded = false;
6524 synchronizeAnimationTimer.stop();
6525 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6527 if (currentNote == null) {
6528 currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6530 listManager.refreshNoteMetadata();
6531 noteIndexUpdated(true);
6532 noteTableView.selectionModel().blockSignals(true);
6533 scrollToGuid(currentNoteGuid);
6534 noteTableView.selectionModel().blockSignals(false);
6535 refreshEvernoteNote(false);
6536 scrollToGuid(currentNoteGuid);
6539 // Check to see if there were any shared notebook errors
6540 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6541 String guid = syncRunner.errorSharedNotebooks.get(0);
6542 String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6543 String localName = listManager.getNotebookNameByGuid(notebookGuid);
6544 SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6546 if (syncDialog.okPressed()) {
6547 if (syncDialog.doNothing.isChecked()) {
6548 syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6551 if (syncDialog.deleteNotebook.isChecked()) {
6552 conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6553 conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6554 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6555 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6563 // Finalize the synchronization
6564 if (!syncRunner.error)
6565 setMessage(tr("Synchronization Complete"));
6567 setMessage(tr("Synchronization completed with errors. Please check the log for details."));
6568 logger.log(logger.MEDIUM, "Sync complete.");
6570 public void saveUploadAmount(long t) {
6571 Global.saveUploadAmount(t);
6573 public void saveUserInformation(User user) {
6574 Global.saveUserInformation(user);
6576 public void saveEvernoteUpdateCount(int i) {
6577 Global.saveEvernoteUpdateCount(i);
6579 public void refreshLists() {
6580 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6583 // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。
6584 Collection<Integer> tabIndex = noteDirty.keySet();
6585 Iterator<Integer> indexIterator = tabIndex.iterator();
6586 HashMap<Integer, Note> saveNotes = new HashMap<Integer, Note>();
6587 HashMap<Integer, String> saveContents = new HashMap<Integer, String>();
6588 for (boolean isNoteDirty: noteDirty.values()) {
6589 int index = indexIterator.next();
6591 saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote());
6592 saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent());
6596 listManager.saveUpdatedNotes(saveNotes, saveContents);
6597 listManager.refreshLists();
6599 tagIndexUpdated(true);
6600 notebookIndexUpdated();
6601 savedSearchIndexUpdated();
6602 listManager.loadNotesIndex();
6604 noteTableView.selectionModel().blockSignals(true);
6605 noteIndexUpdated(true);
6606 noteTableView.selectionModel().blockSignals(false);
6607 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6611 @SuppressWarnings("unused")
6612 private void authTimer() {
6613 Calendar cal = Calendar.getInstance();
6615 // If we are not connected let's get out of here
6616 if (!Global.isConnected)
6619 // If this is the first time through, then we need to set this
6620 // if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime)
6621 // syncRunner.authRefreshTime = cal.getTimeInMillis();
6623 // long now = new Date().getTime();
6624 // if (now > Global.authRefreshTime && Global.isConnected) {
6625 syncRunner.authRefreshNeeded = true;
6629 @SuppressWarnings("unused")
6630 private void authRefreshComplete(boolean goodSync) {
6631 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6632 Global.isConnected = syncRunner.isConnected;
6634 // authTimer.start((int)syncRunner.authTimeRemaining/4);
6635 authTimer.start(1000*60*15);
6636 logger.log(logger.LOW, "Authentication token has been renewed");
6637 // setMessage("Authentication token has been renewed.");
6639 authTimer.start(1000*60*5);
6640 logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6641 // setMessage("Authentication token renew has failed - retry in 5 minutes.");
6643 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6647 @SuppressWarnings("unused")
6648 private synchronized void indexTimer() {
6649 logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning);
6652 if (!indexDisabled && indexRunner.idle) {
6653 thumbnailRunner.interrupt = true;
6654 indexRunner.addWork("SCAN");
6656 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6659 @SuppressWarnings("unused")
6660 private void indexStarted() {
6661 setMessage(tr("Indexing notes"));
6663 @SuppressWarnings("unused")
6664 private void indexComplete() {
6665 setMessage(tr("Index complete"));
6667 @SuppressWarnings("unused")
6668 private synchronized void toggleNoteIndexing() {
6669 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6670 indexDisabled = !indexDisabled;
6672 setMessage(tr("Indexing is now enabled."));
6674 setMessage(tr("Indexing is now disabled."));
6675 menuBar.disableIndexing.setChecked(indexDisabled);
6676 logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6679 @SuppressWarnings("unused")
6680 private void threadMonitorCheck() {
6685 alive = listManager.threadCheck(Global.tagCounterThreadId);
6688 if (tagDeadCount > MAX && !disableTagThreadCheck) {
6689 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
6690 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6691 disableTagThreadCheck = true;
6696 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6698 notebookThreadDeadCount++;
6699 if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6700 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
6701 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6702 disableNotebookThreadCheck=true;
6705 notebookThreadDeadCount=0;
6707 alive = listManager.threadCheck(Global.trashCounterThreadId);
6710 if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6711 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
6712 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6713 disableTrashThreadCheck = true;
6718 alive = listManager.threadCheck(Global.saveThreadId);
6720 saveThreadDeadCount++;
6721 if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6722 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
6723 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6724 disableSaveThreadCheck = true;
6727 saveThreadDeadCount=0;
6729 if (!syncThread.isAlive()) {
6730 syncThreadDeadCount++;
6731 if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6732 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
6733 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6734 disableSyncThreadCheck = true;
6737 syncThreadDeadCount=0;
6739 if (!indexThread.isAlive()) {
6740 indexThreadDeadCount++;
6741 if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6742 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
6743 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6744 disableIndexThreadCheck = true;
6747 indexThreadDeadCount=0;
6752 private void thumbnailTimer() {
6753 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6754 thumbnailRunner.addWork("SCAN");
6758 //**************************************************
6759 //* Backup & Restore
6760 //**************************************************
6761 @SuppressWarnings("unused")
6762 private void databaseBackup() {
6763 QFileDialog fd = new QFileDialog(this);
6764 fd.setFileMode(FileMode.AnyFile);
6765 fd.setConfirmOverwrite(true);
6766 fd.setWindowTitle(tr("Backup Database"));
6767 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6768 fd.setAcceptMode(AcceptMode.AcceptSave);
6769 if (saveLastPath == null || saveLastPath.equals(""))
6770 fd.setDirectory(System.getProperty("user.home"));
6772 fd.setDirectory(saveLastPath);
6773 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6779 saveLastPath = fd.selectedFiles().get(0);
6780 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6781 setMessage(tr("Backing up database"));
6783 // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6785 ExportData noteWriter = new ExportData(conn, true);
6786 String fileName = fd.selectedFiles().get(0);
6788 if (!fileName.endsWith(".nnex"))
6789 fileName = fileName +".nnex";
6790 noteWriter.exportData(fileName);
6791 setMessage(tr("Database backup completed."));
6796 @SuppressWarnings("unused")
6797 private void databaseRestore() {
6798 if (QMessageBox.question(this, tr("Confirmation"),
6799 tr("This is used to restore a database from backups.\n" +
6800 "It is HIGHLY recommened that this only be used to populate\n" +
6801 "an empty database. Restoring into a database that\n already has data" +
6802 " can cause problems.\n\nAre you sure you want to continue?"),
6803 QMessageBox.StandardButton.Yes,
6804 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6809 QFileDialog fd = new QFileDialog(this);
6810 fd.setFileMode(FileMode.ExistingFile);
6811 fd.setConfirmOverwrite(true);
6812 fd.setWindowTitle(tr("Restore Database"));
6813 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6814 fd.setAcceptMode(AcceptMode.AcceptOpen);
6815 if (saveLastPath == null || saveLastPath.equals(""))
6816 fd.setDirectory(System.getProperty("user.home"));
6818 fd.setDirectory(saveLastPath);
6819 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6825 saveLastPath = fd.selectedFiles().get(0);
6826 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6828 setMessage(tr("Restoring database"));
6829 ImportData noteReader = new ImportData(conn, true);
6830 noteReader.importData(fd.selectedFiles().get(0));
6832 if (noteReader.lastError != 0) {
6833 setMessage(noteReader.getErrorMessage());
6834 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6839 listManager.loadNoteTitleColors();
6841 refreshEvernoteNote(true);
6842 setMessage(tr("Database has been restored."));
6845 @SuppressWarnings("unused")
6846 private void exportNotes() {
6847 QFileDialog fd = new QFileDialog(this);
6848 fd.setFileMode(FileMode.AnyFile);
6849 fd.setConfirmOverwrite(true);
6850 fd.setWindowTitle(tr("Backup Database"));
6851 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6852 fd.setAcceptMode(AcceptMode.AcceptSave);
6853 fd.setDirectory(System.getProperty("user.home"));
6854 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6860 setMessage(tr("Exporting Notes"));
6863 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6864 selectedNoteGUIDs.add(currentNoteGuid);
6866 ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6867 String fileName = fd.selectedFiles().get(0);
6869 if (!fileName.endsWith(".nnex"))
6870 fileName = fileName +".nnex";
6871 noteWriter.exportData(fileName);
6872 setMessage(tr("Export completed."));
6878 @SuppressWarnings("unused")
6879 private void importNotes() {
6880 QFileDialog fd = new QFileDialog(this);
6881 fd.setFileMode(FileMode.ExistingFile);
6882 fd.setConfirmOverwrite(true);
6883 fd.setWindowTitle(tr("Import Notes"));
6884 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6885 fd.setAcceptMode(AcceptMode.AcceptOpen);
6886 if (saveLastPath == null || saveLastPath.equals(""))
6887 fd.setDirectory(System.getProperty("user.home"));
6889 fd.setDirectory(saveLastPath);
6890 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6896 setMessage(tr("Importing Notes"));
6899 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6900 selectedNoteGUIDs.add(currentNoteGuid);
6902 String fileName = fd.selectedFiles().get(0);
6903 // saveLastPath.substring(0,fileName.lastIndexOf("/"));
6905 if (fileName.endsWith(".nnex")) {
6906 ImportData noteReader = new ImportData(conn, false);
6907 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6908 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6910 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6912 noteReader.importData(fileName);
6914 if (noteReader.lastError != 0) {
6915 setMessage(noteReader.getErrorMessage());
6916 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6921 if (fileName.endsWith(".enex")) {
6922 ImportEnex noteReader = new ImportEnex(conn, false);
6923 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6924 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6926 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6929 if (QMessageBox.question(this, tr("Confirmation"),
6930 tr("Create new tags from import?"),
6931 QMessageBox.StandardButton.Yes,
6932 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6933 noteReader.createNewTags = true;
6935 noteReader.createNewTags = false;
6937 noteReader.importData(fileName);
6939 if (noteReader.lastError != 0) {
6940 setMessage(noteReader.getErrorMessage());
6941 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6948 listManager.loadNoteTitleColors();
6950 refreshEvernoteNote(false);
6951 setMessage(tr("Notes have been imported."));
6954 setMessage(tr("Import completed."));
6961 //**************************************************
6962 //* Duplicate a note
6963 //**************************************************
6964 @SuppressWarnings("unused")
6965 private void duplicateNote() {
6967 duplicateNote(currentNoteGuid);
6970 //**************************************************
6971 //* Action from when a user clicks Copy As URL
6972 //**************************************************
6973 @SuppressWarnings("unused")
6974 private void copyAsUrlClicked() {
6975 QClipboard clipboard = QApplication.clipboard();
6976 QMimeData mime = new QMimeData();
6978 mime.setText(currentNoteGuid);
6979 List<QUrl> urls = new ArrayList<QUrl>();
6981 // Start building the URL
6982 User user = Global.getUserInformation();
6984 // Check that we have everything we need
6985 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
6986 SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
6988 if (!warning.neverSynchronize())
6991 Global.setBypassSynchronizationWarning(true);
6992 user.setShardId("s0");
6998 // Start building a list of URLs based upon the selected notes
6999 noteTableView.showColumn(Global.noteTableGuidPosition);
7001 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
7002 if (!Global.isColumnVisible("guid"))
7003 noteTableView.hideColumn(Global.noteTableGuidPosition);
7005 // Check that the note is either synchronized, or in a local notebook
7006 for (int i=0; i<selections.size(); i++) {
7008 int row = selections.get(i).row();
7009 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7010 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7011 String selectedGuid = (String)ix.values().toArray()[0];
7013 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7014 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
7015 QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
7016 "new notes to a local notebook."));
7021 // Start building the URLs
7022 for (int i=0; i<selections.size(); i++) {
7024 int row = selections.get(i).row();
7025 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7026 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7027 String selectedGuid = (String)ix.values().toArray()[0];
7028 mime.setText(selectedGuid);
7032 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7033 if (selectedNote.getUpdateSequenceNum() > 0) {
7037 gid = "00000000-0000-0000-0000-000000000000";
7040 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
7042 urls.add(new QUrl(url));
7045 clipboard.setMimeData(mime);
7049 //**************************************************
7051 //**************************************************
7052 public void setupFolderImports() {
7053 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
7055 if (importKeepWatcher == null)
7056 importKeepWatcher = new QFileSystemWatcher();
7057 if (importDeleteWatcher == null) {
7058 importDeleteWatcher = new QFileSystemWatcher();
7059 for (int i=0; i<records.size(); i++) {
7060 if (!records.get(i).keep)
7061 folderImportDelete(records.get(i).folder);
7067 // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
7068 for (int i=0; i<records.size(); i++) {
7069 logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
7070 if (records.get(i).keep)
7071 importKeepWatcher.addPath(records.get(i).folder);
7073 importDeleteWatcher.addPath(records.get(i).folder);
7076 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
7077 List<String> monitorDelete = importKeepWatcher.directories();
7078 for (int i=0; i<monitorDelete.size(); i++) {
7079 logger.log(logger.EXTREME, monitorDelete.get(i));
7081 logger.log(logger.EXTREME, "<end of list>");
7082 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
7083 monitorDelete = importDeleteWatcher.directories();
7084 for (int i=0; i<monitorDelete.size(); i++) {
7085 logger.log(logger.EXTREME, monitorDelete.get(i));
7087 logger.log(logger.EXTREME, "<end of list>");
7089 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
7090 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
7092 // Look at the files already there so we don't import them again if a new file is created
7093 if (importedFiles == null) {
7094 importedFiles = new ArrayList<String>();
7095 for (int j=0; j<records.size(); j++) {
7096 QDir dir = new QDir(records.get(j).folder);
7097 List<QFileInfo> list = dir.entryInfoList();
7098 for (int k=0; k<list.size(); k++) {
7099 if (list.get(k).isFile())
7100 importedFiles.add(list.get(k).absoluteFilePath());
7106 // Menu folderImport action triggered
7107 public void folderImport() {
7108 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
7109 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
7111 if (!dialog.okClicked())
7114 // We have some sort of update.
7115 if (importKeepWatcher.directories().size() > 0)
7116 importKeepWatcher.removePaths(importKeepWatcher.directories());
7117 if (importDeleteWatcher.directories().size() > 0)
7118 importDeleteWatcher.removePaths(importDeleteWatcher.directories());
7120 conn.getWatchFolderTable().expungeAll();
7121 // Start building from the table
7122 for (int i=0; i<dialog.table.rowCount(); i++) {
7123 QTableWidgetItem item = dialog.table.item(i, 0);
7124 String dir = item.text();
7125 item = dialog.table.item(i, 1);
7126 String notebook = item.text();
7127 item = dialog.table.item(i, 2);
7129 if (item.text().equalsIgnoreCase("Keep"))
7134 String guid = conn.getNotebookTable().findNotebookByName(notebook);
7135 conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
7137 setupFolderImports();
7141 public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
7142 logger.log(logger.LOW, "Inside folderImportKeep");
7143 String whichOS = System.getProperty("os.name");
7144 if (whichOS.contains("Windows"))
7145 dirName = dirName.replace('/','\\');
7147 FileImporter importer = new FileImporter(logger, conn);
7149 QDir dir = new QDir(dirName);
7150 List<QFileInfo> list = dir.entryInfoList();
7151 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7153 for (int i=0; i<list.size(); i++){
7154 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7155 boolean redundant = false;
7156 // Check if we've already imported this one or if it existed before
7157 for (int j=0; j<importedFiles.size(); j++) {
7158 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7159 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7163 logger.log(logger.LOW, "Checking if redundant: " +redundant);
7165 importer.setFileInfo(list.get(i));
7166 importer.setFileName(list.get(i).absoluteFilePath());
7169 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7170 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7171 if (list.get(i).isFile() && importer.isValidType()) {
7173 if (!importer.importFile()) {
7174 // If we can't get to the file, it is probably locked. We'll try again later.
7175 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7176 importFilesKeep.add(list.get(i).absoluteFilePath());
7179 Note newNote = importer.getNote();
7180 newNote.setNotebookGuid(notebook);
7181 newNote.setTitle(dir.at(i));
7182 NoteMetadata metadata = new NoteMetadata();
7183 metadata.setDirty(true);
7184 metadata.setGuid(newNote.getGuid());
7185 listManager.addNote(newNote, metadata);
7186 conn.getNoteTable().addNote(newNote, true);
7187 noteTableView.insertRow(newNote, metadata, true, -1);
7188 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7189 listManager.countNotebookResults(listManager.getNoteIndex());
7190 importedFiles.add(list.get(i).absoluteFilePath());
7199 public void folderImportDelete(String dirName) {
7200 logger.log(logger.LOW, "Inside folderImportDelete");
7201 String whichOS = System.getProperty("os.name");
7202 if (whichOS.contains("Windows"))
7203 dirName = dirName.replace('/','\\');
7205 FileImporter importer = new FileImporter(logger, conn);
7206 QDir dir = new QDir(dirName);
7207 List<QFileInfo> list = dir.entryInfoList();
7208 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7210 for (int i=0; i<list.size(); i++){
7211 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7212 importer.setFileInfo(list.get(i));
7213 importer.setFileName(list.get(i).absoluteFilePath());
7215 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7216 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7217 if (list.get(i).isFile() && importer.isValidType()) {
7219 if (!importer.importFile()) {
7220 // If we can't get to the file, it is probably locked. We'll try again later.
7221 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7222 importFilesKeep.add(list.get(i).absoluteFilePath());
7225 Note newNote = importer.getNote();
7226 newNote.setNotebookGuid(notebook);
7227 newNote.setTitle(dir.at(i));
7228 NoteMetadata metadata = new NoteMetadata();
7229 metadata.setDirty(true);
7230 metadata.setGuid(newNote.getGuid());
7231 listManager.addNote(newNote, metadata);
7232 conn.getNoteTable().addNote(newNote, true);
7233 noteTableView.insertRow(newNote, metadata, true, -1);
7234 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7235 listManager.countNotebookResults(listManager.getNoteIndex());
7236 dir.remove(dir.at(i));
7243 //**************************************************
7245 //**************************************************
7246 private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7247 logger.log(logger.HIGH, "Entering exernalFileEdited");
7249 // Strip URL prefix and base dir path
7250 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7251 String name = fileName.replace(dPath, "");
7252 int pos = name.lastIndexOf('.');
7255 guid = guid.substring(0,pos);
7257 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7259 guid = name.substring(0, pos);
7262 QFile file = new QFile(fileName);
7263 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
7264 // If we can't get to the file, it is probably locked. We'll try again later.
7265 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7266 externalFiles.add(fileName);
7269 QByteArray binData = file.readAll();
7271 if (binData.size() == 0) {
7272 // If we can't get to the file, it is probably locked. We'll try again later.
7273 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7274 externalFiles.add(fileName);
7278 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7280 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7281 if (r == null || r.getData() == null || r.getData().getBody() == null)
7283 String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7284 MessageDigest md = MessageDigest.getInstance("MD5");
7285 md.update(binData.toByteArray());
7286 byte[] hash = md.digest();
7287 String newHash = Global.byteArrayToHexString(hash);
7288 if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7289 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7291 if (externalWindows.containsKey(r.getNoteGuid())) {
7292 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(),
7293 r.getGuid(), oldHash, newHash);
7295 conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7296 Data data = r.getData();
7297 data.setBody(binData.toByteArray());
7298 data.setBodyHash(hash);
7299 logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7301 conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7303 if (r.getNoteGuid().equals(currentNoteGuid)) {
7304 QWebSettings.setMaximumPagesInCache(0);
7305 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7306 refreshEvernoteNote(true);
7307 browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7310 if (externalWindows.containsKey(r.getNoteGuid())) {
7311 QWebSettings.setMaximumPagesInCache(0);
7312 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7313 externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7317 logger.log(logger.HIGH, "Exiting externalFielEdited");
7319 // This is a timer event that tries to save any external files that were edited. This
7320 // is only needed if we couldn't save a file earlier.
7321 public void externalFileEditedSaver() {
7322 for (int i=externalFiles.size()-1; i>=0; i--) {
7324 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7325 externalFileEdited(externalFiles.get(i));
7326 externalFiles.remove(i);
7327 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7329 for (int i=0; i<importFilesKeep.size(); i++) {
7331 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7332 folderImportKeep(importFilesKeep.get(i));
7333 importFilesKeep.remove(i);
7334 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7336 for (int i=0; i<importFilesDelete.size(); i++) {
7337 logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7338 folderImportDelete(importFilesDelete.get(i));
7339 importFilesDelete.remove(i);
7346 // If an attachment on the current note was edited, we need to update the current notes's hash
7347 // Update a note content's hash. This happens if a resource is edited outside of NN
7348 public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7349 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7351 for (;position>-1;) {
7352 endPos = browser.getContent().indexOf(">", position+1);
7353 String oldSegment = browser.getContent().substring(position,endPos);
7354 int hashPos = oldSegment.indexOf("hash=\"");
7355 int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7356 String hash = oldSegment.substring(hashPos+6, hashEnd);
7357 if (hash.equalsIgnoreCase(oldHash)) {
7358 String newSegment = oldSegment.replace(oldHash, newHash);
7359 String content = browser.getContent().substring(0,position) +
7361 browser.getContent().substring(endPos);
7362 browser.setContent(new QByteArray(content));;
7365 position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7370 //*************************************************
7371 //* Minimize to tray
7372 //*************************************************
7374 public void changeEvent(QEvent e) {
7375 if (e.type() == QEvent.Type.WindowStateChange) {
7376 if (QSystemTrayIcon.isSystemTrayAvailable()) {
7377 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7379 QTimer.singleShot(10, this, "hide()");
7383 windowMaximized = true;
7385 windowMaximized = false;
7390 //*************************************************
7391 //* Check database userid & passwords
7392 //*************************************************
7393 private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7394 Connection connection;
7397 Class.forName("org.h2.Driver");
7398 } catch (ClassNotFoundException e1) {
7399 e1.printStackTrace();
7404 String passwordString = null;
7405 if (cypherPassword==null || cypherPassword.trim().equals(""))
7406 passwordString = userPassword;
7408 passwordString = cypherPassword+" "+userPassword;
7409 connection = DriverManager.getConnection(url,userid,passwordString);
7410 } catch (SQLException e) {
7415 } catch (SQLException e) {
7416 e.printStackTrace();
7421 //*************************************************
7422 //* View / Hide source HTML for a note
7423 //*************************************************
7424 public void viewSource() {
7425 // ICHANGED すべてのタブに対して
7426 for(int i = 0; i < tabBrowser.count(); i++){
7427 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7428 browser.showSource(menuBar.viewSource.isChecked());
7431 //*************************************************
7432 // Block the program. This is used for things
7433 // like async web calls.
7434 //*************************************************
7435 @SuppressWarnings("unused")
7436 private void blockApplication(BrowserWindow b) {
7437 // Block all signals
7441 blockTimer = new QTimer();
7442 blockTimer.setSingleShot(true);
7443 blockTimer.setInterval(15000);
7444 blockTimer.timeout.connect(this, "unblockApplication()");
7449 @SuppressWarnings("unused")
7450 private void unblockApplication() {
7452 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7453 QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7454 blockingWindow.unblockTime = -1;
7455 blockingWindow.awaitingHttpResponse = false;
7457 blockingWindow = null;
7458 blockSignals(false);
7463 private void tabWindowChanged(int index) {
7464 if (index < 0 || index >= tabBrowser.count()) {
7470 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7471 if (tab.getBrowserWindow().getNote() != null) {
7472 currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7473 currentNote = tab.getBrowserWindow().getNote();
7475 currentNoteGuid = "";
7480 selectedNoteGUIDs.clear();
7481 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7482 selectedNoteGUIDs.add(currentNoteGuid);
7486 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7487 browserWindow.focusLost.disconnect(this, "saveNote()");
7488 browserWindow = tab.getBrowserWindow();
7489 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7490 browserWindow.focusLost.connect(this, "saveNote()");
7491 // メニューバーのボタンを新しいbrowserWindowに合わせる
7492 menuBar.refreshTargetWindow();
7494 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7495 boolean nextIsActive;
7496 if (tab.getBrowserWindow().getNote() != null) {
7497 nextIsActive = tab.getBrowserWindow().getNote().isActive();
7499 nextIsActive = true;
7501 if (Global.showDeleted && nextIsActive) {
7502 switchNoteTable(false);
7503 } else if (!Global.showDeleted && !nextIsActive) {
7504 switchNoteTable(true);
7507 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7508 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7509 scrollToGuid(currentNoteGuid);
7511 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7513 menuBar.noteDuplicateAction.setEnabled(true);
7514 menuBar.noteOnlineHistoryAction.setEnabled(true);
7515 menuBar.noteMergeAction.setEnabled(true);
7517 if (Global.showDeleted) {
7518 menuBar.noteDuplicateAction.setEnabled(false);
7520 if (!Global.isConnected) {
7521 menuBar.noteOnlineHistoryAction.setEnabled(false);
7523 menuBar.noteMergeAction.setEnabled(false);
7525 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7527 upButton.setEnabled(false);
7529 upButton.setEnabled(true);
7530 if (row < listManager.getNoteTableModel().rowCount() - 1)
7531 downButton.setEnabled(true);
7533 downButton.setEnabled(false);
7534 } catch (Exception e) {
7535 upButton.setEnabled(false);
7536 downButton.setEnabled(false);
7539 int currentIndex = tabBrowser.currentIndex();
7540 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7541 int histPosition = historyPosition.get(currentIndex);
7543 // prev, nextボタンの有効・無効化
7544 nextButton.setEnabled(true);
7545 prevButton.setEnabled(true);
7547 if (histPosition <= 1){
7548 prevButton.setEnabled(false);
7550 if (histPosition == histGuids.size()){
7551 nextButton.setEnabled(false);
7554 refreshEvernoteNote(true);
7557 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7561 // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7562 private void switchNoteTable(boolean toDeleted) {
7563 clearNotebookFilter();
7565 clearAttributeFilter();
7566 clearSavedSearchFilter();
7568 listManager.getSelectedNotebooks().clear();
7569 listManager.getSelectedTags().clear();
7570 listManager.setSelectedSavedSearch("");
7572 // toggle the add buttons
7573 newButton.setEnabled(!newButton.isEnabled());
7574 menuBar.noteAdd.setEnabled(newButton.isEnabled());
7575 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
7576 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
7577 menuBar.noteAddNewTab.setEnabled(false);
7579 menuBar.noteAdd.setVisible(true);
7581 if (!toDeleted) { // 生存ノートテーブルへ
7582 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7583 trashTree.clearSelection();
7584 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7585 Global.showDeleted = false;
7586 menuBar.noteRestoreAction.setEnabled(false);
7587 menuBar.noteRestoreAction.setVisible(false);
7588 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7589 rensoNoteListDock.setEnabled(true);
7591 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7592 trashTree.setCurrentItem(trashTree.getTrashItem());
7593 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7594 Global.showDeleted = true;
7595 menuBar.noteRestoreAction.setEnabled(true);
7596 menuBar.noteRestoreAction.setVisible(true);
7597 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
7598 rensoNoteListDock.setEnabled(false);
7601 listManager.loadNotesIndex();
7602 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7603 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7604 noteIndexUpdated(false);
7606 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7608 browserWindow.setReadOnly(!newButton.isEnabled());
7612 // ユーザが連想ノートリストのアイテムを選択した時の処理
7613 @SuppressWarnings("unused")
7614 private void rensoNoteItemPressed(QListWidgetItem current) {
7615 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7617 rensoNotePressedItemGuid = rensoNoteList.getNoteGuid(current);
7620 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7626 String prevCurrentNoteGuid = new String(currentNoteGuid);
7628 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
7629 QModelIndex modelIndex = noteTableView.model().index(i,
7630 Global.noteTableGuidPosition);
7631 if (modelIndex != null) {
7632 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
7634 String tableGuid = (String) ix.values().toArray()[0];
7635 if (tableGuid.equals(rensoNotePressedItemGuid)) {
7636 noteTableView.selectRow(i);
7642 // 連想ノートリストアイテムクリック操作を記録
7643 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7645 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7649 // 関連ノートリストからノートを除外する
7650 @SuppressWarnings("unused")
7651 private void excludeNote() {
7652 if (rensoNotePressedItemGuid != null) {
7654 excludeNote(rensoNotePressedItemGuid);
7659 // 関連ノートリストからノートを除外する
7660 private void excludeNote(String guid) {
7661 if (Global.verifyExclude()) {
7663 Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7664 String title = note.getTitle();
7665 if (title != null) {
7666 msg = new String(tr("Exclude note \"") +title +"\"?");
7668 msg = new String(tr("Exclude note selected note?"));
7671 if (QMessageBox.question(this, tr("Confirmation"), msg,
7672 QMessageBox.StandardButton.Yes,
7673 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7678 // Historyデータベースから除外するノートのデータを削除
7679 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7682 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7684 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7688 // 関連ノートリストのノートにスターを付ける
7689 @SuppressWarnings("unused")
7690 private void starNote() {
7691 if (rensoNotePressedItemGuid != null) {
7693 starNote(rensoNotePressedItemGuid);
7698 // 関連ノートリストのノートにスターを付ける
7699 private void starNote(String guid) {
7701 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7703 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7707 // 関連ノートリストのノートからスターを外す
7708 @SuppressWarnings("unused")
7709 private void unstarNote() {
7710 if (rensoNotePressedItemGuid != null) {
7712 unstarNote(rensoNotePressedItemGuid);
7717 // 関連ノートリストのノートからスターを外す
7718 private void unstarNote(String guid) {
7720 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7722 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7726 // currentNoteGuidを返す
7727 public String getCurrentNoteGuid() {
7728 return currentNoteGuid;
7731 @SuppressWarnings("unused")
7732 // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える
7733 private void tabIndexChanged(int from, int to) {
7735 TabBrowse tab = tabWindows.get(from);
7736 tabWindows.put(from, tabWindows.get(to));
7737 tabWindows.put(to, tab);
7739 boolean isNoteDirty = noteDirty.get(from);
7740 noteDirty.put(from, noteDirty.get(to));
7741 noteDirty.put(to, isNoteDirty);
7743 boolean isInkNote = inkNote.get(from);
7744 inkNote.put(from, inkNote.get(to));
7745 inkNote.put(to, isInkNote);
7747 boolean isReadOnly = readOnly.get(from);
7748 readOnly.put(from, readOnly.get(to));
7749 readOnly.put(to, isReadOnly);
7751 ArrayList<String> histGuids = historyGuids.get(from);
7752 historyGuids.put(from, historyGuids.get(to));
7753 historyGuids.put(to, histGuids);
7755 int histPosition = historyPosition.get(from);
7756 historyPosition.put(from, historyPosition.get(to));
7757 historyPosition.put(to, histPosition);
7759 boolean fromHist = fromHistory.get(from);
7760 fromHistory.put(from, fromHistory.get(to));
7761 fromHistory.put(to, fromHist);
7765 public RensoNoteList getRensoNoteList() {
7766 return rensoNoteList;