~ubuntu-branches/ubuntu/oneiric/ubuntuone-client/oneiric

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
}