evolution-3.6.4/widgets/misc/e-import-assistant.c

Location Tool Test ID Function Issue
e-import-assistant.c:927:25 clang-analyzer Access to field 'data' results in a dereference of a null pointer (loaded from variable 'importers')
e-import-assistant.c:927:25 clang-analyzer Access to field 'data' results in a dereference of a null pointer (loaded from variable 'importers')
   1 /*
   2  * e-import-assistant.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  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  19  *
  20  */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include <config.h>
  24 #endif
  25 
  26 #include "e-import-assistant.h"
  27 
  28 #include <sys/types.h>
  29 #include <sys/stat.h>
  30 #include <unistd.h>
  31 #include <string.h>
  32 
  33 #include <glib/gi18n.h>
  34 #include <gdk/gdkkeysyms.h>
  35 #include <libebackend/libebackend.h>
  36 
  37 #include <e-util/e-import.h>
  38 #include <e-util/e-util-private.h>
  39 
  40 #define E_IMPORT_ASSISTANT_GET_PRIVATE(obj) \
  41 	(G_TYPE_INSTANCE_GET_PRIVATE \
  42 	((obj), E_TYPE_IMPORT_ASSISTANT, EImportAssistantPrivate))
  43 
  44 typedef struct _ImportFilePage ImportFilePage;
  45 typedef struct _ImportDestinationPage ImportDestinationPage;
  46 typedef struct _ImportTypePage ImportTypePage;
  47 typedef struct _ImportSelectionPage ImportSelectionPage;
  48 typedef struct _ImportProgressPage ImportProgressPage;
  49 typedef struct _ImportSimplePage ImportSimplePage;
  50 
  51 struct _ImportFilePage {
  52 	GtkWidget *filename;
  53 	GtkWidget *filetype;
  54 
  55 	EImportTargetURI *target;
  56 	EImportImporter *importer;
  57 };
  58 
  59 struct _ImportDestinationPage {
  60 	GtkWidget *control;
  61 };
  62 
  63 struct _ImportTypePage {
  64 	GtkWidget *intelligent;
  65 	GtkWidget *file;
  66 };
  67 
  68 struct _ImportSelectionPage {
  69 	GSList *importers;
  70 	GSList *current;
  71 	EImportTargetHome *target;
  72 };
  73 
  74 struct _ImportProgressPage {
  75 	GtkWidget *progress_bar;
  76 };
  77 
  78 struct _ImportSimplePage {
  79 	GtkWidget *actionlabel;
  80 	GtkWidget *filetypetable;
  81 	GtkWidget *filetype;
  82 	GtkWidget *control; /* importer's destination or preview widget in an alignment */
  83 	gboolean has_preview; /* TRUE when 'control' holds a preview widget,
  84 				   otherwise holds destination widget */
  85 
  86 	EImportTargetURI *target;
  87 	EImportImporter *importer;
  88 };
  89 
  90 struct _EImportAssistantPrivate {
  91 	ImportFilePage file_page;
  92 	ImportDestinationPage destination_page;
  93 	ImportTypePage type_page;
  94 	ImportSelectionPage selection_page;
  95 	ImportProgressPage progress_page;
  96 	ImportSimplePage simple_page;
  97 
  98 	EImport *import;
  99 
 100 	gboolean is_simple;
 101 	GPtrArray *fileuris; /* each element is a file URI, as a newly allocated string */
 102 
 103 	/* Used for importing phase of operation */
 104 	EImportTarget *import_target;
 105 	EImportImporter *import_importer;
 106 };
 107 
 108 enum {
 109 	PAGE_START,
 110 	PAGE_INTELI_OR_DIRECT,
 111 	PAGE_INTELI_SOURCE,
 112 	PAGE_FILE_CHOOSE,
 113 	PAGE_FILE_DEST,
 114 	PAGE_FINISH,
 115 	PAGE_PROGRESS
 116 };
 117 
 118 enum {
 119 	PROP_0,
 120 	PROP_IS_SIMPLE
 121 };
 122 
 123 enum {
 124 	FINISHED,
 125 	LAST_SIGNAL
 126 };
 127 
 128 static guint signals[LAST_SIGNAL];
 129 
 130 G_DEFINE_TYPE_WITH_CODE (
 131 	EImportAssistant,
 132 	e_import_assistant,
 133 	GTK_TYPE_ASSISTANT,
 134 	G_IMPLEMENT_INTERFACE (
 135 		E_TYPE_EXTENSIBLE, NULL))
 136 
 137 /* Importing functions */
 138 
 139 static void
 140 import_assistant_emit_finished (EImportAssistant *import_assistant)
 141 {
 142 	g_signal_emit (import_assistant, signals[FINISHED], 0);
 143 }
 144 
 145 static void
 146 filename_changed (GtkWidget *widget,
 147                   GtkAssistant *assistant)
 148 {
 149 	EImportAssistantPrivate *priv;
 150 	ImportFilePage *page;
 151 	const gchar *filename;
 152 	gint fileok;
 153 
 154 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 155 	page = &priv->file_page;
 156 
 157 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
 158 
 159 	fileok =
 160 		filename != NULL && *filename != '\0' &&
 161 		g_file_test (filename, G_FILE_TEST_IS_REGULAR);
 162 
 163 	if (fileok) {
 164 		GtkTreeIter iter;
 165 		GtkTreeModel *model;
 166 		gboolean valid;
 167 		GSList *l;
 168 		EImportImporter *first = NULL;
 169 		gint i = 0, firstitem = 0;
 170 
 171 		g_free (page->target->uri_src);
 172 		page->target->uri_src = g_filename_to_uri (filename, NULL, NULL);
 173 
 174 		l = e_import_get_importers (
 175 			priv->import, (EImportTarget *) page->target);
 176 		model = gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype));
 177 		valid = gtk_tree_model_get_iter_first (model, &iter);
 178 		while (valid) {
 179 			gpointer eii = NULL;
 180 
 181 			gtk_tree_model_get (model, &iter, 2, &eii, -1);
 182 
 183 			if (g_slist_find (l, eii) != NULL) {
 184 				if (first == NULL) {
 185 					firstitem = i;
 186 					first = eii;
 187 				}
 188 				gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, TRUE, -1);
 189 			} else {
 190 				if (page->importer == eii)
 191 					page->importer = NULL;
 192 				gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, FALSE, -1);
 193 			}
 194 			i++;
 195 			valid = gtk_tree_model_iter_next (model, &iter);
 196 		}
 197 		g_slist_free (l);
 198 
 199 		if (page->importer == NULL && first) {
 200 			page->importer = first;
 201 			gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), firstitem);
 202 		}
 203 		fileok = first != NULL;
 204 	} else {
 205 		GtkTreeIter iter;
 206 		GtkTreeModel *model;
 207 		gboolean valid;
 208 
 209 		model = gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype));
 210 		for (valid = gtk_tree_model_get_iter_first (model, &iter);
 211 		     valid;
 212 		     valid = gtk_tree_model_iter_next (model, &iter)) {
 213 			gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, FALSE, -1);
 214 		}
 215 	}
 216 
 217 	widget = gtk_assistant_get_nth_page (assistant, PAGE_FILE_CHOOSE);
 218 	gtk_assistant_set_page_complete (assistant, widget, fileok);
 219 }
 220 
 221 static void
 222 filetype_changed_cb (GtkComboBox *combo_box,
 223                      GtkAssistant *assistant)
 224 {
 225 	EImportAssistantPrivate *priv;
 226 	GtkTreeModel *model;
 227 	GtkTreeIter iter;
 228 
 229 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 230 
 231 	g_return_if_fail (gtk_combo_box_get_active_iter (combo_box, &iter));
 232 
 233 	model = gtk_combo_box_get_model (combo_box);
 234 	gtk_tree_model_get (model, &iter, 2, &priv->file_page.importer, -1);
 235 	filename_changed (priv->file_page.filename, assistant);
 236 }
 237 
 238 static GtkWidget *
 239 import_assistant_file_page_init (EImportAssistant *import_assistant)
 240 {
 241 	GtkWidget *page;
 242 	GtkWidget *label;
 243 	GtkWidget *container;
 244 	GtkWidget *widget;
 245 	GtkCellRenderer *cell;
 246 	GtkListStore *store;
 247 	const gchar *text;
 248 	gint row = 0;
 249 
 250 	page = gtk_vbox_new (FALSE, 6);
 251 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 252 	gtk_widget_show (page);
 253 
 254 	container = page;
 255 
 256 	text = _("Choose the file that you want to import into Evolution, "
 257 		 "and select what type of file it is from the list.");
 258 
 259 	widget = gtk_label_new (text);
 260 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 261 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 262 	gtk_widget_show (widget);
 263 
 264 	widget = gtk_table_new (2, 2, FALSE);
 265 	gtk_table_set_row_spacings (GTK_TABLE (widget), 2);
 266 	gtk_table_set_col_spacings (GTK_TABLE (widget), 10);
 267 	gtk_container_set_border_width (GTK_CONTAINER (widget), 8);
 268 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
 269 	gtk_widget_show (widget);
 270 
 271 	container = widget;
 272 
 273 	widget = gtk_label_new_with_mnemonic (_("F_ilename:"));
 274 	gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
 275 	gtk_table_attach (
 276 		GTK_TABLE (container), widget,
 277 		0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
 278 	gtk_widget_show (widget);
 279 
 280 	label = widget;
 281 
 282 	widget = gtk_file_chooser_button_new (
 283 		_("Select a file"), GTK_FILE_CHOOSER_ACTION_OPEN);
 284 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
 285 	gtk_table_attach (
 286 		GTK_TABLE (container), widget, 1, 2,
 287 		row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
 288 	import_assistant->priv->file_page.filename = widget;
 289 	gtk_widget_show (widget);
 290 
 291 	g_signal_connect (
 292 		widget, "selection-changed",
 293 		G_CALLBACK (filename_changed), import_assistant);
 294 
 295 	row++;
 296 
 297 	widget = gtk_label_new_with_mnemonic (_("File _type:"));
 298 	gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
 299 	gtk_table_attach (
 300 		GTK_TABLE (container), widget,
 301 		0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
 302 	gtk_widget_show (widget);
 303 
 304 	label = widget;
 305 
 306 	store = gtk_list_store_new (
 307 		3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
 308 	widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
 309 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
 310 	gtk_table_attach (
 311 		GTK_TABLE (container), widget,
 312 		1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
 313 	import_assistant->priv->file_page.filetype = widget;
 314 	gtk_widget_show (widget);
 315 	g_object_unref (store);
 316 
 317 	cell = gtk_cell_renderer_text_new ();
 318 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE);
 319 	gtk_cell_layout_set_attributes (
 320 		GTK_CELL_LAYOUT (widget), cell,
 321 		"text", 0, "sensitive", 1, NULL);
 322 
 323 	return page;
 324 }
 325 
 326 static GtkWidget *
 327 import_assistant_destination_page_init (EImportAssistant *import_assistant)
 328 {
 329 	GtkWidget *page;
 330 	GtkWidget *container;
 331 	GtkWidget *widget;
 332 	const gchar *text;
 333 
 334 	page = gtk_vbox_new (FALSE, 6);
 335 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 336 	gtk_widget_show (page);
 337 
 338 	container = page;
 339 
 340 	text = _("Choose the destination for this import");
 341 
 342 	widget = gtk_label_new (text);
 343 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 344 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 345 	gtk_widget_show (widget);
 346 
 347 	return page;
 348 }
 349 
 350 static GtkWidget *
 351 import_assistant_type_page_init (EImportAssistant *import_assistant)
 352 {
 353 	GtkRadioButton *radio_button;
 354 	GtkWidget *page;
 355 	GtkWidget *container;
 356 	GtkWidget *widget;
 357 	const gchar *text;
 358 
 359 	page = gtk_vbox_new (FALSE, 6);
 360 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 361 	gtk_widget_show (page);
 362 
 363 	container = page;
 364 
 365 	text = _("Choose the type of importer to run:");
 366 
 367 	widget = gtk_label_new (text);
 368 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 369 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 370 	gtk_widget_show (widget);
 371 
 372 	widget = gtk_radio_button_new_with_mnemonic (
 373 		NULL, _("Import data and settings from _older programs"));
 374 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 375 	import_assistant->priv->type_page.intelligent = widget;
 376 	gtk_widget_show (widget);
 377 
 378 	radio_button = GTK_RADIO_BUTTON (widget);
 379 
 380 	widget = gtk_radio_button_new_with_mnemonic_from_widget (
 381 		radio_button, _("Import a _single file"));
 382 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 383 	import_assistant->priv->type_page.file = widget;
 384 	gtk_widget_show (widget);
 385 
 386 	return page;
 387 }
 388 
 389 static GtkWidget *
 390 import_assistant_selection_page_init (EImportAssistant *import_assistant)
 391 {
 392 	GtkWidget *page;
 393 	GtkWidget *container;
 394 	GtkWidget *widget;
 395 	const gchar *text;
 396 
 397 	page = gtk_vbox_new (FALSE, 6);
 398 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 399 	gtk_widget_show (page);
 400 
 401 	container = page;
 402 
 403 	text = _("Please select the information "
 404 		 "that you would like to import:");
 405 
 406 	widget = gtk_label_new (text);
 407 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 408 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 409 	gtk_widget_show (widget);
 410 
 411 	widget = gtk_hseparator_new ();
 412 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 413 	gtk_widget_show (widget);
 414 
 415 	return page;
 416 }
 417 
 418 static GtkWidget *
 419 import_assistant_progress_page_init (EImportAssistant *import_assistant)
 420 {
 421 	GtkWidget *page;
 422 	GtkWidget *container;
 423 	GtkWidget *widget;
 424 
 425 	page = gtk_vbox_new (FALSE, 6);
 426 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 427 	gtk_widget_show (page);
 428 
 429 	container = page;
 430 
 431 	widget = gtk_progress_bar_new ();
 432 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, FALSE, 0);
 433 	import_assistant->priv->progress_page.progress_bar = widget;
 434 	gtk_widget_show (widget);
 435 
 436 	return page;
 437 }
 438 
 439 static GtkWidget *
 440 import_assistant_simple_page_init (EImportAssistant *import_assistant)
 441 {
 442 	GtkWidget *page;
 443 	GtkWidget *label;
 444 	GtkWidget *container;
 445 	GtkWidget *widget;
 446 	GtkCellRenderer *cell;
 447 	GtkListStore *store;
 448 	gint row = 0;
 449 
 450 	page = gtk_vbox_new (FALSE, 6);
 451 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 452 	gtk_widget_show (page);
 453 
 454 	container = page;
 455 
 456 	widget = gtk_label_new ("");
 457 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 458 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 459 	gtk_widget_show (widget);
 460 	import_assistant->priv->simple_page.actionlabel = widget;
 461 
 462 	widget = gtk_table_new (2, 1, FALSE);
 463 	gtk_table_set_row_spacings (GTK_TABLE (widget), 2);
 464 	gtk_table_set_col_spacings (GTK_TABLE (widget), 10);
 465 	gtk_container_set_border_width (GTK_CONTAINER (widget), 8);
 466 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
 467 	gtk_widget_show (widget);
 468 	import_assistant->priv->simple_page.filetypetable = widget;
 469 
 470 	container = widget;
 471 
 472 	widget = gtk_label_new_with_mnemonic (_("File _type:"));
 473 	gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
 474 	gtk_table_attach (
 475 		GTK_TABLE (container), widget,
 476 		0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
 477 	gtk_widget_show (widget);
 478 
 479 	label = widget;
 480 
 481 	store = gtk_list_store_new (
 482 		3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
 483 	widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
 484 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
 485 	gtk_table_attach (
 486 		GTK_TABLE (container), widget,
 487 		1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
 488 	import_assistant->priv->simple_page.filetype = widget;
 489 	gtk_widget_show (widget);
 490 	g_object_unref (store);
 491 
 492 	cell = gtk_cell_renderer_text_new ();
 493 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE);
 494 	gtk_cell_layout_set_attributes (
 495 		GTK_CELL_LAYOUT (widget), cell,
 496 		"text", 0, "sensitive", 1, NULL);
 497 
 498 	import_assistant->priv->simple_page.control = NULL;
 499 
 500 	return page;
 501 }
 502 
 503 static void
 504 prepare_intelligent_page (GtkAssistant *assistant,
 505                           GtkWidget *vbox)
 506 {
 507 	EImportAssistantPrivate *priv;
 508 	GSList *l;
 509 	GtkWidget *table;
 510 	gint row;
 511 	ImportSelectionPage *page;
 512 
 513 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 514 	page = &priv->selection_page;
 515 
 516 	if (page->target != NULL) {
 517 		gtk_assistant_set_page_complete (assistant, vbox, FALSE);
 518 		return;
 519 	}
 520 
 521 	page->target = e_import_target_new_home (priv->import);
 522 
 523 	if (page->importers)
 524 		g_slist_free (page->importers);
 525 	l = page->importers =
 526 		e_import_get_importers (
 527 			priv->import, (EImportTarget *) page->target);
 528 
 529 	if (l == NULL) {
 530 		GtkWidget *widget;
 531 		const gchar *text;
 532 
 533 		text = _("Evolution checked for settings to import from "
 534 			 "the following applications: Pine, Netscape, Elm, "
 535 			 "iCalendar. No importable settings found. If you "
 536 			 "would like to try again, please click the "
 537 			 "\"Back\" button.");
 538 
 539 		widget = gtk_label_new (text);
 540 		gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 541 		gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0);
 542 		gtk_widget_show (widget);
 543 
 544 		gtk_assistant_set_page_complete (assistant, vbox, FALSE);
 545 
 546 		return;
 547 	}
 548 
 549 	table = gtk_table_new (g_slist_length (l), 2, FALSE);
 550 	row = 0;
 551 	for (; l; l = l->next) {
 552 		EImportImporter *eii = l->data;
 553 		gchar *str;
 554 		GtkWidget *w, *label;
 555 
 556 		w = e_import_get_widget (
 557 			priv->import, (EImportTarget *) page->target, eii);
 558 
 559 		str = g_strdup_printf (_("From %s:"), eii->name);
 560 		label = gtk_label_new (str);
 561 		gtk_widget_show (label);
 562 		g_free (str);
 563 
 564 		gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
 565 
 566 		gtk_table_attach (
 567 			GTK_TABLE (table), label,
 568 			0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
 569 		if (w)
 570 			gtk_table_attach (
 571 				GTK_TABLE (table), w,
 572 				1, 2, row, row + 1, GTK_FILL, 0, 3, 0);
 573 		row++;
 574 	}
 575 
 576 	gtk_widget_show (table);
 577 	gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
 578 
 579 	gtk_assistant_set_page_complete (assistant, vbox, TRUE);
 580 }
 581 
 582 static void
 583 import_status (EImport *import,
 584                const gchar *what,
 585                gint percent,
 586                gpointer user_data)
 587 {
 588 	EImportAssistant *import_assistant = user_data;
 589 	GtkProgressBar *progress_bar;
 590 
 591 	progress_bar = GTK_PROGRESS_BAR (
 592 		import_assistant->priv->progress_page.progress_bar);
 593 	gtk_progress_bar_set_fraction (progress_bar, percent / 100.0);
 594 	gtk_progress_bar_set_text (progress_bar, what);
 595 }
 596 
 597 static void
 598 import_done (EImport *ei,
 599              gpointer user_data)
 600 {
 601 	EImportAssistant *import_assistant = user_data;
 602 
 603 	import_assistant_emit_finished (import_assistant);
 604 }
 605 
 606 static void
 607 import_simple_done (EImport *ei,
 608                     gpointer user_data)
 609 {
 610 	EImportAssistant *import_assistant = user_data;
 611 	EImportAssistantPrivate *priv;
 612 
 613 	g_return_if_fail (import_assistant != NULL);
 614 
 615 	priv = import_assistant->priv;
 616 	g_return_if_fail (priv != NULL);
 617 	g_return_if_fail (priv->fileuris != NULL);
 618 	g_return_if_fail (priv->simple_page.target != NULL);
 619 
 620 	if (import_assistant->priv->fileuris->len > 0) {
 621 		import_status (ei, "", 0, import_assistant);
 622 
 623 		/* process next file URI */
 624 		g_free (priv->simple_page.target->uri_src);
 625 		priv->simple_page.target->uri_src =
 626 			g_ptr_array_remove_index (priv->fileuris, 0);
 627 
 628 		e_import_import (
 629 			priv->import, priv->import_target,
 630 			priv->import_importer, import_status,
 631 			import_simple_done, import_assistant);
 632 	} else
 633 		import_done (ei, import_assistant);
 634 }
 635 
 636 static void
 637 import_intelligent_done (EImport *ei,
 638                          gpointer user_data)
 639 {
 640 	EImportAssistant *import_assistant = user_data;
 641 	ImportSelectionPage *page;
 642 
 643 	page = &import_assistant->priv->selection_page;
 644 
 645 	if (page->current && (page->current = page->current->next)) {
 646 		import_status (ei, "", 0, import_assistant);
 647 		import_assistant->priv->import_importer = page->current->data;
 648 		e_import_import (
 649 			import_assistant->priv->import,
 650 			(EImportTarget *) page->target,
 651 			import_assistant->priv->import_importer,
 652 			import_status, import_intelligent_done,
 653 			import_assistant);
 654 	} else
 655 		import_done (ei, import_assistant);
 656 }
 657 
 658 static void
 659 import_cancelled (EImportAssistant *assistant)
 660 {
 661 	e_import_cancel (
 662 		assistant->priv->import,
 663 		assistant->priv->import_target,
 664 		assistant->priv->import_importer);
 665 }
 666 
 667 static void
 668 prepare_file_page (GtkAssistant *assistant,
 669                    GtkWidget *vbox)
 670 {
 671 	EImportAssistantPrivate *priv;
 672 	GSList *importers, *imp;
 673 	GtkListStore *store;
 674 	ImportFilePage *page;
 675 
 676 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 677 	page = &priv->file_page;
 678 
 679 	if (page->target != NULL) {
 680 		filename_changed (priv->file_page.filename, assistant);
 681 		return;
 682 	}
 683 
 684 	page->target = e_import_target_new_uri (priv->import, NULL, NULL);
 685 	importers = e_import_get_importers (priv->import, (EImportTarget *) page->target);
 686 
 687 	store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype)));
 688 	gtk_list_store_clear (store);
 689 
 690 	for (imp = importers; imp; imp = imp->next) {
 691 		GtkTreeIter iter;
 692 		EImportImporter *eii = imp->data;
 693 
 694 		gtk_list_store_append (store, &iter);
 695 		gtk_list_store_set (
 696 			store, &iter,
 697 			0, eii->name,
 698 			1, TRUE,
 699 			2, eii,
 700 			-1);
 701 	}
 702 
 703 	g_slist_free (importers);
 704 
 705 	gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), 0);
 706 
 707 	filename_changed (priv->file_page.filename, assistant);
 708 
 709 	g_signal_connect (
 710 		page->filetype, "changed",
 711 		G_CALLBACK (filetype_changed_cb), assistant);
 712 }
 713 
 714 static GtkWidget *
 715 create_importer_control (EImport *import,
 716                          EImportTarget *target,
 717                          EImportImporter *importer)
 718 {
 719 	GtkWidget *control;
 720 
 721 	control = e_import_get_widget (import, target, importer);
 722 	if (control == NULL) {
 723 		/* Coding error, not needed for translators */
 724 		control = gtk_label_new (
 725 			"** PLUGIN ERROR ** No settings for importer");
 726 		gtk_widget_show (control);
 727 	}
 728 
 729 	return control;
 730 }
 731 
 732 static gboolean
 733 prepare_destination_page (GtkAssistant *assistant,
 734                           GtkWidget *vbox)
 735 {
 736 	EImportAssistantPrivate *priv;
 737 	ImportDestinationPage *page;
 738 
 739 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 740 	page = &priv->destination_page;
 741 
 742 	if (page->control)
 743 		gtk_container_remove (GTK_CONTAINER (vbox), page->control);
 744 
 745 	page->control = create_importer_control (
 746 		priv->import, (EImportTarget *)
 747 		priv->file_page.target, priv->file_page.importer);
 748 
 749 	gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0);
 750 	gtk_assistant_set_page_complete (assistant, vbox, TRUE);
 751 
 752 	return FALSE;
 753 }
 754 
 755 static void
 756 prepare_progress_page (GtkAssistant *assistant,
 757                        GtkWidget *vbox)
 758 {
 759 	EImportAssistantPrivate *priv;
 760 	EImportCompleteFunc done = NULL;
 761 	ImportSelectionPage *page;
 762 	GtkWidget *cancel_button;
 763 	gboolean intelligent_import;
 764 	gboolean is_simple = FALSE;
 765 
 766 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 767 	page = &priv->selection_page;
 768 
 769 	/* Because we're a GTK_ASSISTANT_PAGE_PROGRESS, this will
 770 	 * prevent the assistant window from being closed via window
 771 	 * manager decorations while importing. */
 772 	gtk_assistant_commit (assistant);
 773 
 774 	/* Install a custom "Cancel Import" button. */
 775 	cancel_button = gtk_button_new_with_mnemonic (_("_Cancel Import"));
 776 	gtk_button_set_image (
 777 		GTK_BUTTON (cancel_button),
 778 		gtk_image_new_from_stock (
 779 		GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON));
 780 	g_signal_connect_swapped (
 781 		cancel_button, "clicked",
 782 		G_CALLBACK (import_cancelled), assistant);
 783 	gtk_assistant_add_action_widget (assistant, cancel_button);
 784 	gtk_widget_show (cancel_button);
 785 
 786 	g_object_get (assistant, "is-simple", &is_simple, NULL);
 787 
 788 	intelligent_import = is_simple ? FALSE : gtk_toggle_button_get_active (
 789 		GTK_TOGGLE_BUTTON (priv->type_page.intelligent));
 790 
 791 	if (is_simple) {
 792 		priv->import_importer = priv->simple_page.importer;
 793 		priv->import_target = (EImportTarget *) priv->simple_page.target;
 794 		done = import_simple_done;
 795 	} else if (intelligent_import) {
 796 		page->current = page->importers;
 797 		if (page->current) {
 798 			priv->import_target = (EImportTarget *) page->target;
 799 			priv->import_importer = page->current->data;
 800 			done = import_intelligent_done;
 801 		}
 802 	} else {
 803 		if (priv->file_page.importer) {
 804 			priv->import_importer = priv->file_page.importer;
 805 			priv->import_target = (EImportTarget *) priv->file_page.target;
 806 			done = import_done;
 807 		}
 808 	}
 809 
 810 	if (done)
 811 		e_import_import (
 812 			priv->import, priv->import_target,
 813 			priv->import_importer, import_status,
 814 			done, assistant);
 815 	else
 816 		import_assistant_emit_finished (E_IMPORT_ASSISTANT (assistant));
 817 }
 818 
 819 static void
 820 simple_filetype_changed_cb (GtkComboBox *combo_box,
 821                             GtkAssistant *assistant)
 822 {
 823 	EImportAssistantPrivate *priv;
 824 	ImportSimplePage *page;
 825 	GtkTreeModel *model;
 826 	GtkTreeIter iter;
 827 	GtkWidget *vbox;
 828 	GtkWidget *control;
 829 
 830 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 831 	page = &priv->simple_page;
 832 
 833 	g_return_if_fail (gtk_combo_box_get_active_iter (combo_box, &iter));
 834 
 835 	model = gtk_combo_box_get_model (combo_box);
 836 	gtk_tree_model_get (model, &iter, 2, &page->importer, -1);
 837 
 838 	vbox = g_object_get_data (G_OBJECT (combo_box), "page-vbox");
 839 	g_return_if_fail (vbox != NULL);
 840 
 841 	if (page->control)
 842 		gtk_widget_destroy (page->control);
 843 	page->has_preview = FALSE;
 844 
 845 	control = e_import_get_preview_widget (
 846 		priv->import, (EImportTarget *)
 847 		page->target, page->importer);
 848 	if (control) {
 849 		page->has_preview = TRUE;
 850 		gtk_widget_set_size_request (control, 440, 360);
 851 	} else
 852 		control = create_importer_control (
 853 			priv->import, (EImportTarget *)
 854 			page->target, page->importer);
 855 
 856 	page->control = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
 857 	gtk_widget_show (page->control);
 858 	gtk_container_add (GTK_CONTAINER (page->control), control);
 859 
 860 	gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0);
 861 	gtk_assistant_set_page_complete (assistant, vbox, TRUE);
 862 }
 863 
 864 static void
 865 prepare_simple_page (GtkAssistant *assistant,
 866                      GtkWidget *vbox)
 867 {
 868 	EImportAssistantPrivate *priv;
 869 	GSList *importers, *imp;
 870 	GtkListStore *store;
 871 	ImportSimplePage *page;
 872 	gchar *uri;
 873 
 874 	priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
 875 	page = &priv->simple_page;
 876 
 877 	g_return_if_fail (priv->fileuris != NULL);
 878 
 879 	if (page->target != NULL) {
 880 		return;
 881 	}
 882 
 883 	uri = g_ptr_array_remove_index (priv->fileuris, 0);
 884 	page->target = e_import_target_new_uri (priv->import, uri, NULL);
 885 	g_free (uri);
 886 	importers = e_import_get_importers (priv->import, (EImportTarget *) page->target);
 887 
 888 	store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (page->filetype)));
 889 	gtk_list_store_clear (store);
 890 
 891 	for (imp = importers; imp; imp = imp->next) {
 892 		GtkTreeIter iter;
 893 		EImportImporter *eii = imp->data;
 894 
 895 		gtk_list_store_append (store, &iter);
 896 		gtk_list_store_set (
 897 			store, &iter,
 898 			0, eii->name,
 899 			1, TRUE,
 900 			2, eii,
 901 			-1);
 902 	}
 903 
 904 	gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), 0);
 905 	g_object_set_data (G_OBJECT (page->filetype), "page-vbox", vbox);
 906 
 907 	simple_filetype_changed_cb (GTK_COMBO_BOX (page->filetype), assistant);
 908 
 909 	g_signal_connect (
 910 		page->filetype, "changed",
 911 		G_CALLBACK (simple_filetype_changed_cb), assistant);
 912 
 913 	if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1) {
 914 		gchar *title;
 915 
 916 		/* only one importer found, make it even simpler */
 917 		gtk_label_set_text (
 918 			GTK_LABEL (page->actionlabel),
 919 			page->has_preview ?
 920 				_("Preview data to be imported") :
 921 				_("Choose the destination for this import"));
 922 
 923 		gtk_widget_hide (page->filetypetable);
 924 
 925 		title = g_strconcat (
 926 			_("Import Data"), " - ",
 927 			((EImportImporter *) importers->data)->name, NULL);
Access to field 'data' results in a dereference of a null pointer (loaded from variable 'importers')
(emitted by clang-analyzer)

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

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

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

928 gtk_assistant_set_page_title (assistant, vbox, title); 929 g_free (title); 930 } else { 931 /* multiple importers found, be able to choose from them */ 932 gtk_label_set_text ( 933 GTK_LABEL (page->actionlabel), 934 _("Select what type of file you " 935 "want to import from the list.")); 936 937 gtk_widget_show (page->filetypetable); 938 939 gtk_assistant_set_page_title (assistant, vbox, _("Import Data")); 940 } 941 942 g_slist_free (importers); 943 } 944 945 static gboolean 946 prepare_simple_destination_page (GtkAssistant *assistant, 947 GtkWidget *vbox) 948 { 949 EImportAssistantPrivate *priv; 950 ImportDestinationPage *page; 951 ImportSimplePage *simple_page; 952 953 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); 954 page = &priv->destination_page; 955 simple_page = &priv->simple_page; 956 957 if (page->control) 958 gtk_container_remove (GTK_CONTAINER (vbox), page->control); 959 960 page->control = create_importer_control ( 961 priv->import, (EImportTarget *) 962 simple_page->target, simple_page->importer); 963 964 gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0); 965 gtk_assistant_set_page_complete (assistant, vbox, TRUE); 966 967 return FALSE; 968 } 969 970 static gint 971 forward_cb (gint current_page, 972 EImportAssistant *import_assistant) 973 { 974 GtkToggleButton *toggle_button; 975 gboolean is_simple = FALSE; 976 977 g_object_get (import_assistant, "is-simple", &is_simple, NULL); 978 979 if (is_simple) { 980 if (!import_assistant->priv->simple_page.has_preview) 981 current_page++; 982 983 return current_page + 1; 984 } 985 986 toggle_button = GTK_TOGGLE_BUTTON ( 987 import_assistant->priv->type_page.intelligent); 988 989 switch (current_page) { 990 case PAGE_INTELI_OR_DIRECT: 991 if (gtk_toggle_button_get_active (toggle_button)) 992 return PAGE_INTELI_SOURCE; 993 else 994 return PAGE_FILE_CHOOSE; 995 case PAGE_INTELI_SOURCE: 996 return PAGE_FINISH; 997 } 998 999 return current_page + 1; 1000 } 1001 1002 static gboolean 1003 set_import_uris (EImportAssistant *assistant, 1004 const gchar * const *uris) 1005 { 1006 EImportAssistantPrivate *priv; 1007 GPtrArray *fileuris = NULL; 1008 gint i; 1009 1010 g_return_val_if_fail (assistant != NULL, FALSE); 1011 g_return_val_if_fail (assistant->priv != NULL, FALSE); 1012 g_return_val_if_fail (assistant->priv->import != NULL, FALSE); 1013 g_return_val_if_fail (uris != NULL, FALSE); 1014 1015 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant); 1016 1017 for (i = 0; uris[i]; i++) { 1018 const gchar *uri = uris[i]; 1019 gchar *filename; 1020 1021 filename = g_filename_from_uri (uri, NULL, NULL); 1022 if (!filename) 1023 filename = g_strdup (uri); 1024 1025 if (filename && *filename && 1026 g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { 1027 gchar *furi; 1028 1029 if (!g_path_is_absolute (filename)) { 1030 gchar *tmp, *curr; 1031 1032 curr = g_get_current_dir (); 1033 tmp = g_build_filename (curr, filename, NULL); 1034 g_free (curr); 1035 1036 g_free (filename); 1037 filename = tmp; 1038 } 1039 1040 if (fileuris == NULL) { 1041 EImportTargetURI *target; 1042 GSList *importers; 1043 1044 furi = g_filename_to_uri (filename, NULL, NULL); 1045 target = e_import_target_new_uri (priv->import, furi, NULL); 1046 importers = e_import_get_importers ( 1047 priv->import, (EImportTarget *) target); 1048 1049 if (importers != NULL) { 1050 /* there is at least one importer which can be used, 1051 * thus there can be done an import */ 1052 fileuris = g_ptr_array_new (); 1053 } 1054 1055 g_slist_free (importers); 1056 e_import_target_free (priv->import, target); 1057 g_free (furi); 1058 1059 if (fileuris == NULL) { 1060 g_free (filename); 1061 break; 1062 } 1063 } 1064 1065 furi = g_filename_to_uri (filename, NULL, NULL); 1066 if (furi) 1067 g_ptr_array_add (fileuris, furi); 1068 } 1069 1070 g_free (filename); 1071 } 1072 1073 if (fileuris != NULL) { 1074 priv->fileuris = fileuris; 1075 } 1076 1077 return fileuris != NULL; 1078 } 1079 1080 static void 1081 import_assistant_set_property (GObject *object, 1082 guint property_id, 1083 const GValue *value, 1084 GParamSpec *pspec) 1085 { 1086 EImportAssistantPrivate *priv; 1087 1088 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); 1089 1090 switch (property_id) { 1091 case PROP_IS_SIMPLE: 1092 priv->is_simple = g_value_get_boolean (value); 1093 return; 1094 } 1095 1096 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 1097 } 1098 1099 static void 1100 import_assistant_get_property (GObject *object, 1101 guint property_id, 1102 GValue *value, 1103 GParamSpec *pspec) 1104 { 1105 EImportAssistantPrivate *priv; 1106 1107 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); 1108 1109 switch (property_id) { 1110 case PROP_IS_SIMPLE: 1111 g_value_set_boolean (value, priv->is_simple); 1112 return; 1113 } 1114 1115 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 1116 } 1117 1118 static void 1119 import_assistant_dispose (GObject *object) 1120 { 1121 EImportAssistantPrivate *priv; 1122 1123 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); 1124 1125 if (priv->file_page.target != NULL) { 1126 e_import_target_free ( 1127 priv->import, (EImportTarget *) 1128 priv->file_page.target); 1129 priv->file_page.target = NULL; 1130 } 1131 1132 if (priv->selection_page.target != NULL) { 1133 e_import_target_free ( 1134 priv->import, (EImportTarget *) 1135 priv->selection_page.target); 1136 priv->selection_page.target = NULL; 1137 } 1138 1139 if (priv->simple_page.target != NULL) { 1140 e_import_target_free ( 1141 priv->import, (EImportTarget *) 1142 priv->simple_page.target); 1143 priv->simple_page.target = NULL; 1144 } 1145 1146 if (priv->import != NULL) { 1147 g_object_unref (priv->import); 1148 priv->import = NULL; 1149 } 1150 1151 if (priv->fileuris != NULL) { 1152 g_ptr_array_foreach (priv->fileuris, (GFunc) g_free, NULL); 1153 g_ptr_array_free (priv->fileuris, TRUE); 1154 priv->fileuris = NULL; 1155 } 1156 1157 /* Chain up to parent's dispose() method. */ 1158 G_OBJECT_CLASS (e_import_assistant_parent_class)->dispose (object); 1159 } 1160 1161 static void 1162 import_assistant_finalize (GObject *object) 1163 { 1164 EImportAssistantPrivate *priv; 1165 1166 priv = E_IMPORT_ASSISTANT_GET_PRIVATE (object); 1167 1168 g_slist_free (priv->selection_page.importers); 1169 1170 /* Chain up to parent's finalize() method. */ 1171 G_OBJECT_CLASS (e_import_assistant_parent_class)->finalize (object); 1172 } 1173 1174 static gboolean 1175 import_assistant_key_press_event (GtkWidget *widget, 1176 GdkEventKey *event) 1177 { 1178 GtkWidgetClass *parent_class; 1179 1180 if (event->keyval == GDK_KEY_Escape) { 1181 g_signal_emit_by_name (widget, "cancel"); 1182 return TRUE; 1183 } 1184 1185 /* Chain up to parent's key_press_event () method. */ 1186 parent_class = GTK_WIDGET_CLASS (e_import_assistant_parent_class); 1187 return parent_class->key_press_event (widget, event); 1188 } 1189 1190 static void 1191 import_assistant_prepare (GtkAssistant *assistant, 1192 GtkWidget *page) 1193 { 1194 gint page_no = gtk_assistant_get_current_page (assistant); 1195 gboolean is_simple = FALSE; 1196 1197 g_object_get (assistant, "is-simple", &is_simple, NULL); 1198 1199 if (is_simple) { 1200 if (page_no == 0) { 1201 prepare_simple_page (assistant, page); 1202 } else if (page_no == 1) { 1203 prepare_simple_destination_page (assistant, page); 1204 } else if (page_no == 2) { 1205 prepare_progress_page (assistant, page); 1206 } 1207 1208 return; 1209 } 1210 1211 switch (page_no) { 1212 case PAGE_INTELI_SOURCE: 1213 prepare_intelligent_page (assistant, page); 1214 break; 1215 case PAGE_FILE_CHOOSE: 1216 prepare_file_page (assistant, page); 1217 break; 1218 case PAGE_FILE_DEST: 1219 prepare_destination_page (assistant, page); 1220 break; 1221 case PAGE_PROGRESS: 1222 prepare_progress_page (assistant, page); 1223 break; 1224 default: 1225 break; 1226 } 1227 } 1228 1229 static void 1230 e_import_assistant_class_init (EImportAssistantClass *class) 1231 { 1232 GObjectClass *object_class; 1233 GtkWidgetClass *widget_class; 1234 GtkAssistantClass *assistant_class; 1235 1236 g_type_class_add_private (class, sizeof (EImportAssistantPrivate)); 1237 1238 object_class = G_OBJECT_CLASS (class); 1239 object_class->dispose = import_assistant_dispose; 1240 object_class->finalize = import_assistant_finalize; 1241 object_class->set_property = import_assistant_set_property; 1242 object_class->get_property = import_assistant_get_property; 1243 1244 widget_class = GTK_WIDGET_CLASS (class); 1245 widget_class->key_press_event = import_assistant_key_press_event; 1246 1247 assistant_class = GTK_ASSISTANT_CLASS (class); 1248 assistant_class->prepare = import_assistant_prepare; 1249 1250 g_object_class_install_property ( 1251 object_class, 1252 PROP_IS_SIMPLE, 1253 g_param_spec_boolean ( 1254 "is-simple", 1255 NULL, 1256 NULL, 1257 FALSE, 1258 G_PARAM_READWRITE | 1259 G_PARAM_CONSTRUCT)); 1260 1261 signals[FINISHED] = g_signal_new ( 1262 "finished", 1263 G_TYPE_FROM_CLASS (class), 1264 G_SIGNAL_RUN_LAST, 1265 0, NULL, NULL, 1266 g_cclosure_marshal_VOID__VOID, 1267 G_TYPE_NONE, 0); 1268 } 1269 1270 static void 1271 import_assistant_construct (EImportAssistant *import_assistant) 1272 { 1273 GtkAssistant *assistant; 1274 GtkWidget *page; 1275 1276 assistant = GTK_ASSISTANT (import_assistant); 1277 1278 import_assistant->priv->import = 1279 e_import_new ("org.gnome.evolution.shell.importer"); 1280 1281 gtk_window_set_position (GTK_WINDOW (assistant), GTK_WIN_POS_CENTER); 1282 gtk_window_set_title (GTK_WINDOW (assistant), _("Evolution Import Assistant")); 1283 gtk_window_set_default_size (GTK_WINDOW (assistant), 500, 330); 1284 1285 e_extensible_load_extensions (E_EXTENSIBLE (import_assistant)); 1286 1287 if (import_assistant->priv->is_simple) { 1288 /* simple import assistant page, URIs of files will be known later */ 1289 page = import_assistant_simple_page_init (import_assistant); 1290 1291 gtk_assistant_append_page (assistant, page); 1292 gtk_assistant_set_page_title (assistant, page, _("Import Data")); 1293 gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1294 1295 /* File destination page - when with preview*/ 1296 page = import_assistant_destination_page_init (import_assistant); 1297 1298 gtk_assistant_append_page (assistant, page); 1299 gtk_assistant_set_page_title (assistant, page, _("Import Location")); 1300 gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1301 } else { 1302 /* complex import assistant pages */ 1303 1304 /* Start page */ 1305 page = gtk_label_new (""); 1306 gtk_label_set_line_wrap (GTK_LABEL (page), TRUE); 1307 gtk_misc_set_alignment (GTK_MISC (page), 0.0, 0.5); 1308 gtk_misc_set_padding (GTK_MISC (page), 12, 12); 1309 gtk_label_set_text (GTK_LABEL (page), _( 1310 "Welcome to the Evolution Import Assistant.\n" 1311 "With this assistant you will be guided through the " 1312 "process of importing external files into Evolution.")); 1313 gtk_widget_show (page); 1314 1315 gtk_assistant_append_page (assistant, page); 1316 gtk_assistant_set_page_title ( 1317 assistant, page, _("Evolution Import Assistant")); 1318 gtk_assistant_set_page_type ( 1319 assistant, page, GTK_ASSISTANT_PAGE_INTRO); 1320 gtk_assistant_set_page_complete (assistant, page, TRUE); 1321 1322 /* Intelligent or direct import page */ 1323 page = import_assistant_type_page_init (import_assistant); 1324 1325 gtk_assistant_append_page (assistant, page); 1326 gtk_assistant_set_page_title ( 1327 assistant, page, _("Importer Type")); 1328 gtk_assistant_set_page_type ( 1329 assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1330 gtk_assistant_set_page_complete (assistant, page, TRUE); 1331 1332 /* Intelligent importer source page */ 1333 page = import_assistant_selection_page_init (import_assistant); 1334 1335 gtk_assistant_append_page (assistant, page); 1336 gtk_assistant_set_page_title ( 1337 assistant, page, _("Select Information to Import")); 1338 gtk_assistant_set_page_type ( 1339 assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1340 1341 /* File selection and file type page */ 1342 page = import_assistant_file_page_init (import_assistant); 1343 1344 gtk_assistant_append_page (assistant, page); 1345 gtk_assistant_set_page_title ( 1346 assistant, page, _("Select a File")); 1347 gtk_assistant_set_page_type ( 1348 assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1349 1350 /* File destination page */ 1351 page = import_assistant_destination_page_init (import_assistant); 1352 1353 gtk_assistant_append_page (assistant, page); 1354 gtk_assistant_set_page_title ( 1355 assistant, page, _("Import Location")); 1356 gtk_assistant_set_page_type ( 1357 assistant, page, GTK_ASSISTANT_PAGE_CONTENT); 1358 1359 /* Finish page */ 1360 page = gtk_label_new (""); 1361 gtk_misc_set_alignment (GTK_MISC (page), 0.5, 0.5); 1362 gtk_label_set_text ( 1363 GTK_LABEL (page), _("Click \"Apply\" to " 1364 "begin importing the file into Evolution.")); 1365 gtk_widget_show (page); 1366 1367 gtk_assistant_append_page (assistant, page); 1368 gtk_assistant_set_page_title (assistant, page, _("Import Data")); 1369 gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM); 1370 gtk_assistant_set_page_complete (assistant, page, TRUE); 1371 } 1372 1373 /* Progress Page */ 1374 page = import_assistant_progress_page_init (import_assistant); 1375 1376 gtk_assistant_append_page (assistant, page); 1377 gtk_assistant_set_page_title (assistant, page, _("Import Data")); 1378 gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_PROGRESS); 1379 gtk_assistant_set_page_complete (assistant, page, TRUE); 1380 1381 gtk_assistant_set_forward_page_func ( 1382 assistant, (GtkAssistantPageFunc) 1383 forward_cb, import_assistant, NULL); 1384 1385 gtk_assistant_update_buttons_state (assistant); 1386 } 1387 1388 static void 1389 e_import_assistant_init (EImportAssistant *import_assistant) 1390 { 1391 import_assistant->priv = 1392 E_IMPORT_ASSISTANT_GET_PRIVATE (import_assistant); 1393 } 1394 1395 GtkWidget * 1396 e_import_assistant_new (GtkWindow *parent) 1397 { 1398 GtkWidget *assistant; 1399 1400 assistant = g_object_new ( 1401 E_TYPE_IMPORT_ASSISTANT, 1402 "transient-for", parent, NULL); 1403 1404 import_assistant_construct (E_IMPORT_ASSISTANT (assistant)); 1405 1406 return assistant; 1407 } 1408 1409 /* Creates a simple assistant with only page to choose an import type 1410 * and where to import, and then finishes. It shows import types based 1411 * on the first valid URI given. 1412 * 1413 * Returns: EImportAssistant widget. 1414 */ 1415 GtkWidget * 1416 e_import_assistant_new_simple (GtkWindow *parent, 1417 const gchar * const *uris) 1418 { 1419 GtkWidget *assistant; 1420 1421 assistant = g_object_new ( 1422 E_TYPE_IMPORT_ASSISTANT, 1423 "transient-for", parent, 1424 "is-simple", TRUE, 1425 NULL); 1426 1427 import_assistant_construct (E_IMPORT_ASSISTANT (assistant)); 1428 1429 if (!set_import_uris (E_IMPORT_ASSISTANT (assistant), uris)) { 1430 g_object_ref_sink (assistant); 1431 g_object_unref (assistant); 1432 return NULL; 1433 } 1434 1435 return assistant; 1436 }