No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-signature-tree-view.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-signature-tree-view.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-signature-tree-view.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #include "e-mail-signature-tree-view.h"
20
21 #define E_MAIL_SIGNATURE_TREE_VIEW_GET_PRIVATE(obj) \
22 (G_TYPE_INSTANCE_GET_PRIVATE \
23 ((obj), E_TYPE_MAIL_SIGNATURE_TREE_VIEW, EMailSignatureTreeViewPrivate))
24
25 #define SOURCE_IS_MAIL_SIGNATURE(source) \
26 (e_source_has_extension ((source), E_SOURCE_EXTENSION_MAIL_SIGNATURE))
27
28 struct _EMailSignatureTreeViewPrivate {
29 ESourceRegistry *registry;
30 guint refresh_idle_id;
31 };
32
33 enum {
34 PROP_0,
35 PROP_REGISTRY
36 };
37
38 enum {
39 COLUMN_DISPLAY_NAME,
40 COLUMN_UID,
41 NUM_COLUMNS
42 };
43
44 G_DEFINE_TYPE (
45 EMailSignatureTreeView,
46 e_mail_signature_tree_view,
47 GTK_TYPE_TREE_VIEW)
48
49 static gboolean
50 mail_signature_tree_view_refresh_idle_cb (EMailSignatureTreeView *tree_view)
51 {
52 /* The refresh function will clear the idle ID. */
53 e_mail_signature_tree_view_refresh (tree_view);
54
55 return FALSE;
56 }
57
58 static void
59 mail_signature_tree_view_registry_changed (ESourceRegistry *registry,
60 ESource *source,
61 EMailSignatureTreeView *tree_view)
62 {
63 /* If the ESource in question has a "Mail Signature" extension,
64 * schedule a refresh of the tree model. Otherwise ignore it.
65 * We use an idle callback to limit how frequently we refresh
66 * the tree model, in case the registry is emitting lots of
67 * signals at once. */
68
69 if (!SOURCE_IS_MAIL_SIGNATURE (source))
70 return;
71
72 if (tree_view->priv->refresh_idle_id > 0)
73 return;
74
75 tree_view->priv->refresh_idle_id = g_idle_add (
76 (GSourceFunc) mail_signature_tree_view_refresh_idle_cb,
77 tree_view);
78 }
79
80 static void
81 mail_signature_tree_view_set_registry (EMailSignatureTreeView *tree_view,
82 ESourceRegistry *registry)
83 {
84 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
85 g_return_if_fail (tree_view->priv->registry == NULL);
86
87 tree_view->priv->registry = g_object_ref (registry);
88
89 g_signal_connect (
90 registry, "source-added",
91 G_CALLBACK (mail_signature_tree_view_registry_changed),
92 tree_view);
93
94 g_signal_connect (
95 registry, "source-changed",
96 G_CALLBACK (mail_signature_tree_view_registry_changed),
97 tree_view);
98
99 g_signal_connect (
100 registry, "source-removed",
101 G_CALLBACK (mail_signature_tree_view_registry_changed),
102 tree_view);
103 }
104
105 static void
106 mail_signature_tree_view_set_property (GObject *object,
107 guint property_id,
108 const GValue *value,
109 GParamSpec *pspec)
110 {
111 switch (property_id) {
112 case PROP_REGISTRY:
113 mail_signature_tree_view_set_registry (
114 E_MAIL_SIGNATURE_TREE_VIEW (object),
115 g_value_get_object (value));
116 return;
117 }
118
119 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
120 }
121
122 static void
123 mail_signature_tree_view_get_property (GObject *object,
124 guint property_id,
125 GValue *value,
126 GParamSpec *pspec)
127 {
128 switch (property_id) {
129 case PROP_REGISTRY:
130 g_value_set_object (
131 value,
132 e_mail_signature_tree_view_get_registry (
133 E_MAIL_SIGNATURE_TREE_VIEW (object)));
134 return;
135 }
136
137 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
138 }
139
140 static void
141 mail_signature_tree_view_dispose (GObject *object)
142 {
143 EMailSignatureTreeViewPrivate *priv;
144
145 priv = E_MAIL_SIGNATURE_TREE_VIEW_GET_PRIVATE (object);
146
147 if (priv->registry != NULL) {
148 g_signal_handlers_disconnect_matched (
149 priv->registry, G_SIGNAL_MATCH_DATA,
150 0, 0, NULL, NULL, object);
151 g_object_unref (priv->registry);
152 priv->registry = NULL;
153 }
154
155 if (priv->refresh_idle_id > 0) {
156 g_source_remove (priv->refresh_idle_id);
157 priv->refresh_idle_id = 0;
158 }
159
160 /* Chain up to parent's dispose() method. */
161 G_OBJECT_CLASS (e_mail_signature_tree_view_parent_class)->
162 dispose (object);
163 }
164
165 static void
166 mail_signature_tree_view_constructed (GObject *object)
167 {
168 GtkTreeView *tree_view;
169 GtkTreeViewColumn *column;
170 GtkCellRenderer *cell_renderer;
171 GtkListStore *list_store;
172
173 /* Chain up to parent's constructed() method. */
174 G_OBJECT_CLASS (e_mail_signature_tree_view_parent_class)->
175 constructed (object);
176
177 list_store = gtk_list_store_new (
178 NUM_COLUMNS,
179 G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */
180 G_TYPE_STRING); /* COLUMN_UID */
181
182 tree_view = GTK_TREE_VIEW (object);
183 gtk_tree_view_set_headers_visible (tree_view, FALSE);
184 gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
185
186 g_object_unref (list_store);
187
188 /* Column: Signature Name */
189
190 column = gtk_tree_view_column_new ();
191 gtk_tree_view_column_set_expand (column, TRUE);
192
193 cell_renderer = gtk_cell_renderer_text_new ();
194 g_object_set (cell_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
195 gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
196
197 gtk_tree_view_column_add_attribute (
198 column, cell_renderer, "text", COLUMN_DISPLAY_NAME);
199
200 gtk_tree_view_append_column (tree_view, column);
201
202 e_mail_signature_tree_view_refresh (
203 E_MAIL_SIGNATURE_TREE_VIEW (object));
204 }
205
206 static void
207 e_mail_signature_tree_view_class_init (EMailSignatureTreeViewClass *class)
208 {
209 GObjectClass *object_class;
210
211 g_type_class_add_private (
212 class, sizeof (EMailSignatureTreeViewPrivate));
213
214 object_class = G_OBJECT_CLASS (class);
215 object_class->set_property = mail_signature_tree_view_set_property;
216 object_class->get_property = mail_signature_tree_view_get_property;
217 object_class->dispose = mail_signature_tree_view_dispose;
218 object_class->constructed = mail_signature_tree_view_constructed;
219
220 g_object_class_install_property (
221 object_class,
222 PROP_REGISTRY,
223 g_param_spec_object (
224 "registry",
225 "Registry",
226 NULL,
227 E_TYPE_SOURCE_REGISTRY,
228 G_PARAM_READWRITE |
229 G_PARAM_CONSTRUCT_ONLY |
230 G_PARAM_STATIC_STRINGS));
231 }
232
233 static void
234 e_mail_signature_tree_view_init (EMailSignatureTreeView *tree_view)
235 {
236 tree_view->priv = E_MAIL_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
237 }
238
239 GtkWidget *
240 e_mail_signature_tree_view_new (ESourceRegistry *registry)
241 {
242 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
243
244 return g_object_new (
245 E_TYPE_MAIL_SIGNATURE_TREE_VIEW,
246 "registry", registry, NULL);
247 }
248
249 void
250 e_mail_signature_tree_view_refresh (EMailSignatureTreeView *tree_view)
251 {
252 ESourceRegistry *registry;
253 GtkTreeModel *tree_model;
254 GtkTreeSelection *selection;
255 ESource *source;
256 GList *list, *link;
257 const gchar *extension_name;
258 gchar *saved_uid = NULL;
259
260 g_return_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view));
261
262 if (tree_view->priv->refresh_idle_id > 0) {
263 g_source_remove (tree_view->priv->refresh_idle_id);
264 tree_view->priv->refresh_idle_id = 0;
265 }
266
267 registry = e_mail_signature_tree_view_get_registry (tree_view);
268 tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
269 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
270
271 source = e_mail_signature_tree_view_ref_selected_source (tree_view);
272 if (source != NULL) {
273 saved_uid = e_source_dup_uid (source);
274 g_object_unref (source);
275 }
276
277 gtk_list_store_clear (GTK_LIST_STORE (tree_model));
278
279 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
280 list = e_source_registry_list_sources (registry, extension_name);
281
282 for (link = list; link != NULL; link = g_list_next (link)) {
283 GtkTreeIter iter;
284 const gchar *display_name;
285 const gchar *uid;
286
287 source = E_SOURCE (link->data);
288 display_name = e_source_get_display_name (source);
289 uid = e_source_get_uid (source);
290
291 gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
292
293 gtk_list_store_set (
294 GTK_LIST_STORE (tree_model), &iter,
295 COLUMN_DISPLAY_NAME, display_name,
296 COLUMN_UID, uid, -1);
297 }
298
299 g_list_free_full (list, (GDestroyNotify) g_object_unref);
300
301 /* Try and restore the previous selected source. */
302
303 source = NULL;
304
305 if (saved_uid != NULL) {
306 source = e_source_registry_ref_source (registry, saved_uid);
307 g_free (saved_uid);
308 }
309
310 if (source != NULL) {
311 e_mail_signature_tree_view_set_selected_source (
312 tree_view, source);
313 g_object_unref (source);
314 }
315
316 /* Hint to refresh a signature preview. */
317 g_signal_emit_by_name (selection, "changed");
318 }
319
320 ESourceRegistry *
321 e_mail_signature_tree_view_get_registry (EMailSignatureTreeView *tree_view)
322 {
323 g_return_val_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view), NULL);
324
325 return tree_view->priv->registry;
326 }
327
328 ESource *
329 e_mail_signature_tree_view_ref_selected_source (EMailSignatureTreeView *tree_view)
330 {
331 ESourceRegistry *registry;
332 GtkTreeSelection *selection;
333 GtkTreeModel *tree_model;
334 GtkTreeIter iter;
335 ESource *source;
336 gchar *uid;
337
338 g_return_val_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view), NULL);
339
340 registry = e_mail_signature_tree_view_get_registry (tree_view);
341 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
342
343 if (!gtk_tree_selection_get_selected (selection, &tree_model, &iter))
344 return NULL;
345
346 gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1);
347 source = e_source_registry_ref_source (registry, uid);
348 g_free (uid);
349
350 return source;
351 }
352
353 void
354 e_mail_signature_tree_view_set_selected_source (EMailSignatureTreeView *tree_view,
355 ESource *source)
356 {
357 ESourceRegistry *registry;
358 GtkTreeSelection *selection;
359 GtkTreeModel *tree_model;
360 GtkTreeIter iter;
361 gboolean valid;
362
363 g_return_if_fail (E_IS_MAIL_SIGNATURE_TREE_VIEW (tree_view));
364 g_return_if_fail (E_IS_SOURCE (source));
365
366 /* It is a programming error to pass an ESource that has no
367 * "Mail Signature" extension. */
368 g_return_if_fail (SOURCE_IS_MAIL_SIGNATURE (source));
369
370 registry = e_mail_signature_tree_view_get_registry (tree_view);
371 tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
372 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
373
374 valid = gtk_tree_model_get_iter_first (tree_model, &iter);
375
376 while (valid) {
377 ESource *candidate;
378 gchar *uid;
379
380 gtk_tree_model_get (tree_model, &iter, COLUMN_UID, &uid, -1);
381 candidate = e_source_registry_ref_source (registry, uid);
382 g_free (uid);
383
384 if (candidate != NULL && e_source_equal (source, candidate)) {
385 gtk_tree_selection_select_iter (selection, &iter);
386 g_object_unref (candidate);
387 break;
388 }
389
390 if (candidate != NULL)
391 g_object_unref (candidate);
392
393 valid = gtk_tree_model_iter_next (tree_model, &iter);
394 }
395 }