evolution-3.6.4/widgets/menus/gal-define-views-dialog.c

Location Tool Test ID Function Issue
gal-define-views-dialog.c:327:18 clang-analyzer Access to field 'view_count' results in a dereference of a null pointer (loaded from variable 'collection')
gal-define-views-dialog.c:327:18 clang-analyzer Access to field 'view_count' results in a dereference of a null pointer (loaded from variable 'collection')
  1 /*
  2  *
  3  * This program is free software; you can redistribute it and/or
  4  * modify it under the terms of the GNU Lesser General Public
  5  * License as published by the Free Software Foundation; either
  6  * version 2 of the License, or (at your option) version 3.
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 11  * Lesser General Public License for more details.
 12  *
 13  * You should have received a copy of the GNU Lesser General Public
 14  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 15  *
 16  *
 17  * Authors:
 18  *		Chris Lahey <clahey@ximian.com>
 19  *
 20  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 21  *
 22  */
 23 
 24 #ifdef HAVE_CONFIG_H
 25 #include <config.h>
 26 #endif
 27 
 28 #include <glib/gi18n.h>
 29 
 30 #include "e-util/e-util.h"
 31 #include "e-util/e-util-private.h"
 32 
 33 #include "gal-define-views-dialog.h"
 34 #include "gal-define-views-model.h"
 35 #include "gal-view-new-dialog.h"
 36 
 37 static void gal_define_views_dialog_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
 38 static void gal_define_views_dialog_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
 39 static void gal_define_views_dialog_dispose	 (GObject *object);
 40 
 41 /* The properties we support */
 42 enum {
 43 	PROP_0,
 44 	PROP_COLLECTION
 45 };
 46 
 47 enum {
 48 	COL_GALVIEW_NAME,
 49 	COL_GALVIEW_DATA
 50 };
 51 
 52 typedef struct {
 53 	gchar         *title;
 54 
 55 	GtkTreeView *treeview;
 56 	GtkTreeModel *model;
 57 
 58 	GalDefineViewsDialog *names;
 59 } GalDefineViewsDialogChild;
 60 
 61 G_DEFINE_TYPE (GalDefineViewsDialog, gal_define_views_dialog, GTK_TYPE_DIALOG)
 62 
 63 static void
 64 gal_define_views_dialog_class_init (GalDefineViewsDialogClass *class)
 65 {
 66 	GObjectClass *object_class;
 67 
 68 	object_class = (GObjectClass *) class;
 69 
 70 	object_class->set_property = gal_define_views_dialog_set_property;
 71 	object_class->get_property = gal_define_views_dialog_get_property;
 72 	object_class->dispose = gal_define_views_dialog_dispose;
 73 
 74 	g_object_class_install_property (
 75 		object_class,
 76 		PROP_COLLECTION,
 77 		g_param_spec_object (
 78 			"collection",
 79 			"Collection",
 80 			NULL,
 81 			GAL_VIEW_COLLECTION_TYPE,
 82 			G_PARAM_READWRITE));
 83 }
 84 
 85 /* Button callbacks */
 86 
 87 static void
 88 gdvd_button_new_dialog_callback (GtkWidget *widget,
 89                                  gint id,
 90                                  GalDefineViewsDialog *dialog)
 91 {
 92 	gchar *name;
 93 	GtkTreeIter iter;
 94 	GalView *view;
 95 	GalViewCollectionItem *item;
 96 	GalViewFactory *factory;
 97 
 98 	switch (id) {
 99 	case GTK_RESPONSE_OK:
100 		g_object_get (
101 			widget,
102 			"name", &name,
103 			"factory", &factory,
104 			NULL);
105 
106 		if (name && factory) {
107 			g_strchomp (name);
108 			if (*name != '\0') {
109 				view = gal_view_factory_new_view (factory, name);
110 				gal_view_collection_append (dialog->collection, view);
111 
112 				item = dialog->collection->view_data[dialog->collection->view_count - 1];
113 				gtk_list_store_append (GTK_LIST_STORE (dialog->model), &iter);
114 				gtk_list_store_set (
115 					GTK_LIST_STORE (dialog->model), &iter,
116 					COL_GALVIEW_NAME, name,
117 					COL_GALVIEW_DATA, item,
118 					-1);
119 
120 				if (view && GAL_VIEW_GET_CLASS (view)->edit)
121 					gal_view_edit (view, GTK_WINDOW (dialog));
122 				g_object_unref (view);
123 			}
124 		}
125 		g_object_unref (factory);
126 		g_free (name);
127 		break;
128 	}
129 	gtk_widget_destroy (widget);
130 }
131 
132 static void
133 gdvd_button_new_callback (GtkWidget *widget,
134                           GalDefineViewsDialog *dialog)
135 {
136 	GtkWidget *view_new_dialog = gal_view_new_dialog_new (dialog->collection);
137 	gtk_window_set_transient_for (GTK_WINDOW (view_new_dialog), GTK_WINDOW (dialog));
138 	g_signal_connect (
139 		view_new_dialog, "response",
140 		G_CALLBACK (gdvd_button_new_dialog_callback), dialog);
141 	gtk_widget_show (view_new_dialog);
142 }
143 
144 static void
145 gdvd_button_modify_callback (GtkWidget *widget,
146                              GalDefineViewsDialog *dialog)
147 {
148 	GtkTreeIter iter;
149 	GalViewCollectionItem *item;
150 
151 	if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (dialog->treeview),
152 					 &dialog->model,
153 					 &iter)) {
154 		gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1);
155 
156 		g_return_if_fail (item && !item->built_in);
157 
158 		gal_view_edit (item->view, GTK_WINDOW (dialog));
159 	}
160 }
161 
162 static void
163 gdvd_button_delete_callback (GtkWidget *widget,
164                              GalDefineViewsDialog *dialog)
165 {
166 	gint row;
167 	GtkTreeIter iter;
168 	GtkTreePath *path;
169 	GtkTreeSelection *selection;
170 	GalViewCollectionItem *item;
171 
172 	selection = gtk_tree_view_get_selection (dialog->treeview);
173 
174 	if (gtk_tree_selection_get_selected (selection,
175 					 &dialog->model,
176 					 &iter)) {
177 		gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1);
178 
179 		g_return_if_fail (item && !item->built_in);
180 
181 		for (row = 0; row < dialog->collection->view_count; row++) {
182 			if (item == dialog->collection->view_data[row]) {
183 				gal_view_collection_delete_view (dialog->collection, row);
184 				path = gtk_tree_model_get_path (dialog->model, &iter);
185 				gtk_list_store_remove (GTK_LIST_STORE (dialog->model), &iter);
186 
187 				if (gtk_tree_path_prev (path)) {
188 					gtk_tree_model_get_iter (dialog->model, &iter, path);
189 				} else {
190 					gtk_tree_model_get_iter_first (dialog->model, &iter);
191 				}
192 
193 				gtk_tree_selection_select_iter (selection, &iter);
194 				break;
195 			}
196 		}
197 	}
198 }
199 
200 static void
201 gdvd_selection_changed_callback (GtkTreeSelection *selection,
202                                  GalDefineViewsDialog *dialog)
203 {
204 	GtkWidget *button;
205 	GtkTreeIter iter;
206 	GalViewCollectionItem *item = NULL;
207 	GalViewClass *gvclass = NULL;
208 
209 	if (gtk_tree_selection_get_selected (selection, &dialog->model, &iter)) {
210 		gtk_tree_model_get (dialog->model, &iter, COL_GALVIEW_DATA, &item, -1);
211 
212 		if (item && item->view)
213 			gvclass = GAL_VIEW_GET_CLASS (item->view);
214 	}
215 
216 	button = e_builder_get_widget (dialog->builder, "button-delete");
217 	gtk_widget_set_sensitive (GTK_WIDGET (button), item && !item->built_in);
218 
219 	button = e_builder_get_widget (dialog->builder, "button-modify");
220 	gtk_widget_set_sensitive (GTK_WIDGET (button), item && !item->built_in && gvclass && gvclass->edit != NULL);
221 }
222 
223 static void
224 gdvd_connect_signal (GalDefineViewsDialog *dialog,
225                      const gchar *widget_name,
226                      const gchar *signal,
227                      GCallback handler)
228 {
229 	GtkWidget *widget;
230 
231 	widget = e_builder_get_widget (dialog->builder, widget_name);
232 
233 	if (widget)
234 		g_signal_connect (widget, signal, handler, dialog);
235 }
236 
237 static void
238 dialog_response (GalDefineViewsDialog *dialog,
239                  gint response_id,
240                  gpointer data)
241 {
242 	gal_view_collection_save (dialog->collection);
243 }
244 
245 static void
246 gal_define_views_dialog_init (GalDefineViewsDialog *dialog)
247 {
248 	GtkWidget *content_area;
249 	GtkWidget *parent;
250 	GtkWidget *widget;
251 	GtkTreeSelection *selection;
252 
253 	dialog->collection = NULL;
254 
255 	dialog->builder = gtk_builder_new ();
256 	e_load_ui_builder_definition (dialog->builder, "gal-define-views.ui");
257 
258 	widget = e_builder_get_widget (dialog->builder, "table-top");
259 	if (!widget) {
260 		return;
261 	}
262 
263 	g_object_ref (widget);
264 
265 	parent = gtk_widget_get_parent (widget);
266 	gtk_container_remove (GTK_CONTAINER (parent), widget);
267 	gtk_window_set_default_size (GTK_WINDOW (dialog), 360, 270);
268 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
269 	gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
270 
271 	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
272 	gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
273 
274 	g_object_unref (widget);
275 
276 	gtk_dialog_add_buttons (
277 		GTK_DIALOG (dialog),
278 		GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
279 		NULL);
280 
281 	dialog->treeview = GTK_TREE_VIEW (e_builder_get_widget (dialog->builder, "treeview1"));
282 	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (dialog->treeview), FALSE);
283 	gtk_tree_view_set_headers_visible (dialog->treeview, TRUE);
284 
285 	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
286 
287 	gdvd_connect_signal (dialog, "button-new",    "clicked", G_CALLBACK (gdvd_button_new_callback));
288 	gdvd_connect_signal (dialog, "button-modify", "clicked", G_CALLBACK (gdvd_button_modify_callback));
289 	gdvd_connect_signal (dialog, "button-delete", "clicked", G_CALLBACK (gdvd_button_delete_callback));
290 	g_signal_connect (
291 		dialog, "response",
292 		G_CALLBACK (dialog_response), NULL);
293 
294 	selection = gtk_tree_view_get_selection (dialog->treeview);
295 	g_signal_connect (
296 		selection, "changed",
297 		G_CALLBACK (gdvd_selection_changed_callback), dialog);
298 	gdvd_selection_changed_callback (selection, dialog);
299 
300 	gtk_widget_show (GTK_WIDGET (dialog));
301 }
302 
303 static void
304 gal_define_views_dialog_dispose (GObject *object)
305 {
306 	GalDefineViewsDialog *gal_define_views_dialog = GAL_DEFINE_VIEWS_DIALOG (object);
307 
308 	if (gal_define_views_dialog->builder)
309 		g_object_unref (gal_define_views_dialog->builder);
310 	gal_define_views_dialog->builder = NULL;
311 
312 	/* Chain up to parent's dispose() method. */
313 	G_OBJECT_CLASS (gal_define_views_dialog_parent_class)->dispose (object);
314 }
315 
316 static void
317 gal_define_views_dialog_set_collection (GalDefineViewsDialog *dialog,
318                                         GalViewCollection *collection)
319 {
320 	gint i;
321 	GtkListStore *store;
322 	GtkCellRenderer *renderer;
323 	dialog->collection = collection;
324 
325 	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
326 
327 	for (i = 0; i < collection->view_count; i++) {
Access to field 'view_count' results in a dereference of a null pointer (loaded from variable 'collection')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'view_count' results in a dereference of a null pointer (loaded from variable 'collection')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

328 GalViewCollectionItem *item = collection->view_data[i]; 329 GtkTreeIter iter; 330 331 /* hide built in views */ 332 /*if (item->built_in == 1) 333 continue;*/ 334 335 gchar *title = NULL; 336 title = e_str_without_underscores (item->title); 337 338 gtk_list_store_append (store, &iter); 339 gtk_list_store_set ( 340 store, &iter, 341 COL_GALVIEW_NAME, title, 342 COL_GALVIEW_DATA, item, 343 -1); 344 345 g_free (title); 346 } 347 348 gtk_tree_sortable_set_sort_column_id ( 349 GTK_TREE_SORTABLE (store), 350 COL_GALVIEW_NAME, GTK_SORT_ASCENDING); 351 352 /* attaching treeview to model */ 353 gtk_tree_view_set_model (dialog->treeview, GTK_TREE_MODEL (store)); 354 gtk_tree_view_set_search_column (dialog->treeview, COL_GALVIEW_NAME); 355 356 dialog->model = GTK_TREE_MODEL (store); 357 358 renderer = gtk_cell_renderer_text_new (); 359 gtk_tree_view_insert_column_with_attributes ( 360 dialog->treeview, 361 COL_GALVIEW_NAME, _("Name"), 362 renderer, "text", COL_GALVIEW_NAME, 363 NULL); 364 365 /* set sort column */ 366 gtk_tree_sortable_set_sort_column_id ( 367 GTK_TREE_SORTABLE (dialog->model), 368 COL_GALVIEW_NAME, GTK_SORT_ASCENDING); 369 370 if (dialog->builder) { 371 GtkWidget *widget = e_builder_get_widget (dialog->builder, "label-views"); 372 if (widget && GTK_IS_LABEL (widget)) { 373 if (collection->title) { 374 gchar *text = g_strdup_printf ( 375 _("Define Views for %s"), 376 collection->title); 377 gtk_label_set_text ( 378 GTK_LABEL (widget), 379 text); 380 gtk_window_set_title (GTK_WINDOW (dialog), text); 381 g_free (text); 382 } else { 383 gtk_label_set_text ( 384 GTK_LABEL (widget), 385 _("Define Views")); 386 gtk_window_set_title ( 387 GTK_WINDOW (dialog), 388 _("Define Views")); 389 } 390 } 391 } 392 } 393 394 /** 395 * gal_define_views_dialog_new 396 * 397 * Returns a new dialog for defining views. 398 * 399 * Returns: The GalDefineViewsDialog. 400 */ 401 GtkWidget * 402 gal_define_views_dialog_new (GalViewCollection *collection) 403 { 404 GtkWidget *widget = g_object_new (GAL_TYPE_DEFINE_VIEWS_DIALOG, NULL); 405 gal_define_views_dialog_set_collection (GAL_DEFINE_VIEWS_DIALOG (widget), collection); 406 return widget; 407 } 408 409 static void 410 gal_define_views_dialog_set_property (GObject *object, 411 guint property_id, 412 const GValue *value, 413 GParamSpec *pspec) 414 { 415 GalDefineViewsDialog *dialog; 416 417 dialog = GAL_DEFINE_VIEWS_DIALOG (object); 418 419 switch (property_id) { 420 case PROP_COLLECTION: 421 if (g_value_get_object (value)) 422 gal_define_views_dialog_set_collection (dialog, GAL_VIEW_COLLECTION (g_value_get_object (value))); 423 else 424 gal_define_views_dialog_set_collection (dialog, NULL); 425 break; 426 427 default: 428 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 429 return; 430 } 431 } 432 433 static void 434 gal_define_views_dialog_get_property (GObject *object, 435 guint property_id, 436 GValue *value, 437 GParamSpec *pspec) 438 { 439 GalDefineViewsDialog *dialog; 440 441 dialog = GAL_DEFINE_VIEWS_DIALOG (object); 442 443 switch (property_id) { 444 case PROP_COLLECTION: 445 g_value_set_object (value, dialog->collection); 446 447 default: 448 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 449 break; 450 } 451 }