X-Git-Url: http://git.sourceforge.jp/view?p=neighbornote%2FNeighborNote.git;a=blobdiff_plain;f=src%2Fcx%2Ffbn%2Fnevernote%2Fgui%2FRensoNoteList.java;h=6a1f2fe720dc114351374ff4241880dd7a714ecb;hp=c48d3b9cb228e2c38245781a45054bde6fbacd68;hb=55556d26dc4897d305f5f6b3d840f28cf8503d26;hpb=596806080519045ebc92746ad1b569f7d8d4d7a5;ds=sidebyside diff --git a/src/cx/fbn/nevernote/gui/RensoNoteList.java b/src/cx/fbn/nevernote/gui/RensoNoteList.java index c48d3b9..6a1f2fe 100644 --- a/src/cx/fbn/nevernote/gui/RensoNoteList.java +++ b/src/cx/fbn/nevernote/gui/RensoNoteList.java @@ -17,17 +17,19 @@ * */ -// ICHANGED 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 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; @@ -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.threads.CounterRunner; 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.utilities.Pair; public class RensoNoteList extends QListWidget { private final DatabaseConnection conn; private final ApplicationLogger logger; private final HashMap rensoNoteListItems; - private final List rensoNoteListTrueItems; + private final HashMap rensoNoteListTrueItems; 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 HashMap mergedHistory; // マージされた操作履歴 private final SyncRunner syncRunner; - private final ENRelatedNotesRunner ENRelatedNotesRunner; - private final QThread ENRelatedNotesThread; + private final ENRelatedNotesRunner enRelatedNotesRunner; + private final QThread enRelatedNotesThread; + private final HashMap> enRelatedNotesCache; // Evernote関連ノートのキャッシュ + private final ENThumbnailRunner enThumbnailRunner; + private final QThread enThumbnailThread; + private String guid; 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; - 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(); + enRelatedNotesCache = new HashMap>(); + 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(); - rensoNoteListTrueItems = new ArrayList(); + rensoNoteListTrueItems = new HashMap(); this.itemPressed.connect(this, "rensoNoteItemPressed(QListWidgetItem)"); @@ -103,15 +125,23 @@ public class RensoNoteList extends QListWidget { 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) { - logger.log(logger.HIGH, "Entering RensoNoteList.refreshRensoNoteList"); + logger.log(logger.HIGH, "Entering RensoNoteList.refreshRensoNoteList guid = " + guid); this.clear(); rensoNoteListItems.clear(); rensoNoteListTrueItems.clear(); + mergedHistory = new HashMap(); if (!this.isEnabled()) { return; @@ -119,109 +149,104 @@ public class RensoNoteList extends QListWidget { if (guid == null || guid.equals("")) { return; } - - HashMap mergedHistory = new HashMap(); - // Evernoteの関連ノートを別スレッドで取得 - ENRelatedNotesRunner.addGuid(guid); -// ENRelatedNotesRunner.setGuid(guid); -// ENRelatedNotesThread.finished.connect(this, "ENRelatedNotesComplete()"); - -// RelatedResult result = getENRelatedNotes(guid); -// List relatedNotes = new ArrayList(); -// if (result != null) { -// relatedNotes = result.getNotes(); -// } -// if (relatedNotes != null && !relatedNotes.isEmpty()) { -// HashMap ENRelatedNotes = new HashMap(); -// -// 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 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 HashMap browseHistory = conn.getHistoryTable().getBehaviorHistory("browse", guid); addWeight(browseHistory, Global.getBrowseWeight()); - mergedHistory = mergeHistory(browseHistory, new HashMap()); + mergedHistory = mergeHistory(filterHistory(browseHistory), mergedHistory); // copy&pasteHistory HashMap copyAndPasteHistory = conn.getHistoryTable().getBehaviorHistory("copy & paste", guid); addWeight(copyAndPasteHistory, Global.getCopyPasteWeight()); - mergedHistory = mergeHistory(copyAndPasteHistory, mergedHistory); + mergedHistory = mergeHistory(filterHistory(copyAndPasteHistory), mergedHistory); // addNewNoteHistory HashMap addNewNoteHistory = conn.getHistoryTable().getBehaviorHistory("addNewNote", guid); addWeight(addNewNoteHistory, Global.getAddNewNoteWeight()); - mergedHistory = mergeHistory(addNewNoteHistory, mergedHistory); + mergedHistory = mergeHistory(filterHistory(addNewNoteHistory), mergedHistory); // rensoItemClickHistory HashMap rensoItemClickHistory = conn.getHistoryTable().getBehaviorHistory("rensoItemClick", guid); addWeight(rensoItemClickHistory, Global.getRensoItemClickWeight()); - mergedHistory = mergeHistory(rensoItemClickHistory, mergedHistory); + mergedHistory = mergeHistory(filterHistory(rensoItemClickHistory), mergedHistory); // sameTagHistory HashMap sameTagHistory = conn.getHistoryTable().getBehaviorHistory("sameTag", guid); addWeight(sameTagHistory, Global.getSameTagWeight()); - mergedHistory = mergeHistory(sameTagHistory, mergedHistory); + mergedHistory = mergeHistory(filterHistory(sameTagHistory), mergedHistory); // sameNotebookNoteHistory HashMap 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 history, int weight){ + logger.log(logger.EXTREME, "Entering RensoNoteList.addWeight"); + Set keySet = history.keySet(); Iterator 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 mergeHistory(HashMap History1, HashMap History2){ + logger.log(logger.EXTREME, "Entering RensoNoteList.mergeHistory"); + HashMap mergedHistory = new HashMap(); mergedHistory.putAll(History1); @@ -236,11 +261,18 @@ public class RensoNoteList extends QListWidget { mergedHistory.put(key, History2.get(key)); } } - + + logger.log(logger.EXTREME, "Leaving RensoNoteList.mergeHistory"); return mergedHistory; } + // 連想ノートリストにハッシュマップのデータを追加 private void addRensoNoteList(HashMap History){ + logger.log(logger.EXTREME, "Entering RensoNoteList.addRensoNoteList"); + + enThumbnailRunner.setUser(Global.getUserInformation()); + enThumbnailRunner.setServerUrl(Global.getServer()); + String currentNoteGuid = new String(parent.getCurrentNoteGuid()); // スター付きノートとスター無しノートを分ける @@ -293,6 +325,18 @@ public class RensoNoteList extends QListWidget { // 存在していて、かつ関連度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); @@ -303,12 +347,13 @@ public class RensoNoteList extends QListWidget { this.addItem(item); this.setItemWidget(item, myItem); rensoNoteListItems.put(item, maxGuid); - rensoNoteListTrueItems.add(myItem); + rensoNoteListTrueItems.put(maxGuid, myItem); } else { break; } } } + logger.log(logger.EXTREME, "Leaving RensoNoteList.addRensoNoteList"); } // リストのアイテムから対象ノートのguidを取得 @@ -319,6 +364,8 @@ public class RensoNoteList extends QListWidget { // 関連ノートリストの右クリックメニュー @Override public void contextMenuEvent(QContextMenuEvent event){ + logger.log(logger.EXTREME, "Entering RensoNoteList.contextMenuEvent"); + if (rensoNotePressedItemGuid == null || rensoNotePressedItemGuid.equals("")) { return; } @@ -345,6 +392,8 @@ public class RensoNoteList extends QListWidget { 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() { - for (int i = 0; i < rensoNoteListTrueItems.size(); i++) { - RensoNoteListItem item = rensoNoteListTrueItems.get(i); + for (RensoNoteListItem item : rensoNoteListTrueItems.values()) { item.setDefaultBackground(); } } @@ -364,24 +412,120 @@ public class RensoNoteList extends QListWidget { // ユーザが連想ノートリストのアイテムを選択した時の処理 @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); } + + logger.log(logger.HIGH, "Leaving RensoNoteList.rensoNoteItemPressed"); } // Evernoteの関連ノートの取得が完了 @SuppressWarnings("unused") - private void ENRelatedNotesComplete() { -// List relatedNoteGuids = ENRelatedNotesRunner.getRelatedGuids(); - List relatedNoteGuids = ENRelatedNotesRunner.getENRelatedNoteGuids(); - System.out.println(relatedNoteGuids); + private void enRelatedNotesComplete() { + logger.log(logger.HIGH, "Entering RensoNoteList.enRelatedNotesComplete"); + + Pair> enRelatedNoteGuidPair = enRelatedNotesRunner.getENRelatedNoteGuids(); // <元ノートguid, 関連ノートguidリスト> + + if (enRelatedNoteGuidPair == null) { + return; + } + + String sourceGuid = enRelatedNoteGuidPair.getFirst(); + List 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 relatedNoteGuids) { + logger.log(logger.EXTREME, "Entering RensoNoteList.addENRelatedNotes"); + + // Evernote関連ノート + HashMap enRelatedNotes = new HashMap(); + + for (String relatedGuid : relatedNoteGuids) { + enRelatedNotes.put(relatedGuid, Global.getENRelatedNotesWeight()); + } + + mergedHistory = mergeHistory(filterHistory(enRelatedNotes), mergedHistory); + + logger.log(logger.EXTREME, "Leaving RensoNoteList.addENRelatedNotes"); } // 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 filterHistory(HashMap sourceHistory) { + HashMap dstHistory = new HashMap(); + + 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 e : rensoNoteListTrueItems.entrySet()) { + // サムネイル取得が完了したノートが現在の連想ノートリストに表示されていたら再描画 + if (guid.equals(e.getKey())) { + e.getValue().repaint(); + } + } + + logger.log(logger.HIGH, "Leaving RensoNoteList.enThumbnailComplete"); } }