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.apache.thrift.TException;
51 import org.h2.tools.ChangeFileEncryption;
53 import com.evernote.edam.error.EDAMNotFoundException;
54 import com.evernote.edam.error.EDAMSystemException;
55 import com.evernote.edam.error.EDAMUserException;
56 import com.evernote.edam.notestore.NoteFilter;
57 import com.evernote.edam.notestore.NoteVersionId;
58 import com.evernote.edam.type.Data;
59 import com.evernote.edam.type.LinkedNotebook;
60 import com.evernote.edam.type.Note;
61 import com.evernote.edam.type.NoteAttributes;
62 import com.evernote.edam.type.Notebook;
63 import com.evernote.edam.type.Publishing;
64 import com.evernote.edam.type.QueryFormat;
65 import com.evernote.edam.type.Resource;
66 import com.evernote.edam.type.SavedSearch;
67 import com.evernote.edam.type.Tag;
68 import com.evernote.edam.type.User;
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;
213 public class NeverNote extends QMainWindow{
215 QStatusBar statusBar; // Application status bar
217 DatabaseConnection conn;
219 MainMenuBar menuBar; // Main menu bar
220 FindDialog find; // Text search in note dialog
221 List<String> emitLog; // Messages displayed in the status bar;
222 QSystemTrayIcon trayIcon; // little tray icon
223 QMenu trayMenu; // System tray menu
224 QAction trayExitAction; // Exit the application
225 QAction trayShowAction; // toggle the show/hide action
226 QAction trayAddNoteAction; // Add a note from the system tray
227 QNetworkAccessManager versionChecker; // Used when checking for new versions
229 NotebookTreeWidget notebookTree; // List of notebooks
230 AttributeTreeWidget attributeTree; // List of note attributes
231 TagTreeWidget tagTree; // list of user created tags
232 SavedSearchTreeWidget savedSearchTree; // list of saved searches
233 TrashTreeWidget trashTree; // Trashcan
234 TableView noteTableView; // List of notes (the widget).
236 public BrowserWindow browserWindow; // Window containing browser & labels
237 public QToolBar toolBar; // The tool bar under the menu
238 QComboBox searchField; // search filter bar on the toolbar;
239 QShortcut searchShortcut; // Shortcut to search bar
240 boolean searchPerformed = false; // Search was done?
241 QuotaProgressBar quotaBar; // The current quota usage
243 ApplicationLogger logger;
244 List<String> selectedNotebookGUIDs; // List of notebook GUIDs
245 List<String> selectedTagGUIDs; // List of selected tag GUIDs
246 List<String> selectedNoteGUIDs; // List of selected notes
247 String selectedSavedSearchGUID; // Currently selected saved searches
248 private final HashMap<String, ExternalBrowse> externalWindows; // Notes being edited by an external window;
250 NoteFilter filter; // Note filter
251 String currentNoteGuid; // GUID of the current note
252 Note currentNote; // The currently viewed note
254 HashMap<Integer, Boolean> noteDirty; // Has the note been changed?
255 HashMap<Integer, Boolean> inkNote; // if this is an ink note, it is read only
256 HashMap<Integer, Boolean> readOnly; // Is this note read-only?
259 ListManager listManager; // DB runnable task
261 List<QTemporaryFile> tempFiles; // Array of temporary files;
263 QTimer indexTimer; // timer to start the index thread
264 IndexRunner indexRunner; // thread to index notes
267 QTimer syncTimer; // Sync on an interval
268 QTimer syncDelayTimer; // Sync delay to free up database
269 SyncRunner syncRunner; // thread to do a sync.
270 QThread syncThread; // Thread which talks to evernote
271 ThumbnailRunner thumbnailRunner; // Runner for thumbnail thread
272 QThread thumbnailThread; // Thread that generates pretty pictures
273 QTimer saveTimer; // Timer to save note contents
275 QTimer authTimer; // Refresh authentication
276 QTimer externalFileSaveTimer; // Save files altered externally
277 QTimer thumbnailTimer; // Wakeup & scan for thumbnails
279 List<String> externalFiles; // External files to save later
280 List<String> importFilesKeep; // Auto-import files to save later
281 List<String> importFilesDelete; // Auto-import files to save later
283 int indexTime; // how often to try and index
284 boolean indexRunning; // Is indexing running?
285 boolean indexDisabled; // Is indexing disabled?
287 int syncThreadsReady; // number of sync threads that are free
288 int syncTime; // Sync interval
289 boolean syncRunning; // Is sync running?
290 boolean automaticSync; // do sync automatically?
291 QTreeWidgetItem attributeTreeSelected;
293 QAction prevButton; // Go to the previous item viewed
294 QAction nextButton; // Go to the next item in the history
295 QAction downButton; // Go to the next item in the list
296 QAction upButton; // Go to the prev. item in the list;
297 QAction synchronizeButton; // Synchronize with Evernote
298 QAction allNotesButton; // Reset & view all notes
299 QTimer synchronizeAnimationTimer; // Timer to change animation button
300 int synchronizeIconAngle; // Used to rotate sync icon
301 QAction printButton; // Print Button
302 QAction tagButton; // Tag edit button
303 QAction attributeButton; // Attribute information button
304 QAction emailButton; // Email button
305 QAction deleteButton; // Delete button
306 QAction newButton; // new Note Button;
307 QSpinBox zoomSpinner; // Zoom zoom
308 QAction searchClearButton; // Clear the search field
310 SearchPanel searchLayout; // Widget to hold search field, zoom, & quota
312 QSplitter mainLeftRightSplitter; // main splitter for left/right side
313 QSplitter leftSplitter1; // first left hand splitter
314 QSplitter browserIndexSplitter; // splitter between note index & note text
316 QFileSystemWatcher importKeepWatcher; // Watch & keep auto-import
317 QFileSystemWatcher importDeleteWatcher; // Watch & Delete auto-import
318 List<String> importedFiles; // History of imported files (so we don't import twice)
320 OnlineNoteHistory historyWindow; // online history window
321 List<NoteVersionId> versions; // history versions
323 QTimer threadMonitorTimer; // Timer to watch threads.
324 int dbThreadDeadCount=0; // number of consecutive dead times for the db thread
325 int syncThreadDeadCount=0; // number of consecutive dead times for the sync thread
326 int indexThreadDeadCount=0; // number of consecutive dead times for the index thread
327 int notebookThreadDeadCount=0; // number of consecutive dead times for the notebook thread
328 int tagDeadCount=0; // number of consecutive dead times for the tag thread
329 int trashDeadCount=0; // number of consecutive dead times for the trash thread
330 int saveThreadDeadCount=0; // number of consecutive dead times for the save thread
331 boolean disableTagThreadCheck=false;
332 boolean disableNotebookThreadCheck=false;
333 boolean disableTrashThreadCheck=false;
334 boolean disableSaveThreadCheck=false;
335 boolean disableSyncThreadCheck=false;
336 boolean disableIndexThreadCheck=false;
338 HashMap<String, String> noteCache; // Cash of note content
339 HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
340 HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
342 HashMap<Integer, ArrayList<String>> historyGuids; // タブごとの以前見たノートのGUID
343 HashMap<Integer, Integer> historyPosition; // Position within the viewed items
344 HashMap<Integer, Boolean> fromHistory; // Is this from the history queue?
346 String trashNoteGuid; // Guid to restore / set into or out of trash to save position
347 List<Thumbnailer> thumbGenerators; // generate preview image
348 ThumbnailViewer thumbnailViewer; // View preview thumbnail;
349 boolean encryptOnShutdown; // should I encrypt when I close?
350 boolean decryptOnShutdown; // should I decrypt on shutdown;
351 String encryptCipher; // What cipher should I use?
352 //Signal0 minimizeToTray;
353 boolean windowMaximized = false; // Keep track of the window state for restores
354 List<String> pdfReadyQueue; // Queue of PDFs that are ready to be rendered.
355 List<QPixmap> syncIcons; // Array of icons used in sync animation
356 private boolean closeAction = false; // Used to say when to close or when to minimize
357 private static Logger log = Logger.getLogger(NeverNote.class);
358 private String saveLastPath; // last path we used
359 private final QTimer messageTimer; // Timer to clear the status message.
360 private QTimer blockTimer;
361 BrowserWindow blockingWindow;
364 private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
365 private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
366 private final RensoNoteList rensoNoteList; // 連想ノートリスト
367 private final QDockWidget rensoNoteListDock; // 連想ノートリストドックウィジェット
368 ClipBoardObserver cbObserver;
369 String rensoNotePressedItemGuid;
371 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
374 //***************************************************************
375 //***************************************************************
376 //** Constructor & main entry point
377 //***************************************************************
378 //***************************************************************
379 // Application Constructor
380 @SuppressWarnings("static-access")
381 public NeverNote(DatabaseConnection dbConn) {
383 cbObserver = new ClipBoardObserver();
386 if (conn.getConnection() == null) {
387 String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
388 "is accessing the database or NeighborNote is already running.\n\n" +
389 "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
391 QMessageBox.critical(null, tr("Database Connection Error") ,msg);
394 setObjectName("mainWindow");
395 // thread().setPriority(Thread.MAX_PRIORITY);
397 logger = new ApplicationLogger("nevernote.log");
398 logger.log(logger.HIGH, "Starting Application");
400 decryptOnShutdown = false;
401 encryptOnShutdown = false;
402 conn.checkDatabaseVersion();
406 // Start building the invalid XML tables
407 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
408 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
410 for (int i=0; i<elements.size(); i++) {
411 Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
414 logger.log(logger.EXTREME, "Starting GUI build");
416 QTranslator nevernoteTranslator = new QTranslator();
417 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("nevernote_" + QLocale.system().name() + ".qm"));
418 QApplication.instance().installTranslator(nevernoteTranslator);
420 Global.originalPalette = QApplication.palette();
421 QApplication.setStyle(Global.getStyle());
422 if (Global.useStandardPalette())
423 QApplication.setPalette(QApplication.style().standardPalette());
424 setWindowTitle(tr("NeighborNote"));
426 mainLeftRightSplitter = new QSplitter();
428 mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
430 setCentralWidget(mainLeftRightSplitter);
431 leftSplitter1 = new QSplitter();
432 leftSplitter1.setOrientation(Qt.Orientation.Vertical);
434 browserIndexSplitter = new QSplitter();
435 browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
437 //* Setup threads & thread timers
438 // int indexRunnerCount = Global.getIndexThreads();
439 // indexRunnerCount = 1;
440 QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount); // increase max thread count
442 logger.log(logger.EXTREME, "Building list manager");
443 listManager = new ListManager(conn, logger);
445 logger.log(logger.EXTREME, "Building index runners & timers");
446 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
447 indexRunner = new IndexRunner("indexRunner.log",
448 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
449 Global.getResourceDatabaseUrl(),
450 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
451 Global.getDatabaseUserPassword(), Global.cipherPassword);
453 indexThread = new QThread(indexRunner, "Index Thread");
454 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
455 indexRunner.indexImageRecognition = Global.indexImageRecognition();
456 indexRunner.indexNoteBody = Global.indexNoteBody();
457 indexRunner.indexNoteTitle = Global.indexNoteTitle();
458 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
461 synchronizeAnimationTimer = new QTimer();
462 synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
464 indexTimer = new QTimer();
465 indexTime = 1000*Global.getIndexThreadSleepInterval();
466 indexTimer.start(indexTime); // Start indexing timer
467 indexTimer.timeout.connect(this, "indexTimer()");
468 indexDisabled = false;
469 indexRunning = false;
471 logger.log(logger.EXTREME, "Setting sync thread & timers");
473 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
474 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
475 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
476 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
477 Global.getDatabaseUserPassword(), Global.cipherPassword);
479 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
480 syncTimer = new QTimer();
481 syncTimer.timeout.connect(this, "syncTimer()");
482 syncRunner.status.message.connect(this, "setMessage(String)");
483 syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
484 syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
487 automaticSync = true;
488 syncTimer.start(syncTime*60*1000);
490 automaticSync = false;
493 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
494 syncThread = new QThread(syncRunner, "Synchronization Thread");
498 logger.log(logger.EXTREME, "Starting thumnail thread");
499 pdfReadyQueue = new ArrayList<String>();
500 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
501 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
502 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
503 Global.getResourceDatabaseUrl(),
504 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
505 Global.getDatabaseUserPassword(), Global.cipherPassword);
507 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
508 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
509 thumbnailThread.start();
510 thumbGenerators = new ArrayList<Thumbnailer>();
511 thumbnailTimer = new QTimer();
512 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
514 thumbnailTimer.setInterval(500*1000); // Thumbnail every minute
515 thumbnailTimer.start();
517 // debugTimer = new QTimer();
518 // debugTimer.timeout.connect(this, "debugDirty()");
519 // debugTimer.start(1000*60);
521 logger.log(logger.EXTREME, "Starting authentication timer");
522 authTimer = new QTimer();
523 authTimer.timeout.connect(this, "authTimer()");
524 authTimer.start(1000*60*15);
525 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
527 logger.log(logger.EXTREME, "Setting save note timer");
528 saveTimer = new QTimer();
529 saveTimer.timeout.connect(this, "saveNote()");
530 if (Global.getAutoSaveInterval() > 0) {
531 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
534 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
536 logger.log(logger.EXTREME, "Starting external file monitor timer");
537 externalFileSaveTimer = new QTimer();
538 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
539 externalFileSaveTimer.setInterval(1000*5); // save every 5 seconds;
540 externalFiles = new ArrayList<String>();
541 importFilesDelete = new ArrayList<String>();
542 importFilesKeep = new ArrayList<String>();
543 externalFileSaveTimer.start();
545 notebookTree = new NotebookTreeWidget(conn);
546 attributeTree = new AttributeTreeWidget();
547 tagTree = new TagTreeWidget(conn);
548 savedSearchTree = new SavedSearchTreeWidget();
549 trashTree = new TrashTreeWidget();
551 noteTableView = new TableView(logger, listManager, this);
553 searchField = new QComboBox();
554 searchField.setObjectName("searchField");
555 //setStyleSheet("QComboBox#searchField { background-color: yellow }");
556 searchField.setEditable(true);
557 searchField.activatedIndex.connect(this, "searchFieldChanged()");
558 searchField.setDuplicatesEnabled(false);
559 searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
560 searchShortcut = new QShortcut(this);
561 setupShortcut(searchShortcut, "Focus_Search");
562 searchShortcut.activated.connect(this, "focusSearch()");
564 quotaBar = new QuotaProgressBar();
566 zoomSpinner = new QSpinBox();
567 zoomSpinner.setMinimum(10);
568 zoomSpinner.setMaximum(1000);
569 zoomSpinner.setAccelerated(true);
570 zoomSpinner.setSingleStep(10);
571 zoomSpinner.setValue(100);
572 zoomSpinner.valueChanged.connect(this, "zoomChanged()");
574 searchLayout = new SearchPanel(searchField, quotaBar, notebookTree, zoomSpinner);
577 QGridLayout leftGrid = new QGridLayout();
578 leftSplitter1.setContentsMargins(5, 0, 0, 7);
579 leftSplitter1.setLayout(leftGrid);
580 leftGrid.addWidget(searchLayout,1,1);
581 leftGrid.addWidget(tagTree,2,1);
582 leftGrid.addWidget(attributeTree,3,1);
583 leftGrid.addWidget(savedSearchTree,4,1);
584 leftGrid.addWidget(trashTree,5, 1);
586 // Setup the browser window
587 noteCache = new HashMap<String,String>();
588 readOnlyCache = new HashMap<String, Boolean>();
589 inkNoteCache = new HashMap<String, Boolean>();
591 browserWindow = new BrowserWindow(conn, cbObserver);
593 // ICHANGED 下から移動してきた。
594 historyGuids = new HashMap<Integer, ArrayList<String>>();
595 historyPosition = new HashMap<Integer, Integer>();
596 fromHistory = new HashMap<Integer, Boolean>();
599 tabWindows = new HashMap<Integer, TabBrowse>();
600 tabBrowser = new TabBrowserWidget(this);
601 tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
602 tabBrowser.setMovable(true);
603 TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver);
604 browserWindow = tab.getBrowserWindow();
605 int index = tabBrowser.addNewTab(tab, "");
606 tabWindows.put(index, tab);
607 tabBrowser.setTabsClosable(true);
608 tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)");
609 tabBrowser.tabCloseRequested.connect(this, "tabWindowClosing(int)");
611 noteDirty = new HashMap<Integer, Boolean>();
612 noteDirty.put(index, false);
614 inkNote = new HashMap<Integer, Boolean>();
615 readOnly = new HashMap<Integer, Boolean>();
619 historyGuids.put(index, new ArrayList<String>());
620 historyPosition.put(index, 0);
621 fromHistory.put(index, false);
623 mainLeftRightSplitter.addWidget(leftSplitter1);
624 mainLeftRightSplitter.addWidget(browserIndexSplitter);
628 rensoNoteList = new RensoNoteList(conn, this);
629 rensoNoteList.itemPressed.connect(this,
630 "rensoNoteItemPressed(QListWidgetItem)");
631 rensoNoteListDock = new QDockWidget(tr("Renso Note List"), this);
632 rensoNoteListDock.setWidget(rensoNoteList);
633 addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
635 if (Global.getListView() == Global.View_List_Wide) {
636 browserIndexSplitter.addWidget(noteTableView);
638 browserIndexSplitter.addWidget(tabBrowser);
639 // browserIndexSplitter.addWidget(browserWindow);
641 mainLeftRightSplitter.addWidget(noteTableView);
643 mainLeftRightSplitter.addWidget(tabBrowser);
644 // mainLeftRightSplitter.addWidget(browserWindow);
647 // Setup the thumbnail viewer
648 thumbnailViewer = new ThumbnailViewer();
649 thumbnailViewer.upArrow.connect(this, "upAction()");
650 thumbnailViewer.downArrow.connect(this, "downAction()");
651 thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
652 thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
654 //Setup external browser manager
655 externalWindows = new HashMap<String, ExternalBrowse>();
657 listManager.loadNotesIndex();
658 initializeNotebookTree();
660 initializeSavedSearchTree();
661 attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
662 attributeTreeSelected = null;
663 initializeNoteTable();
665 selectedNoteGUIDs = new ArrayList<String>();
666 statusBar = new QStatusBar();
667 setStatusBar(statusBar);
668 menuBar = new MainMenuBar(this);
669 emitLog = new ArrayList<String>();
671 tagTree.setDeleteAction(menuBar.tagDeleteAction);
672 tagTree.setMergeAction(menuBar.tagMergeAction);
673 tagTree.setEditAction(menuBar.tagEditAction);
674 tagTree.setAddAction(menuBar.tagAddAction);
675 tagTree.setIconAction(menuBar.tagIconAction);
676 tagTree.setVisible(Global.isWindowVisible("tagTree"));
677 leftSplitter1.setVisible(Global.isWindowVisible("leftPanel"));
678 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
679 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
680 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
682 if (!Global.isWindowVisible("zoom")) {
683 searchLayout.hideZoom();
684 menuBar.hideZoom.setChecked(false);
687 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
688 notebookTree.setEditAction(menuBar.notebookEditAction);
689 notebookTree.setAddAction(menuBar.notebookAddAction);
690 notebookTree.setIconAction(menuBar.notebookIconAction);
691 notebookTree.setStackAction(menuBar.notebookStackAction);
692 notebookTree.setPublishAction(menuBar.notebookPublishAction);
693 notebookTree.setShareAction(menuBar.notebookShareAction);
694 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
695 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
696 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
697 notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
698 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
700 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
701 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
702 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
703 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
704 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
705 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
706 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
708 // ICHANGED noteTableViewに新しいタブで開くを追加
709 noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
711 noteTableView.setAddAction(menuBar.noteAdd);
713 // ICHANGED noteTableViewに新しいタブでノート追加を追加
714 noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
716 noteTableView.setDeleteAction(menuBar.noteDelete);
717 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
718 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
719 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
720 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
721 noteTableView.noteSignal.notePinned.connect(this, "notePinned()");
722 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
723 noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction);
724 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
725 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
727 quotaBar.setMouseClickAction(menuBar.accountAction);
730 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
731 trashTree.setEmptyAction(menuBar.emptyTrashAction);
732 trashTree.setVisible(Global.isWindowVisible("trashTree"));
733 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
734 trashTree.updateCounts(listManager.getTrashCount());
735 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
736 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
738 noteTableView.setVisible(Global.isWindowVisible("noteList"));
739 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
741 if (!Global.isWindowVisible("editorButtonBar"))
742 toggleEditorButtonBar();
744 if (!Global.isWindowVisible("leftPanel"))
745 menuBar.hideLeftSide.setChecked(true);
746 if (Global.isWindowVisible("noteInformation"))
747 toggleNoteInformation();
748 quotaBar.setVisible(Global.isWindowVisible("quota"));
749 // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
750 // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
751 if (!Global.isWindowVisible("quota"))
752 menuBar.hideQuota.setChecked(false);
754 searchField.setVisible(Global.isWindowVisible("searchField"));
755 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
756 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
757 if (!Global.isWindowVisible("searchField"))
758 menuBar.hideSearch.setChecked(false);
760 if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
765 find = new FindDialog();
766 find.getOkButton().clicked.connect(this, "doFindText()");
768 // Setup the tray icon menu bar
769 trayShowAction = new QAction(tr("Show/Hide"), this);
770 trayExitAction = new QAction(tr("Exit"), this);
771 trayAddNoteAction = new QAction(tr("Add Note"), this);
773 trayExitAction.triggered.connect(this, "closeNeverNote()");
774 trayAddNoteAction.triggered.connect(this, "addNote()");
775 trayShowAction.triggered.connect(this, "trayToggleVisible()");
777 trayMenu = new QMenu(this);
778 trayMenu.addAction(trayAddNoteAction);
779 trayMenu.addAction(trayShowAction);
780 trayMenu.addAction(trayExitAction);
783 trayIcon = new QSystemTrayIcon(this);
784 trayIcon.setToolTip(tr("NeighborNote"));
785 trayIcon.setContextMenu(trayMenu);
786 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
789 currentNoteGuid = Global.getLastViewedNoteGuid();
790 if (currentNoteGuid.equals(""))
791 currentNote = new Note();
795 historyGuids = new ArrayList<String>();
800 if (!currentNoteGuid.trim().equals("")) {
801 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
804 noteIndexUpdated(true);
806 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
807 if (menuBar.showEditorBar.isChecked())
808 showEditorButtons(browserWindow);
809 tagIndexUpdated(true);
810 savedSearchIndexUpdated();
811 notebookIndexUpdated();
813 setupSyncSignalListeners();
814 setupBrowserSignalListeners();
815 setupIndexListeners();
818 tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
819 tagTree.showAllTags(true);
821 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
822 if (QSystemTrayIcon.isSystemTrayAvailable()) {
823 setWindowIcon(appIcon);
824 trayIcon.setIcon(appIcon);
825 if (Global.showTrayIcon() || Global.minimizeOnClose())
831 scrollToGuid(currentNoteGuid);
832 if (Global.automaticLogin()) {
834 if (Global.isConnected)
837 setupFolderImports();
840 restoreWindowState(true);
842 if (Global.mimicEvernoteInterface) {
843 notebookTree.selectGuid("");
846 threadMonitorTimer = new QTimer();
847 threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
848 threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
850 // ICHANGED たぶんこれはいらない
853 historyGuids.add(currentNoteGuid);
857 menuBar.blockSignals(true);
858 menuBar.narrowListView.blockSignals(true);
859 menuBar.wideListView.blockSignals(true);
860 if (Global.getListView() == Global.View_List_Narrow) {
861 menuBar.narrowListView.setChecked(true);
864 menuBar.wideListView.setChecked(true);
866 menuBar.blockSignals(false);
867 menuBar.narrowListView.blockSignals(false);
868 menuBar.wideListView.blockSignals(false);
871 // 上に同じコードがあるよね? とりあえずコメントアウト
873 * if (Global.getListView() == Global.View_List_Wide) {
874 * browserIndexSplitter.addWidget(noteTableView); // ICHANGED //
875 * browserIndexSplitter.addWidget(tabBrowser);
876 * browserIndexSplitter.addWidget(browserWindow); } else {
877 * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED //
878 * mainLeftRightSplitter.addWidget(tabBrowser);
879 * mainLeftRightSplitter.addWidget(browserWindow); }
882 messageTimer = new QTimer();
883 messageTimer.timeout.connect(this, "clearMessage()");
884 messageTimer.setInterval(1000*15);
887 int sortCol = Global.getSortColumn();
888 int sortOrder = Global.getSortOrder();
889 noteTableView.proxyModel.blocked = true;
890 // We sort the table twice to fix a bug. For some reaosn the table won't sort properly if it is in narrow
891 // list view and sorted descending on the date created. By sorting it twice it forces the proper sort. Ugly.
892 if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow)
893 noteTableView.sortByColumn(sortCol, SortOrder.resolve(0));
894 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
895 noteTableView.proxyModel.blocked = false;
896 noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)");
898 // Set the startup notebook
899 String defaultNotebook = Global.getStartupNotebook();
900 if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) {
901 for (int k=0; k<listManager.getNotebookIndex().size(); k++) {
902 if (listManager.getNotebookIndex().get(k).isDefaultNotebook()) {
903 notebookTree.clearSelection();
904 notebookTree.selectGuid(listManager.getNotebookIndex().get(k).getGuid());
905 notebookTree.selectionSignal.emit();
910 if (Global.checkVersionUpgrade()) {
911 // ICHANGED TODO とりあえず封印
912 // checkForUpdates();
917 public void debugDirty() {
918 List<Note> dirty = conn.getNoteTable().getDirty();
919 logger.log(logger.LOW, "------ Dirty Notes List Begin ------");
920 for (int i=0; i<dirty.size(); i++) {
921 logger.log(logger.LOW, "GUID: " +dirty.get(i).getGuid() + " Title:" + dirty.get(i).getTitle());
923 logger.log(logger.LOW, "------ Dirty Notes List End ------");
927 public static void main(String[] args) {
928 log.setLevel(Level.FATAL);
929 QApplication.initialize(args);
930 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
931 QSplashScreen splash = new QSplashScreen(pixmap);
934 DatabaseConnection dbConn;
937 initializeGlobalSettings(args);
939 showSplash = Global.isWindowVisible("SplashScreen");
943 dbConn = setupDatabaseConnection();
945 // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
946 Global.getFileManager().purgeResDirectory(true);
948 } catch (InitializationException e) {
951 QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
956 String proxyUrl = Global.getProxyValue("url");
957 String proxyPort = Global.getProxyValue("port");
958 String proxyUserid = Global.getProxyValue("userid");
959 String proxyPassword = Global.getProxyValue("password");
960 boolean proxySet = false;
961 QNetworkProxy proxy = new QNetworkProxy();
962 proxy.setType(ProxyType.HttpProxy);
963 if (!proxyUrl.trim().equals("")) {
964 System.out.println("Proxy URL found: " +proxyUrl);
966 proxy.setHostName(proxyUrl);
968 if (!proxyPort.trim().equals("")) {
969 System.out.println("Proxy Port found: " +proxyPort);
971 proxy.setPort(Integer.parseInt(proxyPort));
973 if (!proxyUserid.trim().equals("")) {
974 System.out.println("Proxy Userid found: " +proxyUserid);
976 proxy.setUser(proxyUserid);
978 if (!proxyPassword.trim().equals("")) {
979 System.out.println("Proxy URL found: " +proxyPassword);
981 proxy.setPassword(proxyPassword);
984 QNetworkProxy.setApplicationProxy(proxy);
988 NeverNote application = new NeverNote(dbConn);
989 if (Global.syncOnly) {
990 System.out.println("Performing synchronization only.");
991 application.remoteConnect();
992 if (Global.isConnected) {
993 application.syncRunner.syncNeeded = true;
994 application.syncRunner.addWork("SYNC");
995 application.syncRunner.addWork("STOP");
996 while(!application.syncRunner.isIdle());
997 application.closeNeverNote();
1002 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
1003 if (Global.startMinimized())
1004 application.showMinimized();
1006 if (Global.wasWindowMaximized())
1007 application.showMaximized();
1013 splash.finish(application);
1014 QApplication.exec();
1015 System.out.println("Goodbye.");
1016 QApplication.exit();
1020 * Open the internal database, or create if not present
1022 * @throws InitializationException when opening the database fails, e.g. because another process has it locked
1024 private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
1025 ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
1027 File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
1028 File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
1029 // IFIXED resourceDatabaseNameになっていたので修正
1030 File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
1032 File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
1035 Global.setDatabaseUrl("");
1037 Global.setResourceDatabaseUrl("");
1039 Global.setIndexDatabaseUrl("");
1042 Global.setBehaviorDatabaseUrl("");
1044 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
1045 boolean goodCheck = false;
1046 while (!goodCheck) {
1047 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
1049 if (!dialog.okPressed())
1051 Global.cipherPassword = dialog.getPassword();
1052 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
1053 Global.getDatabaseUserPassword(), Global.cipherPassword);
1056 // ICHANGED Global.getBehaviorDatabaserUrl()を追加
1057 DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(),
1058 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
1059 Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
1063 // Encrypt the database upon shutdown
1064 private void encryptOnShutdown() {
1065 String dbPath= Global.getFileManager().getDbDirPath("");
1068 Statement st = conn.getConnection().createStatement();
1069 st.execute("shutdown");
1070 st = conn.getResourceConnection().createStatement();
1071 st.execute("shutdown");
1072 st = conn.getIndexConnection().createStatement();
1073 st.execute("shutdown");
1075 st = conn.getBehaviorConnection().createStatement();
1076 st.execute("shutdown");
1078 if (QMessageBox.question(this, tr("Are you sure"),
1079 tr("Are you sure you wish to encrypt the database?"),
1080 QMessageBox.StandardButton.Yes,
1081 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1082 ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1083 ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1084 ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1086 ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1088 Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
1089 Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
1090 Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
1092 Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
1094 QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
1096 } catch (SQLException e) {
1097 e.printStackTrace();
1101 // Decrypt the database upon shutdown
1102 private void decryptOnShutdown() {
1103 String dbPath= Global.getFileManager().getDbDirPath("");
1104 String dbName = "NeverNote";
1106 Statement st = conn.getConnection().createStatement();
1107 st.execute("shutdown");
1108 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
1109 encryptCipher = "AES";
1111 encryptCipher = "XTEA";
1112 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
1113 "Are you sure you wish to decrypt the database?"),
1114 QMessageBox.StandardButton.Yes,
1115 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1117 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
1118 Global.setDatabaseUrl("");
1119 Global.setResourceDatabaseUrl("");
1120 Global.setIndexDatabaseUrl("");
1121 QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
1123 } catch (SQLException e) {
1124 e.printStackTrace();
1128 * Encrypt/Decrypt the local database
1130 public void doDatabaseEncrypt() {
1131 // The database is not currently encrypted
1132 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
1133 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
1134 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
1135 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
1136 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
1137 "Do you wish to proceed?"),
1138 QMessageBox.StandardButton.Yes,
1139 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1142 DBEncryptDialog dialog = new DBEncryptDialog();
1144 if (dialog.okPressed()) {
1145 Global.cipherPassword = dialog.getPassword();
1146 encryptOnShutdown = true;
1147 encryptCipher = dialog.getEncryptionMethod();
1150 DBEncryptDialog dialog = new DBEncryptDialog();
1151 dialog.setWindowTitle(tr("Database Decryption"));
1152 dialog.hideEncryption();
1154 if (dialog.okPressed()) {
1155 if (!dialog.getPassword().equals(Global.cipherPassword)) {
1156 QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
1159 decryptOnShutdown = true;
1166 private static void initializeGlobalSettings(String[] args) throws InitializationException {
1167 StartupConfig startupConfig = new StartupConfig();
1169 for (String arg : args) {
1170 String lower = arg.toLowerCase();
1171 if (lower.startsWith("--name="))
1172 startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
1173 if (lower.startsWith("--home="))
1174 startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
1175 if (lower.startsWith("--disable-viewing"))
1176 startupConfig.setDisableViewing(true);
1177 if (lower.startsWith("--sync-only=true"))
1178 startupConfig.setSyncOnly(true);
1180 Global.setup(startupConfig);
1186 public void closeEvent(QCloseEvent event) {
1187 if (Global.minimizeOnClose() && !closeAction) {
1192 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
1195 if (currentNote != null & browserWindow != null) {
1196 if (currentNote.getTitle() != null && browserWindow != null
1197 && !currentNote.getTitle().equals(browserWindow.getTitle()))
1198 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
1199 browserWindow.getTitle());
1203 setMessage(tr("Beginning shutdown."));
1205 // Close down external windows
1206 Collection<ExternalBrowse> windows = externalWindows.values();
1207 Iterator<ExternalBrowse> iterator = windows.iterator();
1208 while (iterator.hasNext()) {
1209 ExternalBrowse browser = iterator.next();
1210 browser.windowClosing.disconnect();
1214 // ICHANGED タブブラウザに対してクローズ処理を行う
1215 Collection<TabBrowse> win = tabWindows.values();
1216 Iterator<TabBrowse> it = win.iterator();
1217 tabBrowser.currentChanged.disconnect();
1218 tabBrowser.tabCloseRequested.disconnect();
1219 while (it.hasNext()) {
1220 TabBrowse browser = it.next();
1224 externalFileEditedSaver();
1225 if (Global.isConnected && Global.synchronizeOnClose()) {
1226 setMessage(tr("Performing synchronization before closing."));
1227 syncRunner.syncNeeded = true;
1228 syncRunner.addWork("SYNC");
1230 syncRunner.keepRunning = false;
1232 syncRunner.addWork("STOP");
1233 setMessage("Closing Program.");
1234 threadMonitorTimer.stop();
1236 thumbnailRunner.addWork("STOP");
1237 indexRunner.addWork("STOP");
1242 if (tempFiles != null)
1245 browserWindow.noteSignal.tagsChanged.disconnect();
1246 browserWindow.noteSignal.titleChanged.disconnect();
1247 browserWindow.noteSignal.noteChanged.disconnect();
1248 browserWindow.noteSignal.notebookChanged.disconnect();
1249 browserWindow.noteSignal.createdDateChanged.disconnect();
1250 browserWindow.noteSignal.alteredDateChanged.disconnect();
1251 syncRunner.searchSignal.listChanged.disconnect();
1252 syncRunner.tagSignal.listChanged.disconnect();
1253 syncRunner.notebookSignal.listChanged.disconnect();
1254 syncRunner.noteIndexSignal.listChanged.disconnect();
1257 Global.saveWindowVisible("toolBar", toolBar.isVisible());
1258 saveNoteColumnPositions();
1259 saveNoteIndexWidth();
1261 int width = notebookTree.columnWidth(0);
1262 Global.setColumnWidth("notebookTreeName", width);
1263 width = tagTree.columnWidth(0);
1264 Global.setColumnWidth("tagTreeName", width);
1266 Global.saveWindowMaximized(isMaximized());
1267 Global.saveCurrentNoteGuid(currentNoteGuid);
1269 int sortCol = noteTableView.proxyModel.sortColumn();
1270 int sortOrder = noteTableView.proxyModel.sortOrder().value();
1271 Global.setSortColumn(sortCol);
1272 Global.setSortOrder(sortOrder);
1276 Global.keepRunning = false;
1278 logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
1279 if (indexRunner.thread().isAlive())
1280 indexRunner.thread().join(50);
1281 if (!indexRunner.thread().isAlive())
1282 logger.log(logger.MEDIUM, "Index thread has stopped");
1284 logger.log(logger.MEDIUM, "Index thread still running - interrupting");
1285 indexRunner.thread().interrupt();
1287 } catch (InterruptedException e1) {
1288 e1.printStackTrace();
1291 if (!syncRunner.thread().isAlive()) {
1292 logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
1293 if (syncRunner.thread().isAlive()) {
1294 System.out.println(tr("Synchronizing. Please be patient."));
1295 for(;syncRunner.thread().isAlive();) {
1298 } catch (InterruptedException e) {
1299 e.printStackTrace();
1303 logger.log(logger.MEDIUM, "Sync thread has stopped");
1306 if (encryptOnShutdown) {
1307 encryptOnShutdown();
1309 if (decryptOnShutdown) {
1310 decryptOnShutdown();
1313 Global.getFileManager().purgeResDirectory(false);
1314 } catch (InitializationException e) {
1315 System.out.println(tr("Empty res directory purge failed"));
1316 e.printStackTrace();
1318 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
1322 private void closeNeverNote() {
1326 public void setMessage(String s) {
1328 logger.log(logger.HIGH, "Entering NeverNote.setMessage");
1330 System.out.println("*** ERROR *** " +s);
1332 if (statusBar != null) {
1335 logger.log(logger.HIGH, "Message: " +s);
1336 statusBar.showMessage(s);
1337 if (emitLog != null)
1340 if (messageTimer != null) {
1341 messageTimer.stop();
1342 messageTimer.setSingleShot(true);
1343 messageTimer.start();
1348 logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
1351 private void clearMessage() {
1352 statusBar.clearMessage();
1356 private void waitCursor(boolean wait) {
1358 if (QApplication.overrideCursor() == null)
1359 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1362 if (QApplication.overrideCursor() != null)
1363 QApplication.restoreOverrideCursor();
1365 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.ArrowCursor));
1367 listManager.refreshCounters();
1370 private void setupIndexListeners() {
1371 // indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1372 // indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1373 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1374 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1376 private void setupSyncSignalListeners() {
1377 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1378 syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1379 syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1380 syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1381 syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1383 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1384 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1385 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1387 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1388 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1389 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1390 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1391 syncRunner.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1393 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1396 private void setupBrowserSignalListeners() {
1397 setupBrowserWindowListeners(browserWindow, true);
1400 private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1401 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1402 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1403 browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1404 if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1405 browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1406 browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1407 browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1408 browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1409 browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1410 browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1411 browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1412 browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1413 browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1414 browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1415 browser.blockApplication.connect(this, "blockApplication(BrowserWindow)");
1416 browser.unblockApplication.connect(this, "unblockApplication()");
1417 if (master) browser.focusLost.connect(this, "saveNote()");
1418 browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1419 browser.evernoteLinkClicked.connect(this, "evernoteLinkClick(String, String)");
1422 //**************************************************
1424 //**************************************************
1425 private void setupShortcut(QShortcut action, String text) {
1426 if (!Global.shortcutKeys.containsAction(text))
1428 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
1431 //***************************************************************
1432 //***************************************************************
1433 //* Settings and look & feel
1434 //***************************************************************
1435 //***************************************************************
1436 @SuppressWarnings("unused")
1437 private void settings() {
1438 logger.log(logger.HIGH, "Entering NeverNote.settings");
1440 saveNoteColumnPositions();
1441 saveNoteIndexWidth();
1443 ConfigDialog settings = new ConfigDialog(this);
1444 String dateFormat = Global.getDateFormat();
1445 String timeFormat = Global.getTimeFormat();
1447 indexTime = 1000*Global.getIndexThreadSleepInterval();
1448 indexTimer.start(indexTime); // reset indexing timer
1451 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1452 indexRunner.indexNoteBody = Global.indexNoteBody();
1453 indexRunner.indexNoteTitle = Global.indexNoteTitle();
1454 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
1455 indexRunner.indexImageRecognition = Global.indexImageRecognition();
1456 if (Global.showTrayIcon() || Global.minimizeOnClose())
1461 if (menuBar.showEditorBar.isChecked()){
1463 for(int i = 0; i < tabBrowser.count(); i++){
1464 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
1465 showEditorButtons(browser);
1470 // Reset the save timer
1471 if (Global.getAutoSaveInterval() > 0)
1472 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1477 // Set special reloads
1478 if (settings.getDebugPage().reloadSharedNotebooksClicked()) {
1479 conn.executeSql("Delete from LinkedNotebook");
1480 conn.executeSql("delete from SharedNotebook");
1481 conn.executeSql("Delete from Notebook where linked=true");
1482 conn.executeSql("Insert into Sync (key, value) values ('FullLinkedNotebookSync', 'true')");
1483 conn.executeSql("Insert into Sync (key, value) values ('FullSharedNotebookSync', 'true')");
1488 readOnlyCache.clear();
1489 inkNoteCache.clear();
1490 noteIndexUpdated(true);
1492 logger.log(logger.HIGH, "Leaving NeverNote.settings");
1494 // Restore things to the way they were
1495 private void restoreWindowState(boolean mainWindow) {
1496 // We need to name things or this doesn't work.
1497 setObjectName("NeverNote");
1498 restoreState(Global.restoreState(objectName()));
1499 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1500 browserIndexSplitter.setObjectName("browserIndexSplitter");
1501 leftSplitter1.setObjectName("leftSplitter1");
1503 rensoNoteListDock.setObjectName("rensoNoteListDock");
1505 // Restore the actual positions.
1507 restoreGeometry(Global.restoreGeometry(objectName()));
1508 mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1509 browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1510 leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1512 rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
1515 // Save window positions for the next start
1516 private void saveWindowState() {
1517 Global.saveGeometry(objectName(), saveGeometry());
1518 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1519 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1520 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1521 Global.saveState(objectName(), saveState());
1523 Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
1525 // Load the style sheet
1526 private void loadStyleSheet() {
1527 String styleSheetName = "default.qss";
1528 if (Global.getStyle().equalsIgnoreCase("cleanlooks"))
1529 styleSheetName = "default-cleanlooks.qss";
1530 String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
1531 QFile file = new QFile(fileName);
1533 // If a user default.qss doesn't exist, we use the one shipped with NeverNote
1534 if (!file.exists()) {
1535 fileName = Global.getFileManager().getQssDirPath(styleSheetName);
1536 file = new QFile(fileName);
1538 file.open(OpenModeFlag.ReadOnly);
1539 String styleSheet = file.readAll().toString();
1541 setStyleSheet(styleSheet);
1543 // Save column positions for the next time
1544 private void saveNoteColumnPositions() {
1545 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1546 Global.setColumnPosition("noteTableCreationPosition", position);
1547 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1548 Global.setColumnPosition("noteTableTagPosition", position);
1549 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1550 Global.setColumnPosition("noteTableNotebookPosition", position);
1551 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1552 Global.setColumnPosition("noteTableChangedPosition", position);
1553 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1554 Global.setColumnPosition("noteTableAuthorPosition", position);
1555 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1556 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1557 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1558 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1559 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1560 Global.setColumnPosition("noteTableTitlePosition", position);
1561 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1562 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1563 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1564 Global.setColumnPosition("noteTableGuidPosition", position);
1565 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1566 Global.setColumnPosition("noteTableThumbnailPosition", position);
1567 position = noteTableView.header.visualIndex(Global.noteTablePinnedPosition);
1568 Global.setColumnPosition("noteTablePinnedPosition", position);
1571 // Save column widths for the next time
1572 private void saveNoteIndexWidth() {
1574 width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1575 Global.setColumnWidth("noteTableCreationPosition", width);
1576 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1577 Global.setColumnWidth("noteTableChangedPosition", width);
1578 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1579 Global.setColumnWidth("noteTableGuidPosition", width);
1580 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1581 Global.setColumnWidth("noteTableNotebookPosition", width);
1582 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1583 Global.setColumnWidth("noteTableTagPosition", width);
1584 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1585 Global.setColumnWidth("noteTableTitlePosition", width);
1586 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1587 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1588 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1589 Global.setColumnWidth("noteTableAuthorPosition", width);
1590 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1591 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1592 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1593 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1594 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1595 Global.setColumnWidth("noteTableThumbnailPosition", width);
1596 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1597 Global.setColumnWidth("noteTableGuidPosition", width);
1598 width = noteTableView.getColumnWidth(Global.noteTablePinnedPosition);
1599 Global.setColumnWidth("noteTablePinnedPosition", width);
1602 @SuppressWarnings("unused")
1603 private void toggleSearchWindow() {
1604 logger.log(logger.HIGH, "Entering NeverNote.toggleSearchWindow");
1605 searchLayout.toggleSearchField();
1606 menuBar.hideSearch.setChecked(searchField.isVisible());
1607 Global.saveWindowVisible("searchField", searchField.isVisible());
1608 logger.log(logger.HIGH, "Leaving NeverNote.toggleSearchWindow");
1610 @SuppressWarnings("unused")
1611 private void toggleQuotaWindow() {
1612 logger.log(logger.HIGH, "Entering NeverNote.toggleQuotaWindow");
1613 searchLayout.toggleQuotaBar();
1614 menuBar.hideQuota.setChecked(quotaBar.isVisible());
1615 Global.saveWindowVisible("quota", quotaBar.isVisible());
1616 logger.log(logger.HIGH, "Leaving NeverNote.toggleQuotaWindow");
1618 @SuppressWarnings("unused")
1619 private void toggleZoomWindow() {
1620 logger.log(logger.HIGH, "Entering NeverNote.toggleZoomWindow");
1621 searchLayout.toggleZoom();
1622 menuBar.hideZoom.setChecked(zoomSpinner.isVisible());
1623 Global.saveWindowVisible("zoom", zoomSpinner.isVisible());
1624 logger.log(logger.HIGH, "Leaving NeverNote.toggleZoomWindow");
1629 //***************************************************************
1630 //***************************************************************
1631 //** These functions deal with Notebook menu items
1632 //***************************************************************
1633 //***************************************************************
1634 // Setup the tree containing the user's notebooks.
1635 private void initializeNotebookTree() {
1636 logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1637 // notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1638 notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
1639 listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1640 logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1642 // Listener when a notebook is selected
1643 private void notebookTreeSelection() {
1644 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1645 noteTableView.proxyModel.blocked = true;
1648 clearAttributeFilter();
1649 clearSavedSearchFilter();
1650 if (Global.mimicEvernoteInterface) {
1652 //searchField.clear();
1653 searchField.clearEditText();
1655 menuBar.noteRestoreAction.setVisible(false);
1656 menuBar.notebookEditAction.setEnabled(true);
1657 menuBar.notebookDeleteAction.setEnabled(true);
1658 menuBar.notebookPublishAction.setEnabled(true);
1659 menuBar.notebookShareAction.setEnabled(true);
1660 menuBar.notebookIconAction.setEnabled(true);
1661 menuBar.notebookStackAction.setEnabled(true);
1663 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
1664 if (!rensoNoteListDock.isEnabled()) {
1665 rensoNoteListDock.setEnabled(true);
1668 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1669 selectedNotebookGUIDs.clear();
1671 String stackName = "";
1672 if (selections.size() > 0) {
1673 guid = (selections.get(0).text(2));
1674 stackName = selections.get(0).text(0);
1676 if (!Global.mimicEvernoteInterface) {
1677 // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1678 if (selections.size()==0) {
1679 selectedNotebookGUIDs.clear();
1680 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1681 selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1683 menuBar.notebookEditAction.setEnabled(false);
1684 menuBar.notebookDeleteAction.setEnabled(false);
1685 menuBar.notebookStackAction.setEnabled(false);
1686 menuBar.notebookIconAction.setEnabled(false);
1689 if (!guid.equals("") && !guid.equals("STACK")) {
1690 selectedNotebookGUIDs.add(guid);
1691 menuBar.notebookIconAction.setEnabled(true);
1693 menuBar.notebookIconAction.setEnabled(true);
1694 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1695 Notebook book = listManager.getNotebookIndex().get(j);
1696 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1697 selectedNotebookGUIDs.add(book.getGuid());
1700 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1701 listManager.loadNotesIndex();
1702 noteIndexUpdated(false);
1703 refreshEvernoteNote(true);
1704 listManager.refreshCounters = true;
1705 listManager.refreshCounters();
1706 if (selectedNotebookGUIDs.size() == 1) {
1707 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1708 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1710 noteTableView.proxyModel.blocked = true;
1712 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1714 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1717 noteTableView.proxyModel.blocked = false;
1718 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1721 private void clearNotebookFilter() {
1722 notebookTree.blockSignals(true);
1723 notebookTree.clearSelection();
1724 menuBar.noteRestoreAction.setVisible(false);
1725 menuBar.notebookEditAction.setEnabled(false);
1726 menuBar.notebookDeleteAction.setEnabled(false);
1727 selectedNotebookGUIDs.clear();
1728 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1729 notebookTree.blockSignals(false);
1731 // Triggered when the notebook DB has been updated
1732 private void notebookIndexUpdated() {
1733 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1735 // Get the possible icons
1736 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1737 notebookTree.setIcons(icons);
1739 if (selectedNotebookGUIDs == null)
1740 selectedNotebookGUIDs = new ArrayList<String>();
1741 List<Notebook> books = conn.getNotebookTable().getAll();
1742 for (int i=books.size()-1; i>=0; i--) {
1743 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1744 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1746 j=listManager.getArchiveNotebookIndex().size();
1752 listManager.countNotebookResults(listManager.getNoteIndex());
1753 notebookTree.blockSignals(true);
1754 notebookTree.load(books, listManager.getLocalNotebooks());
1755 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1756 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1758 selectedNotebookGUIDs.remove(i);
1760 listManager.refreshCounters = true;
1761 listManager.refreshCounters();
1762 notebookTree.blockSignals(false);
1764 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1766 // Show/Hide note information
1767 @SuppressWarnings("unused")
1768 private void toggleNotebookWindow() {
1769 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1770 searchLayout.toggleNotebook();
1771 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1772 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1773 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1775 // Add a new notebook
1776 @SuppressWarnings("unused")
1777 private void addNotebook() {
1778 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1779 NotebookEdit edit = new NotebookEdit();
1780 edit.setNotebooks(listManager.getNotebookIndex());
1783 if (!edit.okPressed())
1786 Calendar currentTime = new GregorianCalendar();
1787 Long l = new Long(currentTime.getTimeInMillis());
1788 String randint = new String(Long.toString(l));
1790 Notebook newBook = new Notebook();
1791 newBook.setUpdateSequenceNum(0);
1792 newBook.setGuid(randint);
1793 newBook.setName(edit.getNotebook());
1794 newBook.setServiceCreated(new Date().getTime());
1795 newBook.setServiceUpdated(new Date().getTime());
1796 newBook.setDefaultNotebook(false);
1797 newBook.setPublished(false);
1799 listManager.getNotebookIndex().add(newBook);
1801 listManager.getLocalNotebooks().add(newBook.getGuid());
1802 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1803 notebookIndexUpdated();
1804 listManager.countNotebookResults(listManager.getNoteIndex());
1805 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1806 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1808 // Edit an existing notebook
1809 @SuppressWarnings("unused")
1810 private void stackNotebook() {
1811 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1812 StackNotebook edit = new StackNotebook();
1814 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1815 QTreeWidgetItem currentSelection;
1816 for (int i=0; i<selections.size(); i++) {
1817 currentSelection = selections.get(0);
1818 String guid = currentSelection.text(2);
1819 if (guid.equalsIgnoreCase("")) {
1820 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1823 if (guid.equalsIgnoreCase("STACK")) {
1824 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1829 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1834 if (!edit.okPressed())
1837 String stack = edit.getStackName();
1839 for (int i=0; i<selections.size(); i++) {
1840 currentSelection = selections.get(i);
1841 String guid = currentSelection.text(2);
1842 listManager.updateNotebookStack(guid, stack);
1844 notebookIndexUpdated();
1845 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1847 // Edit an existing notebook
1848 @SuppressWarnings("unused")
1849 private void editNotebook() {
1850 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1851 NotebookEdit edit = new NotebookEdit();
1853 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1854 QTreeWidgetItem currentSelection;
1855 currentSelection = selections.get(0);
1856 edit.setNotebook(currentSelection.text(0));
1858 String guid = currentSelection.text(2);
1859 if (!guid.equalsIgnoreCase("STACK")) {
1860 edit.setTitle(tr("Edit Notebook"));
1861 edit.setNotebooks(listManager.getNotebookIndex());
1862 edit.setLocalCheckboxEnabled(false);
1863 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1864 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1865 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1866 i=listManager.getNotebookIndex().size();
1870 edit.setTitle(tr("Edit Stack"));
1871 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1872 edit.hideLocalCheckbox();
1873 edit.hideDefaultCheckbox();
1878 if (!edit.okPressed())
1882 if (guid.equalsIgnoreCase("STACK")) {
1883 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1884 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1885 if (listManager.getNotebookIndex().get(j).getStack() != null &&
1886 listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1887 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1889 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1890 currentSelection.setText(0, edit.getNotebook());
1894 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1895 currentSelection.setText(0, edit.getNotebook());
1897 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1898 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1899 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1900 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1901 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1902 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1903 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1904 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1906 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1907 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1908 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1909 linkedNotebook.setShareName(edit.getNotebook());
1910 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1912 i=listManager.getNotebookIndex().size();
1916 // Build a list of non-closed notebooks
1917 List<Notebook> nbooks = new ArrayList<Notebook>();
1918 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1919 boolean found=false;
1920 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1921 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1925 nbooks.add(listManager.getNotebookIndex().get(i));
1929 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1930 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1931 browserWindow.setNotebookList(filteredBooks);
1932 Iterator<String> set = externalWindows.keySet().iterator();
1933 while(set.hasNext())
1934 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1937 Iterator<Integer>it = tabWindows.keySet().iterator();
1938 while (it.hasNext()) {
1939 tabWindows.get(it.next()).getBrowserWindow()
1940 .setNotebookList(filteredBooks);
1943 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1945 // Publish a notebook
1946 @SuppressWarnings("unused")
1947 private void publishNotebook() {
1948 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1949 QTreeWidgetItem currentSelection;
1950 currentSelection = selections.get(0);
1951 String guid = currentSelection.text(2);
1953 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1958 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1959 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1960 n = listManager.getNotebookIndex().get(i);
1962 i = listManager.getNotebookIndex().size();
1968 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1971 if (!publish.okClicked())
1974 Publishing p = publish.getPublishing();
1975 boolean isPublished = !publish.isStopPressed();
1976 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1977 n.setPublished(isPublished);
1979 listManager.getNotebookIndex().set(position, n);
1980 notebookIndexUpdated();
1982 // Publish a notebook
1983 @SuppressWarnings("unused")
1984 private void shareNotebook() {
1985 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1986 QTreeWidgetItem currentSelection;
1987 currentSelection = selections.get(0);
1988 String guid = currentSelection.text(2);
1990 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1994 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1995 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1996 n = listManager.getNotebookIndex().get(i);
1997 i = listManager.getNotebookIndex().size();
2001 String authToken = null;
2002 if (syncRunner.isConnected)
2003 authToken = syncRunner.authToken;
2004 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
2009 // Delete an existing notebook
2010 @SuppressWarnings("unused")
2011 private void deleteNotebook() {
2012 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2013 boolean stacksFound = false;
2014 boolean notebooksFound = false;
2015 boolean assigned = false;
2016 // Check if any notes have this notebook
2017 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2018 for (int i=0; i<selections.size(); i++) {
2019 QTreeWidgetItem currentSelection;
2020 currentSelection = selections.get(i);
2021 String guid = currentSelection.text(2);
2022 if (!guid.equalsIgnoreCase("STACK")) {
2023 notebooksFound = true;
2024 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
2025 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
2026 if (noteGuid.equals(guid)) {
2028 j=listManager.getNoteIndex().size();
2029 i=selections.size();
2037 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2038 "Please delete the notes or move them to another notebook before deleting any notebooks."));
2042 if (conn.getNotebookTable().getAll().size() == 1) {
2043 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2047 // If all notebooks are clear, verify the delete
2048 String msg1 = new String(tr("Delete selected notebooks?"));
2049 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2050 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2051 " not deleted unless selected?"));
2053 if (stacksFound && notebooksFound)
2055 if (!stacksFound && notebooksFound)
2057 if (stacksFound && !notebooksFound)
2059 if (QMessageBox.question(this, tr("Confirmation"), msg,
2060 QMessageBox.StandardButton.Yes,
2061 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2065 // If confirmed, delete the notebook
2066 for (int i=selections.size()-1; i>=0; i--) {
2067 QTreeWidgetItem currentSelection;
2068 currentSelection = selections.get(i);
2069 String guid = currentSelection.text(2);
2070 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2071 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2072 listManager.renameStack(currentSelection.text(0), "");
2074 conn.getNotebookTable().expungeNotebook(guid, true);
2075 listManager.deleteNotebook(guid);
2079 notebookIndexUpdated();
2080 // notebookTreeSelection();
2081 // notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2082 // listManager.countNotebookResults(listManager.getNoteIndex());
2083 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2085 // A note's notebook has been updated
2086 @SuppressWarnings("unused")
2087 private void updateNoteNotebook(String guid, String notebookGuid) {
2088 // ICHANGED 同じノートブックに入れられたノート間の履歴を登録
2089 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2091 // Update the list manager
2092 listManager.updateNoteNotebook(guid, notebookGuid);
2093 listManager.countNotebookResults(listManager.getNoteIndex());
2094 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
2096 // Find the name of the notebook
2097 String notebookName = null;
2098 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2099 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2100 notebookName = listManager.getNotebookIndex().get(i).getName();
2105 // If we found the name, update the browser window
2106 if (notebookName != null) {
2107 updateListNoteNotebook(guid, notebookName);
2108 if (guid.equals(currentNoteGuid)) {
2109 int pos = browserWindow.notebookBox.findText(notebookName);
2111 browserWindow.notebookBox.setCurrentIndex(pos);
2115 // If we're dealing with the current note, then we need to be sure and update the notebook there
2116 if (guid.equals(currentNoteGuid)) {
2117 if (currentNote != null) {
2118 currentNote.setNotebookGuid(notebookGuid);
2122 // Open/close notebooks
2123 @SuppressWarnings("unused")
2124 private void closeNotebooks() {
2125 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2127 if (!na.okClicked())
2131 listManager.getArchiveNotebookIndex().clear();
2133 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2134 String text = na.getClosedBookList().takeItem(i).text();
2135 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2136 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2137 Notebook n = listManager.getNotebookIndex().get(j);
2138 conn.getNotebookTable().setArchived(n.getGuid(),true);
2139 listManager.getArchiveNotebookIndex().add(n);
2140 j=listManager.getNotebookIndex().size();
2145 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2146 String text = na.getOpenBookList().takeItem(i).text();
2147 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2148 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2149 Notebook n = listManager.getNotebookIndex().get(j);
2150 conn.getNotebookTable().setArchived(n.getGuid(),false);
2151 j=listManager.getNotebookIndex().size();
2155 notebookTreeSelection();
2156 listManager.loadNotesIndex();
2157 notebookIndexUpdated();
2158 noteIndexUpdated(false);
2159 reloadTagTree(true);
2160 // noteIndexUpdated(false);
2162 // Build a list of non-closed notebooks
2163 List<Notebook> nbooks = new ArrayList<Notebook>();
2164 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2165 boolean found=false;
2166 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2167 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2171 nbooks.add(listManager.getNotebookIndex().get(i));
2174 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2175 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2176 browserWindow.setNotebookList(filteredBooks);
2178 // Update any external windows
2179 Iterator<String> set = externalWindows.keySet().iterator();
2180 while(set.hasNext())
2181 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2185 Iterator<Integer> it = tabWindows.keySet().iterator();
2186 while (it.hasNext()) {
2187 tabWindows.get(it.next()).getBrowserWindow()
2188 .setNotebookList(filteredBooks);
2193 // Change the notebook's icon
2194 @SuppressWarnings("unused")
2195 private void setNotebookIcon() {
2196 boolean stackSelected = false;
2197 boolean allNotebookSelected = false;
2199 QTreeWidgetItem currentSelection;
2200 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2201 if (selections.size() == 0)
2204 currentSelection = selections.get(0);
2205 String guid = currentSelection.text(2);
2206 if (guid.equalsIgnoreCase(""))
2207 allNotebookSelected = true;
2208 if (guid.equalsIgnoreCase("STACK"))
2209 stackSelected = true;
2211 QIcon currentIcon = currentSelection.icon(0);
2215 if (!stackSelected && !allNotebookSelected) {
2216 icon = conn.getNotebookTable().getIcon(guid);
2218 dialog = new SetIcon(currentIcon, saveLastPath);
2219 dialog.setUseDefaultIcon(true);
2221 dialog = new SetIcon(icon, saveLastPath);
2222 dialog.setUseDefaultIcon(false);
2225 if (stackSelected) {
2226 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2228 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
2231 dialog = new SetIcon(currentIcon, saveLastPath);
2232 dialog.setUseDefaultIcon(true);
2234 dialog = new SetIcon(icon, saveLastPath);
2235 dialog.setUseDefaultIcon(false);
2239 if (dialog.okPressed()) {
2240 saveLastPath = dialog.getPath();
2242 QIcon newIcon = dialog.getIcon();
2243 if (stackSelected) {
2244 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2245 if (newIcon == null) {
2246 newIcon = new QIcon(iconPath+"books2.png");
2248 currentSelection.setIcon(0,newIcon);
2251 if (allNotebookSelected) {
2252 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2253 if (newIcon == null) {
2254 newIcon = new QIcon(iconPath+"notebook-green.png");
2256 currentSelection.setIcon(0,newIcon);
2259 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2260 if (newIcon == null) {
2261 boolean isPublished = false;;
2262 boolean found = false;
2263 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2264 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2265 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2269 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2271 currentSelection.setIcon(0, newIcon);
2277 //***************************************************************
2278 //***************************************************************
2279 //** These functions deal with Tag menu items
2280 //***************************************************************
2281 //***************************************************************
2282 // Add a new notebook
2283 @SuppressWarnings("unused")
2284 private void addTag() {
2285 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2286 TagEdit edit = new TagEdit();
2287 edit.setTagList(listManager.getTagIndex());
2289 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2290 QTreeWidgetItem currentSelection = null;
2291 if (selections.size() > 0) {
2292 currentSelection = selections.get(0);
2293 edit.setParentTag(currentSelection.text(0));
2298 if (!edit.okPressed())
2301 Calendar currentTime = new GregorianCalendar();
2302 Long l = new Long(currentTime.getTimeInMillis());
2303 String randint = new String(Long.toString(l));
2305 Tag newTag = new Tag();
2306 newTag.setUpdateSequenceNum(0);
2307 newTag.setGuid(randint);
2308 newTag.setName(edit.getTag());
2309 if (edit.getParentTag().isChecked()) {
2310 newTag.setParentGuid(currentSelection.text(2));
2311 newTag.setParentGuidIsSet(true);
2312 currentSelection.setExpanded(true);
2314 conn.getTagTable().addTag(newTag, true);
2315 listManager.getTagIndex().add(newTag);
2316 reloadTagTree(true);
2318 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2320 @SuppressWarnings("unused")
2321 private void reloadTagTree() {
2322 reloadTagTree(false);
2324 private void reloadTagTree(boolean reload) {
2325 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2326 tagIndexUpdated(reload);
2327 boolean filter = false;
2329 listManager.countTagResults(listManager.getNoteIndex());
2330 if (notebookTree.selectedItems().size() > 0
2331 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2333 if (tagTree.selectedItems().size() > 0)
2335 tagTree.showAllTags(!filter);
2336 tagIndexUpdated(false);
2337 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2339 // Edit an existing tag
2340 @SuppressWarnings("unused")
2341 private void editTag() {
2342 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2343 TagEdit edit = new TagEdit();
2344 edit.setTitle("Edit Tag");
2345 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2346 QTreeWidgetItem currentSelection;
2347 currentSelection = selections.get(0);
2348 edit.setTag(currentSelection.text(0));
2349 edit.setTagList(listManager.getTagIndex());
2352 if (!edit.okPressed())
2355 String guid = currentSelection.text(2);
2356 currentSelection.setText(0,edit.getTag());
2358 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2359 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2360 listManager.getTagIndex().get(i).setName(edit.getTag());
2361 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2362 updateListTagName(guid);
2363 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2364 browserWindow.setTag(getTagNamesForNote(currentNote));
2365 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2369 listManager.reloadNoteTagNames(guid, edit.getTag());
2370 noteIndexUpdated(true);
2371 refreshEvernoteNote(true);
2372 browserWindow.setTag(getTagNamesForNote(currentNote));
2373 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2375 // Delete an existing tag
2376 @SuppressWarnings("unused")
2377 private void deleteTag() {
2378 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2380 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2381 QMessageBox.StandardButton.Yes,
2382 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2386 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2387 for (int i=selections.size()-1; i>=0; i--) {
2388 QTreeWidgetItem currentSelection;
2389 currentSelection = selections.get(i);
2390 removeTagItem(currentSelection.text(2));
2392 tagIndexUpdated(true);
2394 listManager.countTagResults(listManager.getNoteIndex());
2395 // tagTree.updateCounts(listManager.getTagCounter());
2396 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2398 // Remove a tag tree item. Go recursively down & remove the children too
2399 private void removeTagItem(String guid) {
2400 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
2401 String parent = listManager.getTagIndex().get(j).getParentGuid();
2402 if (parent != null && parent.equals(guid)) {
2403 //Remove this tag's children
2404 removeTagItem(listManager.getTagIndex().get(j).getGuid());
2407 //Now, remove this tag
2408 removeListTagName(guid);
2409 conn.getTagTable().expungeTag(guid, true);
2410 for (int a=0; a<listManager.getTagIndex().size(); a++) {
2411 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2412 listManager.getTagIndex().remove(a);
2417 // Setup the tree containing the user's tags
2418 private void initializeTagTree() {
2419 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2420 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2421 // tagTree.itemClicked.connect(this, "tagTreeSelection()");
2422 tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2423 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2424 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2426 // Listener when a tag is selected
2427 private void tagTreeSelection() {
2428 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2431 clearAttributeFilter();
2432 clearSavedSearchFilter();
2434 menuBar.noteRestoreAction.setVisible(false);
2436 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2437 if (!rensoNoteListDock.isEnabled()) {
2438 rensoNoteListDock.setEnabled(true);
2441 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2442 QTreeWidgetItem currentSelection;
2443 selectedTagGUIDs.clear();
2444 for (int i=0; i<selections.size(); i++) {
2445 currentSelection = selections.get(i);
2446 selectedTagGUIDs.add(currentSelection.text(2));
2448 if (selections.size() > 0) {
2449 menuBar.tagEditAction.setEnabled(true);
2450 menuBar.tagDeleteAction.setEnabled(true);
2451 menuBar.tagIconAction.setEnabled(true);
2454 menuBar.tagEditAction.setEnabled(false);
2455 menuBar.tagDeleteAction.setEnabled(false);
2456 menuBar.tagIconAction.setEnabled(true);
2458 if (selections.size() > 1)
2459 menuBar.tagMergeAction.setEnabled(true);
2461 menuBar.tagMergeAction.setEnabled(false);
2462 listManager.setSelectedTags(selectedTagGUIDs);
2463 listManager.loadNotesIndex();
2464 noteIndexUpdated(false);
2465 refreshEvernoteNote(true);
2466 listManager.refreshCounters = true;
2467 listManager.refreshCounters();
2468 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2470 // trigger the tag index to be refreshed
2471 @SuppressWarnings("unused")
2472 private void tagIndexUpdated() {
2473 tagIndexUpdated(true);
2475 private void tagIndexUpdated(boolean reload) {
2476 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2477 if (selectedTagGUIDs == null)
2478 selectedTagGUIDs = new ArrayList<String>();
2480 listManager.reloadTagIndex();
2482 tagTree.blockSignals(true);
2484 tagTree.setIcons(conn.getTagTable().getAllIcons());
2485 tagTree.load(listManager.getTagIndex());
2488 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2489 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2491 selectedTagGUIDs.remove(i);
2493 tagTree.blockSignals(false);
2495 browserWindow.setTag(getTagNamesForNote(currentNote));
2496 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2498 // Show/Hide note information
2499 @SuppressWarnings("unused")
2500 private void toggleTagWindow() {
2501 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2502 if (tagTree.isVisible())
2506 menuBar.hideTags.setChecked(tagTree.isVisible());
2507 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2508 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2510 // A note's tags have been updated
2511 @SuppressWarnings("unused")
2512 private void updateNoteTags(String guid, List<String> tags) {
2513 // Save any new tags. We'll need them later.
2514 List<String> newTags = new ArrayList<String>();
2515 for (int i=0; i<tags.size(); i++) {
2516 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2517 newTags.add(tags.get(i));
2520 listManager.saveNoteTags(guid, tags, true);
2521 listManager.countTagResults(listManager.getNoteIndex());
2522 StringBuffer names = new StringBuffer("");
2523 for (int i=0; i<tags.size(); i++) {
2524 names = names.append(tags.get(i));
2525 if (i<tags.size()-1) {
2526 names.append(Global.tagDelimeter + " ");
2529 browserWindow.setTag(names.toString());
2532 for (TabBrowse tab: tabWindows.values()) {
2533 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
2534 int index = tabBrowser.indexOf(tab);
2535 noteDirty.put(index, true);
2540 // Now, we need to add any new tags to the tag tree
2541 for (int i=0; i<newTags.size(); i++)
2542 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2544 // Get a string containing all tag names for a note
2545 private String getTagNamesForNote(Note n) {
2546 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2547 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2549 StringBuffer buffer = new StringBuffer(100);
2550 Vector<String> v = new Vector<String>();
2551 List<String> guids = n.getTagGuids();
2556 for (int i=0; i<guids.size(); i++) {
2557 v.add(listManager.getTagNameByGuid(guids.get(i)));
2559 Comparator<String> comparator = Collections.reverseOrder();
2560 Collections.sort(v,comparator);
2561 Collections.reverse(v);
2563 for (int i = 0; i<v.size(); i++) {
2565 buffer.append(", ");
2566 buffer.append(v.get(i));
2569 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2570 return buffer.toString();
2572 // Tags were added via dropping notes from the note list
2573 @SuppressWarnings("unused")
2574 private void tagsAdded(String noteGuid, String tagGuid) {
2575 String tagName = null;
2576 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2577 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2578 tagName = listManager.getTagIndex().get(i).getName();
2579 i=listManager.getTagIndex().size();
2582 if (tagName == null)
2585 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2586 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2587 List<String> tagNames = new ArrayList<String>();
2588 tagNames.add(new String(tagName));
2589 Note n = listManager.getMasterNoteIndex().get(i);
2590 for (int j=0; j<n.getTagNames().size(); j++) {
2591 tagNames.add(new String(n.getTagNames().get(j)));
2593 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2594 if (n.getGuid().equals(currentNoteGuid)) {
2595 Collections.sort(tagNames);
2596 String display = "";
2597 for (int j=0; j<tagNames.size(); j++) {
2598 display = display+tagNames.get(j);
2599 if (j+2<tagNames.size())
2600 display = display+Global.tagDelimeter+" ";
2602 browserWindow.setTag(display);
2604 i=listManager.getMasterNoteIndex().size();
2609 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2611 private void clearTagFilter() {
2612 tagTree.blockSignals(true);
2613 tagTree.clearSelection();
2614 menuBar.noteRestoreAction.setVisible(false);
2615 menuBar.tagEditAction.setEnabled(false);
2616 menuBar.tagMergeAction.setEnabled(false);
2617 menuBar.tagDeleteAction.setEnabled(false);
2618 menuBar.tagIconAction.setEnabled(false);
2619 selectedTagGUIDs.clear();
2620 listManager.setSelectedTags(selectedTagGUIDs);
2621 tagTree.blockSignals(false);
2623 // Change the icon for a tag
2624 @SuppressWarnings("unused")
2625 private void setTagIcon() {
2626 QTreeWidgetItem currentSelection;
2627 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2628 if (selections.size() == 0)
2631 currentSelection = selections.get(0);
2632 String guid = currentSelection.text(2);
2634 QIcon currentIcon = currentSelection.icon(0);
2635 QIcon icon = conn.getTagTable().getIcon(guid);
2638 dialog = new SetIcon(currentIcon, saveLastPath);
2639 dialog.setUseDefaultIcon(true);
2641 dialog = new SetIcon(icon, saveLastPath);
2642 dialog.setUseDefaultIcon(false);
2645 if (dialog.okPressed()) {
2646 saveLastPath = dialog.getPath();
2647 QIcon newIcon = dialog.getIcon();
2648 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2649 if (newIcon == null)
2650 newIcon = new QIcon(iconPath+"tag.png");
2651 currentSelection.setIcon(0, newIcon);
2656 @SuppressWarnings("unused")
2657 private void mergeTags() {
2658 List<Tag> tags = new ArrayList<Tag>();
2659 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2660 for (int i=0; i<selections.size(); i++) {
2661 Tag record = new Tag();
2662 record.setGuid(selections.get(i).text(2));
2663 record.setName(selections.get(i).text(0));
2667 TagMerge mergeDialog = new TagMerge(tags);
2669 if (!mergeDialog.okClicked())
2671 String newGuid = mergeDialog.getNewTagGuid();
2673 for (int i=0; i<tags.size(); i++) {
2674 if (!tags.get(i).getGuid().equals(newGuid)) {
2675 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2676 for (int j=0; j<noteGuids.size(); j++) {
2677 String noteGuid = noteGuids.get(j);
2678 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2679 if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2680 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2684 listManager.reloadIndexes();
2687 //***************************************************************
2688 //***************************************************************
2689 //** These functions deal with Saved Search menu items
2690 //***************************************************************
2691 //***************************************************************
2692 // Add a new notebook
2693 @SuppressWarnings("unused")
2694 private void addSavedSearch() {
2695 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2696 SavedSearchEdit edit = new SavedSearchEdit();
2697 edit.setSearchList(listManager.getSavedSearchIndex());
2700 if (!edit.okPressed())
2703 Calendar currentTime = new GregorianCalendar();
2704 Long l = new Long(currentTime.getTimeInMillis());
2705 String randint = new String(Long.toString(l));
2707 SavedSearch search = new SavedSearch();
2708 search.setUpdateSequenceNum(0);
2709 search.setGuid(randint);
2710 search.setName(edit.getName());
2711 search.setQuery(edit.getQuery());
2712 search.setFormat(QueryFormat.USER);
2713 listManager.getSavedSearchIndex().add(search);
2714 conn.getSavedSearchTable().addSavedSearch(search, true);
2715 savedSearchIndexUpdated();
2716 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2718 // Edit an existing tag
2719 @SuppressWarnings("unused")
2720 private void editSavedSearch() {
2721 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2722 SavedSearchEdit edit = new SavedSearchEdit();
2723 edit.setTitle(tr("Edit Search"));
2724 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2725 QTreeWidgetItem currentSelection;
2726 currentSelection = selections.get(0);
2727 String guid = currentSelection.text(1);
2728 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2729 edit.setName(currentSelection.text(0));
2730 edit.setQuery(s.getQuery());
2731 edit.setSearchList(listManager.getSavedSearchIndex());
2734 if (!edit.okPressed())
2737 List<SavedSearch> list = listManager.getSavedSearchIndex();
2738 SavedSearch search = null;
2739 boolean found = false;
2740 for (int i=0; i<list.size(); i++) {
2741 search = list.get(i);
2742 if (search.getGuid().equals(guid)) {
2749 search.setName(edit.getName());
2750 search.setQuery(edit.getQuery());
2751 conn.getSavedSearchTable().updateSavedSearch(search, true);
2752 savedSearchIndexUpdated();
2753 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2755 // Delete an existing tag
2756 @SuppressWarnings("unused")
2757 private void deleteSavedSearch() {
2758 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2760 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2761 QMessageBox.StandardButton.Yes,
2762 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2766 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2767 for (int i=selections.size()-1; i>=0; i--) {
2768 QTreeWidgetItem currentSelection;
2769 currentSelection = selections.get(i);
2770 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2771 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2772 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2773 listManager.getSavedSearchIndex().remove(j);
2774 j=listManager.getSavedSearchIndex().size()+1;
2777 selections.remove(i);
2779 savedSearchIndexUpdated();
2780 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2782 // Setup the tree containing the user's tags
2783 private void initializeSavedSearchTree() {
2784 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2785 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2786 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2788 // Listener when a tag is selected
2789 @SuppressWarnings("unused")
2790 private void savedSearchTreeSelection() {
2791 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2793 clearNotebookFilter();
2796 clearAttributeFilter();
2798 String currentGuid = selectedSavedSearchGUID;
2799 menuBar.savedSearchEditAction.setEnabled(true);
2800 menuBar.savedSearchDeleteAction.setEnabled(true);
2801 menuBar.savedSearchIconAction.setEnabled(true);
2803 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2804 if (!rensoNoteListDock.isEnabled()) {
2805 rensoNoteListDock.setEnabled(true);
2808 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2809 QTreeWidgetItem currentSelection;
2810 selectedSavedSearchGUID = "";
2811 for (int i=0; i<selections.size(); i++) {
2812 currentSelection = selections.get(i);
2813 if (currentSelection.text(1).equals(currentGuid)) {
2814 currentSelection.setSelected(false);
2816 selectedSavedSearchGUID = currentSelection.text(1);
2818 // i = selections.size() +1;
2821 // There is the potential for no notebooks to be selected if this
2822 // happens then we make it look like all notebooks were selecetd.
2823 // If that happens, just select the "all notebooks"
2824 if (selections.size()==0) {
2825 clearSavedSearchFilter();
2827 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2829 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2831 private void clearSavedSearchFilter() {
2832 menuBar.savedSearchEditAction.setEnabled(false);
2833 menuBar.savedSearchDeleteAction.setEnabled(false);
2834 menuBar.savedSearchIconAction.setEnabled(false);
2835 savedSearchTree.blockSignals(true);
2836 savedSearchTree.clearSelection();
2837 savedSearchTree.blockSignals(false);
2838 selectedSavedSearchGUID = "";
2839 searchField.setEditText("");
2840 searchPerformed = false;
2841 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2843 // trigger the tag index to be refreshed
2844 private void savedSearchIndexUpdated() {
2845 if (selectedSavedSearchGUID == null)
2846 selectedSavedSearchGUID = new String();
2847 savedSearchTree.blockSignals(true);
2848 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2849 savedSearchTree.load(listManager.getSavedSearchIndex());
2850 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2851 savedSearchTree.blockSignals(false);
2853 // trigger when the saved search selection changes
2854 @SuppressWarnings("unused")
2855 private void updateSavedSearchSelection() {
2856 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2858 menuBar.savedSearchEditAction.setEnabled(true);
2859 menuBar.savedSearchDeleteAction.setEnabled(true);
2860 menuBar.savedSearchIconAction.setEnabled(true);
2861 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2863 if (selections.size() > 0) {
2864 menuBar.savedSearchEditAction.setEnabled(true);
2865 menuBar.savedSearchDeleteAction.setEnabled(true);
2866 menuBar.savedSearchIconAction.setEnabled(true);
2867 selectedSavedSearchGUID = selections.get(0).text(1);
2868 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2869 searchField.setEditText(s.getQuery());
2871 menuBar.savedSearchEditAction.setEnabled(false);
2872 menuBar.savedSearchDeleteAction.setEnabled(false);
2873 menuBar.savedSearchIconAction.setEnabled(false);
2874 selectedSavedSearchGUID = "";
2875 searchField.setEditText("");
2877 searchFieldChanged();
2879 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2883 // Show/Hide note information
2884 @SuppressWarnings("unused")
2885 private void toggleSavedSearchWindow() {
2886 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2887 if (savedSearchTree.isVisible())
2888 savedSearchTree.hide();
2890 savedSearchTree.show();
2891 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2893 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2894 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2896 // Change the icon for a saved search
2897 @SuppressWarnings("unused")
2898 private void setSavedSearchIcon() {
2899 QTreeWidgetItem currentSelection;
2900 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2901 if (selections.size() == 0)
2904 currentSelection = selections.get(0);
2905 String guid = currentSelection.text(1);
2907 QIcon currentIcon = currentSelection.icon(0);
2908 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2911 dialog = new SetIcon(currentIcon, saveLastPath);
2912 dialog.setUseDefaultIcon(true);
2914 dialog = new SetIcon(icon, saveLastPath);
2915 dialog.setUseDefaultIcon(false);
2918 if (dialog.okPressed()) {
2919 saveLastPath = dialog.getPath();
2920 QIcon newIcon = dialog.getIcon();
2921 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2922 if (newIcon == null)
2923 newIcon = new QIcon(iconPath+"search.png");
2924 currentSelection.setIcon(0, newIcon);
2932 //***************************************************************
2933 //***************************************************************
2934 //** These functions deal with Help menu & tool menu items
2935 //***************************************************************
2936 //***************************************************************
2937 // Show database status
2938 @SuppressWarnings("unused")
2939 private void databaseStatus() {
2941 indexRunner.interrupt = true;
2942 int dirty = conn.getNoteTable().getDirtyCount();
2943 int unindexed = conn.getNoteTable().getUnindexedCount();
2944 DatabaseStatus status = new DatabaseStatus();
2945 status.setUnsynchronized(dirty);
2946 status.setUnindexed(unindexed);
2947 status.setNoteCount(conn.getNoteTable().getNoteCount());
2948 status.setNotebookCount(listManager.getNotebookIndex().size());
2949 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2950 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2951 status.setTagCount(listManager.getTagIndex().size());
2952 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2953 status.setWordCount(conn.getWordsTable().getWordCount());
2957 // Compact the database
2958 @SuppressWarnings("unused")
2959 private void compactDatabase() {
2960 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2961 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2962 "but please be aware that depending upon the size of your database this can be time consuming " +
2963 "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
2964 QMessageBox.StandardButton.Yes,
2965 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2968 setMessage("Compacting database.");
2970 listManager.compactDatabase();
2972 setMessage("Database compact is complete.");
2973 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2975 @SuppressWarnings("unused")
2976 private void accountInformation() {
2977 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2978 AccountDialog dialog = new AccountDialog();
2980 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2982 @SuppressWarnings("unused")
2983 private void releaseNotes() {
2984 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
2985 QDialog dialog = new QDialog(this);
2986 QHBoxLayout layout = new QHBoxLayout();
2987 QTextEdit textBox = new QTextEdit();
2988 layout.addWidget(textBox);
2989 textBox.setReadOnly(true);
2990 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
2991 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
2992 QIODevice.OpenModeFlag.Text)))
2994 // ICHANGED 日本語文字化け対策
2995 QTextCodec codec = QTextCodec.codecForName("UTF-8");
2996 QTextStream textStream = new QTextStream(file);
2997 textStream.setCodec(codec);
2998 textBox.setText(textStream.readAll().toString());
3001 dialog.setWindowTitle(tr("Release Notes"));
3002 dialog.setLayout(layout);
3004 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
3006 // Called when user picks Log from the help menu
3007 @SuppressWarnings("unused")
3008 private void logger() {
3009 logger.log(logger.HIGH, "Entering NeverNote.logger");
3010 LogFileDialog dialog = new LogFileDialog(emitLog);
3012 logger.log(logger.HIGH, "Leaving NeverNote.logger");
3014 // Menu option "help/about" was selected
3015 @SuppressWarnings("unused")
3016 private void about() {
3017 logger.log(logger.HIGH, "Entering NeverNote.about");
3018 // ICHANGED based on...の記述を付加
3019 QMessageBox.about(this,
3020 tr("About NeighborNote"),
3021 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
3022 +Global.version + "(based on NixNote 1.5)"
3025 +"Open Source Evernote Client.<br><br>"
3026 +"Licensed under GPL v2. <br><hr><br>"
3027 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
3028 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
3029 +"PDFRenderer is licened under the LGPL<br>"
3030 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3031 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3032 +"Jazzy is licened under the LGPL<br>"
3033 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3034 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3035 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3036 logger.log(logger.HIGH, "Leaving NeverNote.about");
3038 // Hide the entire left hand side
3039 @SuppressWarnings("unused")
3040 private void toggleLeftSide() {
3043 hidden = !menuBar.hideLeftSide.isChecked();
3044 menuBar.hideLeftSide.setChecked(!hidden);
3047 leftSplitter1.setHidden(true);
3049 leftSplitter1.setHidden(false);
3051 Global.saveWindowVisible("leftPanel", hidden);
3054 public void checkForUpdates() {
3055 // Send off thread to check for a new version
3056 versionChecker = new QNetworkAccessManager(this);
3057 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3058 QNetworkRequest request = new QNetworkRequest();
3059 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3060 versionChecker.get(request);
3062 @SuppressWarnings("unused")
3063 private void upgradeFileRead(QNetworkReply reply) {
3064 if (!reply.isReadable())
3067 String winVersion = Global.version;
3068 String osxVersion = Global.version;
3069 String linuxVersion = Global.version;
3070 String linux64Version = Global.version;
3071 String version = Global.version;
3073 // Determine the versions available
3074 QByteArray data = reply.readLine();
3075 while (data != null && !reply.atEnd()) {
3076 String line = data.toString();
3078 if (line.contains(":"))
3079 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3082 if (line.toLowerCase().contains("windows"))
3083 winVersion = lineVersion;
3084 else if (line.toLowerCase().contains("os-x"))
3085 osxVersion = lineVersion;
3086 else if (line.toLowerCase().contains("linux amd64"))
3087 linux64Version = lineVersion;
3088 else if (line.toLowerCase().contains("linux i386"))
3089 linuxVersion = lineVersion;
3090 else if (line.toLowerCase().contains("default"))
3091 version = lineVersion;
3093 // Read the next line
3094 data = reply.readLine();
3097 // Now we need to determine what system we are on.
3098 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3099 version = winVersion;
3100 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3101 version = osxVersion;
3102 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3103 if (System.getProperty("os.arch").contains("amd64") ||
3104 System.getProperty("os.arch").contains("x86_64"))
3105 version = linux64Version;
3107 version = linuxVersion;
3111 for (String validVersion : Global.validVersions) {
3112 if (version.equals(validVersion))
3116 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3118 if (dialog.remindMe())
3119 Global.setCheckVersionUpgrade(true);
3121 Global.setCheckVersionUpgrade(false);
3125 //***************************************************************
3126 //***************************************************************
3127 //** These functions deal with the Toolbar
3128 //***************************************************************
3129 //***************************************************************
3130 @SuppressWarnings("unused")
3131 private void focusSearch() {
3132 searchField.setFocus();
3135 // Text in the search bar has been cleared
3136 private void searchFieldCleared() {
3139 // This is done because we want to force a reload of
3140 // images. Some images we may want to highlight the text.
3141 readOnlyCache.clear();
3142 inkNoteCache.clear();
3144 QWebSettings.setMaximumPagesInCache(0);
3145 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3147 searchField.setEditText("");
3148 saveNoteColumnPositions();
3149 saveNoteIndexWidth();
3150 noteIndexUpdated(true);
3151 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3152 currentNote = listManager.getNoteIndex().get(0);
3153 currentNoteGuid = currentNote.getGuid();
3155 refreshEvernoteNote(true);
3156 if (currentNote != null)
3157 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3159 // text in the search bar changed. We only use this to tell if it was cleared,
3160 // otherwise we trigger off searchFieldChanged.
3161 @SuppressWarnings("unused")
3162 private void searchFieldTextChanged(String text) {
3163 QWebSettings.setMaximumPagesInCache(0);
3164 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3166 if (text.trim().equals("")) {
3167 searchFieldCleared();
3168 if (searchPerformed) {
3170 // This is done because we want to force a reload of
3171 // images. Some images we may want to highlight the text.
3173 readOnlyCache.clear();
3174 inkNoteCache.clear();
3176 listManager.setEnSearch("");
3177 listManager.loadNotesIndex();
3178 refreshEvernoteNote(true);
3179 noteIndexUpdated(false);
3180 refreshEvernoteNote(true);
3182 searchPerformed = false;
3185 // Text in the toolbar has changed
3186 private void searchFieldChanged() {
3187 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3189 readOnlyCache.clear();
3190 inkNoteCache.clear();
3191 saveNoteColumnPositions();
3192 saveNoteIndexWidth();
3193 String text = searchField.currentText();
3194 listManager.setEnSearch(text.trim());
3195 listManager.loadNotesIndex();
3196 noteIndexUpdated(false);
3198 refreshEvernoteNote(true);
3199 searchPerformed = true;
3201 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3204 // Build the window tool bar
3205 private void setupToolBar() {
3206 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3207 toolBar = addToolBar(tr("Tool Bar"));
3208 toolBar.setObjectName("toolBar");
3209 menuBar.setupToolBarVisible();
3210 if (!Global.isWindowVisible("toolBar"))
3211 toolBar.setVisible(false);
3213 toolBar.setVisible(true);
3215 // toolBar.addWidget(menuBar);
3216 // menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3217 // toolBar.addSeparator();
3218 prevButton = toolBar.addAction(tr("Previous"));
3219 QIcon prevIcon = new QIcon(iconPath+"back.png");
3220 prevButton.setIcon(prevIcon);
3221 prevButton.triggered.connect(this, "previousViewedAction()");
3222 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow"));
3224 nextButton = toolBar.addAction(tr("Next"));
3225 QIcon nextIcon = new QIcon(iconPath+"forward.png");
3226 nextButton.setIcon(nextIcon);
3227 nextButton.triggered.connect(this, "nextViewedAction()");
3228 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow"));
3230 upButton = toolBar.addAction(tr("Up"));
3231 QIcon upIcon = new QIcon(iconPath+"up.png");
3232 upButton.setIcon(upIcon);
3233 upButton.triggered.connect(this, "upAction()");
3234 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow"));
3237 downButton = toolBar.addAction(tr("Down"));
3238 QIcon downIcon = new QIcon(iconPath+"down.png");
3239 downButton.setIcon(downIcon);
3240 downButton.triggered.connect(this, "downAction()");
3241 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow"));
3243 synchronizeButton = toolBar.addAction(tr("Synchronize"));
3244 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3245 synchronizeIconAngle = 0;
3246 synchronizeButton.triggered.connect(this, "evernoteSync()");
3247 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize"));
3249 printButton = toolBar.addAction(tr("Print"));
3250 QIcon printIcon = new QIcon(iconPath+"print.png");
3251 printButton.setIcon(printIcon);
3252 printButton.triggered.connect(this, "printNote()");
3253 togglePrintButton(Global.isToolbarButtonVisible("print"));
3255 tagButton = toolBar.addAction(tr("Tag"));
3256 QIcon tagIcon = new QIcon(iconPath+"tag.png");
3257 tagButton.setIcon(tagIcon);
3258 tagButton.triggered.connect(browserWindow, "modifyTags()");
3259 toggleTagButton(Global.isToolbarButtonVisible("tag"));
3261 attributeButton = toolBar.addAction(tr("Attributes"));
3262 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3263 attributeButton.setIcon(attributeIcon);
3264 attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3265 toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
3267 emailButton = toolBar.addAction(tr("Email"));
3268 QIcon emailIcon = new QIcon(iconPath+"email.png");
3269 emailButton.setIcon(emailIcon);
3270 emailButton.triggered.connect(this, "emailNote()");
3271 toggleEmailButton(Global.isToolbarButtonVisible("email"));
3273 deleteButton = toolBar.addAction(tr("Delete"));
3274 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3275 deleteButton.setIcon(deleteIcon);
3276 deleteButton.triggered.connect(this, "deleteNote()");
3277 toggleDeleteButton(Global.isToolbarButtonVisible("delete"));
3279 newButton = toolBar.addAction(tr("New"));
3280 QIcon newIcon = new QIcon(iconPath+"new.png");
3281 newButton.triggered.connect(this, "addNote()");
3282 newButton.setIcon(newIcon);
3283 toggleNewButton(Global.isToolbarButtonVisible("new"));
3285 allNotesButton = toolBar.addAction(tr("All Notes"));
3286 QIcon allIcon = new QIcon(iconPath+"books.png");
3287 allNotesButton.triggered.connect(this, "allNotes()");
3288 allNotesButton.setIcon(allIcon);
3289 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
3291 //toolBar.addSeparator();
3292 //toolBar.addWidget(new QLabel(tr("Quota:")));
3293 //toolBar.addWidget(quotaBar);
3294 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3296 //toolBar.addSeparator();
3298 //toolBar.addWidget(new QLabel(tr("Zoom")));
3299 //toolBar.addWidget(zoomSpinner);
3301 //toolBar.addWidget(new QLabel(" "));
3302 //toolBar.addSeparator();
3303 //toolBar.addWidget(new QLabel(tr(" Search:")));
3304 //toolBar.addWidget(searchField);
3305 QSizePolicy sizePolicy = new QSizePolicy();
3306 sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3307 QLabel spacer = new QLabel("");
3308 spacer.setSizePolicy(sizePolicy);
3309 toolBar.addWidget(spacer);
3310 //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3312 //searchClearButton = toolBar.addAction("Search Clear");
3313 //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3314 //searchClearButton.setIcon(searchClearIcon);
3315 //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3316 //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3318 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3320 // Update the sychronize button picture
3322 public QMenu createPopupMenu() {
3323 QMenu contextMenu = super.createPopupMenu();
3325 contextMenu.addSeparator();
3326 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3327 contextMenu.addAction(prevAction);
3328 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3330 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3331 contextMenu.addAction(nextAction);
3332 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3334 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3335 contextMenu.addAction(upAction);
3336 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3338 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3339 contextMenu.addAction(downAction);
3340 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3342 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3343 contextMenu.addAction(synchronizeAction);
3344 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3346 QAction printAction = addContextAction("print", tr("Print"));
3347 contextMenu.addAction(printAction);
3348 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3350 QAction tagAction = addContextAction("tag", tr("Tag"));
3351 contextMenu.addAction(tagAction);
3352 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3354 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3355 contextMenu.addAction(attributeAction);
3356 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3358 QAction emailAction = addContextAction("email", tr("Email"));
3359 contextMenu.addAction(emailAction);
3360 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3362 QAction deleteAction = addContextAction("delete", tr("Delete"));
3363 contextMenu.addAction(deleteAction);
3364 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3366 QAction newAction = addContextAction("new", tr("Add"));
3367 contextMenu.addAction(newAction);
3368 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3370 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3371 contextMenu.addAction(allNotesAction);
3372 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3374 QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3375 contextMenu.addAction(searchClearAction);
3376 searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3381 private QAction addContextAction(String config, String name) {
3382 QAction newAction = new QAction(this);
3383 newAction.setText(name);
3384 newAction.setCheckable(true);
3385 newAction.setChecked(Global.isToolbarButtonVisible(config));
3388 private void togglePrevArrowButton(Boolean toggle) {
3389 prevButton.setVisible(toggle);
3390 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3392 private void toggleNextArrowButton(Boolean toggle) {
3393 nextButton.setVisible(toggle);
3394 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3396 private void toggleUpArrowButton(Boolean toggle) {
3397 upButton.setVisible(toggle);
3398 Global.saveToolbarButtonsVisible("upArrow", toggle);
3400 private void toggleDownArrowButton(Boolean toggle) {
3401 downButton.setVisible(toggle);
3402 Global.saveToolbarButtonsVisible("downArrow", toggle);
3404 private void toggleSynchronizeButton(Boolean toggle) {
3405 synchronizeButton.setVisible(toggle);
3406 Global.saveToolbarButtonsVisible("synchronize", toggle);
3408 private void togglePrintButton(Boolean toggle) {
3409 printButton.setVisible(toggle);
3410 Global.saveToolbarButtonsVisible("print", toggle);
3412 private void toggleTagButton(Boolean toggle) {
3413 tagButton.setVisible(toggle);
3414 Global.saveToolbarButtonsVisible("tag", toggle);
3416 private void toggleAttributeButton(Boolean toggle) {
3417 attributeButton.setVisible(toggle);
3418 Global.saveToolbarButtonsVisible("attribute", toggle);
3420 private void toggleEmailButton(Boolean toggle) {
3421 emailButton.setVisible(toggle);
3422 Global.saveToolbarButtonsVisible("email", toggle);
3424 private void toggleDeleteButton(Boolean toggle) {
3425 deleteButton.setVisible(toggle);
3426 Global.saveToolbarButtonsVisible("delete", toggle);
3428 private void toggleNewButton(Boolean toggle) {
3429 newButton.setVisible(toggle);
3430 Global.saveToolbarButtonsVisible("new", toggle);
3432 private void toggleAllNotesButton(Boolean toggle) {
3433 allNotesButton.setVisible(toggle);
3434 Global.saveToolbarButtonsVisible("allNotes", toggle);
3436 @SuppressWarnings("unused")
3437 private void toggleSearchClearButton(Boolean toggle) {
3438 searchClearButton.setVisible(toggle);
3439 Global.saveToolbarButtonsVisible("searchClear", toggle);
3446 @SuppressWarnings("unused")
3447 private void updateSyncButton() {
3449 if (syncIcons == null) {
3450 syncIcons = new ArrayList<QPixmap>();
3452 synchronizeIconAngle = 0;
3453 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3455 for (int i=0; i<=360; i++) {
3456 QPixmap rotatedPix = new QPixmap(pix.size());
3457 QPainter p = new QPainter(rotatedPix);
3458 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3459 QSize size = pix.size();
3460 p.translate(size.width()/2, size.height()/2);
3463 p.setBackgroundMode(BGMode.OpaqueMode);
3464 p.translate(-size.width()/2, -size.height()/2);
3465 p.drawPixmap(0,0, pix);
3467 syncIcons.add(rotatedPix);
3471 synchronizeIconAngle++;
3472 if (synchronizeIconAngle > 359)
3473 synchronizeIconAngle=0;
3474 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3477 // Synchronize with Evernote
3479 private void evernoteSync() {
3480 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3481 if (!Global.isConnected)
3483 if (Global.isConnected)
3484 synchronizeAnimationTimer.start(5);
3485 // synchronizeAnimationTimer.start(200);
3487 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3489 private void updateQuotaBar() {
3490 long limit = Global.getUploadLimit();
3491 long amount = Global.getUploadAmount();
3492 if (amount>0 && limit>0) {
3493 int percent =(int)(amount*100/limit);
3494 quotaBar.setValue(percent);
3496 quotaBar.setValue(0);
3499 @SuppressWarnings("unused")
3500 private void zoomChanged() {
3501 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3504 //****************************************************************
3505 //****************************************************************
3506 //* System Tray functions
3507 //****************************************************************
3508 //****************************************************************
3509 private void trayToggleVisible() {
3514 if (windowMaximized)
3521 @SuppressWarnings("unused")
3522 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3523 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3524 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3525 trayToggleVisible();
3530 //***************************************************************
3531 //***************************************************************
3532 //** These functions deal with the trash tree
3533 //***************************************************************
3534 //***************************************************************
3535 // Setup the tree containing the trash.
3536 @SuppressWarnings("unused")
3537 private void trashTreeSelection() {
3538 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3540 clearNotebookFilter();
3542 clearAttributeFilter();
3543 clearSavedSearchFilter();
3545 String tempGuid = currentNoteGuid;
3547 // currentNoteGuid = "";
3548 currentNote = new Note();
3549 selectedNoteGUIDs.clear();
3550 listManager.getSelectedNotebooks().clear();
3551 listManager.getSelectedTags().clear();
3552 listManager.setSelectedSavedSearch("");
3553 browserWindow.clear();
3555 // toggle the add buttons
3556 newButton.setEnabled(!newButton.isEnabled());
3557 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3558 menuBar.noteAdd.setVisible(true);
3560 List<QTreeWidgetItem> selections = trashTree.selectedItems();
3561 if (selections.size() == 0) {
3562 currentNoteGuid = trashNoteGuid;
3563 trashNoteGuid = tempGuid;
3564 Global.showDeleted = false;
3565 menuBar.noteRestoreAction.setEnabled(false);
3566 menuBar.noteRestoreAction.setVisible(false);
3567 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3568 rensoNoteListDock.setEnabled(true);
3571 trashNoteGuid = tempGuid;
3572 currentNoteGuid = trashNoteGuid;
3573 menuBar.noteRestoreAction.setEnabled(true);
3574 menuBar.noteRestoreAction.setVisible(true);
3575 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
3576 rensoNoteListDock.setEnabled(false);
3578 Global.showDeleted = true;
3580 listManager.loadNotesIndex();
3581 noteIndexUpdated(false);
3582 //// browserWindow.setEnabled(newButton.isEnabled());
3583 browserWindow.setReadOnly(!newButton.isEnabled());
3584 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3586 // Empty the trash file
3587 @SuppressWarnings("unused")
3588 private void emptyTrash() {
3589 // browserWindow.clear();
3590 logger.log(logger.EXTREME, "Emptying Trash");
3591 listManager.emptyTrash();
3592 logger.log(logger.EXTREME, "Resetting view after trash empty");
3593 if (trashTree.selectedItems().size() > 0) {
3594 listManager.getSelectedNotebooks().clear();
3595 listManager.getSelectedTags().clear();
3596 listManager.setSelectedSavedSearch("");
3597 newButton.setEnabled(!newButton.isEnabled());
3598 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3599 menuBar.noteAdd.setVisible(true);
3600 browserWindow.clear();
3603 clearNotebookFilter();
3604 clearSavedSearchFilter();
3605 clearAttributeFilter();
3607 Global.showDeleted = false;
3608 menuBar.noteRestoreAction.setEnabled(false);
3609 menuBar.noteRestoreAction.setVisible(false);
3611 listManager.loadNotesIndex();
3612 noteIndexUpdated(false);
3614 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3615 if (!rensoNoteListDock.isEnabled()) {
3616 rensoNoteListDock.setEnabled(true);
3620 // Show/Hide trash window
3621 @SuppressWarnings("unused")
3622 private void toggleTrashWindow() {
3623 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3624 if (trashTree.isVisible())
3628 menuBar.hideTrash.setChecked(trashTree.isVisible());
3630 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3631 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3633 private void clearTrashFilter() {
3634 Global.showDeleted = false;
3635 newButton.setEnabled(true);
3636 menuBar.noteAdd.setEnabled(true);
3637 menuBar.noteAdd.setVisible(true);
3638 trashTree.blockSignals(true);
3639 trashTree.clearSelection();
3640 trashTree.blockSignals(false);
3645 //***************************************************************
3646 //***************************************************************
3647 //** These functions deal with connection settings
3648 //***************************************************************
3649 //***************************************************************
3650 // SyncRunner had a problem and things are disconnected
3651 @SuppressWarnings("unused")
3652 private void remoteErrorDisconnect() {
3653 menuBar.connectAction.setText(tr("Connect"));
3654 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3655 menuBar.synchronizeAction.setEnabled(false);
3656 Global.isConnected = false;
3657 synchronizeAnimationTimer.stop();
3660 // Do a manual connect/disconnect
3661 private void remoteConnect() {
3663 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3665 // If we are already connected, we just disconnect
3666 if (Global.isConnected) {
3667 Global.isConnected = false;
3668 syncRunner.enDisconnect();
3669 setupConnectMenuOptions();
3674 OAuthTokenizer tokenizer = new OAuthTokenizer();
3675 AESEncrypter aes = new AESEncrypter();
3677 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3678 } catch (FileNotFoundException e) {
3679 // File not found, so we'll just get empty strings anyway.
3683 if (Global.getProxyValue("url").equals("")) {
3684 System.setProperty("http.proxyHost","") ;
3685 System.setProperty("http.proxyPort", "") ;
3686 System.setProperty("https.proxyHost","") ;
3687 System.setProperty("https.proxyPort", "") ;
3690 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3691 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3692 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3693 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3695 if (Global.getProxyValue("userid").equals("")) {
3696 Authenticator.setDefault(new Authenticator() {
3698 protected PasswordAuthentication getPasswordAuthentication() {
3700 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3706 syncRunner.userStoreUrl = Global.userStoreUrl;
3707 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3708 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3712 String authString = aes.getString();
3713 if (!authString.equals("")) {
3714 tokenizer.tokenize(authString);
3715 syncRunner.authToken = tokenizer.oauth_token;
3716 syncRunner.enConnect();
3719 Global.isConnected = syncRunner.isConnected;
3721 if (!Global.isConnected) {
3722 OAuthWindow window = new OAuthWindow(logger);
3724 setMessage(window.errorMessage);
3729 setMessage(window.errorMessage);
3732 tokenizer.tokenize(window.response);
3733 if (tokenizer.oauth_token.equals("")) {
3734 setMessage(tr("Invalid authorization token received."));
3737 aes.setString(window.response);
3739 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3740 } catch (FileNotFoundException e) {
3741 // TODO Auto-generated catch block
3742 e.printStackTrace();
3744 syncRunner.authToken = tokenizer.oauth_token;
3745 syncRunner.enConnect();
3746 Global.isConnected = syncRunner.isConnected;
3748 // Global.username = syncRunner.username;
3750 if (!Global.isConnected)
3753 setupConnectMenuOptions();
3754 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3758 private void setupConnectMenuOptions() {
3759 logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3760 if (!Global.isConnected) {
3761 menuBar.connectAction.setText(tr("Connect"));
3762 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3763 menuBar.synchronizeAction.setEnabled(false);
3765 menuBar.connectAction.setText(tr("Disconnect"));
3766 menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3767 menuBar.synchronizeAction.setEnabled(true);
3769 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3774 //***************************************************************
3775 //***************************************************************
3776 //** These functions deal with the GUI Attribute tree
3777 //***************************************************************
3778 //***************************************************************
3779 @SuppressWarnings("unused")
3780 private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3782 // clearTagFilter();
3783 // clearNotebookFilter();
3785 // clearSavedSearchFilter();
3787 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3788 if (!rensoNoteListDock.isEnabled()) {
3789 rensoNoteListDock.setEnabled(true);
3792 if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3793 if (item.childCount() > 0) {
3794 item.setSelected(false);
3796 Global.createdBeforeFilter.reset();
3797 Global.createdSinceFilter.reset();
3798 Global.changedBeforeFilter.reset();
3799 Global.changedSinceFilter.reset();
3800 Global.containsFilter.reset();
3801 attributeTreeSelected = item;
3802 DateAttributeFilterTable f = null;
3803 f = findDateAttributeFilterTable(item.parent());
3805 f.select(item.parent().indexOfChild(item));
3807 Global.containsFilter.select(item.parent().indexOfChild(item));
3810 listManager.loadNotesIndex();
3811 noteIndexUpdated(false);
3814 attributeTreeSelected = null;
3815 item.setSelected(false);
3816 Global.createdBeforeFilter.reset();
3817 Global.createdSinceFilter.reset();
3818 Global.changedBeforeFilter.reset();
3819 Global.changedSinceFilter.reset();
3820 Global.containsFilter.reset();
3821 listManager.loadNotesIndex();
3822 noteIndexUpdated(false);
3824 // This determines what attribute filter we need, depending upon the selection
3825 private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3826 if (w.parent() != null && w.childCount() > 0) {
3827 QTreeWidgetItem parent = w.parent();
3828 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3829 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3830 return Global.createdSinceFilter;
3831 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3832 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3833 return Global.createdBeforeFilter;
3834 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3835 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3836 return Global.changedSinceFilter;
3837 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3838 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3839 return Global.changedBeforeFilter;
3844 // Show/Hide attribute search window
3845 @SuppressWarnings("unused")
3846 private void toggleAttributesWindow() {
3847 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3848 if (attributeTree.isVisible())
3849 attributeTree.hide();
3851 attributeTree.show();
3852 menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3854 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3855 logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3857 private void clearAttributeFilter() {
3858 Global.createdBeforeFilter.reset();
3859 Global.createdSinceFilter.reset();
3860 Global.changedBeforeFilter.reset();
3861 Global.changedSinceFilter.reset();
3862 Global.containsFilter.reset();
3863 attributeTreeSelected = null;
3864 attributeTree.blockSignals(true);
3865 attributeTree.clearSelection();
3866 attributeTree.blockSignals(false);
3870 //***************************************************************
3871 //***************************************************************
3872 //** These functions deal with the GUI Note index table
3873 //***************************************************************
3874 //***************************************************************
3875 // Initialize the note list table
3876 private void initializeNoteTable() {
3877 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3878 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3879 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3880 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3882 // Show/Hide trash window
3883 @SuppressWarnings("unused")
3884 private void toggleNoteListWindow() {
3885 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3886 if (noteTableView.isVisible())
3887 noteTableView.hide();
3889 noteTableView.show();
3890 menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3892 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3893 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3895 // Handle the event that a user selects a note from the table
3896 @SuppressWarnings("unused")
3897 private void noteTableSelection() {
3898 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3904 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3905 // 選択されたノートのguidをselectedNoteGUIDsにセット
3906 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3907 if(selections.size() > 0){
3908 selectedNoteGUIDs.clear();
3909 for(int i = 0; i < selections.size(); i++){
3910 int row = selections.get(i).row();
3911 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3912 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3913 selectedNoteGUIDs.add((String) ix.values().toArray()[0]);
3919 // If we have more than one selection, then set the merge note action to true.
3920 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3921 if (selections.size() > 1)
3922 menuBar.noteMergeAction.setEnabled(true);
3924 menuBar.noteMergeAction.setEnabled(false);
3926 // If the ctrl key is pressed, then they are selecting multiple
3927 // entries and we don't want to change the currently viewed note.
3929 // Shiftキーを押しながらの場合の処理も追加
3930 if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) ||
3931 QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) &&
3932 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3933 selectedNoteGUIDs.clear();
3934 for (int i=0; i<selections.size(); i++) {
3935 int row = selections.get(i).row();
3936 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3937 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3938 selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3943 // ICHANGED たぶんこれは不要
3945 /*if (historyGuids.size() == 0) {
3946 historyGuids.add(currentNoteGuid);
3947 historyPosition = 1;
3950 noteTableView.showColumn(Global.noteTableGuidPosition);
3952 if (!Global.isColumnVisible("guid"))
3953 noteTableView.hideColumn(Global.noteTableGuidPosition);
3955 if (selections.size() > 0) {
3957 menuBar.noteDuplicateAction.setEnabled(true);
3958 menuBar.noteOnlineHistoryAction.setEnabled(true);
3959 menuBar.noteMergeAction.setEnabled(true);
3960 selectedNoteGUIDs.clear();
3961 if (selections.size() != 1 || Global.showDeleted) {
3962 menuBar.noteDuplicateAction.setEnabled(false);
3964 if (selections.size() != 1 || !Global.isConnected) {
3965 menuBar.noteOnlineHistoryAction.setEnabled(false);
3967 if (selections.size() == 1) {
3968 menuBar.noteMergeAction.setEnabled(false);
3970 for (int i=0; i<selections.size(); i++) {
3971 int row = selections.get(i).row();
3973 upButton.setEnabled(false);
3975 upButton.setEnabled(true);
3976 if (row < listManager.getNoteTableModel().rowCount()-1)
3977 downButton.setEnabled(true);
3979 downButton.setEnabled(false);
3980 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3981 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3983 currentNoteGuid = (String)ix.values().toArray()[0];
3984 selectedNoteGUIDs.add(currentNoteGuid);
3988 nextButton.setEnabled(true);
3989 prevButton.setEnabled(true);
3992 int currentIndex = tabBrowser.currentIndex();
3993 ArrayList<String> histGuids = historyGuids.get(currentIndex);
3994 int histPosition = historyPosition.get(currentIndex);
3995 boolean fromHist = fromHistory.get(currentIndex);
3999 int endPosition = histGuids.size() - 1;
4001 for (int j = histPosition; j <= endPosition; j++) {
4002 histGuids.remove(histGuids.size() - 1);
4004 histGuids.add(currentNoteGuid);
4005 historyPosition.put(currentIndex, histGuids.size());
4006 histPosition = histGuids.size();
4008 if (histPosition <= 1){
4009 prevButton.setEnabled(false);
4011 if (histPosition == histGuids.size())
4012 nextButton.setEnabled(false);
4013 fromHistory.put(currentIndex, false);
4016 scrollToGuid(currentNoteGuid);
4017 refreshEvernoteNote(true);
4020 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4021 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4028 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
4031 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4036 // 複数ノートの同時閲覧履歴をデータベースに保存
4037 private void addBrowseHistory() {
4038 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4039 if (tabWindows.size() >= 2) {
4040 Iterator<Integer> it = tabWindows.keySet().iterator();
4041 while (it.hasNext()) {
4042 int tabIndex = it.next();
4043 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4044 // guid1=guid2のデータは登録しない
4045 if (!currentNoteGuid.equals(nextGuid)) {
4046 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4050 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4051 if (externalWindows.size() >= 1) {
4052 Iterator<String> it = externalWindows.keySet().iterator();
4053 while (it.hasNext()) {
4054 String nextGuid = it.next();
4055 // guid1=guid2のデータは登録しない
4056 if (!currentNoteGuid.equals(nextGuid)) {
4057 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4063 // Trigger a refresh when the note db has been updated
4064 private void noteIndexUpdated(boolean reload) {
4065 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4067 refreshEvernoteNoteList();
4068 logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4069 noteTableView.load(reload);
4070 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4072 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4073 pos = noteTableView.proxyModel.rowCount();
4076 if (noteTableView.proxyModel.rowCount() == 0)
4079 QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4081 currentNoteGuid = (String)i.data();
4085 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4087 scrollToGuid(currentNoteGuid);
4088 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4090 // Called when the list of notes is updated
4091 private void refreshEvernoteNoteList() {
4092 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4093 browserWindow.setDisabled(false);
4094 if (selectedNoteGUIDs == null)
4095 selectedNoteGUIDs = new ArrayList<String>();
4096 selectedNoteGUIDs.clear(); // clear out old entries
4098 String saveCurrentNoteGuid = new String();
4099 String tempNoteGuid = new String();
4102 int currentIndex = tabBrowser.currentIndex();
4103 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4105 historyPosition.put(currentIndex, 0);
4107 prevButton.setEnabled(false);
4108 nextButton.setEnabled(false);
4110 if (currentNoteGuid == null)
4111 currentNoteGuid = new String();
4113 //determine current note guid
4114 for (Note note : listManager.getNoteIndex()) {
4115 tempNoteGuid = note.getGuid();
4116 if (currentNoteGuid.equals(tempNoteGuid)) {
4117 saveCurrentNoteGuid = tempNoteGuid;
4121 if (listManager.getNoteIndex().size() == 0) {
4122 currentNoteGuid = "";
4124 browserWindow.clear();
4125 browserWindow.setDisabled(true);
4129 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4130 currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4131 saveCurrentNoteGuid = currentNoteGuid;
4132 refreshEvernoteNote(true);
4135 if (!saveCurrentNoteGuid.equals("")) {
4136 refreshEvernoteNote(false);
4138 currentNoteGuid = "";
4140 reloadTagTree(false);
4142 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4146 // Called when the previous arrow button is clicked
4147 @SuppressWarnings("unused")
4148 private void previousViewedAction() {
4149 int currentIndex = tabBrowser.currentIndex();
4150 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4151 int histPosition = historyPosition.get(currentIndex);
4152 boolean fromHist = fromHistory.get(currentIndex);
4153 if (!prevButton.isEnabled())
4155 if (histPosition == 0)
4158 historyPosition.put(currentIndex, histPosition);
4159 if (histPosition <= 0)
4161 String historyGuid = histGuids.get(histPosition - 1);
4162 fromHistory.put(currentIndex, true);
4164 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4165 QModelIndex modelIndex = noteTableView.model().index(i,
4166 Global.noteTableGuidPosition);
4167 if (modelIndex != null) {
4168 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4170 String tableGuid = (String) ix.values().toArray()[0];
4171 if (tableGuid.equals(historyGuid)) {
4172 noteTableView.selectRow(i);
4179 @SuppressWarnings("unused")
4180 private void nextViewedAction() {
4181 if (!nextButton.isEnabled())
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 String historyGuid = histGuids.get(histPosition);
4190 historyPosition.put(currentIndex, histPosition);
4191 fromHistory.put(currentIndex, true);
4193 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4194 QModelIndex modelIndex = noteTableView.model().index(i,
4195 Global.noteTableGuidPosition);
4196 if (modelIndex != null) {
4197 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4199 String tableGuid = (String) ix.values().toArray()[0];
4200 if (tableGuid.equals(historyGuid)) {
4201 noteTableView.selectRow(i);
4207 // Called when the up arrow is clicked
4208 @SuppressWarnings("unused")
4209 private void upAction() {
4210 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4211 int row = selections.get(0).row();
4213 noteTableView.selectRow(row-1);
4216 // Called when the down arrow is clicked
4217 @SuppressWarnings("unused")
4218 private void downAction() {
4219 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4220 int row = selections.get(0).row();
4221 int max = listManager.getNoteTableModel().rowCount();
4223 noteTableView.selectRow(row+1);
4226 // Update a tag string for a specific note in the list
4227 @SuppressWarnings("unused")
4228 private void updateListTags(String guid, List<String> tags) {
4229 logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4230 StringBuffer tagBuffer = new StringBuffer();
4231 for (int i=0; i<tags.size(); i++) {
4232 tagBuffer.append(tags.get(i));
4233 if (i<tags.size()-1)
4234 tagBuffer.append(", ");
4237 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4238 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4239 if (modelIndex != null) {
4240 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4241 String tableGuid = (String)ix.values().toArray()[0];
4242 if (tableGuid.equals(guid)) {
4243 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4244 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4245 noteTableView.proxyModel.invalidate();
4250 logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4252 // Update a title for a specific note in the list
4253 @SuppressWarnings("unused")
4254 private void updateListAuthor(String guid, String author) {
4255 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4257 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4258 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4259 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4260 if (modelIndex != null) {
4261 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4262 String tableGuid = (String)ix.values().toArray()[0];
4263 if (tableGuid.equals(guid)) {
4264 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4265 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4266 noteTableView.proxyModel.invalidate();
4272 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4274 private void updateListNoteNotebook(String guid, String notebook) {
4275 logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4276 listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4277 logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4279 // Update a title for a specific note in the list
4280 @SuppressWarnings("unused")
4281 private void updateListSourceUrl(String guid, String url) {
4282 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4284 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4285 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4286 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4287 if (modelIndex != null) {
4288 // SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4289 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4290 String tableGuid = (String)ix.values().toArray()[0];
4291 if (tableGuid.equals(guid)) {
4292 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4293 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4294 noteTableView.proxyModel.invalidate();
4299 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4301 @SuppressWarnings("unused")
4302 private void updateListGuid(String oldGuid, String newGuid) {
4303 logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4305 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4306 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4307 if (modelIndex != null) {
4308 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4309 String tableGuid = (String)ix.values().toArray()[0];
4310 if (tableGuid.equals(oldGuid)) {
4311 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4312 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4317 logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4319 private void updateListTagName(String guid) {
4320 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4322 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4323 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4324 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4326 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4327 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4328 if (modelIndex != null) {
4329 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4330 String noteGuid = (String)ix.values().toArray()[0];
4331 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4332 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4333 i=listManager.getNoteTableModel().rowCount();
4339 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4341 private void removeListTagName(String guid) {
4342 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4344 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4345 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4346 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4347 if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4348 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4351 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4352 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4353 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4354 if (modelIndex != null) {
4355 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4356 String noteGuid = (String)ix.values().toArray()[0];
4357 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4358 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4359 i=listManager.getNoteTableModel().rowCount();
4365 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4367 private void updateListNotebookName(String oldName, String newName) {
4368 logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4370 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4371 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition);
4372 if (modelIndex != null) {
4373 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4374 String tableName = (String)ix.values().toArray()[0];
4375 if (tableName.equalsIgnoreCase(oldName)) {
4376 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4380 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4382 @SuppressWarnings("unused")
4383 private void updateListDateCreated(String guid, QDateTime date) {
4384 logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
4386 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4387 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4388 if (modelIndex != null) {
4389 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4390 String tableGuid = (String)ix.values().toArray()[0];
4391 if (tableGuid.equals(guid)) {
4392 listManager.getNoteTableModel().setData(i, Global.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4393 noteTableView.proxyModel.invalidate();
4398 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4400 @SuppressWarnings("unused")
4401 private void updateListDateSubject(String guid, QDateTime date) {
4402 logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
4404 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4405 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4406 if (modelIndex != null) {
4407 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4408 String tableGuid = (String)ix.values().toArray()[0];
4409 if (tableGuid.equals(guid)) {
4410 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4411 listManager.getNoteTableModel().setData(i, Global.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4412 noteTableView.proxyModel.invalidate();
4417 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4419 private void updateListDateChanged(String guid, QDateTime date) {
4420 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4422 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4423 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4424 if (modelIndex != null) {
4425 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4426 String tableGuid = (String)ix.values().toArray()[0];
4427 if (tableGuid.equals(guid)) {
4428 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4429 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4434 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4436 private void updateListDateChanged() {
4437 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4438 QDateTime date = new QDateTime(QDateTime.currentDateTime());
4439 updateListDateChanged(currentNoteGuid, date);
4440 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4443 private void scrollToCurrentGuid() {
4444 //scrollToGuid(currentNoteGuid);
4445 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4446 if (selections.size() == 0)
4448 QModelIndex index = selections.get(0);
4449 int row = selections.get(0).row();
4450 String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4453 // Scroll to the current GUID in tthe list.
4454 // Scroll to a particular index item
4455 private void scrollToGuid(String guid) {
4456 if (currentNote == null || guid == null)
4458 if (currentNote.isActive() && Global.showDeleted) {
4459 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4460 if (!listManager.getNoteIndex().get(i).isActive()) {
4461 currentNote = listManager.getNoteIndex().get(i);
4462 currentNoteGuid = currentNote.getGuid();
4463 i = listManager.getNoteIndex().size();
4467 if (!currentNote.isActive() && !Global.showDeleted) {
4468 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4469 if (listManager.getNoteIndex().get(i).isActive()) {
4470 currentNote = listManager.getNoteIndex().get(i);
4471 currentNoteGuid = currentNote.getGuid();
4472 i = listManager.getNoteIndex().size();
4477 for (int i=0; i<noteTableView.model().rowCount(); i++) {
4478 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4479 if (currentNoteGuid.equals(index.data())) {
4480 // noteTableView.selectionModel().blockSignals(true);
4481 noteTableView.selectRow(i);
4482 // noteTableView.selectionModel().blockSignals(false);
4483 noteTableView.scrollTo(index, ScrollHint.EnsureVisible); // This should work, but it doesn't
4484 i=listManager.getNoteTableModel().rowCount();
4487 noteTableView.repaint();
4489 // Show/Hide columns
4490 private void showColumns() {
4491 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4492 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4493 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4494 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4495 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4496 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4497 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4498 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4499 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4500 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4501 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));
4502 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned"));
4504 // Title color has changed
4505 @SuppressWarnings("unused")
4506 private void titleColorChanged(Integer color) {
4507 logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4510 QColor backgroundColor = new QColor();
4511 QColor foregroundColor = new QColor(QColor.black);
4512 backgroundColor.setRgb(color);
4514 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4515 foregroundColor.setRgb(QColor.white.rgb());
4517 if (selectedNoteGUIDs.size() == 0)
4518 selectedNoteGUIDs.add(currentNoteGuid);
4520 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4521 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4522 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4523 if (modelIndex != null) {
4524 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4525 String tableGuid = (String)ix.values().toArray()[0];
4526 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4527 for (int k=0; k<Global.noteTableColumnCount; k++) {
4528 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4529 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4530 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4532 i=listManager.getNoteTableModel().rowCount();
4537 logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4539 // A note has been pinned or unpinned
4540 @SuppressWarnings("unused")
4541 private void notePinned() {
4542 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4545 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4546 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4547 boolean pinned = !meta.isPinned();
4548 meta.setPinned(pinned); // Toggle the pinned/unpinned
4550 // Update the list & table
4551 listManager.updateNoteMetadata(meta);
4552 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4554 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4556 // Wide list was chosen
4557 public void narrowListView() {
4558 saveNoteColumnPositions();
4559 saveNoteIndexWidth();
4561 int sortCol = noteTableView.proxyModel.sortColumn();
4562 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4563 Global.setSortColumn(sortCol);
4564 Global.setSortOrder(sortOrder);
4566 Global.setListView(Global.View_List_Narrow);
4568 menuBar.wideListView.blockSignals(true);
4569 menuBar.narrowListView.blockSignals(true);
4571 menuBar.wideListView.setChecked(false);
4572 menuBar.narrowListView.setChecked(true);
4574 menuBar.wideListView.blockSignals(false);
4575 menuBar.narrowListView.blockSignals(false);
4577 mainLeftRightSplitter.addWidget(noteTableView);
4578 // ICHANGED browserWindow → tabBrowser
4579 mainLeftRightSplitter.addWidget(tabBrowser);
4581 restoreWindowState(false);
4582 noteTableView.repositionColumns();
4583 noteTableView.resizeColumnWidths();
4584 noteTableView.resizeRowHeights();
4586 sortCol = Global.getSortColumn();
4587 sortOrder = Global.getSortOrder();
4588 noteTableView.proxyModel.blocked = true;
4589 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4590 noteTableView.proxyModel.blocked = false;
4594 noteTableView.load(false);
4595 refreshEvernoteNote(true);
4596 scrollToCurrentGuid();
4598 public void wideListView() {
4599 int sortCol = noteTableView.proxyModel.sortColumn();
4600 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4601 Global.setSortColumn(sortCol);
4602 Global.setSortOrder(sortOrder);
4605 saveNoteColumnPositions();
4606 saveNoteIndexWidth();
4607 Global.setListView(Global.View_List_Wide);
4609 menuBar.wideListView.blockSignals(true);
4610 menuBar.narrowListView.blockSignals(true);
4612 menuBar.wideListView.setChecked(true);
4613 menuBar.narrowListView.setChecked(false);
4615 menuBar.wideListView.blockSignals(false);
4616 menuBar.narrowListView.blockSignals(false);
4617 browserIndexSplitter.setVisible(true);
4618 browserIndexSplitter.addWidget(noteTableView);
4619 // ICHANGED browserWindow → tabBrowser
4620 browserIndexSplitter.addWidget(tabBrowser);
4622 restoreWindowState(false);
4623 noteTableView.repositionColumns();
4624 noteTableView.resizeColumnWidths();
4625 noteTableView.resizeRowHeights();
4627 sortCol = Global.getSortColumn();
4628 sortOrder = Global.getSortOrder();
4629 noteTableView.proxyModel.blocked = true;
4630 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4631 noteTableView.proxyModel.blocked = false;
4634 noteTableView.load(false);
4635 scrollToCurrentGuid();
4637 // Sort order for the notebook has changed
4638 public void tableSortOrderChanged(Integer column, Integer order) {
4640 // Find what notebook (if any) is selected. We ignore stacks & the "All Notebooks".
4641 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4642 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4643 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4645 notebook = currentSelectedNotebook.text(2);
4646 conn.getNotebookTable().setSortOrder(notebook, column, order);
4650 //***************************************************************
4651 @SuppressWarnings("unused")
4652 private void evernoteLinkClick(String syncGuid, String locGuid) {
4654 if (conn.getNoteTable().guidExists(syncGuid)) {
4657 // If we didn't find it via the synchronized guid, look under the local guid
4658 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was
4659 // later synchronized (that causes the guid to change so we need to find the new one).
4660 if (conn.getNoteTable().guidExists(locGuid))
4663 guid = conn.getNoteTable().findAlternateGuid(locGuid);
4666 openExternalEditor(guid);
4670 //If we've gotten this far, we can't find the note
4671 QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4672 " seem to find that note."));
4674 //***************************************************************
4675 //***************************************************************
4676 //** External editor window functions
4677 //***************************************************************
4678 //***************************************************************
4679 private void listDoubleClick() {
4681 openExternalEditor(currentNoteGuid);
4683 private void openExternalEditor(String guid) {
4685 if (externalWindows.containsKey(guid)) {
4686 externalWindows.get(guid).raise();
4690 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4691 // We have a new external editor to create
4692 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4694 ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4696 newBrowser.setWindowIcon(appIcon);
4697 externalWindows.put(guid, newBrowser);
4698 showEditorButtons(newBrowser.getBrowserWindow());
4699 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4700 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4701 newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4702 //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4703 newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4704 newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4705 newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4706 newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4708 browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4709 browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4710 browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4714 @SuppressWarnings({ "rawtypes", "unused" })
4715 private void externalWindowTagsEdited(String guid, List values) {
4716 StringBuffer line = new StringBuffer(100);
4717 for (int i=0; i<values.size(); i++) {
4719 line.append(Global.tagDelimeter+" ");
4720 line.append(values.get(i));
4722 if (guid.equals(currentNoteGuid)) {
4723 browserWindow.setTag(line.toString());
4726 @SuppressWarnings("unused")
4727 private void externalWindowClosing(String guid) {
4728 externalWindows.remove(guid);
4731 // ***************************************************************
4732 // ***************************************************************
4734 // ***************************************************************
4735 // ***************************************************************
4736 @SuppressWarnings("unused")
4737 private void openNewTab() {
4740 // selectedNoteGUIDsをディープコピー
4741 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4743 for (int i=0; i < copySelected.size() ; i++) {
4744 openTabEditor(copySelected.get(i));
4748 // ICHANGED 連想ノートリストから新しいタブで開く
4749 @SuppressWarnings("unused")
4750 private void openNewTabFromRNL(){
4751 if(rensoNotePressedItemGuid != null){
4752 String prevCurrentNoteGuid = new String(currentNoteGuid);
4755 openTabEditor(rensoNotePressedItemGuid);
4757 // 連想ノートリストアイテムクリック操作を記録
4758 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4763 private void openTabEditor(String guid) {
4765 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4767 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4768 showEditorButtons(newBrowser.getBrowserWindow());
4770 String noteTitle = note.getTitle();
4771 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4772 tabWindows.put(index, newBrowser);
4773 noteDirty.put(index, false);
4775 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4776 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4777 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4779 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4781 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4783 // ExtendedInformationを必要があれば表示する
4784 toggleNoteInformation();
4785 // Sourceを必要があれば表示する
4787 // EditorButtonsBarを必要があれば表示する
4788 toggleEditorButtonBar();
4791 ArrayList<String> histGuids = new ArrayList<String>();
4792 historyGuids.put(index, histGuids);
4793 historyPosition.put(index, 0);
4794 fromHistory.put(index, false);
4797 histGuids.add(guid);
4798 historyPosition.put(index, histGuids.size());
4800 tabBrowser.setCurrentIndex(index);
4802 if (guid != null && !guid.equals("")) {
4803 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4809 // ICHANGED タブが閉じられた
4810 private void tabWindowClosing(int index) {
4812 if (tabBrowser.count() <= 1) {
4816 TabBrowse t = (TabBrowse) tabBrowser.widget(index);
4817 String guid = t.getBrowserWindow().getNote().getGuid();
4818 String content = t.getBrowserWindow().getContent();
4819 BrowserWindow browser = t.getBrowserWindow();
4821 if (t.getNoteDirty()) {
4822 saveNoteTabBrowser(guid, content, true, browser);
4826 browser.noteSignal.tagsChanged.disconnect();
4827 browser.noteSignal.titleChanged.disconnect();
4828 browser.noteSignal.noteChanged.disconnect();
4829 browser.noteSignal.notebookChanged.disconnect();
4830 browser.noteSignal.createdDateChanged.disconnect();
4831 browser.noteSignal.alteredDateChanged.disconnect();
4834 tabWindows.remove(index);
4835 tabBrowser.removeTab(index);
4836 noteDirty.remove(index);
4837 inkNote.remove(index);
4838 readOnly.remove(index);
4841 historyGuids.remove(index);
4842 historyPosition.remove(index);
4843 fromHistory.remove(index);
4845 // タブのインデックスを更新(削除によって空いた部分を詰める)
4846 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4848 TabBrowse tab = tabWindows.get(i + 1);
4849 tabWindows.put(i, tab);
4850 tabWindows.remove(i + 1);
4852 boolean isNoteDirty = noteDirty.get(i + 1);
4853 noteDirty.put(i, isNoteDirty);
4854 noteDirty.remove(i + 1);
4856 boolean isInkNote = inkNote.get(i + 1);
4857 inkNote.put(i, isInkNote);
4858 inkNote.remove(i + 1);
4860 boolean isReadOnly = readOnly.get(i + 1);
4861 readOnly.put(i, isReadOnly);
4862 readOnly.remove(i + 1);
4864 ArrayList<String> histGuids = historyGuids.get(i + 1);
4865 historyGuids.put(i, histGuids);
4866 historyGuids.remove(i + 1);
4868 int histPosition = historyPosition.get(i + 1);
4869 historyPosition.put(i, histPosition);
4870 historyPosition.remove(i + 1);
4872 boolean fromHist = fromHistory.get(i + 1);
4873 fromHistory.put(i, fromHist);
4874 fromHistory.remove(i + 1);
4877 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4878 tabWindowChanged(tabBrowser.currentIndex());
4881 @SuppressWarnings("unused")
4882 private void noteAddNewTab() {
4885 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4886 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4887 String prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4889 openEmptyTabEditor();
4892 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4893 TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4894 String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4895 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4896 if (addedTabGuid != null && !addedTabGuid.equals("")) {
4897 if (!prevTabGuid.equals(addedTabGuid)) {
4898 conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4905 private void openEmptyTabEditor() {
4907 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4908 showEditorButtons(newBrowser.getBrowserWindow());
4910 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4912 int index = tabBrowser.addNewTab(newBrowser, "");
4913 tabWindows.put(index, newBrowser);
4914 noteDirty.put(index, false);
4916 // ExtendedInformationを必要があれば表示する
4917 toggleNoteInformation();
4918 // Sourceを必要があれば表示する
4920 // EditorButtonsBarを必要があれば表示する
4921 toggleEditorButtonBar();
4924 ArrayList<String> histGuids = new ArrayList<String>();
4925 historyGuids.put(index, histGuids);
4926 historyPosition.put(index, 0);
4927 fromHistory.put(index, false);
4929 tabBrowser.setCurrentIndex(index);
4932 //***************************************************************
4933 //***************************************************************
4934 //** These functions deal with Note specific things
4935 //***************************************************************
4936 //***************************************************************
4938 private void setNoteDirty() {
4939 for (String guid: selectedNoteGUIDs) {
4945 private void setNoteDirty(String targetGuid) {
4946 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
4948 // Find if the note is being edited externally. If it is, update it.
4949 if (externalWindows.containsKey(targetGuid)) {
4950 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4951 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4952 ExternalBrowse window = externalWindows.get(targetGuid);
4953 window.getBrowserWindow().setContent(unicode);
4956 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
4957 Collection<Integer> tabIndexes = tabWindows.keySet();
4958 Iterator<Integer> indexIterator = tabIndexes.iterator();
4960 for (TabBrowse tab: tabWindows.values()) {
4961 int index = indexIterator.next();
4962 String guid = tab.getBrowserWindow().getNote().getGuid();
4964 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4965 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4967 if (guid.equals(guid)) {
4968 if (index != tabBrowser.currentIndex()) {
4969 TabBrowse window = tabWindows.get(index);
4970 window.getBrowserWindow().setContent(unicode);
4975 // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する
4976 // If the note is dirty, then it is unsynchronized by default.
4978 boolean isNoteDirty = false;
4979 for (TabBrowse tab: tabWindows.values()) {
4980 if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) {
4981 index = tabBrowser.indexOf(tab);
4982 isNoteDirty = noteDirty.get(index);
4990 // Set the note as dirty and check if its status is synchronized in the display table
4991 // まだダーティでなく、かつタブで開かれている場合にnoteDirty = trueにする
4993 noteDirty.put(index, true);
4996 if (listManager.getNoteMetadata().containsKey(targetGuid) &&
4997 listManager.getNoteMetadata().get(targetGuid).isDirty()) {
5001 // If this wasn't already marked as unsynchronized, then we need to update the table
5002 listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false);
5003 // listManager.getUnsynchronizedNotes().add(targetGuid);
5004 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
5005 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
5006 if (modelIndex != null) {
5007 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5008 String tableGuid = (String)ix.values().toArray()[0];
5009 if (tableGuid.equals(targetGuid)) {
5010 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
5016 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
5018 @SuppressWarnings("unused")
5019 private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
5020 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5021 QByteArray unicode = codec.fromUnicode(content);
5022 noteCache.remove(guid);
5023 noteCache.put(guid, unicode.toString());
5024 if (guid.equals(currentNoteGuid)) {
5026 int index = tabBrowser.currentIndex();
5027 noteDirty.put(index, true);
5028 browserWindow.setContent(unicode);
5031 thumbnailRunner.addWork("GENERATE "+ guid);
5032 saveNote(guid, browser);
5038 private void saveNoteTabBrowser(String guid, String content, Boolean save,
5039 BrowserWindow browser) {
5040 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5041 QByteArray unicode = codec.fromUnicode(content);
5042 noteCache.remove(guid);
5043 noteCache.put(guid, unicode.toString());
5045 thumbnailRunner.addWork("GENERATE " + guid);
5046 saveNote(guid, browser);
5050 private void saveNote() {
5052 // すべてのタブに対して、Dirtyを確認し、trueならセーブする
5053 Collection<Integer> dirtyIndex = noteDirty.keySet();
5054 Iterator<Integer> indexIterator = dirtyIndex.iterator();
5055 for (boolean isNoteDirty: noteDirty.values()) {
5056 int index = indexIterator.next();
5061 BrowserWindow b = tabWindows.get(index).getBrowserWindow();
5062 String guid = b.getNote().getGuid();
5064 thumbnailRunner.addWork("GENERATE "+ guid);
5065 noteDirty.put(index, false);
5069 private void saveNote(String guid, BrowserWindow window) {
5070 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5073 logger.log(logger.EXTREME, "Saving to cache");
5074 QTextCodec codec = QTextCodec.codecForLocale();
5075 // QTextDecoder decoder = codec.makeDecoder();
5076 codec = QTextCodec.codecForName("UTF-8");
5077 QByteArray unicode = codec.fromUnicode(window.getContent());
5078 noteCache.put(guid, unicode.toString());
5080 logger.log(logger.EXTREME, "updating list manager");
5081 listManager.updateNoteContent(guid, window.getContent());
5082 logger.log(logger.EXTREME, "Updating title");
5083 listManager.updateNoteTitle(guid, window.getTitle());
5084 updateListDateChanged();
5086 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5087 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5088 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5089 currentNote = listManager.getNoteIndex().get(i);
5090 i = listManager.getNoteIndex().size();
5095 // Get a note from Evernote (and put it in the browser)
5096 private void refreshEvernoteNote(boolean reload) {
5097 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5099 if (Global.disableViewing) {
5100 browserWindow.setEnabled(false);
5104 inkNote.put(tabBrowser.currentIndex(), false);
5105 readOnly.put(tabBrowser.currentIndex(), false);
5107 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) {
5108 readOnly.put(tabBrowser.currentIndex(), true);
5110 Global.cryptCounter =0;
5111 if (readOnly.get(tabBrowser.currentIndex())) {
5112 browserWindow.setReadOnly(true);
5119 browserWindow.loadingData(true);
5121 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5122 if (currentNote == null) {
5128 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5130 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5134 private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5135 NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
5136 formatter.setNote(note, Global.pdfPreview());
5137 formatter.setHighlight(listManager.getEnSearch());
5142 for (TabBrowse tab: tabWindows.values()) {
5143 if (tab.getBrowserWindow() == browser) {
5144 tabIndex = tabBrowser.indexOf(tab);
5149 if (!noteCache.containsKey(guid)) {
5150 js = new QByteArray();
5151 // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
5152 js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
5153 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>");
5154 js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5155 js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5156 if (Global.displayRightToLeft())
5157 js.append("<style> body { direction:rtl; }</style>");
5158 js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5159 js.append("</head>");
5160 formatter.setNote(note, Global.pdfPreview());
5161 js.append(formatter.rebuildNoteHTML());
5162 js.append("</HTML>");
5163 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5164 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5165 js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5166 // if (Global.enableHTMLEntitiesFix) {
5167 // browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5169 browser.setContent(js);
5170 noteCache.put(guid, js.toString());
5172 if (formatter.resourceError)
5173 resourceErrorMessage(tabIndex);
5174 if (formatter.formatError) {
5176 QMessageBox.information(this, tr("Error"),
5177 tr("NeighborNote had issues formatting this note." +
5178 " To protect your data this note is being marked as read-only."));
5182 if (tabIndex >= 0) {
5183 readOnly.put(tabIndex, formatter.readOnly);
5184 inkNote.put(tabIndex, formatter.inkNote);
5187 if (tabIndex >= 0 && readOnly.get(tabIndex)) {
5188 readOnlyCache.put(guid, true);
5190 if (tabIndex >= 0 && inkNote.get(tabIndex)) {
5191 inkNoteCache.put(guid, true);
5195 logger.log(logger.HIGH, "Note content is being pulled from the cache");
5196 String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5197 js = new QByteArray(cachedContent);
5198 browser.setContent(js);
5199 if (readOnlyCache.containsKey(guid) && tabIndex >= 0) {
5200 readOnly.put(tabIndex, true);
5202 readOnly.put(tabIndex, false);
5204 if (inkNoteCache.containsKey(guid) && tabIndex >= 0) {
5205 inkNote.put(tabIndex, true);
5207 inkNote.put(tabIndex, false);
5210 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5211 thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5213 if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) ||
5214 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != "")))
5215 browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
5217 browser.getBrowser().page().setContentEditable(true);
5218 if (tabIndex >= 0) {
5219 browser.setReadOnly(readOnly.get(tabIndex));
5220 deleteButton.setEnabled(!readOnly.get(tabIndex));
5221 tagButton.setEnabled(!readOnly.get(tabIndex));
5222 menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex));
5223 menuBar.noteTags.setEnabled(!readOnly.get(tabIndex));
5225 browser.setNote(note);
5227 if (note != null && note.getNotebookGuid() != null &&
5228 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5229 deleteButton.setEnabled(false);
5230 menuBar.notebookDeleteAction.setEnabled(false);
5232 deleteButton.setEnabled(true);
5233 menuBar.notebookDeleteAction.setEnabled(true);
5236 // Build a list of non-closed notebooks
5237 List<Notebook> nbooks = new ArrayList<Notebook>();
5238 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5239 boolean found=false;
5240 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5241 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
5245 nbooks.add(listManager.getNotebookIndex().get(i));
5248 browser.setTitle(note.getTitle());
5249 browser.setTag(getTagNamesForNote(note));
5250 browser.setAuthor(note.getAttributes().getAuthor());
5252 browser.setAltered(note.getUpdated());
5253 browser.setCreation(note.getCreated());
5254 if (note.getAttributes().getSubjectDate() > 0)
5255 browser.setSubjectDate(note.getAttributes().getSubjectDate());
5257 browser.setSubjectDate(note.getCreated());
5258 browser.setUrl(note.getAttributes().getSourceURL());
5260 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5261 List<Tag> tagList = tagFilter.getValidTags(note);
5262 browser.setAllTags(tagList);
5264 browser.setCurrentTags(note.getTagNames());
5266 for (TabBrowse tab: tabWindows.values()) {
5267 if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
5268 int index = tabBrowser.indexOf(tab);
5269 noteDirty.put(index, false);
5276 browser.loadingData(false);
5277 if (thumbnailViewer.isActiveWindow())
5280 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5281 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5284 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5288 @SuppressWarnings("unused")
5289 private void toggleNoteAttributes() {
5290 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5291 toggleNoteInformation();
5294 // Save a generated thumbnail
5295 private void toggleNoteInformation() {
5296 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5299 boolean isChecked = menuBar.noteAttributes.isChecked();
5301 for(int i = 0; i < tabBrowser.count(); i++){
5302 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5303 boolean isExtended = browser.isExtended();
5304 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5305 browser.toggleInformation();
5309 menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5310 Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5311 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5314 // Listener triggered when a print button is pressed
5315 @SuppressWarnings("unused")
5316 private void printNote() {
5317 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5319 QPrintDialog dialog = new QPrintDialog();
5320 if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5321 QPrinter printer = dialog.printer();
5322 browserWindow.getBrowser().print(printer);
5324 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5327 // Listener triggered when the email button is pressed
5328 @SuppressWarnings("unused")
5329 private void emailNote() {
5330 logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5332 if (Desktop.isDesktopSupported()) {
5333 Desktop desktop = Desktop.getDesktop();
5335 String text2 = browserWindow.getContentsToEmail();
5336 QUrl url = new QUrl("mailto:");
5337 url.addQueryItem("subject", currentNote.getTitle());
5338 // url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5339 url.addQueryItem("body", text2);
5340 QDesktopServices.openUrl(url);
5344 if (desktop.isSupported(Desktop.Action.MAIL)) {
5345 URI uriMailTo = null;
5347 //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5348 String text = browserWindow.getContentsToEmail();
5349 //text = "<b>" +text +"</b>";
5350 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5351 +"&BODY=" +text, null);
5352 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5353 +"&ATTACHMENT=d:/test.pdf", null);
5354 desktop.mail(uriMailTo);
5355 } catch (URISyntaxException e) {
5356 e.printStackTrace();
5357 } catch (IOException e) {
5358 e.printStackTrace();
5365 logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5367 // Reindex all notes
5368 @SuppressWarnings("unused")
5369 private void fullReindex() {
5370 logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5371 indexRunner.addWork("REINDEXALL");
5372 setMessage(tr("Database will be reindexed."));
5373 logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5375 // Listener when a user wants to reindex a specific note
5376 @SuppressWarnings("unused")
5377 private void reindexNote() {
5378 logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5379 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5380 indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5382 if (selectedNotebookGUIDs.size() > 1)
5383 setMessage(tr("Notes will be reindexed."));
5385 setMessage(tr("Note will be reindexed."));
5386 logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5389 @SuppressWarnings("unused")
5390 private void deleteNote() {
5391 logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5392 if (currentNote == null)
5394 if (currentNoteGuid.equals(""))
5396 String title = null;
5397 if (selectedNoteGUIDs.size() == 1)
5398 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5400 // If we are deleting non-trash notes
5401 if (currentNote.isActive()) {
5402 if (Global.verifyDelete()) {
5404 if (selectedNoteGUIDs.size() > 1) {
5405 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5408 msg = new String(tr("Delete note \"") +title +"\"?");
5410 msg = new String(tr("Delete note selected note?"));
5412 if (QMessageBox.question(this, tr("Confirmation"), msg,
5413 QMessageBox.StandardButton.Yes,
5414 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5418 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5419 selectedNoteGUIDs.add(currentNoteGuid);
5420 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5421 listManager.deleteNote(selectedNoteGUIDs.get(i));
5424 // If we are deleting from the trash.
5425 if (Global.verifyDelete()) {
5427 if (selectedNoteGUIDs.size() > 1) {
5428 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5431 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5433 msg = new String(tr("Permanently delete note selected note?"));
5435 if (QMessageBox.question(this, "Confirmation", msg,
5436 QMessageBox.StandardButton.Yes,
5437 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
5441 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5442 selectedNoteGUIDs.add(currentNoteGuid);
5443 for (int i=selectedNoteGUIDs.size()-1; i>=0; i--) {
5444 for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5445 QModelIndex modelIndex = listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5446 if (modelIndex != null) {
5447 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5448 String tableGuid = (String)ix.values().toArray()[0];
5449 if (tableGuid.equals(selectedNoteGUIDs.get(i))) {
5450 listManager.getNoteTableModel().removeRow(j);
5455 listManager.expungeNote(selectedNoteGUIDs.get(i));
5458 conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i));
5459 conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i));
5460 conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i));
5464 currentNoteGuid = "";
5466 // ICHANGED ↓↓↓ここから↓↓↓
5467 // 削除したノートを外部ウィンドウで開いていたら、閉じる
5468 Collection<ExternalBrowse> windows = externalWindows.values();
5469 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5470 Collection<String> guids = externalWindows.keySet();
5471 Iterator<String> guidIterator = guids.iterator();
5472 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5474 while (windowIterator.hasNext()) {
5475 ExternalBrowse browser = windowIterator.next();
5476 String guid = guidIterator.next();
5478 for (int i = 0; i < selectedNoteGUIDs.size(); i++) {
5479 if (guid.equals(selectedNoteGUIDs.get(i))) {
5480 closeWindows.add(browser);
5485 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5486 closeWindows.get(i).close();
5488 // ICHANGED ↑↑↑ここまで↑↑↑
5490 // ICHANGED ↓↓↓ここから↓↓↓
5491 // 削除したノートをタブで開いていたら、閉じる
5492 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5493 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5494 Collection<Integer> tabIndexes = tabWindows.keySet();
5495 Iterator<Integer> indexIterator = tabIndexes.iterator();
5496 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
5498 while (tabIterator.hasNext()) {
5499 TabBrowse tab = tabIterator.next();
5500 int index = indexIterator.next();
5501 String guid = tab.getBrowserWindow().getNote().getGuid();
5503 for(int i = 0; i < selectedNoteGUIDs.size(); i++){
5504 if(guid.equals(selectedNoteGUIDs.get(i))){
5505 closeIndexes.add(index);
5510 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5511 tabWindowClosing(closeIndexes.get(i));
5513 // ICHANGED ↑↑↑ここまで↑↑↑
5515 listManager.loadNotesIndex();
5516 noteIndexUpdated(false);
5517 refreshEvernoteNote(true);
5518 scrollToGuid(currentNoteGuid);
5519 logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5522 // ICHANGED @SuppressWarnings("unused") を削除
5523 private void addNote() {
5524 logger.log(logger.HIGH, "Inside NeverNote.addNote");
5525 // browserWindow.setEnabled(true);
5526 browserWindow.setReadOnly(false);
5528 Calendar currentTime = new GregorianCalendar();
5529 StringBuffer noteString = new StringBuffer(100);
5530 noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5531 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5534 if (Global.overrideDefaultFont()) {
5535 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5536 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5537 noteString.append("<br clear=\"none\" />\n");
5538 noteString.append("</span>\n</font>\n");
5540 noteString.append("<br clear=\"none\" />\n");
5541 noteString.append("</en-note>");
5543 Long l = new Long(currentTime.getTimeInMillis());
5544 String randint = new String(Long.toString(l));
5546 // Find a notebook. We first look for a selected notebook (the "All Notebooks" one doesn't count).
5548 // for the first non-archived notebook. Finally, if nothing else we
5549 // pick the first notebook in the list.
5550 String notebook = null;
5551 listManager.getNotebookIndex().get(0).getGuid();
5552 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5553 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5554 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5555 notebook = currentSelectedNotebook.text(2);
5557 boolean found = false;
5558 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5559 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5560 boolean match = false;
5561 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5562 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5564 j = listManager.getArchiveNotebookIndex().size();
5568 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5569 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5571 // Now we have a list of good notebooks, so we can look for the default
5573 for (int i=0; i<goodNotebooks.size(); i++) {
5574 if (goodNotebooks.get(i).isDefaultNotebook()) {
5575 notebook = goodNotebooks.get(i).getGuid();
5577 i = goodNotebooks.size();
5581 if (goodNotebooks.size() > 0 && !found)
5582 notebook = goodNotebooks.get(0).getGuid();
5585 notebook = listManager.getNotebookIndex().get(0).getGuid();
5588 Note newNote = new Note();
5589 newNote.setUpdateSequenceNum(0);
5590 newNote.setGuid(randint);
5591 newNote.setNotebookGuid(notebook);
5592 newNote.setTitle("Untitled Note");
5593 newNote.setContent(noteString.toString());
5594 newNote.setDeleted(0);
5595 newNote.setCreated(System.currentTimeMillis());
5596 newNote.setUpdated(System.currentTimeMillis());
5597 newNote.setActive(true);
5598 NoteAttributes na = new NoteAttributes();
5599 na.setLatitude(0.0);
5600 na.setLongitude(0.0);
5601 na.setAltitude(0.0);
5602 newNote.setAttributes(new NoteAttributes());
5603 newNote.setTagGuids(new ArrayList<String>());
5604 newNote.setTagNames(new ArrayList<String>());
5606 // If new notes are to be created based upon the selected tags, then we need to assign the tags
5607 if (Global.newNoteWithSelectedTags()) {
5608 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5609 QTreeWidgetItem currentSelection;
5610 for (int i=0; i<selections.size(); i++) {
5611 currentSelection = selections.get(i);
5612 newNote.getTagGuids().add(currentSelection.text(2));
5613 newNote.getTagNames().add(currentSelection.text(0));
5617 conn.getNoteTable().addNote(newNote, true);
5618 NoteMetadata metadata = new NoteMetadata();
5619 metadata.setGuid(newNote.getGuid());
5620 metadata.setDirty(true);
5621 listManager.addNote(newNote, metadata);
5622 // noteTableView.insertRow(newNote, true, -1);
5625 String prevCurrentNoteGuid = new String(currentNoteGuid);
5627 currentNote = newNote;
5628 currentNoteGuid = currentNote.getGuid();
5629 // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5630 // noteTableView.clearSelection();
5632 refreshEvernoteNote(true);
5633 listManager.countNotebookResults(listManager.getNoteIndex());
5634 browserWindow.titleLabel.setFocus();
5635 browserWindow.titleLabel.selectAll();
5636 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5638 // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加
5639 if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5640 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5641 conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5645 // If the window is hidden, then we want to popup this in an external window &
5649 logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5651 // Restore a note from the trash;
5652 @SuppressWarnings("unused")
5653 private void restoreNote() {
5655 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5656 selectedNoteGUIDs.add(currentNoteGuid);
5657 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5658 listManager.restoreNote(selectedNoteGUIDs.get(i));
5660 currentNoteGuid = "";
5661 listManager.loadNotesIndex();
5662 noteIndexUpdated(false);
5665 // Search a note for specific txt
5666 @SuppressWarnings("unused")
5667 private void findText() {
5669 find.setFocusOnTextField();
5671 @SuppressWarnings("unused")
5672 private void doFindText() {
5673 browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5676 @SuppressWarnings("unused")
5677 private void updateNoteTitle(String guid, String title) {
5678 listManager.setNoteSynchronized(guid, false);
5680 // We do this manually because if we've edited the note in an
5681 // external window we run into the possibility of signal recursion
5683 if (guid.equals(currentNoteGuid)) {
5684 browserWindow.titleLabel.blockSignals(true);
5685 browserWindow.titleLabel.setText(title);
5686 browserWindow.titleLabel.blockSignals(false);
5689 // Signal received that note content has changed. Normally we just need the guid to remove
5690 // it from the cache.
5691 @SuppressWarnings("unused")
5692 private void invalidateNoteCache(String guid, String content) {
5693 noteCache.remove(guid);
5694 refreshEvernoteNote(true);
5696 // Signal received that a note guid has changed
5697 @SuppressWarnings("unused")
5698 private void noteGuidChanged(String oldGuid, String newGuid) {
5699 if (noteCache.containsKey(oldGuid)) {
5700 if (!oldGuid.equals(currentNoteGuid)) {
5701 String cache = noteCache.get(oldGuid);
5702 noteCache.put(newGuid, cache);
5703 noteCache.remove(oldGuid);
5705 noteCache.remove(oldGuid);
5706 noteCache.put(newGuid, browserWindow.getContent());
5710 listManager.updateNoteGuid(oldGuid, newGuid, false);
5711 if (currentNoteGuid.equals(oldGuid)) {
5712 if (currentNote != null)
5713 currentNote.setGuid(newGuid);
5714 currentNoteGuid = newGuid;
5717 if (externalWindows.containsKey(oldGuid)) {
5718 ExternalBrowse b = externalWindows.get(oldGuid);
5719 externalWindows.remove(oldGuid);
5720 b.getBrowserWindow().getNote().setGuid(newGuid);
5721 externalWindows.put(newGuid, b);
5725 for(int i = 0; i < tabBrowser.count(); i++){
5726 TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5727 if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) {
5728 b.getBrowserWindow().getNote().setGuid(newGuid);
5732 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5733 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5734 noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5735 i=listManager.getNoteIndex().size();
5739 if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5740 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5741 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5742 listManager.getNoteTableModel().metaData.remove(oldGuid);
5747 // Toggle the note editor button bar
5749 private void toggleEditorButtonBar() {
5750 boolean isChecked = menuBar.showEditorBar.isChecked();
5752 for(int i = 0; i < tabBrowser.count(); i++){
5753 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5754 boolean isVisible = browser.buttonsVisible;
5756 if (isChecked && !isVisible) {
5757 browser.buttonsVisible = true;
5758 showEditorButtons(browser);
5759 } else if(!isChecked && isVisible) {
5760 browser.hideButtons();
5764 Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5767 // Show editor buttons
5768 private void showEditorButtons(BrowserWindow browser) {
5769 browser.buttonLayout.setVisible(true);
5770 browser.undoAction.setVisible(false);
5772 browser.undoButton.setVisible(false);
5774 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5775 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5776 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5777 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5778 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5779 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5780 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5781 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5782 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5783 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5784 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5785 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5786 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5787 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5788 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5789 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5790 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5791 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5792 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5793 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5794 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5795 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5796 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5798 private void duplicateNote(String guid) {
5800 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5801 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5802 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5803 oldNote.setResources(resList);
5804 duplicateNote(oldNote);
5806 private void duplicateNote(Note oldNote) {
5808 // Now that we have a good notebook guid, we need to move the conflicting note
5809 // to the local notebook
5810 Calendar currentTime = new GregorianCalendar();
5811 Long l = new Long(currentTime.getTimeInMillis());
5812 String newGuid = new String(Long.toString(l));
5814 // Note newNote = oldNote.deepCopy();
5815 Note newNote = (Note)Global.deepCopy(oldNote);
5816 newNote.setUpdateSequenceNum(0);
5817 newNote.setGuid(newGuid);
5818 newNote.setDeleted(0);
5819 newNote.setActive(true);
5822 List<String> tagNames = new ArrayList<String>();
5823 List<String> tagGuids = new ArrayList<String>();;
5824 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5825 tagNames.add(oldNote.getTagNames().get(i));
5826 tagGuids.add(oldNote.getTagGuids().get(i));
5829 // Sort note Tags to make them look nice
5830 for (int i=0; i<tagNames.size()-1; i++) {
5831 if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5832 String n1 = tagNames.get(i);
5833 String n2 = tagNames.get(i+1);
5834 tagNames.set(i, n2);
5835 tagNames.set(i+1, n1);
5838 newNote.setTagGuids(tagGuids);
5839 newNote.setTagNames(tagNames);
5841 // Add tag guids to note
5844 // Duplicate resources
5845 List<Resource> resList = oldNote.getResources();
5846 if (resList == null)
5847 resList = new ArrayList<Resource>();
5849 for (int i=0; i<resList.size(); i++) {
5851 while (l == prevGuid) {
5852 currentTime = new GregorianCalendar();
5853 l = new Long(currentTime.getTimeInMillis());
5856 String newResGuid = new String(Long.toString(l));
5857 resList.get(i).setNoteGuid(newGuid);
5858 resList.get(i).setGuid(newResGuid);
5859 resList.get(i).setUpdateSequenceNum(0);
5860 resList.get(i).setActive(true);
5861 conn.getNoteTable().noteResourceTable.saveNoteResource(
5862 (Resource)Global.deepCopy(resList.get(i)), true);
5864 newNote.setResources(resList);
5867 // 操作履歴と除外ノートとスター付きノートも複製する
5868 if(Global.getDuplicateRensoNote()) {
5869 conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5870 conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5871 conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5874 // Add note to the database
5875 conn.getNoteTable().addNote(newNote, true);
5876 NoteMetadata metaData = new NoteMetadata();
5877 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5878 metaData.copy(oldMeta);
5879 metaData.setGuid(newNote.getGuid());
5880 listManager.addNote(newNote, metaData);
5881 noteTableView.insertRow(newNote, metaData, true, -1);
5882 currentNoteGuid = newNote.getGuid();
5883 currentNote = newNote;
5884 refreshEvernoteNote(true);
5885 listManager.countNotebookResults(listManager.getNoteIndex());
5890 @SuppressWarnings("unused")
5891 private void allNotes() {
5892 clearAttributeFilter();
5893 clearNotebookFilter();
5894 clearSavedSearchFilter();
5897 searchField.clear();
5898 if (Global.mimicEvernoteInterface) {
5899 notebookTree.selectGuid("");
5901 notebookTreeSelection();
5902 refreshEvernoteNote(true);
5904 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5905 if (!rensoNoteListDock.isEnabled()) {
5906 rensoNoteListDock.setEnabled(true);
5910 @SuppressWarnings("unused")
5911 private void mergeNotes() {
5912 logger.log(logger.HIGH, "Merging notes");
5915 String masterGuid = null;
5916 List<String> sources = new ArrayList<String>();
5918 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5919 int r = noteTableView.selectionModel().selectedRows().get(i).row();
5920 index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5921 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5923 masterGuid = (String)ix.values().toArray()[0];
5925 sources.add((String)ix.values().toArray()[0]);
5928 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5929 logger.log(logger.EXTREME, "Children count: "+sources.size());
5930 mergeNoteContents(masterGuid, sources);
5931 currentNoteGuid = masterGuid;
5933 // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ
5934 if(Global.getMergeRensoNote()) {
5935 for (int i = 0; i < sources.size(); i++) {
5936 String childGuid = sources.get(i);
5937 if(masterGuid != null && childGuid != null) {
5938 if(!masterGuid.equals(childGuid)) {
5939 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
5940 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
5941 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
5947 // ICHANGED ↓↓↓ここから↓↓↓
5948 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
5949 Collection<ExternalBrowse> windows = externalWindows.values();
5950 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5951 Collection<String> guids = externalWindows.keySet();
5952 Iterator<String> guidIterator = guids.iterator();
5953 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5955 while (windowIterator.hasNext()) {
5956 ExternalBrowse browser = windowIterator.next();
5957 String guid = guidIterator.next();
5959 for (int i = 0; i < sources.size(); i++) {
5960 if (guid.equals(sources.get(i))) {
5961 closeWindows.add(browser);
5966 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5967 closeWindows.get(i).close();
5969 // ICHANGED ↑↑↑ここまで↑↑↑
5971 // ICHANGED ↓↓↓ここから↓↓↓
5972 // マージしたノート(child)をタブで開いていたら、閉じる
5973 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5974 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5975 Collection<Integer> tabIndexes = tabWindows.keySet();
5976 Iterator<Integer> indexIterator = tabIndexes.iterator();
5977 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
5979 while (tabIterator.hasNext()) {
5980 TabBrowse tab = tabIterator.next();
5981 int tabIndex = indexIterator.next();
5982 String guid = tab.getBrowserWindow().getNote().getGuid();
5984 for(int i = 0; i < sources.size(); i++){
5985 if(guid.equals(sources.get(i))){
5986 closeIndexes.add(tabIndex);
5991 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5992 tabWindowClosing(closeIndexes.get(i));
5994 // ICHANGED ↑↑↑ここまで↑↑↑
5996 noteIndexUpdated(false);
5998 // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除
5999 noteCache.remove(masterGuid);
6001 refreshEvernoteNote(true);
6004 private void mergeNoteContents(String targetGuid, List<String> sources) {
6005 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
6006 String newContent = target.getContent();
6007 newContent = newContent.replace("</en-note>", "<br></br>");
6009 for (int i=0; i<sources.size(); i++) {
6010 Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
6011 if (source.isSetTitle()) {
6012 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
6014 String sourceContent = source.getContent();
6015 logger.log(logger.EXTREME, "Merging contents into note");
6016 logger.log(logger.EXTREME, sourceContent);
6017 logger.log(logger.EXTREME, "End of content");
6018 int startOfNote = sourceContent.indexOf("<en-note>");
6019 sourceContent = sourceContent.substring(startOfNote+9);
6020 int endOfNote = sourceContent.indexOf("</en-note>");
6021 sourceContent = sourceContent.substring(0,endOfNote);
6022 newContent = newContent + sourceContent;
6023 logger.log(logger.EXTREME, "New note content");
6024 logger.log(logger.EXTREME, newContent);
6025 logger.log(logger.EXTREME, "End of content");
6026 for (int j=0; j<source.getResourcesSize(); j++) {
6027 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
6028 Resource r = source.getResources().get(j);
6029 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
6031 Calendar currentTime = new GregorianCalendar();
6032 Long l = new Long(currentTime.getTimeInMillis());
6036 while (l == prevGuid) {
6037 currentTime = new GregorianCalendar();
6038 l = new Long(currentTime.getTimeInMillis());
6040 String newResGuid = new String(Long.toString(l));
6041 newRes.setNoteGuid(targetGuid);
6042 newRes.setGuid(newResGuid);
6043 newRes.setUpdateSequenceNum(0);
6044 newRes.setActive(true);
6045 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
6048 logger.log(logger.EXTREME, "Updating note");
6049 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
6050 for (int i=0; i<sources.size(); i++) {
6051 logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
6052 listManager.deleteNote(sources.get(i));
6054 logger.log(logger.EXTREME, "Exiting merge note");
6056 // A resource within a note has had a guid change
6057 @SuppressWarnings("unused")
6058 private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
6059 if (oldGuid != null && !oldGuid.equals(newGuid))
6060 Global.resourceMap.put(oldGuid, newGuid);
6062 // View a thumbnail of the note
6063 public void thumbnailView() {
6065 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
6066 QFile thumbnail = new QFile(thumbnailName);
6067 if (!thumbnail.exists()) {
6069 QImage img = new QImage();
6070 img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
6071 thumbnailViewer.setThumbnail(img);
6073 thumbnailViewer.setThumbnail(thumbnailName);
6074 if (!thumbnailViewer.isVisible())
6075 thumbnailViewer.showFullScreen();
6077 // An error happened while saving a note. Inform the user
6078 @SuppressWarnings("unused")
6079 private void saveRunnerError(String guid, String msg) {
6081 String title = "*Unknown*";
6082 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6083 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6084 title = listManager.getMasterNoteIndex().get(i).getTitle();
6085 i=listManager.getMasterNoteIndex().size();
6088 msg = tr("An error has happened while saving the note \"") +title+
6089 tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
6090 "As a result, changes to the note may not be saved properly in the database."+
6091 "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6092 "\nbe lost. Please review the note to recover any critical data before restarting.");
6094 QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6097 private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6098 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6099 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6100 // Find an idle preview object
6101 for (int i=0; i<thumbGenerators.size(); i++) {
6102 if (thumbGenerators.get(i).mutex.tryLock()) {
6103 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6104 thumbGenerators.get(i).loadContent(guid, html, zoom);
6108 if (thumbGenerators.size() >= 1) {
6109 logger.log(logger.EXTREME, "No available thumbnail generators. Aborting " +guid);
6113 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6114 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6115 thumbGenerators.add(preview);
6117 if (preview.mutex.tryLock()) {
6118 logger.log(logger.EXTREME, "Loading thumbnail for " +guid);
6119 preview.loadContent(guid, html, zoom);
6121 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6126 //**********************************************************
6127 //**********************************************************
6128 //* Online user actions
6129 //**********************************************************
6130 //**********************************************************
6131 private void setupOnlineMenu() {
6132 if (!Global.isConnected) {
6133 menuBar.noteOnlineHistoryAction.setEnabled(false);
6134 menuBar.selectiveSyncAction.setEnabled(false);
6137 menuBar.noteOnlineHistoryAction.setEnabled(true);
6138 menuBar.selectiveSyncAction.setEnabled(true);
6141 @SuppressWarnings("unused")
6142 private void viewNoteHistory() {
6143 if (currentNoteGuid == null || currentNoteGuid.equals(""))
6145 if (currentNote.getUpdateSequenceNum() == 0) {
6146 setMessage(tr("Note has never been synchronized."));
6147 QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6151 setMessage(tr("Getting Note History"));
6153 Note currentOnlineNote = null;
6156 if (Global.isPremium())
6157 versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6159 versions = new ArrayList<NoteVersionId>();
6160 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6161 } catch (EDAMUserException e) {
6162 setMessage("EDAMUserException: " +e.getMessage());
6164 } catch (EDAMSystemException e) {
6165 setMessage("EDAMSystemException: " +e.getMessage());
6167 } catch (EDAMNotFoundException e) {
6168 setMessage(tr("Note not found on server."));
6169 QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6171 } catch (TException e) {
6172 setMessage("EDAMTransactionException: " +e.getMessage());
6176 // If we've gotten this far, we have a good note.
6177 if (historyWindow == null) {
6179 historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6181 historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6182 historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6183 historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6185 historyWindow.historyCombo.clear();
6187 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6188 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6190 historyWindow.setCurrent(isDirty);
6192 loadHistoryWindowContent(currentOnlineNote);
6193 historyWindow.load(versions);
6194 setMessage(tr("History retrieved"));
6196 historyWindow.exec();
6198 private Note reloadHistoryWindow(String selection) {
6200 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6201 String dateTimeFormat = new String(fmt);
6202 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6206 for (int i=0; i<versions.size(); i++) {
6207 StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6208 if (versionDate.toString().equals(selection))
6212 if (index > -1 || selection.indexOf("Current") > -1) {
6213 Note historyNote = null;
6216 usn = versions.get(index).getUpdateSequenceNum();
6217 historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6219 historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6220 } catch (EDAMUserException e) {
6221 setMessage("EDAMUserException: " +e.getMessage());
6224 } catch (EDAMSystemException e) {
6225 setMessage("EDAMSystemException: " +e.getMessage());
6228 } catch (EDAMNotFoundException e) {
6229 setMessage("EDAMNotFoundException: " +e.getMessage());
6232 } catch (TException e) {
6233 setMessage("EDAMTransactionException: " +e.getMessage());
6239 if (historyNote != null)
6240 historyWindow.setContent(historyNote);
6246 private void loadHistoryWindowContent(Note note) {
6247 note.setUpdateSequenceNum(0);
6248 historyWindow.setContent(note);
6250 @SuppressWarnings("unused")
6251 private void restoreHistoryNoteAsNew() {
6252 setMessage(tr("Restoring as new note."));
6253 duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6254 setMessage(tr("Note has been restored as a new note."));
6256 @SuppressWarnings("unused")
6257 private void restoreHistoryNote() {
6258 setMessage(tr("Restoring note."));
6259 Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6260 conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6263 for (int i=0; i<n.getResourcesSize(); i++) {
6264 n.getResources().get(i).setActive(true);
6265 conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6267 NoteMetadata metadata = new NoteMetadata();
6268 metadata.setGuid(n.getGuid());
6269 listManager.addNote(n, metadata);
6270 conn.getNoteTable().addNote(n, true);
6271 refreshEvernoteNote(true);
6272 setMessage(tr("Note has been restored."));
6274 @SuppressWarnings("unused")
6275 private void setupSelectiveSync() {
6277 // Get a list of valid notebooks
6278 List<Notebook> notebooks = null;
6279 List<Tag> tags = null;
6280 List<LinkedNotebook> linkedNotebooks = null;
6282 notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6283 tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6284 linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6285 } catch (EDAMUserException e) {
6286 setMessage("EDAMUserException: " +e.getMessage());
6288 } catch (EDAMSystemException e) {
6289 setMessage("EDAMSystemException: " +e.getMessage());
6291 } catch (TException e) {
6292 setMessage("EDAMTransactionException: " +e.getMessage());
6294 } catch (EDAMNotFoundException e) {
6295 setMessage("EDAMNotFoundException: " +e.getMessage());
6299 // Split up notebooks into synchronized & non-synchronized
6300 List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6301 List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6303 for (int i=notebooks.size()-1; i>=0; i--) {
6304 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6305 if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6306 ignoredBooks.add(notebooks.get(i));
6307 j=dbIgnoredNotebooks.size();
6312 // split up tags into synchronized & non-synchronized
6313 List<Tag> ignoredTags = new ArrayList<Tag>();
6314 List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6316 for (int i=tags.size()-1; i>=0; i--) {
6317 for (int j=0; j<dbIgnoredTags.size(); j++) {
6318 if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6319 ignoredTags.add(tags.get(i));
6320 j=dbIgnoredTags.size();
6325 // split up linked notebooks into synchronized & non-synchronized
6326 List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6327 List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6328 for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6329 String notebookGuid = linkedNotebooks.get(i).getGuid();
6330 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6331 if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6332 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6333 j=dbIgnoredLinkedNotebooks.size();
6338 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6340 if (!ignore.okClicked())
6345 // Clear out old notebooks & add the new ones
6346 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6347 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6348 conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6351 List<String> newNotebooks = new ArrayList<String>();
6352 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6353 String text = ignore.getIgnoredBookList().takeItem(i).text();
6354 for (int j=0; j<notebooks.size(); j++) {
6355 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6356 Notebook n = notebooks.get(j);
6357 conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6359 newNotebooks.add(n.getGuid());
6364 // Clear out old tags & add new ones
6365 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6366 for (int i=0; i<oldIgnoreTags.size(); i++) {
6367 conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6370 List<String> newTags = new ArrayList<String>();
6371 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6372 String text = ignore.getIgnoredTagList().takeItem(i).text();
6373 for (int j=0; j<tags.size(); j++) {
6374 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6375 Tag t = tags.get(j);
6376 conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6377 newTags.add(t.getGuid());
6383 // Clear out old tags & add new ones
6384 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6385 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6386 conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6389 List<String> newLinked = new ArrayList<String>();
6390 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6391 String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6392 for (int j=0; j<linkedNotebooks.size(); j++) {
6393 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6394 LinkedNotebook t = linkedNotebooks.get(j);
6395 conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6396 newLinked.add(t.getGuid());
6397 j=linkedNotebooks.size();
6402 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6408 //**********************************************************
6409 //**********************************************************
6410 //* XML Modifying methods
6411 //**********************************************************
6412 //**********************************************************
6413 // An error has happended fetching a resource. let the user know
6415 private void resourceErrorMessage(int tabIndex) {
6419 if (inkNote.get(tabIndex))
6422 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6423 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6424 "In a perfect world this wouldn't happen, but it has.\n" +
6425 "It is embarasing when a program like me, designed to save all your\n"+
6426 "precious data, has a problem finding data.\n\n" +
6427 "I guess life isn't fair, but I'll survive. Somehow...\n\n" +
6428 "In the mean time, I'm not going to let you make changes to this note.\n" +
6429 "Don't get angry. I'm doing it to prevent you from messing up\n"+
6430 "this note on the Evernote servers. Sorry."+
6431 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6432 inkNote.put(tabIndex, true);
6433 browserWindow.setReadOnly(true);
6440 //**********************************************************
6441 //**********************************************************
6443 //**********************************************************
6444 //**********************************************************
6445 // We should now do a sync with Evernote
6446 private void syncTimer() {
6447 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6448 syncRunner.syncNeeded = true;
6449 syncRunner.disableUploads = Global.disableUploads;
6451 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6453 private void syncStart() {
6454 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6456 if (!syncRunning && Global.isConnected) {
6457 syncRunner.setConnected(true);
6458 syncRunner.setKeepRunning(Global.keepRunning);
6459 syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6461 if (syncThreadsReady > 0) {
6462 thumbnailRunner.interrupt = true;
6463 saveNoteIndexWidth();
6464 saveNoteColumnPositions();
6465 if (syncRunner.addWork("SYNC")) {
6467 syncRunner.syncNeeded = true;
6472 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6474 @SuppressWarnings("unused")
6475 private void syncThreadComplete(Boolean refreshNeeded) {
6476 setMessage(tr("Finalizing Synchronization"));
6478 syncRunning = false;
6479 syncRunner.syncNeeded = false;
6480 synchronizeAnimationTimer.stop();
6481 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6483 if (currentNote == null) {
6484 currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6486 listManager.refreshNoteMetadata();
6487 noteIndexUpdated(true);
6488 noteTableView.selectionModel().blockSignals(true);
6489 scrollToGuid(currentNoteGuid);
6490 noteTableView.selectionModel().blockSignals(false);
6491 refreshEvernoteNote(false);
6492 scrollToGuid(currentNoteGuid);
6495 // Check to see if there were any shared notebook errors
6496 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6497 String guid = syncRunner.errorSharedNotebooks.get(0);
6498 String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6499 String localName = listManager.getNotebookNameByGuid(notebookGuid);
6500 SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6502 if (syncDialog.okPressed()) {
6503 if (syncDialog.doNothing.isChecked()) {
6504 syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6507 if (syncDialog.deleteNotebook.isChecked()) {
6508 conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6509 conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6510 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6511 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6519 // Finalize the synchronization
6520 if (!syncRunner.error)
6521 setMessage(tr("Synchronization Complete"));
6523 setMessage(tr("Synchronization completed with errors. Please check the log for details."));
6524 logger.log(logger.MEDIUM, "Sync complete.");
6526 public void saveUploadAmount(long t) {
6527 Global.saveUploadAmount(t);
6529 public void saveUserInformation(User user) {
6530 Global.saveUserInformation(user);
6532 public void saveEvernoteUpdateCount(int i) {
6533 Global.saveEvernoteUpdateCount(i);
6535 public void refreshLists() {
6536 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6539 // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。
6540 Collection<Integer> tabIndex = noteDirty.keySet();
6541 Iterator<Integer> indexIterator = tabIndex.iterator();
6542 HashMap<Integer, Note> saveNotes = new HashMap<Integer, Note>();
6543 HashMap<Integer, String> saveContents = new HashMap<Integer, String>();
6544 for (boolean isNoteDirty: noteDirty.values()) {
6545 int index = indexIterator.next();
6547 saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote());
6548 saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent());
6552 listManager.saveUpdatedNotes(saveNotes, saveContents);
6553 listManager.refreshLists();
6555 tagIndexUpdated(true);
6556 notebookIndexUpdated();
6557 savedSearchIndexUpdated();
6558 listManager.loadNotesIndex();
6560 noteTableView.selectionModel().blockSignals(true);
6561 noteIndexUpdated(true);
6562 noteTableView.selectionModel().blockSignals(false);
6563 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6567 @SuppressWarnings("unused")
6568 private void authTimer() {
6569 Calendar cal = Calendar.getInstance();
6571 // If we are not connected let's get out of here
6572 if (!Global.isConnected)
6575 // If this is the first time through, then we need to set this
6576 // if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime)
6577 // syncRunner.authRefreshTime = cal.getTimeInMillis();
6579 // long now = new Date().getTime();
6580 // if (now > Global.authRefreshTime && Global.isConnected) {
6581 syncRunner.authRefreshNeeded = true;
6585 @SuppressWarnings("unused")
6586 private void authRefreshComplete(boolean goodSync) {
6587 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6588 Global.isConnected = syncRunner.isConnected;
6590 // authTimer.start((int)syncRunner.authTimeRemaining/4);
6591 authTimer.start(1000*60*15);
6592 logger.log(logger.LOW, "Authentication token has been renewed");
6593 // setMessage("Authentication token has been renewed.");
6595 authTimer.start(1000*60*5);
6596 logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6597 // setMessage("Authentication token renew has failed - retry in 5 minutes.");
6599 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6603 @SuppressWarnings("unused")
6604 private synchronized void indexTimer() {
6605 logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning);
6608 if (!indexDisabled && indexRunner.idle) {
6609 thumbnailRunner.interrupt = true;
6610 indexRunner.addWork("SCAN");
6612 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6615 @SuppressWarnings("unused")
6616 private void indexStarted() {
6617 setMessage(tr("Indexing notes"));
6619 @SuppressWarnings("unused")
6620 private void indexComplete() {
6621 setMessage(tr("Index complete"));
6623 @SuppressWarnings("unused")
6624 private synchronized void toggleNoteIndexing() {
6625 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6626 indexDisabled = !indexDisabled;
6628 setMessage(tr("Indexing is now enabled."));
6630 setMessage(tr("Indexing is now disabled."));
6631 menuBar.disableIndexing.setChecked(indexDisabled);
6632 logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6635 @SuppressWarnings("unused")
6636 private void threadMonitorCheck() {
6641 alive = listManager.threadCheck(Global.tagCounterThreadId);
6644 if (tagDeadCount > MAX && !disableTagThreadCheck) {
6645 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
6646 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6647 disableTagThreadCheck = true;
6652 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6654 notebookThreadDeadCount++;
6655 if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6656 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
6657 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6658 disableNotebookThreadCheck=true;
6661 notebookThreadDeadCount=0;
6663 alive = listManager.threadCheck(Global.trashCounterThreadId);
6666 if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6667 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
6668 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6669 disableTrashThreadCheck = true;
6674 alive = listManager.threadCheck(Global.saveThreadId);
6676 saveThreadDeadCount++;
6677 if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6678 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
6679 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6680 disableSaveThreadCheck = true;
6683 saveThreadDeadCount=0;
6685 if (!syncThread.isAlive()) {
6686 syncThreadDeadCount++;
6687 if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6688 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
6689 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6690 disableSyncThreadCheck = true;
6693 syncThreadDeadCount=0;
6695 if (!indexThread.isAlive()) {
6696 indexThreadDeadCount++;
6697 if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6698 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
6699 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6700 disableIndexThreadCheck = true;
6703 indexThreadDeadCount=0;
6708 private void thumbnailTimer() {
6709 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6710 thumbnailRunner.addWork("SCAN");
6714 //**************************************************
6715 //* Backup & Restore
6716 //**************************************************
6717 @SuppressWarnings("unused")
6718 private void databaseBackup() {
6719 QFileDialog fd = new QFileDialog(this);
6720 fd.setFileMode(FileMode.AnyFile);
6721 fd.setConfirmOverwrite(true);
6722 fd.setWindowTitle(tr("Backup Database"));
6723 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6724 fd.setAcceptMode(AcceptMode.AcceptSave);
6725 if (saveLastPath == null || saveLastPath.equals(""))
6726 fd.setDirectory(System.getProperty("user.home"));
6728 fd.setDirectory(saveLastPath);
6729 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6735 saveLastPath = fd.selectedFiles().get(0);
6736 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6737 setMessage(tr("Backing up database"));
6739 // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6741 ExportData noteWriter = new ExportData(conn, true);
6742 String fileName = fd.selectedFiles().get(0);
6744 if (!fileName.endsWith(".nnex"))
6745 fileName = fileName +".nnex";
6746 noteWriter.exportData(fileName);
6747 setMessage(tr("Database backup completed."));
6752 @SuppressWarnings("unused")
6753 private void databaseRestore() {
6754 if (QMessageBox.question(this, tr("Confirmation"),
6755 tr("This is used to restore a database from backups.\n" +
6756 "It is HIGHLY recommened that this only be used to populate\n" +
6757 "an empty database. Restoring into a database that\n already has data" +
6758 " can cause problems.\n\nAre you sure you want to continue?"),
6759 QMessageBox.StandardButton.Yes,
6760 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6765 QFileDialog fd = new QFileDialog(this);
6766 fd.setFileMode(FileMode.ExistingFile);
6767 fd.setConfirmOverwrite(true);
6768 fd.setWindowTitle(tr("Restore Database"));
6769 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6770 fd.setAcceptMode(AcceptMode.AcceptOpen);
6771 if (saveLastPath == null || saveLastPath.equals(""))
6772 fd.setDirectory(System.getProperty("user.home"));
6774 fd.setDirectory(saveLastPath);
6775 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6781 saveLastPath = fd.selectedFiles().get(0);
6782 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6784 setMessage(tr("Restoring database"));
6785 ImportData noteReader = new ImportData(conn, true);
6786 noteReader.importData(fd.selectedFiles().get(0));
6788 if (noteReader.lastError != 0) {
6789 setMessage(noteReader.getErrorMessage());
6790 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6795 listManager.loadNoteTitleColors();
6797 refreshEvernoteNote(true);
6798 setMessage(tr("Database has been restored."));
6801 @SuppressWarnings("unused")
6802 private void exportNotes() {
6803 QFileDialog fd = new QFileDialog(this);
6804 fd.setFileMode(FileMode.AnyFile);
6805 fd.setConfirmOverwrite(true);
6806 fd.setWindowTitle(tr("Backup Database"));
6807 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6808 fd.setAcceptMode(AcceptMode.AcceptSave);
6809 fd.setDirectory(System.getProperty("user.home"));
6810 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6816 setMessage(tr("Exporting Notes"));
6819 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6820 selectedNoteGUIDs.add(currentNoteGuid);
6822 ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6823 String fileName = fd.selectedFiles().get(0);
6825 if (!fileName.endsWith(".nnex"))
6826 fileName = fileName +".nnex";
6827 noteWriter.exportData(fileName);
6828 setMessage(tr("Export completed."));
6834 @SuppressWarnings("unused")
6835 private void importNotes() {
6836 QFileDialog fd = new QFileDialog(this);
6837 fd.setFileMode(FileMode.ExistingFile);
6838 fd.setConfirmOverwrite(true);
6839 fd.setWindowTitle(tr("Import Notes"));
6840 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6841 fd.setAcceptMode(AcceptMode.AcceptOpen);
6842 if (saveLastPath == null || saveLastPath.equals(""))
6843 fd.setDirectory(System.getProperty("user.home"));
6845 fd.setDirectory(saveLastPath);
6846 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6852 setMessage(tr("Importing Notes"));
6855 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6856 selectedNoteGUIDs.add(currentNoteGuid);
6858 String fileName = fd.selectedFiles().get(0);
6859 // saveLastPath.substring(0,fileName.lastIndexOf("/"));
6861 if (fileName.endsWith(".nnex")) {
6862 ImportData noteReader = new ImportData(conn, false);
6863 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6864 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6866 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6868 noteReader.importData(fileName);
6870 if (noteReader.lastError != 0) {
6871 setMessage(noteReader.getErrorMessage());
6872 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6877 if (fileName.endsWith(".enex")) {
6878 ImportEnex noteReader = new ImportEnex(conn, false);
6879 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6880 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6882 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6885 if (QMessageBox.question(this, tr("Confirmation"),
6886 tr("Create new tags from import?"),
6887 QMessageBox.StandardButton.Yes,
6888 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6889 noteReader.createNewTags = true;
6891 noteReader.createNewTags = false;
6893 noteReader.importData(fileName);
6895 if (noteReader.lastError != 0) {
6896 setMessage(noteReader.getErrorMessage());
6897 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6904 listManager.loadNoteTitleColors();
6906 refreshEvernoteNote(false);
6907 setMessage(tr("Notes have been imported."));
6910 setMessage(tr("Import completed."));
6917 //**************************************************
6918 //* Duplicate a note
6919 //**************************************************
6920 @SuppressWarnings("unused")
6921 private void duplicateNote() {
6923 duplicateNote(currentNoteGuid);
6926 //**************************************************
6927 //* Action from when a user clicks Copy As URL
6928 //**************************************************
6929 @SuppressWarnings("unused")
6930 private void copyAsUrlClicked() {
6931 QClipboard clipboard = QApplication.clipboard();
6932 QMimeData mime = new QMimeData();
6934 mime.setText(currentNoteGuid);
6935 List<QUrl> urls = new ArrayList<QUrl>();
6937 // Start building the URL
6938 User user = Global.getUserInformation();
6940 // Check that we have everything we need
6941 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
6942 SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
6944 if (!warning.neverSynchronize())
6947 Global.setBypassSynchronizationWarning(true);
6948 user.setShardId("s0");
6954 // Start building a list of URLs based upon the selected notes
6955 noteTableView.showColumn(Global.noteTableGuidPosition);
6957 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
6958 if (!Global.isColumnVisible("guid"))
6959 noteTableView.hideColumn(Global.noteTableGuidPosition);
6961 // Check that the note is either synchronized, or in a local notebook
6962 for (int i=0; i<selections.size(); i++) {
6964 int row = selections.get(i).row();
6965 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
6966 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
6967 String selectedGuid = (String)ix.values().toArray()[0];
6969 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
6970 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
6971 QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
6972 "new notes to a local notebook."));
6977 // Start building the URLs
6978 for (int i=0; i<selections.size(); i++) {
6980 int row = selections.get(i).row();
6981 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
6982 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
6983 String selectedGuid = (String)ix.values().toArray()[0];
6984 mime.setText(selectedGuid);
6988 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
6989 if (selectedNote.getUpdateSequenceNum() > 0) {
6993 gid = "00000000-0000-0000-0000-000000000000";
6996 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
6998 urls.add(new QUrl(url));
7001 clipboard.setMimeData(mime);
7005 //**************************************************
7007 //**************************************************
7008 public void setupFolderImports() {
7009 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
7011 if (importKeepWatcher == null)
7012 importKeepWatcher = new QFileSystemWatcher();
7013 if (importDeleteWatcher == null) {
7014 importDeleteWatcher = new QFileSystemWatcher();
7015 for (int i=0; i<records.size(); i++) {
7016 if (!records.get(i).keep)
7017 folderImportDelete(records.get(i).folder);
7023 // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
7024 for (int i=0; i<records.size(); i++) {
7025 logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
7026 if (records.get(i).keep)
7027 importKeepWatcher.addPath(records.get(i).folder);
7029 importDeleteWatcher.addPath(records.get(i).folder);
7032 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
7033 List<String> monitorDelete = importKeepWatcher.directories();
7034 for (int i=0; i<monitorDelete.size(); i++) {
7035 logger.log(logger.EXTREME, monitorDelete.get(i));
7037 logger.log(logger.EXTREME, "<end of list>");
7038 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
7039 monitorDelete = importDeleteWatcher.directories();
7040 for (int i=0; i<monitorDelete.size(); i++) {
7041 logger.log(logger.EXTREME, monitorDelete.get(i));
7043 logger.log(logger.EXTREME, "<end of list>");
7045 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
7046 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
7048 // Look at the files already there so we don't import them again if a new file is created
7049 if (importedFiles == null) {
7050 importedFiles = new ArrayList<String>();
7051 for (int j=0; j<records.size(); j++) {
7052 QDir dir = new QDir(records.get(j).folder);
7053 List<QFileInfo> list = dir.entryInfoList();
7054 for (int k=0; k<list.size(); k++) {
7055 if (list.get(k).isFile())
7056 importedFiles.add(list.get(k).absoluteFilePath());
7062 // Menu folderImport action triggered
7063 public void folderImport() {
7064 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
7065 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
7067 if (!dialog.okClicked())
7070 // We have some sort of update.
7071 if (importKeepWatcher.directories().size() > 0)
7072 importKeepWatcher.removePaths(importKeepWatcher.directories());
7073 if (importDeleteWatcher.directories().size() > 0)
7074 importDeleteWatcher.removePaths(importDeleteWatcher.directories());
7076 conn.getWatchFolderTable().expungeAll();
7077 // Start building from the table
7078 for (int i=0; i<dialog.table.rowCount(); i++) {
7079 QTableWidgetItem item = dialog.table.item(i, 0);
7080 String dir = item.text();
7081 item = dialog.table.item(i, 1);
7082 String notebook = item.text();
7083 item = dialog.table.item(i, 2);
7085 if (item.text().equalsIgnoreCase("Keep"))
7090 String guid = conn.getNotebookTable().findNotebookByName(notebook);
7091 conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
7093 setupFolderImports();
7097 public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
7098 logger.log(logger.LOW, "Inside folderImportKeep");
7099 String whichOS = System.getProperty("os.name");
7100 if (whichOS.contains("Windows"))
7101 dirName = dirName.replace('/','\\');
7103 FileImporter importer = new FileImporter(logger, conn);
7105 QDir dir = new QDir(dirName);
7106 List<QFileInfo> list = dir.entryInfoList();
7107 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7109 for (int i=0; i<list.size(); i++){
7110 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7111 boolean redundant = false;
7112 // Check if we've already imported this one or if it existed before
7113 for (int j=0; j<importedFiles.size(); j++) {
7114 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7115 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7119 logger.log(logger.LOW, "Checking if redundant: " +redundant);
7121 importer.setFileInfo(list.get(i));
7122 importer.setFileName(list.get(i).absoluteFilePath());
7125 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7126 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7127 if (list.get(i).isFile() && importer.isValidType()) {
7129 if (!importer.importFile()) {
7130 // If we can't get to the file, it is probably locked. We'll try again later.
7131 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7132 importFilesKeep.add(list.get(i).absoluteFilePath());
7135 Note newNote = importer.getNote();
7136 newNote.setNotebookGuid(notebook);
7137 newNote.setTitle(dir.at(i));
7138 NoteMetadata metadata = new NoteMetadata();
7139 metadata.setDirty(true);
7140 metadata.setGuid(newNote.getGuid());
7141 listManager.addNote(newNote, metadata);
7142 conn.getNoteTable().addNote(newNote, true);
7143 noteTableView.insertRow(newNote, metadata, true, -1);
7144 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7145 listManager.countNotebookResults(listManager.getNoteIndex());
7146 importedFiles.add(list.get(i).absoluteFilePath());
7155 public void folderImportDelete(String dirName) {
7156 logger.log(logger.LOW, "Inside folderImportDelete");
7157 String whichOS = System.getProperty("os.name");
7158 if (whichOS.contains("Windows"))
7159 dirName = dirName.replace('/','\\');
7161 FileImporter importer = new FileImporter(logger, conn);
7162 QDir dir = new QDir(dirName);
7163 List<QFileInfo> list = dir.entryInfoList();
7164 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7166 for (int i=0; i<list.size(); i++){
7167 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7168 importer.setFileInfo(list.get(i));
7169 importer.setFileName(list.get(i).absoluteFilePath());
7171 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7172 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7173 if (list.get(i).isFile() && importer.isValidType()) {
7175 if (!importer.importFile()) {
7176 // If we can't get to the file, it is probably locked. We'll try again later.
7177 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7178 importFilesKeep.add(list.get(i).absoluteFilePath());
7181 Note newNote = importer.getNote();
7182 newNote.setNotebookGuid(notebook);
7183 newNote.setTitle(dir.at(i));
7184 NoteMetadata metadata = new NoteMetadata();
7185 metadata.setDirty(true);
7186 metadata.setGuid(newNote.getGuid());
7187 listManager.addNote(newNote, metadata);
7188 conn.getNoteTable().addNote(newNote, true);
7189 noteTableView.insertRow(newNote, metadata, true, -1);
7190 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7191 listManager.countNotebookResults(listManager.getNoteIndex());
7192 dir.remove(dir.at(i));
7199 //**************************************************
7201 //**************************************************
7202 private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7203 logger.log(logger.HIGH, "Entering exernalFileEdited");
7205 // Strip URL prefix and base dir path
7206 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7207 String name = fileName.replace(dPath, "");
7208 int pos = name.lastIndexOf('.');
7211 guid = guid.substring(0,pos);
7213 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7215 guid = name.substring(0, pos);
7218 QFile file = new QFile(fileName);
7219 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
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 externalFiles.add(fileName);
7225 QByteArray binData = file.readAll();
7227 if (binData.size() == 0) {
7228 // If we can't get to the file, it is probably locked. We'll try again later.
7229 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7230 externalFiles.add(fileName);
7234 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7236 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7237 if (r == null || r.getData() == null || r.getData().getBody() == null)
7239 String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7240 MessageDigest md = MessageDigest.getInstance("MD5");
7241 md.update(binData.toByteArray());
7242 byte[] hash = md.digest();
7243 String newHash = Global.byteArrayToHexString(hash);
7244 if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7245 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7247 if (externalWindows.containsKey(r.getNoteGuid())) {
7248 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(),
7249 r.getGuid(), oldHash, newHash);
7251 conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7252 Data data = r.getData();
7253 data.setBody(binData.toByteArray());
7254 data.setBodyHash(hash);
7255 logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7257 conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7259 if (r.getNoteGuid().equals(currentNoteGuid)) {
7260 QWebSettings.setMaximumPagesInCache(0);
7261 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7262 refreshEvernoteNote(true);
7263 browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7266 if (externalWindows.containsKey(r.getNoteGuid())) {
7267 QWebSettings.setMaximumPagesInCache(0);
7268 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7269 externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7273 logger.log(logger.HIGH, "Exiting externalFielEdited");
7275 // This is a timer event that tries to save any external files that were edited. This
7276 // is only needed if we couldn't save a file earlier.
7277 public void externalFileEditedSaver() {
7278 for (int i=externalFiles.size()-1; i>=0; i--) {
7280 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7281 externalFileEdited(externalFiles.get(i));
7282 externalFiles.remove(i);
7283 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7285 for (int i=0; i<importFilesKeep.size(); i++) {
7287 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7288 folderImportKeep(importFilesKeep.get(i));
7289 importFilesKeep.remove(i);
7290 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7292 for (int i=0; i<importFilesDelete.size(); i++) {
7293 logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7294 folderImportDelete(importFilesDelete.get(i));
7295 importFilesDelete.remove(i);
7302 // If an attachment on the current note was edited, we need to update the current notes's hash
7303 // Update a note content's hash. This happens if a resource is edited outside of NN
7304 public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7305 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7307 for (;position>-1;) {
7308 endPos = browser.getContent().indexOf(">", position+1);
7309 String oldSegment = browser.getContent().substring(position,endPos);
7310 int hashPos = oldSegment.indexOf("hash=\"");
7311 int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7312 String hash = oldSegment.substring(hashPos+6, hashEnd);
7313 if (hash.equalsIgnoreCase(oldHash)) {
7314 String newSegment = oldSegment.replace(oldHash, newHash);
7315 String content = browser.getContent().substring(0,position) +
7317 browser.getContent().substring(endPos);
7318 browser.setContent(new QByteArray(content));;
7321 position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7326 //*************************************************
7327 //* Minimize to tray
7328 //*************************************************
7330 public void changeEvent(QEvent e) {
7331 if (e.type() == QEvent.Type.WindowStateChange) {
7332 if (QSystemTrayIcon.isSystemTrayAvailable()) {
7333 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7335 QTimer.singleShot(10, this, "hide()");
7339 windowMaximized = true;
7341 windowMaximized = false;
7346 //*************************************************
7347 //* Check database userid & passwords
7348 //*************************************************
7349 private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7350 Connection connection;
7353 Class.forName("org.h2.Driver");
7354 } catch (ClassNotFoundException e1) {
7355 e1.printStackTrace();
7360 String passwordString = null;
7361 if (cypherPassword==null || cypherPassword.trim().equals(""))
7362 passwordString = userPassword;
7364 passwordString = cypherPassword+" "+userPassword;
7365 connection = DriverManager.getConnection(url,userid,passwordString);
7366 } catch (SQLException e) {
7371 } catch (SQLException e) {
7372 e.printStackTrace();
7377 //*************************************************
7378 //* View / Hide source HTML for a note
7379 //*************************************************
7380 public void viewSource() {
7381 // ICHANGED すべてのタブに対して
7382 for(int i = 0; i < tabBrowser.count(); i++){
7383 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7384 browser.showSource(menuBar.viewSource.isChecked());
7387 //*************************************************
7388 // Block the program. This is used for things
7389 // like async web calls.
7390 //*************************************************
7391 @SuppressWarnings("unused")
7392 private void blockApplication(BrowserWindow b) {
7393 // Block all signals
7397 blockTimer = new QTimer();
7398 blockTimer.setSingleShot(true);
7399 blockTimer.setInterval(15000);
7400 blockTimer.timeout.connect(this, "unblockApplication()");
7405 @SuppressWarnings("unused")
7406 private void unblockApplication() {
7408 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7409 QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7410 blockingWindow.unblockTime = -1;
7411 blockingWindow.awaitingHttpResponse = false;
7413 blockingWindow = null;
7414 blockSignals(false);
7419 private void tabWindowChanged(int index) {
7420 if (index < 0 || index >= tabBrowser.count()) {
7426 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7427 if (tab.getBrowserWindow().getNote() != null) {
7428 currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7429 currentNote = tab.getBrowserWindow().getNote();
7431 currentNoteGuid = "";
7436 selectedNoteGUIDs.clear();
7437 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7438 selectedNoteGUIDs.add(currentNoteGuid);
7442 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7443 browserWindow.focusLost.disconnect(this, "saveNote()");
7444 browserWindow = tab.getBrowserWindow();
7445 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7446 browserWindow.focusLost.connect(this, "saveNote()");
7447 // メニューバーのボタンを新しいbrowserWindowに合わせる
7448 menuBar.refreshTargetWindow();
7450 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7451 boolean nextIsActive;
7452 if (tab.getBrowserWindow().getNote() != null) {
7453 nextIsActive = tab.getBrowserWindow().getNote().isActive();
7455 nextIsActive = true;
7457 if (Global.showDeleted && nextIsActive) {
7458 switchNoteTable(false);
7459 } else if (!Global.showDeleted && !nextIsActive) {
7460 switchNoteTable(true);
7463 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7464 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7465 scrollToGuid(currentNoteGuid);
7467 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7469 menuBar.noteDuplicateAction.setEnabled(true);
7470 menuBar.noteOnlineHistoryAction.setEnabled(true);
7471 menuBar.noteMergeAction.setEnabled(true);
7473 if (Global.showDeleted) {
7474 menuBar.noteDuplicateAction.setEnabled(false);
7476 if (!Global.isConnected) {
7477 menuBar.noteOnlineHistoryAction.setEnabled(false);
7479 menuBar.noteMergeAction.setEnabled(false);
7481 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7483 upButton.setEnabled(false);
7485 upButton.setEnabled(true);
7486 if (row < listManager.getNoteTableModel().rowCount() - 1)
7487 downButton.setEnabled(true);
7489 downButton.setEnabled(false);
7490 } catch (Exception e) {
7491 upButton.setEnabled(false);
7492 downButton.setEnabled(false);
7495 int currentIndex = tabBrowser.currentIndex();
7496 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7497 int histPosition = historyPosition.get(currentIndex);
7499 // prev, nextボタンの有効・無効化
7500 nextButton.setEnabled(true);
7501 prevButton.setEnabled(true);
7503 if (histPosition <= 1){
7504 prevButton.setEnabled(false);
7506 if (histPosition == histGuids.size()){
7507 nextButton.setEnabled(false);
7510 refreshEvernoteNote(true);
7513 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7517 // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7518 private void switchNoteTable(boolean toDeleted) {
7519 clearNotebookFilter();
7521 clearAttributeFilter();
7522 clearSavedSearchFilter();
7524 listManager.getSelectedNotebooks().clear();
7525 listManager.getSelectedTags().clear();
7526 listManager.setSelectedSavedSearch("");
7528 // toggle the add buttons
7529 newButton.setEnabled(!newButton.isEnabled());
7530 menuBar.noteAdd.setEnabled(newButton.isEnabled());
7531 menuBar.noteAdd.setVisible(true);
7533 if (!toDeleted) { // 生存ノートテーブルへ
7534 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7535 trashTree.clearSelection();
7536 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7537 Global.showDeleted = false;
7538 menuBar.noteRestoreAction.setEnabled(false);
7539 menuBar.noteRestoreAction.setVisible(false);
7540 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7541 rensoNoteListDock.setEnabled(true);
7543 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7544 trashTree.setCurrentItem(trashTree.getTrashItem());
7545 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7546 Global.showDeleted = true;
7547 menuBar.noteRestoreAction.setEnabled(true);
7548 menuBar.noteRestoreAction.setVisible(true);
7549 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
7550 rensoNoteListDock.setEnabled(false);
7553 listManager.loadNotesIndex();
7554 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7555 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7556 noteIndexUpdated(false);
7558 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7560 browserWindow.setReadOnly(!newButton.isEnabled());
7564 // ユーザが連想ノートリストのアイテムを選択した時の処理
7565 @SuppressWarnings("unused")
7566 private void rensoNoteItemPressed(QListWidgetItem current) {
7567 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7569 rensoNotePressedItemGuid = rensoNoteList.getNoteGuid(current);
7572 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7578 String prevCurrentNoteGuid = new String(currentNoteGuid);
7580 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
7581 QModelIndex modelIndex = noteTableView.model().index(i,
7582 Global.noteTableGuidPosition);
7583 if (modelIndex != null) {
7584 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
7586 String tableGuid = (String) ix.values().toArray()[0];
7587 if (tableGuid.equals(rensoNotePressedItemGuid)) {
7588 noteTableView.selectRow(i);
7594 // 連想ノートリストアイテムクリック操作を記録
7595 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7597 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7601 // 関連ノートリストからノートを除外する
7602 @SuppressWarnings("unused")
7603 private void excludeNote() {
7604 if (rensoNotePressedItemGuid != null) {
7606 excludeNote(rensoNotePressedItemGuid);
7611 // 関連ノートリストからノートを除外する
7612 private void excludeNote(String guid) {
7613 if (Global.verifyExclude()) {
7615 Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7616 String title = note.getTitle();
7617 if (title != null) {
7618 msg = new String(tr("Exclude note \"") +title +"\"?");
7620 msg = new String(tr("Exclude note selected note?"));
7623 if (QMessageBox.question(this, tr("Confirmation"), msg,
7624 QMessageBox.StandardButton.Yes,
7625 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7630 // Historyデータベースから除外するノートのデータを削除
7631 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7634 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7636 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7640 // 関連ノートリストのノートにスターを付ける
7641 @SuppressWarnings("unused")
7642 private void starNote() {
7643 if (rensoNotePressedItemGuid != null) {
7645 starNote(rensoNotePressedItemGuid);
7650 // 関連ノートリストのノートにスターを付ける
7651 private void starNote(String guid) {
7653 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7655 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7659 // 関連ノートリストのノートからスターを外す
7660 @SuppressWarnings("unused")
7661 private void unstarNote() {
7662 if (rensoNotePressedItemGuid != null) {
7664 unstarNote(rensoNotePressedItemGuid);
7669 // 関連ノートリストのノートからスターを外す
7670 private void unstarNote(String guid) {
7672 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7674 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7678 // currentNoteGuidを返す
7679 public String getCurrentNoteGuid() {
7680 return currentNoteGuid;
7683 @SuppressWarnings("unused")
7684 // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える
7685 private void tabIndexChanged(int from, int to) {
7687 TabBrowse tab = tabWindows.get(from);
7688 tabWindows.put(from, tabWindows.get(to));
7689 tabWindows.put(to, tab);
7691 boolean isNoteDirty = noteDirty.get(from);
7692 noteDirty.put(from, noteDirty.get(to));
7693 noteDirty.put(to, isNoteDirty);
7695 boolean isInkNote = inkNote.get(from);
7696 inkNote.put(from, inkNote.get(to));
7697 inkNote.put(to, isInkNote);
7699 boolean isReadOnly = readOnly.get(from);
7700 readOnly.put(from, readOnly.get(to));
7701 readOnly.put(to, isReadOnly);
7703 ArrayList<String> histGuids = historyGuids.get(from);
7704 historyGuids.put(from, historyGuids.get(to));
7705 historyGuids.put(to, histGuids);
7707 int histPosition = historyPosition.get(from);
7708 historyPosition.put(from, historyPosition.get(to));
7709 historyPosition.put(to, histPosition);
7711 boolean fromHist = fromHistory.get(from);
7712 fromHistory.put(from, fromHistory.get(to));
7713 fromHistory.put(to, fromHist);