~ubuntu-branches/ubuntu/lucid/tomboy/lucid-proposed

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;
		}
	}
}