1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
using System;
using System.Collections.Generic;
using System.Text;
namespace Tomboy
{
public class Search
{
private NoteManager manager;
public Search (NoteManager manager)
{
this.manager = manager;
}
/// <summary>
/// Search the notes!
/// </summary>
/// <param name="query">
/// A <see cref="System.String"/>
/// </param>
/// <param name="case_sensitive">
/// A <see cref="System.Boolean"/>
/// </param>
/// <param name="selected_notebook">
/// A <see cref="Notebooks.Notebook"/>. If this is not
/// null, only the notes of the specified notebook will
/// be searched.
/// </param>
/// <returns>
/// A <see cref="IDictionary`2"/>
/// </returns>
public IDictionary<Note,int> SearchNotes (
string query,
bool case_sensitive,
Notebooks.Notebook selected_notebook)
{
string [] words = query.Split (' ', '\t', '\n');
// Used for matching in the raw note XML
string [] encoded_words = XmlEncoder.Encode (query).Split (' ', '\t', '\n');
Dictionary<Note,int> temp_matches = new Dictionary<Note,int>();
// Skip over notes that are template notes
Tag template_tag = TagManager.GetOrCreateSystemTag (TagManager.TemplateNoteSystemTag);
foreach (Note note in manager.Notes) {
// Skip template notes
if (note.ContainsTag (template_tag))
continue;
// Skip notes that are not in the
// selected notebook
if (selected_notebook != null
&& selected_notebook.ContainsNote (note) == false)
continue;
// Check the note's raw XML for at least one
// match, to avoid deserializing Buffers
// unnecessarily.
if (CheckNoteHasMatch (note,
encoded_words,
case_sensitive)){
int match_count =
FindMatchCountInNote (note.TextContent,
words,
case_sensitive);
if (match_count > 0)
// TODO: Improve note.GetHashCode()
temp_matches.Add(note,match_count);
}
}
return temp_matches;
}
bool CheckNoteHasMatch (Note note, string [] encoded_words, bool match_case)
{
string note_text = note.XmlContent;
if (!match_case)
note_text = note_text.ToLower ();
foreach (string word in encoded_words) {
if (note_text.Contains (word) )
continue;
else
return false;
}
return true;
}
int FindMatchCountInNote (string note_text, string [] words, bool match_case)
{
int matches = 0;
if (!match_case)
note_text = note_text.ToLower ();
foreach (string word in words) {
int idx = 0;
bool this_word_found = false;
if (word == String.Empty)
continue;
while (true) {
idx = note_text.IndexOf (word, idx);
if (idx == -1) {
if (this_word_found)
break;
else
return 0;
}
this_word_found = true;
matches++;
idx += word.Length;
}
}
return matches;
}
}
}
|