No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Chris Lahey <clahey@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include "e-util/e-util.h"
30
31 #include "e-table-search.h"
32
33 #define d(x)
34
35 struct _ETableSearchPrivate {
36 guint timeout_id;
37
38 gchar *search_string;
39 gunichar last_character;
40 };
41
42 G_DEFINE_TYPE (ETableSearch, e_table_search, G_TYPE_OBJECT)
43
44 enum {
45 SEARCH_SEARCH,
46 SEARCH_ACCEPT,
47 LAST_SIGNAL
48 };
49
50 #define E_TABLE_SEARCH_GET_PRIVATE(obj) \
51 (G_TYPE_INSTANCE_GET_PRIVATE \
52 ((obj), E_TYPE_TABLE_SEARCH, ETableSearchPrivate))
53
54 d (static gint depth = 0)
55
56 static guint e_table_search_signals[LAST_SIGNAL] = { 0, };
57
58 static gboolean
59 e_table_search_search (ETableSearch *e_table_search,
60 gchar *string,
61 ETableSearchFlags flags)
62 {
63 gboolean ret_val;
64 g_return_val_if_fail (E_IS_TABLE_SEARCH (e_table_search), FALSE);
65
66 g_signal_emit (
67 e_table_search,
68 e_table_search_signals[SEARCH_SEARCH], 0,
69 string, flags, &ret_val);
70
71 return ret_val;
72 }
73
74 static void
75 e_table_search_accept (ETableSearch *e_table_search)
76 {
77 g_return_if_fail (E_IS_TABLE_SEARCH (e_table_search));
78
79 g_signal_emit (
80 e_table_search,
81 e_table_search_signals[SEARCH_ACCEPT], 0);
82 }
83
84 static gboolean
85 ets_accept (gpointer data)
86 {
87 ETableSearch *ets = data;
88 e_table_search_accept (ets);
89 g_free (ets->priv->search_string);
90
91 ets->priv->timeout_id = 0;
92 ets->priv->search_string = g_strdup ("");
93 ets->priv->last_character = 0;
94
95 return FALSE;
96 }
97
98 static void
99 drop_timeout (ETableSearch *ets)
100 {
101 if (ets->priv->timeout_id) {
102 g_source_remove (ets->priv->timeout_id);
103 }
104 ets->priv->timeout_id = 0;
105 }
106
107 static void
108 add_timeout (ETableSearch *ets)
109 {
110 drop_timeout (ets);
111 ets->priv->timeout_id = g_timeout_add_seconds (1, ets_accept, ets);
112 }
113
114 static void
115 e_table_search_finalize (GObject *object)
116 {
117 ETableSearchPrivate *priv;
118
119 priv = E_TABLE_SEARCH_GET_PRIVATE (object);
120
121 drop_timeout (E_TABLE_SEARCH (object));
122
123 g_free (priv->search_string);
124
125 /* Chain up to parent's finalize() method. */
126 G_OBJECT_CLASS (e_table_search_parent_class)->finalize (object);
127 }
128
129 static void
130 e_table_search_class_init (ETableSearchClass *class)
131 {
132 GObjectClass *object_class;
133
134 g_type_class_add_private (class, sizeof (ETableSearchPrivate));
135
136 object_class = G_OBJECT_CLASS (class);
137 object_class->finalize = e_table_search_finalize;
138
139 e_table_search_signals[SEARCH_SEARCH] = g_signal_new (
140 "search",
141 G_TYPE_FROM_CLASS (object_class),
142 G_SIGNAL_RUN_LAST,
143 G_STRUCT_OFFSET (ETableSearchClass, search),
144 (GSignalAccumulator) NULL, NULL,
145 e_marshal_BOOLEAN__STRING_INT,
146 G_TYPE_BOOLEAN, 2,
147 G_TYPE_STRING,
148 G_TYPE_INT);
149
150 e_table_search_signals[SEARCH_ACCEPT] = g_signal_new (
151 "accept",
152 G_TYPE_FROM_CLASS (object_class),
153 G_SIGNAL_RUN_LAST,
154 G_STRUCT_OFFSET (ETableSearchClass, accept),
155 (GSignalAccumulator) NULL, NULL,
156 g_cclosure_marshal_VOID__VOID,
157 G_TYPE_NONE, 0);
158
159 class->search = NULL;
160 class->accept = NULL;
161 }
162
163 static void
164 e_table_search_init (ETableSearch *ets)
165 {
166 ets->priv = E_TABLE_SEARCH_GET_PRIVATE (ets);
167
168 ets->priv->search_string = g_strdup ("");
169 }
170
171 ETableSearch *
172 e_table_search_new (void)
173 {
174 return g_object_new (E_TYPE_TABLE_SEARCH, NULL);
175 }
176
177 /**
178 * e_table_search_column_count:
179 * @e_table_search: The e-table-search to operate on
180 *
181 * Returns: the number of columns in the table search.
182 */
183 void
184 e_table_search_input_character (ETableSearch *ets,
185 gunichar character)
186 {
187 gchar character_utf8[7];
188 gchar *temp_string;
189
190 g_return_if_fail (ets != NULL);
191 g_return_if_fail (E_IS_TABLE_SEARCH (ets));
192
193 character_utf8[g_unichar_to_utf8 (character, character_utf8)] = 0;
194
195 temp_string = g_strdup_printf ("%s%s", ets->priv->search_string, character_utf8);
196 if (e_table_search_search (
197 ets, temp_string,
198 ets->priv->last_character != 0 ?
199 E_TABLE_SEARCH_FLAGS_CHECK_CURSOR_FIRST : 0)) {
200 g_free (ets->priv->search_string);
201 ets->priv->search_string = temp_string;
202 add_timeout (ets);
203 ets->priv->last_character = character;
204 return;
205 } else {
206 g_free (temp_string);
207 }
208
209 if (character == ets->priv->last_character) {
210 if (ets->priv->search_string &&
211 e_table_search_search (ets, ets->priv->search_string, 0)) {
212 add_timeout (ets);
213 }
214 }
215 }
216
217 gboolean
218 e_table_search_backspace (ETableSearch *ets)
219 {
220 gchar *end;
221
222 g_return_val_if_fail (ets != NULL, FALSE);
223 g_return_val_if_fail (E_IS_TABLE_SEARCH (ets), FALSE);
224
225 if (!ets->priv->search_string ||
226 !*ets->priv->search_string)
227 return FALSE;
228
229 end = ets->priv->search_string + strlen (ets->priv->search_string);
230 end = g_utf8_prev_char (end);
231 *end = 0;
232 ets->priv->last_character = 0;
233 add_timeout (ets);
234 return TRUE;
235 }