static void
action_task_list_copy_cb (GtkAction *action,
                          ETaskShellView *task_shell_view)
{
	ETaskShellSidebar *task_shell_sidebar;
	EShell *shell;
	EShellView *shell_view;
	EShellWindow *shell_window;
	ESourceRegistry *registry;
	ESourceSelector *selector;
	ESource *source;

	shell_view = E_SHELL_VIEW (task_shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);
	shell = e_shell_window_get_shell (shell_window);

	registry = e_shell_get_registry (shell);

	task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
	selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
	source = e_source_selector_ref_primary_selection (selector);
	g_return_if_fail (source != NULL);

	copy_source_dialog (
		GTK_WINDOW (shell_window), registry,
		source, E_CAL_CLIENT_SOURCE_TYPE_TASKS);

	g_object_unref (source);
}
static void
action_task_list_new_cb (GtkAction *action,
                         ETaskShellView *task_shell_view)
{
	EShell *shell;
	EShellView *shell_view;
	EShellWindow *shell_window;
	ESourceRegistry *registry;
	ECalClientSourceType source_type;
	GtkWidget *config;
	GtkWidget *dialog;
	const gchar *icon_name;

	shell_view = E_SHELL_VIEW (task_shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);
	shell = e_shell_window_get_shell (shell_window);

	registry = e_shell_get_registry (shell);
	source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
	config = e_cal_source_config_new (registry, NULL, source_type);

	dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config));

	gtk_window_set_transient_for (
		GTK_WINDOW (dialog), GTK_WINDOW (shell_window));

	icon_name = gtk_action_get_icon_name (action);
	gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name);

	gtk_window_set_title (GTK_WINDOW (dialog), _("New Task List"));

	gtk_widget_show (dialog);
}
示例#3
0
static gchar *
set_organizer (ECalComponent *comp,
	       CamelMimeMessage *message,
	       CamelFolder *folder,
	       const gchar *message_uid)
{
	EShell *shell;
	ESource *source = NULL;
	ESourceRegistry *registry;
	ESourceMailIdentity *extension;
	const gchar *extension_name;
	const gchar *address, *name;
	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
	gchar *mailto = NULL;
	gchar *identity_name = NULL, *identity_address = NULL;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	source = em_utils_guess_mail_identity_with_recipients (registry, message, folder,
		message_uid, &identity_name, &identity_address);

	if (!source && folder) {
		CamelStore *store;

		store = camel_folder_get_parent_store (folder);
		source = em_utils_ref_mail_identity_for_store (registry, store);
	}

	if (source == NULL)
		source = e_source_registry_ref_default_mail_identity (registry);

	g_return_val_if_fail (source != NULL, NULL);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	extension = e_source_get_extension (source, extension_name);

	name = identity_name;
	if (!name || !*name)
		name = e_source_mail_identity_get_name (extension);

	address = identity_address;
	if (!address || !*address) {
		name = e_source_mail_identity_get_name (extension);
		address = e_source_mail_identity_get_address (extension);
	}

	if (address && *address) {
		mailto = g_strconcat ("mailto:", address, NULL);
		organizer.value = mailto;
		organizer.cn = name;
		e_cal_component_set_organizer (comp, &organizer);
	}

	g_object_unref (source);
	g_free (identity_name);
	g_free (identity_address);

	return mailto;
}
示例#4
0
static void
create_calendar_clicked_cb (GtkWidget *button,
			    ESourceSelector *selector)
{
	ESourceRegistry *registry;
	ECalClientSourceType source_type;
	GtkWidget *config;
	GtkWidget *dialog;
	GtkWidget *toplevel;
	GtkWindow *window;

	toplevel = gtk_widget_get_toplevel (button);
	if (!GTK_IS_WINDOW (toplevel))
		toplevel = NULL;

	registry = e_shell_get_registry (e_shell_get_default ());
	source_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "source-type"));
	config = e_cal_source_config_new (registry, NULL, source_type);

	dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config));
	window = GTK_WINDOW (dialog);

	if (toplevel)
		gtk_window_set_transient_for (window, GTK_WINDOW (toplevel));

	if (source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) {
		gtk_window_set_icon_name (window, "x-office-calendar");
		gtk_window_set_title (window, _("New Calendar"));
	} else {
		gtk_window_set_icon_name (window, "stock_todo");
		gtk_window_set_title (window, _("New Task List"));
	}

	gtk_widget_show (dialog);
}
void
e_task_shell_view_open_task (ETaskShellView *task_shell_view,
                             ECalModelComponent *comp_data)
{
	EShell *shell;
	EShellView *shell_view;
	EShellWindow *shell_window;
	ESourceRegistry *registry;
	CompEditor *editor;
	CompEditorFlags flags = 0;
	ECalComponent *comp;
	icalcomponent *clone;
	icalproperty *prop;
	const gchar *uid;

	g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view));
	g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));

	shell_view = E_SHELL_VIEW (task_shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);
	shell = e_shell_window_get_shell (shell_window);

	registry = e_shell_get_registry (shell);

	uid = icalcomponent_get_uid (comp_data->icalcomp);
	editor = comp_editor_find_instance (uid);

	if (editor != NULL)
		goto exit;

	comp = e_cal_component_new ();
	clone = icalcomponent_new_clone (comp_data->icalcomp);
	e_cal_component_set_icalcomponent (comp, clone);

	prop = icalcomponent_get_first_property (
		comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
	if (prop != NULL)
		flags |= COMP_EDITOR_IS_ASSIGNED;

	if (itip_organizer_is_user (registry, comp, comp_data->client))
		flags |= COMP_EDITOR_USER_ORG;

	if (!e_cal_component_has_attendees (comp))
		flags |= COMP_EDITOR_USER_ORG;

	editor = task_editor_new (comp_data->client, shell, flags);
	comp_editor_edit_comp (editor, comp);

	g_object_unref (comp);

	if (flags & COMP_EDITOR_IS_ASSIGNED)
		task_editor_show_assignment (TASK_EDITOR (editor));

exit:
	gtk_window_present (GTK_WINDOW (editor));
}
示例#6
0
static GtkWidget *
csv_getwidget (EImport *ei,
               EImportTarget *target,
               EImportImporter *im)
{
	EShell *shell;
	GtkWidget *vbox, *selector, *scrolled_window;
	ESourceRegistry *registry;
	ESource *primary;
	const gchar *extension_name;

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);
	extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;

	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	g_object_set (G_OBJECT (scrolled_window),
		"hscrollbar-policy", GTK_POLICY_AUTOMATIC,
		"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
		NULL);
	gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 6);

	selector = e_source_selector_new (registry, extension_name);
	e_source_selector_set_show_toggles (
		E_SOURCE_SELECTOR (selector), FALSE);
	gtk_container_add (GTK_CONTAINER (scrolled_window), selector);

	primary = g_datalist_get_data (&target->data, "csv-source");
	if (primary == NULL) {
		GList *list;

		list = e_source_registry_list_sources (registry, extension_name);
		if (list != NULL) {
			primary = g_object_ref (list->data);
			g_datalist_set_data_full (
				&target->data, "csv-source", primary,
				(GDestroyNotify) g_object_unref);
		}

		g_list_free_full (list, (GDestroyNotify) g_object_unref);
	}
	e_source_selector_set_primary_selection (
		E_SOURCE_SELECTOR (selector), primary);

	g_signal_connect (
		selector, "primary_selection_changed",
		G_CALLBACK (primary_selection_changed_cb), target);

	gtk_widget_show_all (vbox);

	return vbox;
}
示例#7
0
static gchar *
set_organizer (ECalComponent *comp,
               CamelFolder *folder)
{
	EShell *shell;
	ESource *source = NULL;
	ESourceRegistry *registry;
	ESourceMailIdentity *extension;
	const gchar *extension_name;
	const gchar *address, *name;
	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
	gchar *mailto = NULL;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	if (folder != NULL) {
		CamelStore *store;

		store = camel_folder_get_parent_store (folder);
		source = em_utils_ref_mail_identity_for_store (registry, store);
	}

	if (source == NULL)
		source = e_source_registry_ref_default_mail_identity (registry);

	g_return_val_if_fail (source != NULL, NULL);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	extension = e_source_get_extension (source, extension_name);

	name = e_source_mail_identity_get_name (extension);
	address = e_source_mail_identity_get_address (extension);

	if (name != NULL && address != NULL) {
		mailto = g_strconcat ("mailto:", address, NULL);
		organizer.value = mailto;
		organizer.cn = name;
		e_cal_component_set_organizer (comp, &organizer);
	}

	g_object_unref (source);

	return mailto;
}
示例#8
0
static void
open_default_source (ICalIntelligentImporter *ici,
                     ECalClientSourceType source_type,
                     void (* opened_cb) (ECalClient *cal_client,
                                         const GError *error,
                                         ICalIntelligentImporter *ici))
{
	EShell *shell;
	ESource *source;
	ESourceRegistry *registry;
	struct OpenDefaultSourceData *odsd;

	g_return_if_fail (ici != NULL);
	g_return_if_fail (opened_cb != NULL);

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	switch (source_type) {
		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
			source = e_source_registry_ref_default_calendar (registry);
			break;
		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
			source = e_source_registry_ref_default_task_list (registry);
			break;
		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
			source = e_source_registry_ref_default_memo_list (registry);
			break;
		default:
			g_return_if_reached ();
	}

	odsd = g_new0 (struct OpenDefaultSourceData, 1);
	odsd->ici = ici;
	odsd->opened_cb = opened_cb;

	e_import_status (ici->ei, ici->target, _("Opening calendar"), 0);

	e_cal_client_connect (
		source, source_type, 30, ici->cancellable,
		default_client_connect_cb, odsd);

	g_object_unref (source);
}
示例#9
0
static ECompEditor *
get_component_editor (EShell *shell,
                      ECalClient *client,
                      ECalComponent *comp,
                      gboolean is_new,
                      GError **error)
{
	ECompEditorFlags flags = 0;
	ECompEditor *comp_editor = NULL;
	ESourceRegistry *registry;

	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
	g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL);
	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), NULL);

	registry = e_shell_get_registry (shell);

	if (is_new) {
		flags |= E_COMP_EDITOR_FLAG_IS_NEW;
	} else {
		comp_editor = e_comp_editor_find_existing_for (
			e_client_get_source (E_CLIENT (client)),
			e_cal_component_get_icalcomponent (comp));
	}

	if (!comp_editor) {
		if (itip_organizer_is_user (registry, comp, client))
			flags |= E_COMP_EDITOR_FLAG_ORGANIZER_IS_USER;
		if (e_cal_component_has_attendees (comp))
			flags |= E_COMP_EDITOR_FLAG_WITH_ATTENDEES;

		comp_editor = e_comp_editor_open_for_component (NULL,
			shell, e_client_get_source (E_CLIENT (client)),
			e_cal_component_get_icalcomponent (comp), flags);

		if (comp_editor) {
			/* request save for new events */
			e_comp_editor_set_changed (comp_editor, is_new);
		}
	}

	return comp_editor;
}
static void
action_task_forward_cb (GtkAction *action,
                        ETaskShellView *task_shell_view)
{
	ETaskShellContent *task_shell_content;
	EShell *shell;
	EShellView *shell_view;
	EShellWindow *shell_window;
	ESourceRegistry *registry;
	ECalModelComponent *comp_data;
	ETaskTable *task_table;
	ECalComponent *comp;
	icalcomponent *clone;
	GSList *list;

	shell_view = E_SHELL_VIEW (task_shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);
	shell = e_shell_window_get_shell (shell_window);

	registry = e_shell_get_registry (shell);

	task_shell_content = task_shell_view->priv->task_shell_content;
	task_table = e_task_shell_content_get_task_table (task_shell_content);

	list = e_task_table_get_selected (task_table);
	g_return_if_fail (list != NULL);
	comp_data = list->data;
	g_slist_free (list);

	/* XXX We only forward the first selected task. */
	comp = e_cal_component_new ();
	clone = icalcomponent_new_clone (comp_data->icalcomp);
	e_cal_component_set_icalcomponent (comp, clone);

	itip_send_comp (
		registry, E_CAL_COMPONENT_METHOD_PUBLISH, comp,
		comp_data->client, NULL, NULL, NULL, TRUE, FALSE);

	g_object_unref (comp);
}
示例#11
0
static void
mail_to_event (ECalClientSourceType source_type,
               gboolean with_attendees,
               EMailReader *reader)
{
	EShell *shell;
	EMailBackend *backend;
	ESourceRegistry *registry;
	GPtrArray *uids;
	ESource *source = NULL;
	ESource *default_source;
	GList *list, *iter;
	GtkWindow *parent;
	const gchar *extension_name;

	parent = e_mail_reader_get_window (reader);
	uids = e_mail_reader_get_selected_uids (reader);

	/* Ask before converting 10 or more mails to events. */
	if (uids->len > 10) {
		gchar *question;
		gint response;

		question = g_strdup_printf (
			get_question_add_all_mails (source_type, uids->len), uids->len);
		response = do_ask (question, FALSE);
		g_free (question);

		if (response == GTK_RESPONSE_NO) {
			g_ptr_array_unref (uids);
			return;
		}
	}

	backend = e_mail_reader_get_backend (reader);
	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
	registry = e_shell_get_registry (shell);

	switch (source_type) {
		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
			extension_name = E_SOURCE_EXTENSION_CALENDAR;
			default_source = e_source_registry_ref_default_calendar (registry);
			break;
		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
			extension_name = E_SOURCE_EXTENSION_MEMO_LIST;
			default_source = e_source_registry_ref_default_memo_list (registry);
			break;
		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
			extension_name = E_SOURCE_EXTENSION_TASK_LIST;
			default_source = e_source_registry_ref_default_task_list (registry);
			break;
		default:
			g_return_if_reached ();
	}

	list = e_source_registry_list_sources (registry, extension_name);

	/* If there is only one writable source, no need to prompt the user. */
	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
		ESource *candidate = E_SOURCE (iter->data);

		if (e_source_get_writable (candidate)) {
			if (source == NULL)
				source = candidate;
			else {
				source = NULL;
				break;
			}
		}
	}

	g_list_free_full (list, (GDestroyNotify) g_object_unref);

	if (source == NULL) {
		GtkWidget *dialog;
		ESourceSelector *selector;

		/* ask the user which tasks list to save to */
		dialog = e_source_selector_dialog_new (
			parent, registry, extension_name);

		selector = e_source_selector_dialog_get_selector (
			E_SOURCE_SELECTOR_DIALOG (dialog));

		e_source_selector_set_primary_selection (
			selector, default_source);

		if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
			source = e_source_selector_dialog_peek_primary_selection (
				E_SOURCE_SELECTOR_DIALOG (dialog));

		gtk_widget_destroy (dialog);
	}

	if (source) {
		/* if a source has been selected, perform the mail2event operation */
		AsyncData *data = NULL;
		GThread *thread = NULL;
		GError *error = NULL;

		/* Fill the elements in AsynData */
		data = g_new0 (AsyncData, 1);
		data->client_cache = g_object_ref (e_shell_get_client_cache (shell));
		data->source = g_object_ref (source);
		data->extension_name = extension_name;
		data->source_type = source_type;
		data->folder = e_mail_reader_ref_folder (reader);
		data->uids = g_ptr_array_ref (uids);
		data->with_attendees = with_attendees;

		if (uids->len == 1)
			data->selected_text = get_selected_text (reader);
		else
			data->selected_text = NULL;

		thread = g_thread_try_new (
			NULL, (GThreadFunc) do_mail_to_event, data, &error);
		if (error != NULL) {
			g_warning (G_STRLOC ": %s", error->message);
			g_error_free (error);
		} else {
			g_thread_unref (thread);
		}
	}

	g_object_unref (default_source);
	g_ptr_array_unref (uids);
}
示例#12
0
static GtkWidget *
ivcal_getwidget (EImport *ei,
                 EImportTarget *target,
                 EImportImporter *im)
{
	EShell *shell;
	ESourceRegistry *registry;
	GtkWidget *vbox, *hbox, *first = NULL;
	GSList *group = NULL;
	gint i;
	GtkWidget *nb;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);

	nb = gtk_notebook_new ();
	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), FALSE);
	gtk_notebook_set_show_border (GTK_NOTEBOOK (nb), FALSE);
	gtk_box_pack_start (GTK_BOX (vbox), nb, TRUE, TRUE, 6);

	/* Type of icalendar items */
	for (i = 0; import_type_map[i] != -1; i++) {
		GtkWidget *selector, *rb, *create_button, *vbox;
		GtkWidget *scrolled;
		struct _selector_data *sd;
		const gchar *extension_name;
		const gchar *create_label;

		switch (import_type_map[i]) {
			case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
				extension_name = E_SOURCE_EXTENSION_CALENDAR;
				create_label = _("Cre_ate new calendar");
				break;
			case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
				extension_name = E_SOURCE_EXTENSION_TASK_LIST;
				create_label = _("Cre_ate new task list");
				break;
			default:
				g_warn_if_reached ();
				continue;
		}

		selector = e_source_selector_new (registry, extension_name);
		e_source_selector_set_show_toggles (E_SOURCE_SELECTOR (selector), FALSE);

		vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);

		gtk_notebook_append_page (GTK_NOTEBOOK (nb), vbox, NULL);

		scrolled = gtk_scrolled_window_new (NULL, NULL);
		gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
		gtk_container_add ((GtkContainer *) scrolled, selector);
		gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);

		create_button = gtk_button_new_with_mnemonic (create_label);
		g_object_set_data (G_OBJECT (create_button), "source-type", GINT_TO_POINTER (import_type_map[i]));
		g_object_set (G_OBJECT (create_button),
			"hexpand", FALSE,
			"halign", GTK_ALIGN_END,
			"vexpand", FALSE,
			"valign", GTK_ALIGN_START,
			NULL);
		gtk_box_pack_start (GTK_BOX (vbox), create_button, FALSE, FALSE, 0);

		g_signal_connect (create_button, "clicked", G_CALLBACK (create_calendar_clicked_cb), selector);
		g_signal_connect (
			selector, "primary_selection_changed",
			G_CALLBACK (primary_selection_changed_cb), target);

		rb = gtk_radio_button_new_with_label (group, _(import_type_strings[i]));
		gtk_box_pack_start (GTK_BOX (hbox), rb, FALSE, FALSE, 6);

		sd = g_malloc0 (sizeof (*sd));
		sd->target = target;
		sd->selector = selector;
		sd->notebook = nb;
		sd->page = i;
		g_object_set_data_full ((GObject *) rb, "selector-data", sd, g_free);
		g_signal_connect (
			rb, "toggled",
			G_CALLBACK (button_toggled_cb), sd);

		if (!group)
			group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb));
		if (first == NULL) {
			/* Set primary-source */
			primary_selection_changed_cb (E_SOURCE_SELECTOR (selector), target);
			g_datalist_set_data (&target->data, "primary-type", GINT_TO_POINTER (import_type_map[i]));
			first = rb;
		}
	}
	if (first)
		gtk_toggle_button_set_active ((GtkToggleButton *) first, TRUE);

	gtk_widget_show_all (vbox);

	return vbox;
}
示例#13
0
static CompEditor *
get_component_editor (EShell *shell,
                      ECalClient *client,
                      ECalComponent *comp,
                      gboolean is_new,
                      GError **error)
{
	ECalComponentId *id;
	CompEditorFlags flags = 0;
	CompEditor *editor = NULL;
	ESourceRegistry *registry;

	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
	g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL);
	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), NULL);

	registry = e_shell_get_registry (shell);

	id = e_cal_component_get_id (comp);
	g_return_val_if_fail (id != NULL, NULL);
	g_return_val_if_fail (id->uid != NULL, NULL);

	if (is_new) {
		flags |= COMP_EDITOR_NEW_ITEM;
	} else {
		editor = comp_editor_find_instance (id->uid);
	}

	if (!editor) {
		if (itip_organizer_is_user (registry, comp, client))
			flags |= COMP_EDITOR_USER_ORG;

		switch (e_cal_component_get_vtype (comp)) {
		case E_CAL_COMPONENT_EVENT:
			if (e_cal_component_has_attendees (comp))
				flags |= COMP_EDITOR_MEETING;

			editor = event_editor_new (client, shell, flags);

			if (flags & COMP_EDITOR_MEETING)
				event_editor_show_meeting (EVENT_EDITOR (editor));
			break;
		case E_CAL_COMPONENT_TODO:
			if (e_cal_component_has_attendees (comp))
				flags |= COMP_EDITOR_IS_ASSIGNED;

			editor = task_editor_new (client, shell, flags);

			if (flags & COMP_EDITOR_IS_ASSIGNED)
				task_editor_show_assignment (TASK_EDITOR (editor));
			break;
		case E_CAL_COMPONENT_JOURNAL:
			if (e_cal_component_has_organizer (comp))
				flags |= COMP_EDITOR_IS_SHARED;

			editor = memo_editor_new (client, shell, flags);
			break;
		default:
			g_warn_if_reached ();
			break;
		}

		if (editor) {
			comp_editor_edit_comp (editor, comp);

			/* request save for new events */
			comp_editor_set_changed (editor, is_new);
		}
	}

	e_cal_component_free_id (id);

	return editor;
}
示例#14
0
static gboolean
migrate_mbox_to_maildir (EShell *shell,
                         CamelSession *session,
                         ESource *mbox_source)
{
	ESourceRegistry *registry;
	ESourceExtension *extension;
	const gchar *extension_name;
	CamelService *mbox_service = NULL;
	CamelService *maildir_service = NULL;
	CamelSettings *settings;
	const gchar *data_dir;
	const gchar *mbox_uid;
	gchar *path;
	struct MigrateStore ms;
	GThread *thread;
	GError *error = NULL;

	registry = e_shell_get_registry (shell);

	data_dir = camel_session_get_user_data_dir (session);

	mbox_uid = e_source_get_uid (mbox_source);
	e_source_set_display_name (mbox_source, "local_mbox");

	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
	extension = e_source_get_extension (mbox_source, extension_name);

	e_source_backend_set_backend_name (
		E_SOURCE_BACKEND (extension), "mbox");

	extension_name = e_source_camel_get_extension_name ("mbox");
	extension = e_source_get_extension (mbox_source, extension_name);
	settings = e_source_camel_get_settings (E_SOURCE_CAMEL (extension));

	path = g_build_filename (data_dir, mbox_uid, NULL);
	g_object_set (settings, "path", path, NULL);
	g_free (path);

	e_source_registry_commit_source_sync (
		registry, mbox_source, NULL, &error);

	if (error == NULL)
		mbox_service = camel_session_add_service (
			session, mbox_uid, "mbox",
			CAMEL_PROVIDER_STORE, &error);

	if (error == NULL)
		maildir_service = camel_session_add_service (
			session, "local", "maildir",
			CAMEL_PROVIDER_STORE, &error);

	if (error != NULL) {
		if (mbox_service != NULL)
			g_object_unref (mbox_service);
		if (maildir_service != NULL)
			g_object_unref (maildir_service);
		g_warning ("%s: %s", G_STRFUNC, error->message);
		g_error_free (error);
		return FALSE;
	}

	g_return_val_if_fail (CAMEL_IS_STORE (mbox_service), FALSE);
	g_return_val_if_fail (CAMEL_IS_STORE (maildir_service), FALSE);

	camel_service_set_settings (mbox_service, settings);

	settings = camel_service_ref_settings (maildir_service);

	path = g_build_filename (data_dir, "local", NULL);
	g_object_set (settings, "path", path, NULL);
	if (g_mkdir (path, 0700) == -1)
		g_warning (
			"%s: Failed to make directory '%s': %s",
			G_STRFUNC, path, g_strerror (errno));
	g_free (path);

	g_object_unref (settings);

	ms.mail_store = CAMEL_STORE (mbox_service);
	ms.maildir_store = CAMEL_STORE (maildir_service);
	ms.session = session;
	ms.complete = FALSE;

	thread = g_thread_new (NULL, (GThreadFunc) migrate_stores, &ms);
	/* coverity[loop_condition] */
	while (!ms.complete)
		g_main_context_iteration (NULL, TRUE);

	g_object_unref (mbox_service);
	g_object_unref (maildir_service);
	g_thread_unref (thread);

	return TRUE;
}
示例#15
0
static gboolean
write_calendar (const gchar *uid,
                GOutputStream *stream,
                gint dur_type,
                gint dur_value,
                GError **error)
{
	EShell *shell;
	ESource *source;
	ESourceRegistry *registry;
	EClient *client = NULL;
	GSList *objects = NULL;
	icaltimezone *utc;
	time_t start = time (NULL), end;
	icalcomponent *top_level;
	gchar *email = NULL;
	GSList *users = NULL;
	gboolean success = FALSE;

	utc = icaltimezone_get_utc_timezone ();
	start = time_day_begin_with_zone (start, utc);

	switch (dur_type) {
	case FB_DURATION_DAYS:
		end = time_add_day_with_zone (start, dur_value, utc);
		break;
	default:
	case FB_DURATION_WEEKS:
		end = time_add_week_with_zone (start, dur_value, utc);
		break;
	case FB_DURATION_MONTHS:
		end = time_add_month_with_zone (start, dur_value, utc);
		break;
	}

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);
	source = e_source_registry_ref_source (registry, uid);

	if (source != NULL) {
		EClientCache *client_cache;

		client_cache = e_shell_get_client_cache (shell);
		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error);

		g_object_unref (source);
	} else {
		g_set_error (
			error, E_CAL_CLIENT_ERROR,
			E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR,
			_("Invalid source UID “%s”"), uid);
	}

	if (client == NULL)
		return FALSE;

	if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) {
		if (email && *email)
			users = g_slist_append (users, email);
	}

	top_level = e_cal_util_new_top_level ();

	success = e_cal_client_get_free_busy_sync (
		E_CAL_CLIENT (client), start, end, users, &objects, NULL, error);

	if (success) {
		gchar *ical_string;
		GSList *iter;

		for (iter = objects; iter; iter = iter->next) {
			ECalComponent *comp = iter->data;
			icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
			icalcomponent_add_component (top_level, icalcomp);
		}

		ical_string = icalcomponent_as_ical_string_r (top_level);

		success = g_output_stream_write_all (
			stream, ical_string,
			strlen (ical_string),
			NULL, NULL, error);

		e_cal_client_free_ecalcomp_slist (objects);
		g_free (ical_string);
	}

	if (users)
		g_slist_free (users);

	g_free (email);
	g_object_unref (client);
	icalcomponent_free (top_level);

	return success;
}
示例#16
0
GtkWidget *
itip_formatter_page_factory (EPlugin *ep,
                             EConfigHookItemFactoryData *hook_data)
{
	EShell *shell;
	ESourceRegistry *registry;
	GtkWidget *page;
	GtkWidget *tab_label;
	GtkWidget *frame;
	GtkWidget *frame_label;
	GtkWidget *padding_label;
	GtkWidget *hbox;
	GtkWidget *inner_vbox;
	GtkWidget *check;
	GtkWidget *label;
	GtkWidget *ess;
	GtkWidget *scrolledwin;
	gchar *str;
	GSettings *settings;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	/* Create a new notebook page */
	page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
	tab_label = gtk_label_new (_("Meeting Invitations"));
	gtk_notebook_append_page (GTK_NOTEBOOK (hook_data->parent), page, tab_label);

	/* Frame */
	frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
	gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);

	/* "General" */
	frame_label = gtk_label_new ("");
	str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("General"));
	gtk_label_set_markup (GTK_LABEL (frame_label), str);
	g_free (str);
	gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5);
	gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0);

	/* Indent/padding */
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
	gtk_box_pack_start (GTK_BOX (frame), hbox, FALSE, TRUE, 0);
	padding_label = gtk_label_new ("");
	gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0);
	inner_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
	gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, FALSE, FALSE, 0);

	/* Delete message after acting */
	settings = e_util_ref_settings ("org.gnome.evolution.plugin.itip");

	check = gtk_check_button_new_with_mnemonic (_("_Delete message after acting"));
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), g_settings_get_boolean (settings, CONF_KEY_DELETE));
	g_signal_connect (
		check, "toggled",
		G_CALLBACK (delete_toggled_cb), NULL);
	gtk_box_pack_start (GTK_BOX (inner_vbox), check, FALSE, FALSE, 0);

	g_object_unref (settings);

	/* "Conflict searching" */
	frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
	gtk_box_pack_start (GTK_BOX (page), frame, TRUE, TRUE, 24);

	frame_label = gtk_label_new ("");
	str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Conflict Search"));
	gtk_label_set_markup (GTK_LABEL (frame_label), str);
	g_free (str);
	gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5);
	gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0);

	/* Indent/padding */
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
	gtk_box_pack_start (GTK_BOX (frame), hbox, TRUE, TRUE, 0);
	padding_label = gtk_label_new ("");
	gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0);
	inner_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
	gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, TRUE, TRUE, 0);

	/* Source selector */
	label = gtk_label_new (_("Select the calendars to search for meeting conflicts"));
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
	gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0);

	scrolledwin = gtk_scrolled_window_new (NULL, NULL);

	gtk_scrolled_window_set_policy (
		GTK_SCROLLED_WINDOW (scrolledwin),
		GTK_POLICY_AUTOMATIC,
		GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (
		GTK_SCROLLED_WINDOW (scrolledwin),
		GTK_SHADOW_IN);
	gtk_box_pack_start (GTK_BOX (inner_vbox), scrolledwin, TRUE, TRUE, 0);

	ess = e_conflict_search_selector_new (registry);
	atk_object_set_name (gtk_widget_get_accessible (ess), _("Conflict Search"));
	gtk_container_add (GTK_CONTAINER (scrolledwin), ess);

	gtk_widget_show_all (page);

	return page;
}
示例#17
0
static void
import_contacts (void)
{
	EShell *shell;
	ESourceRegistry *registry;
	EClient *client = NULL;
	GList *list;
	gchar *name;
	GString *line;
	FILE *fp;
	gsize offset;
	const gchar *extension_name;
	GError *error = NULL;

	printf ("importing pine addressbook\n");

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);
	extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;

	name = g_build_filename (g_get_home_dir (), ".addressbook", NULL);
	fp = fopen (name, "r");
	g_free (name);
	if (fp == NULL)
		return;

	list = e_source_registry_list_sources (registry, extension_name);

	if (list != NULL) {
		ESource *source;

		source = E_SOURCE (list->data);
		client = e_book_client_connect_sync (source, 30, NULL, &error);
	} else {
		/* No address books exist. */
		g_warning ("%s: No address books exist.", G_STRFUNC);
		fclose (fp);
		return;
	}

	g_list_free_full (list, (GDestroyNotify) g_object_unref);

	if (error != NULL) {
		g_warning (
			"%s: Failed to open book client: %s",
			G_STRFUNC, error ? error->message : "Unknown error");
		g_clear_error (&error);
		fclose (fp);
		return;
	}

	line = g_string_new ("");
	g_string_set_size (line, 256);
	offset = 0;
	while (fgets (line->str + offset, 256, fp)) {
		gsize len;

		len = strlen (line->str + offset) + offset;
		if (line->str[len - 1] == '\n')
			g_string_truncate (line, len - 1);
		else if (!feof (fp)) {
			offset = len;
			g_string_set_size (line, len + 256);
			continue;
		} else {
			g_string_truncate (line, len);
		}

		import_contact (E_BOOK_CLIENT (client), line->str);
		offset = 0;
	}

	g_string_free (line, TRUE);
	fclose (fp);
	g_object_unref (client);
}
示例#18
0
static gboolean
write_calendar (const gchar *uid,
                GOutputStream *stream,
                gint dur_type,
                gint dur_value,
                GError **error)
{
	EShell *shell;
	ESource *source;
	ESourceRegistry *registry;
	EClient *client = NULL;
	GSList *objects = NULL;
	icaltimezone *utc;
	time_t start = time (NULL), end;
	icalcomponent *top_level;
	gchar *email = NULL;
	GSList *users = NULL;
	gulong handler_id;
	gboolean success = FALSE;

	utc = icaltimezone_get_utc_timezone ();
	start = time_day_begin_with_zone (start, utc);

	switch (dur_type) {
	case FB_DURATION_DAYS:
		end = time_add_day_with_zone (start, dur_value, utc);
		break;
	default:
	case FB_DURATION_WEEKS:
		end = time_add_week_with_zone (start, dur_value, utc);
		break;
	case FB_DURATION_MONTHS:
		end = time_add_month_with_zone (start, dur_value, utc);
		break;
	}

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);
	source = e_source_registry_ref_source (registry, uid);

	if (source != NULL) {
		EClientCache *client_cache;

		client_cache = e_shell_get_client_cache (shell);
		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error);

		g_object_unref (source);
	} else {
		g_set_error (
			error, E_CAL_CLIENT_ERROR,
			E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR,
			_("Invalid source UID '%s'"), uid);
	}

	if (client == NULL)
		return FALSE;

	if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) {
		if (email && *email)
			users = g_slist_append (users, email);
	}

	top_level = e_cal_util_new_top_level ();

	handler_id = g_signal_connect (
		client, "free-busy-data",
		G_CALLBACK (free_busy_data_cb), &objects);

	success = e_cal_client_get_free_busy_sync (
		E_CAL_CLIENT (client), start, end, users, NULL, error);

	if (handler_id > 0)
		g_signal_handler_disconnect (client, handler_id);

	if (success) {
		gchar *ical_string;
		GSList *iter;
		gboolean done = FALSE;

		/* This is to workaround broken dispatch of "free-busy-data" signal,
		 * introduced in 3.8.0. This code can be removed once the below bug is
		 * properly fixed: https://bugzilla.gnome.org/show_bug.cgi?id=692361
		*/
		while (!done) {
			g_usleep (G_USEC_PER_SEC / 10);
			done = !g_main_context_iteration (NULL, FALSE);
		}

		for (iter = objects; iter; iter = iter->next) {
			ECalComponent *comp = iter->data;
			icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
			icalcomponent_add_component (top_level, icalcomp);
		}

		ical_string = icalcomponent_as_ical_string_r (top_level);

		success = g_output_stream_write_all (
			stream, ical_string,
			strlen (ical_string),
			NULL, NULL, error);

		e_cal_client_free_ecalcomp_slist (objects);
		g_free (ical_string);
	}

	if (users)
		g_slist_free (users);

	g_free (email);
	g_object_unref (client);
	icalcomponent_free (top_level);

	return success;
}
static void
memo_shell_content_constructed (GObject *object)
{
	EMemoShellContentPrivate *priv;
	EShell *shell;
	EShellView *shell_view;
	EShellContent *shell_content;
	EShellTaskbar *shell_taskbar;
	EShellWindow *shell_window;
	ESourceRegistry *registry;
	GalViewInstance *view_instance;
	GtkTargetList *target_list;
	GtkTargetEntry *targets;
	GtkWidget *container;
	GtkWidget *widget;
	gint n_targets;

	priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object);

	/* Chain up to parent's constructed() method. */
	G_OBJECT_CLASS (e_memo_shell_content_parent_class)->constructed (object);

	shell_content = E_SHELL_CONTENT (object);
	shell_view = e_shell_content_get_shell_view (shell_content);
	shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);
	shell = e_shell_window_get_shell (shell_window);

	registry = e_shell_get_registry (shell);
	priv->memo_model = e_cal_model_memos_new (registry);

	/* Build content widgets. */

	container = GTK_WIDGET (object);

	widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
	gtk_container_add (GTK_CONTAINER (container), widget);
	priv->paned = g_object_ref (widget);
	gtk_widget_show (widget);

	g_object_bind_property (
		object, "orientation",
		widget, "orientation",
		G_BINDING_SYNC_CREATE);

	container = priv->paned;

	widget = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (
		GTK_SCROLLED_WINDOW (widget),
		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (
		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
	gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
	gtk_widget_show (widget);

	container = widget;

	widget = e_memo_table_new (shell_view, priv->memo_model);
	gtk_container_add (GTK_CONTAINER (container), widget);
	priv->memo_table = g_object_ref (widget);
	gtk_widget_show (widget);

	container = priv->paned;

	widget = e_cal_component_preview_new ();
	gtk_widget_show (widget);

	g_signal_connect_swapped (
		widget, "status-message",
		G_CALLBACK (e_shell_taskbar_set_message),
		shell_taskbar);

	widget = e_preview_pane_new (E_WEB_VIEW (widget));
	gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
	priv->preview_pane = g_object_ref (widget);
	gtk_widget_show (widget);

	g_object_bind_property (
		object, "preview-visible",
		widget, "visible",
		G_BINDING_SYNC_CREATE);

	target_list = gtk_target_list_new (NULL, 0);
	e_target_list_add_calendar_targets (target_list, 0);
	targets = gtk_target_table_new_from_list (target_list, &n_targets);

	e_table_drag_source_set (
		E_TABLE (priv->memo_table),
		GDK_BUTTON1_MASK, targets, n_targets,
		GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK);

	gtk_target_table_free (targets, n_targets);
	gtk_target_list_unref (target_list);

	g_signal_connect_swapped (
		priv->memo_table, "table-drag-data-get",
		G_CALLBACK (memo_shell_content_table_drag_data_get_cb),
		object);

	g_signal_connect_swapped (
		priv->memo_table, "table-drag-data-delete",
		G_CALLBACK (memo_shell_content_table_drag_data_delete_cb),
		object);

	g_signal_connect_swapped (
		priv->memo_table, "cursor-change",
		G_CALLBACK (memo_shell_content_cursor_change_cb),
		object);

	g_signal_connect_swapped (
		priv->memo_table, "selection-change",
		G_CALLBACK (memo_shell_content_selection_change_cb),
		object);

	e_signal_connect_notify (
		priv->memo_table, "notify::is-editing",
		G_CALLBACK (memo_shell_content_is_editing_changed_cb), shell_view);

	g_signal_connect_swapped (
		priv->memo_model, "model-row-changed",
		G_CALLBACK (memo_shell_content_model_row_changed_cb),
		object);

	/* Load the view instance. */

	view_instance = e_shell_view_new_view_instance (shell_view, NULL);
	g_signal_connect_swapped (
		view_instance, "display-view",
		G_CALLBACK (memo_shell_content_display_view_cb),
		object);
	e_shell_view_set_view_instance (shell_view, view_instance);
	gal_view_instance_load (view_instance);
	g_object_unref (view_instance);

	/* Restore pane positions from the last session once
	 * the shell view is fully initialized and visible. */
	g_signal_connect (
		shell_window, "shell-view-created::memos",
		G_CALLBACK (memo_shell_content_restore_state_cb),
		shell_content);
}
示例#20
0
void
e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
{
	EMailShellContent *mail_shell_content;
	EShellBackend *shell_backend;
	EShellSidebar *shell_sidebar;
	EShellView *shell_view;
	EShell *shell;
	EMailReader *reader;
	EMailView *mail_view;
	ESourceRegistry *registry;
	CamelStore *parent_store;
	CamelFolder *folder;
	CamelFolderInfoFlags flags = 0;
	CamelFolderSummary *folder_summary;
	MailFolderCache *folder_cache;
	MessageList *message_list;
	guint selected_count;
	GString *buffer, *title_short = NULL;
	gboolean store_is_local, is_inbox;
	const gchar *display_name;
	const gchar *folder_name;
	const gchar *uid;
	gchar *title;
	guint32 num_deleted;
	guint32 num_junked;
	guint32 num_junked_not_deleted;
	guint32 num_unread;
	guint32 num_visible;

	g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));

	mail_shell_content = mail_shell_view->priv->mail_shell_content;
	mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);

	shell_view = E_SHELL_VIEW (mail_shell_view);
	shell_backend = e_shell_view_get_shell_backend (shell_view);
	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);

	shell = e_shell_backend_get_shell (shell_backend);
	registry = e_shell_get_registry (shell);

	reader = E_MAIL_READER (mail_view);
	folder = e_mail_reader_ref_folder (reader);

	/* If no folder is selected, reset the sidebar banners
	 * to their default values and stop. */
	if (folder == NULL) {
		GtkAction *action;
		gchar *label;

		action = e_shell_view_get_action (shell_view);

		g_object_get (action, "label", &label, NULL);
		e_shell_sidebar_set_secondary_text (shell_sidebar, NULL);
		e_shell_view_set_title (shell_view, label);
		g_free (label);

		return;
	}

	folder_name = camel_folder_get_display_name (folder);
	parent_store = camel_folder_get_parent_store (folder);
	folder_summary = camel_folder_get_folder_summary (folder);

	folder_cache = e_mail_session_get_folder_cache (
		e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend)));
	mail_folder_cache_get_folder_info_flags (folder_cache, parent_store, folder_name, &flags);
	is_inbox = (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX;

	num_deleted = camel_folder_summary_get_deleted_count (folder_summary);
	num_junked = camel_folder_summary_get_junk_count (folder_summary);
	num_junked_not_deleted = camel_folder_summary_get_junk_not_deleted_count (folder_summary);
	num_unread = camel_folder_summary_get_unread_count (folder_summary);
	num_visible = camel_folder_summary_get_visible_count (folder_summary);

	buffer = g_string_sized_new (256);
	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
	selected_count = message_list_selected_count (message_list);

	if (selected_count > 1)
		g_string_append_printf (
			buffer, ngettext ("%d selected, ", "%d selected, ",
			selected_count), selected_count);

	/* "Trash" folder (virtual or real) */
	if (camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_TRASH) {
		if (CAMEL_IS_VTRASH_FOLDER (folder)) {
			/* For a virtual Trash folder, count
			 * the messages marked for deletion. */
			g_string_append_printf (
				buffer, ngettext ("%d deleted",
				"%d deleted", num_deleted), num_deleted);
		} else {
			/* For a regular Trash folder, just
			 * count the visible messages.
			 *
			 * XXX Open question: what to do about messages
			 *     marked for deletion in Trash?  Probably
			 *     this is the wrong question to be asking
			 *     anyway.  Deleting a message in a real
			 *     Trash should permanently expunge the
			 *     message (if the server supports that),
			 *     which would eliminate this corner case. */
			if (!e_mail_reader_get_hide_deleted (reader))
				num_visible += num_deleted;

			g_string_append_printf (
				buffer, ngettext ("%d deleted",
				"%d deleted", num_visible), num_visible);
		}

	/* "Junk" folder (virtual or real) */
	} else if (camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_JUNK) {
		if (e_mail_reader_get_hide_deleted (reader)) {
			/* Junk folder with deleted messages hidden. */
			g_string_append_printf (
				buffer, ngettext ("%d junk",
				"%d junk", num_junked_not_deleted),
				num_junked_not_deleted);
		} else {
			/* Junk folder with deleted messages visible. */
			g_string_append_printf (
				buffer, ngettext ("%d junk", "%d junk",
				num_junked), num_junked);
		}

	/* "Drafts" folder */
	} else if (!is_inbox && em_utils_folder_is_drafts (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d draft", "%d drafts",
			num_visible), num_visible);

	/* "Outbox" folder */
	} else if (!is_inbox && em_utils_folder_is_outbox (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d unsent", "%d unsent",
			num_visible), num_visible);

	/* "Sent" folder */
	} else if (!is_inbox && em_utils_folder_is_sent (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d sent", "%d sent",
			num_visible), num_visible);

	/* Normal folder */
	} else {
		if (!e_mail_reader_get_hide_deleted (reader))
			num_visible +=
				num_deleted - num_junked +
				num_junked_not_deleted;

		if (num_unread > 0 && selected_count <= 1) {
			g_string_append_printf (
				buffer, ngettext ("%d unread, ",
				"%d unread, ", num_unread), num_unread);

			title_short = g_string_sized_new (64);
			g_string_append_printf (
				title_short, ngettext ("%d unread",
				"%d unread", num_unread), num_unread);
		}

		g_string_append_printf (
			buffer, ngettext ("%d total", "%d total",
			num_visible), num_visible);
	}

	uid = camel_service_get_uid (CAMEL_SERVICE (parent_store));
	store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);

	/* Choose a suitable folder name for displaying. */
	display_name = folder_name;
	if (store_is_local) {
		if (strcmp (folder_name, "Drafts") == 0)
			display_name = _("Drafts");
		else if (strcmp (folder_name, "Inbox") == 0)
			display_name = _("Inbox");
		else if (strcmp (folder_name, "Outbox") == 0)
			display_name = _("Outbox");
		else if (strcmp (folder_name, "Sent") == 0)
			display_name = _("Sent");
		else if (strcmp (folder_name, "Templates") == 0)
			display_name = _("Templates");
		else if (strcmp (folder_name, "Trash") == 0)
			display_name = _("Trash");
	}
	if (strcmp (folder_name, "INBOX") == 0)
		display_name = _("Inbox");

	if (title_short && title_short->len > 0)
		title = g_strdup_printf ("%s (%s)", display_name, title_short->str);
	else
		title = g_strdup (display_name);
	e_shell_sidebar_set_secondary_text (shell_sidebar, buffer->str);
	e_shell_view_set_title (shell_view, title);
	g_free (title);

	g_string_free (buffer, TRUE);
	if (title_short)
		g_string_free (title_short, TRUE);

	g_clear_object (&folder);
}