2 * This file is part of NeverNote
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.net.Authenticator;
25 import java.net.PasswordAuthentication;
26 import java.security.MessageDigest;
27 import java.security.NoSuchAlgorithmException;
28 import java.sql.Connection;
29 import java.sql.DriverManager;
30 import java.sql.SQLException;
31 import java.sql.Statement;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.Comparator;
38 import java.util.Date;
39 import java.util.GregorianCalendar;
40 import java.util.HashMap;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.SortedMap;
44 import java.util.Vector;
46 import org.apache.log4j.Level;
47 import org.apache.log4j.Logger;
48 import org.apache.thrift.TException;
49 import org.h2.tools.ChangeFileEncryption;
51 import com.evernote.edam.error.EDAMNotFoundException;
52 import com.evernote.edam.error.EDAMSystemException;
53 import com.evernote.edam.error.EDAMUserException;
54 import com.evernote.edam.notestore.NoteFilter;
55 import com.evernote.edam.notestore.NoteVersionId;
56 import com.evernote.edam.type.Data;
57 import com.evernote.edam.type.LinkedNotebook;
58 import com.evernote.edam.type.Note;
59 import com.evernote.edam.type.NoteAttributes;
60 import com.evernote.edam.type.Notebook;
61 import com.evernote.edam.type.Publishing;
62 import com.evernote.edam.type.QueryFormat;
63 import com.evernote.edam.type.Resource;
64 import com.evernote.edam.type.SavedSearch;
65 import com.evernote.edam.type.Tag;
66 import com.evernote.edam.type.User;
67 import com.trolltech.qt.QThread;
68 import com.trolltech.qt.core.QByteArray;
69 import com.trolltech.qt.core.QDateTime;
70 import com.trolltech.qt.core.QDir;
71 import com.trolltech.qt.core.QEvent;
72 import com.trolltech.qt.core.QFile;
73 import com.trolltech.qt.core.QFileInfo;
74 import com.trolltech.qt.core.QFileSystemWatcher;
75 import com.trolltech.qt.core.QIODevice;
76 import com.trolltech.qt.core.QIODevice.OpenModeFlag;
77 import com.trolltech.qt.core.QLocale;
78 import com.trolltech.qt.core.QModelIndex;
79 import com.trolltech.qt.core.QSize;
80 import com.trolltech.qt.core.QTemporaryFile;
81 import com.trolltech.qt.core.QTextCodec;
82 import com.trolltech.qt.core.QThreadPool;
83 import com.trolltech.qt.core.QTimer;
84 import com.trolltech.qt.core.QTranslator;
85 import com.trolltech.qt.core.QUrl;
86 import com.trolltech.qt.core.Qt;
87 import com.trolltech.qt.core.Qt.BGMode;
88 import com.trolltech.qt.core.Qt.ItemDataRole;
89 import com.trolltech.qt.core.Qt.SortOrder;
90 import com.trolltech.qt.core.Qt.WidgetAttribute;
91 import com.trolltech.qt.gui.QAbstractItemView;
92 import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
93 import com.trolltech.qt.gui.QAction;
94 import com.trolltech.qt.gui.QApplication;
95 import com.trolltech.qt.gui.QCloseEvent;
96 import com.trolltech.qt.gui.QColor;
97 import com.trolltech.qt.gui.QComboBox;
98 import com.trolltech.qt.gui.QComboBox.InsertPolicy;
99 import com.trolltech.qt.gui.QCursor;
100 import com.trolltech.qt.gui.QDesktopServices;
101 import com.trolltech.qt.gui.QDialog;
102 import com.trolltech.qt.gui.QFileDialog;
103 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
104 import com.trolltech.qt.gui.QFileDialog.FileMode;
105 import com.trolltech.qt.gui.QGridLayout;
106 import com.trolltech.qt.gui.QHBoxLayout;
107 import com.trolltech.qt.gui.QIcon;
108 import com.trolltech.qt.gui.QImage;
109 import com.trolltech.qt.gui.QLabel;
110 import com.trolltech.qt.gui.QListWidget;
111 import com.trolltech.qt.gui.QMainWindow;
112 import com.trolltech.qt.gui.QMenu;
113 import com.trolltech.qt.gui.QMessageBox;
114 import com.trolltech.qt.gui.QMessageBox.StandardButton;
115 import com.trolltech.qt.gui.QPainter;
116 import com.trolltech.qt.gui.QPalette.ColorRole;
117 import com.trolltech.qt.gui.QPixmap;
118 import com.trolltech.qt.gui.QPrintDialog;
119 import com.trolltech.qt.gui.QPrinter;
120 import com.trolltech.qt.gui.QSizePolicy;
121 import com.trolltech.qt.gui.QSizePolicy.Policy;
122 import com.trolltech.qt.gui.QSpinBox;
123 import com.trolltech.qt.gui.QSplashScreen;
124 import com.trolltech.qt.gui.QSplitter;
125 import com.trolltech.qt.gui.QStatusBar;
126 import com.trolltech.qt.gui.QSystemTrayIcon;
127 import com.trolltech.qt.gui.QTableWidgetItem;
128 import com.trolltech.qt.gui.QTextEdit;
129 import com.trolltech.qt.gui.QToolBar;
130 import com.trolltech.qt.gui.QTreeWidgetItem;
131 import com.trolltech.qt.webkit.QWebPage.WebAction;
132 import com.trolltech.qt.webkit.QWebSettings;
134 import cx.fbn.nevernote.config.InitializationException;
135 import cx.fbn.nevernote.config.StartupConfig;
136 import cx.fbn.nevernote.dialog.AccountDialog;
137 import cx.fbn.nevernote.dialog.ConfigDialog;
138 import cx.fbn.nevernote.dialog.DBEncryptDialog;
139 import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
140 import cx.fbn.nevernote.dialog.DatabaseStatus;
141 import cx.fbn.nevernote.dialog.FindDialog;
142 import cx.fbn.nevernote.dialog.LoginDialog;
143 import cx.fbn.nevernote.dialog.NotebookArchive;
144 import cx.fbn.nevernote.dialog.NotebookEdit;
145 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
146 import cx.fbn.nevernote.dialog.PublishNotebook;
147 import cx.fbn.nevernote.dialog.SavedSearchEdit;
148 import cx.fbn.nevernote.dialog.SetIcon;
149 import cx.fbn.nevernote.dialog.ShareNotebook;
150 import cx.fbn.nevernote.dialog.StackNotebook;
151 import cx.fbn.nevernote.dialog.TagEdit;
152 import cx.fbn.nevernote.dialog.ThumbnailViewer;
153 import cx.fbn.nevernote.dialog.WatchFolder;
154 import cx.fbn.nevernote.filters.FilterEditorNotebooks;
155 import cx.fbn.nevernote.filters.FilterEditorTags;
156 import cx.fbn.nevernote.gui.AttributeTreeWidget;
157 import cx.fbn.nevernote.gui.BrowserWindow;
158 import cx.fbn.nevernote.gui.DateAttributeFilterTable;
159 import cx.fbn.nevernote.gui.ExternalBrowse;
160 import cx.fbn.nevernote.gui.MainMenuBar;
161 import cx.fbn.nevernote.gui.NotebookTreeWidget;
162 import cx.fbn.nevernote.gui.SavedSearchTreeWidget;
163 import cx.fbn.nevernote.gui.TableView;
164 import cx.fbn.nevernote.gui.TagTreeWidget;
165 import cx.fbn.nevernote.gui.Thumbnailer;
166 import cx.fbn.nevernote.gui.TrashTreeWidget;
167 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
168 import cx.fbn.nevernote.sql.DatabaseConnection;
169 import cx.fbn.nevernote.sql.WatchFolderRecord;
170 import cx.fbn.nevernote.threads.IndexRunner;
171 import cx.fbn.nevernote.threads.SyncRunner;
172 import cx.fbn.nevernote.threads.ThumbnailRunner;
173 import cx.fbn.nevernote.utilities.AESEncrypter;
174 import cx.fbn.nevernote.utilities.ApplicationLogger;
175 import cx.fbn.nevernote.utilities.FileImporter;
176 import cx.fbn.nevernote.utilities.FileUtils;
177 import cx.fbn.nevernote.utilities.ListManager;
178 import cx.fbn.nevernote.utilities.SyncTimes;
179 import cx.fbn.nevernote.xml.ExportData;
180 import cx.fbn.nevernote.xml.ImportData;
181 import cx.fbn.nevernote.xml.NoteFormatter;
184 public class NeverNote extends QMainWindow{
186 QStatusBar statusBar; // Application status bar
188 DatabaseConnection conn;
190 MainMenuBar menuBar; // Main menu bar
191 FindDialog find; // Text search in note dialog
192 List<String> emitLog; // Messages displayed in the status bar;
193 QSystemTrayIcon trayIcon; // little tray icon
194 QMenu trayMenu; // System tray menu
195 QAction trayExitAction; // Exit the application
196 QAction trayShowAction; // toggle the show/hide action
197 QAction trayAddNoteAction; // Add a note from the system tray
199 NotebookTreeWidget notebookTree; // List of notebooks
200 AttributeTreeWidget attributeTree; // List of note attributes
201 TagTreeWidget tagTree; // list of user created tags
202 SavedSearchTreeWidget savedSearchTree; // list of saved searches
203 TrashTreeWidget trashTree; // Trashcan
204 TableView noteTableView; // List of notes (the widget).
206 public BrowserWindow browserWindow; // Window containing browser & labels
207 public QToolBar toolBar; // The tool bar under the menu
208 QComboBox searchField; // search filter bar on the toolbar;
209 boolean searchPerformed = false; // Search was done?
210 QuotaProgressBar quotaBar; // The current quota usage
212 ApplicationLogger logger;
213 List<String> selectedNotebookGUIDs; // List of notebook GUIDs
214 List<String> selectedTagGUIDs; // List of selected tag GUIDs
215 String previousSelectedTag; // Tag that was selected last time
216 List<String> selectedNoteGUIDs; // List of selected notes
217 String previousSelectedNotebook; // Notebook selected last time
218 String selectedSavedSearchGUID; // Currently selected saved searches
219 private final HashMap<String, ExternalBrowse> externalWindows; // Notes being edited by an external window;
221 NoteFilter filter; // Note filter
222 String currentNoteGuid; // GUID of the current note
223 Note currentNote; // The currently viewed note
224 boolean noteDirty; // Has the note been changed?
225 boolean inkNote; // if this is an ink note, it is read only
226 boolean readOnly; // Is this note read-only?
229 ListManager listManager; // DB runnable task
231 List<QTemporaryFile> tempFiles; // Array of temporary files;
233 QTimer indexTimer; // timer to start the index thread
234 IndexRunner indexRunner; // thread to index notes
237 QTimer syncTimer; // Sync on an interval
238 QTimer syncDelayTimer; // Sync delay to free up database
239 SyncRunner syncRunner; // thread to do a sync.
240 QThread syncThread; // Thread which talks to evernote
241 ThumbnailRunner thumbnailRunner; // Runner for thumbnail thread
242 QThread thumbnailThread; // Thread that generates pretty pictures
243 QTimer saveTimer; // Timer to save note contents
245 QTimer authTimer; // Refresh authentication
246 QTimer externalFileSaveTimer; // Save files altered externally
247 QTimer thumbnailTimer; // Wakeup & scan for thumbnails
248 List<String> externalFiles; // External files to save later
249 List<String> importFilesKeep; // Auto-import files to save later
250 List<String> importFilesDelete; // Auto-import files to save later
252 int indexTime; // how often to try and index
253 boolean indexRunning; // Is indexing running?
254 boolean indexDisabled; // Is indexing disabled?
256 int syncThreadsReady; // number of sync threads that are free
257 int syncTime; // Sync interval
258 boolean syncRunning; // Is sync running?
259 boolean automaticSync; // do sync automatically?
260 QTreeWidgetItem attributeTreeSelected;
262 QAction prevButton; // Go to the previous item viewed
263 QAction nextButton; // Go to the next item in the history
264 QAction downButton; // Go to the next item in the list
265 QAction upButton; // Go to the prev. item in the list;
266 QAction synchronizeButton; // Synchronize with Evernote
267 QAction allNotesButton; // Reset & view all notes
268 QTimer synchronizeAnimationTimer; // Timer to change animation button
269 int synchronizeIconAngle; // Used to rotate sync icon
270 QAction printButton; // Print Button
271 QAction tagButton; // Tag edit button
272 QAction attributeButton; // Attribute information button
273 QAction emailButton; // Email button
274 QAction deleteButton; // Delete button
275 QAction newButton; // new Note Button;
276 QSpinBox zoomSpinner; // Zoom zoom
277 QAction searchClearButton; // Clear the search field
279 QSplitter mainLeftRightSplitter; // main splitter for left/right side
280 QSplitter leftSplitter1; // first left hand splitter
281 QSplitter browserIndexSplitter; // splitter between note index & note text
283 QFileSystemWatcher importKeepWatcher; // Watch & keep auto-import
284 QFileSystemWatcher importDeleteWatcher; // Watch & Delete auto-import
285 List<String> importedFiles; // History of imported files (so we don't import twice)
287 OnlineNoteHistory historyWindow; // online history window
288 List<NoteVersionId> versions; // history versions
290 QTimer threadMonitorTimer; // Timer to watch threads.
291 int dbThreadDeadCount=0; // number of consecutive dead times for the db thread
292 int syncThreadDeadCount=0; // number of consecutive dead times for the sync thread
293 int indexThreadDeadCount=0; // number of consecutive dead times for the index thread
294 int notebookThreadDeadCount=0; // number of consecutive dead times for the notebook thread
295 int tagDeadCount=0; // number of consecutive dead times for the tag thread
296 int trashDeadCount=0; // number of consecutive dead times for the trash thread
297 int saveThreadDeadCount=0; // number of consecutive dead times for the save thread
299 HashMap<String, String> noteCache; // Cash of note content
300 HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
301 HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
302 List<String> historyGuids; // GUIDs of previously viewed items
303 int historyPosition; // Position within the viewed items
304 boolean fromHistory; // Is this from the history queue?
305 String trashNoteGuid; // Guid to restore / set into or out of trash to save position
306 List<Thumbnailer> thumbGenerators; // generate preview image
307 ThumbnailViewer thumbnailViewer; // View preview thumbnail;
308 boolean encryptOnShutdown; // should I encrypt when I close?
309 boolean decryptOnShutdown; // should I decrypt on shutdown;
310 String encryptCipher; // What cipher should I use?
311 Signal0 minimizeToTray;
312 boolean windowMaximized = false; // Keep track of the window state for restores
313 List<String> pdfReadyQueue; // Queue of PDFs that are ready to be rendered.
314 List<QPixmap> syncIcons; // Array of icons used in sync animation
315 private boolean closeAction = false; // Used to say when to close or when to minimize
316 private static Logger log = Logger.getLogger(NeverNote.class);
319 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
322 //***************************************************************
323 //***************************************************************
324 //** Constructor & main entry point
325 //***************************************************************
326 //***************************************************************
327 // Application Constructor
328 @SuppressWarnings("static-access")
329 public NeverNote(DatabaseConnection dbConn) {
331 if (conn.getConnection() == null) {
332 String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
333 "is accessing the database or NeverNote is already running.\n\n" +
334 "Please end any other process or shutdown the other NeverNote before starting.\n\nExiting program."));
336 QMessageBox.critical(null, tr("Database Connection Error") ,msg);
340 thread().setPriority(Thread.MAX_PRIORITY);
342 logger = new ApplicationLogger("nevernote.log");
343 logger.log(logger.HIGH, "Starting Application");
345 decryptOnShutdown = false;
346 encryptOnShutdown = false;
347 conn.checkDatabaseVersion();
351 // Start building the invalid XML tables
352 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
353 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
355 for (int i=0; i<elements.size(); i++) {
356 Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
359 logger.log(logger.EXTREME, "Starting GUI build");
361 QTranslator nevernoteTranslator = new QTranslator();
362 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("nevernote_" + QLocale.system().name() + ".qm"));
363 QApplication.instance().installTranslator(nevernoteTranslator);
365 Global.originalPalette = QApplication.palette();
366 QApplication.setStyle(Global.getStyle());
367 if (Global.useStandardPalette())
368 QApplication.setPalette(QApplication.style().standardPalette());
369 setWindowTitle("NeverNote");
371 mainLeftRightSplitter = new QSplitter();
372 setCentralWidget(mainLeftRightSplitter);
373 leftSplitter1 = new QSplitter();
374 leftSplitter1.setOrientation(Qt.Orientation.Vertical);
376 browserIndexSplitter = new QSplitter();
377 browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
379 //* Setup threads & thread timers
380 int indexRunnerCount = Global.getIndexThreads();
381 indexRunnerCount = 1;
382 QThreadPool.globalInstance().setMaxThreadCount(indexRunnerCount+5); // increase max thread count
384 logger.log(logger.EXTREME, "Building list manager");
385 listManager = new ListManager(conn, logger);
387 logger.log(logger.EXTREME, "Building index runners & timers");
388 indexRunner = new IndexRunner("indexRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
389 indexThread = new QThread(indexRunner, "Index Thread");
390 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
393 synchronizeAnimationTimer = new QTimer();
394 synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
396 indexTimer = new QTimer();
397 indexTime = 1000*Global.getIndexThreadSleepInterval();
398 indexTimer.start(indexTime); // Start indexing timer
399 indexTimer.timeout.connect(this, "indexTimer()");
400 indexDisabled = false;
401 indexRunning = false;
403 logger.log(logger.EXTREME, "Setting sync thread & timers");
405 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
406 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
407 syncTimer = new QTimer();
408 syncTimer.timeout.connect(this, "syncTimer()");
409 syncRunner.status.message.connect(this, "setMessage(String)");
410 syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
411 syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
414 automaticSync = true;
415 syncTimer.start(syncTime*60*1000);
417 automaticSync = false;
420 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
421 syncThread = new QThread(syncRunner, "Synchronization Thread");
425 logger.log(logger.EXTREME, "Starting thumnail thread");
426 pdfReadyQueue = new ArrayList<String>();
427 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log", Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
428 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
429 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
430 thumbnailThread.start();
431 thumbGenerators = new ArrayList<Thumbnailer>();
432 thumbnailTimer = new QTimer();
433 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
435 thumbnailTimer.setInterval(60*1000); // Thumbnail every minute
436 thumbnailTimer.start();
438 logger.log(logger.EXTREME, "Starting authentication timer");
439 authTimer = new QTimer();
440 authTimer.timeout.connect(this, "authTimer()");
441 authTimer.start(1000*60*15);
442 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
444 logger.log(logger.EXTREME, "Setting save note timer");
445 saveTimer = new QTimer();
446 saveTimer.timeout.connect(this, "saveNote()");
447 if (Global.getAutoSaveInterval() > 0) {
448 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
451 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
453 logger.log(logger.EXTREME, "Starting external file monitor timer");
454 externalFileSaveTimer = new QTimer();
455 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
456 externalFileSaveTimer.setInterval(1000*5); // save every 5 seconds;
457 externalFiles = new ArrayList<String>();
458 importFilesDelete = new ArrayList<String>();
459 importFilesKeep = new ArrayList<String>();
460 externalFileSaveTimer.start();
462 notebookTree = new NotebookTreeWidget(conn);
463 attributeTree = new AttributeTreeWidget();
464 tagTree = new TagTreeWidget(conn);
465 savedSearchTree = new SavedSearchTreeWidget();
466 trashTree = new TrashTreeWidget();
467 noteTableView = new TableView(logger, listManager);
469 QGridLayout leftGrid = new QGridLayout();
470 leftSplitter1.setLayout(leftGrid);
471 leftGrid.addWidget(notebookTree, 1, 1);
472 leftGrid.addWidget(tagTree,2,1);
473 leftGrid.addWidget(attributeTree,3,1);
474 leftGrid.addWidget(savedSearchTree,4,1);
475 leftGrid.addWidget(trashTree, 5, 1);
477 // Setup the browser window
478 noteCache = new HashMap<String,String>();
479 readOnlyCache = new HashMap<String, Boolean>();
480 inkNoteCache = new HashMap<String, Boolean>();
481 browserWindow = new BrowserWindow(conn);
483 mainLeftRightSplitter.addWidget(leftSplitter1);
484 mainLeftRightSplitter.addWidget(browserIndexSplitter);
486 if (Global.getListView() == Global.View_List_Wide) {
487 browserIndexSplitter.addWidget(noteTableView);
488 browserIndexSplitter.addWidget(browserWindow);
490 mainLeftRightSplitter.addWidget(noteTableView);
491 mainLeftRightSplitter.addWidget(browserWindow);
494 searchField = new QComboBox();
495 searchField.setEditable(true);
496 searchField.activatedIndex.connect(this, "searchFieldChanged()");
497 searchField.setDuplicatesEnabled(false);
498 searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
500 quotaBar = new QuotaProgressBar();
502 // Setup the thumbnail viewer
503 thumbnailViewer = new ThumbnailViewer();
504 thumbnailViewer.upArrow.connect(this, "upAction()");
505 thumbnailViewer.downArrow.connect(this, "downAction()");
506 thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
507 thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
509 //Setup external browser manager
510 externalWindows = new HashMap<String, ExternalBrowse>();
512 listManager.loadNotesIndex();
513 initializeNotebookTree();
515 initializeSavedSearchTree();
516 attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
517 attributeTreeSelected = null;
518 initializeNoteTable();
520 selectedNoteGUIDs = new ArrayList<String>();
521 statusBar = new QStatusBar();
522 setStatusBar(statusBar);
523 menuBar = new MainMenuBar(this);
524 emitLog = new ArrayList<String>();
526 tagTree.setDeleteAction(menuBar.tagDeleteAction);
527 tagTree.setEditAction(menuBar.tagEditAction);
528 tagTree.setAddAction(menuBar.tagAddAction);
529 tagTree.setIconAction(menuBar.tagIconAction);
530 tagTree.setVisible(Global.isWindowVisible("tagTree"));
531 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
532 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
533 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
535 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
536 notebookTree.setEditAction(menuBar.notebookEditAction);
537 notebookTree.setAddAction(menuBar.notebookAddAction);
538 notebookTree.setIconAction(menuBar.notebookIconAction);
539 notebookTree.setStackAction(menuBar.notebookStackAction);
540 notebookTree.setPublishAction(menuBar.notebookPublishAction);
541 notebookTree.setShareAction(menuBar.notebookShareAction);
542 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
543 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
544 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
545 notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
546 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
548 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
549 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
550 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
551 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
552 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
553 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
554 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
556 noteTableView.setAddAction(menuBar.noteAdd);
557 noteTableView.setDeleteAction(menuBar.noteDelete);
558 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
559 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
560 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
561 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
562 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
563 noteTableView.rowChanged.connect(this, "scrollToGuid(String)");
564 noteTableView.resetViewport.connect(this, "scrollToCurrentGuid()");
565 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
566 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
568 quotaBar.setMouseClickAction(menuBar.accountAction);
571 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
572 trashTree.setEmptyAction(menuBar.emptyTrashAction);
573 trashTree.setVisible(Global.isWindowVisible("trashTree"));
574 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
575 trashTree.updateCounts(listManager.getTrashCount());
576 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
577 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
579 noteTableView.setVisible(Global.isWindowVisible("noteList"));
580 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
582 if (!Global.isWindowVisible("editorButtonBar"))
583 toggleEditorButtonBar();
584 if (!Global.isWindowVisible("leftPanel"))
585 menuBar.hideLeftSide.setChecked(true);
586 if (Global.isWindowVisible("noteInformation"))
587 toggleNoteInformation();
591 find = new FindDialog();
592 find.getOkButton().clicked.connect(this, "doFindText()");
594 // Setup the tray icon menu bar
595 trayShowAction = new QAction("Show/Hide", this);
596 trayExitAction = new QAction("Exit", this);
597 trayAddNoteAction = new QAction("Add Note", this);
599 trayExitAction.triggered.connect(this, "closeNeverNote()");
600 trayAddNoteAction.triggered.connect(this, "addNote()");
601 trayShowAction.triggered.connect(this, "trayToggleVisible()");
603 trayMenu = new QMenu(this);
604 trayMenu.addAction(trayAddNoteAction);
605 trayMenu.addAction(trayShowAction);
606 trayMenu.addAction(trayExitAction);
609 trayIcon = new QSystemTrayIcon(this);
610 trayIcon.setToolTip("NeverNote");
611 trayIcon.setContextMenu(trayMenu);
612 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
615 currentNoteGuid = Global.getLastViewedNoteGuid();
616 historyGuids = new ArrayList<String>();
620 if (!currentNoteGuid.trim().equals("")) {
621 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
624 noteIndexUpdated(true);
626 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
627 if (menuBar.showEditorBar.isChecked())
628 showEditorButtons(browserWindow);
629 tagIndexUpdated(true);
630 savedSearchIndexUpdated();
631 notebookIndexUpdated();
633 setupSyncSignalListeners();
634 setupBrowserSignalListeners();
635 setupIndexListeners();
638 tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
639 tagTree.showAllTags(true);
641 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
642 setWindowIcon(appIcon);
643 trayIcon.setIcon(appIcon);
644 if (Global.showTrayIcon())
649 scrollToGuid(currentNoteGuid);
650 if (Global.automaticLogin()) {
652 if (Global.isConnected)
655 setupFolderImports();
658 restoreWindowState(true);
660 if (Global.mimicEvernoteInterface) {
661 notebookTree.selectGuid("");
664 threadMonitorTimer = new QTimer();
665 threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
666 threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
668 historyGuids.add(currentNoteGuid);
671 menuBar.blockSignals(true);
672 menuBar.narrowListView.blockSignals(true);
673 menuBar.wideListView.blockSignals(true);
674 if (Global.getListView() == Global.View_List_Narrow) {
675 menuBar.narrowListView.setChecked(true);
678 menuBar.wideListView.setChecked(true);
680 menuBar.blockSignals(false);
681 menuBar.narrowListView.blockSignals(false);
682 menuBar.wideListView.blockSignals(false);
684 if (Global.getListView() == Global.View_List_Wide) {
685 browserIndexSplitter.addWidget(noteTableView);
686 browserIndexSplitter.addWidget(browserWindow);
688 mainLeftRightSplitter.addWidget(noteTableView);
689 mainLeftRightSplitter.addWidget(browserWindow);
692 int sortCol = Global.getSortColumn();
693 int sortOrder = Global.getSortOrder();
694 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
700 public static void main(String[] args) {
701 log.setLevel(Level.FATAL);
702 QApplication.initialize(args);
703 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
704 QSplashScreen splash = new QSplashScreen(pixmap);
707 DatabaseConnection dbConn;
710 initializeGlobalSettings(args);
712 showSplash = Global.isWindowVisible("SplashScreen");
716 dbConn = setupDatabaseConnection();
718 // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
719 Global.getFileManager().purgeResDirectory(true);
721 } catch (InitializationException e) {
724 QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
728 NeverNote application = new NeverNote(dbConn);
730 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
731 if (Global.startMinimized())
732 application.showMinimized();
734 if (Global.wasWindowMaximized())
735 application.showMaximized();
741 splash.finish(application);
743 System.out.println("Goodbye.");
748 * Open the internal database, or create if not present
750 * @throws InitializationException when opening the database fails, e.g. because another process has it locked
752 private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
753 ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
755 File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
756 boolean dbExists = f.exists();
758 Global.setDatabaseUrl("");
760 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
761 boolean goodCheck = false;
763 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
765 if (!dialog.okPressed())
767 Global.cipherPassword = dialog.getPassword();
768 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
769 Global.getDatabaseUserPassword(), Global.cipherPassword);
772 DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
776 // Encrypt the database upon shutdown
777 private void encryptOnShutdown() {
778 String dbPath= Global.getFileManager().getDbDirPath("");
779 String dbName = "NeverNote";
781 Statement st = conn.getConnection().createStatement();
782 st.execute("shutdown");
783 if (QMessageBox.question(this, "Are you sure",
784 "Are you sure you wish to encrypt the database?",
785 QMessageBox.StandardButton.Yes,
786 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
787 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, null, Global.cipherPassword.toCharArray(), true);
788 Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
789 QMessageBox.information(this, "Encryption Complete", "Encryption is complete");
791 } catch (SQLException e) {
796 // Decrypt the database upon shutdown
797 private void decryptOnShutdown() {
798 String dbPath= Global.getFileManager().getDbDirPath("");
799 String dbName = "NeverNote";
801 Statement st = conn.getConnection().createStatement();
802 st.execute("shutdown");
803 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
804 encryptCipher = "AES";
806 encryptCipher = "XTEA";
807 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
808 "Are you sure you wish to decrypt the database?"),
809 QMessageBox.StandardButton.Yes,
810 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
812 ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
813 Global.setDatabaseUrl("");
814 QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
816 } catch (SQLException e) {
821 * Encrypt/Decrypt the local database
823 public void doDatabaseEncrypt() {
824 // The database is not currently encrypted
825 if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
826 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
827 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
828 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
829 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
830 "Do you wish to proceed?"),
831 QMessageBox.StandardButton.Yes,
832 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
835 DBEncryptDialog dialog = new DBEncryptDialog();
837 if (dialog.okPressed()) {
838 Global.cipherPassword = dialog.getPassword();
839 encryptOnShutdown = true;
840 encryptCipher = dialog.getEncryptionMethod();
843 DBEncryptDialog dialog = new DBEncryptDialog();
844 dialog.setWindowTitle("Database Decryption");
845 dialog.hideEncryption();
847 if (dialog.okPressed()) {
848 if (!dialog.getPassword().equals(Global.cipherPassword)) {
849 QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
852 decryptOnShutdown = true;
859 private static void initializeGlobalSettings(String[] args) throws InitializationException {
860 StartupConfig startupConfig = new StartupConfig();
862 for (String arg : args) {
863 String lower = arg.toLowerCase();
864 if (lower.startsWith("--name="))
865 startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
866 if (lower.startsWith("--home="))
867 startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
868 if (lower.startsWith("--disable-viewing"))
869 startupConfig.setDisableViewing(true);
871 Global.setup(startupConfig);
876 public void closeEvent(QCloseEvent event) {
877 if (Global.minimizeOnClose() && !closeAction && Global.showTrayIcon()) {
882 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
885 if (currentNote!= null & browserWindow!=null) {
886 if (!currentNote.getTitle().equals(browserWindow.getTitle()))
887 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(), browserWindow.getTitle());
890 setMessage(tr("Beginning shutdown."));
892 // Close down external windows
893 Collection<ExternalBrowse> windows = externalWindows.values();
894 Iterator<ExternalBrowse> iterator = windows.iterator();
895 while (iterator.hasNext()) {
896 ExternalBrowse browser = iterator.next();
897 browser.windowClosing.disconnect();
902 externalFileEditedSaver();
903 if (Global.isConnected && Global.synchronizeOnClose()) {
904 setMessage(tr("Performing synchronization before closing."));
905 syncRunner.addWork("SYNC");
907 setMessage("Closing Program.");
908 threadMonitorTimer.stop();
910 syncRunner.addWork("STOP");
911 syncRunner.keepRunning = false;
912 thumbnailRunner.addWork("STOP");
913 syncRunner.keepRunning = false;
914 indexRunner.addWork("STOP");
915 syncRunner.keepRunning = false;
920 if (tempFiles != null)
923 browserWindow.noteSignal.tagsChanged.disconnect();
924 browserWindow.noteSignal.titleChanged.disconnect();
925 browserWindow.noteSignal.noteChanged.disconnect();
926 browserWindow.noteSignal.notebookChanged.disconnect();
927 browserWindow.noteSignal.createdDateChanged.disconnect();
928 browserWindow.noteSignal.alteredDateChanged.disconnect();
929 syncRunner.searchSignal.listChanged.disconnect();
930 syncRunner.tagSignal.listChanged.disconnect();
931 syncRunner.notebookSignal.listChanged.disconnect();
932 syncRunner.noteIndexSignal.listChanged.disconnect();
935 Global.saveWindowVisible("toolBar", toolBar.isVisible());
936 saveNoteColumnPositions();
937 saveNoteIndexWidth();
939 int width = notebookTree.columnWidth(0);
940 Global.setColumnWidth("notebookTreeName", width);
941 width = tagTree.columnWidth(0);
942 Global.setColumnWidth("tagTreeName", width);
944 Global.saveWindowMaximized(isMaximized());
945 Global.saveCurrentNoteGuid(currentNoteGuid);
947 int sortCol = noteTableView.proxyModel.sortColumn();
948 int sortOrder = noteTableView.proxyModel.sortOrder().value();
949 Global.setSortColumn(sortCol);
950 Global.setSortOrder(sortOrder);
954 Global.keepRunning = false;
956 logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
957 indexRunner.thread().join(50);
958 logger.log(logger.MEDIUM, "Index thread has stopped");
959 } catch (InterruptedException e1) {
960 e1.printStackTrace();
962 if (!syncRunner.isIdle()) {
964 logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
966 logger.log(logger.MEDIUM, "Sync thread has stopped");
967 } catch (InterruptedException e1) {
968 e1.printStackTrace();
972 if (encryptOnShutdown) {
975 if (decryptOnShutdown) {
978 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
981 @SuppressWarnings("unused")
982 private void closeNeverNote() {
986 public void setMessage(String s) {
987 logger.log(logger.HIGH, "Entering NeverNote.setMessage");
988 logger.log(logger.HIGH, "Message: " +s);
989 statusBar.showMessage(s);
991 logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
994 private void waitCursor(boolean wait) {
996 if (QApplication.overrideCursor() == null)
997 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1000 while (QApplication.overrideCursor() != null)
1001 QApplication.restoreOverrideCursor();
1005 private void setupIndexListeners() {
1006 // indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1007 // indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1008 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1009 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1011 private void setupSyncSignalListeners() {
1012 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1013 syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1014 syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1015 syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1016 syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1018 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1019 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1020 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1022 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1023 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1024 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1025 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1027 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1030 private void setupBrowserSignalListeners() {
1031 setupBrowserWindowListeners(browserWindow, true);
1034 private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1035 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1036 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1037 browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1038 if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1039 browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1040 browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1041 browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1042 browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1043 browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1044 browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1045 browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1046 browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1047 browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1048 browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1049 if (master) browser.focusLost.connect(this, "saveNote()");
1050 browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1053 //***************************************************************
1054 //***************************************************************
1055 //* Settings and look & feel
1056 //***************************************************************
1057 //***************************************************************
1058 @SuppressWarnings("unused")
1059 private void settings() {
1060 logger.log(logger.HIGH, "Entering NeverNote.settings");
1061 saveNoteColumnPositions();
1062 saveNoteIndexWidth();
1064 ConfigDialog settings = new ConfigDialog(this);
1065 String dateFormat = Global.getDateFormat();
1066 String timeFormat = Global.getTimeFormat();
1068 indexTime = 1000*Global.getIndexThreadSleepInterval();
1069 indexTimer.start(indexTime); // reset indexing timer
1072 indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1073 if (Global.showTrayIcon())
1078 if (menuBar.showEditorBar.isChecked())
1079 showEditorButtons(browserWindow);
1081 // Reset the save timer
1082 if (Global.getAutoSaveInterval() > 0)
1083 saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1087 // This is a hack to force a reload of the index in case the date or time changed.
1088 // if (!dateFormat.equals(Global.getDateFormat()) ||
1089 // !timeFormat.equals(Global.getTimeFormat())) {
1091 readOnlyCache.clear();
1092 inkNoteCache.clear();
1093 noteIndexUpdated(true);
1096 logger.log(logger.HIGH, "Leaving NeverNote.settings");
1098 // Restore things to the way they were
1099 private void restoreWindowState(boolean mainWindow) {
1100 // We need to name things or this doesn't work.
1101 setObjectName("NeverNote");
1102 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1103 browserIndexSplitter.setObjectName("browserIndexSplitter");
1104 leftSplitter1.setObjectName("leftSplitter1");
1106 // Restore the actual positions.
1108 restoreGeometry(Global.restoreGeometry(objectName()));
1109 mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1110 browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1111 leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1114 // Save window positions for the next start
1115 private void saveWindowState() {
1116 Global.saveGeometry(objectName(), saveGeometry());
1117 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1118 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1119 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1121 // Load the style sheet
1122 private void loadStyleSheet() {
1123 String fileName = Global.getFileManager().getQssDirPath("default.qss");
1124 QFile file = new QFile(fileName);
1125 file.open(OpenModeFlag.ReadOnly);
1126 String styleSheet = file.readAll().toString();
1128 setStyleSheet(styleSheet);
1130 // Save column positions for the next time
1131 private void saveNoteColumnPositions() {
1132 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1133 Global.setColumnPosition("noteTableCreationPosition", position);
1134 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1135 Global.setColumnPosition("noteTableTagPosition", position);
1136 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1137 Global.setColumnPosition("noteTableNotebookPosition", position);
1138 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1139 Global.setColumnPosition("noteTableChangedPosition", position);
1140 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1141 Global.setColumnPosition("noteTableAuthorPosition", position);
1142 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1143 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1144 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1145 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1146 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1147 Global.setColumnPosition("noteTableTitlePosition", position);
1148 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1149 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1150 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1151 Global.setColumnPosition("noteTableGuidPosition", position);
1152 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1153 Global.setColumnPosition("noteTableThumbnailPosition", position);
1156 // Save column widths for the next time
1157 private void saveNoteIndexWidth() {
1159 width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1160 Global.setColumnWidth("noteTableCreationPosition", width);
1161 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1162 Global.setColumnWidth("noteTableChangedPosition", width);
1163 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1164 Global.setColumnWidth("noteTableGuidPosition", width);
1165 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1166 Global.setColumnWidth("noteTableNotebookPosition", width);
1167 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1168 Global.setColumnWidth("noteTableTagPosition", width);
1169 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1170 Global.setColumnWidth("noteTableTitlePosition", width);
1171 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1172 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1173 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1174 Global.setColumnWidth("noteTableAuthorPosition", width);
1175 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1176 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1177 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1178 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1179 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1180 Global.setColumnWidth("noteTableThumbnailPosition", width);
1181 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1182 Global.setColumnWidth("noteTableGuidPosition", width);
1186 //***************************************************************
1187 //***************************************************************
1188 //** These functions deal with Notebook menu items
1189 //***************************************************************
1190 //***************************************************************
1191 // Setup the tree containing the user's notebooks.
1192 private void initializeNotebookTree() {
1193 logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1194 notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1195 listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1196 logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1198 // Listener when a notebook is selected
1199 private void notebookTreeSelection() {
1200 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1203 clearAttributeFilter();
1204 clearSavedSearchFilter();
1205 if (Global.mimicEvernoteInterface) {
1207 searchField.clear();
1209 menuBar.noteRestoreAction.setVisible(false);
1210 menuBar.notebookEditAction.setEnabled(true);
1211 menuBar.notebookDeleteAction.setEnabled(true);
1212 menuBar.notebookPublishAction.setEnabled(true);
1213 menuBar.notebookShareAction.setEnabled(true);
1214 menuBar.notebookIconAction.setEnabled(true);
1215 menuBar.notebookStackAction.setEnabled(true);
1216 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1217 QTreeWidgetItem currentSelection;
1218 selectedNotebookGUIDs.clear();
1219 if (!Global.mimicEvernoteInterface) {
1220 for (int i=0; i<selections.size(); i++) {
1221 currentSelection = selections.get(i);
1222 if (!currentSelection.text(2).equals("STACK"))
1223 selectedNotebookGUIDs.add(currentSelection.text(2));
1225 String stackName = currentSelection.text(0);
1226 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1227 Notebook book = listManager.getNotebookIndex().get(j);
1228 if (book.getStack()!=null && book.getStack().equalsIgnoreCase(stackName))
1229 selectedNotebookGUIDs.add(book.getGuid());
1235 // There is the potential for no notebooks to be selected if this
1236 // happens then we make it look like all notebooks were selecetd.
1237 // If that happens, just select the "all notebooks"
1238 selections = notebookTree.selectedItems();
1239 if (selections.size()==0) {
1240 selectedNotebookGUIDs.clear();
1241 menuBar.notebookEditAction.setEnabled(false);
1242 menuBar.notebookDeleteAction.setEnabled(false);
1243 menuBar.notebookIconAction.setEnabled(false);
1244 menuBar.notebookStackAction.setEnabled(false);
1246 if (selectedNotebookGUIDs.size() == 1 && selectedNotebookGUIDs.get(0).equals(previousSelectedNotebook)) {
1247 previousSelectedNotebook = selectedNotebookGUIDs.get(0);
1248 previousSelectedNotebook = "";
1249 notebookTree.clearSelection();
1250 notebookTreeSelection();
1253 if (selectedNotebookGUIDs.size() == 1)
1254 previousSelectedNotebook = selectedNotebookGUIDs.get(0);
1255 if (selectedNotebookGUIDs.size() > 1)
1256 previousSelectedNotebook = "";
1259 String stackName = "";
1260 if (selections.size() > 0) {
1261 guid = (selections.get(0).text(2));
1262 stackName = selections.get(0).text(0);
1264 if (!guid.equals("") && !guid.equals("STACK")) {
1265 selectedNotebookGUIDs.add(guid);
1266 menuBar.notebookIconAction.setEnabled(true);
1269 menuBar.notebookIconAction.setEnabled(true);
1270 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1271 Notebook book = listManager.getNotebookIndex().get(j);
1272 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1273 selectedNotebookGUIDs.add(book.getGuid());
1277 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1278 listManager.loadNotesIndex();
1279 noteIndexUpdated(false);
1280 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1283 private void clearNotebookFilter() {
1284 notebookTree.blockSignals(true);
1285 notebookTree.clearSelection();
1286 menuBar.noteRestoreAction.setVisible(false);
1287 menuBar.notebookEditAction.setEnabled(false);
1288 menuBar.notebookDeleteAction.setEnabled(false);
1289 selectedNotebookGUIDs.clear();
1290 listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1291 notebookTree.blockSignals(false);
1293 // Triggered when the notebook DB has been updated
1294 private void notebookIndexUpdated() {
1295 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1297 // Get the possible icons
1298 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1299 notebookTree.setIcons(icons);
1301 if (selectedNotebookGUIDs == null)
1302 selectedNotebookGUIDs = new ArrayList<String>();
1303 List<Notebook> books = conn.getNotebookTable().getAll();
1304 for (int i=books.size()-1; i>=0; i--) {
1305 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1306 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1308 j=listManager.getArchiveNotebookIndex().size();
1314 listManager.countNotebookResults(listManager.getNoteIndex());
1315 notebookTree.blockSignals(true);
1316 notebookTree.load(books, listManager.getLocalNotebooks());
1317 for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1318 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1320 selectedNotebookGUIDs.remove(i);
1322 notebookTree.blockSignals(false);
1324 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1326 // Show/Hide note information
1327 private void toggleNotebookWindow() {
1328 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1329 if (notebookTree.isVisible())
1330 notebookTree.hide();
1332 notebookTree.show();
1333 menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1334 Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1335 logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1337 // Add a new notebook
1338 @SuppressWarnings("unused")
1339 private void addNotebook() {
1340 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1341 NotebookEdit edit = new NotebookEdit();
1342 edit.setNotebooks(listManager.getNotebookIndex());
1345 if (!edit.okPressed())
1348 Calendar currentTime = new GregorianCalendar();
1349 Long l = new Long(currentTime.getTimeInMillis());
1350 String randint = new String(Long.toString(l));
1352 Notebook newBook = new Notebook();
1353 newBook.setUpdateSequenceNum(0);
1354 newBook.setGuid(randint);
1355 newBook.setName(edit.getNotebook());
1356 newBook.setServiceCreated(new Date().getTime());
1357 newBook.setServiceUpdated(new Date().getTime());
1358 newBook.setDefaultNotebook(false);
1359 newBook.setPublished(false);
1361 listManager.getNotebookIndex().add(newBook);
1363 listManager.getLocalNotebooks().add(newBook.getGuid());
1364 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1365 notebookIndexUpdated();
1366 listManager.countNotebookResults(listManager.getNoteIndex());
1367 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1368 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1370 // Edit an existing notebook
1371 @SuppressWarnings("unused")
1372 private void stackNotebook() {
1373 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1374 StackNotebook edit = new StackNotebook();
1376 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1377 QTreeWidgetItem currentSelection;
1378 for (int i=0; i<selections.size(); i++) {
1379 currentSelection = selections.get(0);
1380 String guid = currentSelection.text(2);
1381 if (guid.equalsIgnoreCase("")) {
1382 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1385 if (guid.equalsIgnoreCase("STACK")) {
1386 QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1391 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1396 if (!edit.okPressed())
1399 String stack = edit.getStackName();
1401 for (int i=0; i<selections.size(); i++) {
1402 currentSelection = selections.get(i);
1403 String guid = currentSelection.text(2);
1404 listManager.updateNotebookStack(guid, stack);
1406 notebookIndexUpdated();
1407 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1409 // Edit an existing notebook
1410 @SuppressWarnings("unused")
1411 private void editNotebook() {
1412 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1413 NotebookEdit edit = new NotebookEdit();
1415 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1416 QTreeWidgetItem currentSelection;
1417 currentSelection = selections.get(0);
1418 edit.setNotebook(currentSelection.text(0));
1420 String guid = currentSelection.text(2);
1421 if (!guid.equalsIgnoreCase("STACK")) {
1422 edit.setTitle(tr("Edit Notebook"));
1423 edit.setNotebooks(listManager.getNotebookIndex());
1424 edit.setLocalCheckboxEnabled(false);
1425 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1426 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1427 edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1428 i=listManager.getNotebookIndex().size();
1432 edit.setTitle(tr("Edit Stack"));
1433 edit.setStacks(conn.getNotebookTable().getAllStackNames());
1434 edit.hideLocalCheckbox();
1435 edit.hideDefaultCheckbox();
1440 if (!edit.okPressed())
1444 if (guid.equalsIgnoreCase("STACK")) {
1445 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1446 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1447 if (listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1448 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1450 conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1451 currentSelection.setText(0, edit.getNotebook());
1455 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1456 currentSelection.setText(0, edit.getNotebook());
1458 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1459 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1460 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1461 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1462 for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1463 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1464 listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1465 conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1467 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1468 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1469 LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1470 linkedNotebook.setShareName(edit.getNotebook());
1471 conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1473 i=listManager.getNotebookIndex().size();
1477 // Build a list of non-closed notebooks
1478 List<Notebook> nbooks = new ArrayList<Notebook>();
1479 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1480 boolean found=false;
1481 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1482 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1486 nbooks.add(listManager.getNotebookIndex().get(i));
1489 browserWindow.setNotebookList(nbooks);
1490 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1492 // Publish a notebook
1493 @SuppressWarnings("unused")
1494 private void publishNotebook() {
1495 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1496 QTreeWidgetItem currentSelection;
1497 currentSelection = selections.get(0);
1498 String guid = currentSelection.text(2);
1500 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1505 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1506 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1507 n = listManager.getNotebookIndex().get(i);
1509 i = listManager.getNotebookIndex().size();
1515 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1518 if (!publish.okClicked())
1521 Publishing p = publish.getPublishing();
1522 boolean isPublished = !publish.isStopPressed();
1523 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1524 n.setPublished(isPublished);
1526 listManager.getNotebookIndex().set(position, n);
1527 notebookIndexUpdated();
1529 // Publish a notebook
1530 @SuppressWarnings("unused")
1531 private void shareNotebook() {
1532 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1533 QTreeWidgetItem currentSelection;
1534 currentSelection = selections.get(0);
1535 String guid = currentSelection.text(2);
1537 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1541 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1542 if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1543 n = listManager.getNotebookIndex().get(i);
1544 i = listManager.getNotebookIndex().size();
1548 String authToken = null;
1549 if (syncRunner.isConnected)
1550 authToken = syncRunner.authToken;
1551 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
1556 // Delete an existing notebook
1557 @SuppressWarnings("unused")
1558 private void deleteNotebook() {
1559 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
1560 boolean stacksFound = false;
1561 boolean notebooksFound = false;
1562 boolean assigned = false;
1563 // Check if any notes have this notebook
1564 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1565 for (int i=0; i<selections.size(); i++) {
1566 QTreeWidgetItem currentSelection;
1567 currentSelection = selections.get(i);
1568 String guid = currentSelection.text(2);
1569 if (!guid.equalsIgnoreCase("STACK")) {
1570 notebooksFound = true;
1571 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
1572 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
1573 if (noteGuid.equals(guid)) {
1575 j=listManager.getNoteIndex().size();
1576 i=selections.size();
1584 QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
1585 "Please delete the notes or move them to another notebook before deleting any notebooks."));
1589 if (conn.getNotebookTable().getAll().size() == 1) {
1590 QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
1594 // If all notebooks are clear, verify the delete
1595 String msg1 = new String(tr("Delete selected notebooks?"));
1596 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
1597 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
1598 " not deleted unless selected?"));
1600 if (stacksFound && notebooksFound)
1602 if (!stacksFound && notebooksFound)
1604 if (stacksFound && !notebooksFound)
1606 if (QMessageBox.question(this, tr("Confirmation"), msg,
1607 QMessageBox.StandardButton.Yes,
1608 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1612 // If confirmed, delete the notebook
1613 for (int i=selections.size()-1; i>=0; i--) {
1614 QTreeWidgetItem currentSelection;
1615 currentSelection = selections.get(i);
1616 String guid = currentSelection.text(2);
1617 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
1618 conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
1619 listManager.renameStack(currentSelection.text(0), "");
1621 conn.getNotebookTable().expungeNotebook(guid, true);
1622 listManager.deleteNotebook(guid);
1626 notebookTreeSelection();
1627 notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
1628 listManager.countNotebookResults(listManager.getNoteIndex());
1629 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
1631 // A note's notebook has been updated
1632 @SuppressWarnings("unused")
1633 private void updateNoteNotebook(String guid, String notebookGuid) {
1635 // Update the list manager
1636 listManager.updateNoteNotebook(guid, notebookGuid);
1637 listManager.countNotebookResults(listManager.getNoteIndex());
1638 // notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1640 // Find the name of the notebook
1641 String notebookName = null;
1642 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1643 if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
1644 notebookName = listManager.getNotebookIndex().get(i).getName();
1649 // If we found the name, update the browser window
1650 if (notebookName != null) {
1651 updateListNoteNotebook(guid, notebookName);
1652 if (guid.equals(currentNoteGuid)) {
1653 int pos = browserWindow.notebookBox.findText(notebookName);
1655 browserWindow.notebookBox.setCurrentIndex(pos);
1659 // If we're dealing with the current note, then we need to be sure and update the notebook there
1660 if (guid.equals(currentNoteGuid)) {
1661 if (currentNote != null) {
1662 currentNote.setNotebookGuid(notebookGuid);
1666 // Open/close notebooks
1667 @SuppressWarnings("unused")
1668 private void closeNotebooks() {
1669 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
1671 if (!na.okClicked())
1675 listManager.getArchiveNotebookIndex().clear();
1677 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
1678 String text = na.getClosedBookList().takeItem(i).text();
1679 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1680 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
1681 Notebook n = listManager.getNotebookIndex().get(j);
1682 conn.getNotebookTable().setArchived(n.getGuid(),true);
1683 listManager.getArchiveNotebookIndex().add(n);
1684 j=listManager.getNotebookIndex().size();
1689 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
1690 String text = na.getOpenBookList().takeItem(i).text();
1691 for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1692 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
1693 Notebook n = listManager.getNotebookIndex().get(j);
1694 conn.getNotebookTable().setArchived(n.getGuid(),false);
1695 j=listManager.getNotebookIndex().size();
1699 notebookTreeSelection();
1700 listManager.loadNotesIndex();
1701 notebookIndexUpdated();
1702 noteIndexUpdated(false);
1703 reloadTagTree(true);
1704 // noteIndexUpdated(false);
1706 // Build a list of non-closed notebooks
1707 List<Notebook> nbooks = new ArrayList<Notebook>();
1708 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1709 boolean found=false;
1710 for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1711 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1715 nbooks.add(listManager.getNotebookIndex().get(i));
1718 browserWindow.setNotebookList(nbooks);
1720 // Change the notebook's icon
1721 @SuppressWarnings("unused")
1722 private void setNotebookIcon() {
1723 boolean stackSelected = false;
1724 boolean allNotebookSelected = false;
1726 QTreeWidgetItem currentSelection;
1727 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1728 if (selections.size() == 0)
1731 currentSelection = selections.get(0);
1732 String guid = currentSelection.text(2);
1733 if (guid.equalsIgnoreCase(""))
1734 allNotebookSelected = true;
1735 if (guid.equalsIgnoreCase("STACK"))
1736 stackSelected = true;
1738 QIcon currentIcon = currentSelection.icon(0);
1742 if (!stackSelected && !allNotebookSelected) {
1743 icon = conn.getNotebookTable().getIcon(guid);
1745 dialog = new SetIcon(currentIcon);
1746 dialog.setUseDefaultIcon(true);
1748 dialog = new SetIcon(icon);
1749 dialog.setUseDefaultIcon(false);
1752 if (stackSelected) {
1753 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
1755 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");
1758 dialog = new SetIcon(currentIcon);
1759 dialog.setUseDefaultIcon(true);
1761 dialog = new SetIcon(icon);
1762 dialog.setUseDefaultIcon(false);
1766 if (dialog.okPressed()) {
1767 QIcon newIcon = dialog.getIcon();
1768 if (stackSelected) {
1769 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
1770 if (newIcon == null) {
1771 newIcon = new QIcon(iconPath+"books2.png");
1773 currentSelection.setIcon(0,newIcon);
1776 if (allNotebookSelected) {
1777 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
1778 if (newIcon == null) {
1779 newIcon = new QIcon(iconPath+"notebook-green.png");
1781 currentSelection.setIcon(0,newIcon);
1784 conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
1785 if (newIcon == null) {
1786 boolean isPublished = false;;
1787 boolean found = false;
1788 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
1789 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1790 isPublished = listManager.getNotebookIndex().get(i).isPublished();
1794 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
1796 currentSelection.setIcon(0, newIcon);
1802 //***************************************************************
1803 //***************************************************************
1804 //** These functions deal with Tag menu items
1805 //***************************************************************
1806 //***************************************************************
1807 // Add a new notebook
1808 @SuppressWarnings("unused")
1809 private void addTag() {
1810 logger.log(logger.HIGH, "Inside NeverNote.addTag");
1811 TagEdit edit = new TagEdit();
1812 edit.setTagList(listManager.getTagIndex());
1815 if (!edit.okPressed())
1818 Calendar currentTime = new GregorianCalendar();
1819 Long l = new Long(currentTime.getTimeInMillis());
1820 String randint = new String(Long.toString(l));
1822 Tag newTag = new Tag();
1823 newTag.setUpdateSequenceNum(0);
1824 newTag.setGuid(randint);
1825 newTag.setName(edit.getTag());
1826 conn.getTagTable().addTag(newTag, true);
1827 listManager.getTagIndex().add(newTag);
1828 reloadTagTree(true);
1830 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
1832 @SuppressWarnings("unused")
1833 private void reloadTagTree() {
1834 reloadTagTree(false);
1836 private void reloadTagTree(boolean reload) {
1837 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
1838 tagIndexUpdated(reload);
1839 boolean filter = false;
1840 listManager.countTagResults(listManager.getNoteIndex());
1841 if (notebookTree.selectedItems().size() > 0
1842 && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
1844 if (tagTree.selectedItems().size() > 0)
1846 tagTree.showAllTags(!filter);
1847 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
1849 // Edit an existing tag
1850 @SuppressWarnings("unused")
1851 private void editTag() {
1852 logger.log(logger.HIGH, "Entering NeverNote.editTag");
1853 TagEdit edit = new TagEdit();
1854 edit.setTitle("Edit Tag");
1855 List<QTreeWidgetItem> selections = tagTree.selectedItems();
1856 QTreeWidgetItem currentSelection;
1857 currentSelection = selections.get(0);
1858 edit.setTag(currentSelection.text(0));
1859 edit.setTagList(listManager.getTagIndex());
1862 if (!edit.okPressed())
1865 String guid = currentSelection.text(2);
1866 currentSelection.setText(0,edit.getTag());
1868 for (int i=0; i<listManager.getTagIndex().size(); i++) {
1869 if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
1870 listManager.getTagIndex().get(i).setName(edit.getTag());
1871 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
1872 updateListTagName(guid);
1873 if (currentNote != null && currentNote.getTagGuids().contains(guid))
1874 browserWindow.setTag(getTagNamesForNote(currentNote));
1875 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
1879 browserWindow.setTag(getTagNamesForNote(currentNote));
1880 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
1882 // Delete an existing tag
1883 @SuppressWarnings("unused")
1884 private void deleteTag() {
1885 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
1887 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
1888 QMessageBox.StandardButton.Yes,
1889 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1893 List<QTreeWidgetItem> selections = tagTree.selectedItems();
1894 for (int i=selections.size()-1; i>=0; i--) {
1895 QTreeWidgetItem currentSelection;
1896 currentSelection = selections.get(i);
1897 removeTagItem(currentSelection.text(2));
1899 tagIndexUpdated(true);
1901 listManager.countTagResults(listManager.getNoteIndex());
1902 // tagTree.updateCounts(listManager.getTagCounter());
1903 logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
1905 // Remove a tag tree item. Go recursively down & remove the children too
1906 private void removeTagItem(String guid) {
1907 for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {
1908 String parent = listManager.getTagIndex().get(j).getParentGuid();
1909 if (parent != null && parent.equals(guid)) {
1910 //Remove this tag's children
1911 removeTagItem(listManager.getTagIndex().get(j).getGuid());
1914 //Now, remove this tag
1915 removeListTagName(guid);
1916 conn.getTagTable().expungeTag(guid, true);
1917 for (int a=0; a<listManager.getTagIndex().size(); a++) {
1918 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
1919 listManager.getTagIndex().remove(a);
1924 // Setup the tree containing the user's tags
1925 private void initializeTagTree() {
1926 logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
1927 // tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
1928 tagTree.itemClicked.connect(this, "tagTreeSelection()");
1929 listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
1930 logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
1932 // Listener when a tag is selected
1933 private void tagTreeSelection() {
1934 logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
1937 clearAttributeFilter();
1938 clearSavedSearchFilter();
1940 menuBar.noteRestoreAction.setVisible(false);
1942 List<QTreeWidgetItem> selections = tagTree.selectedItems();
1943 QTreeWidgetItem currentSelection;
1944 selectedTagGUIDs.clear();
1945 for (int i=0; i<selections.size(); i++) {
1946 currentSelection = selections.get(i);
1947 selectedTagGUIDs.add(currentSelection.text(2));
1949 if (selections.size() > 0) {
1950 menuBar.tagEditAction.setEnabled(true);
1951 menuBar.tagDeleteAction.setEnabled(true);
1952 menuBar.tagIconAction.setEnabled(true);
1955 menuBar.tagEditAction.setEnabled(false);
1956 menuBar.tagDeleteAction.setEnabled(false);
1957 menuBar.tagIconAction.setEnabled(true);
1959 if (selectedTagGUIDs.size() == 1 && selectedTagGUIDs.get(0).equals(previousSelectedTag)) {
1960 previousSelectedTag = selectedTagGUIDs.get(0);
1961 previousSelectedTag = "";
1962 tagTree.clearSelection();
1966 if (selectedTagGUIDs.size() == 1)
1967 previousSelectedTag = selectedTagGUIDs.get(0);
1968 if (selectedTagGUIDs.size() > 1)
1969 previousSelectedTag = "";
1970 listManager.setSelectedTags(selectedTagGUIDs);
1971 listManager.loadNotesIndex();
1972 noteIndexUpdated(false);
1973 logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
1975 // trigger the tag index to be refreshed
1976 @SuppressWarnings("unused")
1977 private void tagIndexUpdated() {
1978 tagIndexUpdated(true);
1980 private void tagIndexUpdated(boolean reload) {
1981 logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
1982 if (selectedTagGUIDs == null)
1983 selectedTagGUIDs = new ArrayList<String>();
1985 listManager.reloadTagIndex();
1987 tagTree.blockSignals(true);
1989 tagTree.setIcons(conn.getTagTable().getAllIcons());
1990 tagTree.load(listManager.getTagIndex());
1992 for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
1993 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
1995 selectedTagGUIDs.remove(i);
1997 tagTree.blockSignals(false);
1999 browserWindow.setTag(getTagNamesForNote(currentNote));
2000 logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2002 // Show/Hide note information
2003 private void toggleTagWindow() {
2004 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2005 if (tagTree.isVisible())
2009 menuBar.hideTags.setChecked(tagTree.isVisible());
2010 Global.saveWindowVisible("tagTree", tagTree.isVisible());
2011 logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2013 // A note's tags have been updated
2014 @SuppressWarnings("unused")
2015 private void updateNoteTags(String guid, List<String> tags) {
2016 // Save any new tags. We'll need them later.
2017 List<String> newTags = new ArrayList<String>();
2018 for (int i=0; i<tags.size(); i++) {
2019 if (conn.getTagTable().findTagByName(tags.get(i))==null)
2020 newTags.add(tags.get(i));
2023 listManager.saveNoteTags(guid, tags);
2024 listManager.countTagResults(listManager.getNoteIndex());
2025 StringBuffer names = new StringBuffer("");
2026 for (int i=0; i<tags.size(); i++) {
2027 names = names.append(tags.get(i));
2028 if (i<tags.size()-1) {
2029 names.append(Global.tagDelimeter + " ");
2032 browserWindow.setTag(names.toString());
2035 // Now, we need to add any new tags to the tag tree
2036 for (int i=0; i<newTags.size(); i++)
2037 tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2039 // Get a string containing all tag names for a note
2040 private String getTagNamesForNote(Note n) {
2041 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2042 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2044 StringBuffer buffer = new StringBuffer(100);
2045 Vector<String> v = new Vector<String>();
2046 List<String> guids = n.getTagGuids();
2051 for (int i=0; i<guids.size(); i++) {
2052 v.add(listManager.getTagNameByGuid(guids.get(i)));
2054 Comparator<String> comparator = Collections.reverseOrder();
2055 Collections.sort(v,comparator);
2056 Collections.reverse(v);
2058 for (int i = 0; i<v.size(); i++) {
2060 buffer.append(", ");
2061 buffer.append(v.get(i));
2064 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2065 return buffer.toString();
2067 // Tags were added via dropping notes from the note list
2068 @SuppressWarnings("unused")
2069 private void tagsAdded(String noteGuid, String tagGuid) {
2070 String tagName = null;
2071 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2072 if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2073 tagName = listManager.getTagIndex().get(i).getName();
2074 i=listManager.getTagIndex().size();
2077 if (tagName == null)
2080 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2081 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2082 List<String> tagNames = new ArrayList<String>();
2083 tagNames.add(new String(tagName));
2084 Note n = listManager.getMasterNoteIndex().get(i);
2085 for (int j=0; j<n.getTagNames().size(); j++) {
2086 tagNames.add(new String(n.getTagNames().get(j)));
2088 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2089 if (n.getGuid().equals(currentNoteGuid)) {
2090 Collections.sort(tagNames);
2091 String display = "";
2092 for (int j=0; j<tagNames.size(); j++) {
2093 display = display+tagNames.get(j);
2094 if (j+2<tagNames.size())
2095 display = display+Global.tagDelimeter+" ";
2097 browserWindow.setTag(display);
2099 i=listManager.getMasterNoteIndex().size();
2104 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2106 private void clearTagFilter() {
2107 tagTree.blockSignals(true);
2108 tagTree.clearSelection();
2109 menuBar.noteRestoreAction.setVisible(false);
2110 menuBar.tagEditAction.setEnabled(false);
2111 menuBar.tagDeleteAction.setEnabled(false);
2112 menuBar.tagIconAction.setEnabled(false);
2113 selectedTagGUIDs.clear();
2114 listManager.setSelectedTags(selectedTagGUIDs);
2115 tagTree.blockSignals(false);
2117 // Change the icon for a tag
2118 @SuppressWarnings("unused")
2119 private void setTagIcon() {
2120 QTreeWidgetItem currentSelection;
2121 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2122 if (selections.size() == 0)
2125 currentSelection = selections.get(0);
2126 String guid = currentSelection.text(2);
2128 QIcon currentIcon = currentSelection.icon(0);
2129 QIcon icon = conn.getTagTable().getIcon(guid);
2132 dialog = new SetIcon(currentIcon);
2133 dialog.setUseDefaultIcon(true);
2135 dialog = new SetIcon(icon);
2136 dialog.setUseDefaultIcon(false);
2139 if (dialog.okPressed()) {
2140 QIcon newIcon = dialog.getIcon();
2141 conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2142 if (newIcon == null)
2143 newIcon = new QIcon(iconPath+"tag.png");
2144 currentSelection.setIcon(0, newIcon);
2150 //***************************************************************
2151 //***************************************************************
2152 //** These functions deal with Saved Search menu items
2153 //***************************************************************
2154 //***************************************************************
2155 // Add a new notebook
2156 @SuppressWarnings("unused")
2157 private void addSavedSearch() {
2158 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2159 SavedSearchEdit edit = new SavedSearchEdit();
2160 edit.setSearchList(listManager.getSavedSearchIndex());
2163 if (!edit.okPressed())
2166 Calendar currentTime = new GregorianCalendar();
2167 Long l = new Long(currentTime.getTimeInMillis());
2168 String randint = new String(Long.toString(l));
2170 SavedSearch search = new SavedSearch();
2171 search.setUpdateSequenceNum(0);
2172 search.setGuid(randint);
2173 search.setName(edit.getName());
2174 search.setQuery(edit.getQuery());
2175 search.setFormat(QueryFormat.USER);
2176 listManager.getSavedSearchIndex().add(search);
2177 conn.getSavedSearchTable().addSavedSearch(search, true);
2178 savedSearchIndexUpdated();
2179 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2181 // Edit an existing tag
2182 @SuppressWarnings("unused")
2183 private void editSavedSearch() {
2184 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2185 SavedSearchEdit edit = new SavedSearchEdit();
2186 edit.setTitle(tr("Edit Search"));
2187 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2188 QTreeWidgetItem currentSelection;
2189 currentSelection = selections.get(0);
2190 String guid = currentSelection.text(1);
2191 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2192 edit.setName(currentSelection.text(0));
2193 edit.setQuery(s.getQuery());
2194 edit.setSearchList(listManager.getSavedSearchIndex());
2197 if (!edit.okPressed())
2200 List<SavedSearch> list = listManager.getSavedSearchIndex();
2201 SavedSearch search = null;
2202 boolean found = false;
2203 for (int i=0; i<list.size(); i++) {
2204 search = list.get(i);
2205 if (search.getGuid().equals(guid)) {
2212 search.setName(edit.getName());
2213 search.setQuery(edit.getQuery());
2214 conn.getSavedSearchTable().updateSavedSearch(search, true);
2215 savedSearchIndexUpdated();
2216 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2218 // Delete an existing tag
2219 @SuppressWarnings("unused")
2220 private void deleteSavedSearch() {
2221 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2223 if (QMessageBox.question(this, "Confirmation", "Delete the selected search?",
2224 QMessageBox.StandardButton.Yes,
2225 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2229 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2230 for (int i=selections.size()-1; i>=0; i--) {
2231 QTreeWidgetItem currentSelection;
2232 currentSelection = selections.get(i);
2233 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2234 if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2235 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2236 listManager.getSavedSearchIndex().remove(j);
2237 j=listManager.getSavedSearchIndex().size()+1;
2240 selections.remove(i);
2242 savedSearchIndexUpdated();
2243 logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2245 // Setup the tree containing the user's tags
2246 private void initializeSavedSearchTree() {
2247 logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2248 savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2249 logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2251 // Listener when a tag is selected
2252 @SuppressWarnings("unused")
2253 private void savedSearchTreeSelection() {
2254 logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2256 clearNotebookFilter();
2259 clearAttributeFilter();
2261 String currentGuid = selectedSavedSearchGUID;
2262 menuBar.savedSearchEditAction.setEnabled(true);
2263 menuBar.savedSearchDeleteAction.setEnabled(true);
2264 menuBar.savedSearchIconAction.setEnabled(true);
2265 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2266 QTreeWidgetItem currentSelection;
2267 selectedSavedSearchGUID = "";
2268 for (int i=0; i<selections.size(); i++) {
2269 currentSelection = selections.get(i);
2270 if (currentSelection.text(1).equals(currentGuid)) {
2271 currentSelection.setSelected(false);
2273 selectedSavedSearchGUID = currentSelection.text(1);
2275 // i = selections.size() +1;
2278 // There is the potential for no notebooks to be selected if this
2279 // happens then we make it look like all notebooks were selecetd.
2280 // If that happens, just select the "all notebooks"
2281 if (selections.size()==0) {
2282 clearSavedSearchFilter();
2284 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2286 logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2288 private void clearSavedSearchFilter() {
2289 menuBar.savedSearchEditAction.setEnabled(false);
2290 menuBar.savedSearchDeleteAction.setEnabled(false);
2291 menuBar.savedSearchIconAction.setEnabled(false);
2292 savedSearchTree.blockSignals(true);
2293 savedSearchTree.clearSelection();
2294 savedSearchTree.blockSignals(false);
2295 selectedSavedSearchGUID = "";
2296 searchField.setEditText("");
2297 searchPerformed = false;
2298 listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2300 // trigger the tag index to be refreshed
2301 private void savedSearchIndexUpdated() {
2302 if (selectedSavedSearchGUID == null)
2303 selectedSavedSearchGUID = new String();
2304 savedSearchTree.blockSignals(true);
2305 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2306 savedSearchTree.load(listManager.getSavedSearchIndex());
2307 savedSearchTree.selectGuid(selectedSavedSearchGUID);
2308 savedSearchTree.blockSignals(false);
2310 // trigger when the saved search selection changes
2311 @SuppressWarnings("unused")
2312 private void updateSavedSearchSelection() {
2313 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2315 menuBar.savedSearchEditAction.setEnabled(true);
2316 menuBar.savedSearchDeleteAction.setEnabled(true);
2317 menuBar.savedSearchIconAction.setEnabled(true);
2318 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2320 if (selections.size() > 0) {
2321 menuBar.savedSearchEditAction.setEnabled(true);
2322 menuBar.savedSearchDeleteAction.setEnabled(true);
2323 menuBar.savedSearchIconAction.setEnabled(true);
2324 selectedSavedSearchGUID = selections.get(0).text(1);
2325 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2326 searchField.setEditText(s.getQuery());
2328 menuBar.savedSearchEditAction.setEnabled(false);
2329 menuBar.savedSearchDeleteAction.setEnabled(false);
2330 menuBar.savedSearchIconAction.setEnabled(false);
2331 selectedSavedSearchGUID = "";
2332 searchField.setEditText("");
2334 searchFieldChanged();
2336 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2340 // Show/Hide note information
2341 private void toggleSavedSearchWindow() {
2342 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2343 if (savedSearchTree.isVisible())
2344 savedSearchTree.hide();
2346 savedSearchTree.show();
2347 menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2349 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2350 logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2352 // Change the icon for a saved search
2353 @SuppressWarnings("unused")
2354 private void setSavedSearchIcon() {
2355 QTreeWidgetItem currentSelection;
2356 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2357 if (selections.size() == 0)
2360 currentSelection = selections.get(0);
2361 String guid = currentSelection.text(1);
2363 QIcon currentIcon = currentSelection.icon(0);
2364 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2367 dialog = new SetIcon(currentIcon);
2368 dialog.setUseDefaultIcon(true);
2370 dialog = new SetIcon(icon);
2371 dialog.setUseDefaultIcon(false);
2374 if (dialog.okPressed()) {
2375 QIcon newIcon = dialog.getIcon();
2376 conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2377 if (newIcon == null)
2378 newIcon = new QIcon(iconPath+"search.png");
2379 currentSelection.setIcon(0, newIcon);
2387 //***************************************************************
2388 //***************************************************************
2389 //** These functions deal with Help menu & tool menu items
2390 //***************************************************************
2391 //***************************************************************
2392 // Show database status
2393 @SuppressWarnings("unused")
2394 private void databaseStatus() {
2396 int dirty = conn.getNoteTable().getDirtyCount();
2397 int unindexed = conn.getNoteTable().getUnindexedCount();
2398 DatabaseStatus status = new DatabaseStatus();
2399 status.setUnsynchronized(dirty);
2400 status.setUnindexed(unindexed);
2401 status.setNoteCount(conn.getNoteTable().getNoteCount());
2402 status.setNotebookCount(listManager.getNotebookIndex().size());
2403 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2404 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2405 status.setTagCount(listManager.getTagIndex().size());
2406 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2407 status.setWordCount(conn.getWordsTable().getWordCount());
2411 // Compact the database
2412 @SuppressWarnings("unused")
2413 private void compactDatabase() {
2414 logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2415 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2416 "but please be aware that depending upon the size of your database this can be time consuming " +
2417 "and NeverNote will be unresponsive until it is complete. Do you wish to continue?"),
2418 QMessageBox.StandardButton.Yes,
2419 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2422 setMessage("Compacting database.");
2424 listManager.compactDatabase();
2426 setMessage("Database compact is complete.");
2427 logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2429 @SuppressWarnings("unused")
2430 private void accountInformation() {
2431 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2432 AccountDialog dialog = new AccountDialog();
2434 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2436 @SuppressWarnings("unused")
2437 private void releaseNotes() {
2438 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
2439 QDialog dialog = new QDialog(this);
2440 QHBoxLayout layout = new QHBoxLayout();
2441 QTextEdit textBox = new QTextEdit();
2442 layout.addWidget(textBox);
2443 textBox.setReadOnly(true);
2444 QFile file = new QFile(Global.getFileManager().getHomeDirPath("release.txt"));
2445 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
2446 QIODevice.OpenModeFlag.Text)))
2448 textBox.setText(file.readAll().toString());
2450 dialog.setWindowTitle(tr("Release Notes"));
2451 dialog.setLayout(layout);
2453 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
2455 // Called when user picks Log from the help menu
2456 @SuppressWarnings("unused")
2457 private void logger() {
2458 logger.log(logger.HIGH, "Entering NeverNote.logger");
2459 QDialog dialog = new QDialog(this);
2460 QHBoxLayout layout = new QHBoxLayout();
2461 QListWidget textBox = new QListWidget();
2462 layout.addWidget(textBox);
2463 textBox.addItems(emitLog);
2465 dialog.setLayout(layout);
2466 dialog.setWindowTitle(tr("Mesasge Log"));
2468 logger.log(logger.HIGH, "Leaving NeverNote.logger");
2470 // Menu option "help/about" was selected
2471 @SuppressWarnings("unused")
2472 private void about() {
2473 logger.log(logger.HIGH, "Entering NeverNote.about");
2474 QMessageBox.about(this,
2475 tr("About NeverNote"),
2476 tr("<h4><center><b>NeverNote</b></center></h4><hr><center>Version ")
2478 +tr("<hr></center>Evernote"
2479 +"An Open Source Evernote Client.<br><br>"
2480 +"Licensed under GPL v2. <br><hr><br>"
2481 +"Evernote is copyright 2001-2010 by Evernote Corporation<br>"
2482 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
2483 +"PDFRenderer is licened under the LGPL<br>"
2484 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
2485 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
2486 +"Jazzy is licened under the LGPL<br>"
2487 +"Java is a registered trademark of Oracle Corporation.<br><hr>"));
2488 logger.log(logger.HIGH, "Leaving NeverNote.about");
2490 // Hide the entire left hand side
2491 @SuppressWarnings("unused")
2492 private void toggleLeftSide() {
2495 hidden = !menuBar.hideLeftSide.isChecked();
2496 menuBar.hideLeftSide.setChecked(!hidden);
2498 if (notebookTree.isVisible() != hidden)
2499 toggleNotebookWindow();
2500 if (savedSearchTree.isVisible() != hidden)
2501 toggleSavedSearchWindow();
2502 if (tagTree.isVisible() != hidden)
2504 if (attributeTree.isVisible() != hidden)
2505 toggleAttributesWindow();
2506 if (trashTree.isVisible() != hidden)
2507 toggleTrashWindow();
2509 Global.saveWindowVisible("leftPanel", hidden);
2514 //***************************************************************
2515 //***************************************************************
2516 //** These functions deal with the Toolbar
2517 //***************************************************************
2518 //***************************************************************
2519 // Text in the search bar has been cleared
2520 private void searchFieldCleared() {
2523 // This is done because we want to force a reload of
2524 // images. Some images we may want to highlight the text.
2525 readOnlyCache.clear();
2526 inkNoteCache.clear();
2528 QWebSettings.setMaximumPagesInCache(0);
2529 QWebSettings.setObjectCacheCapacities(0, 0, 0);
2531 searchField.setEditText("");
2532 saveNoteColumnPositions();
2533 saveNoteIndexWidth();
2534 noteIndexUpdated(true);
2535 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
2536 currentNote = listManager.getNoteIndex().get(0);
2537 currentNoteGuid = currentNote.getGuid();
2539 if (currentNote != null)
2540 loadNoteBrowserInformation(browserWindow);
2542 // text in the search bar changed. We only use this to tell if it was cleared,
2543 // otherwise we trigger off searchFieldChanged.
2544 @SuppressWarnings("unused")
2545 private void searchFieldTextChanged(String text) {
2546 if (text.trim().equals("")) {
2547 searchFieldCleared();
2548 if (searchPerformed) {
2550 // This is done because we want to force a reload of
2551 // images. Some images we may want to highlight the text.
2553 readOnlyCache.clear();
2554 inkNoteCache.clear();
2555 QWebSettings.setMaximumPagesInCache(0);
2556 QWebSettings.setObjectCacheCapacities(0, 0, 0);
2558 listManager.setEnSearch("");
2559 listManager.loadNotesIndex();
2560 refreshEvernoteNote(true);
2561 noteIndexUpdated(false);
2563 searchPerformed = false;
2566 // Text in the toolbar has changed
2567 private void searchFieldChanged() {
2568 logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
2570 readOnlyCache.clear();
2571 inkNoteCache.clear();
2572 saveNoteColumnPositions();
2573 saveNoteIndexWidth();
2574 String text = searchField.currentText();
2575 listManager.setEnSearch(text.trim());
2576 listManager.loadNotesIndex();
2577 //--->>> noteIndexUpdated(true);
2578 noteIndexUpdated(false);
2579 refreshEvernoteNote(true);
2580 searchPerformed = true;
2581 logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
2584 // Build the window tool bar
2585 private void setupToolBar() {
2586 logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
2587 toolBar = addToolBar(tr("Tool Bar"));
2588 menuBar.setupToolBarVisible();
2589 if (!Global.isWindowVisible("toolBar"))
2590 toolBar.setVisible(false);
2592 toolBar.setVisible(true);
2594 prevButton = toolBar.addAction("Previous");
2595 QIcon prevIcon = new QIcon(iconPath+"back.png");
2596 prevButton.setIcon(prevIcon);
2597 prevButton.triggered.connect(this, "previousViewedAction()");
2598 togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow"));
2600 nextButton = toolBar.addAction("Next");
2601 QIcon nextIcon = new QIcon(iconPath+"forward.png");
2602 nextButton.setIcon(nextIcon);
2603 nextButton.triggered.connect(this, "nextViewedAction()");
2604 toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow"));
2606 upButton = toolBar.addAction("Up");
2607 QIcon upIcon = new QIcon(iconPath+"up.png");
2608 upButton.setIcon(upIcon);
2609 upButton.triggered.connect(this, "upAction()");
2610 toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow"));
2613 downButton = toolBar.addAction("Down");
2614 QIcon downIcon = new QIcon(iconPath+"down.png");
2615 downButton.setIcon(downIcon);
2616 downButton.triggered.connect(this, "downAction()");
2617 toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow"));
2619 synchronizeButton = toolBar.addAction("Synchronize");
2620 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
2621 synchronizeIconAngle = 0;
2622 synchronizeButton.triggered.connect(this, "evernoteSync()");
2623 toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize"));
2625 printButton = toolBar.addAction("Print");
2626 QIcon printIcon = new QIcon(iconPath+"print.png");
2627 printButton.setIcon(printIcon);
2628 printButton.triggered.connect(this, "printNote()");
2629 togglePrintButton(Global.isToolbarButtonVisible("print"));
2631 tagButton = toolBar.addAction("Tag");
2632 QIcon tagIcon = new QIcon(iconPath+"tag.png");
2633 tagButton.setIcon(tagIcon);
2634 tagButton.triggered.connect(browserWindow, "modifyTags()");
2635 toggleTagButton(Global.isToolbarButtonVisible("tag"));
2637 attributeButton = toolBar.addAction("Attributes");
2638 QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
2639 attributeButton.setIcon(attributeIcon);
2640 attributeButton.triggered.connect(this, "toggleNoteInformation()");
2641 toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
2643 emailButton = toolBar.addAction("Email");
2644 QIcon emailIcon = new QIcon(iconPath+"email.png");
2645 emailButton.setIcon(emailIcon);
2646 emailButton.triggered.connect(this, "emailNote()");
2647 toggleEmailButton(Global.isToolbarButtonVisible("email"));
2649 deleteButton = toolBar.addAction("Delete");
2650 QIcon deleteIcon = new QIcon(iconPath+"delete.png");
2651 deleteButton.setIcon(deleteIcon);
2652 deleteButton.triggered.connect(this, "deleteNote()");
2653 toggleDeleteButton(Global.isToolbarButtonVisible("delete"));
2655 newButton = toolBar.addAction("New");
2656 QIcon newIcon = new QIcon(iconPath+"new.png");
2657 newButton.triggered.connect(this, "addNote()");
2658 newButton.setIcon(newIcon);
2659 toggleNewButton(Global.isToolbarButtonVisible("new"));
2661 allNotesButton = toolBar.addAction("All Notes");
2662 QIcon allIcon = new QIcon(iconPath+"books.png");
2663 allNotesButton.triggered.connect(this, "allNotes()");
2664 allNotesButton.setIcon(allIcon);
2665 toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
2667 toolBar.addSeparator();
2668 toolBar.addWidget(new QLabel(tr("Quota:")));
2669 toolBar.addWidget(quotaBar);
2670 //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
2672 toolBar.addSeparator();
2675 zoomSpinner = new QSpinBox();
2676 zoomSpinner.setMinimum(10);
2677 zoomSpinner.setMaximum(1000);
2678 zoomSpinner.setAccelerated(true);
2679 zoomSpinner.setSingleStep(10);
2680 zoomSpinner.setValue(100);
2681 zoomSpinner.valueChanged.connect(this, "zoomChanged()");
2682 toolBar.addWidget(new QLabel(tr("Zoom")));
2683 toolBar.addWidget(zoomSpinner);
2685 //toolBar.addWidget(new QLabel(" "));
2686 toolBar.addSeparator();
2687 toolBar.addWidget(new QLabel(tr(" Search:")));
2688 toolBar.addWidget(searchField);
2689 QSizePolicy sizePolicy = new QSizePolicy();
2690 sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
2691 searchField.setSizePolicy(sizePolicy);
2692 searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
2694 searchClearButton = toolBar.addAction("Search Clear");
2695 QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
2696 searchClearButton.setIcon(searchClearIcon);
2697 searchClearButton.triggered.connect(this, "searchFieldCleared()");
2698 toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
2700 logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
2702 // Update the sychronize button picture
2704 public QMenu createPopupMenu() {
2705 QMenu contextMenu = super.createPopupMenu();
2707 contextMenu.addSeparator();
2708 QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
2709 contextMenu.addAction(prevAction);
2710 prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
2712 QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
2713 contextMenu.addAction(nextAction);
2714 nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
2716 QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
2717 contextMenu.addAction(upAction);
2718 upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
2720 QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
2721 contextMenu.addAction(downAction);
2722 downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
2724 QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
2725 contextMenu.addAction(synchronizeAction);
2726 synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
2728 QAction printAction = addContextAction("print", tr("Print"));
2729 contextMenu.addAction(printAction);
2730 printAction.triggered.connect(this, "togglePrintButton(Boolean)");
2732 QAction tagAction = addContextAction("tag", tr("Tag"));
2733 contextMenu.addAction(tagAction);
2734 tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
2736 QAction attributeAction = addContextAction("attribute", tr("Attribute"));
2737 contextMenu.addAction(attributeAction);
2738 attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
2740 QAction emailAction = addContextAction("email", tr("Email"));
2741 contextMenu.addAction(emailAction);
2742 emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
2744 QAction deleteAction = addContextAction("delete", tr("Delete"));
2745 contextMenu.addAction(deleteAction);
2746 deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
2748 QAction newAction = addContextAction("new", tr("Add"));
2749 contextMenu.addAction(newAction);
2750 newAction.triggered.connect(this, "toggleNewButton(Boolean)");
2752 QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
2753 contextMenu.addAction(allNotesAction);
2754 allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
2756 QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
2757 contextMenu.addAction(searchClearAction);
2758 searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
2763 private QAction addContextAction(String config, String name) {
2764 QAction newAction = new QAction(this);
2765 newAction.setText(name);
2766 newAction.setCheckable(true);
2767 newAction.setChecked(Global.isToolbarButtonVisible(config));
2770 private void togglePrevArrowButton(Boolean toggle) {
2771 prevButton.setVisible(toggle);
2772 Global.saveToolbarButtonsVisible("prevArrow", toggle);
2774 private void toggleNextArrowButton(Boolean toggle) {
2775 nextButton.setVisible(toggle);
2776 Global.saveToolbarButtonsVisible("nextArrow", toggle);
2778 private void toggleUpArrowButton(Boolean toggle) {
2779 upButton.setVisible(toggle);
2780 Global.saveToolbarButtonsVisible("upArrow", toggle);
2782 private void toggleDownArrowButton(Boolean toggle) {
2783 downButton.setVisible(toggle);
2784 Global.saveToolbarButtonsVisible("downArrow", toggle);
2786 private void toggleSynchronizeButton(Boolean toggle) {
2787 synchronizeButton.setVisible(toggle);
2788 Global.saveToolbarButtonsVisible("synchronize", toggle);
2790 private void togglePrintButton(Boolean toggle) {
2791 printButton.setVisible(toggle);
2792 Global.saveToolbarButtonsVisible("print", toggle);
2794 private void toggleTagButton(Boolean toggle) {
2795 tagButton.setVisible(toggle);
2796 Global.saveToolbarButtonsVisible("tag", toggle);
2798 private void toggleAttributeButton(Boolean toggle) {
2799 attributeButton.setVisible(toggle);
2800 Global.saveToolbarButtonsVisible("attribute", toggle);
2802 private void toggleEmailButton(Boolean toggle) {
2803 emailButton.setVisible(toggle);
2804 Global.saveToolbarButtonsVisible("email", toggle);
2806 private void toggleDeleteButton(Boolean toggle) {
2807 deleteButton.setVisible(toggle);
2808 Global.saveToolbarButtonsVisible("delete", toggle);
2810 private void toggleNewButton(Boolean toggle) {
2811 newButton.setVisible(toggle);
2812 Global.saveToolbarButtonsVisible("new", toggle);
2814 private void toggleAllNotesButton(Boolean toggle) {
2815 allNotesButton.setVisible(toggle);
2816 Global.saveToolbarButtonsVisible("allNotes", toggle);
2818 private void toggleSearchClearButton(Boolean toggle) {
2819 searchClearButton.setVisible(toggle);
2820 Global.saveToolbarButtonsVisible("searchClear", toggle);
2827 @SuppressWarnings("unused")
2828 private void updateSyncButton() {
2830 if (syncIcons == null) {
2831 syncIcons = new ArrayList<QPixmap>();
2833 synchronizeIconAngle = 0;
2834 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
2836 for (int i=0; i<=360; i++) {
2837 QPixmap rotatedPix = new QPixmap(pix.size());
2838 QPainter p = new QPainter(rotatedPix);
2839 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
2840 QSize size = pix.size();
2841 p.translate(size.width()/2, size.height()/2);
2844 p.setBackgroundMode(BGMode.OpaqueMode);
2845 p.translate(-size.width()/2, -size.height()/2);
2846 p.drawPixmap(0,0, pix);
2848 syncIcons.add(rotatedPix);
2852 synchronizeIconAngle++;
2853 if (synchronizeIconAngle > 359)
2854 synchronizeIconAngle=0;
2855 synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
2858 // Synchronize with Evernote
2859 @SuppressWarnings("unused")
2860 private void evernoteSync() {
2861 logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
2862 if (!Global.isConnected)
2864 if (Global.isConnected)
2865 synchronizeAnimationTimer.start(5);
2866 // synchronizeAnimationTimer.start(200);
2868 logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
2870 private void updateQuotaBar() {
2871 long limit = Global.getUploadLimit();
2872 long amount = Global.getUploadAmount();
2873 if (amount>0 && limit>0) {
2874 int percent =(int)(amount*100/limit);
2875 quotaBar.setValue(percent);
2877 quotaBar.setValue(0);
2880 @SuppressWarnings("unused")
2881 private void zoomChanged() {
2882 browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
2885 //****************************************************************
2886 //****************************************************************
2887 //* System Tray functions
2888 //****************************************************************
2889 //****************************************************************
2890 private void trayToggleVisible() {
2895 if (windowMaximized)
2902 @SuppressWarnings("unused")
2903 private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
2904 if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
2905 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
2906 trayToggleVisible();
2911 //***************************************************************
2912 //***************************************************************
2913 //** These functions deal with the trash tree
2914 //***************************************************************
2915 //***************************************************************
2916 // Setup the tree containing the trash.
2917 @SuppressWarnings("unused")
2918 private void trashTreeSelection() {
2919 logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
2921 clearNotebookFilter();
2923 clearAttributeFilter();
2924 clearSavedSearchFilter();
2926 String tempGuid = currentNoteGuid;
2928 // currentNoteGuid = "";
2929 currentNote = new Note();
2930 selectedNoteGUIDs.clear();
2931 listManager.getSelectedNotebooks().clear();
2932 listManager.getSelectedTags().clear();
2933 listManager.setSelectedSavedSearch("");
2934 browserWindow.clear();
2936 // toggle the add buttons
2937 newButton.setEnabled(!newButton.isEnabled());
2938 menuBar.noteAdd.setEnabled(newButton.isEnabled());
2939 menuBar.noteAdd.setVisible(true);
2941 List<QTreeWidgetItem> selections = trashTree.selectedItems();
2942 if (selections.size() == 0) {
2943 currentNoteGuid = trashNoteGuid;
2944 trashNoteGuid = tempGuid;
2945 Global.showDeleted = false;
2946 menuBar.noteRestoreAction.setEnabled(false);
2947 menuBar.noteRestoreAction.setVisible(false);
2950 currentNoteGuid = trashNoteGuid;
2951 trashNoteGuid = tempGuid;
2952 menuBar.noteRestoreAction.setEnabled(true);
2953 menuBar.noteRestoreAction.setVisible(true);
2954 Global.showDeleted = true;
2956 listManager.loadNotesIndex();
2957 noteIndexUpdated(false);
2958 //// browserWindow.setEnabled(newButton.isEnabled());
2959 browserWindow.setReadOnly(!newButton.isEnabled());
2960 logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
2962 // Empty the trash file
2963 @SuppressWarnings("unused")
2964 private void emptyTrash() {
2965 // browserWindow.clear();
2966 listManager.emptyTrash();
2967 if (trashTree.selectedItems().size() > 0) {
2968 listManager.getSelectedNotebooks().clear();
2969 listManager.getSelectedTags().clear();
2970 listManager.setSelectedSavedSearch("");
2971 newButton.setEnabled(!newButton.isEnabled());
2972 menuBar.noteAdd.setEnabled(newButton.isEnabled());
2973 menuBar.noteAdd.setVisible(true);
2974 browserWindow.clear();
2977 clearNotebookFilter();
2978 clearSavedSearchFilter();
2979 clearAttributeFilter();
2981 Global.showDeleted = false;
2982 menuBar.noteRestoreAction.setEnabled(false);
2983 menuBar.noteRestoreAction.setVisible(false);
2985 listManager.loadNotesIndex();
2986 //--->>> noteIndexUpdated(true);
2987 noteIndexUpdated(false);
2990 // Show/Hide trash window
2991 private void toggleTrashWindow() {
2992 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
2993 if (trashTree.isVisible())
2997 menuBar.hideTrash.setChecked(trashTree.isVisible());
2999 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3000 logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3002 private void clearTrashFilter() {
3003 Global.showDeleted = false;
3004 newButton.setEnabled(true);
3005 menuBar.noteAdd.setEnabled(true);
3006 menuBar.noteAdd.setVisible(true);
3007 trashTree.blockSignals(true);
3008 trashTree.clearSelection();
3009 trashTree.blockSignals(false);
3014 //***************************************************************
3015 //***************************************************************
3016 //** These functions deal with connection settings
3017 //***************************************************************
3018 //***************************************************************
3019 // SyncRunner had a problem and things are disconnected
3020 @SuppressWarnings("unused")
3021 private void remoteErrorDisconnect() {
3022 menuBar.connectAction.setText(tr("Connect"));
3023 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3024 menuBar.synchronizeAction.setEnabled(false);
3025 synchronizeAnimationTimer.stop();
3028 // Do a manual connect/disconnect
3029 private void remoteConnect() {
3030 logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3032 if (Global.isConnected) {
3033 Global.isConnected = false;
3034 syncRunner.enDisconnect();
3035 setupConnectMenuOptions();
3040 AESEncrypter aes = new AESEncrypter();
3042 aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("secure.txt")));
3043 } catch (FileNotFoundException e) {
3044 // File not found, so we'll just get empty strings anyway.
3046 String userid = aes.getUserid();
3047 String password = aes.getPassword();
3048 if (!userid.equals("") && !password.equals("")) {
3049 Global.username = userid;
3050 Global.password = password;
3053 // Show the login dialog box
3054 if (!Global.automaticLogin() || userid.equals("")|| password.equals("")) {
3055 LoginDialog login = new LoginDialog();
3058 if (!login.okPressed()) {
3062 Global.username = login.getUserid();
3063 Global.password = login.getPassword();
3065 syncRunner.username = Global.username;
3066 syncRunner.password = Global.password;
3067 syncRunner.userStoreUrl = Global.userStoreUrl;
3068 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3069 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3071 if (Global.getProxyValue("url").equals("")) {
3072 System.setProperty("http.proxyHost","") ;
3073 System.setProperty("http.proxyPort", "") ;
3074 System.setProperty("https.proxyHost","") ;
3075 System.setProperty("https.proxyPort", "") ;
3078 System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3079 System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3080 System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3081 System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3083 if (Global.getProxyValue("userid").equals("")) {
3084 Authenticator.setDefault(new Authenticator() {
<