Redmineダウンローダ開発メモ(10) 正規ビューワーの開発-タブ追加の流れ - ドナドナされるプログラマのメモの続き。
タブビューワー機能はできたので、最後の大物として検索機能を入れる。検索機能の実装は以下4ステップに分ける。
- 全JSONの結合
- 検索
- 表示
- 結合データのキャッシュ化
1. 全JSONの結合
全JSONを結合する方法として、全サブフォルダを検索する方法とissue_list.jsonを活用する方法の2通りが思いつく。全サブフォルダを検索する場合、削除されたissueも取り込んでしまう点がよろしくない。一方、issue_list.jsonを活用する場合はダウンロード後に何らかの理由で削除されたファイルをアクセスしようとするおそれがある。しかし、後者はファイル欠損が発覚した際に注意を促すダイアログを示すだけで回避できる。そこで、本ソフトではissue_list.jsonを活用することにした。
全JSONの結合は、issueの数が多いと時間がかかる。SharePointなどを使っていると酷いことになると思われるので、読み込み中は読み込み進捗を示すダイアログを表示することにした。今まではこのような小さなダイアログでもいちいち新クラスを作っていたが、今回は非同期用のクラスであるstd::futureおよびラムダ式を活用して簡略にやってみる。なおatomicな処理のためにstd::atomicも使っている。プログレスバーの値は2回セットしているが、これは余計な伸びるアニメーションをスキップするためである。結合したデータはissue[]の形で保持する。
2. 検索
全JSONの結合が終わったら、次は検索である。検索は、まずは全てのキーの全ての値を対象とする。検索関数はissue[i]への検索をするメイン関数と、issue内部を全探索する補助関数で作る。補助関数はissue内のオブジェクトや配列に対し再帰処理で深堀りする仕様とする。検索ワードに引っかかった値はid毎に配列として保持することで全検索結果を保存する。
3. 表示
全検索結果を得たら、いよいよ表示である。表示は、見つかった値をvalueで保持するとして
{{category}} #{{id}} {{title}} {{status}}<br>
{{value}}<br>
{{updated_on}}<br>
という感じにする。一つのidに対し複数のvalueがあった場合は・・・どうしよう。とりあえずはRedmineの動作と同様に最初のvalueのみ表示することにする。
それから、html化させたあと検索ワードで改めてhtmlを検索し、検索ワードをハイライトするよう置換もする。
4. 結合データのキャッシュ化
起動時するたびに結合データを作るのはSharePointを使っている環境ではインフラに悪いので、キャッシュ化する。そしてキャッシュ更新の要否はissue_list.jsonとの比較で判断する。
よし、あとは実装するだけ。今日はここまで。