OSDN Git Service

Evernote APIの帯域制限超過時にエラーメッセージを表示するようにした
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / NeverNote.java
1 /*
2   * This file is part of NixNote/NeighborNote 
3  * Copyright 2009 Randy Baumgarte
4  * Copyright 2013 Yuki Takahashi
5  * 
6  * This file may be licensed under the terms of of the
7  * GNU General Public License Version 2 (the ``GPL'').
8  *
9  * Software distributed under the License is distributed
10  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
11  * express or implied. See the GPL for the specific language
12  * governing rights and limitations.
13  *
14  * You should have received a copy of the GPL along with this
15  * program. If not, go to http://www.gnu.org/licenses/gpl.html
16  * or write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19 */
20 package cx.fbn.nevernote;
21 import java.awt.Desktop;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.net.Authenticator;
27 import java.net.PasswordAuthentication;
28 import java.security.MessageDigest;
29 import java.security.NoSuchAlgorithmException;
30 import java.sql.Connection;
31 import java.sql.DriverManager;
32 import java.sql.SQLException;
33 import java.sql.Statement;
34 import java.text.SimpleDateFormat;
35 import java.util.ArrayList;
36 import java.util.Calendar;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.Date;
41 import java.util.GregorianCalendar;
42 import java.util.HashMap;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.SortedMap;
46 import java.util.Vector;
47
48 import org.apache.log4j.Level;
49 import org.apache.log4j.Logger;
50 import org.h2.tools.ChangeFileEncryption;
51
52 import com.evernote.edam.error.EDAMErrorCode;
53 import com.evernote.edam.error.EDAMNotFoundException;
54 import com.evernote.edam.error.EDAMSystemException;
55 import com.evernote.edam.error.EDAMUserException;
56 import com.evernote.edam.notestore.NoteFilter;
57 import com.evernote.edam.notestore.NoteVersionId;
58 import com.evernote.edam.type.Data;
59 import com.evernote.edam.type.LinkedNotebook;
60 import com.evernote.edam.type.Note;
61 import com.evernote.edam.type.NoteAttributes;
62 import com.evernote.edam.type.Notebook;
63 import com.evernote.edam.type.Publishing;
64 import com.evernote.edam.type.QueryFormat;
65 import com.evernote.edam.type.Resource;
66 import com.evernote.edam.type.SavedSearch;
67 import com.evernote.edam.type.Tag;
68 import com.evernote.edam.type.User;
69 import com.evernote.thrift.TException;
70 import com.trolltech.qt.QThread;
71 import com.trolltech.qt.core.QByteArray;
72 import com.trolltech.qt.core.QDateTime;
73 import com.trolltech.qt.core.QDir;
74 import com.trolltech.qt.core.QEvent;
75 import com.trolltech.qt.core.QFile;
76 import com.trolltech.qt.core.QFileInfo;
77 import com.trolltech.qt.core.QFileSystemWatcher;
78 import com.trolltech.qt.core.QIODevice;
79 import com.trolltech.qt.core.QIODevice.OpenModeFlag;
80 import com.trolltech.qt.core.QLocale;
81 import com.trolltech.qt.core.QMimeData;
82 import com.trolltech.qt.core.QModelIndex;
83 import com.trolltech.qt.core.QSize;
84 import com.trolltech.qt.core.QTemporaryFile;
85 import com.trolltech.qt.core.QTextCodec;
86 import com.trolltech.qt.core.QTextStream;
87 import com.trolltech.qt.core.QThreadPool;
88 import com.trolltech.qt.core.QTimer;
89 import com.trolltech.qt.core.QTranslator;
90 import com.trolltech.qt.core.QUrl;
91 import com.trolltech.qt.core.Qt;
92 import com.trolltech.qt.core.Qt.BGMode;
93 import com.trolltech.qt.core.Qt.DockWidgetArea;
94 import com.trolltech.qt.core.Qt.ItemDataRole;
95 import com.trolltech.qt.core.Qt.KeyboardModifier;
96 import com.trolltech.qt.core.Qt.MouseButton;
97 import com.trolltech.qt.core.Qt.SortOrder;
98 import com.trolltech.qt.core.Qt.WidgetAttribute;
99 import com.trolltech.qt.gui.QAbstractItemView;
100 import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
101 import com.trolltech.qt.gui.QAction;
102 import com.trolltech.qt.gui.QApplication;
103 import com.trolltech.qt.gui.QClipboard;
104 import com.trolltech.qt.gui.QCloseEvent;
105 import com.trolltech.qt.gui.QColor;
106 import com.trolltech.qt.gui.QComboBox;
107 import com.trolltech.qt.gui.QCursor;
108 import com.trolltech.qt.gui.QDesktopServices;
109 import com.trolltech.qt.gui.QDialog;
110 import com.trolltech.qt.gui.QFileDialog;
111 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
112 import com.trolltech.qt.gui.QFileDialog.FileMode;
113 import com.trolltech.qt.gui.QGridLayout;
114 import com.trolltech.qt.gui.QHBoxLayout;
115 import com.trolltech.qt.gui.QIcon;
116 import com.trolltech.qt.gui.QImage;
117 import com.trolltech.qt.gui.QKeySequence;
118 import com.trolltech.qt.gui.QLabel;
119 import com.trolltech.qt.gui.QListWidgetItem;
120 import com.trolltech.qt.gui.QMainWindow;
121 import com.trolltech.qt.gui.QMenu;
122 import com.trolltech.qt.gui.QMessageBox;
123 import com.trolltech.qt.gui.QMessageBox.StandardButton;
124 import com.trolltech.qt.gui.QPainter;
125 import com.trolltech.qt.gui.QPalette.ColorRole;
126 import com.trolltech.qt.gui.QPixmap;
127 import com.trolltech.qt.gui.QPrintDialog;
128 import com.trolltech.qt.gui.QPrinter;
129 import com.trolltech.qt.gui.QShortcut;
130 import com.trolltech.qt.gui.QSizePolicy;
131 import com.trolltech.qt.gui.QSizePolicy.Policy;
132 import com.trolltech.qt.gui.QSpinBox;
133 import com.trolltech.qt.gui.QSplashScreen;
134 import com.trolltech.qt.gui.QSplitter;
135 import com.trolltech.qt.gui.QStatusBar;
136 import com.trolltech.qt.gui.QSystemTrayIcon;
137 import com.trolltech.qt.gui.QTableWidgetItem;
138 import com.trolltech.qt.gui.QTextEdit;
139 import com.trolltech.qt.gui.QToolBar;
140 import com.trolltech.qt.gui.QTreeWidgetItem;
141 import com.trolltech.qt.network.QNetworkAccessManager;
142 import com.trolltech.qt.network.QNetworkProxy;
143 import com.trolltech.qt.network.QNetworkProxy.ProxyType;
144 import com.trolltech.qt.network.QNetworkReply;
145 import com.trolltech.qt.network.QNetworkRequest;
146 import com.trolltech.qt.webkit.QWebPage.WebAction;
147 import com.trolltech.qt.webkit.QWebSettings;
148
149 import cx.fbn.nevernote.config.InitializationException;
150 import cx.fbn.nevernote.config.StartupConfig;
151 import cx.fbn.nevernote.dialog.AccountDialog;
152 import cx.fbn.nevernote.dialog.ConfigDialog;
153 import cx.fbn.nevernote.dialog.DBEncryptDialog;
154 import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
155 import cx.fbn.nevernote.dialog.DatabaseStatus;
156 import cx.fbn.nevernote.dialog.FindDialog;
157 import cx.fbn.nevernote.dialog.IgnoreSync;
158 import cx.fbn.nevernote.dialog.LogFileDialog;
159 import cx.fbn.nevernote.dialog.NotebookArchive;
160 import cx.fbn.nevernote.dialog.NotebookEdit;
161 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
162 import cx.fbn.nevernote.dialog.PublishNotebook;
163 import cx.fbn.nevernote.dialog.SavedSearchEdit;
164 import cx.fbn.nevernote.dialog.SetIcon;
165 import cx.fbn.nevernote.dialog.ShareNotebook;
166 import cx.fbn.nevernote.dialog.SharedNotebookSyncError;
167 import cx.fbn.nevernote.dialog.StackNotebook;
168 import cx.fbn.nevernote.dialog.SynchronizationRequiredWarning;
169 import cx.fbn.nevernote.dialog.TagEdit;
170 import cx.fbn.nevernote.dialog.TagMerge;
171 import cx.fbn.nevernote.dialog.ThumbnailViewer;
172 import cx.fbn.nevernote.dialog.UpgradeAvailableDialog;
173 import cx.fbn.nevernote.dialog.WatchFolder;
174 import cx.fbn.nevernote.evernote.NoteMetadata;
175 import cx.fbn.nevernote.filters.FilterEditorNotebooks;
176 import cx.fbn.nevernote.filters.FilterEditorTags;
177 import cx.fbn.nevernote.gui.AttributeTreeWidget;
178 import cx.fbn.nevernote.gui.BrowserWindow;
179 import cx.fbn.nevernote.gui.DateAttributeFilterTable;
180 import cx.fbn.nevernote.gui.ExternalBrowse;
181 import cx.fbn.nevernote.gui.MainMenuBar;
182 import cx.fbn.nevernote.gui.NotebookTreeWidget;
183 import cx.fbn.nevernote.gui.RensoNoteList;
184 import cx.fbn.nevernote.gui.RensoNoteListDock;
185 import cx.fbn.nevernote.gui.SavedSearchTreeWidget;
186 import cx.fbn.nevernote.gui.SearchPanel;
187 import cx.fbn.nevernote.gui.TabBrowse;
188 import cx.fbn.nevernote.gui.TabBrowserWidget;
189 import cx.fbn.nevernote.gui.TableView;
190 import cx.fbn.nevernote.gui.TagTreeWidget;
191 import cx.fbn.nevernote.gui.Thumbnailer;
192 import cx.fbn.nevernote.gui.TrashTreeWidget;
193 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
194 import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
195 import cx.fbn.nevernote.oauth.OAuthTokenizer;
196 import cx.fbn.nevernote.oauth.OAuthWindow;
197 import cx.fbn.nevernote.sql.DatabaseConnection;
198 import cx.fbn.nevernote.sql.WatchFolderRecord;
199 import cx.fbn.nevernote.threads.IndexRunner;
200 import cx.fbn.nevernote.threads.SyncRunner;
201 import cx.fbn.nevernote.threads.ThumbnailRunner;
202 import cx.fbn.nevernote.utilities.AESEncrypter;
203 import cx.fbn.nevernote.utilities.ApplicationLogger;
204 import cx.fbn.nevernote.utilities.FileImporter;
205 import cx.fbn.nevernote.utilities.FileUtils;
206 import cx.fbn.nevernote.utilities.ListManager;
207 import cx.fbn.nevernote.utilities.SyncTimes;
208 import cx.fbn.nevernote.xml.ExportData;
209 import cx.fbn.nevernote.xml.ImportData;
210 import cx.fbn.nevernote.xml.ImportEnex;
211 import cx.fbn.nevernote.xml.NoteFormatter;
212 //import org.apache.thrift.TException;
213
214
215 public class NeverNote extends QMainWindow{
216         
217         QStatusBar                              statusBar;                                      // Application status bar
218         
219         DatabaseConnection              conn;
220         
221         MainMenuBar                             menuBar;                                        // Main menu bar
222         FindDialog                              find;                                           // Text search in note dialog
223         List<String>                    emitLog;                                        // Messages displayed in the status bar;
224         QSystemTrayIcon                 trayIcon;                                       // little tray icon
225         QMenu                                   trayMenu;                                       // System tray menu
226         QAction                                 trayExitAction;                         // Exit the application
227         QAction                                 trayShowAction;                         // toggle the show/hide action          
228         QAction                                 trayAddNoteAction;                      // Add a note from the system tray
229         QNetworkAccessManager   versionChecker;                         // Used when checking for new versions
230         
231     NotebookTreeWidget          notebookTree;                           // List of notebooks
232     AttributeTreeWidget         attributeTree;                          // List of note attributes
233     TagTreeWidget                       tagTree;                                        // list of user created tags
234     SavedSearchTreeWidget       savedSearchTree;                        // list of saved searches
235     TrashTreeWidget                     trashTree;                                      // Trashcan
236     TableView                           noteTableView;                          //      List of notes (the widget).
237
238     public BrowserWindow        browserWindow;                          // Window containing browser & labels
239     public QToolBar             toolBar;                                        // The tool bar under the menu
240     QComboBox                           searchField;                            // search filter bar on the toolbar;
241     QShortcut                           searchShortcut;                         // Shortcut to search bar
242     boolean                                     searchPerformed = false;        // Search was done?
243     QuotaProgressBar            quotaBar;                                       // The current quota usage
244     
245     ApplicationLogger           logger;
246     List<String>                        selectedNotebookGUIDs;          // List of notebook GUIDs
247     List<String>                        selectedTagGUIDs;                       // List of selected tag GUIDs
248     List<String>                        selectedNoteGUIDs;                      // List of selected notes
249     String                                      selectedSavedSearchGUID;        // Currently selected saved searches
250     private final HashMap<String, ExternalBrowse>       externalWindows;        // Notes being edited by an external window;
251     
252     NoteFilter                          filter;                                         // Note filter
253     String                                      currentNoteGuid;                        // GUID of the current note 
254     Note                                        currentNote;                            // The currently viewed note
255     // ICHANGED
256     HashMap<Integer, Boolean>   noteDirty;                              // Has the note been changed?
257     HashMap<Integer, Boolean>   inkNote;                // if this is an ink note, it is read only
258     HashMap<Integer, Boolean>   readOnly;                               // Is this note read-only?
259         
260   
261     ListManager                         listManager;                                    // DB runnable task
262     
263     List<QTemporaryFile>        tempFiles;                                      // Array of temporary files;
264     
265     QTimer                                      indexTimer;                                     // timer to start the index thread
266     IndexRunner                         indexRunner;                            // thread to index notes
267     QThread                                     indexThread;
268     
269     QTimer                                      syncTimer;                                      // Sync on an interval
270     QTimer                                      syncDelayTimer;                         // Sync delay to free up database
271     SyncRunner                          syncRunner;                                     // thread to do a sync.
272     QThread                                     syncThread;                                     // Thread which talks to evernote
273     ThumbnailRunner                     thumbnailRunner;                        // Runner for thumbnail thread
274     QThread                                     thumbnailThread;                        // Thread that generates pretty pictures
275     QTimer                                      saveTimer;                                      // Timer to save note contents
276     
277     QTimer                                      authTimer;                                      // Refresh authentication
278     QTimer                                      externalFileSaveTimer;          // Save files altered externally
279     QTimer                                      thumbnailTimer;                         // Wakeup & scan for thumbnails
280     QTimer                                      debugTimer;
281     List<String>                        externalFiles;                          // External files to save later
282     List<String>                        importFilesKeep;                        // Auto-import files to save later
283     List<String>                        importFilesDelete;                      // Auto-import files to save later
284     
285     int                                         indexTime;                                      // how often to try and index
286     boolean                                     indexRunning;                           // Is indexing running?
287     boolean                                     indexDisabled;                          // Is indexing disabled?
288     
289     int                                         syncThreadsReady;                       // number of sync threads that are free
290     int                                         syncTime;                                       // Sync interval
291     boolean                                     syncRunning;                            // Is sync running?
292     boolean                                     automaticSync;                          // do sync automatically?
293     QTreeWidgetItem                     attributeTreeSelected;
294
295     QAction                             prevButton;                                     // Go to the previous item viewed
296     QAction                             nextButton;                                     // Go to the next item in the history
297     QAction                             downButton;                                     // Go to the next item in the list
298     QAction                             upButton;                                       // Go to the prev. item in the list;
299     QAction                             synchronizeButton;                      // Synchronize with Evernote
300     QAction                             allNotesButton;                         // Reset & view all notes
301     QTimer                              synchronizeAnimationTimer;      // Timer to change animation button
302     int                                 synchronizeIconAngle;           // Used to rotate sync icon
303     QAction                     printButton;                            // Print Button
304     QAction                             tagButton;                                      // Tag edit button
305     QAction                             attributeButton;                        // Attribute information button
306     QAction                     emailButton;                            // Email button
307     QAction                     deleteButton;                           // Delete button
308     QAction                             newButton;                                      // new Note Button;
309     QSpinBox                    zoomSpinner;                            // Zoom zoom
310     QAction                             searchClearButton;                      // Clear the search field
311     
312     SearchPanel                 searchLayout;                           // Widget to hold search field, zoom, & quota
313     
314     QSplitter                   mainLeftRightSplitter;          // main splitter for left/right side
315     QSplitter                   leftSplitter1;                          // first left hand splitter
316     QSplitter                   browserIndexSplitter;           // splitter between note index & note text
317     
318     QFileSystemWatcher  importKeepWatcher;                      // Watch & keep auto-import
319     QFileSystemWatcher  importDeleteWatcher;            // Watch & Delete auto-import
320     List<String>                importedFiles;                          // History of imported files (so we don't import twice)
321     
322     OnlineNoteHistory   historyWindow;                          // online history window 
323     List<NoteVersionId> versions;                                       // history versions
324     
325     QTimer                              threadMonitorTimer;                     // Timer to watch threads.
326     int                                 dbThreadDeadCount=0;            // number of consecutive dead times for the db thread
327     int                                 syncThreadDeadCount=0;          // number of consecutive dead times for the sync thread
328     int                                 indexThreadDeadCount=0;         // number of consecutive dead times for the index thread
329     int                                 notebookThreadDeadCount=0;      // number of consecutive dead times for the notebook thread
330     int                                 tagDeadCount=0;                         // number of consecutive dead times for the tag thread
331     int                                 trashDeadCount=0;                       // number of consecutive dead times for the trash thread
332     int                                 saveThreadDeadCount=0;          // number of consecutive dead times for the save thread
333     int                                 enRelatedNotesThreadDeadCount=0;        // number of consecutive dead times for the EvernoteRelatedNotes Thread
334     boolean                             disableTagThreadCheck=false;
335     boolean                             disableNotebookThreadCheck=false;
336     boolean                             disableTrashThreadCheck=false;
337     boolean                             disableSaveThreadCheck=false;
338     boolean                             disableSyncThreadCheck=false;
339     boolean                             disableIndexThreadCheck=false;
340     boolean                             disableENRelatedNotesThreadCheck=false;
341     
342     HashMap<String, String>             noteCache;                      // Cash of note content 
343     HashMap<String, Boolean>    readOnlyCache;          // List of cashe notes that are read-only
344     HashMap<String, Boolean>    inkNoteCache;           // List of cache notes that are ink notes 
345         // ICHANGED
346         HashMap<Integer, ArrayList<String>> historyGuids;  // タブごとの以前見たノートのGUID
347         HashMap<Integer, Integer> historyPosition; // Position within the viewed items
348         HashMap<Integer, Boolean> fromHistory; // Is this from the history queue?
349         
350     String                              trashNoteGuid;                          // Guid to restore / set into or out of trash to save position
351     List<Thumbnailer>   thumbGenerators;                                // generate preview image
352     ThumbnailViewer             thumbnailViewer;                        // View preview thumbnail; 
353     boolean                             encryptOnShutdown;                      // should I encrypt when I close?
354     boolean                             decryptOnShutdown;                      // should I decrypt on shutdown;
355     String                              encryptCipher;                          // What cipher should I use?
356     //Signal0                   minimizeToTray;
357     boolean                             windowMaximized = false;        // Keep track of the window state for restores
358     List<String>                pdfReadyQueue;                          // Queue of PDFs that are ready to be rendered.
359     List<QPixmap>               syncIcons;                                      // Array of icons used in sync animation
360     private boolean             closeAction = false;            // Used to say when to close or when to minimize
361     private static Logger log = Logger.getLogger(NeverNote.class); 
362     private String              saveLastPath;                           // last path we used
363     private final QTimer                messageTimer;                           // Timer to clear the status message.
364     private QTimer              blockTimer;
365     BrowserWindow               blockingWindow;
366     
367         // ICHANGED
368         private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
369         private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
370         private final RensoNoteListDock rensoNoteListDock; // 連想ノートリストドックウィジェット
371         ClipBoardObserver cbObserver;
372         String rensoNotePressedItemGuid;
373         
374     String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
375         
376         
377     //***************************************************************
378     //***************************************************************
379     //** Constructor & main entry point
380     //***************************************************************
381     //***************************************************************
382     // Application Constructor  
383         @SuppressWarnings("static-access")
384         public NeverNote(DatabaseConnection dbConn)  {
385                 // ICHANGED
386                 cbObserver = new ClipBoardObserver();
387                 
388                 conn = dbConn;          
389                 if (conn.getConnection() == null) {
390                         String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
391                                 "is accessing the database or NeighborNote is already running.\n\n" +
392                                 "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
393                         
394             QMessageBox.critical(null, tr("Database Connection Error") ,msg);
395                         System.exit(16);
396                 }
397                 setObjectName("mainWindow");
398 //              thread().setPriority(Thread.MAX_PRIORITY);
399                 
400                 logger = new ApplicationLogger("nevernote.log");
401                 logger.log(logger.HIGH, "Starting Application");
402                 
403                 decryptOnShutdown = false;
404                 encryptOnShutdown = false;
405                 conn.checkDatabaseVersion();
406                 
407                 
408                 
409                 // Start building the invalid XML tables
410                 Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
411                 List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
412                 
413                 for (int i=0; i<elements.size(); i++) {
414                         Global.invalidAttributes.put(elements.get(i), conn.getInvalidXMLTable().getInvalidAttributes(elements.get(i)));
415                 }
416                 
417                 logger.log(logger.EXTREME, "Starting GUI build");
418
419                 QTranslator nevernoteTranslator = new QTranslator();
420                 nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("neighbornote_" + QLocale.system().name() + ".qm"));
421                 QApplication.instance().installTranslator(nevernoteTranslator);
422
423                 Global.originalPalette = QApplication.palette();
424                 QApplication.setStyle(Global.getStyle());
425                 if (Global.useStandardPalette())
426                         QApplication.setPalette(QApplication.style().standardPalette());
427         setWindowTitle(tr("NeighborNote"));
428
429         mainLeftRightSplitter = new QSplitter();
430                 // ICHANGED
431                 mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
432                 
433         setCentralWidget(mainLeftRightSplitter);
434         leftSplitter1 = new QSplitter();
435         leftSplitter1.setOrientation(Qt.Orientation.Vertical);
436                 
437         browserIndexSplitter = new QSplitter();
438         browserIndexSplitter.setOrientation(Qt.Orientation.Vertical);
439         
440         //* Setup threads & thread timers
441 //        int indexRunnerCount = Global.getIndexThreads();
442 //       indexRunnerCount = 1;
443         QThreadPool.globalInstance().setMaxThreadCount(Global.threadCount);     // increase max thread count
444
445                 logger.log(logger.EXTREME, "Building list manager");
446         listManager = new ListManager(conn, logger);
447         
448                 logger.log(logger.EXTREME, "Building index runners & timers");
449                 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
450                 indexRunner = new IndexRunner("indexRunner.log",
451                                 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
452                                 Global.getResourceDatabaseUrl(),
453                                 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
454                                 Global.getDatabaseUserPassword(), Global.cipherPassword);
455                 
456                 indexThread = new QThread(indexRunner, "Index Thread");
457         indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
458         indexRunner.indexImageRecognition = Global.indexImageRecognition();
459 //        indexRunner.indexNoteBody = Global.indexNoteBody();
460 //        indexRunner.indexNoteTitle = Global.indexNoteTitle();
461 //        indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
462                 indexThread.start();
463                 
464         synchronizeAnimationTimer = new QTimer();
465         synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
466         
467                 indexTimer = new QTimer();
468                 indexTime = 1000*Global.getIndexThreadSleepInterval();  
469                 indexTimer.start(indexTime);  // Start indexing timer
470                 indexTimer.timeout.connect(this, "indexTimer()");
471                 indexDisabled = false;
472                 indexRunning = false;
473                                 
474                 logger.log(logger.EXTREME, "Setting sync thread & timers");
475                 syncThreadsReady=1;
476                 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
477                 syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
478                                 Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
479                                 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
480                                 Global.getDatabaseUserPassword(), Global.cipherPassword);
481                 
482                 syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
483                 syncTimer = new QTimer();
484                 syncTimer.timeout.connect(this, "syncTimer()");
485         syncRunner.status.message.connect(this, "setMessage(String)");
486         syncRunner.syncSignal.finished.connect(this, "syncThreadComplete(Boolean)");
487         syncRunner.syncSignal.errorDisconnect.connect(this, "remoteErrorDisconnect()");
488         syncRunner.limitSignal.rateLimitReached.connect(this, "informRateLimit(Integer)");
489         syncRunning = false;    
490                 if (syncTime > 0) {
491                         automaticSync = true;
492                         syncTimer.start(syncTime*60*1000);
493                 } else {
494                         automaticSync = false;
495                         syncTimer.stop();
496                 }
497                 syncRunner.setEvernoteUpdateCount(Global.getEvernoteUpdateCount());
498                 syncThread = new QThread(syncRunner, "Synchronization Thread");
499                 syncThread.start();
500                 
501                 
502                 logger.log(logger.EXTREME, "Starting thumnail thread");
503                 pdfReadyQueue = new ArrayList<String>();
504                 // ICHANGED Global.getBehaviorDatabaseUrl()を追加
505                 thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
506                                 Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
507                                 Global.getResourceDatabaseUrl(),
508                                 Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
509                                 Global.getDatabaseUserPassword(), Global.cipherPassword);
510                 
511                 thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
512                 thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
513                 thumbnailThread.start();
514                 thumbGenerators = new ArrayList<Thumbnailer>();
515                 thumbnailTimer = new QTimer();
516                 thumbnailTimer.timeout.connect(this, "thumbnailTimer()");
517                 thumbnailTimer();
518                 thumbnailTimer.setInterval(500*1000);  // Thumbnail every minute
519                 thumbnailTimer.start();
520                 
521 //              debugTimer = new QTimer();
522 //              debugTimer.timeout.connect(this, "debugDirty()");
523 //              debugTimer.start(1000*60);
524                 
525                 logger.log(logger.EXTREME, "Starting authentication timer");
526                 authTimer = new QTimer();
527                 authTimer.timeout.connect(this, "authTimer()");
528                 authTimer.start(1000*60*15);
529                 syncRunner.syncSignal.authRefreshComplete.connect(this, "authRefreshComplete(boolean)");
530                 
531                 logger.log(logger.EXTREME, "Setting save note timer");
532                 saveTimer = new QTimer();
533                 saveTimer.timeout.connect(this, "saveNote()");
534                 if (Global.getAutoSaveInterval() > 0) {
535                         saveTimer.setInterval(1000*60*Global.getAutoSaveInterval()); 
536                         saveTimer.start();
537                 }
538                 listManager.saveRunner.noteSignals.noteSaveRunnerError.connect(this, "saveRunnerError(String, String)");
539                 
540                 logger.log(logger.EXTREME, "Starting external file monitor timer");
541                 externalFileSaveTimer = new QTimer();
542                 externalFileSaveTimer.timeout.connect(this, "externalFileEditedSaver()");
543                 externalFileSaveTimer.setInterval(1000*5);   // save every 5 seconds;
544                 externalFiles = new ArrayList<String>();
545                 importFilesDelete = new ArrayList<String>();
546                 importFilesKeep = new ArrayList<String>();
547                 externalFileSaveTimer.start();
548                 
549         notebookTree = new NotebookTreeWidget(conn);
550         attributeTree = new AttributeTreeWidget();
551         tagTree = new TagTreeWidget(conn);
552         savedSearchTree = new SavedSearchTreeWidget();
553         trashTree = new TrashTreeWidget();
554                 // ICHANGED
555                 noteTableView = new TableView(logger, listManager, this);     
556         
557         searchField = new QComboBox();
558         searchField.setObjectName("searchField");
559         //setStyleSheet("QComboBox#searchField { background-color: yellow }");
560         searchField.setEditable(true);
561         searchField.activatedIndex.connect(this, "searchFieldChanged()");
562         searchField.setDuplicatesEnabled(false);
563         searchField.editTextChanged.connect(this,"searchFieldTextChanged(String)");
564         searchShortcut = new QShortcut(this);
565         setupShortcut(searchShortcut, "Focus_Search");
566         searchShortcut.activated.connect(this, "focusSearch()");
567         
568         quotaBar = new QuotaProgressBar();
569         // Setup the zoom
570         zoomSpinner = new QSpinBox();
571         zoomSpinner.setMinimum(10);
572         zoomSpinner.setMaximum(1000);
573         zoomSpinner.setAccelerated(true);
574         zoomSpinner.setSingleStep(10);
575         zoomSpinner.setValue(100);
576         zoomSpinner.valueChanged.connect(this, "zoomChanged()");
577         
578         searchLayout = new SearchPanel(searchField, quotaBar, notebookTree, zoomSpinner);
579         
580         
581         QGridLayout leftGrid = new QGridLayout();
582         leftSplitter1.setContentsMargins(5, 0, 0, 7);
583         leftSplitter1.setLayout(leftGrid);
584         leftGrid.addWidget(searchLayout,1,1);
585         leftGrid.addWidget(tagTree,2,1);
586         leftGrid.addWidget(attributeTree,3,1);
587         leftGrid.addWidget(savedSearchTree,4,1);
588         leftGrid.addWidget(trashTree,5, 1);
589         
590         // Setup the browser window
591         noteCache = new HashMap<String,String>();
592         readOnlyCache = new HashMap<String, Boolean>();
593         inkNoteCache = new HashMap<String, Boolean>();
594         // ICHANGED
595         browserWindow = new BrowserWindow(conn, cbObserver);
596
597                 // ICHANGED 下から移動してきた。
598                 historyGuids = new HashMap<Integer, ArrayList<String>>();
599                 historyPosition = new HashMap<Integer, Integer>();
600                 fromHistory = new HashMap<Integer, Boolean>();
601                 
602                 // ICHANGED タブブラウザ作成
603                 tabWindows = new HashMap<Integer, TabBrowse>();
604                 tabBrowser = new TabBrowserWidget(this);
605                 tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
606                 tabBrowser.setMovable(true);
607                 tabBrowser.setTabsClosable(true);
608                 TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver);
609                 browserWindow = tab.getBrowserWindow();
610                 int index = tabBrowser.addNewTab(tab, "");
611                 tabWindows.put(index, tab);
612                 tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)");
613                 tabBrowser.tabCloseRequested.connect(this, "tabWindowClosing(int)");
614                 
615                 noteDirty = new HashMap<Integer, Boolean>();
616                 noteDirty.put(index, false);
617                 
618                 inkNote = new HashMap<Integer, Boolean>();
619                 readOnly = new HashMap<Integer, Boolean>();
620
621                 // ICHANGED
622                 // 履歴記録のハッシュマップを初期化
623                 historyGuids.put(index, new ArrayList<String>());
624                 historyPosition.put(index, 0);
625                 fromHistory.put(index, false);
626                 
627         mainLeftRightSplitter.addWidget(leftSplitter1);
628         mainLeftRightSplitter.addWidget(browserIndexSplitter);
629         
630                 // ICHANGED
631                 // 連想ノートリストをセットアップ
632         rensoNoteListDock = new RensoNoteListDock(conn, this, syncRunner, iconPath, tr("Renso Note List"));
633                 addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
634
635                 if (Global.getListView() == Global.View_List_Wide) {
636                         browserIndexSplitter.addWidget(noteTableView);
637                         // ICHANGED
638                         browserIndexSplitter.addWidget(tabBrowser);
639                         // browserIndexSplitter.addWidget(browserWindow);
640                 } else {
641                         mainLeftRightSplitter.addWidget(noteTableView);
642                         // ICHANGED
643                         mainLeftRightSplitter.addWidget(tabBrowser);
644                         // mainLeftRightSplitter.addWidget(browserWindow);
645                 }
646         
647         // Setup the thumbnail viewer
648         thumbnailViewer = new ThumbnailViewer();
649         thumbnailViewer.upArrow.connect(this, "upAction()");
650         thumbnailViewer.downArrow.connect(this, "downAction()");
651         thumbnailViewer.leftArrow.connect(this, "nextViewedAction()");
652         thumbnailViewer.rightArrow.connect(this, "previousViewedAction()");
653         
654         //Setup external browser manager
655         externalWindows = new HashMap<String, ExternalBrowse>();
656
657         listManager.loadNotesIndex();
658         initializeNotebookTree();
659         initializeTagTree();
660         initializeSavedSearchTree();
661         attributeTree.itemClicked.connect(this, "attributeTreeClicked(QTreeWidgetItem, Integer)");
662         attributeTreeSelected = null;
663         initializeNoteTable();    
664
665                 selectedNoteGUIDs = new ArrayList<String>();
666                 statusBar = new QStatusBar();
667                 setStatusBar(statusBar);
668                 menuBar = new MainMenuBar(this);
669                 emitLog = new ArrayList<String>();
670                 
671                 tagTree.setDeleteAction(menuBar.tagDeleteAction);
672                 tagTree.setMergeAction(menuBar.tagMergeAction);
673                 tagTree.setEditAction(menuBar.tagEditAction);
674                 tagTree.setAddAction(menuBar.tagAddAction);
675                 tagTree.setIconAction(menuBar.tagIconAction);
676                 tagTree.setVisible(Global.isWindowVisible("tagTree"));
677                 leftSplitter1.setVisible(Global.isWindowVisible("leftPanel"));
678                 tagTree.noteSignal.tagsAdded.connect(this, "tagsAdded(String, String)");
679                 menuBar.hideTags.setChecked(Global.isWindowVisible("tagTree"));
680                 listManager.tagSignal.listChanged.connect(this, "reloadTagTree()");
681                 
682                 if (!Global.isWindowVisible("zoom")) {
683                         searchLayout.hideZoom();
684                         menuBar.hideZoom.setChecked(false);
685                 } 
686         
687                 notebookTree.setDeleteAction(menuBar.notebookDeleteAction);
688                 notebookTree.setEditAction(menuBar.notebookEditAction);
689                 notebookTree.setAddAction(menuBar.notebookAddAction);
690                 notebookTree.setIconAction(menuBar.notebookIconAction);
691                 notebookTree.setStackAction(menuBar.notebookStackAction);
692                 notebookTree.setPublishAction(menuBar.notebookPublishAction);
693                 notebookTree.setShareAction(menuBar.notebookShareAction);
694                 notebookTree.setVisible(Global.isWindowVisible("notebookTree"));
695                 notebookTree.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
696                 notebookTree.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
697             notebookTree.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
698                 menuBar.hideNotebooks.setChecked(Global.isWindowVisible("notebookTree"));
699
700                 savedSearchTree.setAddAction(menuBar.savedSearchAddAction);
701                 savedSearchTree.setEditAction(menuBar.savedSearchEditAction);
702                 savedSearchTree.setDeleteAction(menuBar.savedSearchDeleteAction);
703                 savedSearchTree.setIconAction(menuBar.savedSearchIconAction);
704                 savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
705                 savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
706                 menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
707                 
708                 // ICHANGED noteTableViewに新しいタブで開くを追加
709                 noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
710                         
711                 noteTableView.setAddAction(menuBar.noteAdd);
712                 
713                 // ICHANGED noteTableViewに新しいタブでノート追加を追加
714                 noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
715                 
716                 noteTableView.setDeleteAction(menuBar.noteDelete);
717                 noteTableView.setRestoreAction(menuBar.noteRestoreAction);
718                 noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
719                 noteTableView.setNoteHistoryAction(menuBar.noteOnlineHistoryAction);
720                 noteTableView.noteSignal.titleColorChanged.connect(this, "titleColorChanged(Integer)");
721                 noteTableView.noteSignal.notePinned.connect(this, "notePinned()");
722                 noteTableView.setMergeNotesAction(menuBar.noteMergeAction);
723                 noteTableView.setCopyAsUrlAction(menuBar.noteCopyAsUrlAction);
724                 noteTableView.doubleClicked.connect(this, "listDoubleClick()");
725                 listManager.trashSignal.countChanged.connect(trashTree, "updateCounts(Integer)");
726                 
727                 quotaBar.setMouseClickAction(menuBar.accountAction);
728                 
729                 trashTree.load();
730         trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
731                 trashTree.setEmptyAction(menuBar.emptyTrashAction);
732                 trashTree.setVisible(Global.isWindowVisible("trashTree"));
733                 menuBar.hideTrash.setChecked(Global.isWindowVisible("trashTree"));
734                 trashTree.updateCounts(listManager.getTrashCount());
735                 attributeTree.setVisible(Global.isWindowVisible("attributeTree"));
736                 menuBar.hideAttributes.setChecked(Global.isWindowVisible("attributeTree"));
737
738                 noteTableView.setVisible(Global.isWindowVisible("noteList"));
739                 menuBar.hideNoteList.setChecked(Global.isWindowVisible("noteList"));
740                 
741                 // ICHANGED
742                 if (!Global.isWindowVisible("editorButtonBar")) {
743                         menuBar.showEditorBar.setChecked(false);
744                         toggleEditorButtonBar();
745                 }
746                 
747                 if (!Global.isWindowVisible("leftPanel"))
748                         menuBar.hideLeftSide.setChecked(true);
749                 
750                 // ICHANGED
751                 if (Global.isWindowVisible("noteInformation")) {
752                         menuBar.noteAttributes.setChecked(true);
753                         toggleNoteInformation();
754                 }
755                 
756                 quotaBar.setVisible(Global.isWindowVisible("quota"));
757                 // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
758                 // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
759                 if (!Global.isWindowVisible("quota"))
760                         menuBar.hideQuota.setChecked(false);
761                 
762                 searchField.setVisible(Global.isWindowVisible("searchField"));
763                 // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
764                 // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
765                 if (!Global.isWindowVisible("searchField"))
766                         menuBar.hideSearch.setChecked(false);
767                 
768                 if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
769                         searchLayout.hide();
770                 
771                 setMenuBar(menuBar);
772                 setupToolBar();
773                 find = new FindDialog();
774                 find.getOkButton().clicked.connect(this, "doFindText()");
775                 
776                 // Setup the tray icon menu bar
777                 trayShowAction = new QAction(tr("Show/Hide"), this);
778                 trayExitAction = new QAction(tr("Exit"), this);
779                 trayAddNoteAction = new QAction(tr("Add Note"), this);
780                 
781                 trayExitAction.triggered.connect(this, "closeNeverNote()");
782                 trayAddNoteAction.triggered.connect(this, "addNote()");
783                 trayShowAction.triggered.connect(this, "trayToggleVisible()");
784                 
785                 trayMenu = new QMenu(this);
786                 trayMenu.addAction(trayAddNoteAction);
787                 trayMenu.addAction(trayShowAction);
788                 trayMenu.addAction(trayExitAction);
789                 
790                 
791                 trayIcon = new QSystemTrayIcon(this);
792                 trayIcon.setToolTip(tr("NeighborNote"));
793                 trayIcon.setContextMenu(trayMenu);
794                 trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
795
796                 currentNoteGuid="";
797                 currentNoteGuid = Global.getLastViewedNoteGuid();
798                 if (currentNoteGuid.equals(""))
799                         currentNote = new Note();
800                 
801                 // ICHANGED
802                 /* 上に移動したので要らない
803                 historyGuids = new ArrayList<String>();
804                 historyPosition = 0;
805                 fromHistory = false;
806                 */
807                 
808                 if (!currentNoteGuid.trim().equals("")) {
809                         currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
810                 }
811                 
812                 noteIndexUpdated(true);
813                 showColumns();
814                 menuBar.showEditorBar.setChecked(Global.isWindowVisible("editorButtonBar"));
815                 if (menuBar.showEditorBar.isChecked())
816                 showEditorButtons(browserWindow);
817                 tagIndexUpdated(true);
818                 savedSearchIndexUpdated();
819                 notebookIndexUpdated();
820                 updateQuotaBar();
821         setupSyncSignalListeners();        
822         setupBrowserSignalListeners();
823         setupIndexListeners();
824               
825         
826         tagTree.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
827         tagTree.showAllTags(true);
828
829                 QIcon appIcon = new QIcon(iconPath+"nevernote.png");
830                 if (QSystemTrayIcon.isSystemTrayAvailable()) {
831                         setWindowIcon(appIcon);
832                         trayIcon.setIcon(appIcon);
833                         if (Global.showTrayIcon() || Global.minimizeOnClose())
834                                 trayIcon.show();
835                         else
836                                 trayIcon.hide();
837                 }
838         
839         scrollToGuid(currentNoteGuid);
840         if (Global.automaticLogin()) {
841                 remoteConnect();
842                 if (Global.isConnected)
843                         syncTimer();
844         }
845         setupFolderImports();
846         
847         loadStyleSheet();
848         restoreWindowState(true);
849         
850         if (Global.mimicEvernoteInterface) {
851                 notebookTree.selectGuid("");
852         }
853         
854         threadMonitorTimer = new QTimer();
855         threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
856         threadMonitorTimer.start(1000*10);  // Check for threads every 10 seconds;              
857         
858                 // ICHANGED たぶんこれはいらない
859                 // IFIXED ?
860                 /*
861                 historyGuids.add(currentNoteGuid);
862                 historyPosition = 1;
863                 */
864         
865         menuBar.blockSignals(true);
866         menuBar.narrowListView.blockSignals(true);
867         menuBar.wideListView.blockSignals(true);
868         if (Global.getListView() == Global.View_List_Narrow) { 
869                 menuBar.narrowListView.setChecked(true);
870         }
871         else{ 
872                 menuBar.wideListView.setChecked(true);
873         }
874         menuBar.blockSignals(false);
875         menuBar.narrowListView.blockSignals(false);
876         menuBar.wideListView.blockSignals(false);
877         
878                 // IFIXED
879                 // 上に同じコードがあるよね? とりあえずコメントアウト
880                 /*
881                  * if (Global.getListView() == Global.View_List_Wide) {
882                  * browserIndexSplitter.addWidget(noteTableView); // ICHANGED //
883                  * browserIndexSplitter.addWidget(tabBrowser);
884                  * browserIndexSplitter.addWidget(browserWindow); } else {
885                  * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED //
886                  * mainLeftRightSplitter.addWidget(tabBrowser);
887                  * mainLeftRightSplitter.addWidget(browserWindow); }
888                  */
889         
890                 messageTimer = new QTimer();
891                 messageTimer.timeout.connect(this, "clearMessage()");
892                 messageTimer.setInterval(1000*15);
893                 clearMessage();
894         
895         int sortCol = Global.getSortColumn();
896                 int sortOrder = Global.getSortOrder();
897                 noteTableView.proxyModel.blocked = true;
898                 // We sort the table twice to fix a bug.  For some reaosn the table won't sort properly if it is in narrow
899                 // list view and sorted descending on the date  created.  By sorting it twice it forces the proper sort.  Ugly.
900                 if (sortCol == 0 && sortOrder == 1 && Global.getListView() == Global.View_List_Narrow) 
901                         noteTableView.sortByColumn(sortCol, SortOrder.resolve(0));   
902                 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
903                 noteTableView.proxyModel.blocked = false;
904                 noteTableView.proxyModel.sortChanged.connect(this, "tableSortOrderChanged(Integer,Integer)");
905                 
906                 // Set the startup notebook
907         String defaultNotebook = Global.getStartupNotebook();
908         if (!defaultNotebook.equals("AllNotebooks") && !defaultNotebook.equals("")) {
909                 for (int k=0; k<listManager.getNotebookIndex().size(); k++) {
910                         if (listManager.getNotebookIndex().get(k).isDefaultNotebook()) {
911                                 notebookTree.clearSelection();
912                                 notebookTree.selectGuid(listManager.getNotebookIndex().get(k).getGuid());
913                                 notebookTree.selectionSignal.emit();
914                         }
915                 }
916         }
917                 
918                 if (Global.checkVersionUpgrade()) {
919                         checkForUpdates();
920                 }
921                 
922                 // ICHANGED
923                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
924                         menuBar.noteAddNewTab.setEnabled(false);
925                 }
926         }
927         
928         
929         public void debugDirty() {
930                 List<Note> dirty = conn.getNoteTable().getDirty();
931                 logger.log(logger.LOW, "------ Dirty Notes List Begin ------");
932                 for (int i=0; i<dirty.size(); i++) {
933                         logger.log(logger.LOW, "GUID: " +dirty.get(i).getGuid() + " Title:" + dirty.get(i).getTitle());
934                 }
935                 logger.log(logger.LOW, "------ Dirty Notes List End ------");
936         }
937                 
938         // Main entry point
939         public static void main(String[] args) {
940                 log.setLevel(Level.FATAL);
941                 QApplication.initialize(args);
942                 QPixmap pixmap = new QPixmap("classpath:cx/fbn/nevernote/icons/splash_logo.png");
943                 QSplashScreen splash = new QSplashScreen(pixmap);
944                 boolean showSplash;
945                 
946                 DatabaseConnection dbConn;
947
948         try {
949             initializeGlobalSettings(args);
950
951             showSplash = Global.isWindowVisible("SplashScreen");
952             if (showSplash)
953                 splash.show();
954
955             dbConn = setupDatabaseConnection();
956
957             // Must be last stage of setup - only safe once DB is open hence we know we are the only instance running
958             Global.getFileManager().purgeResDirectory(true);
959
960         } catch (InitializationException e) {
961             // Fatal
962             e.printStackTrace();
963             QMessageBox.critical(null, "Startup error", "Aborting: " + e.getMessage());
964             return;
965         }
966         
967                 // Setup proxy crap
968                 String proxyUrl = Global.getProxyValue("url");
969                 String proxyPort = Global.getProxyValue("port");
970                 String proxyUserid = Global.getProxyValue("userid");
971                 String proxyPassword = Global.getProxyValue("password");
972                 boolean proxySet = false;
973                 QNetworkProxy proxy = new QNetworkProxy();
974                 proxy.setType(ProxyType.HttpProxy);
975                 if (!proxyUrl.trim().equals("")) {
976                         System.out.println("Proxy URL found: " +proxyUrl);
977                         proxySet = true;
978                         proxy.setHostName(proxyUrl);
979                 }
980                 if (!proxyPort.trim().equals("")) {
981                         System.out.println("Proxy Port found: " +proxyPort);
982                         proxySet = true;
983                         proxy.setPort(Integer.parseInt(proxyPort));
984                 }
985                 if (!proxyUserid.trim().equals("")) {
986                         System.out.println("Proxy Userid found: " +proxyUserid);
987                         proxySet = true;
988                         proxy.setUser(proxyUserid);
989                 }
990                 if (!proxyPassword.trim().equals("")) {
991                         System.out.println("Proxy URL found: " +proxyPassword);
992                         proxySet = true;
993                         proxy.setPassword(proxyPassword);
994                 }
995                 if (proxySet) {
996                         QNetworkProxy.setApplicationProxy(proxy);
997                 }
998                         
999
1000         NeverNote application = new NeverNote(dbConn);
1001                 if (Global.syncOnly) {
1002                         System.out.println("Performing synchronization only.");
1003                         application.remoteConnect();
1004                         if (Global.isConnected) {
1005                                 application.syncRunner.syncNeeded = true;
1006                                 application.syncRunner.addWork("SYNC");
1007                                 application.syncRunner.addWork("STOP");
1008                                 while(!application.syncRunner.isIdle());
1009                                 application.closeNeverNote();
1010                         }
1011                         return;
1012                 }
1013
1014                 application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
1015                 if (Global.startMinimized()) 
1016                         application.showMinimized();
1017                 else {
1018                         if (Global.wasWindowMaximized())
1019                                 application.showMaximized();
1020                         else
1021                                 application.show();
1022                 }
1023                 
1024                 if (showSplash)
1025                         splash.finish(application);
1026                 QApplication.exec();
1027                 System.out.println("Goodbye.");
1028                 QApplication.exit();
1029         }
1030
1031     /**
1032      * Open the internal database, or create if not present
1033      *
1034      * @throws InitializationException when opening the database fails, e.g. because another process has it locked
1035      */
1036     private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
1037         ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
1038         
1039         File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
1040         File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
1041                 // IFIXED resourceDatabaseNameになっていたので修正
1042                 File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
1043                 // ICHANGED
1044                 File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
1045                                 
1046                 if (!f.exists())
1047                         Global.setDatabaseUrl("");
1048                 if (!fr.exists())
1049                         Global.setResourceDatabaseUrl("");              
1050                 if (!fi.exists())
1051                         Global.setIndexDatabaseUrl(""); 
1052                 // ICHANGED
1053                 if (!fb.exists())
1054                         Global.setBehaviorDatabaseUrl("");
1055         
1056         if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
1057             boolean goodCheck = false;
1058             while (!goodCheck) {
1059                 DatabaseLoginDialog dialog = new DatabaseLoginDialog();
1060                 dialog.exec();
1061                 if (!dialog.okPressed())
1062                     System.exit(0);
1063                 Global.cipherPassword = dialog.getPassword();
1064                 goodCheck = databaseCheck(Global.getDatabaseUrl(), Global.getDatabaseUserid(),
1065                         Global.getDatabaseUserPassword(), Global.cipherPassword);
1066             }
1067         }
1068         // ICHANGED Global.getBehaviorDatabaserUrl()を追加
1069         DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(), 
1070                         Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
1071                         Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
1072        return dbConn;
1073     }
1074     
1075     // Encrypt the database upon shutdown
1076     private void encryptOnShutdown() {
1077         String dbPath= Global.getFileManager().getDbDirPath("");
1078         try {
1079                 
1080                 Statement st = conn.getConnection().createStatement();  
1081                 st.execute("shutdown");
1082                 st = conn.getResourceConnection().createStatement();
1083                 st.execute("shutdown");
1084                 st = conn.getIndexConnection().createStatement();
1085                 st.execute("shutdown");
1086                 // ICHANGED
1087                 st = conn.getBehaviorConnection().createStatement();
1088                 st.execute("shutdown");
1089                 
1090                 if (QMessageBox.question(this, tr("Are you sure"), 
1091                                 tr("Are you sure you wish to encrypt the database?"),
1092                                 QMessageBox.StandardButton.Yes, 
1093                                 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1094                         ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1095                         ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1096                         ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1097                         // ICHANGED
1098                         ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
1099                         
1100                         Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
1101                         Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
1102                         Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
1103                         // ICHANGED
1104                                 Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
1105
1106                         QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
1107                 }
1108         } catch (SQLException e) {
1109                         e.printStackTrace();
1110                 }       
1111     }
1112     
1113     // Decrypt the database upon shutdown
1114     private void decryptOnShutdown() {
1115         String dbPath= Global.getFileManager().getDbDirPath("");
1116         String dbName = "NeverNote";
1117         try {
1118                 Statement st = conn.getConnection().createStatement();  
1119                 st.execute("shutdown");
1120                 if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
1121                         encryptCipher = "AES";
1122                 else
1123                         encryptCipher = "XTEA";
1124                 if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure", 
1125                                 "Are you sure you wish to decrypt the database?"),
1126                                 QMessageBox.StandardButton.Yes, 
1127                                 QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
1128
1129                         ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
1130                         Global.setDatabaseUrl("");
1131                         Global.setResourceDatabaseUrl("");
1132                         Global.setIndexDatabaseUrl("");
1133                         QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
1134                 }
1135                 } catch (SQLException e) {
1136                         e.printStackTrace();
1137                 }       
1138     }
1139     /**
1140      * Encrypt/Decrypt the local database
1141      **/
1142     public void doDatabaseEncrypt() {
1143         // The database is not currently encrypted
1144         if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
1145                 if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
1146                                 "to enhance security and is performed\nupon shutdown, but please be aware that if"+
1147                                 " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
1148                                 "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
1149                                 "Do you wish to proceed?"),
1150                                 QMessageBox.StandardButton.Yes, 
1151                                 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
1152                                 return;
1153                 }
1154                 DBEncryptDialog dialog = new DBEncryptDialog();
1155                 dialog.exec();
1156                 if (dialog.okPressed()) {
1157                         Global.cipherPassword = dialog.getPassword();
1158                         encryptOnShutdown  = true;
1159                         encryptCipher = dialog.getEncryptionMethod();
1160                 }
1161         } else {
1162             DBEncryptDialog dialog = new DBEncryptDialog();
1163             dialog.setWindowTitle(tr("Database Decryption"));
1164             dialog.hideEncryption();
1165             dialog.exec();
1166             if (dialog.okPressed()) {
1167                 if (!dialog.getPassword().equals(Global.cipherPassword)) {
1168                         QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
1169                         return;
1170                 }
1171                 decryptOnShutdown  = true;
1172                 encryptCipher = "";
1173             }
1174         }
1175         return;
1176     }
1177
1178         private static void initializeGlobalSettings(String[] args) throws InitializationException {
1179                 StartupConfig   startupConfig = new StartupConfig();
1180
1181         for (String arg : args) {
1182             String lower = arg.toLowerCase();
1183             if (lower.startsWith("--name="))
1184                startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
1185             if (lower.startsWith("--home="))
1186                startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
1187             if (lower.startsWith("--disable-viewing"))
1188                startupConfig.setDisableViewing(true);
1189             if (lower.startsWith("--sync-only=true"))
1190                 startupConfig.setSyncOnly(true);
1191         }
1192         Global.setup(startupConfig);
1193         
1194     }
1195
1196     // Exit point
1197         @Override
1198         public void closeEvent(QCloseEvent event) {     
1199                 if (Global.minimizeOnClose() && !closeAction) {
1200                         event.ignore();
1201                         hide();
1202                         return;
1203                 }
1204                 logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
1205                 waitCursor(true);
1206                 
1207                 if (currentNote != null & browserWindow != null) {
1208                         if (currentNote.getTitle() != null && browserWindow != null
1209                                         && !currentNote.getTitle().equals(browserWindow.getTitle()))
1210                                 conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
1211                                                 browserWindow.getTitle());
1212                 }
1213                 
1214                 saveNote();
1215                 setMessage(tr("Beginning shutdown."));
1216                 
1217                 // Close down external windows
1218                 Collection<ExternalBrowse> windows = externalWindows.values();
1219                 Iterator<ExternalBrowse> iterator = windows.iterator();
1220                 while (iterator.hasNext()) {
1221                         ExternalBrowse browser = iterator.next();
1222                         browser.windowClosing.disconnect();
1223                         browser.close();
1224                 }
1225                 
1226                 // ICHANGED タブブラウザに対してクローズ処理を行う
1227                 Collection<TabBrowse> win = tabWindows.values();
1228                 Iterator<TabBrowse> it = win.iterator();
1229                 tabBrowser.currentChanged.disconnect();
1230                 tabBrowser.tabCloseRequested.disconnect();
1231                 while (it.hasNext()) {
1232                         TabBrowse browser = it.next();
1233                         browser.close();
1234                 }
1235                 
1236                 externalFileEditedSaver();
1237                 if (Global.isConnected && Global.synchronizeOnClose()) {
1238                         setMessage(tr("Performing synchronization before closing."));
1239                         syncRunner.syncNeeded = true;
1240                         syncRunner.addWork("SYNC");
1241                 } else {
1242                         syncRunner.keepRunning = false;
1243                 }
1244                 syncRunner.addWork("STOP");
1245                 setMessage("Closing Program.");
1246                 threadMonitorTimer.stop();
1247
1248                 thumbnailRunner.addWork("STOP");
1249                 indexRunner.addWork("STOP");
1250                 saveNote();
1251                 listManager.stop();
1252                 saveWindowState();
1253                 
1254                 // 連想ノートリストのEvernote関連ノート取得スレッドを終了
1255                 rensoNoteListDock.getRensoNoteList().stopThread();
1256
1257                 if (tempFiles != null)
1258                         tempFiles.clear();
1259
1260                 browserWindow.noteSignal.tagsChanged.disconnect();
1261                 browserWindow.noteSignal.titleChanged.disconnect();
1262                 browserWindow.noteSignal.noteChanged.disconnect();
1263                 browserWindow.noteSignal.notebookChanged.disconnect();
1264                 browserWindow.noteSignal.createdDateChanged.disconnect();
1265                 browserWindow.noteSignal.alteredDateChanged.disconnect();
1266                 syncRunner.searchSignal.listChanged.disconnect();
1267                 syncRunner.tagSignal.listChanged.disconnect();
1268         syncRunner.notebookSignal.listChanged.disconnect();
1269         syncRunner.noteIndexSignal.listChanged.disconnect();
1270
1271                 if (isVisible())
1272                         Global.saveWindowVisible("toolBar", toolBar.isVisible());
1273                 saveNoteColumnPositions();
1274                 saveNoteIndexWidth();
1275                 
1276                 int width = notebookTree.columnWidth(0);
1277                 Global.setColumnWidth("notebookTreeName", width);
1278                 width = tagTree.columnWidth(0);
1279                 Global.setColumnWidth("tagTreeName", width);
1280                 
1281                 Global.saveWindowMaximized(isMaximized());
1282                 Global.saveCurrentNoteGuid(currentNoteGuid);
1283                         
1284                 int sortCol = noteTableView.proxyModel.sortColumn();
1285                 int sortOrder = noteTableView.proxyModel.sortOrder().value();
1286                 Global.setSortColumn(sortCol);
1287                 Global.setSortOrder(sortOrder);
1288                 
1289                 hide();
1290                 trayIcon.hide();
1291                 Global.keepRunning = false;
1292                 try {
1293                         logger.log(logger.MEDIUM, "Waiting for indexThread to stop");
1294                         if (indexRunner.thread().isAlive())
1295                                 indexRunner.thread().join(50);
1296                         if (!indexRunner.thread().isAlive())
1297                                 logger.log(logger.MEDIUM, "Index thread has stopped");
1298                         else {
1299                                 logger.log(logger.MEDIUM, "Index thread still running - interrupting");
1300                                 indexRunner.thread().interrupt();
1301                         }
1302                 } catch (InterruptedException e1) {
1303                         e1.printStackTrace();
1304                 }
1305                 
1306                 if (!syncRunner.thread().isAlive()) {
1307                         logger.log(logger.MEDIUM, "Waiting for syncThread to stop");
1308                         if (syncRunner.thread().isAlive()) {
1309                                 System.out.println(tr("Synchronizing.  Please be patient."));
1310                                 for(;syncRunner.thread().isAlive();) {
1311                                         try {
1312                                                 wait(10);
1313                                         } catch (InterruptedException e) {
1314                                                 e.printStackTrace();
1315                                         }
1316                                 }
1317                         }
1318                         logger.log(logger.MEDIUM, "Sync thread has stopped");
1319                 }
1320
1321                 if (encryptOnShutdown) {
1322                         encryptOnShutdown();
1323                 }
1324                 if (decryptOnShutdown) {
1325                         decryptOnShutdown();
1326                 }
1327                 try {
1328                         Global.getFileManager().purgeResDirectory(false);
1329                 } catch (InitializationException e) {
1330                         System.out.println(tr("Empty res directory purge failed"));
1331                         e.printStackTrace();
1332                 }
1333                 logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
1334         }
1335
1336
1337         private void closeNeverNote() {
1338                 closeAction = true;
1339                 close();
1340         }
1341         public void setMessage(String s) {
1342                 if (logger != null) 
1343                         logger.log(logger.HIGH, "Entering NeverNote.setMessage");
1344                 else
1345                         System.out.println("*** ERROR *** " +s);
1346                 
1347                 if (statusBar != null) {
1348                         statusBar.show();
1349                         if (logger != null) 
1350                                 logger.log(logger.HIGH, "Message: " +s);
1351                         statusBar.showMessage(s);
1352                         if (emitLog != null)
1353                                 emitLog.add(s);
1354                 
1355                         if (messageTimer != null) {
1356                                 messageTimer.stop();
1357                                 messageTimer.setSingleShot(true);
1358                                 messageTimer.start();
1359                         }
1360                 }
1361                         
1362                 if (logger != null) 
1363                         logger.log(logger.HIGH, "Leaving NeverNote.setMessage");
1364         }
1365         
1366         private void clearMessage() {
1367                 statusBar.clearMessage();
1368                 statusBar.hide();
1369         }
1370                 
1371         private void waitCursor(boolean wait) {
1372                 if (wait) {
1373                         if (QApplication.overrideCursor() == null)
1374                                 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.WaitCursor));
1375                 }
1376                 else {
1377                         if (QApplication.overrideCursor() != null)
1378                                 QApplication.restoreOverrideCursor();
1379                         else
1380                                 QApplication.setOverrideCursor(new QCursor(Qt.CursorShape.ArrowCursor));
1381                 }
1382                 listManager.refreshCounters();
1383         }
1384         
1385         private void setupIndexListeners() {
1386 //              indexRunner.noteSignal.noteIndexed.connect(this, "indexThreadComplete(String)");
1387 //              indexRunner.resourceSignal.resourceIndexed.connect(this, "indexThreadComplete(String)");
1388                 indexRunner.signal.indexStarted.connect(this, "indexStarted()");
1389                 indexRunner.signal.indexFinished.connect(this, "indexComplete()");
1390         }
1391         private void setupSyncSignalListeners() {
1392                 syncRunner.tagSignal.listChanged.connect(this, "tagIndexUpdated()");
1393         syncRunner.searchSignal.listChanged.connect(this, "savedSearchIndexUpdated()");
1394         syncRunner.notebookSignal.listChanged.connect(this, "notebookIndexUpdated()");
1395         syncRunner.noteIndexSignal.listChanged.connect(this, "noteIndexUpdated(boolean)");
1396         syncRunner.noteSignal.quotaChanged.connect(this, "updateQuotaBar()");
1397         
1398                 syncRunner.syncSignal.saveUploadAmount.connect(this,"saveUploadAmount(long)");
1399                 syncRunner.syncSignal.saveUserInformation.connect(this,"saveUserInformation(User)");
1400                 syncRunner.syncSignal.saveEvernoteUpdateCount.connect(this,"saveEvernoteUpdateCount(int)");
1401                 
1402                 syncRunner.noteSignal.guidChanged.connect(this, "noteGuidChanged(String, String)");
1403                 syncRunner.noteSignal.noteChanged.connect(this, "invalidateNoteCache(String, String)");
1404                 syncRunner.resourceSignal.resourceGuidChanged.connect(this, "noteResourceGuidChanged(String,String,String)");
1405                 syncRunner.noteSignal.noteDownloaded.connect(listManager, "noteDownloaded(Note)");
1406                 syncRunner.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1407                 
1408                 syncRunner.syncSignal.refreshLists.connect(this, "refreshLists()");
1409         }
1410         
1411         private void setupBrowserSignalListeners() {
1412                 setupBrowserWindowListeners(browserWindow, true);
1413         }
1414
1415         private void setupBrowserWindowListeners(BrowserWindow browser, boolean master) {
1416                 browser.fileWatcher.fileChanged.connect(this, "externalFileEdited(String)");
1417                 browser.noteSignal.tagsChanged.connect(this, "updateNoteTags(String, List)");
1418             browser.noteSignal.tagsChanged.connect(this, "updateListTags(String, List)");
1419             if (master) browser.noteSignal.noteChanged.connect(this, "setNoteDirty()");
1420             browser.noteSignal.titleChanged.connect(listManager, "updateNoteTitle(String, String)");
1421             browser.noteSignal.titleChanged.connect(this, "updateNoteTitle(String, String)");
1422             browser.noteSignal.notebookChanged.connect(this, "updateNoteNotebook(String, String)");
1423             browser.noteSignal.createdDateChanged.connect(listManager, "updateNoteCreatedDate(String, QDateTime)");
1424             browser.noteSignal.alteredDateChanged.connect(listManager, "updateNoteAlteredDate(String, QDateTime)");
1425             browser.noteSignal.subjectDateChanged.connect(listManager, "updateNoteSubjectDate(String, QDateTime)");
1426             browser.noteSignal.authorChanged.connect(listManager, "updateNoteAuthor(String, String)");
1427             browser.noteSignal.geoChanged.connect(listManager, "updateNoteGeoTag(String, Double,Double,Double)");
1428             browser.noteSignal.geoChanged.connect(this, "setNoteDirty()");
1429             browser.noteSignal.sourceUrlChanged.connect(listManager, "updateNoteSourceUrl(String, String)");
1430         browser.blockApplication.connect(this, "blockApplication(BrowserWindow)");
1431         browser.unblockApplication.connect(this, "unblockApplication()");
1432             if (master) browser.focusLost.connect(this, "saveNote()");
1433             browser.resourceSignal.contentChanged.connect(this, "externalFileEdited(String)");
1434             browser.evernoteLinkClicked.connect(this, "evernoteLinkClick(String, String)");
1435         }
1436
1437         //**************************************************
1438         //* Setup shortcuts
1439         //**************************************************
1440         private void setupShortcut(QShortcut action, String text) {
1441                 if (!Global.shortcutKeys.containsAction(text))
1442                         return;
1443                 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
1444         }
1445         
1446         //***************************************************************
1447         //***************************************************************
1448         //* Settings and look & feel
1449         //***************************************************************
1450         //***************************************************************
1451         @SuppressWarnings("unused")
1452         private void settings() {
1453                 logger.log(logger.HIGH, "Entering NeverNote.settings");
1454
1455                 saveNoteColumnPositions();
1456                 saveNoteIndexWidth();
1457                 showColumns();
1458         ConfigDialog settings = new ConfigDialog(this, conn);
1459         String dateFormat = Global.getDateFormat();
1460         String timeFormat = Global.getTimeFormat();
1461         
1462                 indexTime = 1000*Global.getIndexThreadSleepInterval();  
1463                 indexTimer.start(indexTime);  // reset indexing timer
1464         
1465         settings.exec();
1466         indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
1467 //        indexRunner.indexNoteBody = Global.indexNoteBody();
1468 //        indexRunner.indexNoteTitle = Global.indexNoteTitle();
1469 //        indexRunner.specialIndexCharacters = Global.getSpecialIndexCharacters();
1470         indexRunner.indexImageRecognition = Global.indexImageRecognition();
1471         if (Global.showTrayIcon() || Global.minimizeOnClose())
1472                 trayIcon.show();
1473         else
1474                 trayIcon.hide();
1475         showColumns();
1476         if (menuBar.showEditorBar.isChecked()){
1477                 // ICHANGED 
1478                 for(int i = 0; i < tabBrowser.count(); i++){
1479                         BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
1480                         showEditorButtons(browser);
1481                 }
1482                 
1483         }
1484         
1485         // Reset the save timer
1486         if (Global.getAutoSaveInterval() > 0)
1487                         saveTimer.setInterval(1000*60*Global.getAutoSaveInterval());
1488         else
1489                 saveTimer.stop();
1490         
1491         
1492         // Set special reloads
1493         if (settings.getDebugPage().reloadSharedNotebooksClicked()) {
1494                 conn.executeSql("Delete from LinkedNotebook");
1495                 conn.executeSql("delete from SharedNotebook");
1496                 conn.executeSql("Delete from Notebook where linked=true");
1497                 conn.executeSql("Insert into Sync (key, value) values ('FullLinkedNotebookSync', 'true')");
1498                 conn.executeSql("Insert into Sync (key, value) values ('FullSharedNotebookSync', 'true')");
1499         }
1500
1501         // Reload user data
1502         noteCache.clear();
1503         readOnlyCache.clear();
1504         inkNoteCache.clear();
1505         noteIndexUpdated(true);
1506                 
1507         logger.log(logger.HIGH, "Leaving NeverNote.settings");
1508         }
1509         // Restore things to the way they were
1510         private void restoreWindowState(boolean mainWindow) {
1511                 // We need to name things or this doesn't work.
1512                 setObjectName("NeverNote");
1513         restoreState(Global.restoreState(objectName()));
1514                 mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
1515                 browserIndexSplitter.setObjectName("browserIndexSplitter");
1516                 leftSplitter1.setObjectName("leftSplitter1");
1517                 // ICHANGED
1518                 rensoNoteListDock.setObjectName("rensoNoteListDock");
1519                 
1520                 // Restore the actual positions.
1521                 if (mainWindow)
1522                         restoreGeometry(Global.restoreGeometry(objectName()));
1523         mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
1524         browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
1525         leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
1526         // ICHANGED
1527         rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
1528        
1529         }
1530         // Save window positions for the next start
1531         private void saveWindowState() {
1532                 Global.saveGeometry(objectName(), saveGeometry());
1533                 Global.saveState(mainLeftRightSplitter.objectName(), mainLeftRightSplitter.saveState());
1534                 Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
1535                 Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
1536                 Global.saveState(objectName(), saveState());
1537                 // ICHANGED
1538                 Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
1539         }    
1540         // Load the style sheet
1541         private void loadStyleSheet() {
1542                 String styleSheetName = "default.qss";
1543                 if (Global.getStyle().equalsIgnoreCase("cleanlooks"))
1544                                 styleSheetName = "default-cleanlooks.qss";
1545                 String fileName = Global.getFileManager().getQssDirPathUser("default.qss");
1546                 QFile file = new QFile(fileName);
1547                 
1548                 // If a user default.qss doesn't exist, we use the one shipped with NeverNote
1549                 if (!file.exists()) {
1550                         fileName = Global.getFileManager().getQssDirPath(styleSheetName);
1551                         file = new QFile(fileName);
1552                 }
1553                 file.open(OpenModeFlag.ReadOnly);
1554                 String styleSheet = file.readAll().toString();
1555                 file.close();
1556                 setStyleSheet(styleSheet);
1557         }
1558         // Save column positions for the next time
1559         private void saveNoteColumnPositions() {
1560                 int position = noteTableView.header.visualIndex(Global.noteTableCreationPosition);
1561                 Global.setColumnPosition("noteTableCreationPosition", position);
1562                 position = noteTableView.header.visualIndex(Global.noteTableTagPosition);
1563                 Global.setColumnPosition("noteTableTagPosition", position);
1564                 position = noteTableView.header.visualIndex(Global.noteTableNotebookPosition);
1565                 Global.setColumnPosition("noteTableNotebookPosition", position);
1566                 position = noteTableView.header.visualIndex(Global.noteTableChangedPosition);
1567                 Global.setColumnPosition("noteTableChangedPosition", position);
1568                 position = noteTableView.header.visualIndex(Global.noteTableAuthorPosition);
1569                 Global.setColumnPosition("noteTableAuthorPosition", position);
1570                 position = noteTableView.header.visualIndex(Global.noteTableSourceUrlPosition);
1571                 Global.setColumnPosition("noteTableSourceUrlPosition", position);
1572                 position = noteTableView.header.visualIndex(Global.noteTableSubjectDatePosition);
1573                 Global.setColumnPosition("noteTableSubjectDatePosition", position);
1574                 position = noteTableView.header.visualIndex(Global.noteTableTitlePosition);
1575                 Global.setColumnPosition("noteTableTitlePosition", position);
1576                 position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
1577                 Global.setColumnPosition("noteTableSynchronizedPosition", position);
1578                 position = noteTableView.header.visualIndex(Global.noteTableGuidPosition);
1579                 Global.setColumnPosition("noteTableGuidPosition", position);
1580                 position = noteTableView.header.visualIndex(Global.noteTableThumbnailPosition);
1581                 Global.setColumnPosition("noteTableThumbnailPosition", position);
1582                 position = noteTableView.header.visualIndex(Global.noteTablePinnedPosition);
1583                 Global.setColumnPosition("noteTablePinnedPosition", position);
1584
1585         }
1586         // Save column widths for the next time
1587         private void saveNoteIndexWidth() {
1588                 int width;
1589         width = noteTableView.getColumnWidth(Global.noteTableCreationPosition);
1590         Global.setColumnWidth("noteTableCreationPosition", width);
1591                 width = noteTableView.getColumnWidth(Global.noteTableChangedPosition);
1592                 Global.setColumnWidth("noteTableChangedPosition", width);
1593                 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1594                 Global.setColumnWidth("noteTableGuidPosition", width);
1595                 width = noteTableView.getColumnWidth(Global.noteTableNotebookPosition);
1596                 Global.setColumnWidth("noteTableNotebookPosition", width);
1597                 width = noteTableView.getColumnWidth(Global.noteTableTagPosition);
1598                 Global.setColumnWidth("noteTableTagPosition", width);
1599                 width = noteTableView.getColumnWidth(Global.noteTableTitlePosition);
1600                 Global.setColumnWidth("noteTableTitlePosition", width);
1601                 width = noteTableView.getColumnWidth(Global.noteTableSourceUrlPosition);
1602                 Global.setColumnWidth("noteTableSourceUrlPosition", width);
1603                 width = noteTableView.getColumnWidth(Global.noteTableAuthorPosition);
1604                 Global.setColumnWidth("noteTableAuthorPosition", width);
1605                 width = noteTableView.getColumnWidth(Global.noteTableSubjectDatePosition);
1606                 Global.setColumnWidth("noteTableSubjectDatePosition", width);
1607                 width = noteTableView.getColumnWidth(Global.noteTableSynchronizedPosition);
1608                 Global.setColumnWidth("noteTableSynchronizedPosition", width);
1609                 width = noteTableView.getColumnWidth(Global.noteTableThumbnailPosition);
1610                 Global.setColumnWidth("noteTableThumbnailPosition", width);
1611                 width = noteTableView.getColumnWidth(Global.noteTableGuidPosition);
1612                 Global.setColumnWidth("noteTableGuidPosition", width);
1613                 width = noteTableView.getColumnWidth(Global.noteTablePinnedPosition);
1614                 Global.setColumnWidth("noteTablePinnedPosition", width);
1615         }
1616         
1617         @SuppressWarnings("unused")
1618         private void toggleSearchWindow() {
1619                 logger.log(logger.HIGH, "Entering NeverNote.toggleSearchWindow");
1620         searchLayout.toggleSearchField();
1621         menuBar.hideSearch.setChecked(searchField.isVisible());
1622         Global.saveWindowVisible("searchField", searchField.isVisible());
1623         logger.log(logger.HIGH, "Leaving NeverNote.toggleSearchWindow");
1624     }   
1625         @SuppressWarnings("unused")
1626         private void toggleQuotaWindow() {
1627                 logger.log(logger.HIGH, "Entering NeverNote.toggleQuotaWindow");
1628         searchLayout.toggleQuotaBar();
1629         menuBar.hideQuota.setChecked(quotaBar.isVisible());
1630         Global.saveWindowVisible("quota", quotaBar.isVisible());
1631         logger.log(logger.HIGH, "Leaving NeverNote.toggleQuotaWindow");
1632     }   
1633         @SuppressWarnings("unused")
1634         private void toggleZoomWindow() {
1635                 logger.log(logger.HIGH, "Entering NeverNote.toggleZoomWindow");
1636         searchLayout.toggleZoom();
1637         menuBar.hideZoom.setChecked(zoomSpinner.isVisible());
1638         Global.saveWindowVisible("zoom", zoomSpinner.isVisible());
1639         logger.log(logger.HIGH, "Leaving NeverNote.toggleZoomWindow");
1640     }   
1641         
1642         
1643         
1644     //***************************************************************
1645     //***************************************************************
1646     //** These functions deal with Notebook menu items
1647     //***************************************************************
1648     //***************************************************************
1649     // Setup the tree containing the user's notebooks.
1650     private void initializeNotebookTree() {       
1651         logger.log(logger.HIGH, "Entering NeverNote.initializeNotebookTree");
1652 //      notebookTree.itemClicked.connect(this, "notebookTreeSelection()");
1653         notebookTree.selectionSignal.connect(this, "notebookTreeSelection()");
1654         listManager.notebookSignal.refreshNotebookTreeCounts.connect(notebookTree, "updateCounts(List, List)");
1655         logger.log(logger.HIGH, "Leaving NeverNote.initializeNotebookTree");
1656     }   
1657     // Listener when a notebook is selected
1658         private void notebookTreeSelection() {
1659                 logger.log(logger.HIGH, "Entering NeverNote.notebookTreeSelection");
1660                 noteTableView.proxyModel.blocked = true;
1661                 
1662                 clearTrashFilter();
1663                 clearAttributeFilter();
1664                 clearSavedSearchFilter();
1665                 if (Global.mimicEvernoteInterface) {
1666                         clearTagFilter();
1667                         //searchField.clear();
1668                         searchField.clearEditText();
1669                 }
1670                 menuBar.noteRestoreAction.setVisible(false);            
1671         menuBar.notebookEditAction.setEnabled(true);
1672         menuBar.notebookDeleteAction.setEnabled(true);
1673         menuBar.notebookPublishAction.setEnabled(true);
1674         menuBar.notebookShareAction.setEnabled(true);
1675         menuBar.notebookIconAction.setEnabled(true);
1676         menuBar.notebookStackAction.setEnabled(true);
1677         
1678                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
1679                 if (!rensoNoteListDock.isEnabled()) {
1680                         rensoNoteListDock.setEnabled(true);
1681                 }
1682                 
1683         List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1684         selectedNotebookGUIDs.clear();
1685                 String guid = "";
1686                 String stackName = "";
1687                 if (selections.size() > 0) {
1688                 guid = (selections.get(0).text(2));
1689                 stackName = selections.get(0).text(0);
1690         }
1691                 if (!Global.mimicEvernoteInterface) {
1692                         // If no notebooks are selected, we make it look like the "all notebooks" one was selected
1693                         if (selections.size()==0) {
1694                                 selectedNotebookGUIDs.clear();
1695                                 for (int i=0; i < listManager.getNotebookIndex().size(); i++) {
1696                                         selectedNotebookGUIDs.add(listManager.getNotebookIndex().get(i).getGuid());
1697                                 }
1698                                 menuBar.notebookEditAction.setEnabled(false);
1699                                 menuBar.notebookDeleteAction.setEnabled(false);
1700                                 menuBar.notebookStackAction.setEnabled(false);
1701                                 menuBar.notebookIconAction.setEnabled(false);
1702                         }
1703                 }
1704         if (!guid.equals("") && !guid.equals("STACK")) {
1705                 selectedNotebookGUIDs.add(guid);
1706                 menuBar.notebookIconAction.setEnabled(true);
1707         } else {
1708                 menuBar.notebookIconAction.setEnabled(true);
1709                         for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1710                                 Notebook book = listManager.getNotebookIndex().get(j);
1711                                 if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
1712                                         selectedNotebookGUIDs.add(book.getGuid());
1713                         }
1714         }
1715         listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1716         listManager.loadNotesIndex();
1717         noteIndexUpdated(false);
1718         refreshEvernoteNote(true);
1719         listManager.refreshCounters = true;
1720         listManager.refreshCounters();
1721         if (selectedNotebookGUIDs.size() == 1) {
1722                 int col = conn.getNotebookTable().getSortColumn(selectedNotebookGUIDs.get(0));
1723                 int order = conn.getNotebookTable().getSortOrder(selectedNotebookGUIDs.get(0));
1724                 if (col != -1) {
1725                         noteTableView.proxyModel.blocked = true;
1726                         if (order == 1)
1727                                 noteTableView.sortByColumn(col, Qt.SortOrder.DescendingOrder);
1728                         else
1729                                 noteTableView.sortByColumn(col, Qt.SortOrder.AscendingOrder);
1730                 }
1731         }
1732         noteTableView.proxyModel.blocked = false;
1733                 logger.log(logger.HIGH, "Leaving NeverNote.notebookTreeSelection");
1734
1735     }
1736     private void clearNotebookFilter() {
1737         notebookTree.blockSignals(true);
1738         notebookTree.clearSelection();
1739                 menuBar.noteRestoreAction.setVisible(false);
1740         menuBar.notebookEditAction.setEnabled(false);
1741         menuBar.notebookDeleteAction.setEnabled(false);
1742         selectedNotebookGUIDs.clear();
1743         listManager.setSelectedNotebooks(selectedNotebookGUIDs);
1744         notebookTree.blockSignals(false);
1745     }
1746         // Triggered when the notebook DB has been updated
1747         private void notebookIndexUpdated() {
1748                 logger.log(logger.HIGH, "Entering NeverNote.notebookIndexUpdated");
1749         
1750                 // Get the possible icons
1751                 HashMap<String, QIcon> icons = conn.getNotebookTable().getAllIcons();
1752         notebookTree.setIcons(icons);
1753         
1754         if (selectedNotebookGUIDs == null)
1755                         selectedNotebookGUIDs = new ArrayList<String>();
1756                 List<Notebook> books = conn.getNotebookTable().getAll();
1757                 for (int i=books.size()-1; i>=0; i--) {
1758                         for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1759                                 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(books.get(i).getGuid())) {
1760                                         books.remove(i);
1761                                         j=listManager.getArchiveNotebookIndex().size();
1762                                 }
1763                         }
1764                 }
1765                 
1766                 
1767                 listManager.countNotebookResults(listManager.getNoteIndex());
1768                 notebookTree.blockSignals(true);
1769         notebookTree.load(books, listManager.getLocalNotebooks());
1770         for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
1771                 boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
1772                 if (!found)
1773                         selectedNotebookGUIDs.remove(i);
1774         }
1775         listManager.refreshCounters = true;
1776         listManager.refreshCounters();
1777         notebookTree.blockSignals(false);
1778         
1779                 logger.log(logger.HIGH, "Leaving NeverNote.notebookIndexUpdated");
1780     }
1781     // Show/Hide note information
1782         @SuppressWarnings("unused")
1783         private void toggleNotebookWindow() {
1784                 logger.log(logger.HIGH, "Entering NeverNote.toggleNotebookWindow");
1785                 searchLayout.toggleNotebook();
1786         menuBar.hideNotebooks.setChecked(notebookTree.isVisible());
1787         Global.saveWindowVisible("notebookTree", notebookTree.isVisible());
1788         logger.log(logger.HIGH, "Leaving NeverNote.toggleNotebookWindow");
1789     }   
1790         // Add a new notebook
1791         @SuppressWarnings("unused")
1792         private void addNotebook() {
1793                 logger.log(logger.HIGH, "Inside NeverNote.addNotebook");
1794                 NotebookEdit edit = new NotebookEdit();
1795                 edit.setNotebooks(listManager.getNotebookIndex());
1796                 edit.exec();
1797         
1798                 if (!edit.okPressed())
1799                         return;
1800         
1801                 Calendar currentTime = new GregorianCalendar();
1802                 Long l = new Long(currentTime.getTimeInMillis());
1803                 String randint = new String(Long.toString(l));
1804         
1805                 Notebook newBook = new Notebook();
1806                 newBook.setUpdateSequenceNum(0);
1807                 newBook.setGuid(randint);
1808                 newBook.setName(edit.getNotebook());
1809                 newBook.setServiceCreated(new Date().getTime());
1810                 newBook.setServiceUpdated(new Date().getTime());
1811                 newBook.setDefaultNotebook(false);
1812                 newBook.setPublished(false);
1813                 
1814                 listManager.getNotebookIndex().add(newBook);
1815                 if (edit.isLocal())
1816                         listManager.getLocalNotebooks().add(newBook.getGuid());
1817                 conn.getNotebookTable().addNotebook(newBook, true, edit.isLocal());
1818                 notebookIndexUpdated();
1819                 listManager.countNotebookResults(listManager.getNoteIndex());
1820 //              notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
1821                 logger.log(logger.HIGH, "Leaving NeverNote.addNotebook");
1822         }
1823         // Edit an existing notebook
1824         @SuppressWarnings("unused")
1825         private void stackNotebook() {
1826                 logger.log(logger.HIGH, "Entering NeverNote.stackNotebook");
1827                 StackNotebook edit = new StackNotebook();
1828                 
1829                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1830                 QTreeWidgetItem currentSelection;
1831                 for (int i=0; i<selections.size(); i++) {
1832                         currentSelection = selections.get(0);
1833                         String guid = currentSelection.text(2);
1834                         if (guid.equalsIgnoreCase("")) {
1835                                  QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack the \"All Notebooks\" item."));
1836                                  return;
1837                         }
1838                         if (guid.equalsIgnoreCase("STACK")) {
1839                                  QMessageBox.critical(this, tr("Unable To Stack") ,tr("You can't stack a stack."));
1840                                  return;
1841                         }
1842                 }
1843
1844                 edit.setStackNames(conn.getNotebookTable().getAllStackNames());
1845
1846                 
1847                 edit.exec();
1848         
1849                 if (!edit.okPressed())
1850                         return;
1851         
1852                 String stack = edit.getStackName();
1853                 
1854                 for (int i=0; i<selections.size(); i++) {
1855                         currentSelection = selections.get(i);
1856                         String guid = currentSelection.text(2);
1857                         listManager.updateNotebookStack(guid, stack);
1858                 }
1859                 notebookIndexUpdated();
1860                 logger.log(logger.HIGH, "Leaving NeverNote.stackNotebook");
1861         }
1862         // Edit an existing notebook
1863         @SuppressWarnings("unused")
1864         private void editNotebook() {
1865                 logger.log(logger.HIGH, "Entering NeverNote.editNotebook");
1866                 NotebookEdit edit = new NotebookEdit();
1867                 
1868                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1869                 QTreeWidgetItem currentSelection;
1870                 currentSelection = selections.get(0);
1871                 edit.setNotebook(currentSelection.text(0));
1872                 
1873                 String guid = currentSelection.text(2);
1874                 if (!guid.equalsIgnoreCase("STACK")) {
1875                         edit.setTitle(tr("Edit Notebook"));
1876                         edit.setNotebooks(listManager.getNotebookIndex());
1877                         edit.setLocalCheckboxEnabled(false);
1878                         for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1879                                 if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1880                                         edit.setDefaultNotebook(listManager.getNotebookIndex().get(i).isDefaultNotebook());
1881                                         i=listManager.getNotebookIndex().size();
1882                                 }
1883                         }
1884                 } else {
1885                         edit.setTitle(tr("Edit Stack"));
1886                         edit.setStacks(conn.getNotebookTable().getAllStackNames());
1887                         edit.hideLocalCheckbox();
1888                         edit.hideDefaultCheckbox();
1889                 }
1890                 
1891                 edit.exec();
1892         
1893                 if (!edit.okPressed())
1894                         return;
1895         
1896                 
1897                 if (guid.equalsIgnoreCase("STACK")) {
1898                         conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1899                         for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
1900                                 if (listManager.getNotebookIndex().get(j).getStack() != null && 
1901                                         listManager.getNotebookIndex().get(j).getStack().equalsIgnoreCase(currentSelection.text(0)))
1902                                                 listManager.getNotebookIndex().get(j).setStack(edit.getNotebook());
1903                         }
1904                         conn.getNotebookTable().renameStacks(currentSelection.text(0), edit.getNotebook());
1905                         currentSelection.setText(0, edit.getNotebook());
1906                         return;
1907                 }
1908                 
1909                 updateListNotebookName(currentSelection.text(0), edit.getNotebook());
1910                 currentSelection.setText(0, edit.getNotebook());
1911                 
1912                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1913                         if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
1914                                 listManager.getNotebookIndex().get(i).setName(edit.getNotebook());
1915                                 if (!listManager.getNotebookIndex().get(i).isDefaultNotebook() && edit.isDefaultNotebook()) {
1916                                         for (int j=0; j<listManager.getNotebookIndex().size(); j++)
1917                                                 listManager.getNotebookIndex().get(j).setDefaultNotebook(false);
1918                                         listManager.getNotebookIndex().get(i).setDefaultNotebook(true);
1919                                         conn.getNotebookTable().setDefaultNotebook(listManager.getNotebookIndex().get(i).getGuid());
1920                                 }
1921                                 conn.getNotebookTable().updateNotebook(listManager.getNotebookIndex().get(i), true);
1922                                 if (conn.getNotebookTable().isLinked(listManager.getNotebookIndex().get(i).getGuid())) {
1923                                         LinkedNotebook linkedNotebook = conn.getLinkedNotebookTable().getByNotebookGuid(listManager.getNotebookIndex().get(i).getGuid());
1924                                         linkedNotebook.setShareName(edit.getNotebook());
1925                                         conn.getLinkedNotebookTable().updateNotebook(linkedNotebook, true);
1926                                 }
1927                                 i=listManager.getNotebookIndex().size();
1928                         }
1929                 }
1930                 
1931                 // Build a list of non-closed notebooks
1932                 List<Notebook> nbooks = new ArrayList<Notebook>();
1933                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1934                         boolean found=false;
1935                         for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
1936                                 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
1937                                         found = true;
1938                         }
1939                         if (!found)
1940                                 nbooks.add(listManager.getNotebookIndex().get(i));
1941                 }
1942                 
1943                 
1944                 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
1945                 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
1946                 browserWindow.setNotebookList(filteredBooks);
1947                 Iterator<String> set = externalWindows.keySet().iterator();
1948                 while(set.hasNext())
1949                         externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
1950                 
1951                 // ICHANGED
1952                 Iterator<Integer>it = tabWindows.keySet().iterator();
1953                 while (it.hasNext()) {
1954                         tabWindows.get(it.next()).getBrowserWindow()
1955                                         .setNotebookList(filteredBooks);
1956                 }
1957                 
1958                 logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
1959         }
1960         // Publish a notebook
1961         @SuppressWarnings("unused")
1962         private void publishNotebook() {
1963                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
1964                 QTreeWidgetItem currentSelection;
1965                 currentSelection = selections.get(0);
1966                 String guid = currentSelection.text(2);
1967
1968                 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
1969                         return;
1970                 
1971                 Notebook n = null;
1972                 int position = 0;
1973                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
1974                         if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
1975                                 n = listManager.getNotebookIndex().get(i);
1976                                 position = i;
1977                                 i = listManager.getNotebookIndex().size();
1978                         }
1979                 }
1980                 if (n == null)
1981                         return;
1982                 
1983                 PublishNotebook publish = new PublishNotebook(Global.username, Global.getServer(), n);
1984                 publish.exec();
1985                 
1986                 if (!publish.okClicked()) 
1987                         return;
1988                 
1989                 Publishing p = publish.getPublishing();
1990                 boolean isPublished = !publish.isStopPressed();
1991                 conn.getNotebookTable().setPublishing(n.getGuid(), isPublished, p);
1992                 n.setPublished(isPublished);
1993                 n.setPublishing(p);
1994                 listManager.getNotebookIndex().set(position, n);
1995                 notebookIndexUpdated();
1996         }
1997         // Publish a notebook
1998         @SuppressWarnings("unused")
1999         private void shareNotebook() {
2000                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2001                 QTreeWidgetItem currentSelection;
2002                 currentSelection = selections.get(0);
2003                 String guid = currentSelection.text(2);
2004
2005                 if (guid.equalsIgnoreCase("STACK") || guid.equalsIgnoreCase(""))
2006                         return;
2007                 
2008                 Notebook n = null;;
2009                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2010                         if (guid.equals(listManager.getNotebookIndex().get(i).getGuid())) {
2011                                 n = listManager.getNotebookIndex().get(i);
2012                                 i = listManager.getNotebookIndex().size();
2013                         }
2014                 }
2015                                 
2016                 String authToken = null;
2017                 if (syncRunner.isConnected)
2018                         authToken = syncRunner.authToken;
2019                 ShareNotebook share = new ShareNotebook(n.getName(), conn, n, syncRunner);
2020                 share.exec();
2021                 
2022         }
2023
2024         // Delete an existing notebook
2025         @SuppressWarnings("unused")
2026         private void deleteNotebook() {
2027                 logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2028                 boolean stacksFound = false;
2029                 boolean notebooksFound = false;
2030                 boolean assigned = false;
2031                 // Check if any notes have this notebook
2032                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2033         for (int i=0; i<selections.size(); i++) {
2034                 QTreeWidgetItem currentSelection;
2035                 currentSelection = selections.get(i);
2036                 String guid = currentSelection.text(2);
2037                 if (!guid.equalsIgnoreCase("STACK")) {
2038                         notebooksFound = true;
2039                         for (int j=0; j<listManager.getNoteIndex().size(); j++) {
2040                                 String noteGuid = listManager.getNoteIndex().get(j).getNotebookGuid();
2041                                 if (noteGuid.equals(guid)) {
2042                                         assigned = true;
2043                                         j=listManager.getNoteIndex().size();
2044                                         i=selections.size();
2045                                 }
2046                         }
2047                 } else {
2048                         stacksFound = true;
2049                 }
2050         }
2051                 if (assigned) {
2052                         QMessageBox.information(this, tr("Unable to Delete"), tr("Some of the selected notebook(s) contain notes.\n"+
2053                                         "Please delete the notes or move them to another notebook before deleting any notebooks."));
2054                         return;
2055                 }
2056                 
2057                 if (conn.getNotebookTable().getAll().size() == 1) {
2058                         QMessageBox.information(this, tr("Unable to Delete"), tr("You must have at least one notebook."));
2059                         return;
2060                 }
2061         
2062         // If all notebooks are clear, verify the delete
2063                 String msg1 = new String(tr("Delete selected notebooks?"));
2064                 String msg2 = new String(tr("Remove selected stacks (notebooks will not be deleted)?"));
2065                 String msg3 = new String(tr("Delete selected notebooks & remove stacks? Notebooks under the stacks are" +
2066                                 " not deleted unless selected?"));
2067                 String msg = "";
2068                 if (stacksFound && notebooksFound)
2069                         msg = msg3;
2070                 if (!stacksFound && notebooksFound)
2071                         msg = msg1;
2072                 if (stacksFound && !notebooksFound)
2073                         msg = msg2;
2074                 if (QMessageBox.question(this, tr("Confirmation"), msg,
2075                         QMessageBox.StandardButton.Yes, 
2076                         QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2077                         return;
2078                 }
2079                 
2080                 // If confirmed, delete the notebook
2081         for (int i=selections.size()-1; i>=0; i--) {
2082                 QTreeWidgetItem currentSelection;
2083                 currentSelection = selections.get(i);
2084                 String guid = currentSelection.text(2);
2085                 if (currentSelection.text(2).equalsIgnoreCase("STACK")) {
2086                         conn.getNotebookTable().renameStacks(currentSelection.text(0), "");
2087                         listManager.renameStack(currentSelection.text(0), "");
2088                 } else {
2089                         conn.getNotebookTable().expungeNotebook(guid, true);
2090                         listManager.deleteNotebook(guid);
2091                 }
2092         }
2093
2094                 notebookIndexUpdated();
2095 //        notebookTreeSelection();
2096 //        notebookTree.load(listManager.getNotebookIndex(), listManager.getLocalNotebooks());
2097 //        listManager.countNotebookResults(listManager.getNoteIndex());
2098         logger.log(logger.HIGH, "Entering NeverNote.deleteNotebook");
2099         }
2100         // A note's notebook has been updated
2101         @SuppressWarnings("unused")
2102         private void updateNoteNotebook(String guid, String notebookGuid) {
2103                 // ICHANGED 同じノートブックに入れられたノート間の履歴を登録
2104                 conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
2105                 
2106                 // Update the list manager
2107                 listManager.updateNoteNotebook(guid, notebookGuid);
2108                 listManager.countNotebookResults(listManager.getNoteIndex());
2109 //              notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());    
2110                 
2111                 // Find the name of the notebook
2112                 String notebookName = null;
2113                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2114                         if (listManager.getNotebookIndex().get(i).getGuid().equals(notebookGuid)) {
2115                                 notebookName = listManager.getNotebookIndex().get(i).getName();
2116                                 break;
2117                         }
2118                 }
2119                 
2120                 // If we found the name, update the browser window
2121                 if (notebookName != null) {
2122                         updateListNoteNotebook(guid, notebookName);
2123                         if (guid.equals(currentNoteGuid)) {
2124                                 int pos =  browserWindow.notebookBox.findText(notebookName);
2125                                 if (pos >=0)
2126                                         browserWindow.notebookBox.setCurrentIndex(pos);
2127                         }
2128                 }
2129                 
2130                 // If we're dealing with the current note, then we need to be sure and update the notebook there
2131                 if (guid.equals(currentNoteGuid)) {
2132                         if (currentNote != null) {
2133                                 currentNote.setNotebookGuid(notebookGuid);
2134                         }
2135                 }
2136         }
2137         // Open/close notebooks
2138         @SuppressWarnings("unused")
2139         private void closeNotebooks() {
2140                 NotebookArchive na = new NotebookArchive(listManager.getNotebookIndex(), listManager.getArchiveNotebookIndex());
2141                 na.exec();
2142                 if (!na.okClicked())
2143                         return;
2144                 
2145                 waitCursor(true);
2146                 listManager.getArchiveNotebookIndex().clear();
2147                 
2148                 for (int i=na.getClosedBookList().count()-1; i>=0; i--) {
2149                         String text = na.getClosedBookList().takeItem(i).text();
2150                         for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2151                                 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2152                                         Notebook n = listManager.getNotebookIndex().get(j);
2153                                         conn.getNotebookTable().setArchived(n.getGuid(),true);
2154                                         listManager.getArchiveNotebookIndex().add(n);
2155                                         j=listManager.getNotebookIndex().size();
2156                                 }
2157                         }
2158                 }
2159                 
2160                 for (int i=na.getOpenBookList().count()-1; i>=0; i--) {
2161                         String text = na.getOpenBookList().takeItem(i).text();
2162                         for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
2163                                 if (listManager.getNotebookIndex().get(j).getName().equalsIgnoreCase(text)) {
2164                                         Notebook n = listManager.getNotebookIndex().get(j);
2165                                         conn.getNotebookTable().setArchived(n.getGuid(),false);
2166                                         j=listManager.getNotebookIndex().size();
2167                                 }
2168                         }
2169                 }
2170                 notebookTreeSelection();
2171                 listManager.loadNotesIndex();
2172                 notebookIndexUpdated();
2173                 noteIndexUpdated(false);
2174                 reloadTagTree(true);
2175 //              noteIndexUpdated(false);
2176                 
2177                 // Build a list of non-closed notebooks
2178                 List<Notebook> nbooks = new ArrayList<Notebook>();
2179                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
2180                         boolean found=false;
2181                         for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
2182                                 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid()))
2183                                         found = true;
2184                         }
2185                         if (!found)
2186                                 nbooks.add(listManager.getNotebookIndex().get(i));
2187                 }
2188                 
2189                 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
2190                 List<Notebook> filteredBooks = notebookFilter.getValidNotebooks(currentNote, listManager.getNotebookIndex());
2191                 browserWindow.setNotebookList(filteredBooks);
2192                 
2193                 // Update any external windows
2194                 Iterator<String> set = externalWindows.keySet().iterator();
2195                 while(set.hasNext())
2196                         externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
2197                 
2198                 // ICHANGED
2199                 // 全てのタブウィンドウを更新
2200                 Iterator<Integer> it = tabWindows.keySet().iterator();
2201                 while (it.hasNext()) {
2202                         tabWindows.get(it.next()).getBrowserWindow()
2203                                         .setNotebookList(filteredBooks);
2204                 }
2205                 
2206                 waitCursor(false);
2207         }
2208         // Change the notebook's icon
2209         @SuppressWarnings("unused")
2210         private void setNotebookIcon() {
2211                 boolean stackSelected = false;
2212                 boolean allNotebookSelected = false;
2213                 
2214                 QTreeWidgetItem currentSelection;
2215                 List<QTreeWidgetItem> selections = notebookTree.selectedItems();
2216                 if (selections.size() == 0)
2217                         return;
2218                 
2219                 currentSelection = selections.get(0);   
2220                 String guid = currentSelection.text(2);
2221                 if (guid.equalsIgnoreCase(""))
2222                         allNotebookSelected = true;
2223                 if (guid.equalsIgnoreCase("STACK"))
2224                         stackSelected = true;
2225
2226                 QIcon currentIcon = currentSelection.icon(0);
2227                 QIcon icon;
2228                 SetIcon dialog;
2229                 
2230                 if (!stackSelected && !allNotebookSelected) {
2231                         icon = conn.getNotebookTable().getIcon(guid);
2232                         if (icon == null) {
2233                                 dialog = new SetIcon(currentIcon, saveLastPath);
2234                                 dialog.setUseDefaultIcon(true);
2235                         } else {
2236                                 dialog = new SetIcon(icon, saveLastPath);
2237                                 dialog.setUseDefaultIcon(false);
2238                         }
2239                 } else {
2240                         if (stackSelected) {
2241                                 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "STACK");
2242                         } else {
2243                                 icon = conn.getSystemIconTable().getIcon(currentSelection.text(0), "ALLNOTEBOOK");                              
2244                         }
2245                         if (icon == null) {
2246                                 dialog = new SetIcon(currentIcon, saveLastPath);
2247                                 dialog.setUseDefaultIcon(true);
2248                         } else {
2249                                 dialog = new SetIcon(icon, saveLastPath);
2250                                 dialog.setUseDefaultIcon(false);
2251                         }
2252                 }
2253                 dialog.exec();
2254                 if (dialog.okPressed()) {
2255                 saveLastPath = dialog.getPath();
2256
2257                         QIcon newIcon = dialog.getIcon();
2258                         if (stackSelected) {
2259                                 conn.getSystemIconTable().setIcon(currentSelection.text(0), "STACK", newIcon, dialog.getFileType());
2260                                 if (newIcon == null) {
2261                                         newIcon = new QIcon(iconPath+"books2.png");
2262                                 }
2263                                 currentSelection.setIcon(0,newIcon);
2264                                 return;
2265                         }
2266                         if (allNotebookSelected) {
2267                                 conn.getSystemIconTable().setIcon(currentSelection.text(0), "ALLNOTEBOOK", newIcon, dialog.getFileType());
2268                                 if (newIcon == null) {
2269                                         newIcon = new QIcon(iconPath+"notebook-green.png");
2270                                 }
2271                                 currentSelection.setIcon(0,newIcon);
2272                                 return;
2273                         }
2274                         conn.getNotebookTable().setIcon(guid, newIcon, dialog.getFileType());
2275                         if (newIcon == null) {
2276                                 boolean isPublished = false;;
2277                                 boolean found = false;
2278                                 for (int i=0; i<listManager.getNotebookIndex().size() && !found; i++) {
2279                                         if (listManager.getNotebookIndex().get(i).getGuid().equals(guid)) {
2280                                                 isPublished = listManager.getNotebookIndex().get(i).isPublished();
2281                                                 found = true;
2282                                         }
2283                                 }
2284                                 newIcon = notebookTree.findDefaultIcon(guid, currentSelection.text(1), listManager.getLocalNotebooks(), isPublished);
2285                         }
2286                         currentSelection.setIcon(0, newIcon);
2287                 }
2288         
2289         }
2290         
2291         
2292     //***************************************************************
2293     //***************************************************************
2294     //** These functions deal with Tag menu items
2295     //***************************************************************
2296     //***************************************************************
2297         // Add a new notebook
2298         @SuppressWarnings("unused")
2299         private void addTag() {
2300                 logger.log(logger.HIGH, "Inside NeverNote.addTag");
2301                 TagEdit edit = new TagEdit();
2302                 edit.setTagList(listManager.getTagIndex());
2303
2304                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2305                 QTreeWidgetItem currentSelection = null;
2306                 if (selections.size() > 0) {
2307                         currentSelection = selections.get(0);
2308                         edit.setParentTag(currentSelection.text(0));
2309                 }
2310
2311                 edit.exec();
2312         
2313                 if (!edit.okPressed())
2314                         return;
2315         
2316                 Calendar currentTime = new GregorianCalendar();
2317                 Long l = new Long(currentTime.getTimeInMillis());
2318                 String randint = new String(Long.toString(l));
2319         
2320                 Tag newTag = new Tag();
2321                 newTag.setUpdateSequenceNum(0);
2322                 newTag.setGuid(randint);
2323                 newTag.setName(edit.getTag());
2324                 if (edit.getParentTag().isChecked()) {
2325                         newTag.setParentGuid(currentSelection.text(2));
2326                         newTag.setParentGuidIsSet(true);
2327                         currentSelection.setExpanded(true);
2328                 }
2329                 conn.getTagTable().addTag(newTag, true);
2330                 listManager.getTagIndex().add(newTag);
2331                 reloadTagTree(true);
2332                 
2333                 logger.log(logger.HIGH, "Leaving NeverNote.addTag");
2334         }
2335         @SuppressWarnings("unused")
2336         private void reloadTagTree() {
2337                 reloadTagTree(false);
2338         }
2339         private void reloadTagTree(boolean reload) {
2340                 logger.log(logger.HIGH, "Entering NeverNote.reloadTagTree");
2341                 tagIndexUpdated(reload);
2342                 boolean filter = false;
2343                 if (reload)
2344                         listManager.countTagResults(listManager.getNoteIndex());
2345                 if (notebookTree.selectedItems().size() > 0 
2346                                                   && !notebookTree.selectedItems().get(0).text(0).equalsIgnoreCase("All Notebooks"))
2347                                                   filter = true;
2348                 if (tagTree.selectedItems().size() > 0)
2349                         filter = true;
2350                 tagTree.showAllTags(!filter);
2351                 tagIndexUpdated(false);
2352                 logger.log(logger.HIGH, "Leaving NeverNote.reloadTagTree");
2353         }
2354         // Edit an existing tag
2355         @SuppressWarnings("unused")
2356         private void editTag() {
2357                 logger.log(logger.HIGH, "Entering NeverNote.editTag");
2358                 TagEdit edit = new TagEdit();
2359                 edit.setTitle("Edit Tag");
2360                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2361                 QTreeWidgetItem currentSelection;
2362                 currentSelection = selections.get(0);
2363                 edit.setTag(currentSelection.text(0));
2364                 edit.setTagList(listManager.getTagIndex());
2365                 edit.exec();
2366         
2367                 if (!edit.okPressed())
2368                         return;
2369         
2370                 String guid = currentSelection.text(2);
2371                 currentSelection.setText(0,edit.getTag());
2372                 
2373                 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2374                         if (listManager.getTagIndex().get(i).getGuid().equals(guid)) {
2375                                 listManager.getTagIndex().get(i).setName(edit.getTag());
2376                                 conn.getTagTable().updateTag(listManager.getTagIndex().get(i), true);
2377                                 updateListTagName(guid);
2378                                 if (currentNote != null && currentNote.getTagGuids().contains(guid))
2379                                         browserWindow.setTag(getTagNamesForNote(currentNote));
2380                                 logger.log(logger.HIGH, "Leaving NeverNote.editTag");
2381                                 //return;
2382                         }
2383                 }
2384                 listManager.reloadNoteTagNames(guid, edit.getTag());
2385                 noteIndexUpdated(true);
2386                 refreshEvernoteNote(true);
2387                 browserWindow.setTag(getTagNamesForNote(currentNote));
2388                 logger.log(logger.HIGH, "Leaving NeverNote.editTag...");
2389         }
2390         // Delete an existing tag
2391         @SuppressWarnings("unused")
2392         private void deleteTag() {
2393                 logger.log(logger.HIGH, "Entering NeverNote.deleteTag");
2394                 
2395                 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected tags?"),
2396                         QMessageBox.StandardButton.Yes, 
2397                         QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2398                                                         return;
2399                 }
2400                 
2401                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2402         for (int i=selections.size()-1; i>=0; i--) {
2403                 QTreeWidgetItem currentSelection;
2404                 currentSelection = selections.get(i);                   
2405                 removeTagItem(currentSelection.text(2));
2406         }
2407         tagIndexUpdated(true);
2408         tagTreeSelection();
2409         listManager.countTagResults(listManager.getNoteIndex());
2410 //              tagTree.updateCounts(listManager.getTagCounter());
2411         logger.log(logger.HIGH, "Leaving NeverNote.deleteTag");
2412         }
2413         // Remove a tag tree item.  Go recursively down & remove the children too
2414         private void removeTagItem(String guid) {
2415         for (int j=listManager.getTagIndex().size()-1; j>=0; j--) {             
2416                 String parent = listManager.getTagIndex().get(j).getParentGuid();
2417                 if (parent != null && parent.equals(guid)) {            
2418                         //Remove this tag's children
2419                         removeTagItem(listManager.getTagIndex().get(j).getGuid());
2420                 }
2421         }
2422         //Now, remove this tag
2423         removeListTagName(guid);
2424         conn.getTagTable().expungeTag(guid, true);                      
2425         for (int a=0; a<listManager.getTagIndex().size(); a++) {
2426                 if (listManager.getTagIndex().get(a).getGuid().equals(guid)) {
2427                         listManager.getTagIndex().remove(a);
2428                         return;
2429                 }
2430         }
2431         }
2432         // Setup the tree containing the user's tags
2433     private void initializeTagTree() {
2434         logger.log(logger.HIGH, "Entering NeverNote.initializeTagTree");
2435 //      tagTree.itemSelectionChanged.connect(this, "tagTreeSelection()");
2436 //      tagTree.itemClicked.connect(this, "tagTreeSelection()");
2437         tagTree.selectionSignal.connect(this, "tagTreeSelection()");
2438         listManager.tagSignal.refreshTagTreeCounts.connect(tagTree, "updateCounts(List)");
2439         logger.log(logger.HIGH, "Leaving NeverNote.initializeTagTree");
2440     }
2441     // Listener when a tag is selected
2442         private void tagTreeSelection() {
2443         logger.log(logger.HIGH, "Entering NeverNote.tagTreeSelection");
2444                 
2445         clearTrashFilter();
2446         clearAttributeFilter();
2447         clearSavedSearchFilter();
2448         
2449                 menuBar.noteRestoreAction.setVisible(false);
2450                 
2451                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2452                 if (!rensoNoteListDock.isEnabled()) {
2453                         rensoNoteListDock.setEnabled(true);
2454                 }
2455                 
2456         List<QTreeWidgetItem> selections = tagTree.selectedItems();
2457         QTreeWidgetItem currentSelection;
2458         selectedTagGUIDs.clear();
2459         for (int i=0; i<selections.size(); i++) {
2460                 currentSelection = selections.get(i);
2461                 selectedTagGUIDs.add(currentSelection.text(2));
2462         }
2463         if (selections.size() > 0) {
2464                 menuBar.tagEditAction.setEnabled(true);
2465                 menuBar.tagDeleteAction.setEnabled(true);
2466                 menuBar.tagIconAction.setEnabled(true);
2467         }
2468         else {
2469                 menuBar.tagEditAction.setEnabled(false);
2470                 menuBar.tagDeleteAction.setEnabled(false);
2471                 menuBar.tagIconAction.setEnabled(true);
2472         }
2473         if (selections.size() > 1)
2474                 menuBar.tagMergeAction.setEnabled(true);
2475         else
2476                 menuBar.tagMergeAction.setEnabled(false);
2477         listManager.setSelectedTags(selectedTagGUIDs);
2478         listManager.loadNotesIndex();
2479         noteIndexUpdated(false);
2480         refreshEvernoteNote(true);
2481         listManager.refreshCounters = true;
2482         listManager.refreshCounters();
2483         logger.log(logger.HIGH, "Leaving NeverNote.tagTreeSelection");
2484     }
2485     // trigger the tag index to be refreshed
2486     @SuppressWarnings("unused")
2487         private void tagIndexUpdated() {
2488         tagIndexUpdated(true);
2489     }
2490     private void tagIndexUpdated(boolean reload) {
2491         logger.log(logger.HIGH, "Entering NeverNote.tagIndexUpdated");
2492                 if (selectedTagGUIDs == null)
2493                         selectedTagGUIDs = new ArrayList<String>();
2494                 if (reload)
2495                         listManager.reloadTagIndex();
2496
2497                 tagTree.blockSignals(true);
2498                 if (reload) {
2499                         tagTree.setIcons(conn.getTagTable().getAllIcons());
2500                         tagTree.load(listManager.getTagIndex());
2501                 }
2502
2503         for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
2504                 boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
2505                 if (!found)
2506                         selectedTagGUIDs.remove(i);
2507         }
2508         tagTree.blockSignals(false);
2509         
2510                 browserWindow.setTag(getTagNamesForNote(currentNote));
2511         logger.log(logger.HIGH, "Leaving NeverNote.tagIndexUpdated");
2512     }   
2513     // Show/Hide note information
2514         @SuppressWarnings("unused")
2515         private void toggleTagWindow() {
2516                 logger.log(logger.HIGH, "Entering NeverNote.toggleTagWindow");
2517         if (tagTree.isVisible())
2518                 tagTree.hide();
2519         else
2520                 tagTree.show();
2521         menuBar.hideTags.setChecked(tagTree.isVisible());
2522         Global.saveWindowVisible("tagTree", tagTree.isVisible());
2523         logger.log(logger.HIGH, "Leaving NeverNote.toggleTagWindow");
2524     }   
2525         // A note's tags have been updated
2526         @SuppressWarnings("unused")
2527         private void updateNoteTags(String guid, List<String> tags) {
2528                 // Save any new tags.  We'll need them later.
2529                 List<String> newTags = new ArrayList<String>();
2530                 for (int i=0; i<tags.size(); i++) {
2531                         if (conn.getTagTable().findTagByName(tags.get(i))==null) 
2532                                 newTags.add(tags.get(i));
2533                 }
2534                 
2535                 listManager.saveNoteTags(guid, tags, true);
2536                 listManager.countTagResults(listManager.getNoteIndex());
2537                 StringBuffer names = new StringBuffer("");
2538                 for (int i=0; i<tags.size(); i++) {
2539                         names = names.append(tags.get(i));
2540                         if (i<tags.size()-1) {
2541                                 names.append(Global.tagDelimeter + " ");
2542                         }
2543                 }
2544                 browserWindow.setTag(names.toString());
2545                 
2546                 // ICHANGED
2547                 for (TabBrowse tab: tabWindows.values()) {
2548                         if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
2549                                 int index = tabBrowser.indexOf(tab);
2550                                 noteDirty.put(index, true);
2551                                 break;
2552                         }
2553                 }
2554                 
2555                 // Now, we need to add any new tags to the tag tree
2556                 for (int i=0; i<newTags.size(); i++) 
2557                         tagTree.insertTag(newTags.get(i), conn.getTagTable().findTagByName(newTags.get(i)));
2558         }
2559         // Get a string containing all tag names for a note
2560         private String getTagNamesForNote(Note n) {
2561                 logger.log(logger.HIGH, "Entering NeverNote.getTagNamesForNote");
2562                 if (n==null || n.getGuid() == null || n.getGuid().equals(""))
2563                         return "";
2564                 StringBuffer buffer = new StringBuffer(100);
2565                 Vector<String> v = new Vector<String>();
2566                 List<String> guids = n.getTagGuids();
2567                 
2568                 if (guids == null) 
2569                         return "";
2570                 
2571                 for (int i=0; i<guids.size(); i++) {
2572                         v.add(listManager.getTagNameByGuid(guids.get(i)));
2573                 }
2574                 Comparator<String> comparator = Collections.reverseOrder();
2575                 Collections.sort(v,comparator);
2576                 Collections.reverse(v);
2577                 
2578                 for (int i = 0; i<v.size(); i++) {
2579                         if (i>0) 
2580                                 buffer.append(", ");
2581                         buffer.append(v.get(i));
2582                 }
2583                 
2584                 logger.log(logger.HIGH, "Leaving NeverNote.getTagNamesForNote");
2585                 return buffer.toString();
2586         }       
2587         // Tags were added via dropping notes from the note list
2588         @SuppressWarnings("unused")
2589         private void tagsAdded(String noteGuid, String tagGuid) {
2590                 String tagName = null;
2591                 for (int i=0; i<listManager.getTagIndex().size(); i++) {
2592                         if (listManager.getTagIndex().get(i).getGuid().equals(tagGuid)) {
2593                                 tagName = listManager.getTagIndex().get(i).getName();
2594                                 i=listManager.getTagIndex().size();
2595                         }
2596                 }
2597                 if (tagName == null)
2598                         return;
2599                 
2600                 for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
2601                         if (listManager.getMasterNoteIndex().get(i).getGuid().equals(noteGuid)) {
2602                                 List<String> tagNames = new ArrayList<String>();
2603                                 tagNames.add(new String(tagName));
2604                                 Note n = listManager.getMasterNoteIndex().get(i);
2605                                 for (int j=0; j<n.getTagNames().size(); j++) {
2606                                         tagNames.add(new String(n.getTagNames().get(j)));
2607                                 }
2608                                 listManager.getNoteTableModel().updateNoteTags(noteGuid, n.getTagGuids(), tagNames);
2609                                 if (n.getGuid().equals(currentNoteGuid)) {
2610                                         Collections.sort(tagNames);
2611                                         String display = "";
2612                                         for (int j=0; j<tagNames.size(); j++) {
2613                                                 display = display+tagNames.get(j);
2614                                                 if (j+2<tagNames.size()) 
2615                                                         display = display+Global.tagDelimeter+" ";
2616                                         }
2617                                         browserWindow.setTag(display);
2618                                 }
2619                                 i=listManager.getMasterNoteIndex().size();
2620                         }
2621                 }
2622                 
2623                 
2624                 listManager.getNoteTableModel().updateNoteSyncStatus(noteGuid, false);
2625         }
2626         private void clearTagFilter() {
2627                 tagTree.blockSignals(true);
2628                 tagTree.clearSelection();
2629                 menuBar.noteRestoreAction.setVisible(false);
2630                 menuBar.tagEditAction.setEnabled(false);
2631                 menuBar.tagMergeAction.setEnabled(false);
2632                 menuBar.tagDeleteAction.setEnabled(false);
2633                 menuBar.tagIconAction.setEnabled(false);
2634                 selectedTagGUIDs.clear();
2635         listManager.setSelectedTags(selectedTagGUIDs);
2636         tagTree.blockSignals(false);
2637         }
2638         // Change the icon for a tag
2639         @SuppressWarnings("unused")
2640         private void setTagIcon() {
2641                 QTreeWidgetItem currentSelection;
2642                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2643                 if (selections.size() == 0)
2644                         return;
2645                 
2646                 currentSelection = selections.get(0);   
2647                 String guid = currentSelection.text(2);
2648
2649                 QIcon currentIcon = currentSelection.icon(0);
2650                 QIcon icon = conn.getTagTable().getIcon(guid);
2651                 SetIcon dialog;
2652                 if (icon == null) {
2653                         dialog = new SetIcon(currentIcon, saveLastPath);
2654                         dialog.setUseDefaultIcon(true);
2655                 } else {
2656                         dialog = new SetIcon(icon, saveLastPath);
2657                         dialog.setUseDefaultIcon(false);
2658                 }
2659                 dialog.exec();
2660                 if (dialog.okPressed()) {
2661                 saveLastPath = dialog.getPath();
2662                         QIcon newIcon = dialog.getIcon();
2663                         conn.getTagTable().setIcon(guid, newIcon, dialog.getFileType());
2664                         if (newIcon == null) 
2665                                 newIcon = new QIcon(iconPath+"tag.png");
2666                         currentSelection.setIcon(0, newIcon);
2667                 }
2668         
2669         }
2670         // Merge tags
2671         @SuppressWarnings("unused")
2672         private void mergeTags() {
2673                 List<Tag> tags = new ArrayList<Tag>();
2674                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
2675                 for (int i=0; i<selections.size(); i++) {
2676                         Tag record = new Tag();
2677                         record.setGuid(selections.get(i).text(2));
2678                         record.setName(selections.get(i).text(0));
2679                         tags.add(record);
2680                 }
2681
2682                 TagMerge mergeDialog = new TagMerge(tags);
2683                 mergeDialog.exec();
2684                 if (!mergeDialog.okClicked())
2685                         return;
2686                 String newGuid = mergeDialog.getNewTagGuid();
2687                 
2688                 for (int i=0; i<tags.size(); i++) {
2689                         if (!tags.get(i).getGuid().equals(newGuid)) {
2690                                 List<String> noteGuids = conn.getNoteTable().noteTagsTable.getTagNotes(tags.get(i).getGuid());
2691                                 for (int j=0; j<noteGuids.size(); j++) {
2692                                         String noteGuid = noteGuids.get(j);
2693                                         conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
2694                                         if (!conn.getNoteTable().noteTagsTable.checkNoteNoteTags(noteGuid, newGuid))
2695                                                 conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, newGuid, true);
2696                                 }
2697                         }
2698                 }
2699                 listManager.reloadIndexes();
2700         }
2701         
2702     //***************************************************************
2703     //***************************************************************
2704     //** These functions deal with Saved Search menu items
2705     //***************************************************************
2706     //***************************************************************
2707         // Add a new notebook
2708         @SuppressWarnings("unused")
2709         private void addSavedSearch() {
2710                 logger.log(logger.HIGH, "Inside NeverNote.addSavedSearch");
2711                 SavedSearchEdit edit = new SavedSearchEdit();
2712                 edit.setSearchList(listManager.getSavedSearchIndex());
2713                 edit.exec();
2714         
2715                 if (!edit.okPressed())
2716                         return;
2717         
2718                 Calendar currentTime = new GregorianCalendar();         
2719                 Long l = new Long(currentTime.getTimeInMillis());
2720                 String randint = new String(Long.toString(l));
2721         
2722                 SavedSearch search = new SavedSearch();
2723                 search.setUpdateSequenceNum(0);
2724                 search.setGuid(randint);
2725                 search.setName(edit.getName());
2726                 search.setQuery(edit.getQuery());
2727                 search.setFormat(QueryFormat.USER);
2728                 listManager.getSavedSearchIndex().add(search);
2729                 conn.getSavedSearchTable().addSavedSearch(search, true);
2730                 savedSearchIndexUpdated();
2731                 logger.log(logger.HIGH, "Leaving NeverNote.addSavedSearch");
2732         }
2733         // Edit an existing tag
2734         @SuppressWarnings("unused")
2735         private void editSavedSearch() {
2736                 logger.log(logger.HIGH, "Entering NeverNote.editSavedSearch");
2737                 SavedSearchEdit edit = new SavedSearchEdit();
2738                 edit.setTitle(tr("Edit Search"));
2739                 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2740                 QTreeWidgetItem currentSelection;
2741                 currentSelection = selections.get(0);
2742                 String guid = currentSelection.text(1);
2743                 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(guid);
2744                 edit.setName(currentSelection.text(0));
2745                 edit.setQuery(s.getQuery());
2746                 edit.setSearchList(listManager.getSavedSearchIndex());
2747                 edit.exec();
2748         
2749                 if (!edit.okPressed())
2750                         return;
2751         
2752                 List<SavedSearch> list = listManager.getSavedSearchIndex();
2753                 SavedSearch search = null;
2754                 boolean found = false;
2755                 for (int i=0; i<list.size(); i++) {
2756                         search = list.get(i);
2757                         if (search.getGuid().equals(guid)) {
2758                                 i=list.size();
2759                                 found = true;
2760                         }
2761                 }
2762                 if (!found)
2763                         return;
2764                 search.setName(edit.getName());
2765                 search.setQuery(edit.getQuery());
2766                 conn.getSavedSearchTable().updateSavedSearch(search, true);
2767                 savedSearchIndexUpdated();
2768                 logger.log(logger.HIGH, "Leaving NeverNote.editSavedSearch");
2769         }
2770         // Delete an existing tag
2771         @SuppressWarnings("unused")
2772         private void deleteSavedSearch() {
2773                 logger.log(logger.HIGH, "Entering NeverNote.deleteSavedSearch");
2774                 
2775                 if (QMessageBox.question(this, tr("Confirmation"), tr("Delete the selected search?"),
2776                         QMessageBox.StandardButton.Yes, 
2777                         QMessageBox.StandardButton.No)==StandardButton.No.value()) {
2778                                                         return;
2779                 }
2780                 
2781                 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2782         for (int i=selections.size()-1; i>=0; i--) {
2783                 QTreeWidgetItem currentSelection;
2784                 currentSelection = selections.get(i);
2785                 for (int j=0; j<listManager.getSavedSearchIndex().size(); j++) {
2786                         if (listManager.getSavedSearchIndex().get(j).getGuid().equals(currentSelection.text(1))) {
2787                                 conn.getSavedSearchTable().expungeSavedSearch(listManager.getSavedSearchIndex().get(j).getGuid(), true);
2788                                 listManager.getSavedSearchIndex().remove(j);
2789                                 j=listManager.getSavedSearchIndex().size()+1;
2790                         }
2791                 }
2792                 selections.remove(i);
2793         }
2794         savedSearchIndexUpdated();
2795         logger.log(logger.HIGH, "Leaving NeverNote.deleteSavedSearch");
2796         }
2797     // Setup the tree containing the user's tags
2798     private void initializeSavedSearchTree() {
2799         logger.log(logger.HIGH, "Entering NeverNote.initializeSavedSearchTree");
2800         savedSearchTree.itemSelectionChanged.connect(this, "savedSearchTreeSelection()");
2801         logger.log(logger.HIGH, "Leaving NeverNote.initializeSavedSearchTree");
2802     }
2803     // Listener when a tag is selected
2804     @SuppressWarnings("unused")
2805         private void savedSearchTreeSelection() {
2806         logger.log(logger.HIGH, "Entering NeverNote.savedSearchTreeSelection");
2807
2808         clearNotebookFilter();
2809         clearTagFilter();
2810         clearTrashFilter();
2811         clearAttributeFilter();
2812         
2813         String currentGuid = selectedSavedSearchGUID;
2814         menuBar.savedSearchEditAction.setEnabled(true);
2815         menuBar.savedSearchDeleteAction.setEnabled(true);
2816         menuBar.savedSearchIconAction.setEnabled(true);
2817         
2818                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
2819                 if (!rensoNoteListDock.isEnabled()) {
2820                         rensoNoteListDock.setEnabled(true);
2821                 }
2822                 
2823         List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2824         QTreeWidgetItem currentSelection;
2825         selectedSavedSearchGUID = "";
2826         for (int i=0; i<selections.size(); i++) {
2827                 currentSelection = selections.get(i);
2828                 if (currentSelection.text(1).equals(currentGuid)) {
2829                         currentSelection.setSelected(false);
2830                 } else {
2831                         selectedSavedSearchGUID = currentSelection.text(1);
2832                 }
2833 //              i = selections.size() +1;
2834         }
2835         
2836         // There is the potential for no notebooks to be selected if this 
2837         // happens then we make it look like all notebooks were selecetd.
2838         // If that happens, just select the "all notebooks"
2839         if (selections.size()==0) {
2840                 clearSavedSearchFilter();
2841         }
2842         listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2843         
2844         logger.log(logger.HIGH, "Leaving NeverNote.savedSearchTreeSelection");
2845     }
2846     private void clearSavedSearchFilter() {
2847         menuBar.savedSearchEditAction.setEnabled(false);
2848         menuBar.savedSearchDeleteAction.setEnabled(false);
2849         menuBar.savedSearchIconAction.setEnabled(false);
2850         savedSearchTree.blockSignals(true);
2851         savedSearchTree.clearSelection();
2852         savedSearchTree.blockSignals(false);
2853         selectedSavedSearchGUID = "";
2854         searchField.setEditText("");
2855         searchPerformed = false;
2856         listManager.setSelectedSavedSearch(selectedSavedSearchGUID);
2857     }
2858     // trigger the tag index to be refreshed
2859         private void savedSearchIndexUpdated() { 
2860                 if (selectedSavedSearchGUID == null)
2861                         selectedSavedSearchGUID = new String();
2862                 savedSearchTree.blockSignals(true);
2863                 savedSearchTree.setIcons(conn.getSavedSearchTable().getAllIcons());
2864         savedSearchTree.load(listManager.getSavedSearchIndex());
2865         savedSearchTree.selectGuid(selectedSavedSearchGUID);
2866         savedSearchTree.blockSignals(false);
2867     }
2868     // trigger when the saved search selection changes
2869     @SuppressWarnings("unused")
2870         private void updateSavedSearchSelection() {
2871                 logger.log(logger.HIGH, "Entering NeverNote.updateSavedSearchSelection()");
2872                 
2873         menuBar.savedSearchEditAction.setEnabled(true);
2874         menuBar.savedSearchDeleteAction.setEnabled(true);
2875         menuBar.savedSearchIconAction.setEnabled(true);
2876         List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2877
2878         if (selections.size() > 0) {
2879                 menuBar.savedSearchEditAction.setEnabled(true);
2880                 menuBar.savedSearchDeleteAction.setEnabled(true);
2881                 menuBar.savedSearchIconAction.setEnabled(true);
2882                 selectedSavedSearchGUID = selections.get(0).text(1);
2883                 SavedSearch s = conn.getSavedSearchTable().getSavedSearch(selectedSavedSearchGUID);
2884                 searchField.setEditText(s.getQuery());
2885         } else { 
2886                 menuBar.savedSearchEditAction.setEnabled(false);
2887                 menuBar.savedSearchDeleteAction.setEnabled(false);
2888                 menuBar.savedSearchIconAction.setEnabled(false);
2889                 selectedSavedSearchGUID = "";
2890                 searchField.setEditText("");
2891         }
2892         searchFieldChanged();
2893         
2894                 logger.log(logger.HIGH, "Leaving NeverNote.updateSavedSearchSelection()");
2895
2896         
2897     }
2898     // Show/Hide note information
2899         @SuppressWarnings("unused")
2900         private void toggleSavedSearchWindow() {
2901                 logger.log(logger.HIGH, "Entering NeverNote.toggleSavedSearchWindow");
2902         if (savedSearchTree.isVisible())
2903                 savedSearchTree.hide();
2904         else
2905                 savedSearchTree.show();
2906         menuBar.hideSavedSearches.setChecked(savedSearchTree.isVisible());
2907                                 
2908                 Global.saveWindowVisible("savedSearchTree", savedSearchTree.isVisible());
2909         logger.log(logger.HIGH, "Leaving NeverNote.toggleSavedSearchWindow");
2910     }
2911         // Change the icon for a saved search
2912         @SuppressWarnings("unused")
2913         private void setSavedSearchIcon() {
2914                 QTreeWidgetItem currentSelection;
2915                 List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
2916                 if (selections.size() == 0)
2917                         return;
2918                 
2919                 currentSelection = selections.get(0);   
2920                 String guid = currentSelection.text(1);
2921
2922                 QIcon currentIcon = currentSelection.icon(0);
2923                 QIcon icon = conn.getSavedSearchTable().getIcon(guid);
2924                 SetIcon dialog;
2925                 if (icon == null) {
2926                         dialog = new SetIcon(currentIcon, saveLastPath);
2927                         dialog.setUseDefaultIcon(true);
2928                 } else {
2929                         dialog = new SetIcon(icon, saveLastPath);
2930                         dialog.setUseDefaultIcon(false);
2931                 }
2932                 dialog.exec();
2933                 if (dialog.okPressed()) {
2934                 saveLastPath = dialog.getPath();
2935                         QIcon newIcon = dialog.getIcon();
2936                         conn.getSavedSearchTable().setIcon(guid, newIcon, dialog.getFileType());
2937                         if (newIcon == null) 
2938                                 newIcon = new QIcon(iconPath+"search.png");
2939                         currentSelection.setIcon(0, newIcon);
2940                 }
2941         
2942         }
2943         
2944         
2945         
2946         
2947     //***************************************************************
2948     //***************************************************************
2949     //** These functions deal with Help menu & tool menu items
2950     //***************************************************************
2951     //***************************************************************
2952         // Show database status
2953         @SuppressWarnings("unused")
2954         private void databaseStatus() {
2955                 waitCursor(true);
2956                 indexRunner.interrupt = true;
2957                 int dirty = conn.getNoteTable().getDirtyCount();
2958                 int unindexed = conn.getNoteTable().getUnindexedCount();
2959                 DatabaseStatus status = new DatabaseStatus();
2960                 status.setUnsynchronized(dirty);
2961                 status.setUnindexed(unindexed);
2962                 status.setNoteCount(conn.getNoteTable().getNoteCount());
2963                 status.setNotebookCount(listManager.getNotebookIndex().size());
2964                 status.setUnindexedResourceCount(conn.getNoteTable().noteResourceTable.getUnindexedCount());
2965                 status.setSavedSearchCount(listManager.getSavedSearchIndex().size());
2966                 status.setTagCount(listManager.getTagIndex().size());
2967                 status.setResourceCount(conn.getNoteTable().noteResourceTable.getResourceCount());
2968                 status.setWordCount(conn.getWordsTable().getWordCount());
2969                 status.setHistoryCount(conn.getHistoryTable().getHistoryCount());
2970                 status.setRensoClickCount(conn.getHistoryTable().getRensoClickCount());
2971                 waitCursor(false);
2972                 status.exec();
2973         }
2974         // Compact the database
2975         @SuppressWarnings("unused")
2976         private void compactDatabase() {
2977         logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
2978                 if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
2979                                 "but please be aware that depending upon the size of your database this can be time consuming " +
2980                                 "and NeighborNote will be unresponsive until it is complete.  Do you wish to continue?"),
2981                                 QMessageBox.StandardButton.Yes, 
2982                                 QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
2983                                                         return;
2984                 }
2985                 setMessage("Compacting database.");
2986                 waitCursor(true);
2987                 listManager.compactDatabase();
2988                 waitCursor(false);
2989                 setMessage("Database compact is complete.");            
2990         logger.log(logger.HIGH, "Leaving NeverNote.compactDatabase");
2991     }
2992         @SuppressWarnings("unused")
2993         private void accountInformation() {
2994                 logger.log(logger.HIGH, "Entering NeverNote.accountInformation");
2995                 AccountDialog dialog = new AccountDialog();
2996                 dialog.show();
2997                 logger.log(logger.HIGH, "Leaving NeverNote.accountInformation");
2998         }
2999         @SuppressWarnings("unused")
3000         private void releaseNotes() {
3001                 logger.log(logger.HIGH, "Entering NeverNote.releaseNotes");
3002                 QDialog dialog = new QDialog(this);
3003                 QHBoxLayout layout = new QHBoxLayout();
3004                 QTextEdit textBox = new QTextEdit();
3005                 layout.addWidget(textBox);
3006                 textBox.setReadOnly(true);
3007                 QFile file = new QFile(Global.getFileManager().getProgramDirPath("release.txt"));
3008                 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly,
3009                 QIODevice.OpenModeFlag.Text)))
3010                         return;
3011                 // ICHANGED 日本語文字化け対策
3012                 QTextCodec codec = QTextCodec.codecForName("UTF-8");
3013                 QTextStream textStream = new QTextStream(file);
3014                 textStream.setCodec(codec);
3015                 textBox.setText(textStream.readAll().toString());
3016                 
3017                 file.close();
3018                 dialog.setWindowTitle(tr("Release Notes"));
3019                 dialog.setLayout(layout);
3020                 dialog.show();
3021                 logger.log(logger.HIGH, "Leaving NeverNote.releaseNotes");
3022         }
3023         // Called when user picks Log from the help menu
3024         @SuppressWarnings("unused")
3025         private void logger() {
3026                 logger.log(logger.HIGH, "Entering NeverNote.logger");
3027                 LogFileDialog dialog = new LogFileDialog(emitLog);
3028                 dialog.exec();
3029                 logger.log(logger.HIGH, "Leaving NeverNote.logger");
3030         }
3031         // Menu option "help/about" was selected
3032         @SuppressWarnings("unused")
3033         private void about() {
3034                 logger.log(logger.HIGH, "Entering NeverNote.about");
3035                 // ICHANGED based on...の記述を付加
3036                 QMessageBox.about(this, 
3037                                                 tr("About NeighborNote"),
3038                                                 tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
3039                                                 +Global.version + "(based on NixNote 1.5)"
3040                                                 //+"1.2.120724"
3041                                                 +tr("<hr>"
3042                                                                 +"Open Source Evernote Client.<br><br>" 
3043                                                                 +"Licensed under GPL v2.  <br><hr><br>"
3044                                                                 +"</center>Evernote is copyright 2001-2012 by Evernote Corporation<br>"
3045                                                                 +"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
3046                                                                 +"PDFRenderer is licened under the LGPL<br>"
3047                                                                 +"JTidy is copyrighted under the World Wide Web Consortium<br>"
3048                                                                 +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
3049                                                                 +"Jazzy is licened under the LGPL<br>"
3050                                                                 +"Java is a registered trademark of Oracle Corporation.<br><hr>"
3051                                                                 +"Special thanks to:<br>BitRock InstallBuilder for the Windows installer"
3052                                                                 +"<br>CodeCogs (www.codecogs.com) for the LaTeX image rendering."));
3053                 logger.log(logger.HIGH, "Leaving NeverNote.about");
3054         }
3055         // Hide the entire left hand side
3056         @SuppressWarnings("unused")
3057         private void toggleLeftSide() {
3058                 boolean hidden;
3059                 
3060                 hidden = !menuBar.hideLeftSide.isChecked();
3061                 menuBar.hideLeftSide.setChecked(!hidden);
3062                 
3063                 if (!hidden) 
3064                         leftSplitter1.setHidden(true);
3065                 else
3066                         leftSplitter1.setHidden(false);
3067                 
3068                 Global.saveWindowVisible("leftPanel", hidden);
3069                 
3070         }
3071         public void checkForUpdates() {
3072                 // Send off thread to check for a new version
3073                 versionChecker = new QNetworkAccessManager(this);
3074                 versionChecker.finished.connect(this, "upgradeFileRead(QNetworkReply)");
3075                 QNetworkRequest request = new QNetworkRequest();
3076                 request.setUrl(new QUrl(Global.getUpdatesAvailableUrl()));
3077                 versionChecker.get(request);
3078         }
3079         @SuppressWarnings("unused")
3080         private void upgradeFileRead(QNetworkReply reply) {
3081                 if (!reply.isReadable())
3082                         return;
3083                 
3084                 String winVersion = Global.version;
3085                 String osxVersion = Global.version;
3086                 String linuxVersion = Global.version;
3087                 String linux64Version = Global.version;
3088                 String version = Global.version;
3089                 
3090                 // Determine the versions available
3091                 QByteArray data = reply.readLine();
3092                 while (data != null && !reply.atEnd()) {
3093                         String line = data.toString();
3094                         String lineVersion;
3095                         if (line.contains(":")) 
3096                                 lineVersion = line.substring(line.indexOf(":")+1).replace(" ", "").replace("\n", "");
3097                         else
3098                                 lineVersion = "";
3099                         if (line.toLowerCase().contains("windows")) 
3100                                 winVersion = lineVersion;
3101                         else if (line.toLowerCase().contains("os-x")) 
3102                                 osxVersion = lineVersion;
3103                         else if (line.toLowerCase().contains("linux amd64")) 
3104                                 linux64Version = lineVersion;
3105                         else if (line.toLowerCase().contains("linux i386")) 
3106                                 linuxVersion = lineVersion;
3107                         else if (line.toLowerCase().contains("default")) 
3108                                 version = lineVersion;
3109                         
3110                         // Read the next line
3111                         data = reply.readLine();
3112                 }
3113                 
3114                 // Now we need to determine what system we are on.
3115                 if (System.getProperty("os.name").toLowerCase().contains("windows"))
3116                         version = winVersion;
3117                 if (System.getProperty("os.name").toLowerCase().contains("mac os"))
3118                         version = osxVersion;
3119                 if (System.getProperty("os.name").toLowerCase().contains("Linux")) {
3120                         if (System.getProperty("os.arch").contains("amd64") ||
3121                                 System.getProperty("os.arch").contains("x86_64"))
3122                                         version = linux64Version;
3123                         else
3124                                 version = linuxVersion;
3125                 }
3126                 
3127                 
3128                 for (String validVersion : Global.validVersions) {
3129                         if (version.equals(validVersion))
3130                                 return;
3131                 }
3132                 
3133                 UpgradeAvailableDialog dialog = new UpgradeAvailableDialog();
3134                 dialog.exec();
3135                 if (dialog.remindMe())
3136                         Global.setCheckVersionUpgrade(true);
3137                 else
3138                         Global.setCheckVersionUpgrade(false);
3139         }
3140                 
3141         
3142     //***************************************************************
3143     //***************************************************************
3144     //** These functions deal with the Toolbar
3145     //***************************************************************
3146     //*************************************************************** 
3147         @SuppressWarnings("unused")
3148         private void focusSearch() {
3149                 searchField.setFocus();
3150         }
3151
3152         // Text in the search bar has been cleared
3153         private void searchFieldCleared() {
3154                 saveNote();
3155                 
3156                 // This is done because we want to force a reload of
3157                 // images.  Some images we may want to highlight the text.
3158                 readOnlyCache.clear();
3159                 inkNoteCache.clear();
3160                 noteCache.clear();
3161                 QWebSettings.setMaximumPagesInCache(0);
3162                 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3163         
3164                 searchField.setEditText("");
3165                 saveNoteColumnPositions();
3166                 saveNoteIndexWidth();
3167                 noteIndexUpdated(true);
3168                 if (currentNote == null && listManager.getNoteIndex().size() > 0) {
3169                         currentNote = listManager.getNoteIndex().get(0);
3170                         currentNoteGuid = currentNote.getGuid();
3171                 }
3172                 refreshEvernoteNote(true);
3173                 if (currentNote != null)
3174                         loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
3175         }
3176         // text in the search bar changed.  We only use this to tell if it was cleared, 
3177         // otherwise we trigger off searchFieldChanged.
3178         @SuppressWarnings("unused")
3179         private void searchFieldTextChanged(String text) {
3180                 QWebSettings.setMaximumPagesInCache(0);
3181                 QWebSettings.setObjectCacheCapacities(0, 0, 0);
3182
3183                 if (text.trim().equals("")) {
3184                         searchFieldCleared();
3185                         if (searchPerformed) {
3186
3187                                 // This is done because we want to force a reload of
3188                                 // images.  Some images we may want to highlight the text.
3189                                 noteCache.clear();
3190                                 readOnlyCache.clear();
3191                                 inkNoteCache.clear();
3192                                 
3193                                 listManager.setEnSearch("");
3194                                 listManager.loadNotesIndex();
3195                                 refreshEvernoteNote(true);
3196                                 noteIndexUpdated(false);
3197                                 refreshEvernoteNote(true);
3198                         }
3199                         searchPerformed = false;
3200                 }
3201         }
3202     // Text in the toolbar has changed
3203     private void searchFieldChanged() {
3204         logger.log(logger.HIGH, "Entering NeverNote.searchFieldChanged");
3205         noteCache.clear();
3206         readOnlyCache.clear();
3207         inkNoteCache.clear();
3208         saveNoteColumnPositions();
3209         saveNoteIndexWidth();
3210         String text = searchField.currentText();
3211         listManager.setEnSearch(text.trim());
3212         listManager.loadNotesIndex();
3213         noteIndexUpdated(false);
3214
3215         refreshEvernoteNote(true);
3216         searchPerformed = true;
3217         waitCursor(false);
3218         logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
3219     }
3220
3221     // Build the window tool bar
3222     private void setupToolBar() {
3223         logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
3224         toolBar = addToolBar(tr("Tool Bar"));   
3225         toolBar.setObjectName("toolBar");
3226         toolBar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon);
3227         menuBar.setupToolBarVisible();
3228         if (!Global.isWindowVisible("toolBar"))
3229                 toolBar.setVisible(false);
3230         else
3231                 toolBar.setVisible(true);
3232
3233 //      toolBar.addWidget(menuBar);
3234 //      menuBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3235 //      toolBar.addSeparator();
3236         prevButton = toolBar.addAction(tr(""));
3237         prevButton.setToolTip(tr("Previous"));
3238         QIcon prevIcon = new QIcon(iconPath+"back.png");
3239         prevButton.setIcon(prevIcon);
3240         prevButton.triggered.connect(this, "previousViewedAction()");   
3241         togglePrevArrowButton(Global.isToolbarButtonVisible("prevArrow"));
3242         
3243         nextButton = toolBar.addAction(tr(""));
3244         nextButton.setToolTip(tr("Next"));
3245         QIcon nextIcon = new QIcon(iconPath+"forward.png");
3246         nextButton.setIcon(nextIcon);
3247         nextButton.triggered.connect(this, "nextViewedAction()");       
3248         toggleNextArrowButton(Global.isToolbarButtonVisible("nextArrow"));
3249         
3250         toolBar.addSeparator();
3251         
3252         upButton = toolBar.addAction(tr("Up"));
3253         QIcon upIcon = new QIcon(iconPath+"up.png");
3254         upButton.setIcon(upIcon);
3255         upButton.triggered.connect(this, "upAction()");         
3256         toggleUpArrowButton(Global.isToolbarButtonVisible("upArrow"));
3257
3258         
3259         downButton = toolBar.addAction(tr("Down"));
3260         QIcon downIcon = new QIcon(iconPath+"down.png");
3261         downButton.setIcon(downIcon);
3262         downButton.triggered.connect(this, "downAction()");
3263         toggleDownArrowButton(Global.isToolbarButtonVisible("downArrow"));
3264         
3265         synchronizeButton = toolBar.addAction(tr("Synchronize"));
3266         synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
3267         synchronizeIconAngle = 0;
3268         synchronizeButton.triggered.connect(this, "evernoteSync()");
3269         toggleSynchronizeButton(Global.isToolbarButtonVisible("synchronize"));
3270         
3271         printButton = toolBar.addAction(tr("Print"));
3272         QIcon printIcon = new QIcon(iconPath+"print.png");
3273         printButton.setIcon(printIcon);
3274         printButton.triggered.connect(this, "printNote()");
3275         togglePrintButton(Global.isToolbarButtonVisible("print"));
3276
3277         tagButton = toolBar.addAction(tr("Tag")); 
3278         QIcon tagIcon = new QIcon(iconPath+"tag.png");
3279         tagButton.setIcon(tagIcon);
3280         tagButton.triggered.connect(browserWindow, "modifyTags()");
3281         toggleTagButton(Global.isToolbarButtonVisible("tag"));
3282
3283         attributeButton = toolBar.addAction(tr("Attributes")); 
3284         QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
3285         attributeButton.setIcon(attributeIcon);
3286         attributeButton.triggered.connect(this, "toggleNoteAttributes()");
3287         toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
3288                 
3289         emailButton = toolBar.addAction(tr("Email"));
3290         QIcon emailIcon = new QIcon(iconPath+"email.png");
3291         emailButton.setIcon(emailIcon);
3292         emailButton.triggered.connect(this, "emailNote()");
3293         toggleEmailButton(Global.isToolbarButtonVisible("email"));
3294
3295         deleteButton = toolBar.addAction(tr("Delete"));         
3296         QIcon deleteIcon = new QIcon(iconPath+"delete.png");
3297         deleteButton.setIcon(deleteIcon);
3298         deleteButton.triggered.connect(this, "deleteNote()");
3299         toggleDeleteButton(Global.isToolbarButtonVisible("delete"));
3300
3301         newButton = toolBar.addAction(tr("New"));
3302         QIcon newIcon = new QIcon(iconPath+"new.png");
3303         newButton.triggered.connect(this, "addNote()");
3304         newButton.setIcon(newIcon);
3305         toggleNewButton(Global.isToolbarButtonVisible("new"));
3306         
3307         allNotesButton = toolBar.addAction(tr("All Notes"));
3308         QIcon allIcon = new QIcon(iconPath+"books.png");
3309         allNotesButton.triggered.connect(this, "allNotes()");
3310         allNotesButton.setIcon(allIcon);
3311         toggleAllNotesButton(Global.isToolbarButtonVisible("allNotes"));
3312         
3313         //toolBar.addSeparator();
3314         //toolBar.addWidget(new QLabel(tr("Quota:")));
3315         //toolBar.addWidget(quotaBar);
3316         //quotaBar.setSizePolicy(Policy.Minimum, Policy.Minimum);
3317         updateQuotaBar();
3318         //toolBar.addSeparator();
3319         
3320         //toolBar.addWidget(new QLabel(tr("Zoom")));
3321         //toolBar.addWidget(zoomSpinner);
3322         
3323         //toolBar.addWidget(new QLabel("                    "));
3324         //toolBar.addSeparator();
3325         //toolBar.addWidget(new QLabel(tr("  Search:")));
3326         //toolBar.addWidget(searchField);
3327         QSizePolicy sizePolicy = new QSizePolicy();
3328         sizePolicy.setHorizontalPolicy(Policy.MinimumExpanding);
3329         QLabel spacer = new QLabel("");
3330         spacer.setSizePolicy(sizePolicy);
3331         toolBar.addWidget(spacer);
3332         //searchField.setInsertPolicy(InsertPolicy.InsertAtTop);
3333
3334         //searchClearButton = toolBar.addAction("Search Clear");
3335         //QIcon searchClearIcon = new QIcon(iconPath+"searchclear.png");
3336         //searchClearButton.setIcon(searchClearIcon);
3337         //searchClearButton.triggered.connect(this, "searchFieldCleared()");
3338         //toggleSearchClearButton(Global.isToolbarButtonVisible("searchClear"));
3339
3340         logger.log(logger.HIGH, "Leaving NeverNote.setupToolBar");
3341     }
3342     // Update the sychronize button picture
3343     @Override
3344         public QMenu createPopupMenu() {
3345         QMenu contextMenu = super.createPopupMenu();
3346         
3347         contextMenu.addSeparator();
3348         QAction prevAction = addContextAction("prevArrow", tr("Previous Arrow"));
3349         contextMenu.addAction(prevAction);
3350         prevAction.triggered.connect(this, "togglePrevArrowButton(Boolean)");
3351
3352         QAction nextAction = addContextAction("nextArrow", tr("Next Arrow"));
3353         contextMenu.addAction(nextAction);
3354         nextAction.triggered.connect(this, "toggleNextArrowButton(Boolean)");
3355
3356         QAction upAction = addContextAction("upArrow", tr("Up Arrow"));
3357         contextMenu.addAction(upAction);
3358         upAction.triggered.connect(this, "toggleUpArrowButton(Boolean)");
3359
3360         QAction downAction = addContextAction("downArrow", tr("Down Arrow"));
3361         contextMenu.addAction(downAction);
3362         downAction.triggered.connect(this, "toggleDownArrowButton(Boolean)");
3363
3364         QAction synchronizeAction = addContextAction("synchronize", tr("Synchronize"));
3365         contextMenu.addAction(synchronizeAction);
3366         synchronizeAction.triggered.connect(this, "toggleSynchronizeButton(Boolean)");
3367
3368         QAction printAction = addContextAction("print", tr("Print"));
3369         contextMenu.addAction(printAction);
3370         printAction.triggered.connect(this, "togglePrintButton(Boolean)");
3371
3372         QAction tagAction = addContextAction("tag", tr("Tag"));
3373         contextMenu.addAction(tagAction);
3374         tagAction.triggered.connect(this, "toggleTagButton(Boolean)");
3375         
3376         QAction attributeAction = addContextAction("attribute", tr("Attribute"));
3377         contextMenu.addAction(attributeAction);
3378         attributeAction.triggered.connect(this, "toggleAttributeButton(Boolean)");
3379         
3380         QAction emailAction = addContextAction("email", tr("Email"));
3381         contextMenu.addAction(emailAction);
3382         emailAction.triggered.connect(this, "toggleEmailButton(Boolean)");
3383
3384         QAction deleteAction = addContextAction("delete", tr("Delete"));
3385         contextMenu.addAction(deleteAction);
3386         deleteAction.triggered.connect(this, "toggleDeleteButton(Boolean)");
3387
3388         QAction newAction = addContextAction("new", tr("Add"));
3389         contextMenu.addAction(newAction);
3390         newAction.triggered.connect(this, "toggleNewButton(Boolean)");
3391
3392         QAction allNotesAction = addContextAction("allNotes", tr("All Notes"));
3393         contextMenu.addAction(allNotesAction);
3394         allNotesAction.triggered.connect(this, "toggleAllNotesButton(Boolean)");
3395         
3396         QAction searchClearAction = addContextAction("searchClear", tr("Search Clear"));
3397         contextMenu.addAction(searchClearAction);
3398         searchClearAction.triggered.connect(this, "toggleSearchClearButton(Boolean)");
3399         
3400         return contextMenu;
3401         
3402     }
3403     private QAction addContextAction(String config, String name) {
3404         QAction newAction = new QAction(this);
3405                 newAction.setText(name);
3406                 newAction.setCheckable(true);
3407                 newAction.setChecked(Global.isToolbarButtonVisible(config));
3408                 return newAction;
3409     }
3410     private void togglePrevArrowButton(Boolean toggle) {
3411                 prevButton.setVisible(toggle);
3412                 Global.saveToolbarButtonsVisible("prevArrow", toggle);
3413     }
3414     private void toggleNextArrowButton(Boolean toggle) {
3415                 nextButton.setVisible(toggle);
3416                 Global.saveToolbarButtonsVisible("nextArrow", toggle);
3417     }
3418     private void toggleUpArrowButton(Boolean toggle) {
3419                 upButton.setVisible(toggle);
3420                 Global.saveToolbarButtonsVisible("upArrow", toggle);
3421     }
3422     private void toggleDownArrowButton(Boolean toggle) {
3423                 downButton.setVisible(toggle);
3424                 Global.saveToolbarButtonsVisible("downArrow", toggle);
3425     }
3426     private void toggleSynchronizeButton(Boolean toggle) {
3427                 synchronizeButton.setVisible(toggle);
3428                 Global.saveToolbarButtonsVisible("synchronize", toggle);
3429     }
3430     private void togglePrintButton(Boolean toggle) {
3431                 printButton.setVisible(toggle);
3432                 Global.saveToolbarButtonsVisible("print", toggle);
3433     }
3434     private void toggleTagButton(Boolean toggle) {
3435                 tagButton.setVisible(toggle);
3436                 Global.saveToolbarButtonsVisible("tag", toggle);
3437     }
3438     private void toggleAttributeButton(Boolean toggle) {
3439                 attributeButton.setVisible(toggle);
3440                 Global.saveToolbarButtonsVisible("attribute", toggle);
3441     }
3442     private void toggleEmailButton(Boolean toggle) {
3443                 emailButton.setVisible(toggle);
3444                 Global.saveToolbarButtonsVisible("email", toggle);
3445     }
3446     private void toggleDeleteButton(Boolean toggle) {
3447                 deleteButton.setVisible(toggle);
3448                 Global.saveToolbarButtonsVisible("delete", toggle);
3449     }
3450     private void toggleNewButton(Boolean toggle) {
3451                 newButton.setVisible(toggle);
3452                 Global.saveToolbarButtonsVisible("new", toggle);
3453     }
3454     private void toggleAllNotesButton(Boolean toggle) {
3455                 allNotesButton.setVisible(toggle);
3456                 Global.saveToolbarButtonsVisible("allNotes", toggle);
3457     }
3458     @SuppressWarnings("unused")
3459         private void toggleSearchClearButton(Boolean toggle) {
3460                 searchClearButton.setVisible(toggle);
3461                 Global.saveToolbarButtonsVisible("searchClear", toggle);
3462     }
3463
3464
3465
3466
3467
3468     @SuppressWarnings("unused")
3469         private void updateSyncButton() {
3470                 
3471         if (syncIcons == null) {
3472                 syncIcons = new ArrayList<QPixmap>();
3473                 double angle = 0.0;
3474                 synchronizeIconAngle = 0;
3475                 QPixmap pix = new QPixmap(iconPath+"synchronize.png");
3476                 syncIcons.add(pix);
3477                 for (int i=0; i<=360; i++) {
3478                         QPixmap rotatedPix = new QPixmap(pix.size());
3479                         QPainter p = new QPainter(rotatedPix);
3480                 rotatedPix.fill(toolBar.palette().color(ColorRole.Button));
3481                 QSize size = pix.size();
3482                 p.translate(size.width()/2, size.height()/2);
3483                 angle = angle+1.0;
3484                 p.rotate(angle);
3485                 p.setBackgroundMode(BGMode.OpaqueMode);
3486                 p.translate(-size.width()/2, -size.height()/2);
3487                 p.drawPixmap(0,0, pix);
3488                 p.end();
3489                 syncIcons.add(rotatedPix);
3490                 }
3491         }
3492
3493         synchronizeIconAngle++;
3494         if (synchronizeIconAngle > 359)
3495                 synchronizeIconAngle=0;
3496         synchronizeButton.setIcon(syncIcons.get(synchronizeIconAngle));
3497         
3498     }
3499     // Synchronize with Evernote
3500
3501         private void evernoteSync() {
3502         logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
3503         if (!Global.isConnected)
3504                 remoteConnect();
3505         if (Global.isConnected)
3506                 synchronizeAnimationTimer.start(5);
3507 //                      synchronizeAnimationTimer.start(200);
3508         syncTimer();
3509         logger.log(logger.HIGH, "Leaving NeverNote.evernoteSync");
3510     }
3511     private void updateQuotaBar() {
3512         long limit = Global.getUploadLimit();
3513         long amount = Global.getUploadAmount();
3514         if (amount>0 && limit>0) {
3515                 int percent =(int)(amount*100/limit);
3516                 quotaBar.setValue(percent);
3517         } else 
3518                 quotaBar.setValue(0);
3519     }
3520         // Zoom changed
3521     @SuppressWarnings("unused")
3522         private void zoomChanged() {
3523         browserWindow.getBrowser().setZoomFactor(new Double(zoomSpinner.value())/100);
3524     }
3525
3526     //****************************************************************
3527     //****************************************************************
3528     //* System Tray functions
3529     //****************************************************************
3530     //****************************************************************
3531         private void trayToggleVisible() {
3532         if (isVisible()) {
3533                 hide();
3534         } else {
3535                 show();
3536                 if (windowMaximized)
3537                         showMaximized();
3538                 else
3539                         showNormal();
3540                 raise();
3541         }
3542     }
3543     @SuppressWarnings("unused")
3544         private void trayActivated(QSystemTrayIcon.ActivationReason reason) {
3545         if (reason == QSystemTrayIcon.ActivationReason.DoubleClick) {
3546                 String name = QSystemTrayIcon.MessageIcon.resolve(reason.value()).name();
3547                 trayToggleVisible();
3548         }
3549     }
3550     
3551     
3552     //***************************************************************
3553     //***************************************************************
3554     //** These functions deal with the trash tree
3555     //***************************************************************
3556     //***************************************************************    
3557     // Setup the tree containing the trash.
3558     @SuppressWarnings("unused")
3559         private void trashTreeSelection() {     
3560         logger.log(logger.HIGH, "Entering NeverNote.trashTreeSelection");
3561         
3562         clearNotebookFilter();
3563         clearTagFilter();
3564         clearAttributeFilter();
3565         clearSavedSearchFilter();
3566         
3567         String tempGuid = currentNoteGuid;
3568         
3569 //      currentNoteGuid = "";
3570         currentNote = new Note();
3571         selectedNoteGUIDs.clear();
3572         listManager.getSelectedNotebooks().clear();
3573         listManager.getSelectedTags().clear();
3574         listManager.setSelectedSavedSearch("");
3575         browserWindow.clear();
3576     
3577         // toggle the add buttons
3578         newButton.setEnabled(!newButton.isEnabled());
3579         menuBar.noteAdd.setEnabled(newButton.isEnabled());
3580         menuBar.noteAdd.setVisible(true);
3581         
3582         List<QTreeWidgetItem> selections = trashTree.selectedItems();
3583         if (selections.size() == 0) {
3584                 currentNoteGuid = trashNoteGuid;
3585                         trashNoteGuid = tempGuid;
3586                 Global.showDeleted = false;
3587                 menuBar.noteRestoreAction.setEnabled(false);
3588                 menuBar.noteRestoreAction.setVisible(false);
3589                         // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3590                         rensoNoteListDock.setEnabled(true);
3591         }
3592         else {
3593                 trashNoteGuid = tempGuid;
3594                 currentNoteGuid = trashNoteGuid;
3595                 menuBar.noteRestoreAction.setEnabled(true);
3596                 menuBar.noteRestoreAction.setVisible(true);
3597                 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
3598                 rensoNoteListDock.setEnabled(false);
3599                                         
3600                 Global.showDeleted = true;
3601         }
3602         
3603         menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3604                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3605                         menuBar.noteAddNewTab.setEnabled(false);
3606                 }
3607         
3608         listManager.loadNotesIndex();
3609         noteIndexUpdated(false);
3610 ////            browserWindow.setEnabled(newButton.isEnabled());
3611         browserWindow.setReadOnly(!newButton.isEnabled());
3612         logger.log(logger.HIGH, "Leaving NeverNote.trashTreeSelection");
3613     }
3614     // Empty the trash file
3615     @SuppressWarnings("unused")
3616         private void emptyTrash() {
3617 //      browserWindow.clear();
3618         logger.log(logger.EXTREME, "Emptying Trash");
3619         listManager.emptyTrash();
3620         logger.log(logger.EXTREME, "Resetting view after trash empty");
3621         if (trashTree.selectedItems().size() > 0) {
3622                 listManager.getSelectedNotebooks().clear();
3623                 listManager.getSelectedTags().clear();
3624                 listManager.setSelectedSavedSearch("");
3625                 newButton.setEnabled(!newButton.isEnabled());
3626                 menuBar.noteAdd.setEnabled(newButton.isEnabled());
3627                 menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
3628                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3629                         menuBar.noteAddNewTab.setEnabled(false);
3630                 }
3631                 menuBar.noteAdd.setVisible(true);
3632                 browserWindow.clear();
3633                 
3634                 clearTagFilter();
3635                 clearNotebookFilter();
3636                 clearSavedSearchFilter();
3637                 clearAttributeFilter();
3638                         
3639                 Global.showDeleted = false;
3640                 menuBar.noteRestoreAction.setEnabled(false);
3641                 menuBar.noteRestoreAction.setVisible(false);
3642                 
3643                 listManager.loadNotesIndex();
3644                 noteIndexUpdated(false);
3645                 
3646                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3647                 if (!rensoNoteListDock.isEnabled()) {
3648                         rensoNoteListDock.setEnabled(true);
3649                 }
3650         }       
3651    }
3652     // Show/Hide trash window
3653         @SuppressWarnings("unused")
3654         private void toggleTrashWindow() {
3655                 logger.log(logger.HIGH, "Entering NeverNote.toggleTrashWindow");
3656         if (trashTree.isVisible())
3657                 trashTree.hide();
3658         else
3659                 trashTree.show();
3660         menuBar.hideTrash.setChecked(trashTree.isVisible());
3661         
3662                 Global.saveWindowVisible("trashTree", trashTree.isVisible());
3663         logger.log(logger.HIGH, "Leaving NeverNote.trashWindow");
3664     }    
3665         private void clearTrashFilter() {
3666                 Global.showDeleted = false;
3667         newButton.setEnabled(true);
3668         menuBar.noteAdd.setEnabled(true);
3669                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
3670                         menuBar.noteAddNewTab.setEnabled(false);
3671                 } else {
3672                         menuBar.noteAddNewTab.setEnabled(true);
3673                 }
3674         menuBar.noteAdd.setVisible(true);
3675                 trashTree.blockSignals(true);
3676                 trashTree.clearSelection();
3677                 trashTree.blockSignals(false);
3678                 
3679         }
3680     
3681    
3682     //***************************************************************
3683     //***************************************************************
3684     //** These functions deal with connection settings
3685     //***************************************************************
3686     //***************************************************************
3687         // SyncRunner had a problem and things are disconnected
3688         @SuppressWarnings("unused")
3689         private void remoteErrorDisconnect() {
3690                 menuBar.connectAction.setText(tr("Connect"));
3691                 menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3692                 menuBar.synchronizeAction.setEnabled(false);
3693                 Global.isConnected = false;
3694                 synchronizeAnimationTimer.stop();
3695                 return;
3696         }
3697         // Do a manual connect/disconnect
3698     private void remoteConnect() {
3699         
3700         logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
3701
3702         // If we are already connected, we just disconnect
3703         if (Global.isConnected) {
3704                 Global.isConnected = false;
3705                 syncRunner.enDisconnect();
3706                 setupConnectMenuOptions();
3707                 setupOnlineMenu();
3708                 return;
3709         }
3710         
3711         OAuthTokenizer tokenizer = new OAuthTokenizer();
3712         AESEncrypter aes = new AESEncrypter();
3713         try {
3714                         aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3715                 } catch (FileNotFoundException e) {
3716                         // File not found, so we'll just get empty strings anyway. 
3717                 }
3718         
3719                 
3720                 if (Global.getProxyValue("url").equals("")) {
3721                         System.setProperty("http.proxyHost","") ;
3722                         System.setProperty("http.proxyPort", "") ;
3723                         System.setProperty("https.proxyHost","") ;
3724                         System.setProperty("https.proxyPort", "") ;         
3725                 } else {
3726                         // PROXY
3727                         System.setProperty("http.proxyHost",Global.getProxyValue("url")) ;
3728                         System.setProperty("http.proxyPort", Global.getProxyValue("port")) ;
3729                         System.setProperty("https.proxyHost",Global.getProxyValue("url")) ;
3730                         System.setProperty("https.proxyPort", Global.getProxyValue("port")) ;
3731  
3732                         if (Global.getProxyValue("userid").equals("")) {
3733                                 Authenticator.setDefault(new Authenticator() {
3734                         @Override
3735                         protected PasswordAuthentication getPasswordAuthentication() {
3736                                 return new
3737                                 PasswordAuthentication(Global.getProxyValue("userid"),Global.getProxyValue("password").toCharArray());
3738                                 }
3739                         });
3740                 }
3741         }
3742
3743                 syncRunner.userStoreUrl = Global.userStoreUrl;
3744                 syncRunner.noteStoreUrl = Global.noteStoreUrl;
3745                 syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
3746                 
3747                 
3748                 
3749                 String authString = aes.getString();
3750                 if (!authString.equals("")) {
3751                         tokenizer.tokenize(authString);
3752                         syncRunner.authToken = tokenizer.oauth_token;
3753                 syncRunner.enConnect();
3754                 }               
3755
3756                 Global.isConnected = syncRunner.isConnected;
3757                 
3758                 boolean autoLoginMessageFlag = false;
3759                 if (!Global.isConnected) {
3760                 OAuthWindow window = new OAuthWindow(logger);
3761                 if (window.error) {
3762                         setMessage(window.errorMessage);
3763                         return;
3764                 }
3765                 window.exec();
3766                 if (window.error) {
3767                         setMessage(window.errorMessage);
3768                         return;
3769                         }
3770                 tokenizer.tokenize(window.response);
3771                 if (tokenizer.oauth_token.equals("")) {
3772                         setMessage(tr("Invalid authorization token received."));
3773                         return;
3774                 }
3775                 aes.setString(window.response);
3776                 try {
3777                                 aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
3778                         } catch (FileNotFoundException e) {
3779                                 // TODO Auto-generated catch block
3780                                 e.printStackTrace();
3781                         }
3782                 syncRunner.authToken = tokenizer.oauth_token;
3783                         syncRunner.enConnect();
3784                         Global.isConnected = syncRunner.isConnected;
3785                         autoLoginMessageFlag = true;
3786                 }
3787 //              Global.username = syncRunner.username;
3788                         
3789                 if (!Global.isConnected)
3790                         return;
3791                 setupOnlineMenu();
3792                 setupConnectMenuOptions();
3793                 
3794                 // 初回ログイン時に自動ログインが無効だったら、有効化するか確認する
3795                 if (autoLoginMessageFlag && !Global.automaticLogin()) {
3796                         if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure you want to enable the auto-login feature?"), 
3797                                         QMessageBox.StandardButton.Yes, QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
3798                                 Global.setAutomaticLogin(true);
3799                         }
3800                 }
3801                 
3802                 logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
3803     }
3804     private void setupConnectMenuOptions() {
3805         logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
3806                 if (!Global.isConnected) {
3807                         menuBar.connectAction.setText(tr("Connect"));
3808                         menuBar.connectAction.setToolTip(tr("Connect to Evernote"));
3809                         menuBar.synchronizeAction.setEnabled(false);
3810                 } else {
3811                         menuBar.connectAction.setText(tr("Disconnect"));
3812                         menuBar.connectAction.setToolTip(tr("Disconnect from Evernote"));
3813                         menuBar.synchronizeAction.setEnabled(true);
3814                 }
3815                 logger.log(logger.HIGH, "Leaving NeverNote.setupConnectionMenuOptions");
3816     }
3817     
3818     
3819     
3820     //***************************************************************
3821     //***************************************************************
3822     //** These functions deal with the GUI Attribute tree
3823     //***************************************************************
3824     //***************************************************************    
3825     @SuppressWarnings("unused")
3826         private void attributeTreeClicked(QTreeWidgetItem item, Integer integer) {
3827         
3828 //      clearTagFilter();
3829 //      clearNotebookFilter();
3830         clearTrashFilter();
3831 //      clearSavedSearchFilter();
3832         
3833                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
3834                 if (!rensoNoteListDock.isEnabled()) {
3835                         rensoNoteListDock.setEnabled(true);
3836                 }
3837
3838         if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
3839                 if (item.childCount() > 0) {
3840                         item.setSelected(false);
3841                 } else {
3842                 Global.createdBeforeFilter.reset();
3843                 Global.createdSinceFilter.reset();
3844                 Global.changedBeforeFilter.reset();
3845                 Global.changedSinceFilter.reset();
3846                 Global.containsFilter.reset();
3847                         attributeTreeSelected = item;
3848                         DateAttributeFilterTable f = null;
3849                         f = findDateAttributeFilterTable(item.parent());
3850                         if (f!=null)
3851                                 f.select(item.parent().indexOfChild(item));
3852                         else {
3853                                 Global.containsFilter.select(item.parent().indexOfChild(item));
3854                         }
3855                 }
3856                 listManager.loadNotesIndex();
3857                 noteIndexUpdated(false);
3858                 return;
3859         }
3860                 attributeTreeSelected = null;
3861                 item.setSelected(false);
3862         Global.createdBeforeFilter.reset();
3863         Global.createdSinceFilter.reset();
3864         Global.changedBeforeFilter.reset();
3865         Global.changedSinceFilter.reset();
3866         Global.containsFilter.reset();
3867         listManager.loadNotesIndex();
3868                 noteIndexUpdated(false); 
3869     }
3870     // This determines what attribute filter we need, depending upon the selection
3871     private DateAttributeFilterTable findDateAttributeFilterTable(QTreeWidgetItem w) {
3872                 if (w.parent() != null && w.childCount() > 0) {
3873                         QTreeWidgetItem parent = w.parent();
3874                         if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created && 
3875                                 w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3876                                         return Global.createdSinceFilter;
3877                         if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Created && 
3878                         w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3879                                         return Global.createdBeforeFilter;
3880                         if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified && 
3881                         w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Since)
3882                                         return Global.changedSinceFilter;
3883                 if (parent.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.LastModified && 
3884                         w.data(0,ItemDataRole.UserRole)==AttributeTreeWidget.Attributes.Before)
3885                                                 return Global.changedBeforeFilter;
3886                 }
3887                 return null;
3888     }
3889
3890     // Show/Hide attribute search window
3891         @SuppressWarnings("unused")
3892         private void toggleAttributesWindow() {
3893                 logger.log(logger.HIGH, "Entering NeverNote.toggleAttributesWindow");
3894         if (attributeTree.isVisible())
3895                 attributeTree.hide();
3896         else
3897                 attributeTree.show();
3898         menuBar.hideAttributes.setChecked(attributeTree.isVisible());
3899         
3900                 Global.saveWindowVisible("attributeTree", attributeTree.isVisible());
3901         logger.log(logger.HIGH, "Leaving NeverNote.toggleAttributeWindow");
3902     }    
3903         private void clearAttributeFilter() {
3904         Global.createdBeforeFilter.reset();
3905         Global.createdSinceFilter.reset();
3906         Global.changedBeforeFilter.reset();
3907         Global.changedSinceFilter.reset();
3908         Global.containsFilter.reset();
3909         attributeTreeSelected = null;
3910                 attributeTree.blockSignals(true);
3911                 attributeTree.clearSelection();
3912                 attributeTree.blockSignals(false);
3913         }
3914     
3915         
3916     //***************************************************************
3917     //***************************************************************
3918     //** These functions deal with the GUI Note index table
3919     //***************************************************************
3920     //***************************************************************    
3921     // Initialize the note list table
3922         private void initializeNoteTable() {
3923                 logger.log(logger.HIGH, "Entering NeverNote.initializeNoteTable");
3924                 noteTableView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
3925                 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
3926                 logger.log(logger.HIGH, "Leaving NeverNote.initializeNoteTable");
3927         }       
3928     // Show/Hide trash window
3929         @SuppressWarnings("unused")
3930         private void toggleNoteListWindow() {
3931                 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteListWindow");
3932         if (noteTableView.isVisible())
3933                 noteTableView.hide();
3934         else
3935                 noteTableView.show();
3936         menuBar.hideNoteList.setChecked(noteTableView.isVisible());
3937         
3938                 Global.saveWindowVisible("noteList", noteTableView.isVisible());
3939         logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteListWindow");
3940     }   
3941         // Handle the event that a user selects a note from the table
3942     @SuppressWarnings("unused")
3943         private void noteTableSelection() {
3944                 logger.log(logger.HIGH, "Entering NeverNote.noteTableSelection");
3945
3946                 saveNote();
3947                 
3948                 // ICHANGED
3949                 // 右クリックだったときの処理
3950                 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
3951                         // 選択されたノートのguidをselectedNoteGUIDsにセット
3952                         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3953                         if(selections.size() > 0){
3954                                 selectedNoteGUIDs.clear();
3955                                 for(int i = 0; i < selections.size(); i++){
3956                                         int row = selections.get(i).row();
3957                                         QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3958                                         SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3959                                         selectedNoteGUIDs.add((String) ix.values().toArray()[0]);
3960                                 }
3961                         }
3962                         return;
3963                 }
3964                 
3965                 // If we have more than one selection, then set the merge note action to true.
3966         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
3967                 if (selections.size() > 1) 
3968                 menuBar.noteMergeAction.setEnabled(true);
3969                 else
3970                         menuBar.noteMergeAction.setEnabled(false);
3971
3972                 // If the ctrl key is pressed, then they are selecting multiple 
3973                 // entries and we don't want to change the currently viewed note.
3974                 // ICHANGED
3975                 // Shiftキーを押しながらの場合の処理も追加
3976                 if ((QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) ||
3977                                 QApplication.keyboardModifiers().isSet(KeyboardModifier.ShiftModifier)) &&
3978                                 QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
3979                         selectedNoteGUIDs.clear();
3980                 for (int i=0; i<selections.size(); i++) {
3981                         int row = selections.get(i).row();
3982                         QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
3983                         SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
3984                         selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
3985                 }
3986                         return;
3987                 }
3988                 
3989                 // ICHANGED たぶんこれは不要
3990                 // IFIXED ?
3991                 /*if (historyGuids.size() == 0) {
3992                         historyGuids.add(currentNoteGuid);
3993                         historyPosition = 1;
3994                 }*/
3995
3996         noteTableView.showColumn(Global.noteTableGuidPosition);
3997         
3998         if (!Global.isColumnVisible("guid"))
3999                 noteTableView.hideColumn(Global.noteTableGuidPosition);
4000         
4001         if (selections.size() > 0) {
4002                 QModelIndex index;
4003                 menuBar.noteDuplicateAction.setEnabled(true);
4004                 menuBar.noteOnlineHistoryAction.setEnabled(true);
4005                 menuBar.noteMergeAction.setEnabled(true);
4006                 selectedNoteGUIDs.clear();
4007                 if (currentNoteGuid != null && !currentNoteGuid.equals("") && !Global.showDeleted) {
4008                         menuBar.noteAddNewTab.setEnabled(true);
4009                 }
4010                 if (selections.size() != 1 || Global.showDeleted) {
4011                         menuBar.noteDuplicateAction.setEnabled(false);
4012                 }
4013                 if (selections.size() != 1 || !Global.isConnected) {
4014                         menuBar.noteOnlineHistoryAction.setEnabled(false);
4015                 }
4016                 if (selections.size() == 1) {
4017                         menuBar.noteMergeAction.setEnabled(false);
4018                 }
4019                 for (int i=0; i<selections.size(); i++) {
4020                         int row = selections.get(i).row();
4021                         if (row == 0) 
4022                                 upButton.setEnabled(false);
4023                         else
4024                                 upButton.setEnabled(true);
4025                         if (row < listManager.getNoteTableModel().rowCount()-1)
4026                                 downButton.setEnabled(true);
4027                         else
4028                                 downButton.setEnabled(false);
4029                         index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
4030                         SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
4031                                 
4032                         currentNoteGuid = (String)ix.values().toArray()[0];                     
4033                         selectedNoteGUIDs.add(currentNoteGuid);
4034                 }
4035         }
4036         
4037         nextButton.setEnabled(true);
4038                 prevButton.setEnabled(true);
4039                 
4040                 // ICHANGED
4041                 int currentIndex = tabBrowser.currentIndex();
4042                 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4043                 int histPosition = historyPosition.get(currentIndex);
4044                 boolean fromHist = fromHistory.get(currentIndex);
4045                 
4046                 // ICHANGED
4047                 if (!fromHist) {
4048                         int endPosition = histGuids.size() - 1;
4049
4050                         for (int j = histPosition; j <= endPosition; j++) {
4051                                 histGuids.remove(histGuids.size() - 1);
4052                         }
4053                         histGuids.add(currentNoteGuid);
4054                         historyPosition.put(currentIndex, histGuids.size());
4055                         histPosition = histGuids.size();
4056                 }
4057                 if (histPosition <= 1){
4058                         prevButton.setEnabled(false);
4059                 }
4060                 if (histPosition == histGuids.size())
4061                         nextButton.setEnabled(false);
4062                 fromHistory.put(currentIndex, false);
4063                 fromHist = false;
4064                 
4065         scrollToGuid(currentNoteGuid);
4066         refreshEvernoteNote(true);
4067         
4068                 // ICHANGED
4069                 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
4070                         if (!Global.showDeleted) { // ゴミ箱じゃなければ
4071                                 addBrowseHistory();
4072                         }
4073                 }
4074
4075                 // ICHANGED
4076                 // 連想ノートリストを更新
4077                 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
4078                 
4079                 waitCursor(false);
4080                 logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
4081     }
4082     
4083
4084         // ICHANGED
4085     // 複数ノートの同時閲覧履歴をデータベースに保存
4086         private void addBrowseHistory() {
4087                 // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4088                 if (tabWindows.size() >= 2) {
4089                         Iterator<Integer> it = tabWindows.keySet().iterator();
4090                         while (it.hasNext()) {
4091                                 int tabIndex = it.next();
4092                                 String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
4093                                 // guid1=guid2のデータは登録しない
4094                                 if (!currentNoteGuid.equals(nextGuid)) {
4095                                         conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4096                                 }
4097                         }
4098                 }
4099                 // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
4100                 if (externalWindows.size() >= 1) {
4101                         Iterator<String> it = externalWindows.keySet().iterator();
4102                         while (it.hasNext()) {
4103                                 String nextGuid = it.next();
4104                                 // guid1=guid2のデータは登録しない
4105                                 if (!currentNoteGuid.equals(nextGuid)) {
4106                                         conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
4107                                 }
4108                         }
4109                 }
4110         }
4111         
4112         // Trigger a refresh when the note db has been updated
4113         private void noteIndexUpdated(boolean reload) {
4114                 logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
4115                 saveNote();
4116         refreshEvernoteNoteList();
4117         logger.log(logger.HIGH, "Calling note table reload in NeverNote.noteIndexUpdated() - "+reload);
4118         noteTableView.load(reload);
4119         if (currentNoteGuid == null || currentNoteGuid.equals("")) {
4120                 int pos;
4121                 if (noteTableView.proxyModel.sortOrder() == SortOrder.AscendingOrder)
4122                         pos = noteTableView.proxyModel.rowCount();
4123                 else 
4124                         pos = 1;
4125                 if (noteTableView.proxyModel.rowCount() == 0)
4126                         pos = 0;
4127                 if (pos>0)      {
4128                         QModelIndex i = noteTableView.proxyModel.index(pos-1, Global.noteTableGuidPosition);
4129                         if (i!=null) {
4130                                 currentNoteGuid = (String)i.data();
4131                         }
4132                 }
4133         }               
4134                 if (!noteTableView.isColumnHidden(Global.noteTableGuidPosition))
4135                         showColumns();
4136                 scrollToGuid(currentNoteGuid);
4137                 logger.log(logger.HIGH, "Leaving NeverNote.noteIndexUpdated");
4138     }
4139         // Called when the list of notes is updated
4140     private void refreshEvernoteNoteList() {
4141         logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNoteList");
4142         browserWindow.setDisabled(false);
4143                 if (selectedNoteGUIDs == null)
4144                         selectedNoteGUIDs = new ArrayList<String>();
4145                 selectedNoteGUIDs.clear();  // clear out old entries
4146                 
4147                 String saveCurrentNoteGuid = new String();
4148                 String tempNoteGuid = new String();
4149                 
4150                 // ICHANGED
4151                 int currentIndex = tabBrowser.currentIndex();
4152                 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4153                 histGuids.clear();
4154                 historyPosition.put(currentIndex, 0);
4155                 
4156                 prevButton.setEnabled(false);
4157                 nextButton.setEnabled(false);
4158                 
4159                 if (currentNoteGuid == null) 
4160                         currentNoteGuid = new String();
4161                 
4162                 //determine current note guid
4163                 for (Note note : listManager.getNoteIndex()) {
4164                         tempNoteGuid = note.getGuid();
4165                         if (currentNoteGuid.equals(tempNoteGuid)) {
4166                                 saveCurrentNoteGuid = tempNoteGuid;
4167                         }
4168                 }
4169                 
4170                 if (listManager.getNoteIndex().size() == 0) {
4171                         currentNoteGuid = "";
4172                         currentNote = null;
4173                         browserWindow.clear();
4174                         browserWindow.setDisabled(true);
4175                         waitCursor(false);
4176                 } 
4177                 
4178                 if (Global.showDeleted && listManager.getNoteIndex().size() > 0 && saveCurrentNoteGuid.equals("")) {
4179                         currentNoteGuid = listManager.getNoteIndex().get(0).getGuid();
4180                         saveCurrentNoteGuid = currentNoteGuid;
4181                         refreshEvernoteNote(true);
4182                 }
4183                 
4184                 if (!saveCurrentNoteGuid.equals("")) {
4185                         refreshEvernoteNote(false);
4186                 } else {
4187                                 currentNoteGuid = "";
4188                 }
4189                 reloadTagTree(false);
4190
4191                 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
4192         } 
4193     
4194         // ICHANGED
4195         // Called when the previous arrow button is clicked
4196         @SuppressWarnings("unused")
4197         private void previousViewedAction() {
4198                 int currentIndex = tabBrowser.currentIndex();
4199                 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4200                 int histPosition = historyPosition.get(currentIndex);
4201                 boolean fromHist = fromHistory.get(currentIndex);
4202                 if (!prevButton.isEnabled())
4203                         return;
4204                 if (histPosition == 0)
4205                         return;
4206                 histPosition--;
4207                 historyPosition.put(currentIndex, histPosition);
4208                 if (histPosition <= 0)
4209                         return;
4210                 String historyGuid = histGuids.get(histPosition - 1);
4211                 fromHistory.put(currentIndex, true);
4212                 fromHist = true;
4213                 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4214                         QModelIndex modelIndex = noteTableView.model().index(i,
4215                                         Global.noteTableGuidPosition);
4216                         if (modelIndex != null) {
4217                                 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4218                                                 modelIndex);
4219                                 String tableGuid = (String) ix.values().toArray()[0];
4220                                 if (tableGuid.equals(historyGuid)) {
4221                                         noteTableView.selectRow(i);
4222                                         return;
4223                                 }
4224                         }
4225                 }
4226         }
4227         
4228     @SuppressWarnings("unused")
4229         private void nextViewedAction() {
4230         if (!nextButton.isEnabled())
4231                 return;
4232                 // ICHANGED
4233                 int currentIndex = tabBrowser.currentIndex();
4234                 ArrayList<String> histGuids = historyGuids.get(currentIndex);
4235                 int histPosition = historyPosition.get(currentIndex);
4236                 boolean fromHist = fromHistory.get(currentIndex);
4237                 String historyGuid = histGuids.get(histPosition);
4238                 histPosition++;
4239                 historyPosition.put(currentIndex, histPosition);
4240                 fromHistory.put(currentIndex, true);
4241                 fromHist = true;
4242                 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
4243                         QModelIndex modelIndex = noteTableView.model().index(i,
4244                                         Global.noteTableGuidPosition);
4245                         if (modelIndex != null) {
4246                                 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
4247                                                 modelIndex);
4248                                 String tableGuid = (String) ix.values().toArray()[0];
4249                                 if (tableGuid.equals(historyGuid)) {
4250                                         noteTableView.selectRow(i);
4251                                         return;
4252                                 }
4253                         }
4254                 }
4255     }
4256     // Called when the up arrow is clicked 
4257     @SuppressWarnings("unused")
4258         private void upAction() {
4259         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4260         int row = selections.get(0).row();
4261         if (row > 0) {
4262                 noteTableView.selectRow(row-1);
4263         }
4264     }
4265     // Called when the down arrow is clicked 
4266     @SuppressWarnings("unused")
4267         private void downAction() {
4268         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4269         int row = selections.get(0).row();
4270         int max = listManager.getNoteTableModel().rowCount();
4271         if (row < max-1) {
4272                 noteTableView.selectRow(row+1);
4273         }
4274     }
4275     // Update a tag string for a specific note in the list
4276     @SuppressWarnings("unused")
4277         private void updateListTags(String guid, List<String> tags) {
4278         logger.log(logger.HIGH, "Entering NeverNote.updateListTags");
4279         StringBuffer tagBuffer = new StringBuffer();
4280         for (int i=0; i<tags.size(); i++) {
4281                 tagBuffer.append(tags.get(i));
4282                 if (i<tags.size()-1)
4283                         tagBuffer.append(", ");
4284         }
4285         
4286         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4287                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4288                 if (modelIndex != null) {
4289                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4290                         String tableGuid =  (String)ix.values().toArray()[0];
4291                         if (tableGuid.equals(guid)) {
4292                                 listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition,tagBuffer.toString());
4293                                 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4294                                 noteTableView.proxyModel.invalidate();
4295                                 return;
4296                         }
4297                 }
4298         }
4299         logger.log(logger.HIGH, "Leaving NeverNote.updateListTags");
4300     }
4301     // Update a title for a specific note in the list
4302     @SuppressWarnings("unused")
4303         private void updateListAuthor(String guid, String author) {
4304         logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4305
4306         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4307                 //QModelIndex modelIndex =  noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4308                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4309                 if (modelIndex != null) {
4310                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4311                         String tableGuid =  (String)ix.values().toArray()[0];
4312                         if (tableGuid.equals(guid)) {
4313                                 listManager.getNoteTableModel().setData(i, Global.noteTableAuthorPosition,author);
4314                                 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4315                                 noteTableView.proxyModel.invalidate();
4316                                 return;
4317                         }       
4318                 }
4319         }
4320         
4321         logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4322     }
4323         private void updateListNoteNotebook(String guid, String notebook) {
4324         logger.log(logger.HIGH, "Entering NeverNote.updateListNoteNotebook");
4325         listManager.getNoteTableModel().updateNoteSyncStatus(guid, false);
4326         logger.log(logger.HIGH, "Leaving NeverNote.updateListNoteNotebook");
4327     }
4328     // Update a title for a specific note in the list
4329     @SuppressWarnings("unused")
4330         private void updateListSourceUrl(String guid, String url) {
4331         logger.log(logger.HIGH, "Entering NeverNote.updateListAuthor");
4332
4333         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4334                 //QModelIndex modelIndex =  noteTableView.proxyModel.index(i, Global.noteTableGuidPosition);
4335                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4336                 if (modelIndex != null) {
4337 //                      SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(modelIndex);
4338                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4339                         String tableGuid =  (String)ix.values().toArray()[0];
4340                         if (tableGuid.equals(guid)) {
4341                                 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4342                                 listManager.getNoteTableModel().setData(i, Global.noteTableSourceUrlPosition,url);
4343                                 noteTableView.proxyModel.invalidate();
4344                                 return;
4345                         }       
4346                 }
4347         }
4348         logger.log(logger.HIGH, "Leaving NeverNote.updateListAuthor");
4349     }
4350         @SuppressWarnings("unused")
4351         private void updateListGuid(String oldGuid, String newGuid) {
4352         logger.log(logger.HIGH, "Entering NeverNote.updateListTitle");
4353
4354         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4355                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4356                 if (modelIndex != null) {
4357                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4358                         String tableGuid =  (String)ix.values().toArray()[0];
4359                         if (tableGuid.equals(oldGuid)) {
4360                                 listManager.getNoteTableModel().setData(i, Global.noteTableGuidPosition,newGuid);
4361                                 //listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4362                                 return;
4363                         }       
4364                 }
4365         }
4366         logger.log(logger.HIGH, "Leaving NeverNote.updateListTitle");
4367     }
4368         private void updateListTagName(String guid) {
4369         logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4370                 
4371                 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4372                         if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4373                                 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4374
4375                                 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4376                                         QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4377                                         if (modelIndex != null) {
4378                                                 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4379                                                 String noteGuid = (String)ix.values().toArray()[0];
4380                                                 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4381                                                         listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4382                                                         i=listManager.getNoteTableModel().rowCount();
4383                                                 }
4384                                         }
4385                                 }
4386                         }
4387                 }       
4388         logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4389     }
4390         private void removeListTagName(String guid) {
4391         logger.log(logger.HIGH, "Entering NeverNote.updateTagName");
4392                 
4393                 for (int j=0; j<listManager.getNoteIndex().size(); j++) {
4394                         if (listManager.getNoteIndex().get(j).getTagGuids().contains(guid)) {
4395                                 for (int i=listManager.getNoteIndex().get(j).getTagGuids().size()-1; i>=0; i--) {
4396                                         if (listManager.getNoteIndex().get(j).getTagGuids().get(i).equals(guid))
4397                                                 listManager.getNoteIndex().get(j).getTagGuids().remove(i);
4398                                 }
4399                                 
4400                                 String newName = listManager.getTagNamesForNote(listManager.getNoteIndex().get(j));
4401                                 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4402                                         QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4403                                         if (modelIndex != null) {
4404                                                 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4405                                                 String noteGuid = (String)ix.values().toArray()[0];
4406                                                 if (noteGuid.equalsIgnoreCase(listManager.getNoteIndex().get(j).getGuid())) {
4407                                                         listManager.getNoteTableModel().setData(i, Global.noteTableTagPosition, newName);
4408                                                         i=listManager.getNoteTableModel().rowCount();
4409                                                 }
4410                                         }
4411                                 }
4412                         }
4413                 }       
4414         logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebook");
4415     }
4416     private void updateListNotebookName(String oldName, String newName) {
4417         logger.log(logger.HIGH, "Entering NeverNote.updateListNotebookName");
4418
4419         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4420                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableNotebookPosition); 
4421                 if (modelIndex != null) {
4422                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4423                         String tableName =  (String)ix.values().toArray()[0];
4424                         if (tableName.equalsIgnoreCase(oldName)) {
4425                                 listManager.getNoteTableModel().setData(i, Global.noteTableNotebookPosition, newName);
4426                         }
4427                 }
4428         }
4429         logger.log(logger.HIGH, "Leaving NeverNote.updateListNotebookName");
4430     }
4431     @SuppressWarnings("unused")
4432         private void updateListDateCreated(String guid, QDateTime date) {
4433         logger.log(logger.HIGH, "Entering NeverNote.updateListDateCreated");
4434
4435         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4436                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4437                 if (modelIndex != null) {
4438                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4439                         String tableGuid =  (String)ix.values().toArray()[0];
4440                         if (tableGuid.equals(guid)) {
4441                                 listManager.getNoteTableModel().setData(i, Global.noteTableCreationPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4442                                 noteTableView.proxyModel.invalidate();
4443                                 return;
4444                         }
4445                 }
4446         }
4447         logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4448     }
4449     @SuppressWarnings("unused")
4450         private void updateListDateSubject(String guid, QDateTime date) {
4451         logger.log(logger.HIGH, "Entering NeverNote.updateListDateSubject");
4452
4453         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4454                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4455                 if (modelIndex != null) {
4456                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4457                         String tableGuid =  (String)ix.values().toArray()[0];
4458                         if (tableGuid.equals(guid)) {
4459                                 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4460                                 listManager.getNoteTableModel().setData(i, Global.noteTableSubjectDatePosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4461                                 noteTableView.proxyModel.invalidate();
4462                                 return;
4463                         }
4464                 }
4465         }
4466         logger.log(logger.HIGH, "Leaving NeverNote.updateListDateCreated");
4467     }
4468         private void updateListDateChanged(String guid, QDateTime date) {
4469         logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4470
4471         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4472                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4473                 if (modelIndex != null) {
4474                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4475                         String tableGuid =  (String)ix.values().toArray()[0];
4476                         if (tableGuid.equals(guid)) {
4477                                 listManager.getNoteTableModel().setData(i, Global.noteTableSynchronizedPosition, "false");
4478                                 listManager.getNoteTableModel().setData(i, Global.noteTableChangedPosition, date.toString(Global.getDateFormat()+" " +Global.getTimeFormat()));
4479                                 return;
4480                         }
4481                 }
4482         }
4483         logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4484     }
4485     private void updateListDateChanged() {
4486         logger.log(logger.HIGH, "Entering NeverNote.updateListDateChanged");
4487         QDateTime date = new QDateTime(QDateTime.currentDateTime());
4488         updateListDateChanged(currentNoteGuid, date);
4489         logger.log(logger.HIGH, "Leaving NeverNote.updateListDateChanged");
4490     }  
4491     // Redo scroll
4492         private void scrollToCurrentGuid() {
4493         //scrollToGuid(currentNoteGuid);
4494         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
4495         if (selections.size() == 0)
4496                 return;
4497         QModelIndex index = selections.get(0);
4498         int row = selections.get(0).row();
4499         String guid = (String)index.model().index(row, Global.noteTableGuidPosition).data();
4500         scrollToGuid(guid);
4501     }
4502         // Scroll to the current GUID in tthe list.
4503     // Scroll to a particular index item
4504     private void scrollToGuid(String guid) {
4505         if (currentNote == null || guid == null) 
4506                 return;
4507         if (currentNote.isActive() && Global.showDeleted) {
4508                 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4509                         if (!listManager.getNoteIndex().get(i).isActive()) {
4510                                 currentNote = listManager.getNoteIndex().get(i);
4511                                 currentNoteGuid =  currentNote.getGuid();
4512                                 i = listManager.getNoteIndex().size();
4513                         }
4514                 }
4515         }
4516         if (!currentNote.isActive() && !Global.showDeleted) {
4517                 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
4518                         if (listManager.getNoteIndex().get(i).isActive()) {
4519                                 currentNote = listManager.getNoteIndex().get(i);
4520                                 currentNoteGuid =  currentNote.getGuid();
4521                                 i = listManager.getNoteIndex().size();
4522                         }
4523                 }
4524         }
4525         QModelIndex index; 
4526         for (int i=0; i<noteTableView.model().rowCount(); i++) {
4527                 index = noteTableView.model().index(i, Global.noteTableGuidPosition);
4528                 if (currentNoteGuid.equals(index.data())) {
4529 //                      noteTableView.selectionModel().blockSignals(true);
4530                         noteTableView.selectRow(i);
4531 //                              noteTableView.selectionModel().blockSignals(false);
4532                         noteTableView.scrollTo(index, ScrollHint.EnsureVisible);  // This should work, but it doesn't
4533                                 i=listManager.getNoteTableModel().rowCount();
4534                 }
4535         }
4536         noteTableView.repaint();
4537     }
4538     // Show/Hide columns
4539     private void showColumns() {
4540                 noteTableView.setColumnHidden(Global.noteTableCreationPosition, !Global.isColumnVisible("dateCreated"));
4541                 noteTableView.setColumnHidden(Global.noteTableChangedPosition, !Global.isColumnVisible("dateChanged"));
4542                 noteTableView.setColumnHidden(Global.noteTableSubjectDatePosition, !Global.isColumnVisible("dateSubject"));
4543                 noteTableView.setColumnHidden(Global.noteTableAuthorPosition, !Global.isColumnVisible("author"));
4544                 noteTableView.setColumnHidden(Global.noteTableSourceUrlPosition, !Global.isColumnVisible("sourceUrl"));
4545                 noteTableView.setColumnHidden(Global.noteTableTagPosition, !Global.isColumnVisible("tags"));
4546                 noteTableView.setColumnHidden(Global.noteTableNotebookPosition, !Global.isColumnVisible("notebook"));
4547                 noteTableView.setColumnHidden(Global.noteTableSynchronizedPosition, !Global.isColumnVisible("synchronized"));
4548                 noteTableView.setColumnHidden(Global.noteTableGuidPosition, !Global.isColumnVisible("guid"));
4549                 noteTableView.setColumnHidden(Global.noteTableThumbnailPosition, !Global.isColumnVisible("thumbnail"));
4550                 noteTableView.setColumnHidden(Global.noteTableTitlePosition, !Global.isColumnVisible("title"));         
4551                 noteTableView.setColumnHidden(Global.noteTablePinnedPosition, !Global.isColumnVisible("pinned")); 
4552     }
4553     // Title color has changed
4554     @SuppressWarnings("unused")
4555         private void titleColorChanged(Integer color) {
4556         logger.log(logger.HIGH, "Entering NeverNote.titleColorChanged");
4557
4558         setNoteDirty();
4559         QColor backgroundColor = new QColor();
4560                 QColor foregroundColor = new QColor(QColor.black);
4561                 backgroundColor.setRgb(color);
4562                 
4563                 if (backgroundColor.rgb() == QColor.black.rgb() || backgroundColor.rgb() == QColor.blue.rgb())
4564                         foregroundColor.setRgb(QColor.white.rgb());
4565         
4566                 if (selectedNoteGUIDs.size() == 0)
4567                         selectedNoteGUIDs.add(currentNoteGuid);
4568                 
4569         for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4570                 for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
4571                         QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
4572                         if (modelIndex != null) {
4573                                 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
4574                                 String tableGuid =  (String)ix.values().toArray()[0];
4575                                 if (tableGuid.equals(selectedNoteGUIDs.get(j))) {
4576                                         for (int k=0; k<Global.noteTableColumnCount; k++) {
4577                                                 listManager.getNoteTableModel().setData(i, k, backgroundColor, Qt.ItemDataRole.BackgroundRole);
4578                                                 listManager.getNoteTableModel().setData(i, k, foregroundColor, Qt.ItemDataRole.ForegroundRole);
4579                                                 listManager.updateNoteTitleColor(selectedNoteGUIDs.get(j), backgroundColor.rgb());
4580                                         }
4581                                         i=listManager.getNoteTableModel().rowCount();
4582                                 }
4583                         }
4584                 }
4585         }
4586         logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
4587     }
4588     // A note has been pinned or unpinned
4589         @SuppressWarnings("unused")
4590         private void notePinned() {
4591                 logger.log(logger.EXTREME, "Entering NeverNote.notePinned()");
4592                 setNoteDirty();
4593
4594         for (int j=0; j<selectedNoteGUIDs.size(); j++) {
4595                 NoteMetadata meta = listManager.getNoteMetadata().get(selectedNoteGUIDs.get(j));
4596                 boolean pinned = !meta.isPinned();
4597                 meta.setPinned(pinned);   // Toggle the pinned/unpinned 
4598                 
4599                 // Update the list & table
4600                 listManager.updateNoteMetadata(meta);   
4601                 noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
4602         }
4603                 logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
4604     }
4605     // Wide list was chosen
4606     public void narrowListView() {
4607         saveNoteColumnPositions();
4608         saveNoteIndexWidth();
4609         saveWindowState();
4610                 int sortCol = noteTableView.proxyModel.sortColumn();
4611                 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4612                 Global.setSortColumn(sortCol);
4613                 Global.setSortOrder(sortOrder);
4614
4615                 Global.setListView(Global.View_List_Narrow);
4616         
4617         menuBar.wideListView.blockSignals(true);
4618         menuBar.narrowListView.blockSignals(true);
4619         
4620         menuBar.wideListView.setChecked(false);
4621         menuBar.narrowListView.setChecked(true);
4622         
4623         menuBar.wideListView.blockSignals(false);
4624         menuBar.narrowListView.blockSignals(false);
4625         
4626         mainLeftRightSplitter.addWidget(noteTableView);
4627         // ICHANGED browserWindow → tabBrowser
4628         mainLeftRightSplitter.addWidget(tabBrowser);
4629         
4630         restoreWindowState(false);
4631         noteTableView.repositionColumns();
4632         noteTableView.resizeColumnWidths();
4633         noteTableView.resizeRowHeights();
4634         
4635         sortCol = Global.getSortColumn();
4636                 sortOrder = Global.getSortOrder();
4637                 noteTableView.proxyModel.blocked = true;
4638                 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4639                 noteTableView.proxyModel.blocked = false;
4640
4641                 
4642         showColumns();
4643         noteTableView.load(false);
4644         refreshEvernoteNote(true);
4645         scrollToCurrentGuid();
4646     }
4647     public void wideListView() {
4648                 int sortCol = noteTableView.proxyModel.sortColumn();
4649                 int sortOrder = noteTableView.proxyModel.sortOrder().value();
4650                 Global.setSortColumn(sortCol);
4651                 Global.setSortOrder(sortOrder);
4652
4653                 saveWindowState();
4654         saveNoteColumnPositions();
4655         saveNoteIndexWidth();
4656         Global.setListView(Global.View_List_Wide);
4657
4658         menuBar.wideListView.blockSignals(true);
4659         menuBar.narrowListView.blockSignals(true);
4660         
4661         menuBar.wideListView.setChecked(true);
4662         menuBar.narrowListView.setChecked(false);
4663
4664         menuBar.wideListView.blockSignals(false);
4665         menuBar.narrowListView.blockSignals(false);
4666         browserIndexSplitter.setVisible(true);
4667         browserIndexSplitter.addWidget(noteTableView);
4668                 // ICHANGED browserWindow → tabBrowser
4669                 browserIndexSplitter.addWidget(tabBrowser);
4670                 
4671         restoreWindowState(false);
4672         noteTableView.repositionColumns();
4673         noteTableView.resizeColumnWidths();
4674         noteTableView.resizeRowHeights();
4675         
4676         sortCol = Global.getSortColumn();
4677                 sortOrder = Global.getSortOrder();
4678                 noteTableView.proxyModel.blocked = true;
4679                 noteTableView.sortByColumn(sortCol, SortOrder.resolve(sortOrder));
4680                 noteTableView.proxyModel.blocked = false;
4681
4682         showColumns();
4683         noteTableView.load(false);
4684         scrollToCurrentGuid();
4685     }
4686     // Sort order for the notebook has changed   
4687     public void tableSortOrderChanged(Integer column, Integer order) {
4688         
4689         // Find what notebook (if any) is selected.  We ignore stacks & the "All Notebooks".
4690         List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
4691         if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
4692                 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
4693                 String notebook;
4694                 notebook = currentSelectedNotebook.text(2);
4695                 conn.getNotebookTable().setSortOrder(notebook, column, order);
4696         }       
4697     }
4698     
4699     //***************************************************************
4700     @SuppressWarnings("unused")
4701         private void evernoteLinkClick(String syncGuid, String locGuid) {
4702         String guid = null;
4703         if (conn.getNoteTable().guidExists(syncGuid)) {
4704                 guid = syncGuid;
4705         } else {
4706                 // If we didn't find it via the synchronized guid, look under the local guid
4707                 // Iwe don't find it there, look to see if the GUID is posted under the local GUID, but was 
4708                 // later synchronized (that causes the guid to change so we need to find the new one).
4709                 if (conn.getNoteTable().guidExists(locGuid)) 
4710                         guid = locGuid;
4711                 else
4712                         guid = conn.getNoteTable().findAlternateGuid(locGuid);
4713         }
4714                 if (guid != null) {
4715                         openExternalEditor(guid);
4716                         return;
4717                 }
4718         
4719         //If we've gotten this far, we can't find the note
4720         QMessageBox.information(this, tr("Note Not Found"), tr("Sorry, but I can't"+
4721                         " seem to find that note."));
4722     }
4723     //***************************************************************
4724     //***************************************************************
4725     //** External editor window functions                    
4726     //***************************************************************
4727     //***************************************************************
4728         private void listDoubleClick() {
4729                 saveNote();
4730         openExternalEditor(currentNoteGuid);
4731     }
4732     private void openExternalEditor(String guid) {
4733         
4734         if (externalWindows.containsKey(guid)) {
4735                 externalWindows.get(guid).raise();
4736                 return;
4737         }
4738         
4739         Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4740         // We have a new external editor to create
4741         QIcon appIcon = new QIcon(iconPath+"nevernote.png");
4742         // ICHANGED
4743         ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
4744         
4745         newBrowser.setWindowIcon(appIcon);
4746         externalWindows.put(guid, newBrowser);
4747         showEditorButtons(newBrowser.getBrowserWindow());
4748         loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4749         setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4750         newBrowser.windowClosing.connect(this, "externalWindowClosing(String)");
4751         //newBrowser.getBrowserWindow().noteSignal.titleChanged.connect(this, "externalWindowTitleEdited(String, String)");
4752         newBrowser.getBrowserWindow().noteSignal.tagsChanged.connect(this, "externalWindowTagsEdited(String, List)");
4753         newBrowser.contentsChanged.connect(this, "saveNoteExternalBrowser(String, String, Boolean, BrowserWindow)");
4754         newBrowser.getBrowserWindow().blockApplication.connect(this, "blockApplication(BrowserWindow)");
4755         newBrowser.getBrowserWindow().unblockApplication.connect(this, "unblockApplication()");
4756
4757         browserWindow.noteSignal.tagsChanged.connect(newBrowser, "updateTags(String, List)");
4758         browserWindow.noteSignal.titleChanged.connect(newBrowser, "updateTitle(String, String)");
4759         browserWindow.noteSignal.notebookChanged.connect(newBrowser, "updateNotebook(String, String)");
4760         
4761         newBrowser.show();
4762     }
4763     @SuppressWarnings({ "rawtypes", "unused" })
4764         private void externalWindowTagsEdited(String guid, List values) {
4765         StringBuffer line = new StringBuffer(100);
4766         for (int i=0; i<values.size(); i++) {
4767                 if (i>0) 
4768                         line.append(Global.tagDelimeter+" ");
4769                 line.append(values.get(i));
4770         }
4771         if (guid.equals(currentNoteGuid)) {
4772                 browserWindow.setTag(line.toString());
4773         }
4774     }
4775     @SuppressWarnings("unused")
4776         private void externalWindowClosing(String guid) {
4777                 externalWindows.remove(guid);
4778     }
4779     
4780         // ***************************************************************
4781         // ***************************************************************
4782         // ** タブウィンドウの機能
4783         // ***************************************************************
4784         // ***************************************************************
4785         @SuppressWarnings("unused")
4786         private void openNewTab() {
4787                 saveNote();
4788
4789                 // selectedNoteGUIDsをディープコピー
4790                 List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
4791                 
4792                 for (int i=0; i < copySelected.size() ; i++) {
4793                         openTabEditor(copySelected.get(i));
4794                 }
4795         }
4796         
4797         // ICHANGED 連想ノートリストから新しいタブで開く
4798         @SuppressWarnings("unused")
4799         private void openNewTabFromRNL(){
4800                 if(rensoNotePressedItemGuid != null){
4801                         String prevCurrentNoteGuid = new String(currentNoteGuid);
4802                         
4803                         saveNote();
4804                         openTabEditor(rensoNotePressedItemGuid);
4805                         
4806                         // 連想ノートリストアイテムクリック操作を記録
4807                         conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
4808                 }
4809         }
4810
4811         // ICHANGED
4812         private void openTabEditor(String guid) {
4813                 
4814                 Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
4815                 // 新しいタブエディタを作成
4816                 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4817                 showEditorButtons(newBrowser.getBrowserWindow());
4818                 
4819                 String noteTitle = note.getTitle();
4820                 int index = tabBrowser.addNewTab(newBrowser, noteTitle);
4821                 tabWindows.put(index, newBrowser);
4822                 noteDirty.put(index, false);
4823                 
4824                 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
4825                 noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
4826                 loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
4827                 // 再接続
4828                 noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
4829                 
4830                 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4831                 
4832                 // ExtendedInformationを必要があれば表示する
4833                 toggleNoteInformation();
4834                 // Sourceを必要があれば表示する
4835                 viewSource();
4836                 // EditorButtonsBarを必要があれば表示する
4837                 toggleEditorButtonBar();
4838
4839                 // 履歴記録のハッシュマップを初期化
4840                 ArrayList<String> histGuids = new ArrayList<String>();
4841                 historyGuids.put(index, histGuids);
4842                 historyPosition.put(index, 0);
4843                 fromHistory.put(index, false);
4844
4845                 // 履歴に今開いたノートを追加
4846                 histGuids.add(guid);
4847                 historyPosition.put(index, histGuids.size());
4848
4849                 tabBrowser.setCurrentIndex(index);
4850
4851                 if (guid != null && !guid.equals("")) {
4852                         if (!Global.showDeleted) { // ゴミ箱じゃなければ
4853                                 addBrowseHistory();
4854                         }
4855                 }
4856         }
4857
4858         // ICHANGED タブが閉じられた
4859         private void tabWindowClosing(int index) {
4860                 // タブが1つしかなかったら閉じない
4861                 if (tabBrowser.count() <= 1) {
4862                         return;
4863                 }
4864
4865                 TabBrowse t = (TabBrowse) tabBrowser.widget(index);
4866                 String guid = t.getBrowserWindow().getNote().getGuid();
4867                 String content = t.getBrowserWindow().getContent();
4868                 BrowserWindow browser = t.getBrowserWindow();
4869                 // ノートが変更されていたら保存
4870                 if (t.getNoteDirty()) {
4871                         saveNoteTabBrowser(guid, content, true, browser);
4872                 }
4873
4874                 // シグナル切断
4875                 browser.noteSignal.tagsChanged.disconnect();
4876                 browser.noteSignal.titleChanged.disconnect();
4877                 browser.noteSignal.noteChanged.disconnect();
4878                 browser.noteSignal.notebookChanged.disconnect();
4879                 browser.noteSignal.createdDateChanged.disconnect();
4880                 browser.noteSignal.alteredDateChanged.disconnect();
4881
4882                 // ノートを削除
4883                 tabWindows.remove(index);
4884                 tabBrowser.removeTab(index);
4885                 noteDirty.remove(index);
4886                 inkNote.remove(index);
4887                 readOnly.remove(index);
4888
4889                 // 履歴記録のハッシュマップを削除
4890                 historyGuids.remove(index);
4891                 historyPosition.remove(index);
4892                 fromHistory.remove(index);
4893                 
4894                 // タブのインデックスを更新(削除によって空いた部分を詰める)
4895                 for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
4896                         // tabWindows
4897                         TabBrowse tab = tabWindows.get(i + 1);
4898                         tabWindows.put(i, tab);
4899                         tabWindows.remove(i + 1);
4900                         // noteDirty
4901                         boolean isNoteDirty = noteDirty.get(i + 1);
4902                         noteDirty.put(i, isNoteDirty);
4903                         noteDirty.remove(i + 1);
4904                         // inkNote
4905                         boolean isInkNote = inkNote.get(i + 1);
4906                         inkNote.put(i, isInkNote);
4907                         inkNote.remove(i + 1);
4908                         // readOnly
4909                         boolean isReadOnly = readOnly.get(i + 1);
4910                         readOnly.put(i, isReadOnly);
4911                         readOnly.remove(i + 1);
4912                         // historyGuids
4913                         ArrayList<String> histGuids = historyGuids.get(i + 1);
4914                         historyGuids.put(i, histGuids);
4915                         historyGuids.remove(i + 1);
4916                         // historyPosition
4917                         int histPosition = historyPosition.get(i + 1);
4918                         historyPosition.put(i, histPosition);
4919                         historyPosition.remove(i + 1);
4920                         // fromHistory
4921                         boolean fromHist = fromHistory.get(i + 1);
4922                         fromHistory.put(i,  fromHist);
4923                         fromHistory.remove(i + 1);
4924                 }
4925                 
4926                 // タブが残り1つになったら、閉じるボタンを消す
4927                 if (tabBrowser.count() == 1) {
4928                         tabBrowser.hideTabCloseButton(0);
4929                 }
4930                 
4931                 // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
4932                 tabWindowChanged(tabBrowser.currentIndex());
4933         }
4934         
4935         @SuppressWarnings("unused")
4936         private void noteAddNewTab() {
4937                 saveNote();
4938                 
4939                 // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
4940                 TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
4941                 String prevTabGuid = null;
4942                 if (prevTab.getBrowserWindow() != null && prevTab.getBrowserWindow().getNote() != null) {
4943                         prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
4944                 }
4945                 
4946                 openEmptyTabEditor();
4947                 addNote();
4948                 
4949                 // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
4950                 if (prevTabGuid != null && !prevTabGuid.equals("")) {
4951                         TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
4952                         String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
4953                         if (addedTabGuid != null && !addedTabGuid.equals("")) {
4954                                 if (!prevTabGuid.equals(addedTabGuid)) {
4955                                         conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
4956                                 }
4957                         }
4958                 }
4959         }
4960         
4961         // ICHANGED
4962         private void openEmptyTabEditor() {
4963                 // 新しいタブエディタを作成
4964                 TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
4965                 showEditorButtons(newBrowser.getBrowserWindow());
4966                 
4967                 setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
4968                 
4969                 int index = tabBrowser.addNewTab(newBrowser, "");
4970                 tabWindows.put(index, newBrowser);
4971                 noteDirty.put(index, false);
4972                 
4973                 // ExtendedInformationを必要があれば表示する
4974                 toggleNoteInformation();
4975                 // Sourceを必要があれば表示する
4976                 viewSource();
4977                 // EditorButtonsBarを必要があれば表示する
4978                 toggleEditorButtonBar();
4979
4980                 // 履歴記録のハッシュマップを初期化
4981                 ArrayList<String> histGuids = new ArrayList<String>();
4982                 historyGuids.put(index, histGuids);
4983                 historyPosition.put(index, 0);
4984                 fromHistory.put(index, false);
4985
4986                 tabBrowser.setCurrentIndex(index);
4987         }
4988
4989     //***************************************************************
4990     //***************************************************************
4991     //** These functions deal with Note specific things
4992     //***************************************************************
4993     //***************************************************************    
4994         // ICHANGED
4995         private void setNoteDirty() {
4996                 for (String guid: selectedNoteGUIDs) {
4997                         setNoteDirty(guid);
4998                 }
4999         }
5000         
5001         // ICHANGED
5002         private void setNoteDirty(String targetGuid) {
5003                 logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
5004                 
5005                 // Find if the note is being edited externally.  If it is, update it.
5006                 if (externalWindows.containsKey(targetGuid)) {
5007                         QTextCodec codec = QTextCodec.codecForName("UTF-8");
5008                 QByteArray unicode =  codec.fromUnicode(browserWindow.getContent());
5009                         ExternalBrowse window = externalWindows.get(targetGuid);
5010                 window.getBrowserWindow().setContent(unicode);
5011                 }
5012                 
5013                 // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
5014                 Collection<Integer> tabIndexes = tabWindows.keySet();
5015                 Iterator<Integer>       indexIterator = tabIndexes.iterator();
5016                 
5017                 for (TabBrowse tab: tabWindows.values()) {
5018                         int index = indexIterator.next();
5019                         String guid = tab.getBrowserWindow().getNote().getGuid();
5020                         
5021                         QTextCodec codec = QTextCodec.codecForName("UTF-8");
5022                         QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
5023                         
5024                         if (guid.equals(guid)) {
5025                                 if (index != tabBrowser.currentIndex()) {
5026                                         TabBrowse window = tabWindows.get(index);
5027                                         window.getBrowserWindow().setContent(unicode);
5028                                 }
5029                         }
5030                 }
5031                 
5032                 // ターゲットノートがタブで開かれていて、かつDirty = trueかどうかを取得する
5033                 // If the note is dirty, then it is unsynchronized by default.
5034                 int index = -1;
5035                 boolean isNoteDirty = false;
5036                 for (TabBrowse tab: tabWindows.values()) {
5037                         if (tab.getBrowserWindow().getNote().getGuid().equals(targetGuid)) {
5038                                 index = tabBrowser.indexOf(tab);
5039                                 isNoteDirty = noteDirty.get(index);
5040                                 break;
5041                         }
5042                 }
5043                 if (isNoteDirty) {
5044                         return;
5045                 }
5046                 
5047                 // Set the note as dirty and check if its status is synchronized in the display table
5048                 // まだダーティでなく、かつタブで開かれている場合にnoteDirty = trueにする
5049                 if (index >= 0) {
5050                         noteDirty.put(index, true);
5051                 }
5052
5053                 if (listManager.getNoteMetadata().containsKey(targetGuid) &&
5054                                 listManager.getNoteMetadata().get(targetGuid).isDirty()) {
5055                                 return;
5056                 }
5057                 
5058                 // If this wasn't already marked as unsynchronized, then we need to update the table
5059                 listManager.getNoteTableModel().updateNoteSyncStatus(targetGuid, false);
5060 //      listManager.getUnsynchronizedNotes().add(targetGuid);
5061         for (int i=0; i<listManager.getNoteTableModel().rowCount(); i++) {
5062                 QModelIndex modelIndex =  listManager.getNoteTableModel().index(i, Global.noteTableGuidPosition);
5063                 if (modelIndex != null) {
5064                         SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5065                         String tableGuid =  (String)ix.values().toArray()[0];
5066                         if (tableGuid.equals(targetGuid)) {
5067                                 listManager.getNoteTableModel().proxyModel.setData(i, Global.noteTableSynchronizedPosition, "false");
5068                                 return;
5069                         }
5070                 }
5071         }
5072         
5073                 logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
5074     }
5075     @SuppressWarnings("unused")
5076         private void saveNoteExternalBrowser(String guid, String content, Boolean save, BrowserWindow browser) {
5077                 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5078         QByteArray unicode =  codec.fromUnicode(content);
5079         noteCache.remove(guid);
5080                 noteCache.put(guid, unicode.toString());
5081         if (guid.equals(currentNoteGuid)) {
5082                 // ICHANGED
5083                 int index = tabBrowser.currentIndex();
5084                 noteDirty.put(index, true);
5085                 browserWindow.setContent(unicode);
5086         } 
5087         if (save) {
5088                 thumbnailRunner.addWork("GENERATE "+ guid);
5089                 saveNote(guid, browser);
5090         }
5091         
5092     }
5093     
5094         // ICHANGED
5095         private void saveNoteTabBrowser(String guid, String content, Boolean save,
5096                         BrowserWindow browser) {
5097                 QTextCodec codec = QTextCodec.codecForName("UTF-8");
5098                 QByteArray unicode = codec.fromUnicode(content);
5099                 noteCache.remove(guid);
5100                 noteCache.put(guid, unicode.toString());
5101                 if (save) {
5102                         thumbnailRunner.addWork("GENERATE " + guid);
5103                         saveNote(guid, browser);
5104                 }
5105         }
5106         
5107     private void saveNote() {
5108         // ICHANGED
5109         // すべてのタブに対して、Dirtyを確認し、trueならセーブする
5110         Collection<Integer> dirtyIndex = noteDirty.keySet();
5111         Iterator<Integer> indexIterator = dirtyIndex.iterator();
5112         for (boolean isNoteDirty: noteDirty.values()) {
5113                 int index = indexIterator.next();
5114                 if (isNoteDirty) {
5115                         if (index < 0) {
5116                                 return;
5117                         }
5118                         BrowserWindow b = tabWindows.get(index).getBrowserWindow();
5119                         String guid = b.getNote().getGuid();
5120                         saveNote(guid, b);
5121                         thumbnailRunner.addWork("GENERATE "+ guid);
5122                         noteDirty.put(index, false);
5123                 }
5124         }
5125     }
5126     private void saveNote(String guid, BrowserWindow window) {
5127                 logger.log(logger.EXTREME, "Inside NeverNote.saveNote()");
5128                 waitCursor(true);
5129                 
5130                 logger.log(logger.EXTREME, "Saving to cache");
5131                 QTextCodec codec = QTextCodec.codecForLocale();
5132 //              QTextDecoder decoder = codec.makeDecoder();
5133                 codec = QTextCodec.codecForName("UTF-8");
5134         QByteArray unicode =  codec.fromUnicode(window.getContent());
5135                 noteCache.put(guid, unicode.toString());
5136                         
5137                 logger.log(logger.EXTREME, "updating list manager");
5138                 listManager.updateNoteContent(guid, window.getContent());
5139                 logger.log(logger.EXTREME, "Updating title");
5140                 listManager.updateNoteTitle(guid, window.getTitle());
5141                 updateListDateChanged();
5142
5143                 logger.log(logger.EXTREME, "Looking through note index for refreshed note");
5144                 for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5145                 if (listManager.getNoteIndex().get(i).getGuid().equals(guid)) {
5146                         currentNote = listManager.getNoteIndex().get(i);
5147                         i = listManager.getNoteIndex().size();
5148                 }
5149         }
5150         waitCursor(false);
5151     }
5152     // Get a note from Evernote (and put it in the browser)
5153         private void refreshEvernoteNote(boolean reload) {
5154                 logger.log(logger.HIGH, "Entering NeverNote.refreshEvernoteNote");
5155                 
5156                 if (Global.disableViewing) {
5157                         browserWindow.setEnabled(false);
5158                         return;
5159                 }
5160                 // ICHANGED
5161                 inkNote.put(tabBrowser.currentIndex(), false);
5162                 readOnly.put(tabBrowser.currentIndex(), false);
5163                 
5164                 if (Global.showDeleted || currentNoteGuid == null || currentNoteGuid.equals("")) {
5165                         readOnly.put(tabBrowser.currentIndex(), true);
5166                 }
5167                 Global.cryptCounter =0;
5168                 if (readOnly.get(tabBrowser.currentIndex())) {
5169                         browserWindow.setReadOnly(true);
5170                 }
5171                 
5172                 if (!reload)
5173                         return;
5174                 
5175                 waitCursor(true);
5176                 browserWindow.loadingData(true);
5177
5178                 currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
5179                 if (currentNote == null) {
5180                         waitCursor(false);
5181                         return;
5182                 }
5183                 
5184                 // ICHANGED
5185                 tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
5186                 
5187                 loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
5188         }
5189
5190         // ICHANGED
5191         private void loadNoteBrowserInformation(BrowserWindow browser, String guid, Note note) {
5192                 NoteFormatter   formatter = new NoteFormatter(logger, conn, tempFiles);
5193                 formatter.setNote(note, Global.pdfPreview());
5194                 formatter.setHighlight(listManager.getEnSearch());
5195                 QByteArray js;
5196                 int tabIndex = -1;
5197                 
5198                 // 対象のタブインデックスを取得
5199                 for (TabBrowse tab: tabWindows.values()) {
5200                         if (tab.getBrowserWindow() == browser) {
5201                                 tabIndex = tabBrowser.indexOf(tab);
5202                                 break;
5203                         }
5204                 }
5205                 
5206                 if (!noteCache.containsKey(guid)) {
5207                         js = new QByteArray();
5208                         // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly 
5209                         js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");               
5210                         js.append("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>");
5211                         js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
5212                         js.append("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>");
5213                         if (Global.displayRightToLeft())
5214                                 js.append("<style> body { direction:rtl; }</style>");
5215                         js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
5216                         js.append("</head>");
5217                         formatter.setNote(note, Global.pdfPreview());
5218                         js.append(formatter.rebuildNoteHTML());
5219                         js.append("</HTML>");
5220                         js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
5221                         js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
5222                         js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
5223 //              if (Global.enableHTMLEntitiesFix) {
5224 //                      browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
5225 //              } else
5226                         browser.setContent(js);
5227                         noteCache.put(guid, js.toString());
5228
5229                         if (formatter.resourceError)
5230                                 resourceErrorMessage(tabIndex);
5231                         if (formatter.formatError) {
5232                                 waitCursor(false);
5233                              QMessageBox.information(this, tr("Error"),
5234                                                 tr("NeighborNote had issues formatting this note." +
5235                                                 " To protect your data this note is being marked as read-only."));      
5236                              waitCursor(true);
5237                         }
5238                         
5239                         if (tabIndex >= 0) {
5240                                 readOnly.put(tabIndex, formatter.readOnly);
5241                                 inkNote.put(tabIndex, formatter.inkNote);
5242                         } 
5243                         
5244                         if (tabIndex >= 0 && readOnly.get(tabIndex)) {
5245                                 readOnlyCache.put(guid, true);
5246                         }
5247                         if (tabIndex >= 0 && inkNote.get(tabIndex)) {
5248                                 inkNoteCache.put(guid, true);
5249                         }
5250                         
5251                 } else {
5252                         logger.log(logger.HIGH, "Note content is being pulled from the cache");
5253                         String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
5254                         js = new QByteArray(cachedContent);
5255                         browser.setContent(js);
5256                         if (readOnlyCache.containsKey(guid) && tabIndex >= 0) {
5257                                 readOnly.put(tabIndex, true);
5258                         } else {
5259                                 readOnly.put(tabIndex, false);
5260                         }
5261                         if (inkNoteCache.containsKey(guid) && tabIndex >= 0) {
5262                                 inkNote.put(tabIndex, true);
5263                         } else {
5264                                 inkNote.put(tabIndex, false);
5265                         }
5266                 }
5267                 if (conn.getNoteTable().isThumbnailNeeded(guid)) {
5268                         thumbnailHTMLReady(guid, js, Global.calculateThumbnailZoom(js.toString()));
5269                 }
5270                 if (tabIndex >= 0 && (readOnly.get(tabIndex) || inkNote.get(tabIndex) || 
5271                                 (note.getAttributes() != null && note.getAttributes().getContentClass() != null && note.getAttributes().getContentClass() != "")))
5272                         browser.getBrowser().page().setContentEditable(false);  // We don't allow editing of ink notes
5273                 else
5274                         browser.getBrowser().page().setContentEditable(true);
5275                 if (tabIndex >= 0) {
5276                         browser.setReadOnly(readOnly.get(tabIndex));
5277                         deleteButton.setEnabled(!readOnly.get(tabIndex));
5278                         tagButton.setEnabled(!readOnly.get(tabIndex));
5279                         menuBar.noteDelete.setEnabled(!readOnly.get(tabIndex));
5280                         menuBar.noteTags.setEnabled(!readOnly.get(tabIndex));
5281                 }
5282                 browser.setNote(note);
5283                 
5284                 if (note != null && note.getNotebookGuid() != null && 
5285                                 conn.getNotebookTable().isLinked(note.getNotebookGuid())) {
5286                         deleteButton.setEnabled(false);
5287                         menuBar.notebookDeleteAction.setEnabled(false);
5288                 } else {
5289                         deleteButton.setEnabled(true);
5290                         menuBar.notebookDeleteAction.setEnabled(true);
5291                 }
5292                 
5293                 // Build a list of non-closed notebooks
5294                 List<Notebook> nbooks = new ArrayList<Notebook>();
5295                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5296                         boolean found=false;
5297                         for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5298                                 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) 
5299                                         found = true;
5300                         }
5301                         if (!found)
5302                                 nbooks.add(listManager.getNotebookIndex().get(i));
5303                 }
5304                 
5305                 browser.setTitle(note.getTitle());
5306                 browser.setTag(getTagNamesForNote(note));
5307                 browser.setAuthor(note.getAttributes().getAuthor());
5308
5309                 browser.setAltered(note.getUpdated());
5310                 browser.setCreation(note.getCreated());
5311                 if (note.getAttributes().getSubjectDate() > 0)
5312                         browser.setSubjectDate(note.getAttributes().getSubjectDate());
5313                 else
5314                         browser.setSubjectDate(note.getCreated());
5315                 browser.setUrl(note.getAttributes().getSourceURL());
5316                 
5317                 FilterEditorTags tagFilter = new FilterEditorTags(conn, logger);
5318                 List<Tag> tagList = tagFilter.getValidTags(note);
5319                 browser.setAllTags(tagList);
5320                 
5321                 browser.setCurrentTags(note.getTagNames());
5322                 // ICHANGED
5323                 for (TabBrowse tab: tabWindows.values()) {
5324                         if (tab.getBrowserWindow().getNote().getGuid().equals(guid)) {
5325                                 int index = tabBrowser.indexOf(tab);
5326                                 noteDirty.put(index, false);
5327                                 break;
5328                         }
5329                 }
5330                 
5331                 scrollToGuid(guid);
5332                 
5333                 browser.loadingData(false);
5334                 if (thumbnailViewer.isActiveWindow())
5335                         thumbnailView();
5336                 
5337                 FilterEditorNotebooks notebookFilter = new FilterEditorNotebooks(conn, logger);
5338                 browser.setNotebookList(notebookFilter.getValidNotebooks(note, listManager.getNotebookIndex()));
5339
5340                 waitCursor(false);
5341                 logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
5342         }
5343         
5344         // ICHANGED
5345         @SuppressWarnings("unused")
5346         private void toggleNoteAttributes() {
5347                 menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
5348                 toggleNoteInformation();
5349         }
5350         
5351         // Save a generated thumbnail
5352         private void toggleNoteInformation() {
5353                 logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
5354         
5355         // ICHANGED
5356                 boolean isChecked = menuBar.noteAttributes.isChecked();
5357                 
5358         for(int i = 0; i < tabBrowser.count(); i++){
5359                 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5360                 boolean isExtended = browser.isExtended();
5361                 if((isChecked && !isExtended) || (!isChecked && isExtended)){
5362                         browser.toggleInformation();
5363                 }
5364         }
5365         
5366         menuBar.noteAttributes.setChecked(browserWindow.isExtended());
5367         Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
5368         logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
5369     }
5370         
5371         // Listener triggered when a print button is pressed
5372     @SuppressWarnings("unused")
5373         private void printNote() {
5374                 logger.log(logger.HIGH, "Entering NeverNote.printNote");
5375
5376         QPrintDialog dialog = new QPrintDialog();
5377         if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
5378                 QPrinter printer = dialog.printer();
5379                 browserWindow.getBrowser().print(printer);
5380         }
5381                 logger.log(logger.HIGH, "Leaving NeverNote.printNote");
5382
5383     }
5384     // Listener triggered when the email button is pressed
5385     @SuppressWarnings("unused")
5386         private void emailNote() {
5387         logger.log(logger.HIGH, "Entering NeverNote.emailNote");
5388         
5389         if (Desktop.isDesktopSupported()) {
5390             Desktop desktop = Desktop.getDesktop();
5391             
5392             String text2 = browserWindow.getContentsToEmail();
5393             QUrl url = new QUrl("mailto:");
5394             url.addQueryItem("subject", currentNote.getTitle());
5395 //            url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
5396             url.addQueryItem("body", text2);
5397             QDesktopServices.openUrl(url);
5398         }
5399 /*            
5400             
5401             if (desktop.isSupported(Desktop.Action.MAIL)) {
5402                 URI uriMailTo = null;
5403                 try {
5404                         //String text = browserWindow.getBrowser().page().currentFrame().toPlainText();
5405                         String text = browserWindow.getContentsToEmail();
5406                         //text = "<b>" +text +"</b>";
5407                                         uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5408                                                         +"&BODY=" +text, null);
5409                                         uriMailTo = new URI("mailto", "&SUBJECT="+currentNote.getTitle()
5410                                                         +"&ATTACHMENT=d:/test.pdf", null);
5411                                         desktop.mail(uriMailTo);
5412                                 } catch (URISyntaxException e) {
5413                                         e.printStackTrace();
5414                                 } catch (IOException e) {
5415                                         e.printStackTrace();
5416                                 }
5417
5418             }
5419
5420         }     
5421  */     
5422         logger.log(logger.HIGH, "Leaving NeverNote.emailNote");
5423     }
5424         // Reindex all notes
5425     @SuppressWarnings("unused")
5426         private void fullReindex() {
5427         logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
5428         indexRunner.addWork("REINDEXALL");
5429         setMessage(tr("Database will be reindexed."));
5430         logger.log(logger.HIGH, "Leaving NeverNote.fullReindex");
5431     }
5432     // Listener when a user wants to reindex a specific note
5433     @SuppressWarnings("unused")
5434         private void reindexNote() {
5435         logger.log(logger.HIGH, "Entering NeverNote.reindexNote");
5436                 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5437                         indexRunner.addWork("REINDEXNOTE "+selectedNoteGUIDs.get(i));
5438                 }
5439                 if (selectedNotebookGUIDs.size() > 1)
5440                         setMessage(tr("Notes will be reindexed."));
5441                 else
5442                         setMessage(tr("Note will be reindexed."));
5443         logger.log(logger.HIGH, "Leaving NeverNote.reindexNote");
5444     }
5445     // Delete the note
5446     @SuppressWarnings("unused")
5447         private void deleteNote() {
5448         logger.log(logger.HIGH, "Entering NeverNote.deleteNote");
5449         if (currentNote == null) 
5450                 return;
5451         if (currentNoteGuid.equals(""))
5452                 return;
5453         String title = null;
5454         if (selectedNoteGUIDs.size() == 1)
5455                 title = conn.getNoteTable().getNote(selectedNoteGUIDs.get(0),false,false,false,false,false).getTitle();
5456
5457         // If we are deleting non-trash notes
5458         if (currentNote.isActive()) { 
5459                 if (Global.verifyDelete()) {
5460                         String msg;
5461                         if (selectedNoteGUIDs.size() > 1) {
5462                                 msg = new String(tr("Delete ") +selectedNoteGUIDs.size() +" notes?");
5463                         } else {
5464                                 if (title != null)
5465                                         msg = new String(tr("Delete note \"") +title +"\"?");
5466                                 else                            
5467                                         msg = new String(tr("Delete note selected note?"));
5468                         }
5469                         if (QMessageBox.question(this, tr("Confirmation"), msg,
5470                                         QMessageBox.StandardButton.Yes, 
5471                                         QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
5472                                         return;
5473                         }
5474                 }
5475                 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) 
5476                         selectedNoteGUIDs.add(currentNoteGuid);
5477                 closeTabs(selectedNoteGUIDs);
5478                 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5479                         listManager.deleteNote(selectedNoteGUIDs.get(i));
5480                 }
5481         } else { 
5482                 // If we are deleting from the trash.
5483                 if (Global.verifyDelete()) {
5484                         String msg;
5485                         if (selectedNoteGUIDs.size() > 1) {
5486                                 msg = new String(tr("Permanently delete ") +selectedNoteGUIDs.size() +" notes?");
5487                         } else {
5488                                 if (title != null)
5489                                 msg = new String(tr("Permanently delete note \"") +title +"\"?");
5490                                 else
5491                                         msg = new String(tr("Permanently delete note selected note?"));
5492                         }
5493                         if (QMessageBox.question(this, "Confirmation", msg,
5494                                 QMessageBox.StandardButton.Yes, 
5495                                         QMessageBox.StandardButton.No)==StandardButton.No.value()) {                                            
5496                                         return;
5497                         }
5498                 }
5499                 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) 
5500                         selectedNoteGUIDs.add(currentNoteGuid);
5501                 for (int i=selectedNoteGUIDs.size()-1; i>=0; i--) {
5502                         for (int j=listManager.getNoteTableModel().rowCount()-1; j>=0; j--) {
5503                         QModelIndex modelIndex =  listManager.getNoteTableModel().index(j, Global.noteTableGuidPosition);
5504                         if (modelIndex != null) {
5505                                 SortedMap<Integer, Object> ix = listManager.getNoteTableModel().itemData(modelIndex);
5506                                 String tableGuid =  (String)ix.values().toArray()[0];
5507                                 if (tableGuid.equals(selectedNoteGUIDs.get(i))) {
5508                                         listManager.getNoteTableModel().removeRow(j);
5509                                         j=-1;
5510                                 }
5511                         }
5512                 }
5513                         closeTabs(selectedNoteGUIDs);
5514                         listManager.expungeNote(selectedNoteGUIDs.get(i));
5515                         
5516                         // ICHANGED
5517                         conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i));
5518                         conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i));
5519                         conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i));
5520                         
5521                 }
5522         }
5523         currentNoteGuid = "";
5524         closeExternalWindows(selectedNoteGUIDs);
5525                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
5526                         menuBar.noteAddNewTab.setEnabled(false);
5527                 }
5528                 
5529         listManager.loadNotesIndex();
5530         noteIndexUpdated(false);
5531         refreshEvernoteNote(true);
5532         scrollToGuid(currentNoteGuid);
5533         logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
5534     }
5535     
5536     // 対象ノートをタブで開いていたら閉じる
5537     private void closeTabs(List<String> noteGUIDs) {
5538                 Collection<TabBrowse> tabBrowsers = tabWindows.values();
5539                 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
5540                 Collection<Integer> tabIndexes = tabWindows.keySet();
5541                 Iterator<Integer>       indexIterator = tabIndexes.iterator();
5542                 List<Integer> closeIndexes = new ArrayList<Integer>();  //イテレータ操作中に中身をいじっちゃダメなので
5543
5544                 while (tabIterator.hasNext()) {
5545                         TabBrowse tab = tabIterator.next();
5546                         int index = indexIterator.next();
5547                         String guid = tab.getBrowserWindow().getNote().getGuid();
5548                         
5549                         for(int i = 0; i < noteGUIDs.size(); i++){
5550                                 if(guid.equals(noteGUIDs.get(i))){
5551                                         closeIndexes.add(index);
5552                                 }
5553                         }
5554                 }
5555                 
5556                 for(int i = closeIndexes.size() - 1; i >= 0; i--){
5557                         tabWindowClosing(closeIndexes.get(i));
5558                 }
5559     }
5560     
5561     // 対象ノートを外部ウィンドウで開いていたら閉じる
5562     private void closeExternalWindows(List<String> noteGUIDs) {
5563                 Collection<ExternalBrowse>      windows = externalWindows.values();
5564                 Iterator<ExternalBrowse>        windowIterator = windows.iterator();
5565                 Collection<String>                      guids = externalWindows.keySet();
5566                 Iterator<String>                        guidIterator = guids.iterator();
5567                 List<ExternalBrowse>            closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
5568                 
5569                 while (windowIterator.hasNext()) {
5570                         ExternalBrowse browser = windowIterator.next();
5571                         String guid = guidIterator.next();
5572                         
5573                         for (int i = 0; i < noteGUIDs.size(); i++) {
5574                                 if (guid.equals(noteGUIDs.get(i))) {
5575                                         closeWindows.add(browser);
5576                                 }
5577                         }
5578                 }
5579                 
5580                 for (int i = closeWindows.size() - 1; i >= 0; i--) {
5581                         closeWindows.get(i).close();
5582                 }
5583     }
5584     
5585     // Add a new note
5586         private void addNote() {
5587         logger.log(logger.HIGH, "Inside NeverNote.addNote");
5588 //      browserWindow.setEnabled(true);
5589         browserWindow.setReadOnly(false);
5590         saveNote();
5591         Calendar currentTime = new GregorianCalendar();
5592         StringBuffer noteString = new StringBuffer(100);
5593         noteString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
5594                 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
5595                 "<en-note>\n");
5596         
5597         if (Global.overrideDefaultFont()) {
5598                 noteString.append("<font face=\"" +Global.getDefaultFont() +"\" >");
5599                 noteString.append("<span style=\"font-size:" +Global.getDefaultFontSize() +"pt;\">");
5600                 noteString.append("<br clear=\"none\" />\n");
5601                 noteString.append("</span>\n</font>\n");
5602         } else
5603                 noteString.append("<br clear=\"none\" />\n");
5604         noteString.append("</en-note>");
5605         
5606         Long l = new Long(currentTime.getTimeInMillis());
5607         String randint = new String(Long.toString(l));          
5608         
5609         // Find a notebook.  We first look for a selected notebook (the "All Notebooks" one doesn't count).  
5610         // Then we look
5611         // for the first non-archived notebook.  Finally, if nothing else we 
5612         // pick the first notebook in the list.
5613         String notebook = null;
5614         listManager.getNotebookIndex().get(0).getGuid();
5615         List<QTreeWidgetItem> selectedNotebook = notebookTree.selectedItems();
5616         if (selectedNotebook.size() > 0 && !selectedNotebook.get(0).text(0).equalsIgnoreCase("All Notebooks") && !selectedNotebook.get(0).text(2).equalsIgnoreCase("STACK")) {
5617                 QTreeWidgetItem currentSelectedNotebook = selectedNotebook.get(0);
5618                 notebook = currentSelectedNotebook.text(2);
5619         } else {
5620                 boolean found = false;
5621                 List<Notebook> goodNotebooks = new ArrayList<Notebook>();
5622                 for (int i=0; i<listManager.getNotebookIndex().size(); i++) {
5623                         boolean match = false;
5624                         for (int j=0; j<listManager.getArchiveNotebookIndex().size(); j++) {
5625                                 if (listManager.getArchiveNotebookIndex().get(j).getGuid().equals(listManager.getNotebookIndex().get(i).getGuid())) {
5626                                         match = true;
5627                                         j = listManager.getArchiveNotebookIndex().size();
5628                                 }
5629                         }
5630                         if (!match)
5631                                 //goodNotebooks.add(listManager.getNotebookIndex().get(i).deepCopy());
5632                                 goodNotebooks.add((Notebook)Global.deepCopy(listManager.getNotebookIndex().get(i)));
5633                 }
5634                 // Now we have a list of good notebooks, so we can look for the default
5635                 found = false;
5636                 for (int i=0; i<goodNotebooks.size(); i++) {
5637                         if (goodNotebooks.get(i).isDefaultNotebook()) {
5638                                 notebook = goodNotebooks.get(i).getGuid();
5639                                 found = true;
5640                                 i = goodNotebooks.size();
5641                         }
5642                 }
5643                 
5644                 if (goodNotebooks.size() > 0 && !found)
5645                         notebook = goodNotebooks.get(0).getGuid();
5646      
5647                 if (notebook==null)
5648                         notebook = listManager.getNotebookIndex().get(0).getGuid();             
5649         }
5650         
5651         Note newNote = new Note();
5652         newNote.setUpdateSequenceNum(0);
5653         newNote.setGuid(randint);
5654         newNote.setNotebookGuid(notebook);
5655         newNote.setTitle("Untitled Note");
5656         newNote.setContent(noteString.toString());
5657         newNote.setDeleted(0);
5658         newNote.setCreated(System.currentTimeMillis());
5659         newNote.setUpdated(System.currentTimeMillis());
5660         newNote.setActive(true);
5661         NoteAttributes na = new NoteAttributes();
5662         na.setLatitude(0.0);
5663         na.setLongitude(0.0);
5664         na.setAltitude(0.0);
5665         newNote.setAttributes(new NoteAttributes());
5666                 newNote.setTagGuids(new ArrayList<String>());
5667                 newNote.setTagNames(new ArrayList<String>());
5668         
5669         // If new notes are to be created based upon the selected tags, then we need to assign the tags
5670         if (Global.newNoteWithSelectedTags()) { 
5671                 List<QTreeWidgetItem> selections = tagTree.selectedItems();
5672                 QTreeWidgetItem currentSelection;
5673                 for (int i=0; i<selections.size(); i++) {
5674                         currentSelection = selections.get(i);
5675                         newNote.getTagGuids().add(currentSelection.text(2));
5676                         newNote.getTagNames().add(currentSelection.text(0));
5677                 }
5678         }
5679         
5680         conn.getNoteTable().addNote(newNote, true);
5681         NoteMetadata metadata = new NoteMetadata();
5682         metadata.setGuid(newNote.getGuid());
5683         metadata.setDirty(true);
5684         listManager.addNote(newNote, metadata);
5685 //      noteTableView.insertRow(newNote, true, -1);
5686         
5687         // ICHANGED
5688         String prevCurrentNoteGuid = new String(currentNoteGuid);
5689         
5690         currentNote = newNote;
5691         currentNoteGuid = currentNote.getGuid();
5692         // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
5693         // noteTableView.clearSelection();
5694         
5695         // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加
5696         if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
5697                 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
5698                         conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
5699                 }
5700         }
5701         
5702         refreshEvernoteNote(true);
5703         listManager.countNotebookResults(listManager.getNoteIndex());
5704         browserWindow.titleLabel.setFocus();
5705         browserWindow.titleLabel.selectAll();
5706 //      notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
5707         
5708         // If the window is hidden, then we want to popup this in an external window & 
5709         if (!isVisible())
5710                 listDoubleClick();
5711         waitCursor(false);
5712         logger.log(logger.HIGH, "Leaving NeverNote.addNote");
5713     }
5714     // Restore a note from the trash;
5715     @SuppressWarnings("unused")
5716         private void restoreNote() {
5717         waitCursor(true);
5718                 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) 
5719                         selectedNoteGUIDs.add(currentNoteGuid);
5720                 for (int i=0; i<selectedNoteGUIDs.size(); i++) {
5721                         listManager.restoreNote(selectedNoteGUIDs.get(i));
5722                 }
5723         currentNoteGuid = "";
5724         listManager.loadNotesIndex();
5725         noteIndexUpdated(false);
5726         waitCursor(false);
5727     }
5728     // Search a note for specific txt
5729     @SuppressWarnings("unused")
5730         private void findText() {
5731         find.show();
5732         find.setFocusOnTextField();
5733     }
5734     @SuppressWarnings("unused")
5735         private void doFindText() {
5736         browserWindow.getBrowser().page().findText(find.getText(), find.getFlags());
5737         find.setFocus();
5738     }
5739     @SuppressWarnings("unused")
5740         private void updateNoteTitle(String guid, String title) {
5741         listManager.setNoteSynchronized(guid, false);
5742         
5743         // We do this manually because if we've edited the note in an 
5744         // external window we run into the possibility of signal recursion
5745         // looping.
5746         if (guid.equals(currentNoteGuid)) {
5747                 browserWindow.titleLabel.blockSignals(true);
5748                 browserWindow.titleLabel.setText(title);
5749                 browserWindow.titleLabel.blockSignals(false);
5750         }
5751     }
5752     // Signal received that note content has changed.  Normally we just need the guid to remove
5753     // it from the cache.
5754     @SuppressWarnings("unused")
5755         private void invalidateNoteCache(String guid, String content) {
5756         noteCache.remove(guid);
5757                 refreshEvernoteNote(true);
5758     }
5759     // Signal received that a note guid has changed
5760     @SuppressWarnings("unused")
5761         private void noteGuidChanged(String oldGuid, String newGuid) {
5762         if (noteCache.containsKey(oldGuid)) {
5763                 if (!oldGuid.equals(currentNoteGuid)) {
5764                         String cache = noteCache.get(oldGuid);
5765                         noteCache.put(newGuid, cache);
5766                         noteCache.remove(oldGuid);
5767                 } else {
5768                         noteCache.remove(oldGuid);
5769                         noteCache.put(newGuid, browserWindow.getContent());
5770                 }
5771         }
5772   
5773         listManager.updateNoteGuid(oldGuid, newGuid, false);
5774         if (currentNoteGuid.equals(oldGuid)) {
5775                 if (currentNote != null)
5776                         currentNote.setGuid(newGuid);
5777                 currentNoteGuid = newGuid;
5778         }
5779                 
5780         if (externalWindows.containsKey(oldGuid)) {
5781                         ExternalBrowse b = externalWindows.get(oldGuid);
5782                         externalWindows.remove(oldGuid);
5783                         b.getBrowserWindow().getNote().setGuid(newGuid);
5784                         externalWindows.put(newGuid, b);
5785                 }
5786         
5787                 // ICHANGED
5788                 for(int i = 0; i < tabBrowser.count(); i++){
5789                         TabBrowse b = (TabBrowse)tabBrowser.widget(i);
5790                         if (b.getBrowserWindow().getNote().getGuid().equals(oldGuid)) {
5791                                 b.getBrowserWindow().getNote().setGuid(newGuid);
5792                         }
5793                 }
5794
5795         for (int i=0; i<listManager.getNoteIndex().size(); i++) {
5796                 if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
5797                         noteTableView.proxyModel.addGuid(newGuid, listManager.getNoteMetadata().get(newGuid));
5798                         i=listManager.getNoteIndex().size();
5799                 }
5800         }
5801         
5802         if (listManager.getNoteTableModel().metaData.containsKey(oldGuid)) {
5803                 NoteMetadata meta = listManager.getNoteTableModel().metaData.get(oldGuid);
5804                 listManager.getNoteTableModel().metaData.put(newGuid, meta);
5805                 listManager.getNoteTableModel().metaData.remove(oldGuid);
5806         }
5807         
5808     }
5809         
5810     // Toggle the note editor button bar
5811     // ICHANGED すべてのタブに
5812     private void toggleEditorButtonBar() {
5813         boolean isChecked = menuBar.showEditorBar.isChecked();
5814         
5815         for(int i = 0; i < tabBrowser.count(); i++){
5816                 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
5817                 boolean isVisible = browser.buttonsVisible;
5818
5819                 if (isChecked && !isVisible) {
5820                         browser.buttonsVisible = true;
5821                         showEditorButtons(browser);
5822                 } else if(!isChecked && isVisible) {
5823                         browser.hideButtons();
5824                 }
5825         }
5826
5827         Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
5828     }
5829     
5830     // Show editor buttons
5831     private void showEditorButtons(BrowserWindow browser) {
5832                 browser.buttonLayout.setVisible(true);
5833                 browser.undoAction.setVisible(false);
5834                 
5835                 browser.undoButton.setVisible(false);
5836
5837                 browser.undoAction.setVisible(Global.isEditorButtonVisible("undo"));
5838                 browser.redoAction.setVisible(Global.isEditorButtonVisible("redo"));
5839                 browser.cutAction.setVisible(Global.isEditorButtonVisible("cut"));
5840                 browser.copyAction.setVisible(Global.isEditorButtonVisible("copy"));
5841                 browser.pasteAction.setVisible(Global.isEditorButtonVisible("paste"));
5842                 browser.strikethroughAction.setVisible(Global.isEditorButtonVisible("strikethrough"));
5843                 browser.underlineAction.setVisible(Global.isEditorButtonVisible("underline"));
5844                 browser.boldAction.setVisible(Global.isEditorButtonVisible("bold"));
5845                 browser.italicAction.setVisible(Global.isEditorButtonVisible("italic"));
5846                 browser.hlineAction.setVisible(Global.isEditorButtonVisible("hline"));
5847                 browser.indentAction.setVisible(Global.isEditorButtonVisible("indent"));
5848                 browser.outdentAction.setVisible(Global.isEditorButtonVisible("outdent"));
5849                 browser.bulletListAction.setVisible(Global.isEditorButtonVisible("bulletList"));
5850                 browser.numberListAction.setVisible(Global.isEditorButtonVisible("numberList"));
5851                 browser.fontListAction.setVisible(Global.isEditorButtonVisible("font"));
5852                 browser.fontSizeAction.setVisible(Global.isEditorButtonVisible("fontSize"));
5853                 browser.fontColorAction.setVisible(Global.isEditorButtonVisible("fontColor"));
5854                 browser.fontHilightAction.setVisible(Global.isEditorButtonVisible("fontHilight"));
5855                 browser.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
5856                 browser.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
5857                 browser.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
5858                 browser.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
5859                 browser.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
5860     }
5861     private void duplicateNote(String guid) {
5862                 
5863                 Note oldNote = conn.getNoteTable().getNote(guid, true, false,false,false,true);
5864                 List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
5865                 oldNote.setContent(conn.getNoteTable().getNoteContentNoUTFConversion(guid));
5866                 oldNote.setResources(resList);
5867                 duplicateNote(oldNote);
5868         }
5869         private void duplicateNote(Note oldNote) {
5870                 waitCursor(true);
5871                 // Now that we have a good notebook guid, we need to move the conflicting note
5872                 // to the local notebook
5873                 Calendar currentTime = new GregorianCalendar();
5874                 Long l = new Long(currentTime.getTimeInMillis());
5875                 String newGuid = new String(Long.toString(l));
5876                                         
5877 //              Note newNote = oldNote.deepCopy();
5878                 Note newNote = (Note)Global.deepCopy(oldNote);
5879                 newNote.setUpdateSequenceNum(0);
5880                 newNote.setGuid(newGuid);
5881                 newNote.setDeleted(0);
5882                 newNote.setActive(true);
5883                 
5884                 /*
5885                 List<String> tagNames = new ArrayList<String>();
5886                 List<String> tagGuids = new ArrayList<String>();;
5887                 for (int i=0; i<oldNote.getTagGuidsSize(); i++) {
5888                         tagNames.add(oldNote.getTagNames().get(i));
5889                         tagGuids.add(oldNote.getTagGuids().get(i));
5890                 }
5891
5892                 // Sort note Tags to make them look nice
5893                 for (int i=0; i<tagNames.size()-1; i++) {
5894                         if (tagNames.get(i).compareTo(tagNames.get(i+1))<0) {
5895                                 String n1 = tagNames.get(i);
5896                                 String n2 = tagNames.get(i+1);
5897                                 tagNames.set(i, n2);
5898                                 tagNames.set(i+1, n1);
5899                         }
5900                 }
5901                 newNote.setTagGuids(tagGuids);
5902                 newNote.setTagNames(tagNames);
5903                 
5904                 // Add tag guids to note
5905                 */
5906                 
5907                 // Duplicate resources
5908                 List<Resource> resList = oldNote.getResources();
5909                 if (resList == null)
5910                         resList = new ArrayList<Resource>();
5911                 long prevGuid = 0;
5912                 for (int i=0; i<resList.size(); i++) {
5913                         l = prevGuid;
5914                         while (l == prevGuid) {
5915                                 currentTime = new GregorianCalendar();
5916                                 l = new Long(currentTime.getTimeInMillis());
5917                         }
5918                         prevGuid = l;
5919                         String newResGuid = new String(Long.toString(l));
5920                         resList.get(i).setNoteGuid(newGuid);
5921                         resList.get(i).setGuid(newResGuid);
5922                         resList.get(i).setUpdateSequenceNum(0);
5923                         resList.get(i).setActive(true);
5924                         conn.getNoteTable().noteResourceTable.saveNoteResource(
5925                                         (Resource)Global.deepCopy(resList.get(i)), true);
5926                 }
5927                 newNote.setResources(resList);
5928                 
5929                 // ICHANGED
5930                 // 操作履歴と除外ノートとスター付きノートも複製する
5931                 if(Global.getDuplicateRensoNote()) {
5932                         conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
5933                         conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
5934                         conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
5935                 }
5936                 
5937                 // Add note to the database
5938                 conn.getNoteTable().addNote(newNote, true);
5939                 NoteMetadata metaData = new NoteMetadata();
5940                 NoteMetadata oldMeta = listManager.getNoteMetadata().get(oldNote.getGuid());
5941                 metaData.copy(oldMeta);
5942                 metaData.setGuid(newNote.getGuid());
5943                 listManager.addNote(newNote, metaData);
5944                 noteTableView.insertRow(newNote, metaData, true, -1);
5945                 currentNoteGuid = newNote.getGuid();
5946                 currentNote = newNote;
5947                 refreshEvernoteNote(true);
5948                 listManager.countNotebookResults(listManager.getNoteIndex());
5949                 waitCursor(false);
5950                 
5951         }
5952         // View all notes
5953         @SuppressWarnings("unused")
5954         private void allNotes() {
5955                 clearAttributeFilter();
5956                 clearNotebookFilter();
5957                 clearSavedSearchFilter();
5958                 clearTrashFilter();
5959                 clearTagFilter();
5960                 searchField.clear();
5961                 if (Global.mimicEvernoteInterface) {
5962                         notebookTree.selectGuid("");
5963                 }
5964                 notebookTreeSelection();
5965                 refreshEvernoteNote(true);
5966                 
5967                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
5968                 if (!rensoNoteListDock.isEnabled()) {
5969                         rensoNoteListDock.setEnabled(true);
5970                 }
5971         }
5972         // Merge notes
5973         @SuppressWarnings("unused")
5974         private void mergeNotes() {
5975                 logger.log(logger.HIGH, "Merging notes");
5976                 waitCursor(true);
5977                 saveNote();
5978                 String masterGuid = null;
5979                 List<String> sources = new ArrayList<String>();
5980                 QModelIndex index;
5981                 for (int i=0; i<noteTableView.selectionModel().selectedRows().size(); i++) {
5982                         int r = noteTableView.selectionModel().selectedRows().get(i).row();
5983                         index = noteTableView.proxyModel.index(r, Global.noteTableGuidPosition);
5984                         SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
5985                 if (i == 0) 
5986                         masterGuid = (String)ix.values().toArray()[0];
5987                 else 
5988                         sources.add((String)ix.values().toArray()[0]);  
5989                 }
5990                 
5991                 logger.log(logger.EXTREME, "Master guid=" +masterGuid);
5992                 logger.log(logger.EXTREME, "Children count: "+sources.size());
5993                 mergeNoteContents(masterGuid, sources);
5994                 currentNoteGuid = masterGuid;
5995                 
5996                 // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ
5997                 if(Global.getMergeRensoNote()) {
5998                         for (int i = 0; i < sources.size(); i++) {
5999                                 String childGuid = sources.get(i);
6000                                 if(masterGuid != null && childGuid != null) {
6001                                         if(!masterGuid.equals(childGuid)) {
6002                                                 conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
6003                                                 conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
6004                                                 conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
6005                                         }
6006                                 }
6007                         }
6008                 }
6009                 
6010         // ICHANGED ↓↓↓ここから↓↓↓
6011                 // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
6012                 Collection<ExternalBrowse>      windows = externalWindows.values();
6013                 Iterator<ExternalBrowse>        windowIterator = windows.iterator();
6014                 Collection<String>                      guids = externalWindows.keySet();
6015                 Iterator<String>                        guidIterator = guids.iterator();
6016                 List<ExternalBrowse>            closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
6017                 
6018                 while (windowIterator.hasNext()) {
6019                         ExternalBrowse browser = windowIterator.next();
6020                         String guid = guidIterator.next();
6021                         
6022                         for (int i = 0; i < sources.size(); i++) {
6023                                 if (guid.equals(sources.get(i))) {
6024                                         closeWindows.add(browser);
6025                                 }
6026                         }
6027                 }
6028                 
6029                 for (int i = closeWindows.size() - 1; i >= 0; i--) {
6030                         closeWindows.get(i).close();
6031                 }
6032                 // ICHANGED ↑↑↑ここまで↑↑↑
6033                 
6034         // ICHANGED ↓↓↓ここから↓↓↓
6035         // マージしたノート(child)をタブで開いていたら、閉じる
6036                 Collection<TabBrowse> tabBrowsers = tabWindows.values();
6037                 Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
6038                 Collection<Integer> tabIndexes = tabWindows.keySet();
6039                 Iterator<Integer>       indexIterator = tabIndexes.iterator();
6040                 List<Integer> closeIndexes = new ArrayList<Integer>();  //イテレータ操作中に中身をいじっちゃダメなので
6041
6042                 while (tabIterator.hasNext()) {
6043                         TabBrowse tab = tabIterator.next();
6044                         int tabIndex = indexIterator.next();
6045                         String guid = tab.getBrowserWindow().getNote().getGuid();
6046                         
6047                         for(int i = 0; i < sources.size(); i++){
6048                                 if(guid.equals(sources.get(i))){
6049                                         closeIndexes.add(tabIndex);
6050                                 }
6051                         }
6052                 }
6053                 
6054                 for(int i = closeIndexes.size() - 1; i >= 0; i--){
6055                         tabWindowClosing(closeIndexes.get(i));
6056                 }
6057                 // ICHANGED ↑↑↑ここまで↑↑↑              
6058                 
6059                 noteIndexUpdated(false);
6060                 // IFIXED 
6061                 // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除
6062                 noteCache.remove(masterGuid);
6063                 
6064                 refreshEvernoteNote(true);
6065                 waitCursor(false);
6066         }
6067         private void mergeNoteContents(String targetGuid, List<String> sources) {
6068                 Note target = conn.getNoteTable().getNote(targetGuid, true, false, false, false, false);
6069                 String newContent = target.getContent();
6070                 newContent = newContent.replace("</en-note>", "<br></br>");
6071                 
6072                 for (int i=0; i<sources.size(); i++) {
6073                         Note source = conn.getNoteTable().getNote(sources.get(i), true, true, false, false, false);
6074                         if (source.isSetTitle()) {
6075                                 newContent = newContent +("<table bgcolor=\"lightgrey\"><tr><td><font size=\"6\"><b>" +source.getTitle() +"</b></font></td></tr></table>");
6076                         }
6077                         String sourceContent = source.getContent();
6078                         logger.log(logger.EXTREME, "Merging contents into note");
6079                         logger.log(logger.EXTREME, sourceContent);
6080                         logger.log(logger.EXTREME, "End of content");
6081                         int startOfNote = sourceContent.indexOf("<en-note>");
6082                         sourceContent = sourceContent.substring(startOfNote+9);
6083                         int endOfNote = sourceContent.indexOf("</en-note>");
6084                         sourceContent = sourceContent.substring(0,endOfNote);
6085                         newContent = newContent + sourceContent;
6086                         logger.log(logger.EXTREME, "New note content");
6087                         logger.log(logger.EXTREME, newContent);
6088                         logger.log(logger.EXTREME, "End of content");
6089                         for (int j=0; j<source.getResourcesSize(); j++) {
6090                                 logger.log(logger.EXTREME, "Reassigning resource: "+source.getResources().get(j).getGuid());
6091                                 Resource r = source.getResources().get(j);
6092                                 Resource newRes = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), true);
6093                                 
6094                                 Calendar currentTime = new GregorianCalendar();
6095                                 Long l = new Long(currentTime.getTimeInMillis());
6096                                                         
6097                                 long prevGuid = 0;
6098                                 l = prevGuid;
6099                                 while (l == prevGuid) {
6100                                         currentTime = new GregorianCalendar();
6101                                         l = new Long(currentTime.getTimeInMillis());
6102                                 }
6103                                 String newResGuid = new String(Long.toString(l));
6104                                 newRes.setNoteGuid(targetGuid);
6105                                 newRes.setGuid(newResGuid);
6106                                 newRes.setUpdateSequenceNum(0);
6107                                 newRes.setActive(true);
6108                                 conn.getNoteTable().noteResourceTable.saveNoteResource(newRes, true);
6109                         }
6110                 }
6111                 logger.log(logger.EXTREME, "Updating note");
6112                 conn.getNoteTable().updateNoteContent(targetGuid, newContent +"</en-note>");
6113                 for (int i=0; i<sources.size(); i++) {
6114                         logger.log(logger.EXTREME, "Deleting note " +sources.get(i));
6115                         listManager.deleteNote(sources.get(i));
6116                 }
6117                 logger.log(logger.EXTREME, "Exiting merge note");
6118         }
6119         // A resource within a note has had a guid change 
6120         @SuppressWarnings("unused")
6121         private void noteResourceGuidChanged(String noteGuid, String oldGuid, String newGuid) {
6122                 if (oldGuid != null && !oldGuid.equals(newGuid))
6123                         Global.resourceMap.put(oldGuid, newGuid);
6124         }
6125         // View a thumbnail of the note
6126         public void thumbnailView() {
6127                 
6128                 String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + currentNoteGuid + ".png");
6129                 QFile thumbnail = new QFile(thumbnailName);
6130                 if (!thumbnail.exists()) {
6131                         
6132                         QImage img = new QImage();
6133                         img.loadFromData(conn.getNoteTable().getThumbnail(currentNoteGuid));
6134                         thumbnailViewer.setThumbnail(img);
6135                 } else
6136                         thumbnailViewer.setThumbnail(thumbnailName);
6137                 if (!thumbnailViewer.isVisible()) 
6138                         thumbnailViewer.showFullScreen();
6139         }
6140         // An error happened while saving a note.  Inform the user
6141         @SuppressWarnings("unused")
6142         private void saveRunnerError(String guid, String msg) {
6143                 if (msg == null) {
6144                         String title = "*Unknown*";
6145                         for (int i=0; i<listManager.getMasterNoteIndex().size(); i++) {
6146                                 if (listManager.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
6147                                         title = listManager.getMasterNoteIndex().get(i).getTitle();
6148                                         i=listManager.getMasterNoteIndex().size();
6149                                 }
6150                         }
6151                         msg = tr("An error has happened while saving the note \"") +title+
6152                         tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process.  "+
6153                         "As a result, changes to the note may not be saved properly in the database."+
6154                         "\n\nA cached copy is being preserved so you can recover any data, but data may" +
6155                         "\nbe lost.  Please review the note to recover any critical data before restarting.");
6156                         
6157                         QMessageBox.information(this, tr("Error Saving Note"), tr(msg));
6158                 }
6159         }
6160         private void thumbnailHTMLReady(String guid, QByteArray html, Integer zoom) {
6161                 logger.log(logger.HIGH, "Entering thumnailHTMLReady()");
6162                 logger.log(logger.HIGH, "Thumbnail ready for " +guid);
6163                 // Find an idle preview object
6164                 for (int i=0; i<thumbGenerators.size(); i++) {
6165                         if (thumbGenerators.get(i).mutex.tryLock()) {
6166                                 logger.log(logger.EXTREME, "Idle generator found - loading thumbnail for " +guid);
6167                                 thumbGenerators.get(i).loadContent(guid, html, zoom);
6168                                 return;
6169                         }
6170                 } 
6171                 if (thumbGenerators.size() >= 1) {
6172                         logger.log(logger.EXTREME, "No available thumbnail generators.  Aborting " +guid);
6173                         return;
6174                 }
6175                 
6176                 logger.log(logger.EXTREME, "Creating new thumbnail generator " +guid);
6177                 Thumbnailer preview = new Thumbnailer(logger, conn, listManager, thumbnailRunner);
6178                 thumbGenerators.add(preview);
6179
6180                 if (preview.mutex.tryLock()) {
6181                         logger.log(logger.EXTREME, "Loading thumbnail for  " +guid);
6182                         preview.loadContent(guid, html, zoom);
6183                 }
6184                 logger.log(logger.HIGH, "Exiting thumnailHTMLReady()");
6185         }
6186         
6187         
6188         
6189         //**********************************************************
6190     //**********************************************************
6191     //* Online user actions
6192     //**********************************************************
6193     //**********************************************************
6194     private void setupOnlineMenu() {
6195         if (!Global.isConnected) {
6196                 menuBar.noteOnlineHistoryAction.setEnabled(false);
6197                 menuBar.selectiveSyncAction.setEnabled(false);
6198                 return;
6199         } else {
6200                 menuBar.noteOnlineHistoryAction.setEnabled(true);
6201                 menuBar.selectiveSyncAction.setEnabled(true);
6202         }
6203     }
6204     @SuppressWarnings("unused")
6205         private void viewNoteHistory() {
6206         if (currentNoteGuid == null || currentNoteGuid.equals("")) 
6207                 return;
6208         if (currentNote.getUpdateSequenceNum() == 0) {
6209                 setMessage(tr("Note has never been synchronized."));
6210                         QMessageBox.information(this, tr("Error"), tr("This note has never been sent to Evernote, so there is no history."));
6211                         return;
6212         }
6213         
6214         setMessage(tr("Getting Note History"));
6215         waitCursor(true);
6216         Note currentOnlineNote = null;
6217         versions = null;
6218         try {
6219                 if (Global.isPremium())
6220                         versions = syncRunner.localNoteStore.listNoteVersions(syncRunner.authToken, currentNoteGuid);
6221                 else
6222                         versions = new ArrayList<NoteVersionId>();
6223                 currentOnlineNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true, true, false, false);
6224                 } catch (EDAMUserException e) {
6225                         setMessage("EDAMUserException: " +e.getMessage());
6226                         return;
6227                 } catch (EDAMSystemException e) {
6228                         if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6229                                 QMessageBox.warning(this, tr("Rate limit reached"), tr("Rate limit reached.\nRetry your request in " + e.getRateLimitDuration() + " seconds."));
6230                         }
6231                         setMessage("EDAMSystemException: " +e.getMessage());
6232                         return;
6233                 } catch (EDAMNotFoundException e) {
6234                         setMessage(tr("Note not found on server."));
6235                         QMessageBox.information(this, tr("Error"), tr("This note could not be found on Evernote's servers."));
6236                         return;
6237                 } catch (TException e) {
6238                         setMessage("EDAMTransactionException: " +e.getMessage());
6239                         return;
6240                 }
6241                 
6242                 // If we've gotten this far, we have a good note.
6243                 if (historyWindow == null) {
6244                         // ICHANGED
6245                         historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
6246                         
6247                         historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
6248                         historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
6249                         historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
6250                 } else {
6251                         historyWindow.historyCombo.clear();
6252                 }
6253                 boolean isDirty = conn.getNoteTable().isNoteDirty(currentNoteGuid);
6254                 if (currentNote.getUpdateSequenceNum() != currentOnlineNote.getUpdateSequenceNum())
6255                         isDirty = true;
6256                 historyWindow.setCurrent(isDirty);
6257                 
6258                 loadHistoryWindowContent(currentOnlineNote);
6259                 historyWindow.load(versions);
6260                 setMessage(tr("History retrieved"));
6261                 waitCursor(false);
6262                 historyWindow.exec();
6263     }
6264     private Note reloadHistoryWindow(String selection) {
6265         waitCursor(true);
6266                 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
6267                 String dateTimeFormat = new String(fmt);
6268                 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
6269                 int index = -1;
6270                 int usn = 0;
6271                 
6272                 for (int i=0; i<versions.size(); i++) {
6273                         StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
6274                         if (versionDate.toString().equals(selection))
6275                                 index = i;
6276                 }
6277                 
6278                 if (index > -1 || selection.indexOf("Current") > -1) {
6279                         Note historyNote = null;
6280                         try {
6281                                 if (index > -1) {
6282                                         usn = versions.get(index).getUpdateSequenceNum();
6283                                         historyNote = syncRunner.localNoteStore.getNoteVersion(syncRunner.authToken, currentNoteGuid, usn, true, true, true);
6284                                 } else
6285                                         historyNote = syncRunner.localNoteStore.getNote(syncRunner.authToken, currentNoteGuid, true,true,true,true);
6286                         } catch (EDAMUserException e) {
6287                                 setMessage("EDAMUserException: " +e.getMessage());
6288                                 waitCursor(false);
6289                                 return null;
6290                         } catch (EDAMSystemException e) {
6291                                 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6292                                         QMessageBox.warning(this, tr("Rate limit reached"), tr("Rate limit reached.\nRetry your request in " + e.getRateLimitDuration() + " seconds."));
6293                                 }
6294                                 setMessage("EDAMSystemException: " +e.getMessage());
6295                                 waitCursor(false);
6296                                 return null;
6297                         } catch (EDAMNotFoundException e) {
6298                                 setMessage("EDAMNotFoundException: " +e.getMessage());
6299                                 waitCursor(false);
6300                                 return null;
6301                         } catch (TException e) {
6302                                 setMessage("EDAMTransactionException: " +e.getMessage());
6303                                 waitCursor(false);
6304                                 return null;
6305                         }
6306                         
6307                         waitCursor(false);
6308                         if (historyNote != null) 
6309                                 historyWindow.setContent(historyNote);
6310                         return historyNote;
6311                 }
6312                 waitCursor(false);
6313                 return null;
6314     }
6315     private void loadHistoryWindowContent(Note note) {
6316         note.setUpdateSequenceNum(0);
6317                 historyWindow.setContent(note); 
6318     }
6319     @SuppressWarnings("unused")
6320         private void restoreHistoryNoteAsNew() {
6321         setMessage(tr("Restoring as new note."));
6322         duplicateNote(reloadHistoryWindow(historyWindow.historyCombo.currentText()));
6323         setMessage(tr("Note has been restored as a new note."));
6324     }
6325     @SuppressWarnings("unused")
6326         private void restoreHistoryNote() {
6327         setMessage(tr("Restoring note."));
6328         Note n = reloadHistoryWindow(historyWindow.historyCombo.currentText());
6329         conn.getNoteTable().expungeNote(n.getGuid(), true, false);
6330         n.setActive(true);
6331         n.setDeleted(0);
6332                 for (int i=0; i<n.getResourcesSize(); i++) {
6333                         n.getResources().get(i).setActive(true);
6334                         conn.getNoteTable().noteResourceTable.saveNoteResource(n.getResources().get(i), true);
6335                 }
6336                 NoteMetadata metadata = new NoteMetadata();
6337                 metadata.setGuid(n.getGuid());
6338         listManager.addNote(n, metadata);
6339         conn.getNoteTable().addNote(n, true);
6340         refreshEvernoteNote(true);
6341         setMessage(tr("Note has been restored."));
6342     }
6343     @SuppressWarnings("unused")
6344         private void setupSelectiveSync() {
6345         
6346         // Get a list of valid notebooks
6347         List<Notebook> notebooks = null; 
6348         List<Tag> tags = null;
6349         List<LinkedNotebook> linkedNotebooks = null;
6350         try {
6351                         notebooks = syncRunner.localNoteStore.listNotebooks(syncRunner.authToken);
6352                         tags = syncRunner.localNoteStore.listTags(syncRunner.authToken);
6353                         linkedNotebooks = syncRunner.localNoteStore.listLinkedNotebooks(syncRunner.authToken);
6354                 } catch (EDAMUserException e) {
6355                         setMessage("EDAMUserException: " +e.getMessage());
6356                         return;
6357                 } catch (EDAMSystemException e) {
6358                         if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
6359                                 QMessageBox.warning(this, tr("Rate limit reached"), tr("Rate limit reached.\nRetry your request in " + e.getRateLimitDuration() + " seconds."));
6360                         }
6361                         setMessage("EDAMSystemException: " +e.getMessage());
6362                         return;
6363                 } catch (TException e) {
6364                         setMessage("EDAMTransactionException: " +e.getMessage());
6365                         return;
6366                 } catch (EDAMNotFoundException e) {
6367                         setMessage("EDAMNotFoundException: " +e.getMessage());
6368                         return;
6369                 }
6370         
6371                 // Split up notebooks into synchronized & non-synchronized
6372         List<Notebook> ignoredBooks = new ArrayList<Notebook>();
6373         List<String> dbIgnoredNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6374         
6375         for (int i=notebooks.size()-1; i>=0; i--) {
6376                 for (int j=0; j<dbIgnoredNotebooks.size(); j++) {
6377                         if (notebooks.get(i).getGuid().equalsIgnoreCase(dbIgnoredNotebooks.get(j))) {
6378                                 ignoredBooks.add(notebooks.get(i));
6379                                 j=dbIgnoredNotebooks.size();
6380                         }
6381                 }
6382         }
6383         
6384         // split up tags into synchronized & non-synchronized
6385         List<Tag> ignoredTags = new ArrayList<Tag>();
6386         List<String> dbIgnoredTags = conn.getSyncTable().getIgnoreRecords("TAG");
6387         
6388         for (int i=tags.size()-1; i>=0; i--) {
6389                 for (int j=0; j<dbIgnoredTags.size(); j++) {
6390                         if (tags.get(i).getGuid().equalsIgnoreCase(dbIgnoredTags.get(j))) {
6391                                 ignoredTags.add(tags.get(i));
6392                                 j=dbIgnoredTags.size();
6393                         }
6394                 }
6395         }
6396         
6397         // split up linked notebooks into synchronized & non-synchronized
6398         List<LinkedNotebook> ignoredLinkedNotebooks = new ArrayList<LinkedNotebook>();
6399         List<String> dbIgnoredLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6400         for (int i=linkedNotebooks.size()-1; i>=0; i--) {
6401                 String notebookGuid = linkedNotebooks.get(i).getGuid();
6402                 for (int j=0; j<dbIgnoredLinkedNotebooks.size(); j++) {
6403                         if (notebookGuid.equalsIgnoreCase(dbIgnoredLinkedNotebooks.get(j))) {
6404                                 ignoredLinkedNotebooks.add(linkedNotebooks.get(i));
6405                                 j=dbIgnoredLinkedNotebooks.size();
6406                         }
6407                 }
6408         }
6409         
6410                 IgnoreSync ignore = new IgnoreSync(notebooks, ignoredBooks, tags, ignoredTags, linkedNotebooks, ignoredLinkedNotebooks);
6411                 ignore.exec();
6412                 if (!ignore.okClicked())
6413                         return;
6414                 
6415                 waitCursor(true);
6416                 
6417                 // Clear out old notebooks & add  the new ones
6418                 List<String> oldIgnoreNotebooks = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
6419                 for (int i=0; i<oldIgnoreNotebooks.size(); i++) {
6420                         conn.getSyncTable().deleteRecord("IGNORENOTEBOOK-"+oldIgnoreNotebooks.get(i));
6421                 }
6422                 
6423                 List<String> newNotebooks = new ArrayList<String>();
6424                 for (int i=ignore.getIgnoredBookList().count()-1; i>=0; i--) {
6425                         String text = ignore.getIgnoredBookList().takeItem(i).text();
6426                         for (int j=0; j<notebooks.size(); j++) {
6427                                 if (notebooks.get(j).getName().equalsIgnoreCase(text)) {
6428                                         Notebook n = notebooks.get(j);
6429                                         conn.getSyncTable().addRecord("IGNORENOTEBOOK-"+n.getGuid(), n.getGuid());
6430                                         j=notebooks.size();
6431                                         newNotebooks.add(n.getGuid());
6432                                 }
6433                         }
6434                 }
6435                 
6436                 // Clear out old tags & add new ones
6437                 List<String> oldIgnoreTags = conn.getSyncTable().getIgnoreRecords("TAG");
6438                 for (int i=0; i<oldIgnoreTags.size(); i++) {
6439                         conn.getSyncTable().deleteRecord("IGNORETAG-"+oldIgnoreTags.get(i));
6440                 }
6441                 
6442                 List<String> newTags = new ArrayList<String>();
6443                 for (int i=ignore.getIgnoredTagList().count()-1; i>=0; i--) {
6444                         String text = ignore.getIgnoredTagList().takeItem(i).text();
6445                         for (int j=0; j<tags.size(); j++) {
6446                                 if (tags.get(j).getName().equalsIgnoreCase(text)) {
6447                                         Tag t = tags.get(j);
6448                                         conn.getSyncTable().addRecord("IGNORETAG-"+t.getGuid(), t.getGuid());
6449                                         newTags.add(t.getGuid());
6450                                         j=tags.size();
6451                                 }
6452                         }
6453                 }
6454                 
6455                 // Clear out old tags & add new ones
6456                 List<String> oldIgnoreLinkedNotebooks = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
6457                 for (int i=0; i<oldIgnoreLinkedNotebooks.size(); i++) {
6458                         conn.getSyncTable().deleteRecord("IGNORELINKEDNOTEBOOK-"+oldIgnoreLinkedNotebooks.get(i));
6459                 }
6460                 
6461                 List<String> newLinked = new ArrayList<String>();
6462                 for (int i=ignore.getIgnoredLinkedNotebookList().count()-1; i>=0; i--) {
6463                         String text = ignore.getIgnoredLinkedNotebookList().takeItem(i).text();
6464                         for (int j=0; j<linkedNotebooks.size(); j++) {
6465                                 if (linkedNotebooks.get(j).getShareName().equalsIgnoreCase(text)) {
6466                                         LinkedNotebook t = linkedNotebooks.get(j);
6467                                         conn.getSyncTable().addRecord("IGNORELINKEDNOTEBOOK-"+t.getGuid(), t.getGuid());
6468                                         newLinked.add(t.getGuid());
6469                                         j=linkedNotebooks.size();
6470                                 }
6471                         }
6472                 }
6473                 
6474                 conn.getNoteTable().expungeIgnoreSynchronizedNotes(newNotebooks, newTags, newLinked);
6475                 waitCursor(false);
6476                 refreshLists();
6477     }
6478     
6479     
6480         //**********************************************************
6481         //**********************************************************
6482         //* XML Modifying methods
6483         //**********************************************************
6484         //**********************************************************
6485         // An error has happended fetching a resource.  let the user know
6486     // ICHANGED
6487         private void resourceErrorMessage(int tabIndex) {
6488                 if (tabIndex < 0) {
6489                         return;
6490                 }
6491                 if (inkNote.get(tabIndex))
6492                         return;
6493                 waitCursor(false);
6494                 QMessageBox.information(this, tr("DOUGH!!!"), tr("Well, this is embarrassing."+
6495                 "\n\nSome attachments or images for this note appear to be missing from my database.\n"+
6496                 "In a perfect world this wouldn't happen, but it has.\n" +
6497                 "It is embarasing when a program like me, designed to save all your\n"+
6498                 "precious data, has a problem finding data.\n\n" +
6499                 "I guess life isn't fair, but I'll survive.  Somehow...\n\n" +
6500                 "In the mean time, I'm not going to let you make changes to this note.\n" +
6501                 "Don't get angry.  I'm doing it to prevent you from messing up\n"+
6502                 "this note on the Evernote servers.  Sorry."+
6503                 "\n\nP.S. You might want to re-synchronize to see if it corrects this problem.\nWho knows, you might get lucky."));
6504                 inkNote.put(tabIndex, true);
6505                 browserWindow.setReadOnly(true);
6506                 waitCursor(true);
6507         }
6508
6509         
6510         
6511         
6512         //**********************************************************
6513         //**********************************************************
6514         //* Timer functions
6515         //**********************************************************
6516         //**********************************************************
6517         // We should now do a sync with Evernote
6518         private void syncTimer() {
6519                 logger.log(logger.EXTREME, "Entering NeverNote.syncTimer()");
6520                 syncRunner.syncNeeded = true;
6521                 syncRunner.disableUploads = Global.disableUploads;
6522                 syncStart();
6523                 logger.log(logger.EXTREME, "Leaving NeverNote.syncTimer()");
6524         }
6525         private void syncStart() {
6526                 logger.log(logger.EXTREME, "Entering NeverNote.syncStart()");
6527                 saveNote();
6528                 if (!syncRunning && Global.isConnected) {
6529                         syncRunner.setConnected(true);
6530                         syncRunner.setKeepRunning(Global.keepRunning);
6531                         syncRunner.syncDeletedContent = Global.synchronizeDeletedContent();
6532                         
6533                         if (syncThreadsReady > 0) {
6534                                 thumbnailRunner.interrupt = true;
6535                                 saveNoteIndexWidth();
6536                                 saveNoteColumnPositions();
6537                                 if (syncRunner.addWork("SYNC")) {
6538                                         syncRunning = true;
6539                                         syncRunner.syncNeeded = true;
6540                                         syncThreadsReady--;
6541                                 }                               
6542                         }
6543                 }
6544                 logger.log(logger.EXTREME, "Leaving NeverNote.syncStart");
6545         }
6546         @SuppressWarnings("unused")
6547         private void syncThreadComplete(Boolean refreshNeeded) {
6548                 setMessage(tr("Finalizing Synchronization"));
6549                 syncThreadsReady++;
6550                 syncRunning = false;
6551                 syncRunner.syncNeeded = false;
6552                 synchronizeAnimationTimer.stop();
6553                 synchronizeButton.setIcon(new QIcon(iconPath+"synchronize.png"));
6554                 saveNote();
6555                 if (currentNote == null) {
6556                         currentNote = conn.getNoteTable().getNote(currentNoteGuid, false, false, false, false, true);
6557                 }
6558                 listManager.refreshNoteMetadata();
6559                 noteIndexUpdated(true);
6560                 noteTableView.selectionModel().blockSignals(true);
6561                 scrollToGuid(currentNoteGuid);
6562                 noteTableView.selectionModel().blockSignals(false);
6563                 refreshEvernoteNote(false);
6564                 scrollToGuid(currentNoteGuid);
6565                 waitCursor(false);
6566                 
6567                 // Check to see if there were any shared notebook errors
6568                 if (syncRunner.error && syncRunner.errorSharedNotebooks.size() > 0) {
6569                         String guid = syncRunner.errorSharedNotebooks.get(0);
6570                         String notebookGuid = conn.getLinkedNotebookTable().getLocalNotebookGuid(guid);
6571                         String localName = listManager.getNotebookNameByGuid(notebookGuid);
6572                         SharedNotebookSyncError syncDialog = new SharedNotebookSyncError(localName);
6573                         syncDialog.exec();
6574                         if (syncDialog.okPressed()) {
6575                                 if (syncDialog.doNothing.isChecked()) {
6576                                         syncRunner.errorSharedNotebooksIgnored.put(guid, guid);
6577                                         evernoteSync();
6578                                 }
6579                                 if (syncDialog.deleteNotebook.isChecked()) {
6580                                         conn.getNoteTable().expungeNotesByNotebook(notebookGuid, true, false);
6581                                         conn.getNotebookTable().expungeNotebook(notebookGuid, false);
6582                                         conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6583                                         conn.getLinkedNotebookTable().expungeNotebook(guid, false);
6584                                         evernoteSync();
6585                                 }
6586                                 refreshLists();
6587                                 return;
6588                         }
6589                 }
6590                 
6591                 // Finalize the synchronization
6592                 if (!syncRunner.error)
6593                         setMessage(tr("Synchronization Complete"));
6594                 else
6595                         setMessage(tr("Synchronization completed with errors.  Please check the log for details."));
6596                 logger.log(logger.MEDIUM, "Sync complete.");
6597         }   
6598         public void saveUploadAmount(long t) {
6599                 Global.saveUploadAmount(t);
6600         }
6601         public void saveUserInformation(User user) {
6602                 Global.saveUserInformation(user);
6603         }
6604         public void saveEvernoteUpdateCount(int i) {
6605                 Global.saveEvernoteUpdateCount(i);
6606         }
6607         public void refreshLists() {
6608                 logger.log(logger.EXTREME, "Entering NeverNote.refreshLists");
6609                 updateQuotaBar();
6610                 // ICHANGED
6611                 // すべてのタブのノートを調べて、Dirtyならばセーブする。その後refreshListsする。
6612                 Collection<Integer> tabIndex = noteDirty.keySet();
6613                 Iterator<Integer> indexIterator = tabIndex.iterator();
6614                 HashMap<Integer, Note> saveNotes = new HashMap<Integer, Note>();
6615                 HashMap<Integer, String> saveContents = new HashMap<Integer, String>();
6616                 for (boolean isNoteDirty: noteDirty.values()) {
6617                         int index = indexIterator.next();
6618                         if (isNoteDirty) {
6619                                 saveNotes.put(index, tabWindows.get(index).getBrowserWindow().getNote());
6620                                 saveContents.put(index, tabWindows.get(index).getBrowserWindow().getContent());
6621                         }
6622                 }
6623                 
6624                 listManager.saveUpdatedNotes(saveNotes, saveContents);
6625                 listManager.refreshLists();
6626
6627                 tagIndexUpdated(true);
6628                 notebookIndexUpdated();
6629                 savedSearchIndexUpdated();
6630                 listManager.loadNotesIndex();
6631
6632                 noteTableView.selectionModel().blockSignals(true);
6633         noteIndexUpdated(true);
6634                 noteTableView.selectionModel().blockSignals(false);
6635                 logger.log(logger.EXTREME, "Leaving NeverNote.refreshLists");
6636         }
6637
6638         
6639         @SuppressWarnings("unused")
6640         private void authTimer() {
6641         Calendar cal = Calendar.getInstance();
6642                 
6643         // If we are not connected let's get out of here
6644         if (!Global.isConnected)
6645                 return;
6646                 
6647                 // If this is the first time through, then we need to set this
6648  //             if (syncRunner.authRefreshTime == 0 || cal.getTimeInMillis() > syncRunner.authRefreshTime) 
6649 //                      syncRunner.authRefreshTime = cal.getTimeInMillis();
6650                 
6651 //              long now = new Date().getTime();
6652 //              if (now > Global.authRefreshTime && Global.isConnected) {
6653                         syncRunner.authRefreshNeeded = true;
6654                         syncStart();
6655 //              }
6656         }
6657         @SuppressWarnings("unused")
6658         private void authRefreshComplete(boolean goodSync) {
6659                 logger.log(logger.EXTREME, "Entering NeverNote.authRefreshComplete");
6660                 Global.isConnected = syncRunner.isConnected;
6661                 if (goodSync) {
6662 //                      authTimer.start((int)syncRunner.authTimeRemaining/4);
6663                         authTimer.start(1000*60*15);
6664                         logger.log(logger.LOW, "Authentication token has been renewed");
6665 //                      setMessage("Authentication token has been renewed.");
6666                 } else {
6667                         authTimer.start(1000*60*5);
6668                         logger.log(logger.LOW, "Authentication token renew has failed - retry in 5 minutes.");
6669 //                      setMessage("Authentication token renew has failed - retry in 5 minutes.");
6670                 }
6671                 logger.log(logger.EXTREME, "Leaving NeverNote.authRefreshComplete");
6672         }
6673         
6674         
6675         @SuppressWarnings("unused")
6676         private synchronized void indexTimer() {
6677                 logger.log(logger.EXTREME, "Index timer activated.  Sync running="+syncRunning);
6678                 if (syncRunning) 
6679                         return;
6680                 if (!indexDisabled && indexRunner.idle) { 
6681                         thumbnailRunner.interrupt = true;
6682                         indexRunner.addWork("SCAN");
6683                 }
6684                 logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
6685         }
6686
6687         @SuppressWarnings("unused")
6688         private void indexStarted() {
6689                 setMessage(tr("Indexing notes"));
6690         }
6691         @SuppressWarnings("unused")
6692         private void indexComplete() {
6693                 setMessage(tr("Index complete"));
6694         }
6695         @SuppressWarnings("unused")
6696         private synchronized void toggleNoteIndexing() {
6697                 logger.log(logger.HIGH, "Entering NeverNote.toggleIndexing");
6698                 indexDisabled = !indexDisabled;
6699                 if (!indexDisabled)
6700                         setMessage(tr("Indexing is now enabled."));
6701                 else
6702                         setMessage(tr("Indexing is now disabled."));
6703                 menuBar.disableIndexing.setChecked(indexDisabled);
6704         logger.log(logger.HIGH, "Leaving NeverNote.toggleIndexing");
6705     }  
6706         
6707         @SuppressWarnings("unused")
6708         private void threadMonitorCheck() {
6709                 int MAX=3;
6710                 
6711                 
6712                 boolean alive;
6713                 alive = listManager.threadCheck(Global.tagCounterThreadId);
6714                 if (!alive) {
6715                         tagDeadCount++;
6716                         if (tagDeadCount > MAX && !disableTagThreadCheck) {
6717                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died.  I recommend "+
6718                                 "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6719                                 disableTagThreadCheck = true;
6720                         }
6721                 } else
6722                         tagDeadCount=0;
6723                 
6724                 alive = listManager.threadCheck(Global.notebookCounterThreadId);
6725                 if (!alive) {
6726                         notebookThreadDeadCount++;
6727                         if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
6728                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died.  I recommend "+
6729                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6730                                 disableNotebookThreadCheck=true;
6731                         }
6732                 } else
6733                         notebookThreadDeadCount=0;
6734                 
6735                 alive = listManager.threadCheck(Global.trashCounterThreadId);
6736                 if (!alive) {
6737                         trashDeadCount++;
6738                         if (trashDeadCount > MAX && !disableTrashThreadCheck) {
6739                                 QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died.  I recommend "+
6740                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6741                                 disableTrashThreadCheck = true;
6742                         }
6743                 } else
6744                         trashDeadCount = 0;
6745
6746                 alive = listManager.threadCheck(Global.saveThreadId);
6747                 if (!alive) {
6748                         saveThreadDeadCount++;
6749                         if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
6750                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died.  I recommend "+
6751                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6752                                 disableSaveThreadCheck = true;
6753                         }
6754                 } else
6755                         saveThreadDeadCount=0;
6756
6757                 if (!syncThread.isAlive()) {
6758                         syncThreadDeadCount++;
6759                         if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
6760                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died.  I recommend "+
6761                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6762                                 disableSyncThreadCheck = true;
6763                         }
6764                 } else
6765                         syncThreadDeadCount=0;
6766
6767                 if (!indexThread.isAlive()) {
6768                         indexThreadDeadCount++;
6769                         if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
6770                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died.  I recommend "+
6771                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6772                                 disableIndexThreadCheck = true;
6773                         }
6774                 } else
6775                         indexThreadDeadCount=0;
6776
6777                 if (!rensoNoteListDock.getRensoNoteList().getEnRelatedNotesThread().isAlive()) {
6778                         enRelatedNotesThreadDeadCount++;
6779                         if (enRelatedNotesThreadDeadCount > MAX && !disableENRelatedNotesThreadCheck) {
6780                                 QMessageBox.information(this, tr("A thread has died."), tr("It appears as the Evernote Related Notes thread has died.  I recommend "+
6781                                         "checking stopping NeighborNote, saving the logs for later viewing, and restarting.  Sorry."));
6782                                 disableENRelatedNotesThreadCheck = true;
6783                         }
6784                 } else
6785                         enRelatedNotesThreadDeadCount=0;
6786         }
6787
6788         private void thumbnailTimer() {
6789                 if (Global.enableThumbnails() && !syncRunning && indexRunner.idle) {
6790                         thumbnailRunner.addWork("SCAN");
6791                 }
6792         }
6793         
6794         //**************************************************
6795         //* Backup & Restore
6796         //**************************************************
6797         @SuppressWarnings("unused")
6798         private void databaseBackup() {
6799                 QFileDialog fd = new QFileDialog(this);
6800                 fd.setFileMode(FileMode.AnyFile);
6801                 fd.setConfirmOverwrite(true);
6802                 fd.setWindowTitle(tr("Backup Database"));
6803                 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6804                 fd.setAcceptMode(AcceptMode.AcceptSave);
6805                 if (saveLastPath == null || saveLastPath.equals(""))
6806                         fd.setDirectory(System.getProperty("user.home"));
6807                 else
6808                         fd.setDirectory(saveLastPath);
6809                 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6810                         return;
6811                 }
6812                 
6813                 
6814         waitCursor(true);
6815         saveLastPath = fd.selectedFiles().get(0);
6816         saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6817         setMessage(tr("Backing up database"));
6818         saveNote();
6819 //      conn.backupDatabase(Global.getUpdateSequenceNumber(), Global.getSequenceDate());
6820         
6821         ExportData noteWriter = new ExportData(conn, true);
6822         String fileName = fd.selectedFiles().get(0);
6823
6824         if (!fileName.endsWith(".nnex"))
6825                 fileName = fileName +".nnex";
6826         noteWriter.exportData(fileName);
6827         setMessage(tr("Database backup completed."));
6828  
6829
6830         waitCursor(false);
6831         }
6832         @SuppressWarnings("unused")
6833         private void databaseRestore() {
6834                 if (QMessageBox.question(this, tr("Confirmation"),
6835                                 tr("This is used to restore a database from backups.\n" +
6836                                 "It is HIGHLY recommened that this only be used to populate\n" +
6837                                 "an empty database.  Restoring into a database that\n already has data" +
6838                                 " can cause problems.\n\nAre you sure you want to continue?"),
6839                                 QMessageBox.StandardButton.Yes, 
6840                                 QMessageBox.StandardButton.No)==StandardButton.No.value()) {
6841                                         return;
6842                                 }
6843                 
6844                 
6845                 QFileDialog fd = new QFileDialog(this);
6846                 fd.setFileMode(FileMode.ExistingFile);
6847                 fd.setConfirmOverwrite(true);
6848                 fd.setWindowTitle(tr("Restore Database"));
6849                 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6850                 fd.setAcceptMode(AcceptMode.AcceptOpen);
6851                 if (saveLastPath == null || saveLastPath.equals(""))
6852                         fd.setDirectory(System.getProperty("user.home"));
6853                 else
6854                         fd.setDirectory(saveLastPath);
6855                 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6856                         return;
6857                 }
6858                 
6859                 
6860                 waitCursor(true);
6861         saveLastPath = fd.selectedFiles().get(0);
6862         saveLastPath = saveLastPath.substring(0,saveLastPath.lastIndexOf("/"));
6863
6864                 setMessage(tr("Restoring database"));
6865         ImportData noteReader = new ImportData(conn, true);
6866         noteReader.importData(fd.selectedFiles().get(0));
6867         
6868         if (noteReader.lastError != 0) {
6869                 setMessage(noteReader.getErrorMessage());
6870                 logger.log(logger.LOW, "Restore problem: " +noteReader.lastError);
6871                 waitCursor(false);
6872                 return;
6873         }
6874         
6875         listManager.loadNoteTitleColors();
6876         refreshLists();
6877         refreshEvernoteNote(true);
6878         setMessage(tr("Database has been restored."));
6879         waitCursor(false);
6880         }
6881         @SuppressWarnings("unused")
6882         private void exportNotes() {
6883                 QFileDialog fd = new QFileDialog(this);
6884                 fd.setFileMode(FileMode.AnyFile);
6885                 fd.setConfirmOverwrite(true);
6886                 fd.setWindowTitle(tr("Backup Database"));
6887                 fd.setFilter(tr("NixNote Export (*.nnex);;All Files (*.*)"));
6888                 fd.setAcceptMode(AcceptMode.AcceptSave);
6889                 fd.setDirectory(System.getProperty("user.home"));
6890                 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6891                         return;
6892                 }
6893                 
6894                 
6895         waitCursor(true);
6896         setMessage(tr("Exporting Notes"));
6897         saveNote();
6898         
6899                 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) 
6900                         selectedNoteGUIDs.add(currentNoteGuid);
6901                 
6902         ExportData noteWriter = new ExportData(conn, false, selectedNoteGUIDs);
6903         String fileName = fd.selectedFiles().get(0);
6904
6905         if (!fileName.endsWith(".nnex"))
6906                 fileName = fileName +".nnex";
6907         noteWriter.exportData(fileName);
6908         setMessage(tr("Export completed."));
6909  
6910
6911         waitCursor(false);
6912                 
6913         }
6914         @SuppressWarnings("unused")
6915         private void importNotes() {
6916                 QFileDialog fd = new QFileDialog(this);
6917                 fd.setFileMode(FileMode.ExistingFile);
6918                 fd.setConfirmOverwrite(true);
6919                 fd.setWindowTitle(tr("Import Notes"));
6920                 fd.setFilter(tr("NixNote Export (*.nnex);;Evernote Export (*.enex);;All Files (*.*)"));
6921                 fd.setAcceptMode(AcceptMode.AcceptOpen);
6922                 if (saveLastPath == null || saveLastPath.equals(""))
6923                         fd.setDirectory(System.getProperty("user.home"));
6924                 else
6925                         fd.setDirectory(saveLastPath);
6926                 if (fd.exec() == 0 || fd.selectedFiles().size() == 0) {
6927                         return;
6928                 }
6929                 
6930                 
6931         waitCursor(true);
6932         setMessage(tr("Importing Notes"));
6933         saveNote();
6934         
6935                 if (selectedNoteGUIDs.size() == 0 && !currentNoteGuid.equals("")) 
6936                         selectedNoteGUIDs.add(currentNoteGuid);
6937                 
6938         String fileName = fd.selectedFiles().get(0);
6939 //      saveLastPath.substring(0,fileName.lastIndexOf("/"));
6940
6941         if (fileName.endsWith(".nnex")) {
6942                 ImportData noteReader = new ImportData(conn, false);
6943                 if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0) 
6944                         noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6945                 else
6946                         noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6947   
6948                 noteReader.importData(fileName);
6949         
6950                 if (noteReader.lastError != 0) {
6951                         setMessage(noteReader.getErrorMessage());
6952                         logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6953                         waitCursor(false);
6954                         return;
6955                 }
6956         } else {
6957                 if (fileName.endsWith(".enex")) {
6958                 ImportEnex noteReader = new ImportEnex(conn, false);
6959                         if (selectedNotebookGUIDs != null && selectedNotebookGUIDs.size() > 0) 
6960                                 noteReader.setNotebookGuid(selectedNotebookGUIDs.get(0));
6961                         else
6962                                 noteReader.setNotebookGuid(listManager.getNotebookIndex().get(0).getGuid());
6963   
6964                         waitCursor(false);
6965                         if (QMessageBox.question(this, tr("Confirmation"), 
6966                                         tr("Create new tags from import?"),
6967                                         QMessageBox.StandardButton.Yes, 
6968                                         QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
6969                                                                 noteReader.createNewTags = true;
6970                         } else
6971                                 noteReader.createNewTags = false;
6972                         waitCursor(true);
6973                         noteReader.importData(fileName);
6974         
6975                         if (noteReader.lastError != 0) {
6976                                 setMessage(noteReader.getErrorMessage());
6977                                 logger.log(logger.LOW, "Import problem: " +noteReader.lastError);
6978                                 waitCursor(false);
6979                                 return;
6980                         }
6981                 }
6982         }
6983         
6984         listManager.loadNoteTitleColors();
6985         refreshLists();
6986         refreshEvernoteNote(false);
6987         setMessage(tr("Notes have been imported."));
6988         waitCursor(false);
6989         
6990         setMessage(tr("Import completed."));
6991  
6992
6993         waitCursor(false);
6994                 
6995         }
6996         
6997         //**************************************************
6998         //* Duplicate a note 
6999         //**************************************************
7000         @SuppressWarnings("unused")
7001         private void duplicateNote() {
7002                 saveNote();
7003                 duplicateNote(currentNoteGuid);
7004         }
7005
7006         //**************************************************
7007         //* Action from when a user clicks Copy As URL
7008         //**************************************************
7009         @SuppressWarnings("unused")
7010         private void copyAsUrlClicked() {
7011                 QClipboard clipboard = QApplication.clipboard();
7012                 QMimeData mime = new QMimeData();
7013                 String url;
7014                 mime.setText(currentNoteGuid);
7015                 List<QUrl> urls = new ArrayList<QUrl>();
7016                 
7017                 // Start building the URL
7018                 User user = Global.getUserInformation();
7019
7020                 // Check that we have everything we need
7021                 if ((user.getShardId().equals("") || user.getId() == 0) && !Global.bypassSynchronizationWarning()) {
7022                         SynchronizationRequiredWarning warning = new SynchronizationRequiredWarning(this);
7023                         warning.exec();
7024                         if (!warning.neverSynchronize())
7025                                 return;
7026                         else {
7027                                 Global.setBypassSynchronizationWarning(true);
7028                                 user.setShardId("s0");
7029                                 user.setId(0);
7030                         }       
7031                 }
7032
7033                 
7034                 // Start building a list of URLs based upon the selected notes
7035         noteTableView.showColumn(Global.noteTableGuidPosition);
7036         
7037         List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
7038         if (!Global.isColumnVisible("guid"))
7039                 noteTableView.hideColumn(Global.noteTableGuidPosition);
7040
7041                 // Check that the note is either synchronized, or in a local notebook
7042                 for (int i=0; i<selections.size(); i++) {
7043                         QModelIndex index;
7044                         int row = selections.get(i).row();
7045                 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7046                 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7047                 String selectedGuid = (String)ix.values().toArray()[0];
7048                 
7049                 Note n = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7050                 if (n.getUpdateSequenceNum() == 0 && !conn.getNotebookTable().isNotebookLocal(n.getNotebookGuid())) {
7051                         QMessageBox.critical(this, tr("Please Synchronize") ,tr("Please either synchronize or move any " +
7052                                         "new notes to a local notebook."));
7053                         return; 
7054                 }
7055                 }
7056
7057                 // Start building the URLs
7058         for (int i=0; i<selections.size(); i++) {
7059                 QModelIndex index;
7060                         int row = selections.get(i).row();
7061                 index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
7062                 SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
7063                 String selectedGuid = (String)ix.values().toArray()[0];
7064                 mime.setText(selectedGuid);
7065                 
7066                 String lid;
7067                 String gid;
7068                 Note selectedNote = conn.getNoteTable().getNote(selectedGuid, false, false, false, false, false);
7069                 if (selectedNote.getUpdateSequenceNum() > 0) {
7070                         gid = selectedGuid;
7071                         lid = selectedGuid;
7072                 } else {
7073                         gid = "00000000-0000-0000-0000-000000000000";
7074                         lid = selectedGuid;
7075                 }
7076                 url = new String("evernote://///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
7077                                 +gid+"/"+lid +"/");
7078                 urls.add(new QUrl(url));
7079         }
7080                 mime.setUrls(urls);
7081                 clipboard.setMimeData(mime);
7082         }
7083         
7084         
7085         //**************************************************
7086         //* Folder Imports
7087         //**************************************************
7088         public void setupFolderImports() {
7089                 List<WatchFolderRecord> records = conn.getWatchFolderTable().getAll();
7090                 
7091                 if (importKeepWatcher == null)
7092                         importKeepWatcher = new QFileSystemWatcher();
7093                 if (importDeleteWatcher == null) {
7094                         importDeleteWatcher = new QFileSystemWatcher();
7095                         for (int i=0; i<records.size(); i++) {
7096                                 if (!records.get(i).keep)
7097                                         folderImportDelete(records.get(i).folder); 
7098                         }
7099                 }
7100
7101                                 
7102                 
7103 //              importKeepWatcher.addPath(records.get(i).folder.replace('\\', '/'));
7104                 for (int i=0; i<records.size(); i++) {
7105                         logger.log(logger.LOW, "Adding file monitor: " +records.get(i).folder);
7106                         if (records.get(i).keep) 
7107                                 importKeepWatcher.addPath(records.get(i).folder);
7108                         else
7109                                 importDeleteWatcher.addPath(records.get(i).folder);
7110                 }
7111                 
7112                 logger.log(logger.EXTREME, "List of directories being watched (kept)...");
7113                 List<String> monitorDelete = importKeepWatcher.directories();
7114                 for (int i=0; i<monitorDelete.size(); i++) {
7115                         logger.log(logger.EXTREME, monitorDelete.get(i));
7116                 }
7117                 logger.log(logger.EXTREME, "<end of list>");
7118                 logger.log(logger.EXTREME, "List of directories being watched (delete)...");
7119                 monitorDelete = importDeleteWatcher.directories();
7120                 for (int i=0; i<monitorDelete.size(); i++) {
7121                         logger.log(logger.EXTREME, monitorDelete.get(i));
7122                 }
7123                 logger.log(logger.EXTREME, "<end of list>");
7124                 
7125                 importKeepWatcher.directoryChanged.connect(this, "folderImportKeep(String)");
7126                 importDeleteWatcher.directoryChanged.connect(this, "folderImportDelete(String)");
7127                 
7128                 // Look at the files already there so we don't import them again if a new file is created
7129                 if (importedFiles == null) {
7130                         importedFiles = new ArrayList<String>();
7131                         for (int j=0; j<records.size(); j++) {
7132                                 QDir dir = new QDir(records.get(j).folder);
7133                                 List<QFileInfo> list = dir.entryInfoList();
7134                                 for (int k=0; k<list.size(); k++) {
7135                                         if (list.get(k).isFile())
7136                                                 importedFiles.add(list.get(k).absoluteFilePath());
7137                                 }
7138                         }
7139                 }
7140         }
7141         
7142         // Menu folderImport action triggered
7143         public void folderImport() {
7144                 List<WatchFolderRecord> recs = conn.getWatchFolderTable().getAll();
7145                 WatchFolder dialog = new WatchFolder(recs, listManager.getNotebookIndex());
7146                 dialog.exec();
7147                 if (!dialog.okClicked())
7148                         return;
7149                 
7150                 // We have some sort of update.
7151                 if (importKeepWatcher.directories().size() > 0)
7152                         importKeepWatcher.removePaths(importKeepWatcher.directories());
7153                 if (importDeleteWatcher.directories().size() > 0)
7154                         importDeleteWatcher.removePaths(importDeleteWatcher.directories());
7155                 
7156                 conn.getWatchFolderTable().expungeAll();
7157                 // Start building from the table
7158                 for (int i=0; i<dialog.table.rowCount(); i++) {
7159                         QTableWidgetItem item = dialog.table.item(i, 0);
7160                         String dir = item.text();
7161                         item = dialog.table.item(i, 1);
7162                         String notebook = item.text();
7163                         item = dialog.table.item(i, 2);
7164                         boolean keep;
7165                         if (item.text().equalsIgnoreCase("Keep"))
7166                                 keep = true;
7167                         else
7168                                 keep = false;
7169                         
7170                         String guid = conn.getNotebookTable().findNotebookByName(notebook);
7171                         conn.getWatchFolderTable().addWatchFolder(dir, guid, keep, 0);
7172                 }
7173                 setupFolderImports();
7174         }
7175         
7176         
7177         public void folderImportKeep(String dirName) throws NoSuchAlgorithmException {
7178                 logger.log(logger.LOW, "Inside folderImportKeep");
7179                 String whichOS = System.getProperty("os.name");
7180                 if (whichOS.contains("Windows")) 
7181                         dirName = dirName.replace('/','\\');
7182                 
7183                 FileImporter importer = new FileImporter(logger, conn);
7184                 
7185                 QDir dir = new QDir(dirName);
7186                 List<QFileInfo> list = dir.entryInfoList();
7187                 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7188
7189                 for (int i=0; i<list.size(); i++){
7190                         logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7191                         boolean redundant = false;
7192                         // Check if we've already imported this one or if it existed before
7193                         for (int j=0; j<importedFiles.size(); j++) {
7194                                 logger.log(logger.LOW, "redundant file list: " +list.get(i).absoluteFilePath());
7195                                 if (importedFiles.get(j).equals(list.get(i).absoluteFilePath()))
7196                                         redundant = true;
7197                         }
7198                         
7199                         logger.log(logger.LOW, "Checking if redundant: " +redundant);
7200                         if (!redundant) {
7201                                 importer.setFileInfo(list.get(i));
7202                                 importer.setFileName(list.get(i).absoluteFilePath());
7203                         
7204                         
7205                                 logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7206                                 logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7207                                 if (list.get(i).isFile() && importer.isValidType()) {
7208                         
7209                                         if (!importer.importFile()) {
7210                                                 // If we can't get to the file, it is probably locked.  We'll try again later.
7211                                                 logger.log(logger.LOW, "Unable to save externally edited file.  Saving for later.");
7212                                                 importFilesKeep.add(list.get(i).absoluteFilePath());
7213                                         } else {
7214
7215                                                 Note newNote = importer.getNote();
7216                                                 newNote.setNotebookGuid(notebook);
7217                                                 newNote.setTitle(dir.at(i));
7218                                                 NoteMetadata metadata = new NoteMetadata();
7219                                                 metadata.setDirty(true);
7220                                                 metadata.setGuid(newNote.getGuid());
7221                                                 listManager.addNote(newNote, metadata);
7222                                                 conn.getNoteTable().addNote(newNote, true);
7223                                                 noteTableView.insertRow(newNote, metadata, true, -1);
7224                                                 listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7225                                                 listManager.countNotebookResults(listManager.getNoteIndex());
7226                                                 importedFiles.add(list.get(i).absoluteFilePath());
7227                                         }
7228                                 }
7229                         }
7230                 }
7231         
7232         
7233         }
7234         
7235         public void folderImportDelete(String dirName) {
7236                 logger.log(logger.LOW, "Inside folderImportDelete");
7237                 String whichOS = System.getProperty("os.name");
7238                 if (whichOS.contains("Windows")) 
7239                         dirName = dirName.replace('/','\\');
7240                 
7241                 FileImporter importer = new FileImporter(logger, conn);
7242                 QDir dir = new QDir(dirName);
7243                 List<QFileInfo> list = dir.entryInfoList();
7244                 String notebook = conn.getWatchFolderTable().getNotebook(dirName);
7245                 
7246                 for (int i=0; i<list.size(); i++){
7247                         logger.log(logger.LOW, "File found: " +list.get(i).fileName());
7248                         importer.setFileInfo(list.get(i));
7249                         importer.setFileName(list.get(i).absoluteFilePath());
7250                         
7251                         logger.log(logger.LOW, "File importing is a file: " +list.get(i).isFile());
7252                         logger.log(logger.LOW, "File importing is a valid: " +importer.isValidType());
7253                         if (list.get(i).isFile() && importer.isValidType()) {
7254                 
7255                                 if (!importer.importFile()) {
7256                                         // If we can't get to the file, it is probably locked.  We'll try again later.
7257                                         logger.log(logger.LOW, "Unable to save externally edited file.  Saving for later.");
7258                                         importFilesKeep.add(list.get(i).absoluteFilePath());
7259                                 } else {
7260                 
7261                                         Note newNote = importer.getNote();
7262                                         newNote.setNotebookGuid(notebook);
7263                                         newNote.setTitle(dir.at(i));
7264                                         NoteMetadata metadata = new NoteMetadata();
7265                                         metadata.setDirty(true);
7266                                         metadata.setGuid(newNote.getGuid());
7267                                         listManager.addNote(newNote, metadata);
7268                                         conn.getNoteTable().addNote(newNote, true);
7269                                         noteTableView.insertRow(newNote, metadata, true, -1);
7270                                         listManager.updateNoteContent(newNote.getGuid(), importer.getNoteContent());
7271                                         listManager.countNotebookResults(listManager.getNoteIndex());
7272                                         dir.remove(dir.at(i));
7273                                 }
7274                         }
7275                 }
7276         }
7277         
7278         
7279         //**************************************************
7280         //* External events
7281         //**************************************************
7282         private void externalFileEdited(String fileName) throws NoSuchAlgorithmException {
7283                 logger.log(logger.HIGH, "Entering exernalFileEdited");
7284
7285                 // Strip URL prefix and base dir path
7286                 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
7287                 String name = fileName.replace(dPath, "");
7288                 int pos = name.lastIndexOf('.');
7289                 String guid = name;
7290                 if (pos > -1) {
7291                         guid = guid.substring(0,pos);
7292                 }
7293                 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
7294                 if (pos > -1) {
7295                         guid = name.substring(0, pos);
7296                 }
7297                 
7298                 QFile file = new QFile(fileName);
7299         if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
7300                 // If we can't get to the file, it is probably locked.  We'll try again later.
7301                 logger.log(logger.LOW, "Unable to save externally edited file.  Saving for later.");
7302                 externalFiles.add(fileName);
7303                 return;
7304                 }
7305                 QByteArray binData = file.readAll();
7306         file.close();
7307         if (binData.size() == 0) {
7308                 // If we can't get to the file, it is probably locked.  We'll try again later.
7309                 logger.log(logger.LOW, "Unable to save externally edited file.  Saving for later.");
7310                 externalFiles.add(fileName);
7311                 return;
7312         }
7313         
7314         Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
7315         if (r==null)
7316                 r = conn.getNoteTable().noteResourceTable.getNoteResource(Global.resourceMap.get(guid), true);
7317         if (r == null || r.getData() == null || r.getData().getBody() == null)
7318                 return;
7319         String oldHash = Global.byteArrayToHexString(r.getData().getBodyHash());
7320         MessageDigest md = MessageDigest.getInstance("MD5");
7321                 md.update(binData.toByteArray());
7322                 byte[] hash = md.digest();
7323         String newHash = Global.byteArrayToHexString(hash);
7324         if (r.getNoteGuid().equalsIgnoreCase(currentNoteGuid)) {
7325                 updateResourceContentHash(browserWindow, r.getGuid(), oldHash, newHash);
7326         }
7327         if (externalWindows.containsKey(r.getNoteGuid())) {
7328                 updateResourceContentHash(externalWindows.get(r.getNoteGuid()).getBrowserWindow(), 
7329                                 r.getGuid(), oldHash, newHash);
7330         }
7331         conn.getNoteTable().updateResourceContentHash(r.getNoteGuid(), oldHash, newHash);
7332         Data data = r.getData();
7333         data.setBody(binData.toByteArray());
7334         data.setBodyHash(hash);
7335         logger.log(logger.LOW, "externalFileEdited: " +data.getSize() +" bytes");
7336         r.setData(data);
7337         conn.getNoteTable().noteResourceTable.updateNoteResource(r,true);
7338         
7339         if (r.getNoteGuid().equals(currentNoteGuid)) {
7340                         QWebSettings.setMaximumPagesInCache(0);
7341                         QWebSettings.setObjectCacheCapacities(0, 0, 0);
7342                         refreshEvernoteNote(true);
7343                         browserWindow.getBrowser().triggerPageAction(WebAction.Reload);
7344         }
7345         
7346         if (externalWindows.containsKey(r.getNoteGuid())) {
7347                 QWebSettings.setMaximumPagesInCache(0);
7348                         QWebSettings.setObjectCacheCapacities(0, 0, 0);
7349                         externalWindows.get(r.getNoteGuid()).getBrowserWindow().getBrowser().triggerPageAction(WebAction.Reload);
7350                         
7351         }
7352         
7353                 logger.log(logger.HIGH, "Exiting externalFielEdited");
7354         }
7355         // This is a timer event that tries to save any external files that were edited.  This
7356         // is only needed if we couldn't save a file earlier.
7357         public void externalFileEditedSaver() {
7358                 for (int i=externalFiles.size()-1; i>=0; i--) {
7359                         try {
7360                                 logger.log(logger.MEDIUM, "Trying to save " +externalFiles.get(i));
7361                                 externalFileEdited(externalFiles.get(i));
7362                                 externalFiles.remove(i);
7363                         } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7364                 }
7365                 for (int i=0; i<importFilesKeep.size(); i++) {
7366                         try {
7367                                 logger.log(logger.MEDIUM, "Trying to save " +importFilesKeep.get(i));
7368                                 folderImportKeep(importFilesKeep.get(i));
7369                                 importFilesKeep.remove(i);
7370                         } catch (NoSuchAlgorithmException e) {e.printStackTrace();}
7371                 }
7372                 for (int i=0; i<importFilesDelete.size(); i++) {
7373                         logger.log(logger.MEDIUM, "Trying to save " +importFilesDelete.get(i));
7374                         folderImportDelete(importFilesDelete.get(i));
7375                         importFilesDelete.remove(i);
7376                 }
7377         }
7378         
7379         
7380         
7381         
7382         // If an attachment on the current note was edited, we need to update the current notes's hash
7383         // Update a note content's hash.  This happens if a resource is edited outside of NN
7384         public void updateResourceContentHash(BrowserWindow browser, String guid, String oldHash, String newHash) {
7385                 int position = browserWindow.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=");
7386                 int endPos;
7387                 for (;position>-1;) {
7388                         endPos = browser.getContent().indexOf(">", position+1);
7389                         String oldSegment = browser.getContent().substring(position,endPos);
7390                         int hashPos = oldSegment.indexOf("hash=\"");
7391                         int hashEnd = oldSegment.indexOf("\"", hashPos+7);
7392                         String hash = oldSegment.substring(hashPos+6, hashEnd);
7393                         if (hash.equalsIgnoreCase(oldHash)) {
7394                                 String newSegment = oldSegment.replace(oldHash, newHash);
7395                                 String content = browser.getContent().substring(0,position) +
7396                                                  newSegment +
7397                                                  browser.getContent().substring(endPos);
7398                                 browser.setContent(new QByteArray(content));;
7399                         }
7400                         
7401                         position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
7402                 }
7403         }
7404
7405
7406         //*************************************************
7407         //* Minimize to tray
7408         //*************************************************
7409         @Override
7410         public void changeEvent(QEvent e) {
7411                 if (e.type() == QEvent.Type.WindowStateChange) {
7412                         if (QSystemTrayIcon.isSystemTrayAvailable()) {
7413                                 if (isMinimized() && (Global.showTrayIcon() || Global.showTrayIcon())) {
7414                                         e.accept();
7415                                         QTimer.singleShot(10, this, "hide()");
7416                                         return;
7417                                 }
7418                                 if (isMaximized())
7419                                         windowMaximized = true;
7420                                 else 
7421                                         windowMaximized = false;
7422                         }
7423                 }
7424         }
7425         
7426         //*************************************************
7427         //* Check database userid & passwords
7428         //*************************************************
7429         private static boolean databaseCheck(String url,String userid, String userPassword, String cypherPassword) {
7430                         Connection connection;
7431                         
7432                         try {
7433                                 Class.forName("org.h2.Driver");
7434                         } catch (ClassNotFoundException e1) {
7435                                 e1.printStackTrace();
7436                                 System.exit(16);
7437                         }
7438
7439                         try {
7440                                 String passwordString = null;
7441                                 if (cypherPassword==null || cypherPassword.trim().equals(""))
7442                                         passwordString = userPassword;
7443                                 else
7444                                         passwordString = cypherPassword+" "+userPassword;
7445                                 connection = DriverManager.getConnection(url,userid,passwordString);
7446                         } catch (SQLException e) {
7447                                 return false;
7448                         }
7449                         try {
7450                                 connection.close();
7451                         } catch (SQLException e) {
7452                                 e.printStackTrace();
7453                         }
7454                         return true;
7455         }
7456
7457         //*************************************************
7458         //* View / Hide source HTML for a note
7459         //*************************************************
7460         public void viewSource() {
7461                 // ICHANGED すべてのタブに対して
7462         for(int i = 0; i < tabBrowser.count(); i++){
7463                 BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
7464                 browser.showSource(menuBar.viewSource.isChecked());
7465         }
7466         }
7467         //*************************************************
7468         // Block the program.  This is used for things  
7469         // like async web calls.
7470         //*************************************************
7471         @SuppressWarnings("unused")
7472         private void blockApplication(BrowserWindow b) {
7473                 // Block all signals
7474                 waitCursor(true);
7475                 blockSignals(true);
7476                 
7477                 blockTimer = new QTimer();
7478                 blockTimer.setSingleShot(true);
7479                 blockTimer.setInterval(15000);
7480                 blockTimer.timeout.connect(this, "unblockApplication()");
7481                 blockingWindow  = b;
7482                 blockTimer.start();
7483         }
7484         
7485         @SuppressWarnings("unused")
7486         private void unblockApplication() {
7487                 waitCursor(false);
7488                 if (blockingWindow != null && new GregorianCalendar().getTimeInMillis() > blockingWindow.unblockTime && blockingWindow.unblockTime != -1) {
7489                         QMessageBox.critical(null, tr("No Response from CodeCogs") ,tr("Unable to contact CodeCogs for LaTeX formula."));
7490                         blockingWindow.unblockTime = -1;
7491                         blockingWindow.awaitingHttpResponse = false;
7492                 }
7493                 blockingWindow = null;
7494                 blockSignals(false);
7495         }
7496         
7497         // ICHANGED
7498         // タブが変更された
7499         private void tabWindowChanged(int index) {
7500                 if (index < 0 || index >= tabBrowser.count()) {
7501                         return;
7502                 }
7503                 
7504                 saveNote();
7505
7506                 TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
7507                 if (tab.getBrowserWindow().getNote() != null) {
7508                         currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
7509                         currentNote = tab.getBrowserWindow().getNote();
7510                 } else {
7511                         currentNoteGuid = "";
7512                         currentNote = null;
7513                 }
7514
7515                 // 選択ノートを更新
7516                 selectedNoteGUIDs.clear();
7517                 if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
7518                         selectedNoteGUIDs.add(currentNoteGuid);
7519                 }
7520                 
7521                 // browserWindowを更新
7522                 browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
7523                 browserWindow.focusLost.disconnect(this, "saveNote()");
7524                 browserWindow = tab.getBrowserWindow();
7525                 browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
7526                 browserWindow.focusLost.connect(this, "saveNote()");
7527                 // メニューバーのボタンを新しいbrowserWindowに合わせる
7528                 menuBar.refreshTargetWindow();
7529                 
7530                 // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
7531                 boolean nextIsActive;
7532                 if (tab.getBrowserWindow().getNote() != null) {
7533                         nextIsActive = tab.getBrowserWindow().getNote().isActive();
7534                 } else {
7535                         nextIsActive = true;
7536                 }
7537                 if (Global.showDeleted && nextIsActive) {
7538                         switchNoteTable(false);
7539                 } else if (!Global.showDeleted && !nextIsActive) {
7540                         switchNoteTable(true);
7541                 }
7542
7543                 // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7544                 noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7545                 scrollToGuid(currentNoteGuid);
7546                 // 再接続
7547                 noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7548
7549                 menuBar.noteDuplicateAction.setEnabled(true);
7550                 menuBar.noteOnlineHistoryAction.setEnabled(true);
7551                 menuBar.noteMergeAction.setEnabled(true);
7552                 
7553                 if (Global.showDeleted) {
7554                         menuBar.noteDuplicateAction.setEnabled(false);
7555                 }
7556                 if (!Global.isConnected) {
7557                         menuBar.noteOnlineHistoryAction.setEnabled(false);
7558                 }
7559                 menuBar.noteMergeAction.setEnabled(false);
7560                 try {
7561                         int row = noteTableView.selectionModel().selectedRows().get(0).row();
7562                         if (row == 0)
7563                                 upButton.setEnabled(false);
7564                         else
7565                                 upButton.setEnabled(true);
7566                         if (row < listManager.getNoteTableModel().rowCount() - 1)
7567                                 downButton.setEnabled(true);
7568                         else
7569                                 downButton.setEnabled(false);
7570                 } catch (Exception e) {
7571                         upButton.setEnabled(false);
7572                         downButton.setEnabled(false);
7573                 }
7574                 
7575                 int currentIndex = tabBrowser.currentIndex();
7576                 ArrayList<String> histGuids = historyGuids.get(currentIndex);
7577                 int histPosition = historyPosition.get(currentIndex);
7578
7579                 // prev, nextボタンの有効・無効化
7580                 nextButton.setEnabled(true);
7581                 prevButton.setEnabled(true);
7582
7583                 if (histPosition <= 1){
7584                         prevButton.setEnabled(false);
7585                 }
7586                 if (histPosition == histGuids.size()){
7587                         nextButton.setEnabled(false);
7588                 }
7589
7590                 refreshEvernoteNote(true);
7591
7592                 // 連想ノートリストを更新
7593                 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7594         }
7595         
7596         // ICHANGD
7597         // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
7598         private void switchNoteTable(boolean toDeleted) {
7599         clearNotebookFilter();
7600         clearTagFilter();
7601         clearAttributeFilter();
7602         clearSavedSearchFilter();
7603         
7604         listManager.getSelectedNotebooks().clear();
7605         listManager.getSelectedTags().clear();
7606         listManager.setSelectedSavedSearch("");
7607     
7608         // toggle the add buttons
7609         newButton.setEnabled(!newButton.isEnabled());
7610         menuBar.noteAdd.setEnabled(newButton.isEnabled());
7611         menuBar.noteAddNewTab.setEnabled(newButton.isEnabled());
7612                 if (currentNoteGuid == null || currentNoteGuid.equals("")) {
7613                         menuBar.noteAddNewTab.setEnabled(false);
7614                 }
7615         menuBar.noteAdd.setVisible(true);
7616         
7617         if (!toDeleted) {       // 生存ノートテーブルへ
7618                 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7619                 trashTree.clearSelection();
7620                 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7621                 Global.showDeleted = false;
7622                 menuBar.noteRestoreAction.setEnabled(false);
7623                 menuBar.noteRestoreAction.setVisible(false);
7624                 // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
7625                 rensoNoteListDock.setEnabled(true);
7626         } else {        // ゴミ箱へ
7627                 trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
7628                 trashTree.setCurrentItem(trashTree.getTrashItem());
7629                 trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
7630                 Global.showDeleted = true;
7631                 menuBar.noteRestoreAction.setEnabled(true);
7632                 menuBar.noteRestoreAction.setVisible(true);
7633                 // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
7634                 rensoNoteListDock.setEnabled(false);
7635         }
7636         
7637         listManager.loadNotesIndex();
7638         // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
7639         noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
7640         noteIndexUpdated(false);
7641         // 再接続
7642         noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
7643         
7644         browserWindow.setReadOnly(!newButton.isEnabled());
7645         }
7646
7647         // ICHANGED
7648         // ユーザが連想ノートリストのアイテムを選択した時の処理
7649         @SuppressWarnings("unused")
7650         private void rensoNoteItemPressed(QListWidgetItem current) {
7651                 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
7652
7653                 rensoNotePressedItemGuid = rensoNoteListDock.getRensoNoteList().getNoteGuid(current);
7654                 
7655                 // 右クリックだったら終了
7656                 if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
7657                         return;
7658                 }
7659                 
7660                 saveNote();
7661
7662                 String prevCurrentNoteGuid = new String(currentNoteGuid);
7663                 
7664                 for (int i = 0; i < noteTableView.model().rowCount(); i++) {
7665                         QModelIndex modelIndex = noteTableView.model().index(i,
7666                                         Global.noteTableGuidPosition);
7667                         if (modelIndex != null) {
7668                                 SortedMap<Integer, Object> ix = noteTableView.model().itemData(
7669                                                 modelIndex);
7670                                 String tableGuid = (String) ix.values().toArray()[0];
7671                                 if (tableGuid.equals(rensoNotePressedItemGuid)) {
7672                                         noteTableView.selectRow(i);
7673                                         break;
7674                                 }
7675                         }
7676                 }
7677                 
7678                 // 連想ノートリストアイテムクリック操作を記録
7679                 conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
7680
7681                 logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
7682         }
7683         
7684         // ICHANGED
7685         // 関連ノートリストからノートを除外する
7686         @SuppressWarnings("unused")
7687         private void excludeNote() {
7688                 if (rensoNotePressedItemGuid != null) {
7689                         saveNote();
7690                         excludeNote(rensoNotePressedItemGuid);
7691                 }
7692         }
7693         
7694         // ICHANGED
7695         // 関連ノートリストからノートを除外する
7696         private void excludeNote(String guid) {
7697                 if (Global.verifyExclude()) {
7698                         String msg;
7699                         Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
7700                         String title = note.getTitle();
7701                         if (title != null) {
7702                                 msg = new String(tr("Exclude note \"") +title +"\"?");
7703                         } else {                                
7704                                 msg = new String(tr("Exclude note selected note?"));
7705                         }
7706                         
7707                         if (QMessageBox.question(this, tr("Confirmation"), msg,
7708                                         QMessageBox.StandardButton.Yes, 
7709                                         QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
7710                                         return;
7711                         }
7712                 }
7713                 
7714                 // Historyデータベースから除外するノートのデータを削除
7715                 conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
7716                 
7717                 // 除外ノートテーブルに追加
7718                 conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
7719                 
7720                 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7721         }
7722         
7723         // ICHANGED
7724         // 関連ノートリストのノートにスターを付ける
7725         @SuppressWarnings("unused")
7726         private void starNote() {
7727                 if (rensoNotePressedItemGuid != null) {
7728                         saveNote();
7729                         starNote(rensoNotePressedItemGuid);
7730                 }
7731         }
7732         
7733         // ICHANGED
7734         // 関連ノートリストのノートにスターを付ける
7735         private void starNote(String guid) {
7736                 // スター付きノートテーブルに追加
7737                 conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
7738                 
7739                 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7740         }
7741         
7742         // ICHANGED
7743         // 関連ノートリストのノートからスターを外す
7744         @SuppressWarnings("unused")
7745         private void unstarNote() {
7746                 if (rensoNotePressedItemGuid != null) {
7747                         saveNote();
7748                         unstarNote(rensoNotePressedItemGuid);
7749                 }
7750         }
7751         
7752         // ICHANGED
7753         // 関連ノートリストのノートからスターを外す
7754         private void unstarNote(String guid) {
7755                 // スター付きノートテーブルから削除
7756                 conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
7757                 
7758                 rensoNoteListDock.getRensoNoteList().refreshRensoNoteList(currentNoteGuid);
7759         }
7760         
7761         // ICHANGED
7762         // currentNoteGuidを返す
7763         public String getCurrentNoteGuid() {
7764                 return currentNoteGuid;
7765         }
7766         
7767         @SuppressWarnings("unused")
7768         // タブ入れ替えによってタブインデックスが変わったので、インデックスで管理しているハッシュマップ達も入れ替える
7769         private void tabIndexChanged(int from, int to) {
7770                 // tabWindows
7771                 TabBrowse tab = tabWindows.get(from);
7772                 tabWindows.put(from, tabWindows.get(to));
7773                 tabWindows.put(to, tab);
7774                 // noteDirty
7775                 boolean isNoteDirty = noteDirty.get(from);
7776                 noteDirty.put(from, noteDirty.get(to));
7777                 noteDirty.put(to, isNoteDirty);
7778                 // inkNote
7779                 boolean isInkNote = inkNote.get(from);
7780                 inkNote.put(from, inkNote.get(to));
7781                 inkNote.put(to, isInkNote);
7782                 // readOnly
7783                 boolean isReadOnly = readOnly.get(from);
7784                 readOnly.put(from, readOnly.get(to));
7785                 readOnly.put(to, isReadOnly);
7786                 // historyGuids
7787                 ArrayList<String> histGuids = historyGuids.get(from);
7788                 historyGuids.put(from, historyGuids.get(to));
7789                 historyGuids.put(to, histGuids);
7790                 // historyPosition
7791                 int histPosition = historyPosition.get(from);
7792                 historyPosition.put(from, historyPosition.get(to));
7793                 historyPosition.put(to, histPosition);
7794                 // fromHistory
7795                 boolean fromHist = fromHistory.get(from);
7796                 fromHistory.put(from,  fromHistory.get(to));
7797                 fromHistory.put(to, fromHist);
7798         }
7799         
7800         // 連想ノートリストのgetter
7801         public RensoNoteList getRensoNoteList() {
7802                 return rensoNoteListDock.getRensoNoteList();
7803         }
7804         
7805         // 帯域制限の超過をユーザに通知
7806         @SuppressWarnings("unused")
7807         private void informRateLimit(Integer rateLimitDuration) {
7808                 QMessageBox.warning(this, tr("Rate limit reached"), tr("Rate limit reached.\nRetry your request in " + rateLimitDuration + " seconds."));
7809         }
7810 }