*
*/
-// 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.error.EDAMNotFoundException;
-import com.evernote.edam.error.EDAMSystemException;
-import com.evernote.edam.error.EDAMUserException;
-import com.evernote.edam.limits.Constants;
-import com.evernote.edam.notestore.RelatedQuery;
-import com.evernote.edam.notestore.RelatedResult;
-import com.evernote.edam.notestore.RelatedResultSpec;
import com.evernote.edam.type.Note;
-import com.evernote.thrift.TException;
+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 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<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 final QAction unstarAction;
private final QAction excludeNoteAction;
private final NeverNote parent;
private final QMenu menu;
+ private HashMap<String, Integer> mergedHistory; // マージされた操作履歴
private final SyncRunner syncRunner;
+ 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;
- 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.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>();
- rensoNoteListTrueItems = new ArrayList<RensoNoteListItem>();
+ rensoNoteListTrueItems = new HashMap<String, RensoNoteListItem>();
this.itemPressed.connect(this, "rensoNoteItemPressed(QListWidgetItem)");
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<String, Integer>();
if (!this.isEnabled()) {
return;
if (guid == null || guid.equals("")) {
return;
}
+
+ 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);
- HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
+ 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());
- 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());
- mergedHistory = mergeHistory(copyAndPasteHistory, mergedHistory);
+ mergedHistory = mergeHistory(filterHistory(copyAndPasteHistory), mergedHistory);
// 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());
- mergedHistory = mergeHistory(rensoItemClickHistory, mergedHistory);
+ mergedHistory = mergeHistory(filterHistory(rensoItemClickHistory), mergedHistory);
// 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());
- mergedHistory = mergeHistory(sameNotebookHistory, mergedHistory);
+ mergedHistory = mergeHistory(filterHistory(sameNotebookHistory), mergedHistory);
+ logger.log(logger.EXTREME, "Leaving RensoNoteList.calculateHistory");
+ }
+
+ // 操作回数に重み付けする
+ private void addWeight(HashMap<String, Integer> history, int weight){
+ logger.log(logger.EXTREME, "Entering RensoNoteList.addWeight");
- // Evernoteの関連ノートを取得
- RelatedResult result = getENRelatedNotes(guid);
- List<Note> relatedNotes = new ArrayList<Note>();
- if (result != null) {
- relatedNotes = result.getNotes();
+ 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);
}
- 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);
+
+ 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;
}
// すべての関連ポイントの合計を取得(関連度のパーセント算出に利用)
}
addRensoNoteList(mergedHistory);
-
- logger.log(logger.HIGH, "Leaving RensoNoteList.refreshRensoNoteList");
- }
-
- 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){
- 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.repaintRensoNoteList");
}
// 引数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);
mergedHistory.put(key, History2.get(key));
}
}
-
+
+ logger.log(logger.EXTREME, "Leaving RensoNoteList.mergeHistory");
return mergedHistory;
}
+ // 連想ノートリストにハッシュマップのデータを追加
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());
// スター付きノートとスター無しノートを分ける
// 存在していて、かつ関連度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);
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を取得
// 関連ノートリストの右クリックメニュー
@Override
public void contextMenuEvent(QContextMenuEvent event){
+ logger.log(logger.EXTREME, "Entering RensoNoteList.contextMenuEvent");
+
if (rensoNotePressedItemGuid == null || rensoNotePressedItemGuid.equals("")) {
return;
}
menu.exec(event.globalPos());
rensoNotePressedItemGuid = null;
+
+ logger.log(logger.EXTREME, "Leaving RensoNoteList.contextMenuEvent");
}
// コンテキストメニューが表示されているかどうか
// コンテキストメニューが閉じられた時
@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();
}
}
// ユーザが連想ノートリストのアイテムを選択した時の処理
@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() {
+ 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の関連ノート取得スレッドを終了させる
+ 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");
}
}