evolution-3.6.4/widgets/misc/e-mail-signature-tree-view.c

No issues found

Incomplete coverage

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
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  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 }