1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
1 |
/*
|
2 |
* Ubuntu One Nautilus plugin
|
|
3 |
*
|
|
4 |
* Authors: Alejandro J. Cura <alecu@canonical.com>
|
|
5 |
*
|
|
6 |
* Copyright 2010 Canonical Ltd.
|
|
7 |
*
|
|
8 |
* This program is free software: you can redistribute it and/or modify it
|
|
9 |
* under the terms of the GNU General Public License version 3, as published
|
|
10 |
* by the Free Software Foundation.
|
|
11 |
*
|
|
12 |
* This program is distributed in the hope that it will be useful, but
|
|
13 |
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
|
14 |
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
|
15 |
* PURPOSE. See the GNU General Public License for more details.
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License along
|
|
18 |
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19 |
*
|
|
20 |
*/
|
|
21 |
||
22 |
#include <string.h> |
|
23 |
#include <glib.h> |
|
24 |
||
25 |
static gint |
|
26 |
compare_glongs (gconstpointer a, |
|
27 |
gconstpointer b, |
|
28 |
gpointer user_data) |
|
29 |
{
|
|
30 |
return (glong) a - (glong) b; |
|
31 |
}
|
|
32 |
||
33 |
||
34 |
static void |
|
35 |
tree_of_arrays_insert (GTree *tree, |
|
36 |
gpointer key, |
|
37 |
gpointer value) |
|
38 |
{
|
|
39 |
GPtrArray *array = g_tree_lookup (tree, key); |
|
40 |
if (array == NULL) { |
|
41 |
array = g_ptr_array_new (); |
|
42 |
g_tree_insert (tree, key, array); |
|
43 |
}
|
|
44 |
g_ptr_array_add (array, value); |
|
45 |
}
|
|
46 |
||
47 |
||
48 |
static void |
|
49 |
destroy_tree_array (gpointer data) |
|
50 |
{
|
|
51 |
g_ptr_array_free (data, TRUE); |
|
52 |
}
|
|
53 |
||
54 |
typedef struct { |
|
55 |
GString *built_string; |
|
56 |
gchar *source_string; |
|
57 |
gchar *source_cursor; |
|
58 |
} BuildResultsData; |
|
59 |
||
60 |
||
61 |
static void |
|
62 |
append_array_strings (gpointer data, |
|
63 |
gpointer user_data) |
|
64 |
{
|
|
65 |
g_string_append (user_data, data); |
|
66 |
}
|
|
67 |
||
68 |
||
69 |
static gboolean |
|
70 |
build_results (gpointer key, |
|
71 |
gpointer value, |
|
72 |
gpointer data) |
|
73 |
{
|
|
74 |
BuildResultsData* results_data = data; |
|
75 |
glong tag_start = (glong)key; |
|
76 |
gchar *tag_start_ptr = g_utf8_offset_to_pointer (results_data->source_string, |
|
77 |
tag_start); |
|
78 |
glong len = tag_start_ptr - results_data->source_cursor; |
|
79 |
||
80 |
gchar *escaped_str = g_markup_escape_text (results_data->source_cursor, |
|
81 |
len); |
|
82 |
||
83 |
g_string_append (results_data->built_string, |
|
84 |
escaped_str); |
|
85 |
g_free (escaped_str); |
|
86 |
results_data->source_cursor += len; |
|
87 |
||
88 |
g_ptr_array_foreach (value, |
|
89 |
append_array_strings, |
|
90 |
results_data->built_string); |
|
91 |
return FALSE; |
|
92 |
}
|
|
93 |
||
94 |
||
95 |
gchar * |
|
96 |
highlight_result(gchar *needles, gchar *haystack) |
|
97 |
{
|
|
98 |
gchar **split_needles; |
|
99 |
GTree *result_parts; |
|
100 |
gchar *folded_needles; |
|
101 |
gchar *folded_haystack; |
|
1.1.27
by Rodrigo Moya
Import upstream version 1.3.6 |
102 |
gchar **needle; |
103 |
gchar *escaped_str; |
|
1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
104 |
BuildResultsData results_data; |
105 |
||
106 |
folded_needles = g_utf8_casefold (needles, -1); |
|
107 |
folded_haystack = g_utf8_casefold (haystack, -1); |
|
108 |
||
109 |
results_data.built_string = g_string_new (""); |
|
110 |
results_data.source_string = haystack; |
|
111 |
results_data.source_cursor = haystack; |
|
112 |
||
113 |
result_parts = g_tree_new_full (compare_glongs, |
|
114 |
NULL, |
|
115 |
NULL, |
|
116 |
destroy_tree_array); |
|
117 |
||
118 |
split_needles = g_strsplit (folded_needles, " ", 0); |
|
1.1.27
by Rodrigo Moya
Import upstream version 1.3.6 |
119 |
needle = split_needles; |
1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
120 |
while (*needle != NULL) { |
1.1.27
by Rodrigo Moya
Import upstream version 1.3.6 |
121 |
gchar *search_start; |
122 |
gchar *start_ptr; |
|
1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
123 |
glong needle_len = g_utf8_strlen (*needle, -1); |
124 |
if (needle_len < 1) { |
|
125 |
needle++; |
|
126 |
continue; |
|
127 |
}
|
|
1.1.27
by Rodrigo Moya
Import upstream version 1.3.6 |
128 |
search_start = folded_haystack; |
129 |
start_ptr = g_strstr_len (search_start, -1, *needle); |
|
1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
130 |
while (start_ptr != NULL) { |
131 |
glong start = g_utf8_pointer_to_offset (folded_haystack, |
|
132 |
start_ptr); |
|
133 |
glong end = start + g_utf8_strlen (*needle, -1); |
|
134 |
tree_of_arrays_insert (result_parts, |
|
135 |
(gpointer) start, |
|
136 |
"<b>"); |
|
137 |
tree_of_arrays_insert (result_parts, |
|
138 |
(gpointer) end, |
|
139 |
"</b>"); |
|
140 |
search_start = g_utf8_next_char (start_ptr); |
|
141 |
start_ptr = g_strstr_len (search_start, |
|
142 |
-1, |
|
143 |
*needle); |
|
144 |
}
|
|
145 |
needle++; |
|
146 |
}
|
|
147 |
g_free (folded_needles); |
|
148 |
g_free (folded_haystack); |
|
149 |
||
150 |
||
151 |
g_tree_foreach (result_parts, build_results, &results_data); |
|
152 |
||
1.1.27
by Rodrigo Moya
Import upstream version 1.3.6 |
153 |
escaped_str = g_markup_escape_text (results_data.source_cursor, -1); |
1.1.26
by Rodrigo Moya
Import upstream version 1.3.5 |
154 |
g_string_append (results_data.built_string, |
155 |
escaped_str); |
|
156 |
g_free (escaped_str); |
|
157 |
||
158 |
g_tree_destroy (result_parts); |
|
159 |
g_strfreev (split_needles); |
|
160 |
return g_string_free (results_data.built_string, |
|
161 |
FALSE); |
|
162 |
}
|