OSDN Git Service

loggerを修正した
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / gui / RensoNoteList.java
index c48d3b9..6a1f2fe 100644 (file)
  *
 */
 
  *
 */
 
-// ICHANGED
 package cx.fbn.nevernote.gui;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 package cx.fbn.nevernote.gui;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import com.evernote.edam.type.Note;
 import com.trolltech.qt.QThread;
 import java.util.Set;
 
 import com.evernote.edam.type.Note;
 import com.trolltech.qt.QThread;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QFile;
 import com.trolltech.qt.core.QSize;
 import com.trolltech.qt.core.Qt.MouseButton;
 import com.trolltech.qt.gui.QAction;
 import com.trolltech.qt.core.QSize;
 import com.trolltech.qt.core.Qt.MouseButton;
 import com.trolltech.qt.gui.QAction;
@@ -40,15 +42,18 @@ import com.trolltech.qt.gui.QMenu;
 import cx.fbn.nevernote.Global;
 import cx.fbn.nevernote.NeverNote;
 import cx.fbn.nevernote.sql.DatabaseConnection;
 import cx.fbn.nevernote.Global;
 import cx.fbn.nevernote.NeverNote;
 import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.threads.CounterRunner;
 import cx.fbn.nevernote.threads.ENRelatedNotesRunner;
 import cx.fbn.nevernote.threads.ENRelatedNotesRunner;
+import cx.fbn.nevernote.threads.ENThumbnailRunner;
 import cx.fbn.nevernote.threads.SyncRunner;
 import cx.fbn.nevernote.utilities.ApplicationLogger;
 import cx.fbn.nevernote.threads.SyncRunner;
 import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.Pair;
 
 public class RensoNoteList extends QListWidget {
        private final DatabaseConnection conn;
        private final ApplicationLogger logger;
        private final HashMap<QListWidgetItem, String> rensoNoteListItems;
 
 public class RensoNoteList extends QListWidget {
        private final DatabaseConnection conn;
        private final ApplicationLogger logger;
        private final HashMap<QListWidgetItem, String> rensoNoteListItems;
-       private final List<RensoNoteListItem> rensoNoteListTrueItems;
+       private final HashMap<String, RensoNoteListItem> rensoNoteListTrueItems;
        private String rensoNotePressedItemGuid;
        private final QAction openNewTabAction;
        private final QAction starAction;
        private String rensoNotePressedItemGuid;
        private final QAction openNewTabAction;
        private final QAction starAction;
@@ -56,27 +61,44 @@ public class RensoNoteList extends QListWidget {
        private final QAction excludeNoteAction;
        private final NeverNote parent;
        private final QMenu menu;
        private final QAction excludeNoteAction;
        private final NeverNote parent;
        private final QMenu menu;
+       private HashMap<String, Integer> mergedHistory;                         // マージされた操作履歴
        private final SyncRunner syncRunner;
        private final SyncRunner syncRunner;
-       private final ENRelatedNotesRunner ENRelatedNotesRunner;
-       private final QThread ENRelatedNotesThread;
+       private final ENRelatedNotesRunner enRelatedNotesRunner;
+       private final QThread enRelatedNotesThread;
+       private final HashMap<String, List<String>> enRelatedNotesCache;        // Evernote関連ノートのキャッシュ<guid, 関連ノートリスト>
+       private final ENThumbnailRunner enThumbnailRunner;
+       private final QThread enThumbnailThread;
+       private String guid;
        private int allPointSum;
 
        private int allPointSum;
 
-       public RensoNoteList(DatabaseConnection c, NeverNote p, SyncRunner syncRunner) {
-               logger = new ApplicationLogger("rensoNoteList.log");
-               logger.log(logger.HIGH, "Setting up rensoNoteList");
+       public RensoNoteList(DatabaseConnection c, NeverNote p, SyncRunner syncRunner, ApplicationLogger logger) {
+               this.logger = logger;
+               this.logger.log(this.logger.HIGH, "Setting up rensoNoteList");
                allPointSum = 0;
 
                this.conn = c;
                this.parent = p;
                this.syncRunner = syncRunner;
                
                allPointSum = 0;
 
                this.conn = c;
                this.parent = p;
                this.syncRunner = syncRunner;
                
-               this.ENRelatedNotesRunner = new ENRelatedNotesRunner(this.syncRunner);
-               this.ENRelatedNotesRunner.ENRelatedNotesSignal.getENRelatedNotesFinished.connect(this, "ENRelatedNotesComplete()");
-               this.ENRelatedNotesThread = new QThread(ENRelatedNotesRunner, "ENRelatedNotes Thread");
-               this.ENRelatedNotesThread.start();
+               this.guid = new String();
+               mergedHistory = new HashMap<String, Integer>();
+               enRelatedNotesCache = new HashMap<String, List<String>>();
+               this.enRelatedNotesRunner = new ENRelatedNotesRunner(this.syncRunner, "enRelatedNotesRunner.log");
+               this.enRelatedNotesRunner.enRelatedNotesSignal.getENRelatedNotesFinished.connect(this, "enRelatedNotesComplete()");
+               this.enRelatedNotesRunner.limitSignal.rateLimitReached.connect(parent, "informRateLimit(Integer)");
+               this.enRelatedNotesThread = new QThread(enRelatedNotesRunner, "ENRelatedNotes Thread");
+               this.getEnRelatedNotesThread().start();
+               
+               this.enThumbnailRunner = new ENThumbnailRunner("enThumbnailRunner.log", CounterRunner.NOTEBOOK, 
+                                       Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+                                       Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+               this.enThumbnailRunner.enThumbnailSignal.getENThumbnailFinished.connect(this, "enThumbnailComplete(String)");
+               this.enThumbnailRunner.limitSignal.rateLimitReached.connect(parent, "informRateLimit(Integer)");
+               this.enThumbnailThread = new QThread(enThumbnailRunner, "ENThumbnail Thread");
+               this.enThumbnailThread.start();
                
                rensoNoteListItems = new HashMap<QListWidgetItem, String>();
                
                rensoNoteListItems = new HashMap<QListWidgetItem, String>();
-               rensoNoteListTrueItems = new ArrayList<RensoNoteListItem>();
+               rensoNoteListTrueItems = new HashMap<String, RensoNoteListItem>();
                
                this.itemPressed.connect(this, "rensoNoteItemPressed(QListWidgetItem)");
                
                
                this.itemPressed.connect(this, "rensoNoteItemPressed(QListWidgetItem)");
                
@@ -103,15 +125,23 @@ public class RensoNoteList extends QListWidget {
                menu.addAction(excludeNoteAction);
                menu.aboutToHide.connect(this, "contextMenuHidden()");
                
                menu.addAction(excludeNoteAction);
                menu.aboutToHide.connect(this, "contextMenuHidden()");
                
-               logger.log(logger.HIGH, "rensoNoteList setup complete");
+               this.logger.log(this.logger.HIGH, "rensoNoteList setup complete");
+       }
+       
+       // オーバーロード
+       // 現在開いているノートの連想ノートリストをリフレッシュ
+       public void refreshRensoNoteList() {
+               refreshRensoNoteList(guid);
        }
 
        }
 
+       // 連想ノートリストをリフレッシュ
        public void refreshRensoNoteList(String guid) {
        public void refreshRensoNoteList(String guid) {
-               logger.log(logger.HIGH, "Entering RensoNoteList.refreshRensoNoteList");
+               logger.log(logger.HIGH, "Entering RensoNoteList.refreshRensoNoteList guid = " + guid);
 
                this.clear();
                rensoNoteListItems.clear();
                rensoNoteListTrueItems.clear();
 
                this.clear();
                rensoNoteListItems.clear();
                rensoNoteListTrueItems.clear();
+               mergedHistory = new HashMap<String, Integer>();
 
                if (!this.isEnabled()) {
                        return;
 
                if (!this.isEnabled()) {
                        return;
@@ -119,109 +149,104 @@ public class RensoNoteList extends QListWidget {
                if (guid == null || guid.equals("")) {
                        return;
                }
                if (guid == null || guid.equals("")) {
                        return;
                }
-
-               HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
                
                
-               // Evernoteの関連ノートを別スレッドで取得
-               ENRelatedNotesRunner.addGuid(guid);
-//             ENRelatedNotesRunner.setGuid(guid);
-//             ENRelatedNotesThread.finished.connect(this, "ENRelatedNotesComplete()");
-               
-//             RelatedResult result = getENRelatedNotes(guid);
-//             List<Note> relatedNotes = new ArrayList<Note>();
-//             if (result != null) {
-//                     relatedNotes = result.getNotes();
-//             }
-//             if (relatedNotes != null && !relatedNotes.isEmpty()) {
-//                     HashMap<String, Integer> ENRelatedNotes = new HashMap<String, Integer>();
-//                     
-//                     for (Note relatedNote : relatedNotes) {
-//                             String relatedGuid = relatedNote.getGuid();
-//                             ENRelatedNotes.put(relatedGuid, 1);
-//                     }
-//                     addWeight(ENRelatedNotes, 10);
-//                     mergedHistory = mergeHistory(ENRelatedNotes, mergedHistory);
-//             }
+               this.guid = guid;
+               // すでにEvernote関連ノートがキャッシュされているか確認
+               boolean isCached;
+               isCached = enRelatedNotesCache.containsKey(guid);
+               if (!isCached) {        // キャッシュ無し
+                       // Evernoteの関連ノートを別スレッドで取得させる
+                       enRelatedNotesRunner.addGuid(guid);
+               } else {                        // キャッシュ有り
+                       List<String> relatedNoteGuids = enRelatedNotesCache.get(guid);
+                       addENRelatedNotes(relatedNoteGuids);
+               }
+               
+               calculateHistory(guid);
+               repaintRensoNoteList(false);
+
+               logger.log(logger.HIGH, "Leaving RensoNoteList.refreshRensoNoteList");
+       }
+       
+       // 操作履歴をデータベースから取得してノートごとの関連度を算出、その後mergedHistoryに追加
+       private void calculateHistory(String guid) {
+               logger.log(logger.EXTREME, "Entering RensoNoteList.calculateHistory guid = " + guid);
                
                // browseHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> browseHistory = conn.getHistoryTable().getBehaviorHistory("browse", guid);
                addWeight(browseHistory, Global.getBrowseWeight());
                
                // browseHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> browseHistory = conn.getHistoryTable().getBehaviorHistory("browse", guid);
                addWeight(browseHistory, Global.getBrowseWeight());
-               mergedHistory = mergeHistory(browseHistory, new HashMap<String, Integer>());
+               mergedHistory = mergeHistory(filterHistory(browseHistory), mergedHistory);
                
                // copy&pasteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> copyAndPasteHistory = conn.getHistoryTable().getBehaviorHistory("copy & paste", guid);
                addWeight(copyAndPasteHistory, Global.getCopyPasteWeight());
                
                // copy&pasteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> copyAndPasteHistory = conn.getHistoryTable().getBehaviorHistory("copy & paste", guid);
                addWeight(copyAndPasteHistory, Global.getCopyPasteWeight());
-               mergedHistory = mergeHistory(copyAndPasteHistory, mergedHistory);
+               mergedHistory = mergeHistory(filterHistory(copyAndPasteHistory), mergedHistory);
                
                // addNewNoteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> addNewNoteHistory = conn.getHistoryTable().getBehaviorHistory("addNewNote", guid);
                addWeight(addNewNoteHistory, Global.getAddNewNoteWeight());
                
                // addNewNoteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> addNewNoteHistory = conn.getHistoryTable().getBehaviorHistory("addNewNote", guid);
                addWeight(addNewNoteHistory, Global.getAddNewNoteWeight());
-               mergedHistory = mergeHistory(addNewNoteHistory, mergedHistory);
+               mergedHistory = mergeHistory(filterHistory(addNewNoteHistory), mergedHistory);
                
                // rensoItemClickHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> rensoItemClickHistory = conn.getHistoryTable().getBehaviorHistory("rensoItemClick", guid);
                addWeight(rensoItemClickHistory, Global.getRensoItemClickWeight());
                
                // rensoItemClickHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> rensoItemClickHistory = conn.getHistoryTable().getBehaviorHistory("rensoItemClick", guid);
                addWeight(rensoItemClickHistory, Global.getRensoItemClickWeight());
-               mergedHistory = mergeHistory(rensoItemClickHistory, mergedHistory);
+               mergedHistory = mergeHistory(filterHistory(rensoItemClickHistory), mergedHistory);
                
                // sameTagHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> sameTagHistory = conn.getHistoryTable().getBehaviorHistory("sameTag", guid);
                addWeight(sameTagHistory, Global.getSameTagWeight());
                
                // sameTagHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> sameTagHistory = conn.getHistoryTable().getBehaviorHistory("sameTag", guid);
                addWeight(sameTagHistory, Global.getSameTagWeight());
-               mergedHistory = mergeHistory(sameTagHistory, mergedHistory);
+               mergedHistory = mergeHistory(filterHistory(sameTagHistory), mergedHistory);
                
                // sameNotebookNoteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> sameNotebookHistory = conn.getHistoryTable().getBehaviorHistory("sameNotebook", guid);
                addWeight(sameNotebookHistory, Global.getSameNotebookWeight());
                
                // sameNotebookNoteHistory<guid, 回数(ポイント)>
                HashMap<String, Integer> sameNotebookHistory = conn.getHistoryTable().getBehaviorHistory("sameNotebook", guid);
                addWeight(sameNotebookHistory, Global.getSameNotebookWeight());
-               mergedHistory = mergeHistory(sameNotebookHistory, mergedHistory);
-               
-               // すべての関連ポイントの合計を取得(関連度のパーセント算出に利用)
-               allPointSum = 0;
-               for (int p : mergedHistory.values()) {
-                       allPointSum += p;
-               }
-               
-               addRensoNoteList(mergedHistory);
-
-               logger.log(logger.HIGH, "Leaving RensoNoteList.refreshRensoNoteList");
+               mergedHistory = mergeHistory(filterHistory(sameNotebookHistory), mergedHistory);
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.calculateHistory");
        }
        
        }
        
-//     private RelatedResult getENRelatedNotes(String guid) {
-//             RelatedQuery rquery = new RelatedQuery();
-//             rquery.setNoteGuid(guid);
-//             RelatedResultSpec resultSpec = new RelatedResultSpec();
-//             resultSpec.setMaxNotes(Constants.EDAM_RELATED_MAX_NOTES);
-//             if (syncRunner != null && syncRunner.localNoteStore != null) {
-//                     try {
-//                             RelatedResult result = syncRunner.localNoteStore.findRelated(syncRunner.authToken, rquery, resultSpec);
-//                             return result;
-//                     } catch (EDAMUserException e) {
-//                             // TODO 自動生成された catch ブロック
-//                             e.printStackTrace();
-//                     } catch (EDAMSystemException e) {
-//                             // TODO 自動生成された catch ブロック
-//                             e.printStackTrace();
-//                     } catch (EDAMNotFoundException e) {
-//                             // TODO 自動生成された catch ブロック
-//                             e.printStackTrace();
-//                     } catch (TException e) {
-//                             // TODO 自動生成された catch ブロック
-//                             e.printStackTrace();
-//                     }
-//             }
-//             return null;
-//     }
-
        // 操作回数に重み付けする
        private void addWeight(HashMap<String, Integer> history, int weight){
        // 操作回数に重み付けする
        private void addWeight(HashMap<String, Integer> history, int weight){
+               logger.log(logger.EXTREME, "Entering RensoNoteList.addWeight");
+               
                Set<String> keySet = history.keySet();
                Iterator<String> hist_iterator = keySet.iterator();
                while(hist_iterator.hasNext()){
                        String key = hist_iterator.next();
                        history.put(key, history.get(key) * weight);
                }
                Set<String> keySet = history.keySet();
                Iterator<String> hist_iterator = keySet.iterator();
                while(hist_iterator.hasNext()){
                        String key = hist_iterator.next();
                        history.put(key, history.get(key) * weight);
                }
+               
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.addWeight");
+       }
+       
+       // 連想ノートリストを再描画
+       private void repaintRensoNoteList(boolean needClear) {
+               logger.log(logger.EXTREME, "Entering RensoNoteList.repaintRensoNoteList");
+               
+               if (needClear) {
+                       this.clear();
+                       rensoNoteListItems.clear();
+                       rensoNoteListTrueItems.clear();
+               }
+               
+               if (!this.isEnabled()) {
+                       return;
+               }
+               
+               // すべての関連ポイントの合計を取得(関連度のパーセント算出に利用)
+               allPointSum = 0;
+               for (int p : mergedHistory.values()) {
+                       allPointSum += p;
+               }
+               
+               addRensoNoteList(mergedHistory);
+               
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.repaintRensoNoteList");
        }
        
        // 引数1と引数2をマージしたハッシュマップを返す
        private HashMap<String, Integer> mergeHistory(HashMap<String, Integer> History1, HashMap<String, Integer> History2){
        }
        
        // 引数1と引数2をマージしたハッシュマップを返す
        private HashMap<String, Integer> mergeHistory(HashMap<String, Integer> History1, HashMap<String, Integer> History2){
+               logger.log(logger.EXTREME, "Entering RensoNoteList.mergeHistory");
+               
                HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
                
                mergedHistory.putAll(History1);
                HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
                
                mergedHistory.putAll(History1);
@@ -236,11 +261,18 @@ public class RensoNoteList extends QListWidget {
                                mergedHistory.put(key, History2.get(key));
                        }
                }
                                mergedHistory.put(key, History2.get(key));
                        }
                }
-
+               
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.mergeHistory");
                return mergedHistory;
        }
        
                return mergedHistory;
        }
        
+       // 連想ノートリストにハッシュマップのデータを追加
        private void addRensoNoteList(HashMap<String, Integer> History){
        private void addRensoNoteList(HashMap<String, Integer> History){
+               logger.log(logger.EXTREME, "Entering RensoNoteList.addRensoNoteList");
+               
+               enThumbnailRunner.setUser(Global.getUserInformation());
+               enThumbnailRunner.setServerUrl(Global.getServer());
+               
                String currentNoteGuid = new String(parent.getCurrentNoteGuid());
                
                // スター付きノートとスター無しノートを分ける
                String currentNoteGuid = new String(parent.getCurrentNoteGuid());
                
                // スター付きノートとスター無しノートを分ける
@@ -293,6 +325,18 @@ public class RensoNoteList extends QListWidget {
                                
                                // 存在していて、かつ関連度0でなければノート情報を取得して連想ノートリストに追加
                                if (isNoteActive && maxNum > 0) {
                                
                                // 存在していて、かつ関連度0でなければノート情報を取得して連想ノートリストに追加
                                if (isNoteActive && maxNum > 0) {
+                                       // Evernoteサムネイルが取得済みか確認。未取得ならサムネイル取得スレッドにキュー
+                                       if (Global.isConnected) {
+                                               String thumbnailName = Global.getFileManager().getResDirPath("enThumbnail-" + maxGuid + ".png");
+                                               QFile thumbnail = new QFile(thumbnailName);
+                                               if (!thumbnail.exists()) {      // Evernoteサムネイルがファイルとして存在しない
+                                                       QByteArray data = conn.getNoteTable().getENThumbnail(maxGuid);
+                                                       if (data == null) {     // Evernoteサムネイル未取得
+                                                               enThumbnailRunner.addGuid(maxGuid);
+                                                       }
+                                               }
+                                       }
+                                       
                                        // スター付きか確認
                                        boolean isStared;
                                        isStared = conn.getStaredTable().existNote(currentNoteGuid, maxGuid);
                                        // スター付きか確認
                                        boolean isStared;
                                        isStared = conn.getStaredTable().existNote(currentNoteGuid, maxGuid);
@@ -303,12 +347,13 @@ public class RensoNoteList extends QListWidget {
                                        this.addItem(item);
                                        this.setItemWidget(item, myItem);
                                        rensoNoteListItems.put(item, maxGuid);
                                        this.addItem(item);
                                        this.setItemWidget(item, myItem);
                                        rensoNoteListItems.put(item, maxGuid);
-                                       rensoNoteListTrueItems.add(myItem);
+                                       rensoNoteListTrueItems.put(maxGuid, myItem);
                                } else {
                                        break;
                                }
                        }
                }
                                } else {
                                        break;
                                }
                        }
                }
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.addRensoNoteList");
        }
 
        // リストのアイテムから対象ノートのguidを取得
        }
 
        // リストのアイテムから対象ノートのguidを取得
@@ -319,6 +364,8 @@ public class RensoNoteList extends QListWidget {
        // 関連ノートリストの右クリックメニュー
        @Override
        public void contextMenuEvent(QContextMenuEvent event){
        // 関連ノートリストの右クリックメニュー
        @Override
        public void contextMenuEvent(QContextMenuEvent event){
+               logger.log(logger.EXTREME, "Entering RensoNoteList.contextMenuEvent");
+               
                if (rensoNotePressedItemGuid == null || rensoNotePressedItemGuid.equals("")) {
                        return;
                }
                if (rensoNotePressedItemGuid == null || rensoNotePressedItemGuid.equals("")) {
                        return;
                }
@@ -345,6 +392,8 @@ public class RensoNoteList extends QListWidget {
                menu.exec(event.globalPos());
                
                rensoNotePressedItemGuid = null;
                menu.exec(event.globalPos());
                
                rensoNotePressedItemGuid = null;
+               
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.contextMenuEvent");
        }
        
        // コンテキストメニューが表示されているかどうか
        }
        
        // コンテキストメニューが表示されているかどうか
@@ -355,8 +404,7 @@ public class RensoNoteList extends QListWidget {
        // コンテキストメニューが閉じられた時
        @SuppressWarnings("unused")
        private void contextMenuHidden() {
        // コンテキストメニューが閉じられた時
        @SuppressWarnings("unused")
        private void contextMenuHidden() {
-               for (int i = 0; i < rensoNoteListTrueItems.size(); i++) {
-                       RensoNoteListItem item = rensoNoteListTrueItems.get(i);
+               for (RensoNoteListItem item : rensoNoteListTrueItems.values()) {
                        item.setDefaultBackground();
                }
        }
                        item.setDefaultBackground();
                }
        }
@@ -364,24 +412,120 @@ public class RensoNoteList extends QListWidget {
        // ユーザが連想ノートリストのアイテムを選択した時の処理
        @SuppressWarnings("unused")
        private void rensoNoteItemPressed(QListWidgetItem current) {
        // ユーザが連想ノートリストのアイテムを選択した時の処理
        @SuppressWarnings("unused")
        private void rensoNoteItemPressed(QListWidgetItem current) {
+               logger.log(logger.HIGH, "Entering RensoNoteList.rensoNoteItemPressed");
+               
                rensoNotePressedItemGuid = null;
                // 右クリックだったときの処理
                if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
                        rensoNotePressedItemGuid = getNoteGuid(current);
                }
                rensoNotePressedItemGuid = null;
                // 右クリックだったときの処理
                if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
                        rensoNotePressedItemGuid = getNoteGuid(current);
                }
+               
+               logger.log(logger.HIGH, "Leaving RensoNoteList.rensoNoteItemPressed");
        }
        
        // Evernoteの関連ノートの取得が完了
        @SuppressWarnings("unused")
        }
        
        // Evernoteの関連ノートの取得が完了
        @SuppressWarnings("unused")
-       private void ENRelatedNotesComplete() {
-//             List<String> relatedNoteGuids = ENRelatedNotesRunner.getRelatedGuids();
-               List<String> relatedNoteGuids = ENRelatedNotesRunner.getENRelatedNoteGuids();
-               System.out.println(relatedNoteGuids);
+       private void enRelatedNotesComplete() {
+               logger.log(logger.HIGH, "Entering RensoNoteList.enRelatedNotesComplete");
+               
+               Pair<String, List<String>> enRelatedNoteGuidPair = enRelatedNotesRunner.getENRelatedNoteGuids();        // <元ノートguid, 関連ノートguidリスト>
+               
+               if (enRelatedNoteGuidPair == null) {
+                       return;
+               }
+               
+               String sourceGuid = enRelatedNoteGuidPair.getFirst();
+               List<String> enRelatedNoteGuids = enRelatedNoteGuidPair.getSecond();
+               
+               
+               if (sourceGuid != null && !sourceGuid.equals("") && enRelatedNoteGuids != null) {       // Evernote関連ノートがnullでなければ
+                       // まずキャッシュに追加
+                       enRelatedNotesCache.put(sourceGuid, enRelatedNoteGuids);
+                       
+                       if (!enRelatedNoteGuids.isEmpty()) {    // Evernote関連ノートが存在していて
+                               if (sourceGuid.equals(this.guid)) {     // 取得したデータが今開いているノートの関連ノートなら
+                                       // mergedHistoryにEvernote関連ノートを追加してから再描画
+                                       addENRelatedNotes(enRelatedNoteGuids);
+                                       repaintRensoNoteList(true);
+                               }
+                       }
+               }
+               
+               logger.log(logger.HIGH, "Leaving RensoNoteList.enRelatedNotesComplete");
+       }
+       
+       // Evernote関連ノートの関連度情報をmergedHistoryに追加
+       private void addENRelatedNotes(List<String> relatedNoteGuids) {
+               logger.log(logger.EXTREME, "Entering RensoNoteList.addENRelatedNotes");
+               
+               // Evernote関連ノート<guid, 関連ポイント>
+               HashMap<String, Integer> enRelatedNotes = new HashMap<String, Integer>();
+               
+               for (String relatedGuid : relatedNoteGuids) {
+                       enRelatedNotes.put(relatedGuid, Global.getENRelatedNotesWeight());
+               }
+               
+               mergedHistory = mergeHistory(filterHistory(enRelatedNotes), mergedHistory);
+               
+               logger.log(logger.EXTREME, "Leaving RensoNoteList.addENRelatedNotes");
        }
        
        // Evernoteの関連ノート取得スレッドを終了させる
        }
        
        // Evernoteの関連ノート取得スレッドを終了させる
-       public void stopThread() {
-               ENRelatedNotesRunner.setKeepRunning(false);
-               // TODO keepRunningをfalseにしても、guidQueueが次のキューが来るまで待機するので終了できない。guidQueueに終了命令を処理できる仕組みを要追加。
+       public boolean stopThread() {
+               logger.log(logger.HIGH, "Entering RensoNoteList.stopThread");
+               
+               if (!enRelatedNotesRunner.addStop()) {
+                       logger.log(logger.HIGH, "RensoNoteList.stopThread failed(enRelatedNotesRunner)");
+                       return false;
+               }
+               if (!enThumbnailRunner.addStop()) {
+                       logger.log(logger.HIGH, "RensoNoteList.stopThread failed(enThumbnailRunner)");
+                       return false;
+               }
+               
+               logger.log(logger.HIGH, "RensoNoteList.stopThread succeeded");
+               return true;
+       }
+
+       public QThread getEnRelatedNotesThread() {
+               return enRelatedNotesThread;
+       }
+       
+       public String getGuid() {
+               return guid;
+       }
+       
+       // ローカルに存在していて、かつアクティブなノートだけを返す
+       private HashMap<String, Integer> filterHistory(HashMap<String, Integer> sourceHistory) {
+               HashMap<String, Integer> dstHistory = new HashMap<String, Integer>();
+               
+               for (String guid : sourceHistory.keySet()) {
+                       if (conn.getNoteTable().exists(guid)) {
+                               if (conn.getNoteTable().getNote(guid, false, false, false, false, false).isActive()) {
+                                       dstHistory.put(guid, sourceHistory.get(guid));
+                               }
+                       }
+               }
+               
+               return dstHistory;
+       }
+       
+       /**
+        * Evernoteサムネイルの取得が完了
+        * 
+        * @param guid 現在開いているノートのguid
+        */
+       @SuppressWarnings("unused")
+       private void enThumbnailComplete(String guid) {
+               logger.log(logger.HIGH, "Entering RensoNoteList.enThumbnailComplete");
+               
+               for (Map.Entry<String, RensoNoteListItem> e : rensoNoteListTrueItems.entrySet()) {
+                       // サムネイル取得が完了したノートが現在の連想ノートリストに表示されていたら再描画
+                       if (guid.equals(e.getKey())) {
+                               e.getValue().repaint();
+                       }
+               }
+               
+               logger.log(logger.HIGH, "Leaving RensoNoteList.enThumbnailComplete");
        }
 }
        }
 }