2 * This file is part of NixNote
3 * Copyright 2009 Randy Baumgarte
5 * This file may be licensed under the terms of of the
6 * GNU General Public License Version 2 (the ``GPL'').
8 * Software distributed under the License is distributed
9 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
10 * express or implied. See the GPL for the specific language
11 * governing rights and limitations.
13 * You should have received a copy of the GPL along with this
14 * program. If not, go to http://www.gnu.org/licenses/gpl.html
15 * or write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 package cx.fbn.nevernote;
20 import java.awt.Desktop;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.net.Authenticator;
26 import java.net.PasswordAuthentication;
27 import java.security.MessageDigest;
28 import java.security.NoSuchAlgorithmException;
29 import java.sql.Connection;
30 import java.sql.DriverManager;
31 import java.sql.SQLException;
32 import java.sql.Statement;
33 import java.text.SimpleDateFormat;
34 import java.util.ArrayList;
35 import java.util.Calendar;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.Comparator;
39 import java.util.Date;
40 import java.util.GregorianCalendar;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.SortedMap;
45 import java.util.Vector;
47 import org.apache.log4j.Level;
48 import org.apache.log4j.Logger;
49 import org.apache.thrift.TException;
50 import org.h2.tools.ChangeFileEncryption;
52 import com.evernote.edam.error.EDAMNotFoundException;
53 import com.evernote.edam.error.EDAMSystemException;
54 import com.evernote.edam.error.EDAMUserException;
55 import com.evernote.edam.notestore.NoteFilter;
56 import com.evernote.edam.notestore.NoteVersionId;
57 import com.evernote.edam.type.Data;
58 import com.evernote.edam.type.LinkedNotebook;
59 import com.evernote.edam.type.Note;
60 import com.evernote.edam.type.NoteAttributes;
61 import com.evernote.edam.type.Notebook;
62 import com.evernote.edam.type.Publishing;
63 import com.evernote.edam.type.QueryFormat;
64 import com.evernote.edam.type.Resource;
65 import com.evernote.edam.type.SavedSearch;
66 import com.evernote.edam.type.Tag;
67 import com.evernote.edam.type.User;
68 import com.trolltech.qt.QThread;
69 import com.trolltech.qt.core.QByteArray;
70 import com.trolltech.qt.core.QDateTime;
71 import com.trolltech.qt.core.QDir;
72 import com.trolltech.qt.core.QEvent;
73 import com.trolltech.qt.core.QFile;
74 import com.trolltech.qt.core.QFileInfo;
75 import com.trolltech.qt.core.QFileSystemWatcher;
76 import com.trolltech.qt.core.QIODevice;
77 import com.trolltech.qt.core.QIODevice.OpenModeFlag;
78 import com.trolltech.qt.core.QLocale;
79 import com.trolltech.qt.core.QMimeData;
80 import com.trolltech.qt.core.QModelIndex;
81 import com.trolltech.qt.core.QSize;
82 import com.trolltech.qt.core.QTemporaryFile;
83 import com.trolltech.qt.core.QTextCodec;
84 import com.trolltech.qt.core.QThreadPool;
85 import com.trolltech.qt.core.QTimer;
86 import com.trolltech.qt.core.QTranslator;
87 import com.trolltech.qt.core.QUrl;
88 import com.trolltech.qt.core.Qt;
89 import com.trolltech.qt.core.Qt.BGMode;
90 import com.trolltech.qt.core.Qt.DockWidgetArea;
91 import com.trolltech.qt.core.Qt.ItemDataRole;
92 import com.trolltech.qt.core.Qt.KeyboardModifier;
93 import com.trolltech.qt.core.Qt.MouseButton;
94 import com.trolltech.qt.core.Qt.SortOrder;
95 import com.trolltech.qt.core.Qt.WidgetAttribute;
96 import com.trolltech.qt.gui.QAbstractItemView;
97 import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
98 import com.trolltech.qt.gui.QAction;
99 import com.trolltech.qt.gui.QApplication;
100 import com.trolltech.qt.gui.QClipboard;
101 import com.trolltech.qt.gui.QCloseEvent;
102 import com.trolltech.qt.gui.QColor;
103 import com.trolltech.qt.gui.QComboBox;
104 import com.trolltech.qt.gui.QCursor;
105 import com.trolltech.qt.gui.QDesktopServices;
106 import com.trolltech.qt.gui.QDialog;
107 import com.trolltech.qt.gui.QDockWidget;
108 import com.trolltech.qt.gui.QFileDialog;
109 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
110 import com.trolltech.qt.gui.QFileDialog.FileMode;
111 import com.trolltech.qt.gui.QGridLayout;
112 import com.trolltech.qt.gui.QHBoxLayout;
113 import com.trolltech.qt.gui.QIcon;
114 import com.trolltech.qt.gui.QImage;
115 import com.trolltech.qt.gui.QKeySequence;
116 import com.trolltech.qt.gui.QLabel;
117 import com.trolltech.qt.gui.QListWidgetItem;
118 import com.trolltech.qt.gui.QMainWindow;
119 import com.trolltech.qt.gui.QMenu;
120 import com.trolltech.qt.gui.QMessageBox;
121 import com.trolltech.qt.gui.QMessageBox.StandardButton;
122 import com.trolltech.qt.gui.QPainter;
123 import com.trolltech.qt.gui.QPalette.ColorRole;
124 import com.trolltech.qt.gui.QPixmap;
125 import com.trolltech.qt.gui.QPrintDialog;
126 import com.trolltech.qt.gui.QPrinter;
127 import com.trolltech.qt.gui.QShortcut;
128 import com.trolltech.qt.gui.QSizePolicy;
129 import com.trolltech.qt.gui.QSizePolicy.Policy;
130 import com.trolltech.qt.gui.QSpinBox;
131 import com.trolltech.qt.gui.QSplashScreen;
132 import com.trolltech.qt.gui.QSplitter;
133 import com.trolltech.qt.gui.QStatusBar;
134 import com.trolltech.qt.gui.QSystemTrayIcon;
135 import com.trolltech.qt.gui.QTableWidgetItem;
136 import com.trolltech.qt.gui.QTextEdit;
137 import com.trolltech.qt.gui.QToolBar;
138 import com.trolltech.qt.gui.QTreeWidgetItem;
139 import com.trolltech.qt.network.QNetworkAccessManager;
140 import com.trolltech.qt.network.QNetworkProxy;
141 import com.trolltech.qt.network.QNetworkProxy.ProxyType;
142 import com.trolltech.qt.network.QNetworkReply;
143 import com.trolltech.qt.network.QNetworkRequest;
144 import com.trolltech.qt.webkit.QWebPage.WebAction;
145 import com.trolltech.qt.webkit.QWebSettings;
147 import cx.fbn.nevernote.config.InitializationException;
148 import cx.fbn.nevernote.config.StartupConfig;
149 import cx.fbn.nevernote.dialog.AccountDialog;
150 import cx.fbn.nevernote.dialog.ConfigDialog;
151 import cx.fbn.nevernote.dialog.DBEncryptDialog;
152 import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
153 import cx.fbn.nevernote.dialog.DatabaseStatus;
154 import cx.fbn.nevernote.dialog.FindDialog;
155 import cx.fbn.nevernote.dialog.IgnoreSync;
156 import cx.fbn.nevernote.dialog.LogFileDialog;
157 import cx.fbn.nevernote.dialog.NotebookArchive;
158 import cx.fbn.nevernote.dialog.NotebookEdit;
159 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
160 import cx.fbn.nevernote.dialog.PublishNotebook;
161 import cx.fbn.nevernote.dialog.SavedSearchEdit;
162 import cx.fbn.nevernote.dialog.SetIcon;
163 import cx.fbn.nevernote.dialog.ShareNotebook;
164 import cx.fbn.nevernote.dialog.SharedNotebookSyncError;
165 import cx.fbn.nevernote.dialog.StackNotebook;
166 import cx.fbn.nevernote.dialog.SynchronizationRequiredWarning;
167 import cx.fbn.nevernote.dialog.TagEdit;
168 import cx.fbn.nevernote.dialog.TagMerge;
169 import cx.fbn.nevernote.dialog.ThumbnailViewer;
170 import cx.fbn.nevernote.dialog.UpgradeAvailableDialog;
171 import cx.fbn.nevernote.dialog.WatchFolder;
172 import cx.fbn.nevernote.evernote.NoteMetadata;
173 import cx.fbn.nevernote.filters.FilterEditorNotebooks;
174 import cx.fbn.nevernote.filters.FilterEditorTags;
175 import cx.fbn.nevernote.gui.AttributeTreeWidget;
176 import cx.fbn.nevernote.gui.BrowserWindow;
177 import cx.fbn.nevernote.gui.DateAttributeFilterTable;
178 import cx.fbn.nevernote.gui.ExternalBrowse;
179 import cx.fbn.nevernote.gui.MainMenuBar;
180 import cx.fbn.nevernote.gui.NotebookTreeWidget;
181 import cx.fbn.nevernote.gui.RensoNoteList;
182 import cx.fbn.nevernote.gui.SavedSearchTreeWidget;
183 import cx.fbn.nevernote.gui.SearchPanel;
184 import cx.fbn.nevernote.gui.TabBrowse;
185 import cx.fbn.nevernote.gui.TabBrowserWidget;
186 import cx.fbn.nevernote.gui.TableView;
187 import cx.fbn.nevernote.gui.TagTreeWidget;
188 import cx.fbn.nevernote.gui.Thumbnailer;
189 import cx.fbn.nevernote.gui.TrashTreeWidget;
190 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
191 import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
192 import cx.fbn.nevernote.oauth.OAuthTokenizer;
193 import cx.fbn.nevernote.oauth.OAuthWindow;
194 import cx.fbn.nevernote.sql.DatabaseConnection;
195 import cx.fbn.nevernote.sql.WatchFolderRecord;
196 import cx.fbn.nevernote.threads.IndexRunner;
197 import cx.fbn.nevernote.threads.SyncRunner;
198 import cx.fbn.nevernote.threads.ThumbnailRunner;
199 import cx.fbn.nevernote.utilities.AESEncrypter;
200 import cx.fbn.nevernote.utilities.ApplicationLogger;
201 import cx.fbn.nevernote.utilities.FileImporter;
202 import cx.fbn.nevernote.utilities.FileUtils;
203 import cx.fbn.nevernote.utilities.ListManager;
204 import cx.fbn.nevernote.utilities.SyncTimes;
205 import cx.fbn.nevernote.xml.ExportData;
206 import cx.fbn.nevernote.xml.ImportData;
207 import cx.fbn.nevernote.xml.ImportEnex;
208 import cx.fbn.nevernote.xml.NoteFormatter;
211 public class NeverNote extends QMainWindow{
213 QStatusBar statusBar; // Application status bar
215 DatabaseConnection conn;
217 MainMenuBar menuBar; // Main menu bar
218 FindDialog find; // Text search in note dialog
219 List<String> emitLog; // Messages displayed in the status bar;
220 QSystemTrayIcon trayIcon; // little tray icon
221 QMenu trayMenu; // System tray menu
222 QAction trayExitAction; // Exit the application
223 QAction trayShowAction; // toggle the show/hide action
224 QAction trayAddNoteAction; // Add a note from the system tray
225 QNetworkAccessManager versionChecker; // Used when checking for new versions
227 NotebookTreeWidget notebookTree; // List of notebooks
228 AttributeTreeWidget attributeTree; // List of note attributes
229 TagTreeWidget tagTree; // list of user created tags
230 SavedSearchTreeWidget savedSearchTree; // list of saved searches
231 TrashTreeWidget trashTree; // Trashcan
232 TableView noteTableView; // List of notes (the widget).
234 public BrowserWindow browserWindow; // Window containing browser & labels
235 public QToolBar toolBar; // The tool bar under the menu
236 QComboBox searchField; // search filter bar on the toolbar;
237 QShortcut searchShortcut; // Shortcut to search bar
238 boolean searchPerformed = false; // Search was done?
239 QuotaProgressBar quotaBar; // The current quota usage
241 ApplicationLogger logger;
242 List<String> selectedNotebookGUIDs; // List of notebook GUIDs
243 List<String> selectedTagGUIDs; // List of selected tag GUIDs
244 List<String> selectedNoteGUIDs; // List of selected notes
245 String selectedSavedSearchGUID; // Currently selected saved searches
246 private final HashMap<String, ExternalBrowse> externalWindows; // Notes being edited by an external window;
248 NoteFilter filter; // Note filter
249 String currentNoteGuid; // GUID of the current note
250 Note currentNote; // The currently viewed note
251 boolean noteDirty; // Has the note been changed?
252 boolean inkNote; // if this is an ink note, it is read only
253 boolean readOnly; // Is this note read-only?
256 ListManager listManager; // DB runnable task
258 List<QTemporaryFile> tempFiles; // Array of temporary files;
260 QTimer indexTimer; // timer to start the index thread
261 IndexRunner indexRunner; // thread to index notes
264 QTimer syncTimer; // Sync on an interval
265 QTimer syncDelayTimer; // Sync delay to free up database
266 SyncRunner syncRunner; // thread to do a sync.
267 QThread syncThread; // Thread which talks to evernote
268 ThumbnailRunner thumbnailRunner; // Runner for thumbnail thread
269 QThread thumbnailThread; // Thread that generates pretty pictures
270 QTimer saveTimer; // Timer to save note contents
272 QTimer authTimer; // Refresh authentication
273 QTimer externalFileSaveTimer; // Save files altered externally
274 QTimer thumbnailTimer; // Wakeup & scan for thumbnails
276 List<String> externalFiles; // External files to save later
277 List<String> importFilesKeep; // Auto-import files to save later
278 List<String> importFilesDelete; // Auto-import files to save later
280 int indexTime; // how often to try and index
281 boolean indexRunning; // Is indexing running?
282 boolean indexDisabled; // Is indexing disabled?
284 int syncThreadsReady; // number of sync threads that are free
285 int syncTime; // Sync interval
286 boolean syncRunning; // Is sync running?
287 boolean automaticSync; // do sync automatically?
288 QTreeWidgetItem attributeTreeSelected;
290 QAction prevButton; // Go to the previous item viewed
291 QAction nextButton; // Go to the next item in the history
292 QAction downButton; // Go to the next item in the list
293 QAction upButton; // Go to the prev. item in the list;
294 QAction synchronizeButton; // Synchronize with Evernote
295 QAction allNotesButton; // Reset & view all notes
296 QTimer synchronizeAnimationTimer; // Timer to change animation button
297 int synchronizeIconAngle; // Used to rotate sync icon
298 QAction printButton; // Print Button
299 QAction tagButton; // Tag edit button
300 QAction attributeButton; // Attribute information button
301 QAction emailButton; // Email button
302 QAction deleteButton; // Delete button
303 QAction newButton; // new Note Button;
304 QSpinBox zoomSpinner; // Zoom zoom
305 QAction searchClearButton; // Clear the search field
307 SearchPanel searchLayout; // Widget to hold search field, zoom, & quota
309 QSplitter mainLeftRightSplitter; // main splitter for left/right side
310 QSplitter leftSplitter1; // first left hand splitter
311 QSplitter browserIndexSplitter; // splitter between note index & note text
313 QFileSystemWatcher importKeepWatcher; // Watch & keep auto-import
314 QFileSystemWatcher importDeleteWatcher; // Watch & Delete auto-import
315 List<String> importedFiles; // History of imported files (so we don't import twice)
317 OnlineNoteHistory historyWindow; // online history window
318 List<NoteVersionId> versions; // history versions
320 QTimer threadMonitorTimer; // Timer to watch threads.
321 int dbThreadDeadCount=0; // number of consecutive dead times for the db thread
322 int syncThreadDeadCount=0; // number of consecutive dead times for the sync thread
323 int indexThreadDeadCount=0; // number of consecutive dead times for the index thread
324 int notebookThreadDeadCount=0; // number of consecutive dead times for the notebook thread
325 int tagDeadCount=0; // number of consecutive dead times for the tag thread
326 int trashDeadCount=0; // number of consecutive dead times for the trash thread
327 int saveThreadDeadCount=0; // number of consecutive dead times for the save thread
328 boolean disableTagThreadCheck=false;
329 boolean disableNotebookThreadCheck=false;
330 boolean disableTrashThreadCheck=false;
331 boolean disableSaveThreadCheck=false;
332 boolean disableSyncThreadCheck=false;
333 boolean disableIndexThreadCheck=false;
335 HashMap<String, String> noteCache; // Cash of note content
336 HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
337 HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
339 HashMap<Integer, ArrayList<String>> historyGuids; // タブごとの以前見たノートのGUID
340 HashMap<Integer, Integer> historyPosition; // Position within the viewed items
341 HashMap<Integer, Boolean> fromHistory; // Is this from the history queue?
343 String trashNoteGuid; // Guid to restore / set into or out of trash to save position
344 List<Thumbnailer> thumbGenerators; // generate preview image
345 ThumbnailViewer thumbnailViewer; // View preview thumbnail;
346 boolean encryptOnShutdown; // should I encrypt when I close?
347 boolean decryptOnShutdown; // should I decrypt on shutdown;
348 String encryptCipher; // What cipher should I use?
349 //Signal0 minimizeToTray;
350 boolean windowMaximized = false; // Keep track of the window state for restores
351 List<String> pdfReadyQueue; // Queue of PDFs that are ready to be rendered.
352 List<QPixmap> syncIcons; // Array of icons used in sync animation
353 private boolean closeAction = false; // Used to say when to close or when to minimize
354 private static Logger log = Logger.getLogger(NeverNote.class);
355 private String saveLastPath; // last path we used
356 private final QTimer messageTimer; // Timer to clear the status message.
357 private QTimer blockTimer;
358 BrowserWindow blockingWindow;
361 private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
362 private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
363 private final RensoNoteList rensoNoteList; // 連想ノートリスト
364 private final QDockWidget rensoNoteListDock; // 連想ノートリストドックウィジェット
367 ClipBoardObserver cbObserver;
370 String rensoNotePressedItemGuid;
372 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
375 //***************************************************************
376 //***************************************************************
377 //** Constructor & main entry point
378 //***************************************************************
379 //***************************************************************
380 // Application Constructor
381 @SuppressWarnings("static-access")
382 public NeverNote(DatabaseConnection dbConn) {
384 cbObserver = new ClipBoardObserver();
387 if (conn.getConnection() == null) {
388 String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
389 "is accessing the database or NeighborNote is already running.\n\n" +
390 "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
392 QMessageBox.critical(null, tr("Database Connection Error") ,msg);
395 setObjectName("mainWindow");
396 // thread().setPriority(Thread.MAX_PRIORITY);
398 logger = new ApplicationLogger("nevernote.log");
399 logger.log(logger.HIGH, "Starting Application");
401 decryptOnShutdown = false;
402 encryptOnShutdown = false;
403 conn.checkDatabaseVersion();
407 // Start building the invalid XML tables
408 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
409 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
411 for (int i=0; i<elements.size(); i++) {
412 Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
415 logger.log(logger.EXTREME, "Starting GUI build");
417 QTranslator nevernoteTranslator = new QTranslator();
418 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("nevernote_" + QLocale.system().name() + ".qm"));
419 QApplication.instance().installTranslator(nevernoteTranslator);
421 Global.originalPalette = QApplication.palette();
422 QApplication.setStyle(Global.getStyle());
423 if (Global.useStandardPalette())
424 QApplication.setPalette(QApplication.style().standardPalette());
425 setWindowTitle(tr("NeighborNote"));
427 mainLeftRightSplitter = new QSplitter();
429 mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
431 setCentralWidget(mainLeftRightSplitter);
432 leftSplitter1 = new QSplitter();
433 leftSplitter1.setOrientation(Qt.Orientation.Vertical);
435 browserIndexSplitter = new QSplitter();
436 browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
438 //* Setup threads & thread timers
439 // int indexRunnerCount = Global.getIndexThreads();
440 // indexRunnerCount = 1;
441 QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount); // increase max thread count
443 logger.log(logger.EXTREME, "Building list manager");
444 listManager = new ListManager(conn, logger);
446 logger.log(logger.EXTREME, "Building index runners & timers");
447 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
448 indexRunner = new IndexRunner("indexRunner.log",
449 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
450 Global.getResourceDatabaseUrl(),
451 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
452 Global.getDatabaseUserPassword(), Global.cipherPassword);
454 indexThread = new QThread(indexRunner, "Index Thread");
455 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
456 indexRunner.indexImageRecognition = Global.indexImageRecognition();
457 indexRunner.indexNoteBody = Global.indexNoteBody();
458 indexRunner.indexNoteTitle = Global.indexNoteTitle();
459 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
462 synchronizeAnimationTimer = new QTimer();
463 synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
465 indexTimer = new QTimer();
466 indexTime = 1000*Global.getIndexThreadSleepInterval();
467 indexTimer.start(indexTime); // Start indexing timer
468 indexTimer.timeout.connect(this, "indexTimer()");
469 indexDisabled = false;
470 indexRunning = false;
472 logger.log(logger.EXTREME, "Setting sync thread & timers");
474 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
475 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
476 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
477 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
478 Global.getDatabaseUserPassword(), Global.cipherPassword);
480 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
481 syncTimer = new QTimer();
482 syncTimer.timeout.connect(this, "syncTimer()");
483 syncRunner.status.message.connect(this, "setMessage(String)");
484 syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
485 syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
488 automaticSync = true;
489 syncTimer.start(syncTime*60*1000);
491 automaticSync = false;
494 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
495 syncThread = new QThread(syncRunner, "Synchronization Thread");
499 logger.log(logger.EXTREME, "Starting thumnail thread");
500 pdfReadyQueue = new ArrayList<String>();
501 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
502 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
503 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
504 Global.getResourceDatabaseUrl(),
505 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
506 Global.getDatabaseUserPassword(), Global.cipherPassword);
508 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
509 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
510 thumbnailThread.start();
511 thumbGenerators = new ArrayList<Thumbnailer>();
512 thumbnailTimer = new QTimer();
513 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
515 thumbnailTimer.setInterval(500*1000); // Thumbnail every minute
516 thumbnailTimer.start();
518 // debugTimer = new QTimer();
519 // debugTimer.timeout.connect(this, "debugDirty()");
520 // debugTimer.start(1000*60);
522 logger.log(logger.EXTREME, "Starting authentication timer");
523 authTimer = new QTimer();
524 authTimer.timeout.connect(this, "authTimer()");
525 authTimer.start(1000*60*15);
526 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
528 logger.log(logger.EXTREME, "Setting save note timer");
529 saveTimer = new QTimer();
530 saveTimer.timeout.connect(this, "saveNote()");
531 if (Global.getAutoSaveInterval() > 0) {
532 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
535 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
537 logger.log(logger.EXTREME, "Starting external file monitor timer");
538 externalFileSaveTimer = new QTimer();
539 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
540 externalFileSaveTimer.setInterval(1000*5); // save every 5 seconds;
541 externalFiles = new ArrayList<String>();
542 importFilesDelete = new ArrayList<String>();
543 importFilesKeep = new ArrayList<String>();
544 externalFileSaveTimer.start();
546 notebookTree = new NotebookTreeWidget(conn);
547 attributeTree = new AttributeTreeWidget();
548 tagTree = new TagTreeWidget(conn);
549 savedSearchTree = new SavedSearchTreeWidget();
550 trashTree = new TrashTreeWidget();
552 noteTableView = new TableView(logger, listManager, this);
554 searchField = new QComboBox();
555 searchField.setObjectName("searchField");
556 //setStyleSheet("QComboBox#searchField { background-color: yellow }");
557 searchField.setEditable(true);
558 searchField.activatedIndex.connect(this, "searchFieldChanged()");
559 searchField.setDuplicatesEnabled(false);
560 searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
561 searchShortcut = new QShortcut(this);
562 setupShortcut(searchShortcut, "Focus_Search");
563 searchShortcut.activated.connect(this, "focusSearch()");
565 quotaBar = new QuotaProgressBar();
567 zoomSpinner = new QSpinBox();
568 zoomSpinner.setMinimum(10);
569 zoomSpinner.setMaximum(1000);
570 zoomSpinner.setAccelerated(true);
571 zoomSpinner.setSingleStep(10);
572 zoomSpinner.setValue(100);
573 zoomSpinner.valueChanged.connect(this, "zoomChanged()");
575 searchLayout = new SearchPanel(searchField, quotaBar, notebookTree, zoomSpinner);
578 QGridLayout leftGrid = new QGridLayout();
579 leftSplitter1.setContentsMargins(5, 0, 0, 7);
580 leftSplitter1.setLayout(leftGrid);
581 leftGrid.addWidget(searchLayout,1,1);
582 leftGrid.addWidget(tagTree,2,1);
583 leftGrid.addWidget(attributeTree,3,1);
584 leftGrid.addWidget(savedSearchTree,4,1);
585 leftGrid.addWidget(trashTree,5, 1);
587 // Setup the browser window
588 noteCache = new HashMap<String,String>();
589 readOnlyCache = new HashMap<String, Boolean>();
590 inkNoteCache = new HashMap<String, Boolean>();
592 browserWindow = new BrowserWindow(conn, cbObserver);
594 // ICHANGED 下から移動してきた。
595 historyGuids = new HashMap<Integer, ArrayList<String>>();
596 historyPosition = new HashMap<Integer, Integer>();
597 fromHistory = new HashMap<Integer, Boolean>();
600 tabWindows = new HashMap<Integer, TabBrowse>();
601 tabBrowser = new TabBrowserWidget(this);
602 tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
603 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)");
613 historyGuids.put(index, new ArrayList<String>());
614 historyPosition.put(index, 0);
615 fromHistory.put(index, false);
617 mainLeftRightSplitter.addWidget(leftSplitter1);
618 mainLeftRightSplitter.addWidget(browserIndexSplitter);
622 rensoNoteList = new RensoNoteList(conn, this);
623 rensoNoteList.itemPressed.connect(this,
624 "rensoNoteItemPressed(QListWidgetItem)");
625 rensoNoteListDock = new QDockWidget(tr("Renso Note List"), this);
626 rensoNoteListDock.setWidget(rensoNoteList);
627 addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
629 if (Global.getListView() == Global.View_List_Wide) {
630 browserIndexSplitter.addWidget(noteTableView);
632 browserIndexSplitter.addWidget(tabBrowser);
633 // browserIndexSplitter.addWidget(browserWindow);
635 mainLeftRightSplitter.addWidget(noteTableView);
637 mainLeftRightSplitter.addWidget(tabBrowser);
638 // mainLeftRightSplitter.addWidget(browserWindow);
641 // Setup the thumbnail viewer
642 thumbnailViewer = new ThumbnailViewer();
643 thumbnailViewer.upArrow.connect(this, "upAction()");
644 thumbnailViewer.downArrow.connect(this, "downAction()");
645 thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
646 thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
648 //Setup external browser manager
649 externalWindows = new HashMap<String, ExternalBrowse>();
651 listManager.loadNotesIndex();
652 initializeNotebookTree();
654 initializeSavedSearchTree();
655 attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
656 attributeTreeSelected = null;
657 initializeNoteTable();
659 selectedNoteGUIDs = new ArrayList<String>();
660 statusBar = new QStatusBar();
661 setStatusBar(statusBar);
662 menuBar = new MainMenuBar(this);
663 emitLog = new ArrayList<String>();
665 tagTree.setDeleteAction(menuBar.tagDeleteAction);
666 tagTree.setMergeAction(menuBar.tagMergeAction);
667 tagTree.setEditAction(menuBar.tagEditAction);
668 tagTree.setAddAction(menuBar.tagAddAction);
669 tagTree.setIconAction(menuBar.tagIconAction);
670 tagTree.setVisible(Global.isWindowVisible("tagTree"));
671 leftSplitter1.setVisible(Global.isWindowVisible("leftPanel"));
672 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
673 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
674 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
676 if (!Global.isWindowVisible("zoom")) {
677 searchLayout.hideZoom();
678 menuBar.hideZoom.setChecked(false);
681 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
682 notebookTree.setEditAction(menuBar.notebookEditAction);
683 notebookTree.setAddAction(menuBar.notebookAddAction);
684 notebookTree.setIconAction(menuBar.notebookIconAction);
685 notebookTree.setStackAction(menuBar.notebookStackAction);
686 notebookTree.setPublishAction(menuBar.notebookPublishAction);
687 notebookTree.setShareAction(menuBar.notebookShareAction);
688 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
689 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
690 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
691 notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
692 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
694 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
695 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
696 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
697 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
698 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
699 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
700 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
702 // ICHANGED noteTableViewに新しいタブで開くを追加
703 noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
705 noteTableView.setAddAction(menuBar.noteAdd);
707 // ICHANGED noteTableViewに新しいタブでノート追加を追加
708 noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
710 noteTableView.setDeleteAction(menuBar.noteDelete);
711 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
712 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
713 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
714 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
715 noteTableView.noteSignal.notePinned.connect(this, "notePinned()");
716 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
717 noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction);
718 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
719 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
721 quotaBar.setMouseClickAction(menuBar.accountAction);
724 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
725 trashTree.setEmptyAction(menuBar.emptyTrashAction);
726 trashTree.setVisible(Global.isWindowVisible("trashTree"));
727 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
728 trashTree.updateCounts(listManager.getTrashCount());
729 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
730 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
732 noteTableView.setVisible(Global.isWindowVisible("noteList"));
733 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
735 if (!Global.isWindowVisible("editorButtonBar"))
736 toggleEditorButtonBar();
738 if (!Global.isWindowVisible("leftPanel"))
739 menuBar.hideLeftSide.setChecked(true);
740 if (Global.isWindowVisible("noteInformation"))
741 toggleNoteInformation();
742 quotaBar.setVisible(Global.isWindowVisible("quota"));
743 // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
744 // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
745 if (!Global.isWindowVisible("quota"))
746 menuBar.hideQuota.setChecked(false);
748 searchField.setVisible(Global.isWindowVisible("searchField"));
749 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
750 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
751 if (!Global.isWindowVisible("searchField"))
752 menuBar.hideSearch.setChecked(false);
754 if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
759 find = new FindDialog();
760 find.getOkButton().clicked.connect(this, "doFindText()");
762 // Setup the tray icon menu bar
763 trayShowAction = new QAction(tr("Show/Hide"), this);
764 trayExitAction = new QAction(tr("Exit"), this);
765 trayAddNoteAction = new QAction(tr("Add Note"), this);
767 trayExitAction.triggered.connect(this, "closeNeverNote()");
768 trayAddNoteAction.triggered.connect(this, "addNote()");
769 trayShowAction.triggered.connect(this, "trayToggleVisible()");
771 trayMenu = new QMenu(this);
772 trayMenu.addAction(trayAddNoteAction);
773 trayMenu.addAction(trayShowAction);
774 trayMenu.addAction(trayExitAction);
777 trayIcon = new QSystemTrayIcon(this);
778 trayIcon.setToolTip(tr("NeighborNote"));
779 trayIcon.setContextMenu(trayMenu);
780 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
783 currentNoteGuid = Global.getLastViewedNoteGuid();
784 if (currentNoteGuid.equals(""))
785 currentNote = new Note();
789 historyGuids = new ArrayList<String>();
795 if (!currentNoteGuid.trim().equals("")) {
796 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
799 noteIndexUpdated(true);
801 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
802 if (menuBar.showEditorBar.isChecked())
803 showEditorButtons(browserWindow);
804 tagIndexUpdated(true);
805 savedSearchIndexUpdated();
806 notebookIndexUpdated();
808 setupSyncSignalListeners();
809 setupBrowserSignalListeners();
810 setupIndexListeners();
813 tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
814 tagTree.showAllTags(true);
816 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
817 if (QSystemTrayIcon.isSystemTrayAvailable()) {
818 setWindowIcon(appIcon);
819 trayIcon.setIcon(appIcon);
820 if (Global.showTrayIcon() || Global.minimizeOnClose())
826 scrollToGuid(currentNoteGuid);
827 if (Global.automaticLogin()) {
829 if (Global.isConnected)
832 setupFolderImports();
835 restoreWindowState(true);
837 if (Global.mimicEvernoteInterface) {
838 notebookTree.selectGuid("");
841 threadMonitorTimer = new QTimer();
842 threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
843 threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
845 // ICHANGED たぶんこれはいらない
848 historyGuids.add(currentNoteGuid);
852 menuBar.blockSignals(true);
853 menuBar.narrowListView.blockSignals(true);
854 menuBar.wideListView.blockSignals(true);
855 if (Global.getListView() == Global.View_List_Narrow) {
856 menuBar.narrowListView.setChecked(true);
859 menuBar.wideListView.setChecked(true);
861 menuBar.blockSignals(false);
862 menuBar.narrowListView.blockSignals(false);
863 menuBar.wideListView.blockSignals(false);
866 // 上に同じコードがあるよね? とりあえずコメントアウト
868 * if (Global.getListView() == Global.View_List_Wide) {
869 * browserIndexSplitter.addWidget(noteTableView); // ICHANGED //
870 * browserIndexSplitter.addWidget(tabBrowser);
871 * browserIndexSplitter.addWidget(browserWindow); } else {
872 * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED //
873 * mainLeftRightSplitter.addWidget(tabBrowser);
874 * mainLeftRightSplitter.addWidget(browserWindow); }
877 messageTimer = new QTimer();
878 messageTimer.timeout.connect(this, "clearMessage()");
879 messageTimer.setInterval(1000*15);
882 int sortCol = Global.getSortColumn();
883 int sortOrder = Global.getSortOrder();
884 noteTableView.proxyModel.blocked = true;
885 // We sort the table twice to fix a bug. For some reaosn the table won't sort properly if it is in narrow
886 // list view and sorted descending on the date created. By sorting it twice it forces the proper sort. Ugly.
887 if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow)
888 noteTableView.sortByColumn(sortCol, SortOrder.resolve(0));
889 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
890 noteTableView.proxyModel.blocked = false;
891 noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)");
893 // Set the startup notebook
894 String defaultNotebook = Global.getStartupNotebook();
895 if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) {
896 for (int k=0; k<listManager.getNotebookIndex().size(); k++) {
897 if (listManager.getNotebookIndex().get(k).isDefaultNotebook()) {
898 notebookTree.clearSelection();
899 notebookTree.selectGuid(listManager.getNotebookIndex().get(k).getGuid());
900 notebookTree.selectionSignal.emit();
905 if (Global.checkVersionUpgrade()) {
906 // ICHANGED TODO とりあえず封印
907 // checkForUpdates();
912 public void debugDirty() {
913 List<Note> dirty = conn.getNoteTable().getDirty();
914 logger.log(logger.LOW, "------ Dirty Notes List Begin ------");
915 for (int i=0; i<dirty.size(); i++) {
916 logger.log(logger.LOW, "GUID: " +dirty.get(i).getGuid() + " Title:" + dirty.get(i).getTitle());
918 logger.log(logger.LOW, "------ Dirty Notes List End ------");
922 public static void main(String[] args) {
923 log.setLevel(Level.FATAL);
924 QApplication.initialize(args);
925 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
926 QSplashScreen splash = new QSplashScreen(pixmap);
929 DatabaseConnection dbConn;
932 initializeGlobalSettings(args);
934 showSplash = Global.isWindowVisible("SplashScreen");
938 dbConn = setupDatabaseConnection();
940 // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
941 Global.getFileManager().purgeResDirectory(true);
943 } catch (InitializationException e) {
946 QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
951 String proxyUrl = Global.getProxyValue("url");
952 String proxyPort = Global.getProxyValue("port");
953 String proxyUserid = Global.getProxyValue("userid");
954 String proxyPassword = Global.getProxyValue("password");
955 boolean proxySet = false;
956 QNetworkProxy proxy = new QNetworkProxy();
957 proxy.setType(ProxyType.HttpProxy);
958 if (!proxyUrl.trim().equals("")) {
959 System.out.println("Proxy URL found: " +proxyUrl);
961 proxy.setHostName(proxyUrl);
963 if (!proxyPort.trim().equals("")) {
964 System.out.println("Proxy Port found: " +proxyPort);
966 proxy.setPort(Integer.parseInt(proxyPort));
968 if (!proxyUserid.trim().equals("")) {
969 System.out.println("Proxy Userid found: " +proxyUserid);
971 proxy.setUser(proxyUserid);
973 if (!proxyPassword.trim().equals("")) {
974 System.out.println("Proxy URL found: " +proxyPassword);
976 proxy.setPassword(proxyPassword);
979 QNetworkProxy.setApplicationProxy(proxy);
983 NeverNote application = new NeverNote(dbConn);
984 if (Global.syncOnly) {
985 System.out.println("Performing synchronization only.");
986 application.remoteConnect();
987 if (Global.isConnected) {
988 application.syncRunner.syncNeeded = true;
989 application.syncRunner.addWork("SYNC");
990 application.syncRunner.addWork("STOP");
991 while(!application.syncRunner.isIdle());
992 application.closeNeverNote();
997 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
998 if (Global.startMinimized())
999 application.showMinimized();
1001 if (Global.wasWindowMaximized())
1002 application.showMaximized();
1008 splash.finish(application);
1009 QApplication.exec();
1010 System.out.println("Goodbye.");
1011 QApplication.exit();
1015 * Open the internal database, or create if not present
1017 * @throws InitializationException when opening the database fails, e.g. because another process has it locked
1019 private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
1020 ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
1022 File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
1023 File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
1024 // IFIXED resourceDatabaseNameになっていたので修正
1025 File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
1027 File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
1030 Global.setDatabaseUrl("");
1032 Global.setResourceDatabaseUrl("");
1034 Global.setIndexDatabaseUrl("");
1037 Global.setBehaviorDatabaseUrl("");
1039 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
1040 boolean goodCheck = false;
1041 while (!goodCheck) {
1042 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
1044 if (!dialog.okPressed())
1046 Global.cipherPassword = dialog.getPassword();
1047 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
1048 Global.getDatabaseUserPassword(), Global.cipherPassword);
1051 // ICHANGED Global.getBehaviorDatabaserUrl()を追加
1052 DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(),
1053 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
1054 Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
1058 // Encrypt the database upon shutdown
1059 private void encryptOnShutdown() {
1060 String dbPath= Global.getFileManager().getDbDirPath("");
1063 Statement st = conn.getConnection().createStatement();
1064 st.execute("shutdown");
1065 st = conn.getResourceConnection().createStatement();
1066 st.execute("shutdown");
1067 st = conn.getIndexConnection().createStatement();
1068 st.execute("shutdown");
1070 st = conn.getBehaviorConnection().createStatement();
1071 st.execute("shutdown");
1073 if (QMessageBox.question(this, tr("Are you sure"),
1074 tr("Are you sure you wish to encrypt the database?"),
1075 QMessageBox.StandardButton.Yes,
1076 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1077 ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1078 ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1079 ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1081 ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1083 Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
1084 Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
1085 Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
1087 Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
1089 QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
1091 } catch (SQLException e) {
1092 e.printStackTrace();
1096 // Decrypt the database upon shutdown
1097 private void decryptOnShutdown() {
1098 String dbPath= Global.getFileManager().getDbDirPath("");
1099 String dbName = "NeverNote";
1101 Statement st = conn.getConnection().createStatement();
1102 st.execute("shutdown");
1103 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
1104 encryptCipher = "AES";
1106 encryptCipher = "XTEA";
1107 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
1108 "Are you sure you wish to decrypt the database?"),
1109 QMessageBox.StandardButton.Yes,
1110 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1112 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
1113 Global.setDatabaseUrl("");
1114 Global.setResourceDatabaseUrl("");
1115 Global.setIndexDatabaseUrl("");
1116 QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
1118 } catch (SQLException e) {
1119 e.printStackTrace();
1123 * Encrypt/Decrypt the local database
1125 public void doDatabaseEncrypt() {
1126 // The database is not currently encrypted
1127 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
1128 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
1129 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
1130 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
1131 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
1132 "Do you wish to proceed?"),
1133 QMessageBox.StandardButton.Yes,
1134 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1137 DBEncryptDialog dialog = new DBEncryptDialog();
1139 if (dialog.okPressed()) {
1140 Global.cipherPassword = dialog.getPassword();
1141 encryptOnShutdown = true;
1142 encryptCipher = dialog.getEncryptionMethod();
1145 DBEncryptDialog dialog = new DBEncryptDialog();
1146 dialog.setWindowTitle(tr("Database Decryption"));
1147 dialog.hideEncryption();
1149 if (dialog.okPressed()) {
1150 if (!dialog.getPassword().equals(Global.cipherPassword)) {
1151 QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
1154 decryptOnShutdown = true;
1161 private static void initializeGlobalSettings(String[] args) throws InitializationException {
1162 StartupConfig startupConfig = new StartupConfig();
1164 for (String arg : args) {
1165 String lower = arg.toLowerCase();
1166 if (lower.startsWith("--name="))
1167 startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
1168 if (lower.startsWith("--home="))
1169 startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
1170 if (lower.startsWith("--disable-viewing"))
1171 startupConfig.setDisableViewing(true);
1172 if (lower.startsWith("--sync-only=true"))
1173 startupConfig.setSyncOnly(true);
1175 Global.setup(startupConfig);
1181 public void closeEvent(QCloseEvent event) {
1182 if (Global.minimizeOnClose() && !closeAction) {
1187 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
1190 if (currentNote != null & browserWindow != null) {
1191 if (currentNote.getTitle() != null && browserWindow != null
1192 && !currentNote.getTitle().equals(browserWindow.getTitle()))
1193 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
1194 browserWindow.getTitle());
1198 setMessage(tr("Beginning shutdown."));
1200 // Close down external windows
1201 Collection<ExternalBrowse> windows = externalWindows.values();
1202 Iterator<ExternalBrowse> iterator = windows.iterator();
1203 while (iterator.hasNext()) {
1204 ExternalBrowse browser = iterator.next();
1205 browser.windowClosing.disconnect();
1209 // ICHANGED タブブラウザに対してクローズ処理を行う
1210 Collection<TabBrowse> win = tabWindows.values();
1211 Iterator<TabBrowse> it = win.iterator();
1212 tabBrowser.currentChanged.disconnect();
1213 tabBrowser.tabCloseRequested.disconnect();
1214 while (it.hasNext()) {
1215 TabBrowse browser = it.next();
1219 externalFileEditedSaver();
1220 if (Global.isConnected && Global.synchronizeOnClose()) {
1221 setMessage(tr("Performing synchronization before closing."));
1222 syncRunner.syncNeeded = true;
1223 syncRunner.addWork("SYNC");
1225 syncRunner.keepRunning = false;
1227 syncRunner.addWork("STOP");
1228 setMessage("Closing Program.");
1229 threadMonitorTimer.stop();
1231 thumbnailRunner.addWork("STOP");
1232 indexRunner.addWork("STOP");
1237 if (tempFiles != null)
1240 browserWindow.noteSignal.tagsChanged.disconnect();
1241 browserWindow.noteSignal.titleChanged.disconnect();
1242 browserWindow.noteSignal.noteChanged.disconnect();
1243 browserWindow.noteSignal.notebookChanged.disconnect();
1244 browserWindow.noteSignal.createdDateChanged.disconnect();
1245 browserWindow.noteSignal.alteredDateChanged.disconnect();
1246 syncRunner.searchSignal.listChanged.disconnect();
1247 syncRunner.tagSignal.listChanged.disconnect();
1248 syncRunner.notebookSignal.listChanged.disconnect();
1249 syncRunner.noteIndexSignal.listChanged.disconnect();
1252 Global.saveWindowVisible("toolBar", toolBar.isVisible());
1253 saveNoteColumnPositions();
1254 saveNoteIndexWidth();
1256 int width = notebookTree.columnWidth(0);
1257 Global.setColumnWidth("notebookTreeName", width);
1258 width = tagTree.columnWidth(0);
1259 Global.setColumnWidth("tagTreeName", width);
1261 Global.saveWindowMaximized(isMaximized());
1262 Global.saveCurrentNoteGuid(currentNoteGuid);
1264 int sortCol = noteTableView.proxyModel.sortColumn();
1265 int sortOrder = noteTableView.proxyModel.sortOrder().value();
1266 Global.setSortColumn(sortCol);
1267 Global.setSortOrder(sortOrder);
1271 Global.keepRunning = false;
1273 logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
1274 if (indexRunner.thread().isAlive())
1275 indexRunner.thread().join(50);
1276 if (!indexRunner.thread().isAlive())
1277 logger.log(logger.MEDIUM, "Index thread has stopped");
1279 logger.log(logger.MEDIUM, "Index thread still running - interrupting");
1280 indexRunner.thread().interrupt();
1282 } catch (InterruptedException e1) {
1283 e1.printStackTrace();
1286 if (!syncRunner.thread().isAlive()) {
1287 logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
1288 if (syncRunner.thread().isAlive()) {
1289 System.out.println(tr("Synchronizing. Please be patient."));
1290 for(;syncRunner.thread().isAlive();) {
1293 } catch (InterruptedException e) {
1294 e.printStackTrace();
1298 logger.log(logger.MEDIUM, "Sync thread has stopped");
1301 if (encryptOnShutdown) {
1302 encryptOnShutdown();
1304 if (decryptOnShutdown) {
1305 decryptOnShutdown();
1308 Global.getFileManager().purgeResDirectory(false);
1309 } catch (InitializationException e) {
1310 System.out.println(tr("Empty res directory purge failed"));
1311 e.printStackTrace();
1313 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
1317 private void closeNeverNote() {
1321 public void setMessage(String s) {
1323 logger.log(logger.HIGH, "Entering NeverNote.setMessage");
1325 System.out.println("*** ERROR *** " +s);
1327 if (statusBar != null) {
1330 logger.log(logger.HIGH, "Message: " +s);
1331 statusBar.showMessage(s);
1332 if (emitLog != null)
1335 if (messageTimer != null) {
1336 messageTimer.stop();
1337 messageTimer.setSingleShot(true);
1338 messageTimer.start();
1343 logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
1346 private void clearMessage() {
1347 statusBar.clearMessage();
1351 private void waitCursor(boolean wait) {
1353 if (QApplication.overrideCursor() == null)
1354 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1357 if (QApplication.overrideCursor() != null)
1358 QApplication.restoreOverrideCursor();
1360 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.ArrowCursor));
1362 listManager.refreshCounters();
1365 private void setupIndexListeners() {
1366 // indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1367 // indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1368 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1369 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1371 private void setupSyncSignalListeners() {
1372 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1373 syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1374 syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1375 syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1376 syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1378 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1379 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1380 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1382 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1383 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1384 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1385 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1386 syncRunner.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1388 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1391 private void setupBrowserSignalListeners() {
1392 setupBrowserWindowListeners(browserWindow, true);
1395 private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1396 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1397 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1398 browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1399 if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1400 browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1401 browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1402 browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1403 browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1404 browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1405 browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1406 browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1407 browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1408 browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1409 browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1410 browser.blockApplication.connect(this, "blockApplication(BrowserWindow)");
1411 browser.unblockApplication.connect(this, "unblockApplication()");
1412 if (master) browser.focusLost.connect(this, "saveNote()");
1413 browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1414 browser.evernoteLinkClicked.connect(this, "evernoteLinkClick(String, String)");
1417 //**************************************************
1419 //**************************************************
1420 private void setupShortcut(QShortcut action, String text) {
1421 if (!Global.shortcutKeys.containsAction(text))
1423 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
1426 //***************************************************************
1427 //***************************************************************
1428 //* Settings and look & feel
1429 //***************************************************************
1430 //***************************************************************
1431 @SuppressWarnings("unused")
1432 private void settings() {
1433 logger.log(logger.HIGH, "Entering NeverNote.settings");
1435 saveNoteColumnPositions();
1436 saveNoteIndexWidth();
1438 ConfigDialog settings = new ConfigDialog(this);
1439 String dateFormat = Global.getDateFormat();
1440 String timeFormat = Global.getTimeFormat();
1442 indexTime = 1000*Global.getIndexThreadSleepInterval();
1443 indexTimer.start(indexTime); // reset indexing timer
1446 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1447 indexRunner.indexNoteBody = Global.indexNoteBody();
1448 indexRunner.indexNoteTitle = Global.indexNoteTitle();
1449 indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
1450 indexRunner.indexImageRecognition = Global.indexImageRecognition();
1451 if (Global.showTrayIcon() || Global.minimizeOnClose())
1456 if (menuBar.showEditorBar.isChecked()){
1458 for(int i = 0; i < tabBrowser.count(); i++){
1459 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
1460 showEditorButtons(browser);
1465 // Reset the save timer
1466 if (Global.getAutoSaveInterval() > 0)
1467 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1472 // Set special reloads
1473 if (settings.getDebugPage().reloadSharedNotebooksClicked()) {
1474 conn.executeSql("Delete from LinkedNotebook");
1475 conn.executeSql("delete from SharedNotebook");
1476 conn.executeSql("Delete from Notebook where linked=true");
1477 conn.executeSql("Insert into Sync (key, value) values ('FullLinkedNotebookSync', 'true')");
1478 conn.executeSql("Insert into Sync (key, value) values ('FullSharedNotebookSync', 'true')");
1483 readOnlyCache.clear();
1484 inkNoteCache.clear();
1485 noteIndexUpdated(true);
1487 logger.log(logger.HIGH, "Leaving NeverNote.settings");
1489 // Restore things to the way they were
1490 private void restoreWindowState(boolean mainWindow) {
1491 // We need to name things or this doesn't work.
1492 setObjectName("NeverNote");
1493 restoreState(Global.restoreState(objectName()));
1494 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1495 browserIndexSplitter.setObjectName("browserIndexSplitter");
1496 leftSplitter1.setObjectName("leftSplitter1");
1498 rensoNoteListDock.setObjectName("rensoNoteListDock");
1500 // Restore the actual positions.
1502 restoreGeometry(Global.restoreGeometry(objectName()));
1503 mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1504 browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1505 leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1507 rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
1510 // Save window positions for the next start
1511 private void saveWindowState() {
1512 Global.saveGeometry(objectName(), saveGeometry());
1513 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1514 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1515 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1516 Global.saveState(objectName(), saveState());
1518 Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
1520 // Load the style sheet
1521 private void loadStyleSheet() {
1522 String styleSheetName = "default.qss";
1523 if (Global.getStyle().equalsIgnoreCase("cleanlooks"))
1524 styleSheetName = "default-cleanlooks.qss";
1525 String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
1526 QFile file = new QFile(fileName);
1528 // If a user default.qss doesn't exist, we use the one shipped with NeverNote
1529 if (!file.exists()) {
1530 fileName = Global.getFileManager().getQssDirPath(styleSheetName);
1531 file = new QFile(fileName);
1533 file.open(OpenModeFlag.ReadOnly);
1534 String styleSheet = file.readAll().toString();
1536 setStyleSheet(styleSheet);
1538 // Save column positions for the next time
1539 private void saveNoteColumnPositions() {
1540 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1541 Global.setColumnPosition("noteTableCreationPosition", position);
1542 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1543 Global.setColumnPosition("noteTableTagPosition", position);
1544 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1545 Global.setColumnPosition("noteTableNotebookPosition", position);
1546 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1547 Global.setColumnPosition("noteTableChangedPosition", position);
1548 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1549 Global.setColumnPosition("noteTableAuthorPosition", position);
1550 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1551 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1552 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1553 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1554 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1555 Global.setColumnPosition("noteTableTitlePosition", position);
1556 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1557 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1558 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1559 Global.setColumnPosition("noteTableGuidPosition", position);
1560 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1561 Global.setColumnPosition("noteTableThumbnailPosition", position);
1562 position = noteTableView.header.visualIndex(Global.noteTablePinnedPosition);
1563 Global.setColumnPosition("noteTablePinnedPosition", position);
1566 // Save column widths for the next time
1567 private void saveNoteIndexWidth() {
1569 width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1570 Global.setColumnWidth("noteTableCreationPosition", width);
1571 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1572 Global.setColumnWidth("noteTableChangedPosition", width);
1573 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1574 Global.setColumnWidth("noteTableGuidPosition", width);
1575 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1576 Global.setColumnWidth("noteTableNotebookPosition", width);
1577 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1578 Global.setColumnWidth("noteTableTagPosition", width);
1579 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1580 Global.setColumnWidth("noteTableTitlePosition", width);
1581 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1582 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1583 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1584 Global.setColumnWidth("noteTableAuthorPosition", width);
1585 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1586 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1587 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1588 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1589 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1590 Global.setColumnWidth("noteTableThumbnailPosition", width);
1591 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1592 Global.setColumnWidth("noteTableGuidPosition", width);
1593 width = noteTableView.getColumnWidth(Global.noteTablePinnedPosition);
1594 Global.setColumnWidth("noteTablePinnedPosition", width);
1597 @SuppressWarnings("unused")
1598 private void toggleSearchWindow() {
1599 logger.log(logger.HIGH, "Entering NeverNote.toggleSearchWindow");
1600 searchLayout.toggleSearchField();
1601 menuBar.hideSearch.setChecked(searchField.isVisible());
1602 Global.saveWindowVisible("searchField", searchField.isVisible());
1603 logger.log(logger.HIGH, "Leaving NeverNote.toggleSearchWindow");
1605 @SuppressWarnings("unused")
1606 private void toggleQuotaWindow() {
1607 logger.log(logger.HIGH, "Entering NeverNote.toggleQuotaWindow");
1608 searchLayout.toggleQuotaBar();
1609 menuBar.hideQuota.setChecked(quotaBar.isVisible());
1610 Global.saveWindowVisible("quota", quotaBar.isVisible());
1611 logger.log(logger.HIGH, "Leaving NeverNote.toggleQuotaWindow");
1613 @SuppressWarnings("unused")
1614 private void toggleZoomWindow() {
1615 logger.log(logger.HIGH, "Entering NeverNote.toggleZoomWindow");
1616 searchLayout.toggleZoom();
1617 menuBar.hideZoom.setChecked(zoomSpinner.isVisible());
1618 Global.saveWindowVisible("zoom", zoomSpinner.isVisible());
1619 logger.log(logger.HIGH, "Leaving NeverNote.toggleZoomWindow");
1624 //***************************************************************
1625 //***************************************************************
1626 //** These functions deal with Notebook menu items
1627 //***************************************************************
1628 //***************************************************************
1629 // Setup the tree containing the user's notebooks.
1630 private void initializeNotebookTree() {
1631 logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1632 // notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1633 notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
1634 listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1635 logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1637 // Listener when a notebook is selected
1638 private void notebookTreeSelection() {
1639 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1640 noteTableView.proxyModel.blocked = true;
1643 clearAttributeFilter();
1644 clearSavedSearchFilter();
1645 if (Global.mimicEvernoteInterface) {
1647 //searchField.clear();
1648 searchField.clearEditText();
1650 menuBar.noteRestoreAction.setVisible(false);
1651 menuBar.notebookEditAction.setEnabled(true);
1652 menuBar.notebookDeleteAction.setEnabled(true);
1653 menuBar.notebookPublishAction.setEnabled(true);
1654 menuBar.notebookShareAction.setEnabled(true);
1655 menuBar.notebookIconAction.setEnabled(true);
1656 menuBar.notebookStackAction.setEnabled(true);
1658 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
1659 if (!rensoNoteListDock.isEnabled()) {
1660 rensoNoteListDock.setEnabled(true);
1663 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1664 selectedNotebookGUIDs.clear();
1666 String stackName = "";
1667 if (selections.size() > 0) {
1668 guid = (selections.get(0).text(2));
1669 stackName = selections.get(0).text(0);
1671 if (!Global.mimicEvernoteInterface) {
1672 // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1673 if (selections.size()==0) {
1674 selectedNotebookGUIDs.clear();
1675 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1676 selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1678 menuBar.notebookEditAction.setEnabled(false);
1679 menuBar.notebookDeleteAction.setEnabled(false);
1680 menuBar.notebookStackAction.setEnabled(false);
1681 menuBar.notebookIconAction.setEnabled(false);
1684 if (!guid.equals("") && !guid.equals("STACK")) {
1685 selectedNotebookGUIDs.add(guid);
1686 menuBar.notebookIconAction.setEnabled(true);
1688 menuBar.notebookIconAction.setEnabled(true);
1689 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1690 Notebook book = listManager.getNotebookIndex().get(j);
1691 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1692 selectedNotebookGUIDs.add(book.getGuid());
1695 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1696 listManager.loadNotesIndex();
1697 noteIndexUpdated(false);
1698 refreshEvernoteNote(true);
1699 listManager.refreshCounters = true;
1700 listManager.refreshCounters();
1701 if (selectedNotebookGUIDs.size() == 1) {
1702 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1703 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1705 noteTableView.proxyModel.blocked = true;
1707 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1709 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1712 noteTableView.proxyModel.blocked = false;
1713 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1716 private void clearNotebookFilter() {
1717 notebookTree.blockSignals(true);
1718 notebookTree.clearSelection();
1719 menuBar.noteRestoreAction.setVisible(false);
1720 menuBar.notebookEditAction.setEnabled(false);
1721 menuBar.notebookDeleteAction.setEnabled(false);
1722 selectedNotebookGUIDs.clear();
1723 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1724 notebookTree.blockSignals(false);
1726 // Triggered when the notebook DB has been updated
1727 private void notebookIndexUpdated() {
1728 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1730 // Get the possible icons
1731 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1732 notebookTree.setIcons(icons);
1734 if (selectedNotebookGUIDs == null)
1735 selectedNotebookGUIDs = new ArrayList<String>();
1736 List<Notebook> books = conn.getNotebookTable().getAll();
1737 for (int i=books.size()-1; i>=0; i--) {
1738 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1739 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1741 j=listManager.getArchiveNotebookIndex().size();
1747 listManager.countNotebookResults(listManager.getNoteIndex());
1748 notebookTree.blockSignals(true);
1749 notebookTree.load(books, listManager.getLocalNotebooks());
1750 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1751 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1753 selectedNotebookGUIDs.remove(i);
1755 listManager.refreshCounters = true;
1756 listManager.refreshCounters();
1757 notebookTree.blockSignals(false);
1759 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1761 // Show/Hide note information
1762 @SuppressWarnings("unused")
1763 private void toggleNotebookWindow() {
1764 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1765 searchLayout.toggleNotebook();
1766 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1767 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1768 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1770 // Add a new notebook
1771 @SuppressWarnings("unused")
1772 private void addNotebook() {
1773 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1774 NotebookEdit edit = new NotebookEdit();
1775 edit.setNotebooks(listManager.getNotebookIndex());
1778 if (!edit.okPressed())
1781 Calendar currentTime = new GregorianCalendar();
1782 Long l = new Long(currentTime.getTimeInMillis());
1783 String randint = new String(Long.toString(l));
1785 Notebook newBook = new Notebook();
1786 newBook.setUpdateSequenceNum(0);
1787 newBook.setGuid(randint);
1788 newBook.setName(edit.getNotebook());
1789 newBook.setServiceCreated(new Date().getTime());
1790 newBook.setServiceUpdated(new Date().getTime());
1791 newBook.setDefaultNotebook(false);
1792 newBook.setPublished(false);
1794 listManager.getNotebookIndex().add(newBook);
1796 listManager.getLocalNotebooks().add(newBook.getGuid());
1797 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1798 notebookIndexUpdated();
1799 listManager.countNotebookResults(listManager.getNoteIndex());
1800 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1801 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1803 // Edit an existing notebook
1804 @SuppressWarnings("unused")
1805 private void stackNotebook() {
1806 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1807 StackNotebook edit = new StackNotebook();
1809 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1810 QTreeWidgetItem currentSelection;
1811 for (int i=0; i<selections.size(); i++) {
1812 currentSelection = selections.get(0);
1813 String guid = currentSelection.text(2);
1814 if (guid.equalsIgnoreCase("")) {
1815 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1818 if (guid.equalsIgnoreCase("STACK")) {
1819 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1824 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1829 if (!edit.okPressed())
1832 String stack = edit.getStackName();
1834 for (int i=0; i<selections.size(); i++) {
1835 currentSelection = selections.get(i);
1836 String guid = currentSelection.text(2);
1837 listManager.updateNotebookStack(guid, stack);
1839 notebookIndexUpdated();
1840 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1842 // Edit an existing notebook
1843 @SuppressWarnings("unused")
1844 private void editNotebook() {
1845 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1846 NotebookEdit edit = new NotebookEdit();
1848 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1849 QTreeWidgetItem currentSelection;
1850 currentSelection = selections.get(0);
1851 edit.setNotebook(currentSelection.text(0));
1853 String guid = currentSelection.text(2);
1854 if (!guid.equalsIgnoreCase("STACK")) {
1855 edit.setTitle(tr("Edit Notebook"));
1856 edit.setNotebooks(listManager.getNotebookIndex());
1857 edit.setLocalCheckboxEnabled(false);
1858 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1859 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1860 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1861 i=listManager.getNotebookIndex().size();
1865 edit.setTitle(tr("Edit Stack"));
1866 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1867 edit.hideLocalCheckbox();
1868 edit.hideDefaultCheckbox();
1873 if (!edit.okPressed())
1877 if (guid.equalsIgnoreCase("STACK")) {
1878 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1879 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1880 if (listManager.getNotebookIndex().get(j).getStack() != null &&
1881 listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1882 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1884 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1885 currentSelection.setText(0, edit.getNotebook());
1889 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1890 currentSelection.setText(0, edit.getNotebook());
1892 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1893 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1894 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1895 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1896 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1897 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1898 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1899 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1901 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1902 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1903 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1904 linkedNotebook.setShareName(edit.getNotebook());
1905 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1907 i=listManager.getNotebookIndex().size();
1911 // Build a list of non-closed notebooks
1912 List<Notebook> nbooks = new ArrayList<Notebook>();
1913 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1914 boolean found=false;
1915 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1916 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1920 nbooks.add(listManager.getNotebookIndex().get(i));
1924 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1925 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1926 browserWindow.setNotebookList(filteredBooks);
1927 Iterator<String> set = externalWindows.keySet().iterator();
1928 while(set.hasNext())
1929 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1932 Iterator<Integer>it = tabWindows.keySet().iterator();
1933 while (it.hasNext()) {
1934 tabWindows.get(it.next()).getBrowserWindow()
1935 .setNotebookList(filteredBooks);
1938 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1940 // Publish a notebook
1941 @SuppressWarnings("unused")
1942 private void publishNotebook() {
1943 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1944 QTreeWidgetItem currentSelection;
1945 currentSelection = selections.get(0);
1946 String guid = currentSelection.text(2);
1948 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1953 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1954 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1955 n = listManager.getNotebookIndex().get(i);
1957 i = listManager.getNotebookIndex().size();
1963 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1966 if (!publish.okClicked())
1969 Publishing p = publish.getPublishing();
1970 boolean isPublished = !publish.isStopPressed();
1971 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1972 n.setPublished(isPublished);
1974 listManager.getNotebookIndex().set(position, n);
1975 notebookIndexUpdated();
1977 // Publish a notebook
1978 @SuppressWarnings("unused")
1979 private void shareNotebook() {
1980 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1981 QTreeWidgetItem currentSelection;
1982 currentSelection = selections.get(0);
1983 String guid = currentSelection.text(2);
1985 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1989 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1990 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1991 n = listManager.getNotebookIndex().get(i);
1992 i = listManager.getNotebookIndex().size();
1996 String authToken = null;
1997 if (syncRunner.isConnected)
1998 authToken = syncRunner.authToken;
1999 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
2004 // Delete an existing notebook
2005 @SuppressWarnings("unused")
2006 private void deleteNotebook() {
2007 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2008 boolean stacksFound = false;
2009 boolean notebooksFound = false;
2010 boolean assigned = false;
2011 // Check if any notes have this notebook
2012 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2013 for (int i=0; i<selections.size(); i++) {
2014 QTreeWidgetItem currentSelection;
2015 currentSelection = selections.get(i);
2016 String guid = currentSelection.text(2);
2017 if (!guid.equalsIgnoreCase("STACK")) {
2018 notebooksFound = true;
2019 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
2020 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
2021 if (noteGuid.equals(guid)) {
2023 j=listManager.getNoteIndex().size();
2024 i=selections.size();
2032 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2033 "Please delete the notes or move them to another notebook before deleting any notebooks."));
2037 if (conn.getNotebookTable().getAll().size() == 1) {
2038 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2042 // If all notebooks are clear, verify the delete
2043 String msg1 = new String(tr("Delete selected notebooks?"));
2044 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2045 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2046 " not deleted unless selected?"));
2048 if (stacksFound && notebooksFound)
2050 if (!stacksFound && notebooksFound)
2052 if (stacksFound && !notebooksFound)
2054 if (QMessageBox.question(this, tr("Confirmation"), msg,
2055 QMessageBox.StandardButton.Yes,
2056 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2060 // If confirmed, delete the notebook
2061 for (int i=selections.size()-1; i>=0; i--) {
2062 QTreeWidgetItem currentSelection;
2063 currentSelection = selections.get(i);
2064 String guid = currentSelection.text(2);
2065 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2066 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2067 listManager.renameStack(currentSelection.text(0), "");
2069 conn.getNotebookTable().expungeNotebook(guid, true);
2070 listManager.deleteNotebook(guid);
2074 notebookIndexUpdated();
2075 // notebookTreeSelection();
2076 // notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2077 // listManager.countNotebookResults(listManager.getNoteIndex());
2078 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2080 // A note's notebook has been updated
2081 @SuppressWarnings("unused")
2082 private void updateNoteNotebook(String guid, String notebookGuid) {
2083 // ICHANGED 同じノートブックに入れられたノート間の履歴を登録
2084 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2086 // Update the list manager
2087 listManager.updateNoteNotebook(guid, notebookGuid);
2088 listManager.countNotebookResults(listManager.getNoteIndex());
2089 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
2091 // Find the name of the notebook
2092 String notebookName = null;
2093 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2094 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2095 notebookName = listManager.getNotebookIndex().get(i).getName();
2100 // If we found the name, update the browser window
2101 if (notebookName != null) {
2102 updateListNoteNotebook(guid, notebookName);
2103 if (guid.equals(currentNoteGuid)) {
2104 int pos = browserWindow.notebookBox.findText(notebookName);
2106 browserWindow.notebookBox.setCurrentIndex(pos);
2110 // If we're dealing with the current note, then we need to be sure and update the notebook there
2111 if (guid.equals(currentNoteGuid)) {
2112 if (currentNote != null) {
2113 currentNote.setNotebookGuid(notebookGuid);
2117 // Open/close notebooks
2118 @SuppressWarnings("unused")
2119 private void closeNotebooks() {
2120 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2122 if (!na.okClicked())
2126 listManager.getArchiveNotebookIndex().clear();
2128 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2129 String text = na.getClosedBookList().takeItem(i).text();
2130 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2131 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2132 Notebook n = listManager.getNotebookIndex().get(j);
2133 conn.getNotebookTable().setArchived(n.getGuid(),true);
2134 listManager.getArchiveNotebookIndex().add(n);
2135 j=listManager.getNotebookIndex().size();
2140 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2141 String text = na.getOpenBookList().takeItem(i).text();
2142 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2143 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2144 Notebook n = listManager.getNotebookIndex().get(j);
2145 conn.getNotebookTable().setArchived(n.getGuid(),false);
2146 j=listManager.getNotebookIndex().size();
2150 notebookTreeSelection();
2151 listManager.loadNotesIndex();
2152 notebookIndexUpdated();
2153 noteIndexUpdated(false);
2154 reloadTagTree(true);
2155 // noteIndexUpdated(false);
2157 // Build a list of non-closed notebooks
2158 List<Notebook> nbooks = new ArrayList<Notebook>();
2159 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2160 boolean found=false;
2161 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2162 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2166 nbooks.add(listManager.getNotebookIndex().get(i));
2169 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2170 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2171 browserWindow.setNotebookList(filteredBooks);
2173 // Update any external windows
2174 Iterator<String> set = externalWindows.keySet().iterator();
2175 while(set.hasNext())
2176 externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2180 Iterator<Integer> it = tabWindows.keySet().iterator();
2181 while (it.hasNext()) {
2182 tabWindows.get(it.next()).getBrowserWindow()
2183 .setNotebookList(filteredBooks);
2188 // Change the notebook's icon
2189 @SuppressWarnings("unused")
2190 private void setNotebookIcon() {
2191 boolean stackSelected = false;
2192 boolean allNotebookSelected = false;
2194 QTreeWidgetItem currentSelection;
2195 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2196 if (selections.size() == 0)
2199 currentSelection = selections.get(0);
2200 String guid = currentSelection.text(2);
2201 if (guid.equalsIgnoreCase(""))
2202 allNotebookSelected = true;
2203 if (guid.equalsIgnoreCase("STACK"))
2204 stackSelected = true;
2206 QIcon currentIcon = currentSelection.icon(0);
2210 if (!stackSelected && !allNotebookSelected) {
2211 icon = conn.getNotebookTable().getIcon(guid);
2213 dialog = new SetIcon(currentIcon, saveLastPath);
2214 dialog.setUseDefaultIcon(true);
2216 dialog = new SetIcon(icon, saveLastPath);
2217 dialog.setUseDefaultIcon(false);
2220 if (stackSelected) {
2221 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2223 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
2226 dialog = new SetIcon(currentIcon, saveLastPath);
2227 dialog.setUseDefaultIcon(true);
2229 dialog = new SetIcon(icon, saveLastPath);
2230 dialog.setUseDefaultIcon(false);
2234 if (dialog.okPressed()) {
2235 saveLastPath = dialog.getPath();
2237 QIcon newIcon = dialog.getIcon();
2238 if (stackSelected) {
2239 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2240 if (newIcon == null) {
2241 newIcon = new QIcon(iconPath+"books2.png");
2243 currentSelection.setIcon(0,newIcon);
2246 if (allNotebookSelected) {
2247 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2248 if (newIcon == null) {
2249 newIcon = new QIcon(iconPath+"notebook-green.png");
2251 currentSelection.setIcon(0,newIcon);
2254 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2255 if (newIcon == null) {
2256 boolean isPublished = false;;
2257 boolean found = false;
2258 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2259 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2260 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2264 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2266 currentSelection.setIcon(0, newIcon);
2272 //***************************************************************
2273 //***************************************************************
2274 //** These functions deal with Tag menu items
2275 //***************************************************************
2276 //***************************************************************
2277 // Add a new notebook
2278 @SuppressWarnings("unused")
2279 private void addTag() {
2280 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2281 TagEdit edit = new TagEdit();
2282 edit.setTagList(listManager.getTagIndex());
2284 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2285 QTreeWidgetItem currentSelection = null;
2286 if (selections.size() > 0) {
2287 currentSelection = selections.get(0);
2288 edit.setParentTag(currentSelection.text(0));
2293 if (!edit.okPressed())
2296 Calendar currentTime = new GregorianCalendar();
2297 Long l = new Long(currentTime.getTimeInMillis());
2298 String randint = new String(Long.toString(l));
2300 Tag newTag = new Tag();
2301 newTag.setUpdateSequenceNum(0);
2302 newTag.setGuid(randint);
2303 newTag.setName(edit.getTag());
2304 if (edit.getParentTag().isChecked()) {
2305 newTag.setParentGuid(currentSelection.text(2));
2306 newTag.setParentGuidIsSet(true);
2307 currentSelection.setExpanded(true);
2309 conn.getTagTable().addTag(newTag, true);
2310 listManager.getTagIndex().add(newTag);
2311 reloadTagTree(true);
2313 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2315 @SuppressWarnings("unused")
2316 private void reloadTagTree() {
2317 reloadTagTree(false);
2319 private void reloadTagTree(boolean reload) {
2320 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2321 tagIndexUpdated(reload);
2322 boolean filter = false;
2324 listManager.countTagResults(listManager.getNoteIndex());
2325 if (notebookTree.selectedItems().size() > 0
2326 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2328 if (tagTree.selectedItems().size() > 0)
2330 tagTree.showAllTags(!filter);
2331 tagIndexUpdated(false);
2332 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2334 // Edit an existing tag
2335 @SuppressWarnings("unused")
2336 private void editTag() {
2337 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2338 TagEdit edit = new TagEdit();
2339 edit.setTitle("Edit Tag");
2340 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2341 QTreeWidgetItem currentSelection;
2342 currentSelection = selections.get(0);
2343 edit.setTag(currentSelection.text(0));
2344 edit.setTagList(listManager.getTagIndex());
2347 if (!edit.okPressed())
2350 String guid = currentSelection.text(2);
2351 currentSelection.setText(0,edit.getTag());
2353 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2354 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2355 listManager.getTagIndex().get(i).setName(edit.getTag());
2356 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2357 updateListTagName(guid);
2358 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2359 browserWindow.setTag(getTagNamesForNote(currentNote));
2360 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2364 listManager.reloadNoteTagNames(guid, edit.getTag());
2365 noteIndexUpdated(true);
2366 refreshEvernoteNote(true);
2367 browserWindow.setTag(getTagNamesForNote(currentNote));
2368 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2370 // Delete an existing tag
2371 @SuppressWarnings("unused")
2372 private void deleteTag() {
2373 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2375 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2376 QMessageBox.StandardButton.Yes,
2377 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2381 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2382 for (int i=selections.size()-1; i>=0; i--) {
2383 QTreeWidgetItem currentSelection;
2384 currentSelection = selections.get(i);
2385 removeTagItem(currentSelection.text(2));
2387 tagIndexUpdated(true);
2389 listManager.countTagResults(listManager.getNoteIndex());
2390 // tagTree.updateCounts(listManager.getTagCounter());
2391 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2393 // Remove a tag tree item. Go recursively down & remove the children too
2394 private void removeTagItem(String guid) {
2395 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
2396 String parent = listManager.getTagIndex().get(j).getParentGuid();
2397 if (parent != null && parent.equals(guid)) {
2398 //Remove this tag's children
2399 removeTagItem(listManager.getTagIndex().get(j).getGuid());
2402 //Now, remove this tag
2403 removeListTagName(guid);
2404 conn.getTagTable().expungeTag(guid, true);
2405 for (int a=0; a<listManager.getTagIndex().size(); a++) {
2406 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2407 listManager.getTagIndex().remove(a);
2412 // Setup the tree containing the user's tags
2413 private void initializeTagTree() {
2414 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2415 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2416 // tagTree.itemClicked.connect(this, "tagTreeSelection()");
2417 tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2418 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2419 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2421 // Listener when a tag is selected
2422 private void tagTreeSelection() {
2423 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2426 clearAttributeFilter();
2427 clearSavedSearchFilter();
2429 menuBar.noteRestoreAction.setVisible(false);
2431 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2432 if (!rensoNoteListDock.isEnabled()) {
2433 rensoNoteListDock.setEnabled(true);
2436 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2437 QTreeWidgetItem currentSelection;
2438 selectedTagGUIDs.clear();
2439 for (int i=0; i<selections.size(); i++) {
2440 currentSelection = selections.get(i);
2441 selectedTagGUIDs.add(currentSelection.text(2));
2443 if (selections.size() > 0) {
2444 menuBar.tagEditAction.setEnabled(true);
2445 menuBar.tagDeleteAction.setEnabled(true);
2446 menuBar.tagIconAction.setEnabled(true);
2449 menuBar.tagEditAction.setEnabled(false);
2450 menuBar.tagDeleteAction.setEnabled(false);
2451 menuBar.tagIconAction.setEnabled(true);
2453 if (selections.size() > 1)
2454 menuBar.tagMergeAction.setEnabled(true);
2456 menuBar.tagMergeAction.setEnabled(false);
2457 listManager.setSelectedTags(selectedTagGUIDs);
2458 listManager.loadNotesIndex();
2459 noteIndexUpdated(false);
2460 refreshEvernoteNote(true);
2461 listManager.refreshCounters = true;
2462 listManager.refreshCounters();
2463 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2465 // trigger the tag index to be refreshed
2466 @SuppressWarnings("unused")
2467 private void tagIndexUpdated() {
2468 tagIndexUpdated(true);
2470 private void tagIndexUpdated(boolean reload) {
2471 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2472 if (selectedTagGUIDs == null)
2473 selectedTagGUIDs = new ArrayList<String>();
2475 listManager.reloadTagIndex();
2477 tagTree.blockSignals(true);
2479 tagTree.setIcons(conn.getTagTable().getAllIcons());
2480 tagTree.load(listManager.getTagIndex());
2483 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2484 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2486 selectedTagGUIDs.remove(i);
2488 tagTree.blockSignals(false);
2490 browserWindow.setTag(getTagNamesForNote(currentNote));
2491 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2493 // Show/Hide note information
2494 @SuppressWarnings("unused")
2495 private void toggleTagWindow() {
2496 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2497 if (tagTree.isVisible())
2501 menuBar.hideTags.setChecked(tagTree.isVisible());
2502 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2503 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2505 // A note's tags have been updated
2506 @SuppressWarnings("unused")
2507 private void updateNoteTags(String guid, List<String> tags) {
2508 // Save any new tags. We'll need them later.
2509 List<String> newTags = new ArrayList<String>();
2510 for (int i=0; i<tags.size(); i++) {
2511 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2512 newTags.add(tags.get(i));
2515 listManager.saveNoteTags(guid, tags, true);
2516 listManager.countTagResults(listManager.getNoteIndex());
2517 StringBuffer names = new StringBuffer("");
2518 for (int i=0; i<tags.size(); i++) {
2519 names = names.append(tags.get(i));
2520 if (i<tags.size()-1) {
2521 names.append(Global.tagDelimeter + " ");
2524 browserWindow.setTag(names.toString());
2527 // Now, we need to add any new tags to the tag tree
2528 for (int i=0; i<newTags.size(); i++)
2529 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2531 // Get a string containing all tag names for a note
2532 private String getTagNamesForNote(Note n) {
2533 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2534 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2536 StringBuffer buffer = new StringBuffer(100);
2537 Vector<String> v = new Vector<String>();
2538 List<String> guids = n.getTagGuids();
2543 for (int i=0; i<guids.size(); i++) {
2544 v.add(listManager.getTagNameByGuid(guids.get(i)));
2546 Comparator<String> comparator = Collections.reverseOrder();
2547 Collections.sort(v,comparator);
2548 Collections.reverse(v);
2550 for (int i = 0; i<v.size(); i++) {
2552 buffer.append(", ");
2553 buffer.append(v.get(i));
2556 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2557 return buffer.toString();
2559 // Tags were added via dropping notes from the note list
2560 @SuppressWarnings("unused")
2561 private void tagsAdded(String noteGuid, String tagGuid) {
2562 String tagName = null;
2563 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2564 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2565 tagName = listManager.getTagIndex().get(i).getName();
2566 i=listManager.getTagIndex().size();
2569 if (tagName == null)
2572 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2573 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2574 List<String> tagNames = new ArrayList<String>();
2575 tagNames.add(new String(tagName));
2576 Note n = listManager.getMasterNoteIndex().get(i);
2577 for (int j=0; j<n.getTagNames().size(); j++) {
2578 tagNames.add(new String(n.getTagNames().get(j)));
2580 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2581 if (n.getGuid().equals(currentNoteGuid)) {
2582 Collections.sort(tagNames);
2583 String display = "";
2584 for (int j=0; j<tagNames.size(); j++) {
2585 display = display+tagNames.get(j);
2586 if (j+2<tagNames.size())
2587 display = display+Global.tagDelimeter+" ";
2589 browserWindow.setTag(display);
2591 i=listManager.getMasterNoteIndex().size();
2596 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2598 private void clearTagFilter() {
2599 tagTree.blockSignals(true);
2600 tagTree.clearSelection();
2601 menuBar.noteRestoreAction.setVisible(false);
2602 menuBar.tagEditAction.setEnabled(false);
2603 menuBar.tagMergeAction.setEnabled(false);
2604 menuBar.tagDeleteAction.setEnabled(false);
2605 menuBar.tagIconAction.setEnabled(false);
2606 selectedTagGUIDs.clear();
2607 listManager.setSelectedTags(selectedTagGUIDs);
2608 tagTree.blockSignals(false);
2610 // Change the icon for a tag
2611 @SuppressWarnings("unused")
2612 private void setTagIcon() {
2613 QTreeWidgetItem currentSelection;
2614 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2615 if (selections.size() == 0)
2618 currentSelection = selections.get(0);
2619 String guid = currentSelection.text(2);
2621 QIcon currentIcon = currentSelection.icon(0);
2622 QIcon icon = conn.getTagTable().getIcon(guid);
2625 dialog = new SetIcon(currentIcon, saveLastPath);
2626 dialog.setUseDefaultIcon(true);
2628 dialog = new SetIcon(icon, saveLastPath);
2629 dialog.setUseDefaultIcon(false);
2632 if (dialog.okPressed()) {
2633 saveLastPath = dialog.getPath();
2634 QIcon newIcon = dialog.getIcon();
2635 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2636 if (newIcon == null)
2637 newIcon = new QIcon(iconPath+"tag.png");
2638 currentSelection.setIcon(0, newIcon);
2643 @SuppressWarnings("unused")
2644 private void mergeTags() {
2645 List<Tag> tags = new ArrayList<Tag>();
2646 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2647 for (int i=0; i<selections.size(); i++) {
2648 Tag record = new Tag();
2649 record.setGuid(selections.get(i).text(2));
2650 record.setName(selections.get(i).text(0));
2654 TagMerge mergeDialog = new TagMerge(tags);
2656 if (!mergeDialog.okClicked())
2658 String newGuid = mergeDialog.getNewTagGuid();
2660 for (int i=0; i<tags.size(); i++) {
2661 if (!tags.get(i).getGuid().equals(newGuid)) {
2662 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2663 for (int j=0; j<noteGuids.size(); j++) {
2664 String noteGuid = noteGuids.get(j);
2665 conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2666 if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2667 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2671 listManager.reloadIndexes();
2674 //***************************************************************
2675 //***************************************************************
2676 //** These functions deal with Saved Search menu items
2677 //***************************************************************
2678 //***************************************************************
2679 // Add a new notebook
2680 @SuppressWarnings("unused")
2681 private void addSavedSearch() {
2682 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2683 SavedSearchEdit edit = new SavedSearchEdit();
2684 edit.setSearchList(listManager.getSavedSearchIndex());
2687 if (!edit.okPressed())
2690 Calendar currentTime = new GregorianCalendar();
2691 Long l = new Long(currentTime.getTimeInMillis());
2692 String randint = new String(Long.toString(l));
2694 SavedSearch search = new SavedSearch();
2695 search.setUpdateSequenceNum(0);
2696 search.setGuid(randint);
2697 search.setName(edit.getName());
2698 search.setQuery(edit.getQuery());
2699 search.setFormat(QueryFormat.USER);
2700 listManager.getSavedSearchIndex().add(search);
2701 conn.getSavedSearchTable().addSavedSearch(search, true);
2702 savedSearchIndexUpdated();
2703 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2705 // Edit an existing tag
2706 @SuppressWarnings("unused")
2707 private void editSavedSearch() {
2708 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2709 SavedSearchEdit edit = new SavedSearchEdit();
2710 edit.setTitle(tr("Edit Search"));
2711 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2712 QTreeWidgetItem currentSelection;
2713 currentSelection = selections.get(0);
2714 String guid = currentSelection.text(1);
2715 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2716 edit.setName(currentSelection.text(0));
2717 edit.setQuery(s.getQuery());
2718 edit.setSearchList(listManager.getSavedSearchIndex());
2721 if (!edit.okPressed())
2724 List<SavedSearch> list = listManager.getSavedSearchIndex();
2725 SavedSearch search = null;
2726 boolean found = false;
2727 for (int i=0; i<list.size(); i++) {
2728 search = list.get(i);
2729 if (search.getGuid().equals(guid)) {
2736 search.setName(edit.getName());
2737 search.setQuery(edit.getQuery());
2738 conn.getSavedSearchTable().updateSavedSearch(search, true);
2739 savedSearchIndexUpdated();
2740 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2742 // Delete an existing tag
2743 @SuppressWarnings("unused")
2744 private void deleteSavedSearch() {
2745 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2747 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2748 QMessageBox.StandardButton.Yes,
2749 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2753 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2754 for (int i=selections.size()-1; i>=0; i--) {
2755 QTreeWidgetItem currentSelection;
2756 currentSelection = selections.get(i);
2757 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2758 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2759 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2760 listManager.getSavedSearchIndex().remove(j);
2761 j=listManager.getSavedSearchIndex().size()+1;
2764 selections.remove(i);
2766 savedSearchIndexUpdated();
2767 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2769 // Setup the tree containing the user's tags
2770 private void initializeSavedSearchTree() {
2771 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2772 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2773 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2775 // Listener when a tag is selected
2776 @SuppressWarnings("unused")
2777 private void savedSearchTreeSelection() {
2778 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2780 clearNotebookFilter();
2783 clearAttributeFilter();
2785 String currentGuid = selectedSavedSearchGUID;
2786 menuBar.savedSearchEditAction.setEnabled(true);
2787 menuBar.savedSearchDeleteAction.setEnabled(true);
2788 menuBar.savedSearchIconAction.setEnabled(true);
2790 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2791 if (!rensoNoteListDock.isEnabled()) {
2792 rensoNoteListDock.setEnabled(true);
2795 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2796 QTreeWidgetItem currentSelection;
2797 selectedSavedSearchGUID = "";
2798 for (int i=0; i<selections.size(); i++) {
2799 currentSelection = selections.get(i);
2800 if (currentSelection.text(1).equals(currentGuid)) {
2801 currentSelection.setSelected(false);
2803 selectedSavedSearchGUID = currentSelection.text(1);
2805 // i = selections.size() +1;
2808 // There is the potential for no notebooks to be selected if this
2809 // happens then we make it look like all notebooks were selecetd.
2810 // If that happens, just select the "all notebooks"
2811 if (selections.size()==0) {
2812 clearSavedSearchFilter();
2814 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2816 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2818 private void clearSavedSearchFilter() {
2819 menuBar.savedSearchEditAction.setEnabled(false);
2820 menuBar.savedSearchDeleteAction.setEnabled(false);
2821 menuBar.savedSearchIconAction.setEnabled(false);
2822 savedSearchTree.blockSignals(true);
2823 savedSearchTree.clearSelection();
2824 savedSearchTree.blockSignals(false);
2825 selectedSavedSearchGUID = "";
2826 searchField.setEditText("");
2827 searchPerformed = false;
2828 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2830 // trigger the tag index to be refreshed
2831 private void savedSearchIndexUpdated() {
2832 if (selectedSavedSearchGUID == null)
2833 selectedSavedSearchGUID = new String();
2834 savedSearchTree.blockSignals(true);
2835 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2836 savedSearchTree.load(listManager.getSavedSearchIndex());
2837 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2838 savedSearchTree.blockSignals(false);
2840 // trigger when the saved search selection changes
2841 @SuppressWarnings("unused")
2842 private void updateSavedSearchSelection() {
2843 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2845 menuBar.savedSearchEditAction.setEnabled(true);
2846 menuBar.savedSearchDeleteAction.setEnabled(true);
2847 menuBar.savedSearchIconAction.setEnabled(true);
2848 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2850 if (selections.size() > 0) {
2851 menuBar.savedSearchEditAction.setEnabled(true);
2852 menuBar.savedSearchDeleteAction.setEnabled(true);
2853 menuBar.savedSearchIconAction.setEnabled(true);
2854 selectedSavedSearchGUID = selections.get(0).text(1);
2855 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2856 searchField.setEditText(s.getQuery());
2858 menuBar.savedSearchEditAction.setEnabled(false);
2859 menuBar.savedSearchDeleteAction.setEnabled(false);
2860 menuBar.savedSearchIconAction.setEnabled(false);
2861 selectedSavedSearchGUID = "";
2862 searchField.setEditText("");
2864 searchFieldChanged();
2866 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2870 // Show/Hide note information
2871 @SuppressWarnings("unused")
2872 private void toggleSavedSearchWindow() {
2873 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2874 if (savedSearchTree.isVisible())
2875 savedSearchTree.hide();
2877 savedSearchTree.show();
2878 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2880 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2881 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2883 // Change the icon for a saved search
2884 @SuppressWarnings("unused")
2885 private void setSavedSearchIcon() {
2886 QTreeWidgetItem currentSelection;
2887 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2888 if (selections.size() == 0)
2891 currentSelection = selections.get(0);
2892 String guid = currentSelection.text(1);
2894 QIcon currentIcon = currentSelection.icon(0);
2895 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2898 dialog = new SetIcon(currentIcon, saveLastPath);
2899 dialog.setUseDefaultIcon(true);
2901 dialog = new SetIcon(icon, saveLastPath);
2902 dialog.setUseDefaultIcon(false);
2905 if (dialog.okPressed()) {
2906 saveLastPath = dialog.getPath();
2907 QIcon newIcon = dialog.getIcon();
2908 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2909 if (newIcon == null)
2910 newIcon = new QIcon(iconPath+"search.png");
2911 currentSelection.setIcon(0, newIcon);
2919 //***************************************************************
2920 //***************************************************************
2921 //** These functions deal with Help menu & tool menu items
2922 //***************************************************************
2923 //***************************************************************
2924 // Show database status
2925 @SuppressWarnings("unused")
2926 private void databaseStatus() {
2928 indexRunner.interrupt = true;
2929 int dirty = conn.getNoteTable().getDirtyCount();
2930 int unindexed = conn.getNoteTable().getUnindexedCount();
2931 DatabaseStatus status = new DatabaseStatus();
2932 status.setUnsynchronized(dirty);
2933 status.setUnindexed(unindexed);
2934 status.setNoteCount(conn.getNoteTable().getNoteCount());
2935 status.setNotebookCount(listManager.getNotebookIndex().size());
2936 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2937 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2938 status.setTagCount(listManager.getTagIndex().size());
2939 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2940 status.setWordCount(conn.getWordsTable().getWordCount());
2944 // Compact the database
2945 @SuppressWarnings("unused")
2946 private void compactDatabase() {
2947 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2948 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2949 "but please be aware that depending upon the size of your database this can be time consuming " +
2950 "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
2951 QMessageBox.StandardButton.Yes,
2952 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2955 setMessage("Compacting database.");
2957 listManager.compactDatabase();
2959 setMessage("Database compact is complete.");
2960 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2962 @SuppressWarnings("unused")
2963 private void accountInformation() {
2964 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2965 AccountDialog dialog = new AccountDialog();
2967 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2969 @SuppressWarnings("unused")
2970 private void releaseNotes() {
2971 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
2972 QDialog dialog = new QDialog(this);
2973 QHBoxLayout layout = new QHBoxLayout();
2974 QTextEdit textBox = new QTextEdit();
2975 layout.addWidget(textBox);
2976 textBox.setReadOnly(true);
2977 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
2978 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
2979 QIODevice.OpenModeFlag.Text)))
2981 textBox.setText(file.readAll().toString());
2983 dialog.setWindowTitle(tr("Release Notes"));
2984 dialog.setLayout(layout);
2986 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
2988 // Called when user picks Log from the help menu
2989 @SuppressWarnings("unused")
2990 private void logger() {
2991 logger.log(logger.HIGH, "Entering NeverNote.logger");
2992 LogFileDialog dialog = new LogFileDialog(emitLog);
2994 logger.log(logger.HIGH, "Leaving NeverNote.logger");
2996 // Menu option "help/about" was selected
2997 @SuppressWarnings("unused")
2998 private void about() {
2999 logger.log(logger.HIGH, "Entering NeverNote.about");
3000 // ICHANGED based on...の記述を付加
3001 QMessageBox.about(this,
3002 tr("About NeighborNote"),
3003 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
3004 +Global.version + "(based on NixNote 1.5)"
3007 +"Open Source Evernote Client.<br><br>"
3008 +"Licensed under GPL v2. <br><hr><br>"
3009 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
3010 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
3011 +"PDFRenderer is licened under the LGPL<br>"
3012 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3013 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3014 +"Jazzy is licened under the LGPL<br>"
3015 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3016 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3017 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3018 logger.log(logger.HIGH, "Leaving NeverNote.about");
3020 // Hide the entire left hand side
3021 @SuppressWarnings("unused")
3022 private void toggleLeftSide() {
3025 hidden = !menuBar.hideLeftSide.isChecked();
3026 menuBar.hideLeftSide.setChecked(!hidden);
3029 leftSplitter1.setHidden(true);
3031 leftSplitter1.setHidden(false);
3033 Global.saveWindowVisible("leftPanel", hidden);
3036 public void checkForUpdates() {
3037 // Send off thread to check for a new version
3038 versionChecker = new QNetworkAccessManager(this);
3039 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3040 QNetworkRequest request = new QNetworkRequest();
3041 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3042 versionChecker.get(request);
3044 @SuppressWarnings("unused")
3045 private void upgradeFileRead(QNetworkReply reply) {
3046 if (!reply.isReadable())
3049 String winVersion = Global.version;
3050 String osxVersion = Global.version;
3051 String linuxVersion = Global.version;
3052 String linux64Version = Global.version;
3053 String version = Global.version;
3055 // Determine the versions available
3056 QByteArray data = reply.readLine();
3057 while (data != null && !reply.atEnd()) {
3058 String line = data.toString();
3060 if (line.contains(":"))
3061 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3064 if (line.toLowerCase().contains("windows"))
3065 winVersion = lineVersion;
3066 else if (line.toLowerCase().contains("os-x"))
3067 osxVersion = lineVersion;
3068 else if (line.toLowerCase().contains("linux amd64"))
3069 linux64Version = lineVersion;
3070 else if (line.toLowerCase().contains("linux i386"))
3071 linuxVersion = lineVersion;
3072 else if (line.toLowerCase().contains("default"))
3073 version = lineVersion;
3075 // Read the next line
3076 data = reply.readLine();
3079 // Now we need to determine what system we are on.
3080 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3081 version = winVersion;
3082 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3083 version = osxVersion;
3084 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3085 if (System.getProperty("os.arch").contains("amd64") ||
3086 System.getProperty("os.arch").contains("x86_64"))
3087 version = linux64Version;
3089 version = linuxVersion;
3093 for (String validVersion : Global.validVersions) {
3094 if (version.equals(validVersion))
3098 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3100 if (dialog.remindMe())
3101 Global.setCheckVersionUpgrade(true);
3103 Global.setCheckVersionUpgrade(false);
3107 //***************************************************************
3108 //***************************************************************
3109 //** These functions deal with the Toolbar
3110 //***************************************************************
3111 //***************************************************************
3112 @SuppressWarnings("unused")
3113 private void focusSearch() {
3114 searchField.setFocus();
3117 // Text in the search bar has been cleared
3118 private void searchFieldCleared() {
3121 // This is done because we want to force a reload of
3122 // images. Some images we may want to highlight the text.
3123 readOnlyCache.clear();
3124 inkNoteCache.clear();
3126 QWebSettings.setMaximumPagesInCache(0);
3127 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3129 searchField.setEditText("");
3130 saveNoteColumnPositions();
3131 saveNoteIndexWidth();
3132 noteIndexUpdated(true);
3133 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3134 currentNote = listManager.getNoteIndex().get(0);
3135 currentNoteGuid = currentNote.getGuid();
3137 refreshEvernoteNote(true);
3138 if (currentNote != null)
3139 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3141 // text in the search bar changed. We only use this to tell if it was cleared,
3142 // otherwise we trigger off searchFieldChanged.
3143 @SuppressWarnings("unused")
3144 private void searchFieldTextChanged(String text) {
3145 QWebSettings.setMaximumPagesInCache(0);
3146 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3148 if (text.trim().equals("")) {
3149 searchFieldCleared();
3150 if (searchPerformed) {
3152 // This is done because we want to force a reload of
3153 // images. Some images we may want to highlight the text.
3155 readOnlyCache.clear();
3156 inkNoteCache.clear();
3158 listManager.setEnSearch("");
3159 listManager.loadNotesIndex();
3160 refreshEvernoteNote(true);
3161 noteIndexUpdated(false);
3162 refreshEvernoteNote(true);
3164 searchPerformed = false;
3167 // Text in the toolbar has changed
3168 private void searchFieldChanged() {
3169 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3171 readOnlyCache.clear();
3172 inkNoteCache.clear();
3173 saveNoteColumnPositions();
3174 saveNoteIndexWidth();
3175 String text = searchField.currentText();
3176 listManager.setEnSearch(text.trim());
3177 listManager.loadNotesIndex();
3178 noteIndexUpdated(false);
3180 refreshEvernoteNote(true);
3181 searchPerformed = true;
3183 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3186 // Build the window tool bar
3187 private void setupToolBar() {
3188 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3189 toolBar = addToolBar(tr("Tool Bar"));
3190 toolBar.setObjectName("toolBar");
3191 menuBar.setupToolBarVisible();
3192 if (!Global.isWindowVisible("toolBar"))
3193 toolBar.setVisible(false);
3195 toolBar.setVisible(true);
3197 // toolBar.addWidget(menuBar);
3198 // menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3199 // toolBar.addSeparator();
3200 prevButton = toolBar.addAction(tr("Previous"));
3201 QIcon prevIcon = new QIcon(iconPath+"back.png");
3202 prevButton.setIcon(prevIcon);
3203 prevButton.triggered.connect(this, "previousViewedAction()");
3204 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow"));
3206 nextButton = toolBar.addAction(tr("Next"));
3207 QIcon nextIcon = new QIcon(iconPath+"forward.png");
3208 nextButton.setIcon(nextIcon);
3209 nextButton.triggered.connect(this, "nextViewedAction()");
3210 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow"));
3212 upButton = toolBar.addAction(tr("Up"));
3213 QIcon upIcon = new QIcon(iconPath+"up.png");
3214 upButton.setIcon(upIcon);
3215 upButton.triggered.connect(this, "upAction()");
3216 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow"));
3219 downButton = toolBar.addAction(tr("Down"));
3220 QIcon downIcon = new QIcon(iconPath+"down.png");
3221 downButton.setIcon(downIcon);
3222 downButton.triggered.connect(this, "downAction()");
3223 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow"));
3225 synchronizeButton = toolBar.addAction(tr("Synchronize"));
3226 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3227 synchronizeIconAngle = 0;
3228 synchronizeButton.triggered.connect(this, "evernoteSync()");
3229 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize"));
3231 printButton = toolBar.addAction(tr("Print"));
3232 QIcon printIcon = new QIcon(iconPath+"print.png");
3233 printButton.setIcon(printIcon);
3234 printButton.triggered.connect(this, "printNote()");
3235 togglePrintButton(Global.isToolbarButtonVisible("print"));
3237 tagButton = toolBar.addAction(tr("Tag"));
3238 QIcon tagIcon = new QIcon(iconPath+"tag.png");
3239 tagButton.setIcon(tagIcon);
3240 tagButton.triggered.connect(browserWindow, "modifyTags()");
3241 toggleTagButton(Global.isToolbarButtonVisible("tag"));
3243 attributeButton = toolBar.addAction(tr("Attributes"));
3244 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3245 attributeButton.setIcon(attributeIcon);
3246 attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3247 toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
3249 emailButton = toolBar.addAction(tr("Email"));
3250 QIcon emailIcon = new QIcon(iconPath+"email.png");
3251 emailButton.setIcon(emailIcon);
3252 emailButton.triggered.connect(this, "emailNote()");
3253 toggleEmailButton(Global.isToolbarButtonVisible("email"));
3255 deleteButton = toolBar.addAction(tr("Delete"));
3256 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3257 deleteButton.setIcon(deleteIcon);
3258 deleteButton.triggered.connect(this, "deleteNote()");
3259 toggleDeleteButton(Global.isToolbarButtonVisible("delete"));
3261 newButton = toolBar.addAction(tr("New"));
3262 QIcon newIcon = new QIcon(iconPath+"new.png");
3263 newButton.triggered.connect(this, "addNote()");
3264 newButton.setIcon(newIcon);
3265 toggleNewButton(Global.isToolbarButtonVisible("new"));
3267 allNotesButton = toolBar.addAction(tr("All Notes"));
3268 QIcon allIcon = new QIcon(iconPath+"books.png");
3269 allNotesButton.triggered.connect(this, "allNotes()");
3270 allNotesButton.setIcon(allIcon);
3271 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
3273 //toolBar.addSeparator();
3274 //toolBar.addWidget(new QLabel(tr("Quota:")));
3275 //toolBar.addWidget(quotaBar);
3276 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3278 //toolBar.addSeparator();
3280 //toolBar.addWidget(new QLabel(tr("Zoom")));
3281 //toolBar.addWidget(zoomSpinner);
3283 //toolBar.addWidget(new QLabel(" "));
3284 //toolBar.addSeparator();
3285 //toolBar.addWidget(new QLabel(tr(" Search:")));
3286 //toolBar.addWidget(searchField);
3287 QSizePolicy sizePolicy = new QSizePolicy();
3288 sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3289 QLabel spacer = new QLabel("");
3290 spacer.setSizePolicy(sizePolicy);
3291 toolBar.addWidget(spacer);
3292 //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3294 //searchClearButton = toolBar.addAction("Search Clear");
3295 //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3296 //searchClearButton.setIcon(searchClearIcon);
3297 //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3298 //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3300 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3302 // Update the sychronize button picture
3304 public QMenu createPopupMenu() {
3305 QMenu contextMenu = super.createPopupMenu();
3307 contextMenu.addSeparator();
3308 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3309 contextMenu.addAction(prevAction);
3310 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3312 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3313 contextMenu.addAction(nextAction);
3314 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3316 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3317 contextMenu.addAction(upAction);
3318 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3320 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3321 contextMenu.addAction(downAction);
3322 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3324 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3325 contextMenu.addAction(synchronizeAction);
3326 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3328 QAction printAction = addContextAction("print", tr("Print"));
3329 contextMenu.addAction(printAction);
3330 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3332 QAction tagAction = addContextAction("tag", tr("Tag"));
3333 contextMenu.addAction(tagAction);
3334 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3336 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3337 contextMenu.addAction(attributeAction);
3338 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3340 QAction emailAction = addContextAction("email", tr("Email"));
3341 contextMenu.addAction(emailAction);
3342 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3344 QAction deleteAction = addContextAction("delete", tr("Delete"));
3345 contextMenu.addAction(deleteAction);
3346 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3348 QAction newAction = addContextAction("new", tr("Add"));
3349 contextMenu.addAction(newAction);
3350 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3352 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3353 contextMenu.addAction(allNotesAction);
3354 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3356 QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3357 contextMenu.addAction(searchClearAction);
3358 searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3363 private QAction addContextAction(String config, String name) {
3364 QAction newAction = new QAction(this);
3365 newAction.setText(name);
3366 newAction.setCheckable(true);
3367 newAction.setChecked(Global.isToolbarButtonVisible(config));
3370 private void togglePrevArrowButton(Boolean toggle) {
3371 prevButton.setVisible(toggle);
3372 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3374 private void toggleNextArrowButton(Boolean toggle) {
3375 nextButton.setVisible(toggle);
3376 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3378 private void toggleUpArrowButton(Boolean toggle) {
3379 upButton.setVisible(toggle);
3380 Global.saveToolbarButtonsVisible("upArrow", toggle);
3382 private void toggleDownArrowButton(Boolean toggle) {
3383 downButton.setVisible(toggle);
3384 Global.saveToolbarButtonsVisible("downArrow", toggle);
3386 private void toggleSynchronizeButton(Boolean toggle) {
3387 synchronizeButton.setVisible(toggle);
3388 Global.saveToolbarButtonsVisible("synchronize", toggle);
3390 private void togglePrintButton(Boolean toggle) {
3391 printButton.setVisible(toggle);
3392 Global.saveToolbarButtonsVisible("print", toggle);
3394 private void toggleTagButton(Boolean toggle) {
3395 tagButton.setVisible(toggle);
3396 Global.saveToolbarButtonsVisible("tag", toggle);
3398 private void toggleAttributeButton(Boolean toggle) {
3399 attributeButton.setVisible(toggle);
3400 Global.saveToolbarButtonsVisible("attribute", toggle);
3402 private void toggleEmailButton(Boolean toggle) {
3403 emailButton.setVisible(toggle);
3404 Global.saveToolbarButtonsVisible("email", toggle);
3406 private void toggleDeleteButton(Boolean toggle) {
3407 deleteButton.setVisible(toggle);
3408 Global.saveToolbarButtonsVisible("delete", toggle);
3410 private void toggleNewButton(Boolean toggle) {
3411 newButton.setVisible(toggle);
3412 Global.saveToolbarButtonsVisible("new", toggle);
3414 private void toggleAllNotesButton(Boolean toggle) {
3415 allNotesButton.setVisible(toggle);
3416 Global.saveToolbarButtonsVisible("allNotes", toggle);
3418 @SuppressWarnings("unused")
3419 private void toggleSearchClearButton(Boolean toggle) {
3420 searchClearButton.setVisible(toggle);
3421 Global.saveToolbarButtonsVisible("searchClear", toggle);
3428 @SuppressWarnings("unused")
3429 private void updateSyncButton() {
3431 if (syncIcons == null) {
3432 syncIcons = new ArrayList<QPixmap>();
3434 synchronizeIconAngle = 0;
3435 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3437 for (int i=0; i<=360; i++) {
3438 QPixmap rotatedPix = new QPixmap(pix.size());
3439 QPainter p = new QPainter(rotatedPix);
3440 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3441 QSize size = pix.size();
3442 p.translate(size.width()/2, size.height()/2);
3445 p.setBackgroundMode(BGMode.OpaqueMode);
3446 p.translate(-size.width()/2, -size.height()/2);
3447 p.drawPixmap(0,0, pix);
3449 syncIcons.add(rotatedPix);
3453 synchronizeIconAngle++;
3454 if (synchronizeIconAngle > 359)
3455 synchronizeIconAngle=0;
3456 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3459 // Synchronize with Evernote
3461 private void evernoteSync() {
3462 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3463 if (!Global.isConnected)
3465 if (Global.isConnected)
3466 synchronizeAnimationTimer.start(5);
3467 // synchronizeAnimationTimer.start(200);
3469 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3471 private void updateQuotaBar() {
3472 long limit = Global.getUploadLimit();
3473 long amount = Global.getUploadAmount();
3474 if (amount>0 && limit>0) {
3475 int percent =(int)(amount*100/limit);
3476 quotaBar.setValue(percent);
3478 quotaBar.setValue(0);
3481 @SuppressWarnings("unused")
3482 private void zoomChanged() {
3483 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3486 //****************************************************************
3487 //****************************************************************
3488 //* System Tray functions
3489 //****************************************************************
3490 //****************************************************************
3491 private void trayToggleVisible() {
3496 if (windowMaximized)
3503 @SuppressWarnings("unused")
3504 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3505 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3506 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3507 trayToggleVisible();
3512 //***************************************************************
3513 //***************************************************************
3514 //** These functions deal with the trash tree
3515 //***************************************************************
3516 //***************************************************************
3517 // Setup the tree containing the trash.
3518 @SuppressWarnings("unused")
3519 private void trashTreeSelection() {
3520 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3522 clearNotebookFilter();
3524 clearAttributeFilter();
3525 clearSavedSearchFilter();
3527 String tempGuid = currentNoteGuid;
3529 // currentNoteGuid = "";
3530 currentNote = new Note();
3531 selectedNoteGUIDs.clear();
3532 listManager.getSelectedNotebooks().clear();
3533 listManager.getSelectedTags().clear();
3534 listManager.setSelectedSavedSearch("");
3535 browserWindow.clear();
3537 // toggle the add buttons
3538 newButton.setEnabled(!newButton.isEnabled());
3539 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3540 menuBar.noteAdd.setVisible(true);
3542 List<QTreeWidgetItem> selections = trashTree.selectedItems();
3543 if (selections.size() == 0) {
3544 currentNoteGuid = trashNoteGuid;
3545 trashNoteGuid = tempGuid;
3546 Global.showDeleted = false;
3547 menuBar.noteRestoreAction.setEnabled(false);
3548 menuBar.noteRestoreAction.setVisible(false);
3549 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3550 rensoNoteListDock.setEnabled(true);
3553 trashNoteGuid = tempGuid;
3554 currentNoteGuid = trashNoteGuid;
3555 menuBar.noteRestoreAction.setEnabled(true);
3556 menuBar.noteRestoreAction.setVisible(true);
3557 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
3558 rensoNoteListDock.setEnabled(false);
3560 Global.showDeleted = true;
3562 listManager.loadNotesIndex();
3563 noteIndexUpdated(false);
3564 //// browserWindow.setEnabled(newButton.isEnabled());
3565 browserWindow.setReadOnly(!newButton.isEnabled());
3566 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3568 // Empty the trash file
3569 @SuppressWarnings("unused")
3570 private void emptyTrash() {
3571 // browserWindow.clear();
3572 logger.log(logger.EXTREME, "Emptying Trash");
3573 listManager.emptyTrash();
3574 logger.log(logger.EXTREME, "Resetting view after trash empty");
3575 if (trashTree.selectedItems().size() > 0) {
3576 listManager.getSelectedNotebooks().clear();
3577 listManager.getSelectedTags().clear();
3578 listManager.setSelectedSavedSearch("");
3579 newButton.setEnabled(!newButton.isEnabled());
3580 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3581 menuBar.noteAdd.setVisible(true);
3582 browserWindow.clear();
3585 clearNotebookFilter();
3586 clearSavedSearchFilter();
3587 clearAttributeFilter();
3589 Global.showDeleted = false;
3590 menuBar.noteRestoreAction.setEnabled(false);
3591 menuBar.noteRestoreAction.setVisible(false);
3593 listManager.loadNotesIndex();
3594 noteIndexUpdated(false);
3596 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3597 if (!rensoNoteListDock.isEnabled()) {
3598 rensoNoteListDock.setEnabled(true);
3602 // Show/Hide trash window
3603 @SuppressWarnings("unused")
3604 private void toggleTrashWindow() {
3605 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3606 if (trashTree.isVisible())
3610 menuBar.hideTrash.setChecked(trashTree.isVisible());
3612 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3613 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3615 private void clearTrashFilter() {
3616 Global.showDeleted = false;
3617 newButton.setEnabled(true);
3618 menuBar.noteAdd.setEnabled(true);
3619 menuBar.noteAdd.setVisible(true);
3620 trashTree.blockSignals(true);
3621 trashTree.clearSelection();
3622 trashTree.blockSignals(false);
3627 //***************************************************************
3628 //***************************************************************
3629 //** These functions deal with connection settings
3630 //***************************************************************
3631 //***************************************************************
3632 // SyncRunner had a problem and things are disconnected
3633 @SuppressWarnings("unused")
3634 private void remoteErrorDisconnect() {
3635 menuBar.connectAction.setText(tr("Connect"));
3636 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3637 menuBar.synchronizeAction.setEnabled(false);
3638 Global.isConnected = false;
3639 synchronizeAnimationTimer.stop();
3642 // Do a manual connect/disconnect
3643 private void remoteConnect() {
3645 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3647 // If we are already connected, we just disconnect
3648 if (Global.isConnected) {
3649 Global.isConnected = false;
3650 syncRunner.enDisconnect();
3651 setupConnectMenuOptions();
3656 OAuthTokenizer tokenizer = new OAuthTokenizer();
3657 AESEncrypter aes = new AESEncrypter();
3659 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3660 } catch (FileNotFoundException e) {
3661 // File not found, so we'll just get empty strings anyway.
3665 if (Global.getProxyValue("url").equals("")) {
3666 System.setProperty("http.proxyHost","") ;
3667 System.setProperty("http.proxyPort", "") ;
3668 System.setProperty("https.proxyHost","") ;
3669 System.setProperty("https.proxyPort", "") ;
3672 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3673 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3674 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3675 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3677 if (Global.getProxyValue("userid").equals("")) {
3678 Authenticator.setDefault(new Authenticator() {
3680 protected PasswordAuthentication getPasswordAuthentication() {
3682 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3688 syncRunner.userStoreUrl = Global.userStoreUrl;
3689 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3690 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3694 String authString = aes.getString();
3695 if (!authString.equals("")) {
3696 tokenizer.tokenize(authString);
3697 syncRunner.authToken = tokenizer.oauth_token;
3698 syncRunner.enConnect();
3701 Global.isConnected = syncRunner.isConnected;
3703 if (!Global.isConnected) {
3704 OAuthWindow window = new OAuthWindow(logger);
3706 setMessage(window.errorMessage);
3711 setMessage(window.errorMessage);
3714 tokenizer.tokenize(window.response);
3715 if (tokenizer.oauth_token.equals("")) {
3716 setMessage(tr("Invalid authorization token received."));
3719 aes.setString(window.response);
3721 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3722 } catch (FileNotFoundException e) {
3723 // TODO Auto-generated catch block
3724 e.printStackTrace();
3726 syncRunner.authToken = tokenizer.oauth_token;
3727 syncRunner.enConnect();
3728 Global.isConnected = syncRunner.isConnected;
3730 // Global.username = syncRunner.username;
3732 if (!Global.isConnected)
3735 setupConnectMenuOptions();
3736 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3740 private void setupConnectMenuOptions() {
3741 logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3742 if (!Global.isConnected) {
3743 menuBar.connectAction.setText(tr("Connect"));
3744 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3745 menuBar.synchronizeAction.setEnabled(false);
3747 menuBar.connectAction.setText(tr("Disconnect"));
3748 menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3749 menuBar.synchronizeAction.setEnabled(true);
3751 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3756 //***************************************************************
3757 //***************************************************************
3758 //** These functions deal with the GUI Attribute tree
3759 //***************************************************************
3760 //***************************************************************
3761 @SuppressWarnings("unused")
3762 private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3764 // clearTagFilter();
3765 // clearNotebookFilter();
3767 // clearSavedSearchFilter();
3769 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3770 if (!rensoNoteListDock.isEnabled()) {
3771 rensoNoteListDock.setEnabled(true);
3774 if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3775 if (item.childCount() > 0) {
3776 item.setSelected(false);
3778 Global.createdBeforeFilter.reset();
3779 Global.createdSinceFilter.reset();
3780 Global.changedBeforeFilter.reset();
3781 Global.changedSinceFilter.reset();
3782 Global.containsFilter.reset();
3783 attributeTreeSelected = item;
3784 DateAttributeFilterTable f = null;
3785 f = findDateAttributeFilterTable(item.parent());
3787 f.select(item.parent().indexOfChild(item));
3789 Global.containsFilter.select(item.parent().indexOfChild(item));
3792 listManager.loadNotesIndex();
3793 noteIndexUpdated(false);
3796 attributeTreeSelected = null;
3797 item.setSelected(false);
3798 Global.createdBeforeFilter.reset();
3799 Global.createdSinceFilter.reset();
3800 Global.changedBeforeFilter.reset();
3801 Global.changedSinceFilter.reset();
3802 Global.containsFilter.reset();
3803 listManager.loadNotesIndex();
3804 noteIndexUpdated(false);
3806 // This determines what attribute filter we need, depending upon the selection
3807 private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3808 if (w.parent() != null && w.childCount() > 0) {
3809 QTreeWidgetItem parent = w.parent();
3810 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3811 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3812 return Global.createdSinceFilter;
3813 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created &&
3814 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3815 return Global.createdBeforeFilter;
3816 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3817 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3818 return Global.changedSinceFilter;
3819 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified &&
3820 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3821 return Global.changedBeforeFilter;
3826 // Show/Hide attribute search window
3827 @SuppressWarnings("unused")
3828 private void toggleAttributesWindow() {
3829 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3830 if (attributeTree.isVisible())
3831 attributeTree.hide();
3833 attributeTree.show();
3834 menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3836 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3837 logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3839 private void clearAttributeFilter() {
3840 Global.createdBeforeFilter.reset();
3841 Global.createdSinceFilter.reset();
3842 Global.changedBeforeFilter.reset();
3843 Global.changedSinceFilter.reset();
3844 Global.containsFilter.reset();
3845 attributeTreeSelected = null;
3846 attributeTree.blockSignals(true);
3847 attributeTree.clearSelection();
3848 attributeTree.blockSignals(false);
3852 //***************************************************************
3853 //***************************************************************
3854 //** These functions deal with the GUI Note index table
3855 //***************************************************************
3856 //***************************************************************
3857 // Initialize the note list table
3858 private void initializeNoteTable() {
3859 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3860 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3861 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3862 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3864 // Show/Hide trash window
3865 @SuppressWarnings("unused")
3866 private void toggleNoteListWindow() {
3867 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3868 if (noteTableView.isVisible())
3869 noteTableView.hide();
3871 noteTableView.show();
3872 menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3874 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3875 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3877 // Handle the event that a user selects a note from the table
3878 @SuppressWarnings("unused")
3879 private void noteTableSelection() {
3880 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3885 // Ctrlを押しながらノートテーブルを選択した時に選択ノート数0になってしまうのを止める
3886 if (noteTableView.selectionModel().selectedRows().size() == 0) {
3887 scrollToGuid(currentNoteGuid);
3893 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3894 // 選択されたノート(current)のguidをcurrentnoteguidにセット
3895 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3896 if(selections.size() > 0){
3897 selectedNoteGUIDs.clear();
3898 for(int i = 0; i < selections.size(); i++){
3899 int row = selections.get(i).row();
3900 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3901 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3902 currentNoteGuid = (String) ix.values().toArray()[0];
3903 selectedNoteGUIDs.add(currentNoteGuid);
3909 // If we have more than one selection, then set the merge note action to true.
3910 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3911 if (selections.size() > 1)
3912 menuBar.noteMergeAction.setEnabled(true);
3914 menuBar.noteMergeAction.setEnabled(false);
3916 // If the ctrl key is pressed, then they are selecting multiple
3917 // entries and we don't want to change the currently viewed note.
3919 if (QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) &&
3920 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3921 selectedNoteGUIDs.clear();
3922 for (int i=0; i<selections.size(); i++) {
3923 int row = selections.get(i).row();
3924 QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3925 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3926 selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3931 // ICHANGED たぶんこれは不要
3933 /*if (historyGuids.size() == 0) {
3934 historyGuids.add(currentNoteGuid);
3935 historyPosition = 1;
3938 noteTableView.showColumn(Global.noteTableGuidPosition);
3940 if (!Global.isColumnVisible("guid"))
3941 noteTableView.hideColumn(Global.noteTableGuidPosition);
3943 if (selections.size() > 0) {
3945 menuBar.noteDuplicateAction.setEnabled(true);
3946 menuBar.noteOnlineHistoryAction.setEnabled(true);
3947 menuBar.noteMergeAction.setEnabled(true);
3948 selectedNoteGUIDs.clear();
3949 if (selections.size() != 1 || Global.showDeleted) {
3950 menuBar.noteDuplicateAction.setEnabled(false);
3952 if (selections.size() != 1 || !Global.isConnected) {
3953 menuBar.noteOnlineHistoryAction.setEnabled(false);
3955 if (selections.size() == 1) {
3956 menuBar.noteMergeAction.setEnabled(false);
3958 for (int i=0; i<selections.size(); i++) {
3959 int row = selections.get(i).row();
3961 upButton.setEnabled(false);
3963 upButton.setEnabled(true);
3964 if (row < listManager.getNoteTableModel().rowCount()-1)
3965 downButton.setEnabled(true);
3967 downButton.setEnabled(false);
3968 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3969 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3971 currentNoteGuid = (String)ix.values().toArray()[0];
3972 selectedNoteGUIDs.add(currentNoteGuid);
3976 nextButton.setEnabled(true);
3977 prevButton.setEnabled(true);
3980 int currentIndex = tabBrowser.currentIndex();
3981 ArrayList<String> histGuids = historyGuids.get(currentIndex);
3982 int histPosition = historyPosition.get(currentIndex);
3983 boolean fromHist = fromHistory.get(currentIndex);
3987 int endPosition = histGuids.size() - 1;
3989 for (int j = histPosition; j <= endPosition; j++) {
3990 histGuids.remove(histGuids.size() - 1);
3992 histGuids.add(currentNoteGuid);
3993 historyPosition.put(currentIndex, histGuids.size());
3994 histPosition = histGuids.size();
3996 if (histPosition <= 1){
3997 prevButton.setEnabled(false);
3999 if (histPosition == histGuids.size())
4000 nextButton.setEnabled(false);
4001 fromHistory.put(currentIndex, false);
4004 scrollToGuid(currentNoteGuid);
4005 refreshEvernoteNote(true);
4008 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4009 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4016 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
4019 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4024 // 複数ノートの同時閲覧履歴をデータベースに保存
4025 private void addBrowseHistory() {
4026 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4027 if (tabWindows.size() >= 2) {
4028 Iterator<Integer> it = tabWindows.keySet().iterator();
4029 while (it.hasNext()) {
4030 int tabIndex = it.next();
4031 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4032 // guid1=guid2のデータは登録しない
4033 if (!currentNoteGuid.equals(nextGuid)) {
4034 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4038 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4039 if (externalWindows.size() >= 1) {
4040 Iterator<String> it = externalWindows.keySet().iterator();
4041 while (it.hasNext()) {
4042 String nextGuid = it.next();
4043 // guid1=guid2のデータは登録しない
4044 if (!currentNoteGuid.equals(nextGuid)) {
4045 conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4051 // Trigger a refresh when the note db has been updated
4052 private void noteIndexUpdated(boolean reload) {
4053 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4055 refreshEvernoteNoteList();
4056 logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4057 noteTableView.load(reload);
4058 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4060 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4061 pos = noteTableView.proxyModel.rowCount();
4064 if (noteTableView.proxyModel.rowCount() == 0)
4067 QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4069 currentNoteGuid = (String)i.data();
4073 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4075 scrollToGuid(currentNoteGuid);
4076 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4078 // Called when the list of notes is updated
4079 private void refreshEvernoteNoteList() {
4080 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4081 browserWindow.setDisabled(false);
4082 if (selectedNoteGUIDs == null)
4083 selectedNoteGUIDs = new ArrayList<String>();
4084 selectedNoteGUIDs.clear(); // clear out old entries
4086 String saveCurrentNoteGuid = new String();
4087 String tempNoteGuid = new String();
4090 int currentIndex = tabBrowser.currentIndex();
4091 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4093 historyPosition.put(currentIndex, 0);
4095 prevButton.setEnabled(false);
4096 nextButton.setEnabled(false);
4098 if (currentNoteGuid == null)
4099 currentNoteGuid = new String();
4101 //determine current note guid
4102 for (Note note : listManager.getNoteIndex()) {
4103 tempNoteGuid = note.getGuid();
4104 if (currentNoteGuid.equals(tempNoteGuid)) {
4105 saveCurrentNoteGuid = tempNoteGuid;
4109 if (listManager.getNoteIndex().size() == 0) {
4110 currentNoteGuid = "";
4112 browserWindow.clear();
4113 browserWindow.setDisabled(true);
4117 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4118 currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4119 saveCurrentNoteGuid = currentNoteGuid;
4120 refreshEvernoteNote(true);
4123 if (!saveCurrentNoteGuid.equals("")) {
4124 refreshEvernoteNote(false);
4126 currentNoteGuid = "";
4128 reloadTagTree(false);
4130 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4134 // Called when the previous arrow button is clicked
4135 @SuppressWarnings("unused")
4136 private void previousViewedAction() {
4137 int currentIndex = tabBrowser.currentIndex();
4138 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4139 int histPosition = historyPosition.get(currentIndex);
4140 boolean fromHist = fromHistory.get(currentIndex);
4141 if (!prevButton.isEnabled())
4143 if (histPosition == 0)
4146 historyPosition.put(currentIndex, histPosition);
4147 if (histPosition <= 0)
4149 String historyGuid = histGuids.get(histPosition - 1);
4150 fromHistory.put(currentIndex, true);
4152 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4153 QModelIndex modelIndex = noteTableView.model().index(i,
4154 Global.noteTableGuidPosition);
4155 if (modelIndex != null) {
4156 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4158 String tableGuid = (String) ix.values().toArray()[0];
4159 if (tableGuid.equals(historyGuid)) {
4160 noteTableView.selectRow(i);
4167 @SuppressWarnings("unused")
4168 private void nextViewedAction() {
4169 if (!nextButton.isEnabled())
4172 int currentIndex = tabBrowser.currentIndex();
4173 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4174 int histPosition = historyPosition.get(currentIndex);
4175 boolean fromHist = fromHistory.get(currentIndex);
4176 String historyGuid = histGuids.get(histPosition);
4178 historyPosition.put(currentIndex, histPosition);
4179 fromHistory.put(currentIndex, true);
4181 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4182 QModelIndex modelIndex = noteTableView.model().index(i,
4183 Global.noteTableGuidPosition);
4184 if (modelIndex != null) {
4185 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4187 String tableGuid = (String) ix.values().toArray()[0];
4188 if (tableGuid.equals(historyGuid)) {
4189 noteTableView.selectRow(i);
4195 // Called when the up arrow is clicked
4196 @SuppressWarnings("unused")
4197 private void upAction() {
4198 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4199 int row = selections.get(0).row();
4201 noteTableView.selectRow(row-1);
4204 // Called when the down arrow is clicked
4205 @SuppressWarnings("unused")
4206 private void downAction() {
4207 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4208 int row = selections.get(0).row();
4209 int max = listManager.getNoteTableModel().rowCount();
4211 noteTableView.selectRow(row+1);
4214 // Update a tag string for a specific note in the list
4215 @SuppressWarnings("unused")
4216 private void updateListTags(String guid, List<String> tags) {
4217 logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4218 StringBuffer tagBuffer = new StringBuffer();
4219 for (int i=0; i<tags.size(); i++) {
4220 tagBuffer.append(tags.get(i));
4221 if (i<tags.size()-1)
4222 tagBuffer.append(", ");
4225 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4226 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4227 if (modelIndex != null) {
4228 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4229 String tableGuid = (String)ix.values().toArray()[0];
4230 if (tableGuid.equals(guid)) {
4231 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4232 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4233 noteTableView.proxyModel.invalidate();
4238 logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4240 // Update a title for a specific note in the list
4241 @SuppressWarnings("unused")
4242 private void updateListAuthor(String guid, String author) {
4243 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4245 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4246 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4247 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4248 if (modelIndex != null) {
4249 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4250 String tableGuid = (String)ix.values().toArray()[0];
4251 if (tableGuid.equals(guid)) {
4252 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4253 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4254 noteTableView.proxyModel.invalidate();
4260 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4262 private void updateListNoteNotebook(String guid, String notebook) {
4263 logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4264 listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4265 logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4267 // Update a title for a specific note in the list
4268 @SuppressWarnings("unused")
4269 private void updateListSourceUrl(String guid, String url) {
4270 logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4272 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4273 //QModelIndex modelIndex = noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4274 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4275 if (modelIndex != null) {
4276 // SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4277 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4278 String tableGuid = (String)ix.values().toArray()[0];
4279 if (tableGuid.equals(guid)) {
4280 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4281 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4282 noteTableView.proxyModel.invalidate();
4287 logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4289 @SuppressWarnings("unused")
4290 private void updateListGuid(String oldGuid, String newGuid) {
4291 logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4293 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4294 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4295 if (modelIndex != null) {
4296 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4297 String tableGuid = (String)ix.values().toArray()[0];
4298 if (tableGuid.equals(oldGuid)) {
4299 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4300 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4305 logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4307 private void updateListTagName(String guid) {
4308 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4310 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4311 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4312 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4314 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4315 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4316 if (modelIndex != null) {
4317 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4318 String noteGuid = (String)ix.values().toArray()[0];
4319 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4320 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4321 i=listManager.getNoteTableModel().rowCount();
4327 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4329 private void removeListTagName(String guid) {
4330 logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4332 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4333 if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4334 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4335 if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4336 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4339 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4340 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4341 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4342 if (modelIndex != null) {
4343 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4344 String noteGuid = (String)ix.values().toArray()[0];
4345 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4346 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4347 i=listManager.getNoteTableModel().rowCount();
4353 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4355 private void updateListNotebookName(String oldName, String newName) {
4356 logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4358 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4359 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition);
4360 if (modelIndex != null) {
4361 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4362 String tableName = (String)ix.values().toArray()[0];
4363 if (tableName.equalsIgnoreCase(oldName)) {
4364 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4368 logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4370 @SuppressWarnings("unused")
4371 private void updateListDateCreated(String guid, QDateTime date) {
4372 logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
4374 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4375 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4376 if (modelIndex != null) {
4377 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4378 String tableGuid = (String)ix.values().toArray()[0];
4379 if (tableGuid.equals(guid)) {
4380 listManager.getNoteTableModel().setData(i, Global.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4381 noteTableView.proxyModel.invalidate();
4386 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4388 @SuppressWarnings("unused")
4389 private void updateListDateSubject(String guid, QDateTime date) {
4390 logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
4392 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4393 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4394 if (modelIndex != null) {
4395 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4396 String tableGuid = (String)ix.values().toArray()[0];
4397 if (tableGuid.equals(guid)) {
4398 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4399 listManager.getNoteTableModel().setData(i, Global.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4400 noteTableView.proxyModel.invalidate();
4405 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4407 private void updateListDateChanged(String guid, QDateTime date) {
4408 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4410 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4411 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4412 if (modelIndex != null) {
4413 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4414 String tableGuid = (String)ix.values().toArray()[0];
4415 if (tableGuid.equals(guid)) {
4416 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4417 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4422 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4424 private void updateListDateChanged() {
4425 logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4426 QDateTime date = new QDateTime(QDateTime.currentDateTime());
4427 updateListDateChanged(currentNoteGuid, date);
4428 logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4431 private void scrollToCurrentGuid() {
4432 //scrollToGuid(currentNoteGuid);
4433 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4434 if (selections.size() == 0)
4436 QModelIndex index = selections.get(0);
4437 int row = selections.get(0).row();
4438 String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4441 // Scroll to the current GUID in tthe list.
4442 // Scroll to a particular index item
4443 private void scrollToGuid(String guid) {
4444 if (currentNote == null || guid == null)
4446 if (currentNote.isActive() && Global.showDeleted) {
4447 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4448 if (!listManager.getNoteIndex().get(i).isActive()) {
4449 currentNote = listManager.getNoteIndex().get(i);
4450 currentNoteGuid = currentNote.getGuid();
4451 i = listManager.getNoteIndex().size();
4455 if (!currentNote.isActive() && !Global.showDeleted) {
4456 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4457 if (listManager.getNoteIndex().get(i).isActive()) {
4458 currentNote = listManager.getNoteIndex().get(i);
4459 currentNoteGuid = currentNote.getGuid();
4460 i = listManager.getNoteIndex().size();
4465 for (int i=0; i<noteTableView.model().rowCount(); i++) {
4466 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4467 if (currentNoteGuid.equals(index.data())) {
4468 // noteTableView.selectionModel().blockSignals(true);
4469 noteTableView.selectRow(i);
4470 // noteTableView.selectionModel().blockSignals(false);
4471 noteTableView.scrollTo(index, ScrollHint.EnsureVisible); // This should work, but it doesn't
4472 i=listManager.getNoteTableModel().rowCount();
4475 noteTableView.repaint();
4477 // Show/Hide columns
4478 private void showColumns() {
4479 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4480 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4481 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4482 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4483 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4484 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4485 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4486 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4487 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4488 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4489 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));
4490 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned"));
4492 // Title color has changed
4493 @SuppressWarnings("unused")
4494 private void titleColorChanged(Integer color) {
4495 logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4498 QColor backgroundColor = new QColor();
4499 QColor foregroundColor = new QColor(QColor.black);
4500 backgroundColor.setRgb(color);
4502 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4503 foregroundColor.setRgb(QColor.white.rgb());
4505 if (selectedNoteGUIDs.size() == 0)
4506 selectedNoteGUIDs.add(currentNoteGuid);
4508 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4509 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4510 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4511 if (modelIndex != null) {
4512 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4513 String tableGuid = (String)ix.values().toArray()[0];
4514 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4515 for (int k=0; k<Global.noteTableColumnCount; k++) {
4516 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4517 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4518 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4520 i=listManager.getNoteTableModel().rowCount();
4527 restoreSelectedNoteInfo();
4529 logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4531 // A note has been pinned or unpinned
4532 @SuppressWarnings("unused")
4533 private void notePinned() {
4534 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4537 for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4538 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4539 boolean pinned = !meta.isPinned();
4540 meta.setPinned(pinned); // Toggle the pinned/unpinned
4542 // Update the list & table
4543 listManager.updateNoteMetadata(meta);
4544 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4548 restoreSelectedNoteInfo();
4550 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4552 // Wide list was chosen
4553 public void narrowListView() {
4554 saveNoteColumnPositions();
4555 saveNoteIndexWidth();
4557 int sortCol = noteTableView.proxyModel.sortColumn();
4558 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4559 Global.setSortColumn(sortCol);
4560 Global.setSortOrder(sortOrder);
4562 Global.setListView(Global.View_List_Narrow);
4564 menuBar.wideListView.blockSignals(true);
4565 menuBar.narrowListView.blockSignals(true);
4567 menuBar.wideListView.setChecked(false);
4568 menuBar.narrowListView.setChecked(true);
4570 menuBar.wideListView.blockSignals(false);
4571 menuBar.narrowListView.blockSignals(false);
4573 mainLeftRightSplitter.addWidget(noteTableView);
4574 // ICHANGED browserWindow → tabBrowser
4575 mainLeftRightSplitter.addWidget(tabBrowser);
4577 restoreWindowState(false);
4578 noteTableView.repositionColumns();
4579 noteTableView.resizeColumnWidths();
4580 noteTableView.resizeRowHeights();
4582 sortCol = Global.getSortColumn();
4583 sortOrder = Global.getSortOrder();
4584 noteTableView.proxyModel.blocked = true;
4585 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4586 noteTableView.proxyModel.blocked = false;
4590 noteTableView.load(false);
4591 refreshEvernoteNote(true);
4592 scrollToCurrentGuid();
4594 public void wideListView() {
4595 int sortCol = noteTableView.proxyModel.sortColumn();
4596 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4597 Global.setSortColumn(sortCol);
4598 Global.setSortOrder(sortOrder);
4601 saveNoteColumnPositions();
4602 saveNoteIndexWidth();
4603 Global.setListView(Global.View_List_Wide);
4605 menuBar.wideListView.blockSignals(true);
4606 menuBar.narrowListView.blockSignals(true);
4608 menuBar.wideListView.setChecked(true);
4609 menuBar.narrowListView.setChecked(false);
4611 menuBar.wideListView.blockSignals(false);
4612 menuBar.narrowListView.blockSignals(false);
4613 browserIndexSplitter.setVisible(true);
4614 browserIndexSplitter.addWidget(noteTableView);
4615 // ICHANGED browserWindow → tabBrowser
4616 browserIndexSplitter.addWidget(tabBrowser);
4618 restoreWindowState(false);
4619 noteTableView.repositionColumns();
4620 noteTableView.resizeColumnWidths();
4621 noteTableView.resizeRowHeights();
4623 sortCol = Global.getSortColumn();
4624 sortOrder = Global.getSortOrder();
4625 noteTableView.proxyModel.blocked = true;
4626 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4627 noteTableView.proxyModel.blocked = false;
4630 noteTableView.load(false);
4631 scrollToCurrentGuid();
4633 // Sort order for the notebook has changed
4634 public void tableSortOrderChanged(Integer column, Integer order) {
4636 // Find what notebook (if any) is selected. We ignore stacks & the "All Notebooks".
4637 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4638 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4639 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4641 notebook = currentSelectedNotebook.text(2);
4642 conn.getNotebookTable().setSortOrder(notebook, column, order);
4646 //***************************************************************
4647 @SuppressWarnings("unused")
4648 private void evernoteLinkClick(String syncGuid, String locGuid) {
4650 if (conn.getNoteTable().guidExists(syncGuid)) {
4653 // If we didn't find it via the synchronized guid, look under the local guid
4654 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was
4655 // later synchronized (that causes the guid to change so we need to find the new one).
4656 if (conn.getNoteTable().guidExists(locGuid))
4659 guid = conn.getNoteTable().findAlternateGuid(locGuid);
4662 openExternalEditor(guid);
4666 //If we've gotten this far, we can't find the note
4667 QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4668 " seem to find that note."));
4670 //***************************************************************
4671 //***************************************************************
4672 //** External editor window functions
4673 //***************************************************************
4674 //***************************************************************
4675 private void listDoubleClick() {
4677 openExternalEditor(currentNoteGuid);
4679 private void openExternalEditor(String guid) {
4681 if (externalWindows.containsKey(guid)) {
4682 externalWindows.get(guid).raise();
4686 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4687 // We have a new external editor to create
4688 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4690 ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4692 newBrowser.setWindowIcon(appIcon);
4693 externalWindows.put(guid, newBrowser);
4694 showEditorButtons(newBrowser.getBrowserWindow());
4695 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4696 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4697 newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4698 //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4699 newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4700 newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4701 newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4702 newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4704 browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4705 browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4706 browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4710 @SuppressWarnings({ "rawtypes", "unused" })
4711 private void externalWindowTagsEdited(String guid, List values) {
4712 StringBuffer line = new StringBuffer(100);
4713 for (int i=0; i<values.size(); i++) {
4715 line.append(Global.tagDelimeter+" ");
4716 line.append(values.get(i));
4718 if (guid.equals(currentNoteGuid)) {
4719 browserWindow.setTag(line.toString());
4722 @SuppressWarnings("unused")
4723 private void externalWindowClosing(String guid) {
4724 externalWindows.remove(guid);
4727 // ***************************************************************
4728 // ***************************************************************
4730 // ***************************************************************
4731 // ***************************************************************
4732 @SuppressWarnings("unused")
4733 private void openNewTab() {
4736 // selectedNoteGUIDsをディープコピー
4737 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4739 for (int i=0; i < copySelected.size() ; i++) {
4740 openTabEditor(copySelected.get(i));
4744 // ICHANGED 連想ノートリストから新しいタブで開く
4745 @SuppressWarnings("unused")
4746 private void openNewTabFromRNL(){
4747 if(rensoNotePressedItemGuid != null){
4748 String prevCurrentNoteGuid = new String(currentNoteGuid);
4751 openTabEditor(rensoNotePressedItemGuid);
4753 // 連想ノートリストアイテムクリック操作を記録
4754 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4759 private void openTabEditor(String guid) {
4761 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4763 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4764 showEditorButtons(newBrowser.getBrowserWindow());
4766 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4767 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4768 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4770 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4772 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4774 String noteTitle = note.getTitle();
4775 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4776 tabWindows.put(index, newBrowser);
4778 // ExtendedInformationを必要があれば表示する
4779 toggleNoteInformation();
4780 // Sourceを必要があれば表示する
4782 // EditorButtonsBarを必要があれば表示する
4783 toggleEditorButtonBar();
4786 ArrayList<String> histGuids = new ArrayList<String>();
4787 historyGuids.put(index, histGuids);
4788 historyPosition.put(index, 0);
4789 fromHistory.put(index, false);
4792 histGuids.add(guid);
4793 historyPosition.put(index, histGuids.size());
4795 tabBrowser.setCurrentIndex(index);
4797 if (guid != null && !guid.equals("")) {
4798 if (!Global.showDeleted) { // ゴミ箱じゃなければ
4804 // ICHANGED タブが閉じられた
4805 private void tabWindowClosing(int index) {
4807 if (tabBrowser.count() <= 1) {
4811 TabBrowse t = (TabBrowse) tabBrowser.widget(index);
4812 String guid = t.getBrowserWindow().getNote().getGuid();
4813 String content = t.getBrowserWindow().getContent();
4814 BrowserWindow browser = t.getBrowserWindow();
4816 if (t.getNoteDirty()) {
4817 saveNoteTabBrowser(guid, content, true, browser);
4821 browser.noteSignal.tagsChanged.disconnect();
4822 browser.noteSignal.titleChanged.disconnect();
4823 browser.noteSignal.noteChanged.disconnect();
4824 browser.noteSignal.notebookChanged.disconnect();
4825 browser.noteSignal.createdDateChanged.disconnect();
4826 browser.noteSignal.alteredDateChanged.disconnect();
4829 tabWindows.remove(index);
4830 tabBrowser.removeTab(index);
4833 historyGuids.remove(index);
4834 historyPosition.remove(index);
4835 fromHistory.remove(index);
4837 // タブのインデックスを更新(削除によって空いた部分を詰める)
4838 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4840 TabBrowse tab = tabWindows.get(i + 1);
4841 tabWindows.put(i, tab);
4842 tabWindows.remove(i + 1);
4844 ArrayList<String> histGuids = historyGuids.get(i + 1);
4845 historyGuids.put(i, histGuids);
4846 historyGuids.remove(i + 1);
4848 int histPosition = historyPosition.get(i + 1);
4849 historyPosition.put(i, histPosition);
4850 historyPosition.remove(i + 1);
4852 boolean fromHist = fromHistory.get(i + 1);
4853 fromHistory.put(i, fromHist);
4854 fromHistory.remove(i + 1);
4857 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4858 tabWindowChanged(tabBrowser.currentIndex());
4861 @SuppressWarnings("unused")
4862 private void noteAddNewTab() {
4865 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4866 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4867 String prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4869 openEmptyTabEditor();
4872 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4873 TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4874 String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4875 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4876 if (addedTabGuid != null && !addedTabGuid.equals("")) {
4877 if (!prevTabGuid.equals(addedTabGuid)) {
4878 conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4885 private void openEmptyTabEditor() {
4887 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4888 showEditorButtons(newBrowser.getBrowserWindow());
4890 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4892 int index = tabBrowser.addNewTab(newBrowser, "");
4893 tabWindows.put(index, newBrowser);
4895 // ExtendedInformationを必要があれば表示する
4896 toggleNoteInformation();
4897 // Sourceを必要があれば表示する
4899 // EditorButtonsBarを必要があれば表示する
4900 toggleEditorButtonBar();
4903 ArrayList<String> histGuids = new ArrayList<String>();
4904 historyGuids.put(index, histGuids);
4905 historyPosition.put(index, 0);
4906 fromHistory.put(index, false);
4908 tabBrowser.setCurrentIndex(index);
4911 //***************************************************************
4912 //***************************************************************
4913 //** These functions deal with Note specific things
4914 //***************************************************************
4915 //***************************************************************
4916 private void setNoteDirty() {
4917 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
4919 // Find if the note is being edited externally. If it is, update it.
4920 if (externalWindows.containsKey(currentNoteGuid)) {
4921 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4922 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4923 ExternalBrowse window = externalWindows.get(currentNoteGuid);
4924 window.getBrowserWindow().setContent(unicode);
4927 // ICHANGED ↓↓↓ここから↓↓↓
4928 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
4929 Collection<TabBrowse> tabBrowsers = tabWindows.values();
4930 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
4931 Collection<Integer> tabIndexes = tabWindows.keySet();
4932 Iterator<Integer> indexIterator = tabIndexes.iterator();
4934 while (tabIterator.hasNext()) {
4935 TabBrowse tab = tabIterator.next();
4936 int index = indexIterator.next();
4937 String guid = tab.getBrowserWindow().getNote().getGuid();
4939 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4940 QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
4942 if (guid.equals(currentNoteGuid)) {
4943 if (index != tabBrowser.currentIndex()) {
4944 TabBrowse window = tabWindows.get(index);
4945 window.getBrowserWindow().setContent(unicode);
4949 // ICHANGED ↑↑↑ここまで↑↑↑
4951 // If the note is dirty, then it is unsynchronized by default.
4955 // Set the note as dirty and check if its status is synchronized in the display table
4957 if (listManager.getNoteMetadata().containsKey(currentNoteGuid) &&
4958 listManager.getNoteMetadata().get(currentNoteGuid).isDirty()) {
4962 // If this wasn't already marked as unsynchronized, then we need to update the table
4963 listManager.getNoteTableModel().updateNoteSyncStatus(currentNoteGuid, false);
4964 // listManager.getUnsynchronizedNotes().add(currentNoteGuid);
4965 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4966 QModelIndex modelIndex = listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4967 if (modelIndex != null) {
4968 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4969 String tableGuid = (String)ix.values().toArray()[0];
4970 if (tableGuid.equals(currentNoteGuid)) {
4971 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
4977 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
4979 @SuppressWarnings("unused")
4980 private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
4981 QTextCodec codec = QTextCodec.codecForName("UTF-8");
4982 QByteArray unicode = codec.fromUnicode(content);
4983 noteCache.remove(guid);
4984 noteCache.put(guid, unicode.toString());
4985 if (guid.equals(currentNoteGuid)) {
4987 browserWindow.setContent(unicode);
4990 thumbnailRunner.addWork("GENERATE "+ guid);
4991 saveNote(guid, browser);
4997 private void saveNoteTabBrowser(String guid, String content, Boolean save,
4998 BrowserWindow browser) {
4999 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5000 QByteArray unicode = codec.fromUnicode(content);
5001 noteCache.remove(guid);
5002 noteCache.put(guid, unicode.toString());
5004 thumbnailRunner.addWork("GENERATE " + guid);
5005 saveNote(guid, browser);
5009 private void saveNote() {
5011 saveNote(currentNoteGuid, browserWindow);
5012 thumbnailRunner.addWork("GENERATE "+ currentNoteGuid);
5016 private void saveNote(String guid, BrowserWindow window) {
5017 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5020 logger.log(logger.EXTREME, "Saving to cache");
5021 QTextCodec codec = QTextCodec.codecForLocale();
5022 // QTextDecoder decoder = codec.makeDecoder();
5023 codec = QTextCodec.codecForName("UTF-8");
5024 QByteArray unicode = codec.fromUnicode(window.getContent());
5025 noteCache.put(guid, unicode.toString());
5027 logger.log(logger.EXTREME, "updating list manager");
5028 listManager.updateNoteContent(guid, window.getContent());
5029 logger.log(logger.EXTREME, "Updating title");
5030 listManager.updateNoteTitle(guid, window.getTitle());
5031 updateListDateChanged();
5033 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5034 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5035 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5036 currentNote = listManager.getNoteIndex().get(i);
5037 i = listManager.getNoteIndex().size();
5042 // Get a note from Evernote (and put it in the browser)
5043 private void refreshEvernoteNote(boolean reload) {
5044 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5046 if (Global.disableViewing) {
5047 browserWindow.setEnabled(false);
5052 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals(""))
5054 Global.cryptCounter =0;
5056 browserWindow.setReadOnly(true);
5063 browserWindow.loadingData(true);
5065 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5066 if (currentNote == null) {
5072 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5074 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5077 private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5078 NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
5079 formatter.setNote(note, Global.pdfPreview());
5080 formatter.setHighlight(listManager.getEnSearch());
5082 if (!noteCache.containsKey(guid)) {
5083 js = new QByteArray();
5084 // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
5085 js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
5086 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>");
5087 js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5088 js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5089 if (Global.displayRightToLeft())
5090 js.append("<style> body { direction:rtl; }</style>");
5091 js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5092 js.append("</head>");
5093 formatter.setNote(note, Global.pdfPreview());
5094 js.append(formatter.rebuildNoteHTML());
5095 js.append("</HTML>");
5096 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5097 js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5098 js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5099 // if (Global.enableHTMLEntitiesFix) {
5100 // browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5102 browser.setContent(js);
5103 noteCache.put(guid, js.toString());
5105 if (formatter.resourceError)
5106 resourceErrorMessage();
5107 if (formatter.formatError) {
5109 QMessageBox.information(this, tr("Error"),
5110 tr("NeighborNote had issues formatting this note." +
5111 " To protect your data this note is being marked as read-only."));
5114 readOnly = formatter.readOnly;
5115 inkNote = formatter.inkNote;
5117 readOnlyCache.put(guid, true);
5119 inkNoteCache.put(guid, true);
5121 logger.log(logger.HIGH, "Note content is being pulled from the cache");
5122 String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5123 js = new QByteArray(cachedContent);
5124 browser.setContent(js);
5125 if (readOnlyCache.containsKey(guid))
5127 if (inkNoteCache.containsKey(guid))
5130 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5131 thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5133 if (readOnly || inkNote ||
5134 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != ""))
5135 browser.getBrowser().page().setContentEditable(false); // We don't allow editing of ink notes
5137 browser.getBrowser().page().setContentEditable(true);
5138 browser.setReadOnly(readOnly);
5139 deleteButton.setEnabled(!readOnly);
5140 tagButton.setEnabled(!readOnly);
5141 menuBar.noteDelete.setEnabled(!readOnly);
5142 menuBar.noteTags.setEnabled(!readOnly);
5143 browser.setNote(note);
5145 if (note != null && note.getNotebookGuid() != null &&
5146 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5147 deleteButton.setEnabled(false);
5148 menuBar.notebookDeleteAction.setEnabled(false);
5150 deleteButton.setEnabled(true);
5151 menuBar.notebookDeleteAction.setEnabled(true);
5154 // Build a list of non-closed notebooks
5155 List<Notebook> nbooks = new ArrayList<Notebook>();
5156 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5157 boolean found=false;
5158 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5159 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
5163 nbooks.add(listManager.getNotebookIndex().get(i));
5166 browser.setTitle(note.getTitle());
5167 browser.setTag(getTagNamesForNote(note));
5168 browser.setAuthor(note.getAttributes().getAuthor());
5170 browser.setAltered(note.getUpdated());
5171 browser.setCreation(note.getCreated());
5172 if (note.getAttributes().getSubjectDate() > 0)
5173 browser.setSubjectDate(note.getAttributes().getSubjectDate());
5175 browser.setSubjectDate(note.getCreated());
5176 browser.setUrl(note.getAttributes().getSourceURL());
5178 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5179 List<Tag> tagList = tagFilter.getValidTags(note);
5180 browser.setAllTags(tagList);
5182 browser.setCurrentTags(note.getTagNames());
5186 browser.loadingData(false);
5187 if (thumbnailViewer.isActiveWindow())
5190 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5191 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5194 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5198 @SuppressWarnings("unused")
5199 private void toggleNoteAttributes() {
5200 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5201 toggleNoteInformation();
5204 // Save a generated thumbnail
5205 private void toggleNoteInformation() {
5206 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5209 boolean isChecked = menuBar.noteAttributes.isChecked();
5211 for(int i = 0; i < tabBrowser.count(); i++){
5212 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5213 boolean isExtended = browser.isExtended();
5214 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5215 browser.toggleInformation();
5219 menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5220 Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5221 logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5224 // Listener triggered when a print button is pressed
5225 @SuppressWarnings("unused")
5226 private void printNote() {
5227 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5229 QPrintDialog dialog = new QPrintDialog();
5230 if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5231 QPrinter printer = dialog.printer();
5232 browserWindow.getBrowser().print(printer);
5234 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5237 // Listener triggered when the email button is pressed
5238 @SuppressWarnings("unused")
5239 private void emailNote() {
5240 logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5242 if (Desktop.isDesktopSupported()) {
5243 Desktop desktop = Desktop.getDesktop();
5245 String text2 = browserWindow.getContentsToEmail();
5246 QUrl url = new QUrl("mailto:");
5247 url.addQueryItem("subject", currentNote.getTitle());
5248 // url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5249 url.addQueryItem("body", text2);
5250 QDesktopServices.openUrl(url);
5254 if (desktop.isSupported(Desktop.Action.MAIL)) {
5255 URI uriMailTo = null;
5257 //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5258 String text = browserWindow.getContentsToEmail();
5259 //text = "<b>" +text +"</b>";
5260 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5261 +"&BODY=" +text, null);
5262 uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5263 +"&ATTACHMENT=d:/test.pdf", null);
5264 desktop.mail(uriMailTo);
5265 } catch (URISyntaxException e) {
5266 e.printStackTrace();
5267 } catch (IOException e) {
5268 e.printStackTrace();
5275 logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5277 // Reindex all notes
5278 @SuppressWarnings("unused")
5279 private void fullReindex() {
5280 logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5281 indexRunner.addWork("REINDEXALL");
5282 setMessage(tr("Database will be reindexed."));
5283 logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5285 // Listener when a user wants to reindex a specific note
5286 @SuppressWarnings("unused")
5287 private void reindexNote() {
5288 logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5289 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5290 indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5292 if (selectedNotebookGUIDs.size() > 1)
5293 setMessage(tr("Notes will be reindexed."));
5295 setMessage(tr("Note will be reindexed."));
5296 logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5299 @SuppressWarnings("unused")
5300 private void deleteNote() {
5301 logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5302 if (currentNote == null)
5304 if (currentNoteGuid.equals(""))
5306 String title = null;
5307 if (selectedNoteGUIDs.size() == 1)
5308 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5310 // If we are deleting non-trash notes
5311 if (currentNote.isActive()) {
5312 if (Global.verifyDelete()) {
5314 if (selectedNoteGUIDs.size() > 1) {
5315 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5318 msg = new String(tr("Delete note \"") +title +"\"?");
5320 msg = new String(tr("Delete note selected note?"));
5322 if (QMessageBox.question(this, tr("Confirmation"), msg,
5323 QMessageBox.StandardButton.Yes,
5324 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5326 restoreSelectedNoteInfo();
5331 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5332 selectedNoteGUIDs.add(currentNoteGuid);
5333 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5334 listManager.deleteNote(selectedNoteGUIDs.get(i));
5337 // If we are deleting from the trash.
5338 if (Global.verifyDelete()) {
5340 if (selectedNoteGUIDs.size() > 1) {
5341 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5344 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5346 msg = new String(tr("Permanently delete note selected note?"));
5348 if (QMessageBox.question(this, "Confirmation", msg,
5349 QMessageBox.StandardButton.Yes,
5350 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
5352 restoreSelectedNoteInfo();
5357 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5358 selectedNoteGUIDs.add(currentNoteGuid);
5359 for (int i=selectedNoteGUIDs.size()-1; i>=0; i--) {
5360 for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5361 QModelIndex modelIndex = listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5362 if (modelIndex != null) {
5363 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5364 String tableGuid = (String)ix.values().toArray()[0];
5365 if (tableGuid.equals(selectedNoteGUIDs.get(i))) {
5366 listManager.getNoteTableModel().removeRow(j);
5371 listManager.expungeNote(selectedNoteGUIDs.get(i));
5374 conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i));
5375 conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i));
5376 conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i));
5380 currentNoteGuid = "";
5382 // ICHANGED ↓↓↓ここから↓↓↓
5383 // 削除したノートを外部ウィンドウで開いていたら、閉じる
5384 Collection<ExternalBrowse> windows = externalWindows.values();
5385 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5386 Collection<String> guids = externalWindows.keySet();
5387 Iterator<String> guidIterator = guids.iterator();
5388 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5390 while (windowIterator.hasNext()) {
5391 ExternalBrowse browser = windowIterator.next();
5392 String guid = guidIterator.next();
5394 for (int i = 0; i < selectedNoteGUIDs.size(); i++) {
5395 if (guid.equals(selectedNoteGUIDs.get(i))) {
5396 closeWindows.add(browser);
5401 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5402 closeWindows.get(i).close();
5404 // ICHANGED ↑↑↑ここまで↑↑↑
5406 // ICHANGED ↓↓↓ここから↓↓↓
5407 // 削除したノートをタブで開いていたら、閉じる
5408 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5409 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5410 Collection<Integer> tabIndexes = tabWindows.keySet();
5411 Iterator<Integer> indexIterator = tabIndexes.iterator();
5412 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
5414 while (tabIterator.hasNext()) {
5415 TabBrowse tab = tabIterator.next();
5416 int index = indexIterator.next();
5417 String guid = tab.getBrowserWindow().getNote().getGuid();
5419 for(int i = 0; i < selectedNoteGUIDs.size(); i++){
5420 if(guid.equals(selectedNoteGUIDs.get(i))){
5421 closeIndexes.add(index);
5426 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5427 tabWindowClosing(closeIndexes.get(i));
5429 // ICHANGED ↑↑↑ここまで↑↑↑
5432 restoreSelectedNoteInfo();
5434 listManager.loadNotesIndex();
5435 noteIndexUpdated(false);
5436 refreshEvernoteNote(true);
5437 scrollToGuid(currentNoteGuid);
5438 logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5441 // ICHANGED @SuppressWarnings("unused") を削除
5442 private void addNote() {
5443 logger.log(logger.HIGH, "Inside NeverNote.addNote");
5444 // browserWindow.setEnabled(true);
5445 browserWindow.setReadOnly(false);
5447 Calendar currentTime = new GregorianCalendar();
5448 StringBuffer noteString = new StringBuffer(100);
5449 noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5450 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5453 if (Global.overrideDefaultFont()) {
5454 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5455 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5456 noteString.append("<br clear=\"none\" />\n");
5457 noteString.append("</span>\n</font>\n");
5459 noteString.append("<br clear=\"none\" />\n");
5460 noteString.append("</en-note>");
5462 Long l = new Long(currentTime.getTimeInMillis());
5463 String randint = new String(Long.toString(l));
5465 // Find a notebook. We first look for a selected notebook (the "All Notebooks" one doesn't count).
5467 // for the first non-archived notebook. Finally, if nothing else we
5468 // pick the first notebook in the list.
5469 String notebook = null;
5470 listManager.getNotebookIndex().get(0).getGuid();
5471 List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5472 if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5473 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5474 notebook = currentSelectedNotebook.text(2);
5476 boolean found = false;
5477 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5478 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5479 boolean match = false;
5480 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5481 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5483 j = listManager.getArchiveNotebookIndex().size();
5487 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5488 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5490 // Now we have a list of good notebooks, so we can look for the default
5492 for (int i=0; i<goodNotebooks.size(); i++) {
5493 if (goodNotebooks.get(i).isDefaultNotebook()) {
5494 notebook = goodNotebooks.get(i).getGuid();
5496 i = goodNotebooks.size();
5500 if (goodNotebooks.size() > 0 && !found)
5501 notebook = goodNotebooks.get(0).getGuid();
5504 notebook = listManager.getNotebookIndex().get(0).getGuid();
5507 Note newNote = new Note();
5508 newNote.setUpdateSequenceNum(0);
5509 newNote.setGuid(randint);
5510 newNote.setNotebookGuid(notebook);
5511 newNote.setTitle("Untitled Note");
5512 newNote.setContent(noteString.toString());
5513 newNote.setDeleted(0);
5514 newNote.setCreated(System.currentTimeMillis());
5515 newNote.setUpdated(System.currentTimeMillis());
5516 newNote.setActive(true);
5517 NoteAttributes na = new NoteAttributes();
5518 na.setLatitude(0.0);
5519 na.setLongitude(0.0);
5520 na.setAltitude(0.0);
5521 newNote.setAttributes(new NoteAttributes());
5522 newNote.setTagGuids(new ArrayList<String>());
5523 newNote.setTagNames(new ArrayList<String>());
5525 // If new notes are to be created based upon the selected tags, then we need to assign the tags
5526 if (Global.newNoteWithSelectedTags()) {
5527 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5528 QTreeWidgetItem currentSelection;
5529 for (int i=0; i<selections.size(); i++) {
5530 currentSelection = selections.get(i);
5531 newNote.getTagGuids().add(currentSelection.text(2));
5532 newNote.getTagNames().add(currentSelection.text(0));
5536 conn.getNoteTable().addNote(newNote, true);
5537 NoteMetadata metadata = new NoteMetadata();
5538 metadata.setGuid(newNote.getGuid());
5539 metadata.setDirty(true);
5540 listManager.addNote(newNote, metadata);
5541 // noteTableView.insertRow(newNote, true, -1);
5544 String prevCurrentNoteGuid = new String(currentNoteGuid);
5546 currentNote = newNote;
5547 currentNoteGuid = currentNote.getGuid();
5548 // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5549 // noteTableView.clearSelection();
5551 refreshEvernoteNote(true);
5552 listManager.countNotebookResults(listManager.getNoteIndex());
5553 browserWindow.titleLabel.setFocus();
5554 browserWindow.titleLabel.selectAll();
5555 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5557 // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加
5558 if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5559 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5560 conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5564 // If the window is hidden, then we want to popup this in an external window &
5568 logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5570 // Restore a note from the trash;
5571 @SuppressWarnings("unused")
5572 private void restoreNote() {
5574 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
5575 selectedNoteGUIDs.add(currentNoteGuid);
5576 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5577 listManager.restoreNote(selectedNoteGUIDs.get(i));
5579 currentNoteGuid = "";
5580 listManager.loadNotesIndex();
5581 noteIndexUpdated(false);
5584 // Search a note for specific txt
5585 @SuppressWarnings("unused")
5586 private void findText() {
5588 find.setFocusOnTextField();
5590 @SuppressWarnings("unused")
5591 private void doFindText() {
5592 browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5595 @SuppressWarnings("unused")
5596 private void updateNoteTitle(String guid, String title) {
5597 listManager.setNoteSynchronized(guid, false);
5599 // We do this manually because if we've edited the note in an
5600 // external window we run into the possibility of signal recursion
5602 if (guid.equals(currentNoteGuid)) {
5603 browserWindow.titleLabel.blockSignals(true);
5604 browserWindow.titleLabel.setText(title);
5605 browserWindow.titleLabel.blockSignals(false);
5608 // Signal received that note content has changed. Normally we just need the guid to remove
5609 // it from the cache.
5610 @SuppressWarnings("unused")
5611 private void invalidateNoteCache(String guid, String content) {
5612 noteCache.remove(guid);
5613 refreshEvernoteNote(true);
5615 // Signal received that a note guid has changed
5616 @SuppressWarnings("unused")
5617 private void noteGuidChanged(String oldGuid, String newGuid) {
5618 if (noteCache.containsKey(oldGuid)) {
5619 if (!oldGuid.equals(currentNoteGuid)) {
5620 String cache = noteCache.get(oldGuid);
5621 noteCache.put(newGuid, cache);
5622 noteCache.remove(oldGuid);
5624 noteCache.remove(oldGuid);
5625 noteCache.put(newGuid, browserWindow.getContent());
5629 listManager.updateNoteGuid(oldGuid, newGuid, false);
5630 if (currentNoteGuid.equals(oldGuid)) {
5631 if (currentNote != null)
5632 currentNote.setGuid(newGuid);
5633 currentNoteGuid = newGuid;
5636 if (externalWindows.containsKey(oldGuid)) {
5637 ExternalBrowse b = externalWindows.get(oldGuid);
5638 externalWindows.remove(oldGuid);
5639 b.getBrowserWindow().getNote().setGuid(newGuid);
5640 externalWindows.put(newGuid, b);
5644 for(int i = 0; i < tabBrowser.count(); i++){
5645 TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5646 b.getBrowserWindow().getNote().setGuid(newGuid);
5649 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5650 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5651 noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5652 i=listManager.getNoteIndex().size();
5656 if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5657 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5658 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5659 listManager.getNoteTableModel().metaData.remove(oldGuid);
5664 // Toggle the note editor button bar
5666 private void toggleEditorButtonBar() {
5667 boolean isChecked = menuBar.showEditorBar.isChecked();
5669 for(int i = 0; i < tabBrowser.count(); i++){
5670 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5671 boolean isVisible = browser.buttonsVisible;
5673 if (isChecked && !isVisible) {
5674 browser.buttonsVisible = true;
5675 showEditorButtons(browser);
5676 } else if(!isChecked && isVisible) {
5677 browser.hideButtons();
5681 Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5684 // Show editor buttons
5685 private void showEditorButtons(BrowserWindow browser) {
5686 browser.buttonLayout.setVisible(true);
5687 browser.undoAction.setVisible(false);
5689 browser.undoButton.setVisible(false);
5691 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5692 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5693 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5694 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5695 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5696 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5697 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5698 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5699 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5700 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5701 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5702 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5703 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5704 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5705 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5706 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5707 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5708 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5709 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5710 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5711 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5712 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5713 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5715 private void duplicateNote(String guid) {
5717 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5718 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5719 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5720 oldNote.setResources(resList);
5721 duplicateNote(oldNote);
5723 private void duplicateNote(Note oldNote) {
5725 // Now that we have a good notebook guid, we need to move the conflicting note
5726 // to the local notebook
5727 Calendar currentTime = new GregorianCalendar();
5728 Long l = new Long(currentTime.getTimeInMillis());
5729 String newGuid = new String(Long.toString(l));
5731 // Note newNote = oldNote.deepCopy();
5732 Note newNote = (Note)Global.deepCopy(oldNote);
5733 newNote.setUpdateSequenceNum(0);
5734 newNote.setGuid(newGuid);
5735 newNote.setDeleted(0);
5736 newNote.setActive(true);
5739 List<String> tagNames = new ArrayList<String>();
5740 List<String> tagGuids = new ArrayList<String>();;
5741 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5742 tagNames.add(oldNote.getTagNames().get(i));
5743 tagGuids.add(oldNote.getTagGuids().get(i));
5746 // Sort note Tags to make them look nice
5747 for (int i=0; i<tagNames.size()-1; i++) {
5748 if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5749 String n1 = tagNames.get(i);
5750 String n2 = tagNames.get(i+1);
5751 tagNames.set(i, n2);
5752 tagNames.set(i+1, n1);
5755 newNote.setTagGuids(tagGuids);
5756 newNote.setTagNames(tagNames);
5758 // Add tag guids to note
5761 // Duplicate resources
5762 List<Resource> resList = oldNote.getResources();
5763 if (resList == null)
5764 resList = new ArrayList<Resource>();
5766 for (int i=0; i<resList.size(); i++) {
5768 while (l == prevGuid) {
5769 currentTime = new GregorianCalendar();
5770 l = new Long(currentTime.getTimeInMillis());
5773 String newResGuid = new String(Long.toString(l));
5774 resList.get(i).setNoteGuid(newGuid);
5775 resList.get(i).setGuid(newResGuid);
5776 resList.get(i).setUpdateSequenceNum(0);
5777 resList.get(i).setActive(true);
5778 conn.getNoteTable().noteResourceTable.saveNoteResource(
5779 (Resource)Global.deepCopy(resList.get(i)), true);
5781 newNote.setResources(resList);
5784 // 操作履歴と除外ノートとスター付きノートも複製する
5785 if(Global.getDuplicateRensoNote()) {
5786 conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5787 conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5788 conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5791 // Add note to the database
5792 conn.getNoteTable().addNote(newNote, true);
5793 NoteMetadata metaData = new NoteMetadata();
5794 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5795 metaData.copy(oldMeta);
5796 metaData.setGuid(newNote.getGuid());
5797 listManager.addNote(newNote, metaData);
5798 noteTableView.insertRow(newNote, metaData, true, -1);
5799 currentNoteGuid = newNote.getGuid();
5800 currentNote = newNote;
5801 refreshEvernoteNote(true);
5802 listManager.countNotebookResults(listManager.getNoteIndex());
5807 @SuppressWarnings("unused")
5808 private void allNotes() {
5809 clearAttributeFilter();
5810 clearNotebookFilter();
5811 clearSavedSearchFilter();
5814 searchField.clear();
5815 if (Global.mimicEvernoteInterface) {
5816 notebookTree.selectGuid("");
5818 notebookTreeSelection();
5819 refreshEvernoteNote(true);
5821 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5822 if (!rensoNoteListDock.isEnabled()) {
5823 rensoNoteListDock.setEnabled(true);
5827 @SuppressWarnings("unused")
5828 private void mergeNotes() {
5829 logger.log(logger.HIGH, "Merging notes");
5832 String masterGuid = null;
5833 List<String> sources = new ArrayList<String>();
5835 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5836 int r = noteTableView.selectionModel().selectedRows().get(i).row();
5837 index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5838 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5840 masterGuid = (String)ix.values().toArray()[0];
5842 sources.add((String)ix.values().toArray()[0]);
5845 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5846 logger.log(logger.EXTREME, "Children count: "+sources.size());
5847 mergeNoteContents(masterGuid, sources);
5848 currentNoteGuid = masterGuid;
5850 // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ
5851 if(Global.getMergeRensoNote()) {
5852 for (int i = 0; i < sources.size(); i++) {
5853 String childGuid = sources.get(i);
5854 if(masterGuid != null && childGuid != null) {
5855 if(!masterGuid.equals(childGuid)) {
5856 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
5857 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
5858 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
5864 // ICHANGED ↓↓↓ここから↓↓↓
5865 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
5866 Collection<ExternalBrowse> windows = externalWindows.values();
5867 Iterator<ExternalBrowse> windowIterator = windows.iterator();
5868 Collection<String> guids = externalWindows.keySet();
5869 Iterator<String> guidIterator = guids.iterator();
5870 List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5872 while (windowIterator.hasNext()) {
5873 ExternalBrowse browser = windowIterator.next();
5874 String guid = guidIterator.next();
5876 for (int i = 0; i < sources.size(); i++) {
5877 if (guid.equals(sources.get(i))) {
5878 closeWindows.add(browser);
5883 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5884 closeWindows.get(i).close();
5886 // ICHANGED ↑↑↑ここまで↑↑↑
5888 // ICHANGED ↓↓↓ここから↓↓↓
5889 // マージしたノート(child)をタブで開いていたら、閉じる
5890 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5891 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5892 Collection<Integer> tabIndexes = tabWindows.keySet();
5893 Iterator<Integer> indexIterator = tabIndexes.iterator();
5894 List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
5896 while (tabIterator.hasNext()) {
5897 TabBrowse tab = tabIterator.next();
5898 int tabIndex = indexIterator.next();
5899 String guid = tab.getBrowserWindow().getNote().getGuid();
5901 for(int i = 0; i < sources.size(); i++){
5902 if(guid.equals(sources.get(i))){
5903 closeIndexes.add(tabIndex);
5908 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5909 tabWindowClosing(closeIndexes.get(i));
5911 // ICHANGED ↑↑↑ここまで↑↑↑
5913 noteIndexUpdated(false);
5915 // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除
5916 noteCache.remove(masterGuid);
5918 refreshEvernoteNote(true);
5921 private void mergeNoteContents(String targetGuid, List<String> sources) {
5922 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
5923 String newContent = target.getContent();
5924 newContent = newContent.replace("</en-note>", "<br></br>");
5926 for (int i=0; i<sources.size(); i++) {
5927 Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
5928 if (source.isSetTitle()) {
5929 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
5931 String sourceContent = source.getContent();
5932 logger.log(logger.EXTREME, "Merging contents into note");
5933 logger.log(logger.EXTREME, sourceContent);
5934 logger.log(logger.EXTREME, "End of content");
5935 int startOfNote = sourceContent.indexOf("<en-note>");
5936 sourceContent = sourceContent.substring(startOfNote+9);
5937 int endOfNote = sourceContent.indexOf("</en-note>");
5938 sourceContent = sourceContent.substring(0,endOfNote);
5939 newContent = newContent + sourceContent;
5940 logger.log(logger.EXTREME, "New note content");
5941 logger.log(logger.EXTREME, newContent);
5942 logger.log(logger.EXTREME, "End of content");
5943 for (int j=0; j<source.getResourcesSize(); j++) {
5944 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
5945 Resource r = source.getResources().get(j);
5946 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
5948 Calendar currentTime = new GregorianCalendar();
5949 Long l = new Long(currentTime.getTimeInMillis());
5953 while (l == prevGuid) {
5954 currentTime = new GregorianCalendar();
5955 l = new Long(currentTime.getTimeInMillis());
5957 String newResGuid = new String(Long.toString(l));
5958 newRes.setNoteGuid(targetGuid);
5959 newRes.setGuid(newResGuid);
5960 newRes.setUpdateSequenceNum(0);
5961 newRes.setActive(true);
5962 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
5965 logger.log(logger.EXTREME, "Updating note");
5966 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
5967 for (int i=0; i<sources.size(); i++) {
5968 logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
5969 listManager.deleteNote(sources.get(i));
5971 logger.log(logger.EXTREME, "Exiting merge note");
5973 // A resource within a note has had a guid change
5974 @SuppressWarnings("unused")
5975 private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
5976 if (oldGuid != null && !oldGuid.equals(newGuid))
5977 Global.resourceMap.put(oldGuid, newGuid);
5979 // View a thumbnail of the note
5980 public void thumbnailView() {
5982 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
5983 QFile thumbnail = new QFile(thumbnailName);
5984 if (!thumbnail.exists()) {
5986 QImage img = new QImage();
5987 img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
5988 thumbnailViewer.setThumbnail(img);
5990 thumbnailViewer.setThumbnail(thumbnailName);
5991 if (!thumbnailViewer.isVisible())
5992 thumbnailViewer.showFullScreen();
5994 // An error happened while saving a note. Inform the user
5995 @SuppressWarnings("unused")
5996 private void saveRunnerError(String guid, String msg) {
5998 String title = "*Unknown*";
5999 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6000 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6001 title = listManager.getMasterNoteIndex().get(i).getTitle();
6002 i=listManager.getMasterNoteIndex().size();
6005 msg = tr("An error has happened while saving the note \"") +title+
6006 tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
6007 "As a result, changes to the note may not be saved properly in the database."+
6008 "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6009 "\nbe lost. Please review the note to recover any critical data before restarting.");
6011 QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6014 private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6015 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6016 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6017 // Find an idle preview object
6018 for (int i=0; i<thumbGenerators.size(); i++) {
6019 if (thumbGenerators.get(i).mutex.tryLock()) {
6020 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6021 thumbGenerators.get(i).loadContent(guid, html, zoom);
6025 if (thumbGenerators.size() >= 1) {
6026 logger.log(logger.EXTREME, "No available thumbnail generators. Aborting " +guid);
6030 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6031 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6032 thumbGenerators.add(preview);
6034 if (preview.mutex.tryLock()) {
6035 logger.log(logger.EXTREME, "Loading thumbnail for " +guid);
6036 preview.loadContent(guid, html, zoom);
6038 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6043 //**********************************************************
6044 //**********************************************************
6045 //* Online user actions
6046 //**********************************************************
6047 //**********************************************************
6048 private void setupOnlineMenu() {
6049 if (!Global.isConnected) {
6050 menuBar.noteOnlineHistoryAction.setEnabled(false);
6051 menuBar.selectiveSyncAction.setEnabled(false);
6054 menuBar.noteOnlineHistoryAction.setEnabled(true);
6055 menuBar.selectiveSyncAction.setEnabled(true);
6058 @SuppressWarnings("unused")
6059 private void viewNoteHistory() {
6060 if (currentNoteGuid == null || currentNoteGuid.equals(""))
6062 if (currentNote.getUpdateSequenceNum() == 0) {
6063 setMessage(tr("Note has never been synchronized."));
6064 QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6068 setMessage(tr("Getting Note History"));
6070 Note currentOnlineNote = null;
6073 if (Global.isPremium())
6074 versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6076 versions = new ArrayList<NoteVersionId>();
6077 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6078 } catch (EDAMUserException e) {
6079 setMessage("EDAMUserException: " +e.getMessage());
6081 } catch (EDAMSystemException e) {
6082 setMessage("EDAMSystemException: " +e.getMessage());
6084 } catch (EDAMNotFoundException e) {
6085 setMessage(tr("Note not found on server."));
6086 QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6088 } catch (TException e) {
6089 setMessage("EDAMTransactionException: " +e.getMessage());
6093 // If we've gotten this far, we have a good note.
6094 if (historyWindow == null) {
6096 historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6098 historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6099 historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6100 historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6102 historyWindow.historyCombo.clear();
6104 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6105 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6107 historyWindow.setCurrent(isDirty);
6109 loadHistoryWindowContent(currentOnlineNote);
6110 historyWindow.load(versions);
6111 setMessage(tr("History retrieved"));
6113 historyWindow.exec();
6115 private Note reloadHistoryWindow(String selection) {
6117 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6118 String dateTimeFormat = new String(fmt);
6119 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6123 for (int i=0; i<versions.size(); i++) {
6124 StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6125 if (versionDate.toString().equals(selection))
6129 if (index > -1 || selection.indexOf("Current") > -1) {
6130 Note historyNote = null;
6133 usn = versions.get(index).getUpdateSequenceNum();
6134 historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6136 historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6137 } catch (EDAMUserException e) {
6138 setMessage("EDAMUserException: " +e.getMessage());
6141 } catch (EDAMSystemException e) {
6142 setMessage("EDAMSystemException: " +e.getMessage());
6145 } catch (EDAMNotFoundException e) {
6146 setMessage("EDAMNotFoundException: " +e.getMessage());
6149 } catch (TException e) {
6150 setMessage("EDAMTransactionException: " +e.getMessage());
6156 if (historyNote != null)
6157 historyWindow.setContent(historyNote);
6163 private void loadHistoryWindowContent(Note note) {
6164 note.setUpdateSequenceNum(0);
6165 historyWindow.setContent(note);
6167 @SuppressWarnings("unused")
6168 private void restoreHistoryNoteAsNew() {
6169 setMessage(tr("Restoring as new note."));
6170 duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6171 setMessage(tr("Note has been restored as a new note."));
6173 @SuppressWarnings("unused")
6174 private void restoreHistoryNote() {
6175 setMessage(tr("Restoring note."));
6176 Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6177 conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6180 for (int i=0; i<n.getResourcesSize(); i++) {
6181 n.getResources().get(i).setActive(true);
6182 conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6184 NoteMetadata metadata = new NoteMetadata();
6185 metadata.setGuid(n.getGuid());
6186 listManager.addNote(n, metadata);
6187 conn.getNoteTable().addNote(n, true);
6188 refreshEvernoteNote(true);
6189 setMessage(tr("Note has been restored."));
6191 @SuppressWarnings("unused")
6192 private void setupSelectiveSync() {
6194 // Get a list of valid notebooks
6195 List<Notebook> notebooks = null;
6196 List<Tag> tags = null;
6197 List<LinkedNotebook> linkedNotebooks = null;
6199 notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6200 tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6201 linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6202 } catch (EDAMUserException e) {
6203 setMessage("EDAMUserException: " +e.getMessage());
6205 } catch (EDAMSystemException e) {
6206 setMessage("EDAMSystemException: " +e.getMessage());
6208 } catch (TException e) {
6209 setMessage("EDAMTransactionException: " +e.getMessage());
6211 } catch (EDAMNotFoundException e) {
6212 setMessage("EDAMNotFoundException: " +e.getMessage());
6216 // Split up notebooks into synchronized & non-synchronized
6217 List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6218 List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6220 for (int i=notebooks.size()-1; i>=0; i--) {
6221 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6222 if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6223 ignoredBooks.add(notebooks.get(i));
6224 j=dbIgnoredNotebooks.size();
6229 // split up tags into synchronized & non-synchronized
6230 List<Tag> ignoredTags = new ArrayList<Tag>();
6231 List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6233 for (int i=tags.size()-1; i>=0; i--) {
6234 for (int j=0; j<dbIgnoredTags.size(); j++) {
6235 if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6236 ignoredTags.add(tags.get(i));
6237 j=dbIgnoredTags.size();
6242 // split up linked notebooks into synchronized & non-synchronized
6243 List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6244 List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6245 for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6246 String notebookGuid = linkedNotebooks.get(i).getGuid();
6247 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6248 if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6249 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6250 j=dbIgnoredLinkedNotebooks.size();
6255 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6257 if (!ignore.okClicked())
6262 // Clear out old notebooks & add the new ones
6263 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6264 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6265 conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6268 List<String> newNotebooks = new ArrayList<String>();
6269 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6270 String text = ignore.getIgnoredBookList().takeItem(i).text();
6271 for (int j=0; j<notebooks.size(); j++) {
6272 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6273 Notebook n = notebooks.get(j);
6274 conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6276 newNotebooks.add(n.getGuid());
6281 // Clear out old tags & add new ones
6282 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6283 for (int i=0; i<oldIgnoreTags.size(); i++) {
6284 conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6287 List<String> newTags = new ArrayList<String>();
6288 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6289 String text = ignore.getIgnoredTagList().takeItem(i).text();
6290 for (int j=0; j<tags.size(); j++) {
6291 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6292 Tag t = tags.get(j);
6293 conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6294 newTags.add(t.getGuid());
6300 // Clear out old tags & add new ones
6301 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6302 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6303 conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6306 List<String> newLinked = new ArrayList<String>();
6307 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6308 String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6309 for (int j=0; j<linkedNotebooks.size(); j++) {
6310 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6311 LinkedNotebook t = linkedNotebooks.get(j);
6312 conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6313 newLinked.add(t.getGuid());
6314 j=linkedNotebooks.size();
6319 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6325 //**********************************************************
6326 //**********************************************************
6327 //* XML Modifying methods
6328 //**********************************************************
6329 //**********************************************************
6330 // An error has happended fetching a resource. let the user know
6331 private void resourceErrorMessage() {
6335 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6336 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6337 "In a perfect world this wouldn't happen, but it has.\n" +
6338 "It is embarasing when a program like me, designed to save all your\n"+
6339 "precious data, has a problem finding data.\n\n" +
6340 "I guess life isn't fair, but I'll survive. Somehow...\n\n" +
6341 "In the mean time, I'm not going to let you make changes to this note.\n" +
6342 "Don't get angry. I'm doing it to prevent you from messing up\n"+
6343 "this note on the Evernote servers. Sorry."+
6344 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6346 browserWindow.setReadOnly(true);
6353 //**********************************************************
6354 //**********************************************************
6356 //**********************************************************
6357 //**********************************************************
6358 // We should now do a sync with Evernote
6359 private void syncTimer() {
6360 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6361 syncRunner.syncNeeded = true;
6362 syncRunner.disableUploads = Global.disableUploads;
6364 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6366 private void syncStart() {
6367 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6369 if (!syncRunning && Global.isConnected) {
6370 syncRunner.setConnected(true);
6371 syncRunner.setKeepRunning(Global.keepRunning);
6372 syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6374 if (syncThreadsReady > 0) {
6375 thumbnailRunner.interrupt = true;
6376 saveNoteIndexWidth();
6377 saveNoteColumnPositions();
6378 if (syncRunner.addWork("SYNC")) {
6380 syncRunner.syncNeeded = true;
6385 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6387 @SuppressWarnings("unused")
6388 private void syncThreadComplete(Boolean refreshNeeded) {
6389 setMessage(tr("Finalizing Synchronization"));
6391 syncRunning = false;
6392 syncRunner.syncNeeded = false;
6393 synchronizeAnimationTimer.stop();
6394 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6396 if (currentNote == null) {
6397 currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6399 listManager.refreshNoteMetadata();
6400 noteIndexUpdated(true);
6401 noteTableView.selectionModel().blockSignals(true);
6402 scrollToGuid(currentNoteGuid);
6403 noteTableView.selectionModel().blockSignals(false);
6404 refreshEvernoteNote(false);
6405 scrollToGuid(currentNoteGuid);
6408 // Check to see if there were any shared notebook errors
6409 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6410 String guid = syncRunner.errorSharedNotebooks.get(0);
6411 String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6412 String localName = listManager.getNotebookNameByGuid(notebookGuid);
6413 SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6415 if (syncDialog.okPressed()) {
6416 if (syncDialog.doNothing.isChecked()) {
6417 syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6420 if (syncDialog.deleteNotebook.isChecked()) {
6421 conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6422 conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6423 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6424 conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6432 // Finalize the synchronization
6433 if (!syncRunner.error)
6434 setMessage(tr("Synchronization Complete"));
6436 setMessage(tr("Synchronization completed with errors. Please check the log for details."));
6437 logger.log(logger.MEDIUM, "Sync complete.");
6439 public void saveUploadAmount(long t) {
6440 Global.saveUploadAmount(t);
6442 public void saveUserInformation(User user) {
6443 Global.saveUserInformation(user);
6445 public void saveEvernoteUpdateCount(int i) {
6446 Global.saveEvernoteUpdateCount(i);
6448 public void refreshLists() {
6449 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6451 listManager.refreshLists(currentNote, noteDirty, browserWindow.getContent());
6452 tagIndexUpdated(true);
6453 notebookIndexUpdated();
6454 savedSearchIndexUpdated();
6455 listManager.loadNotesIndex();
6457 noteTableView.selectionModel().blockSignals(true);
6458 noteIndexUpdated(true);
6459 noteTableView.selectionModel().blockSignals(false);
6460 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6464 @SuppressWarnings("unused")
6465 private void authTimer() {
6466 Calendar cal = Calendar.getInstance();
6468 // If we are not connected let's get out of here
6469 if (!Global.isConnected)
6472 // If this is the first time through, then we need to set this
6473 // if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime)
6474 // syncRunner.authRefreshTime = cal.getTimeInMillis();
6476 // long now = new Date().getTime();
6477 // if (now > Global.authRefreshTime && Global.isConnected) {
6478 syncRunner.authRefreshNeeded = true;
6482 @SuppressWarnings("unused")
6483 private void authRefreshComplete(boolean goodSync) {
6484 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6485 Global.isConnected = syncRunner.isConnected;
6487 // authTimer.start((int)syncRunner.authTimeRemaining/4);
6488 authTimer.start(1000*60*15);
6489 logger.log(logger.LOW, "Authentication token has been renewed");
6490 // setMessage("Authentication token has been renewed.");
6492 authTimer.start(1000*60*5);
6493 logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6494 // setMessage("Authentication token renew has failed - retry in 5 minutes.");
6496 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6500 @SuppressWarnings("unused")
6501 private synchronized void indexTimer() {
6502 logger.log(logger.EXTREME, "Index timer activated. Sync running="+syncRunning);
6505 if (!indexDisabled && indexRunner.idle) {
6506 thumbnailRunner.interrupt = true;
6507 indexRunner.addWork("SCAN");
6509 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6512 @SuppressWarnings("unused")
6513 private void indexStarted() {
6514 setMessage(tr("Indexing notes"));
6516 @SuppressWarnings("unused")
6517 private void indexComplete() {
6518 setMessage(tr("Index complete"));
6520 @SuppressWarnings("unused")
6521 private synchronized void toggleNoteIndexing() {
6522 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6523 indexDisabled = !indexDisabled;
6525 setMessage(tr("Indexing is now enabled."));
6527 setMessage(tr("Indexing is now disabled."));
6528 menuBar.disableIndexing.setChecked(indexDisabled);
6529 logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6532 @SuppressWarnings("unused")
6533 private void threadMonitorCheck() {
6538 alive = listManager.threadCheck(Global.tagCounterThreadId);
6541 if (tagDeadCount > MAX && !disableTagThreadCheck) {
6542 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
6543 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6544 disableTagThreadCheck = true;
6549 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6551 notebookThreadDeadCount++;
6552 if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6553 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
6554 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6555 disableNotebookThreadCheck=true;
6558 notebookThreadDeadCount=0;
6560 alive = listManager.threadCheck(Global.trashCounterThreadId);
6563 if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6564 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
6565 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6566 disableTrashThreadCheck = true;
6571 alive = listManager.threadCheck(Global.saveThreadId);
6573 saveThreadDeadCount++;
6574 if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6575 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
6576 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6577 disableSaveThreadCheck = true;
6580 saveThreadDeadCount=0;
6582 if (!syncThread.isAlive()) {
6583 syncThreadDeadCount++;
6584 if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6585 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
6586 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6587 disableSyncThreadCheck = true;
6590 syncThreadDeadCount=0;
6592 if (!indexThread.isAlive()) {
6593 indexThreadDeadCount++;
6594 if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6595 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
6596 "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
6597 disableIndexThreadCheck = true;
6600 indexThreadDeadCount=0;
6605 private void thumbnailTimer() {
6606 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6607 thumbnailRunner.addWork("SCAN");
6611 //**************************************************
6612 //* Backup & Restore
6613 //**************************************************
6614 @SuppressWarnings("unused")
6615 private void databaseBackup() {
6616 QFileDialog fd = new QFileDialog(this);
6617 fd.setFileMode(FileMode.AnyFile);
6618 fd.setConfirmOverwrite(true);
6619 fd.setWindowTitle(tr("Backup Database"));
6620 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6621 fd.setAcceptMode(AcceptMode.AcceptSave);
6622 if (saveLastPath == null || saveLastPath.equals(""))
6623 fd.setDirectory(System.getProperty("user.home"));
6625 fd.setDirectory(saveLastPath);
6626 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6632 saveLastPath = fd.selectedFiles().get(0);
6633 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6634 setMessage(tr("Backing up database"));
6636 // conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6638 ExportData noteWriter = new ExportData(conn, true);
6639 String fileName = fd.selectedFiles().get(0);
6641 if (!fileName.endsWith(".nnex"))
6642 fileName = fileName +".nnex";
6643 noteWriter.exportData(fileName);
6644 setMessage(tr("Database backup completed."));
6649 @SuppressWarnings("unused")
6650 private void databaseRestore() {
6651 if (QMessageBox.question(this, tr("Confirmation"),
6652 tr("This is used to restore a database from backups.\n" +
6653 "It is HIGHLY recommened that this only be used to populate\n" +
6654 "an empty database. Restoring into a database that\n already has data" +
6655 " can cause problems.\n\nAre you sure you want to continue?"),
6656 QMessageBox.StandardButton.Yes,
6657 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6662 QFileDialog fd = new QFileDialog(this);
6663 fd.setFileMode(FileMode.ExistingFile);
6664 fd.setConfirmOverwrite(true);
6665 fd.setWindowTitle(tr("Restore Database"));
6666 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6667 fd.setAcceptMode(AcceptMode.AcceptOpen);
6668 if (saveLastPath == null || saveLastPath.equals(""))
6669 fd.setDirectory(System.getProperty("user.home"));
6671 fd.setDirectory(saveLastPath);
6672 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6678 saveLastPath = fd.selectedFiles().get(0);
6679 saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6681 setMessage(tr("Restoring database"));
6682 ImportData noteReader = new ImportData(conn, true);
6683 noteReader.importData(fd.selectedFiles().get(0));
6685 if (noteReader.lastError != 0) {
6686 setMessage(noteReader.getErrorMessage());
6687 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6692 listManager.loadNoteTitleColors();
6694 refreshEvernoteNote(true);
6695 setMessage(tr("Database has been restored."));
6698 @SuppressWarnings("unused")
6699 private void exportNotes() {
6700 QFileDialog fd = new QFileDialog(this);
6701 fd.setFileMode(FileMode.AnyFile);
6702 fd.setConfirmOverwrite(true);
6703 fd.setWindowTitle(tr("Backup Database"));
6704 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6705 fd.setAcceptMode(AcceptMode.AcceptSave);
6706 fd.setDirectory(System.getProperty("user.home"));
6707 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6713 setMessage(tr("Exporting Notes"));
6716 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6717 selectedNoteGUIDs.add(currentNoteGuid);
6719 ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6720 String fileName = fd.selectedFiles().get(0);
6722 if (!fileName.endsWith(".nnex"))
6723 fileName = fileName +".nnex";
6724 noteWriter.exportData(fileName);
6725 setMessage(tr("Export completed."));
6731 @SuppressWarnings("unused")
6732 private void importNotes() {
6733 QFileDialog fd = new QFileDialog(this);
6734 fd.setFileMode(FileMode.ExistingFile);
6735 fd.setConfirmOverwrite(true);
6736 fd.setWindowTitle(tr("Import Notes"));
6737 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6738 fd.setAcceptMode(AcceptMode.AcceptOpen);
6739 if (saveLastPath == null || saveLastPath.equals(""))
6740 fd.setDirectory(System.getProperty("user.home"));
6742 fd.setDirectory(saveLastPath);
6743 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6749 setMessage(tr("Importing Notes"));
6752 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals(""))
6753 selectedNoteGUIDs.add(currentNoteGuid);
6755 String fileName = fd.selectedFiles().get(0);
6756 // saveLastPath.substring(0,fileName.lastIndexOf("/"));
6758 if (fileName.endsWith(".nnex")) {
6759 ImportData noteReader = new ImportData(conn, false);
6760 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6761 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6763 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6765 noteReader.importData(fileName);
6767 if (noteReader.lastError != 0) {
6768 setMessage(noteReader.getErrorMessage());
6769 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6774 if (fileName.endsWith(".enex")) {
6775 ImportEnex noteReader = new ImportEnex(conn, false);
6776 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0)
6777 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6779 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6782 if (QMessageBox.question(this, tr("Confirmation"),
6783 tr("Create new tags from import?"),
6784 QMessageBox.StandardButton.Yes,
6785 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6786 noteReader.createNewTags = true;
6788 noteReader.createNewTags = false;
6790 noteReader.importData(fileName);
6792 if (noteReader.lastError != 0) {
6793 setMessage(noteReader.getErrorMessage());
6794 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6801 listManager.loadNoteTitleColors();
6803 refreshEvernoteNote(false);
6804 setMessage(tr("Notes have been imported."));
6807 setMessage(tr("Import completed."));
6814 //**************************************************
6815 //* Duplicate a note
6816 //**************************************************
6817 @SuppressWarnings("unused")
6818 private void duplicateNote() {
6820 duplicateNote(currentNoteGuid);
6823 //**************************************************
6824 //* Action from when a user clicks Copy As URL
6825 //**************************************************
6826 @SuppressWarnings("unused")
6827 private void copyAsUrlClicked() {
6828 QClipboard clipboard = QApplication.clipboard();
6829 QMimeData mime = new QMimeData();
6831 mime.setText(currentNoteGuid);
6832 List<QUrl> urls = new ArrayList<QUrl>();
6834 // Start building the URL
6835 User user = Global.getUserInformation();
6837 // Check that we have everything we need
6838 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
6839 SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
6841 if (!warning.neverSynchronize())
6844 Global.setBypassSynchronizationWarning(true);
6845 user.setShardId("s0");
6851 // Start building a list of URLs based upon the selected notes
6852 noteTableView.showColumn(Global.noteTableGuidPosition);
6854 List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
6855 if (!Global.isColumnVisible("guid"))
6856 noteTableView.hideColumn(Global.noteTableGuidPosition);
6858 // Check that the note is either synchronized, or in a local notebook
6859 for (int i=0; i<selections.size(); i++) {
6861 int row = selections.get(i).row();
6862 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
6863 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
6864 String selectedGuid = (String)ix.values().toArray()[0];
6866 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
6867 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
6868 QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
6869 "new notes to a local notebook."));
6874 // Start building the URLs
6875 for (int i=0; i<selections.size(); i++) {
6877 int row = selections.get(i).row();
6878 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
6879 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
6880 String selectedGuid = (String)ix.values().toArray()[0];
6881 mime.setText(selectedGuid);
6885 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
6886 if (selectedNote.getUpdateSequenceNum() > 0) {
6890 gid = "00000000-0000-0000-0000-000000000000";
6893 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
6895 urls.add(new QUrl(url));
6898 clipboard.setMimeData(mime);
6902 //**************************************************
6904 //**************************************************
6905 public void setupFolderImports() {
6906 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
6908 if (importKeepWatcher == null)
6909 importKeepWatcher = new QFileSystemWatcher();
6910 if (importDeleteWatcher == null) {
6911 importDeleteWatcher = new QFileSystemWatcher();
6912 for (int i=0; i<records.size(); i++) {
6913 if (!records.get(i).keep)
6914 folderImportDelete(records.get(i).folder);
6920 // importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
6921 for (int i=0; i<records.size(); i++) {
6922 logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
6923 if (records.get(i).keep)
6924 importKeepWatcher.addPath(records.get(i).folder);
6926 importDeleteWatcher.addPath(records.get(i).folder);
6929 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
6930 List<String> monitorDelete = importKeepWatcher.directories();
6931 for (int i=0; i<monitorDelete.size(); i++) {
6932 logger.log(logger.EXTREME, monitorDelete.get(i));
6934 logger.log(logger.EXTREME, "<end of list>");
6935 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
6936 monitorDelete = importDeleteWatcher.directories();
6937 for (int i=0; i<monitorDelete.size(); i++) {
6938 logger.log(logger.EXTREME, monitorDelete.get(i));
6940 logger.log(logger.EXTREME, "<end of list>");
6942 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
6943 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
6945 // Look at the files already there so we don't import them again if a new file is created
6946 if (importedFiles == null) {
6947 importedFiles = new ArrayList<String>();
6948 for (int j=0; j<records.size(); j++) {
6949 QDir dir = new QDir(records.get(j).folder);
6950 List<QFileInfo> list = dir.entryInfoList();
6951 for (int k=0; k<list.size(); k++) {
6952 if (list.get(k).isFile())
6953 importedFiles.add(list.get(k).absoluteFilePath());
6959 // Menu folderImport action triggered
6960 public void folderImport() {
6961 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
6962 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
6964 if (!dialog.okClicked())
6967 // We have some sort of update.
6968 if (importKeepWatcher.directories().size() > 0)
6969 importKeepWatcher.removePaths(importKeepWatcher.directories());
6970 if (importDeleteWatcher.directories().size() > 0)
6971 importDeleteWatcher.removePaths(importDeleteWatcher.directories());
6973 conn.getWatchFolderTable().expungeAll();
6974 // Start building from the table
6975 for (int i=0; i<dialog.table.rowCount(); i++) {
6976 QTableWidgetItem item = dialog.table.item(i, 0);
6977 String dir = item.text();
6978 item = dialog.table.item(i, 1);
6979 String notebook = item.text();
6980 item = dialog.table.item(i, 2);
6982 if (item.text().equalsIgnoreCase("Keep"))
6987 String guid = conn.getNotebookTable().findNotebookByName(notebook);
6988 conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
6990 setupFolderImports();
6994 public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
6995 logger.log(logger.LOW, "Inside folderImportKeep");
6996 String whichOS = System.getProperty("os.name");
6997 if (whichOS.contains("Windows"))
6998 dirName = dirName.replace('/','\\');
7000 FileImporter importer = new FileImporter(logger, conn);
7002 QDir dir = new QDir(dirName);
7003 List<QFileInfo> list = dir.entryInfoList();
7004 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7006 for (int i=0; i<list.size(); i++){
7007 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7008 boolean redundant = false;
7009 // Check if we've already imported this one or if it existed before
7010 for (int j=0; j<importedFiles.size(); j++) {
7011 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7012 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7016 logger.log(logger.LOW, "Checking if redundant: " +redundant);
7018 importer.setFileInfo(list.get(i));
7019 importer.setFileName(list.get(i).absoluteFilePath());
7022 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7023 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7024 if (list.get(i).isFile() && importer.isValidType()) {
7026 if (!importer.importFile()) {
7027 // If we can't get to the file, it is probably locked. We'll try again later.
7028 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7029 importFilesKeep.add(list.get(i).absoluteFilePath());
7032 Note newNote = importer.getNote();
7033 newNote.setNotebookGuid(notebook);
7034 newNote.setTitle(dir.at(i));
7035 NoteMetadata metadata = new NoteMetadata();
7036 metadata.setDirty(true);
7037 metadata.setGuid(newNote.getGuid());
7038 listManager.addNote(newNote, metadata);
7039 conn.getNoteTable().addNote(newNote, true);
7040 noteTableView.insertRow(newNote, metadata, true, -1);
7041 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7042 listManager.countNotebookResults(listManager.getNoteIndex());
7043 importedFiles.add(list.get(i).absoluteFilePath());
7052 public void folderImportDelete(String dirName) {
7053 logger.log(logger.LOW, "Inside folderImportDelete");
7054 String whichOS = System.getProperty("os.name");
7055 if (whichOS.contains("Windows"))
7056 dirName = dirName.replace('/','\\');
7058 FileImporter importer = new FileImporter(logger, conn);
7059 QDir dir = new QDir(dirName);
7060 List<QFileInfo> list = dir.entryInfoList();
7061 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7063 for (int i=0; i<list.size(); i++){
7064 logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7065 importer.setFileInfo(list.get(i));
7066 importer.setFileName(list.get(i).absoluteFilePath());
7068 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7069 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7070 if (list.get(i).isFile() && importer.isValidType()) {
7072 if (!importer.importFile()) {
7073 // If we can't get to the file, it is probably locked. We'll try again later.
7074 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7075 importFilesKeep.add(list.get(i).absoluteFilePath());
7078 Note newNote = importer.getNote();
7079 newNote.setNotebookGuid(notebook);
7080 newNote.setTitle(dir.at(i));
7081 NoteMetadata metadata = new NoteMetadata();
7082 metadata.setDirty(true);
7083 metadata.setGuid(newNote.getGuid());
7084 listManager.addNote(newNote, metadata);
7085 conn.getNoteTable().addNote(newNote, true);
7086 noteTableView.insertRow(newNote, metadata, true, -1);
7087 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7088 listManager.countNotebookResults(listManager.getNoteIndex());
7089 dir.remove(dir.at(i));
7096 //**************************************************
7098 //**************************************************
7099 private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7100 logger.log(logger.HIGH, "Entering exernalFileEdited");
7102 // Strip URL prefix and base dir path
7103 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7104 String name = fileName.replace(dPath, "");
7105 int pos = name.lastIndexOf('.');
7108 guid = guid.substring(0,pos);
7110 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7112 guid = name.substring(0, pos);
7115 QFile file = new QFile(fileName);
7116 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
7117 // If we can't get to the file, it is probably locked. We'll try again later.
7118 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7119 externalFiles.add(fileName);
7122 QByteArray binData = file.readAll();
7124 if (binData.size() == 0) {
7125 // If we can't get to the file, it is probably locked. We'll try again later.
7126 logger.log(logger.LOW, "Unable to save externally edited file. Saving for later.");
7127 externalFiles.add(fileName);
7131 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7133 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7134 if (r == null || r.getData() == null || r.getData().getBody() == null)
7136 String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7137 MessageDigest md = MessageDigest.getInstance("MD5");
7138 md.update(binData.toByteArray());
7139 byte[] hash = md.digest();
7140 String newHash = Global.byteArrayToHexString(hash);
7141 if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7142 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7144 if (externalWindows.containsKey(r.getNoteGuid())) {
7145 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(),
7146 r.getGuid(), oldHash, newHash);
7148 conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7149 Data data = r.getData();
7150 data.setBody(binData.toByteArray());
7151 data.setBodyHash(hash);
7152 logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7154 conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7156 if (r.getNoteGuid().equals(currentNoteGuid)) {
7157 QWebSettings.setMaximumPagesInCache(0);
7158 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7159 refreshEvernoteNote(true);
7160 browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7163 if (externalWindows.containsKey(r.getNoteGuid())) {
7164 QWebSettings.setMaximumPagesInCache(0);
7165 QWebSettings.setObjectCacheCapacities(0, 0, 0);
7166 externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7170 logger.log(logger.HIGH, "Exiting externalFielEdited");
7172 // This is a timer event that tries to save any external files that were edited. This
7173 // is only needed if we couldn't save a file earlier.
7174 public void externalFileEditedSaver() {
7175 for (int i=externalFiles.size()-1; i>=0; i--) {
7177 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7178 externalFileEdited(externalFiles.get(i));
7179 externalFiles.remove(i);
7180 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7182 for (int i=0; i<importFilesKeep.size(); i++) {
7184 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7185 folderImportKeep(importFilesKeep.get(i));
7186 importFilesKeep.remove(i);
7187 } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7189 for (int i=0; i<importFilesDelete.size(); i++) {
7190 logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7191 folderImportDelete(importFilesDelete.get(i));
7192 importFilesDelete.remove(i);
7199 // If an attachment on the current note was edited, we need to update the current notes's hash
7200 // Update a note content's hash. This happens if a resource is edited outside of NN
7201 public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7202 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7204 for (;position>-1;) {
7205 endPos = browser.getContent().indexOf(">", position+1);
7206 String oldSegment = browser.getContent().substring(position,endPos);
7207 int hashPos = oldSegment.indexOf("hash=\"");
7208 int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7209 String hash = oldSegment.substring(hashPos+6, hashEnd);
7210 if (hash.equalsIgnoreCase(oldHash)) {
7211 String newSegment = oldSegment.replace(oldHash, newHash);
7212 String content = browser.getContent().substring(0,position) +
7214 browser.getContent().substring(endPos);
7215 browser.setContent(new QByteArray(content));;
7218 position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7223 //*************************************************
7224 //* Minimize to tray
7225 //*************************************************
7227 public void changeEvent(QEvent e) {
7228 if (e.type() == QEvent.Type.WindowStateChange) {
7229 if (QSystemTrayIcon.isSystemTrayAvailable()) {
7230 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7232 QTimer.singleShot(10, this, "hide()");
7236 windowMaximized = true;
7238 windowMaximized = false;
7243 //*************************************************
7244 //* Check database userid & passwords
7245 //*************************************************
7246 private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7247 Connection connection;
7250 Class.forName("org.h2.Driver");
7251 } catch (ClassNotFoundException e1) {
7252 e1.printStackTrace();
7257 String passwordString = null;
7258 if (cypherPassword==null || cypherPassword.trim().equals(""))
7259 passwordString = userPassword;
7261 passwordString = cypherPassword+" "+userPassword;
7262 connection = DriverManager.getConnection(url,userid,passwordString);
7263 } catch (SQLException e) {
7268 } catch (SQLException e) {
7269 e.printStackTrace();
7274 //*************************************************
7275 //* View / Hide source HTML for a note
7276 //*************************************************
7277 public void viewSource() {
7278 // ICHANGED すべてのタブに対して
7279 for(int i = 0; i < tabBrowser.count(); i++){
7280 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7281 browser.showSource(menuBar.viewSource.isChecked());
7284 //*************************************************
7285 // Block the program. This is used for things
7286 // like async web calls.
7287 //*************************************************
7288 @SuppressWarnings("unused")
7289 private void blockApplication(BrowserWindow b) {
7290 // Block all signals
7294 blockTimer = new QTimer();
7295 blockTimer.setSingleShot(true);
7296 blockTimer.setInterval(15000);
7297 blockTimer.timeout.connect(this, "unblockApplication()");
7302 @SuppressWarnings("unused")
7303 private void unblockApplication() {
7305 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7306 QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7307 blockingWindow.unblockTime = -1;
7308 blockingWindow.awaitingHttpResponse = false;
7310 blockingWindow = null;
7311 blockSignals(false);
7316 private void tabWindowChanged(int index) {
7317 if (index < 0 || index >= tabBrowser.count()) {
7323 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7324 if (tab.getBrowserWindow().getNote() != null) {
7325 currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7326 currentNote = tab.getBrowserWindow().getNote();
7328 currentNoteGuid = "";
7333 selectedNoteGUIDs.clear();
7334 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7335 selectedNoteGUIDs.add(currentNoteGuid);
7339 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7340 browserWindow.focusLost.disconnect(this, "saveNote()");
7341 browserWindow = tab.getBrowserWindow();
7342 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7343 browserWindow.focusLost.connect(this, "saveNote()");
7344 // メニューバーのボタンを新しいbrowserWindowに合わせる
7345 menuBar.refreshTargetWindow();
7347 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7348 boolean nextIsActive;
7349 if (tab.getBrowserWindow().getNote() != null) {
7350 nextIsActive = tab.getBrowserWindow().getNote().isActive();
7352 nextIsActive = true;
7354 if (Global.showDeleted && nextIsActive) {
7355 switchNoteTable(false);
7356 } else if (!Global.showDeleted && !nextIsActive) {
7357 switchNoteTable(true);
7360 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7361 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7362 scrollToGuid(currentNoteGuid);
7364 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7366 menuBar.noteDuplicateAction.setEnabled(true);
7367 menuBar.noteOnlineHistoryAction.setEnabled(true);
7368 menuBar.noteMergeAction.setEnabled(true);
7370 if (Global.showDeleted) {
7371 menuBar.noteDuplicateAction.setEnabled(false);
7373 if (!Global.isConnected) {
7374 menuBar.noteOnlineHistoryAction.setEnabled(false);
7376 menuBar.noteMergeAction.setEnabled(false);
7378 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7380 upButton.setEnabled(false);
7382 upButton.setEnabled(true);
7383 if (row < listManager.getNoteTableModel().rowCount() - 1)
7384 downButton.setEnabled(true);
7386 downButton.setEnabled(false);
7387 } catch (Exception e) {
7388 upButton.setEnabled(false);
7389 downButton.setEnabled(false);
7392 int currentIndex = tabBrowser.currentIndex();
7393 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7394 int histPosition = historyPosition.get(currentIndex);
7396 // prev, nextボタンの有効・無効化
7397 nextButton.setEnabled(true);
7398 prevButton.setEnabled(true);
7400 if (histPosition <= 1){
7401 prevButton.setEnabled(false);
7403 if (histPosition == histGuids.size()){
7404 nextButton.setEnabled(false);
7407 refreshEvernoteNote(true);
7410 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7414 // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7415 private void switchNoteTable(boolean toDeleted) {
7416 clearNotebookFilter();
7418 clearAttributeFilter();
7419 clearSavedSearchFilter();
7421 listManager.getSelectedNotebooks().clear();
7422 listManager.getSelectedTags().clear();
7423 listManager.setSelectedSavedSearch("");
7425 // toggle the add buttons
7426 newButton.setEnabled(!newButton.isEnabled());
7427 menuBar.noteAdd.setEnabled(newButton.isEnabled());
7428 menuBar.noteAdd.setVisible(true);
7430 if (!toDeleted) { // 生存ノートテーブルへ
7431 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7432 trashTree.clearSelection();
7433 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7434 Global.showDeleted = false;
7435 menuBar.noteRestoreAction.setEnabled(false);
7436 menuBar.noteRestoreAction.setVisible(false);
7437 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7438 rensoNoteListDock.setEnabled(true);
7440 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7441 trashTree.setCurrentItem(trashTree.getTrashItem());
7442 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7443 Global.showDeleted = true;
7444 menuBar.noteRestoreAction.setEnabled(true);
7445 menuBar.noteRestoreAction.setVisible(true);
7446 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
7447 rensoNoteListDock.setEnabled(false);
7450 listManager.loadNotesIndex();
7451 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7452 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7453 noteIndexUpdated(false);
7455 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7457 browserWindow.setReadOnly(!newButton.isEnabled());
7461 // ユーザが連想ノートリストのアイテムを選択した時の処理
7462 @SuppressWarnings("unused")
7463 private void rensoNoteItemPressed(QListWidgetItem current) {
7464 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7466 rensoNotePressedItemGuid = null;
7468 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7469 rensoNotePressedItemGuid = rensoNoteList.getNoteGuid(current);
7475 String prevCurrentNoteGuid = new String(currentNoteGuid);
7477 // 選択されたノート(current)のguidをcurrentnoteguidにセット
7478 currentNoteGuid = rensoNoteList.getNoteGuid(current);
7481 selectedNoteGUIDs.clear();
7482 selectedNoteGUIDs.add(currentNoteGuid);
7484 nextButton.setEnabled(true);
7485 prevButton.setEnabled(true);
7487 int currentIndex = tabBrowser.currentIndex();
7488 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7489 int histPosition = historyPosition.get(currentIndex);
7490 boolean fromHist = fromHistory.get(currentIndex);
7492 int endPosition = histGuids.size() - 1;
7493 for (int j = histPosition; j <= endPosition; j++) {
7494 histGuids.remove(histGuids.size() - 1);
7497 histGuids.add(currentNoteGuid);
7498 historyPosition.put(currentIndex, histGuids.size());
7499 histPosition = histGuids.size();
7501 if (histPosition <= 1)
7502 prevButton.setEnabled(false);
7503 if (histPosition == histGuids.size())
7504 nextButton.setEnabled(false);
7506 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7507 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
7508 scrollToGuid(currentNoteGuid);
7510 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
7512 refreshEvernoteNote(true); // Evernoteからノートをゲット(そしてブラウザに表示)
7514 // upButton, downButton, 選択リストア用のprevRowを設定
7515 int row = noteTableView.selectionModel().selectedRows().get(0).row();
7517 upButton.setEnabled(false);
7519 upButton.setEnabled(true);
7520 if (row < listManager.getNoteTableModel().rowCount() - 1)
7521 downButton.setEnabled(true);
7523 downButton.setEnabled(false);
7525 // 連想ノートリストアイテムクリック操作を記録
7526 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7529 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7531 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7535 public void restoreSelectedNoteInfo(){
7537 // currentNoteGuid = browserWindow.getNote().getGuid(); ↓と同じはずだけど敢えて使わない
7538 int currentTabIndex = tabBrowser.currentIndex();
7539 TabBrowse currentTab = tabWindows.get(currentTabIndex);
7540 currentNoteGuid = currentTab.getBrowserWindow().getNote().getGuid();
7542 selectedNoteGUIDs.clear();
7543 selectedNoteGUIDs.add(currentNoteGuid);
7545 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7546 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
7547 scrollToGuid(currentNoteGuid);
7549 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
7553 // 関連ノートリストからノートを除外する
7554 @SuppressWarnings("unused")
7555 private void excludeNote() {
7556 if (rensoNotePressedItemGuid != null) {
7558 excludeNote(rensoNotePressedItemGuid);
7563 // 関連ノートリストからノートを除外する
7564 private void excludeNote(String guid) {
7565 if (Global.verifyExclude()) {
7567 Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7568 String title = note.getTitle();
7569 if (title != null) {
7570 msg = new String(tr("Exclude note \"") +title +"\"?");
7572 msg = new String(tr("Exclude note selected note?"));
7575 if (QMessageBox.question(this, tr("Confirmation"), msg,
7576 QMessageBox.StandardButton.Yes,
7577 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7582 // Historyデータベースから除外するノートのデータを削除
7583 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7586 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7588 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7592 // 関連ノートリストのノートにスターを付ける
7593 @SuppressWarnings("unused")
7594 private void starNote() {
7595 if (rensoNotePressedItemGuid != null) {
7597 starNote(rensoNotePressedItemGuid);
7602 // 関連ノートリストのノートにスターを付ける
7603 private void starNote(String guid) {
7605 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7607 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7611 // 関連ノートリストのノートからスターを外す
7612 @SuppressWarnings("unused")
7613 private void unstarNote() {
7614 if (rensoNotePressedItemGuid != null) {
7616 unstarNote(rensoNotePressedItemGuid);
7621 // 関連ノートリストのノートからスターを外す
7622 private void unstarNote(String guid) {
7624 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7626 rensoNoteList.refreshRensoNoteList(currentNoteGuid);
7630 // currentNoteGuidを返す
7631 public String getCurrentNoteGuid() {
7632 return currentNoteGuid;