void
e_migrate_base_dirs (EShell *shell)
{
	const gchar *home_dir;
	gchar *old_base_dir;

	g_return_if_fail (E_IS_SHELL (shell));

	/* XXX This blocks, but it's all just local file
	 *     renames so it should be nearly instantaneous. */

	home_dir = g_get_home_dir ();
	old_base_dir = g_build_filename (home_dir, ".evolution", NULL);

	/* Is there even anything to migrate? */
	if (!g_file_test (old_base_dir, G_FILE_TEST_IS_DIR))
		goto exit;

	shell_xdg_migrate_cache_dir (shell, old_base_dir);
	shell_xdg_migrate_config_dir (shell, old_base_dir);
	shell_xdg_migrate_data_dir (shell, old_base_dir);

	/* Try to remove the old base directory.  Good chance this will
	 * fail on the first try, since Evolution puts stuff here too. */
	g_rmdir (old_base_dir);

exit:
	g_free (old_base_dir);
}
Example #2
0
void
e_composer_load_snapshot (EShell *shell,
                          GFile *snapshot_file,
                          GCancellable *cancellable,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
	GSimpleAsyncResult *simple;
	LoadContext *context;

	g_return_if_fail (E_IS_SHELL (shell));
	g_return_if_fail (G_IS_FILE (snapshot_file));

	context = g_slice_new0 (LoadContext);

	simple = g_simple_async_result_new (
		G_OBJECT (shell), callback, user_data,
		e_composer_load_snapshot);

	g_simple_async_result_set_check_cancellable (simple, cancellable);

	g_simple_async_result_set_op_res_gpointer (
		simple, context, (GDestroyNotify) load_context_free);

	g_file_load_contents_async (
		snapshot_file, cancellable, (GAsyncReadyCallback)
		load_snapshot_loaded_cb, simple);
}
Example #3
0
gboolean
e_shell_migrate_attempt (EShell *shell)
{
	gint major, minor, micro;

	g_return_val_if_fail (E_IS_SHELL (shell), FALSE);

	shell_migrate_get_version (shell, &major, &minor, &micro);

	/* Abort all migration if the user downgraded. */
	if (shell_migrate_downgraded (major, minor, micro))
		return TRUE;

	/* This sets the folder permissions to S_IRWXU if needed */
	if (major <= 2 && minor <= 30)
		fix_folder_permissions (e_get_user_data_dir ());

	/* Attempt to run migration all the time and let the backend
	 * make the choice */
	if (!shell_migrate_attempt (shell, major, minor, micro))
		_exit (EXIT_SUCCESS);

	/* We want our handler to run last, hence g_signal_connect_after(). */
	g_signal_connect_after (
		shell, "event::ready-to-start",
		G_CALLBACK (shell_migrate_ready_to_start_event_cb), NULL);

	return TRUE;
}
Example #4
0
void
eab_send_as_attachment (EShell *shell,
                        GSList *destinations)
{
	CreateComposerData *ccd;

	g_return_if_fail (E_IS_SHELL (shell));

	if (destinations == NULL)
		return;

	ccd = g_new0 (CreateComposerData, 1);
	ccd->attachment_destinations = g_slist_copy (destinations);
	g_slist_foreach (ccd->attachment_destinations, (GFunc) g_object_ref, NULL);

	e_msg_composer_new (shell, eab_composer_created_cb, ccd);
}
Example #5
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;
}
Example #6
0
void
eab_send_as_to (EShell *shell,
                GSList *destinations)
{
	GPtrArray *to_array;
	GPtrArray *bcc_array;
	CreateComposerData *ccd;

	g_return_if_fail (E_IS_SHELL (shell));

	if (destinations == NULL)
		return;

	to_array = g_ptr_array_new ();
	bcc_array = g_ptr_array_new ();

	/* Sort contacts into "To" and "Bcc" destinations. */
	while (destinations != NULL) {
		EDestination *destination = destinations->data;

		if (e_destination_is_evolution_list (destination)) {
			if (e_destination_list_show_addresses (destination))
				g_ptr_array_add (to_array, e_destination_copy (destination));
			else
				g_ptr_array_add (bcc_array, e_destination_copy (destination));
		} else
			g_ptr_array_add (to_array, e_destination_copy (destination));

		destinations = g_slist_next (destinations);
	}

	/* Add sentinels to each array. */
	g_ptr_array_add (to_array, NULL);
	g_ptr_array_add (bcc_array, NULL);

	ccd = g_new0 (CreateComposerData, 1);
	ccd->to_destinations = (EDestination **) g_ptr_array_free (to_array, FALSE);
	ccd->bcc_destinations = (EDestination **) g_ptr_array_free (bcc_array, FALSE);
	ccd->attachment_destinations = NULL;

	e_msg_composer_new (shell, eab_composer_created_cb, ccd);
}
Example #7
0
/**
 * e_shell_run_open_dialog:
 * @shell: an #EShell
 * @title: file chooser dialog title
 * @customize_func: optional dialog customization function
 * @customize_data: optional data to pass to @customize_func
 *
 * Runs a #GtkFileChooserDialog in open mode with the given title and
 * returns the selected #GFile.  If @customize_func is provided, the
 * function is called just prior to running the dialog (the file chooser
 * is the first argument, @customize data is the second).  If the user
 * cancels the dialog the function will return %NULL.
 *
 * Returns: the #GFile to open, or %NULL
 **/
GFile *
e_shell_run_open_dialog (EShell *shell,
                         const gchar *title,
                         GtkCallback customize_func,
                         gpointer customize_data)
{
    GtkFileChooser *file_chooser;
    GFile *chosen_file = NULL;
    GtkWidget *dialog;
    GtkWindow *parent;

    g_return_val_if_fail (E_IS_SHELL (shell), NULL);

    parent = e_shell_get_active_window (shell);

    dialog = gtk_file_chooser_dialog_new (
                 title, parent,
                 GTK_FILE_CHOOSER_ACTION_OPEN,
                 _("_Cancel"), GTK_RESPONSE_CANCEL,
                 _("_Open"), GTK_RESPONSE_ACCEPT, NULL);

    file_chooser = GTK_FILE_CHOOSER (dialog);

    gtk_dialog_set_default_response (
        GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);

    gtk_file_chooser_set_local_only (file_chooser, FALSE);

    /* Allow further customizations before running the dialog. */
    if (customize_func != NULL)
        customize_func (dialog, customize_data);

    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
        chosen_file = gtk_file_chooser_get_file (file_chooser);

    gtk_widget_destroy (dialog);

    return chosen_file;
}
Example #8
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;
}
Example #9
0
void
eab_send_as_to (EShell *shell,
                GSList *destinations)
{
	EMsgComposer *composer;
	EComposerHeaderTable *table;
	GPtrArray *to_array;
	GPtrArray *bcc_array;

	union {
		gpointer *pdata;
		EDestination **destinations;
	} convert;

	g_return_if_fail (E_IS_SHELL (shell));

	if (destinations == NULL)
		return;

	composer = e_msg_composer_new (shell);
	table = e_msg_composer_get_header_table (composer);

	to_array = g_ptr_array_new ();
	bcc_array = g_ptr_array_new ();

	/* Sort contacts into "To" and "Bcc" destinations. */
	while (destinations != NULL) {
		EDestination *destination = destinations->data;

		if (e_destination_is_evolution_list (destination)) {
			if (e_destination_list_show_addresses (destination))
				g_ptr_array_add (to_array, destination);
			else
				g_ptr_array_add (bcc_array, destination);
		} else
			g_ptr_array_add (to_array, destination);

		destinations = g_slist_next (destinations);
	}

	/* Add sentinels to each array. */
	g_ptr_array_add (to_array, NULL);
	g_ptr_array_add (bcc_array, NULL);

	/* XXX Acrobatics like this make me question whether NULL-terminated
	 *     arrays are really the best argument type for passing a list of
	 *     destinations to the header table. */

	/* Set "To" destinations. */
	convert.pdata = to_array->pdata;
	e_composer_header_table_set_destinations_to (
		table, convert.destinations);
	g_ptr_array_free (to_array, FALSE);

	/* Add "Bcc" destinations. */
	convert.pdata = bcc_array->pdata;
	e_composer_header_table_add_destinations_bcc (
		table, convert.destinations);
	g_ptr_array_free (bcc_array, FALSE);

	gtk_widget_show (GTK_WIDGET (composer));
}
Example #10
0
void
eab_send_as_attachment (EShell *shell,
                        GSList *destinations)
{
	EMsgComposer *composer;
	EComposerHeaderTable *table;
	CamelMimePart *attachment;
	GSList *contacts, *iter;
	gchar *data;

	g_return_if_fail (E_IS_SHELL (shell));

	if (destinations == NULL)
		return;

	composer = e_msg_composer_new (shell);
	table = e_msg_composer_get_header_table (composer);

	attachment = camel_mime_part_new ();

	contacts = g_slist_copy (destinations);
	for (iter = contacts; iter != NULL; iter = iter->next)
		iter->data = e_destination_get_contact (iter->data);
	data = eab_contact_list_to_string (contacts);
	g_slist_free (contacts);

	camel_mime_part_set_content (
		attachment, data, strlen (data), "text/x-vcard");

	if (destinations->next != NULL)
		camel_mime_part_set_description (
			attachment, _("Multiple vCards"));
	else {
		EContact *contact;
		const gchar *file_as;
		gchar *description;

		contact = e_destination_get_contact (destinations->data);
		file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
		description = g_strdup_printf (_("vCard for %s"), file_as);
		camel_mime_part_set_description (attachment, description);
		g_free (description);
	}

	camel_mime_part_set_disposition (attachment, "attachment");

	e_msg_composer_attach (composer, attachment);
	g_object_unref (attachment);

	if (destinations->next != NULL)
		e_composer_header_table_set_subject (
			table, _("Contact information"));
	else {
		EContact *contact;
		gchar *tempstr;
		const gchar *tempstr2;
		gchar *tempfree = NULL;

		contact = e_destination_get_contact (destinations->data);
		tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
		if (!tempstr2 || !*tempstr2)
			tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
		if (!tempstr2 || !*tempstr2)
			tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
		}
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
		}
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
		}

		if (!tempstr2 || !*tempstr2)
			tempstr = g_strdup_printf (_("Contact information"));
		else
			tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);

		e_composer_header_table_set_subject (table, tempstr);

		g_free (tempstr);
		g_free (tempfree);
	}

	gtk_widget_show (GTK_WIDGET (composer));
}
Example #11
0
/**
 * e_shell_run_save_dialog:
 * @shell: an #EShell
 * @title: file chooser dialog title
 * @suggestion: file name suggestion, or %NULL
 * @filters: Possible filters for dialog, or %NULL
 * @customize_func: optional dialog customization function
 * @customize_data: optional data to pass to @customize_func
 *
 * Runs a #GtkFileChooserDialog in save mode with the given title and
 * returns the selected #GFile.  If @customize_func is provided, the
 * function is called just prior to running the dialog (the file chooser
 * is the first argument, @customize_data is the second).  If the user
 * cancels the dialog the function will return %NULL.
 *
 * With non-%NULL @filters will be added also file filters to the dialog.
 * The string format is "pat1:mt1;pat2:mt2:...", where 'pat' is a pattern
 * and 'mt' is a MIME type for the pattern to be used.  There can be more
 * than one MIME type, those are separated by comma.
 *
 * Returns: the #GFile to save to, or %NULL
 **/
GFile *
e_shell_run_save_dialog (EShell *shell,
                         const gchar *title,
                         const gchar *suggestion,
                         const gchar *filters,
                         GtkCallback customize_func,
                         gpointer customize_data)
{
    GtkFileChooser *file_chooser;
    GFile *chosen_file = NULL;
    GtkWidget *dialog;
    GtkWindow *parent;

    g_return_val_if_fail (E_IS_SHELL (shell), NULL);

    parent = e_shell_get_active_window (shell);

    dialog = gtk_file_chooser_dialog_new (
                 title, parent,
                 GTK_FILE_CHOOSER_ACTION_SAVE,
                 _("_Cancel"), GTK_RESPONSE_CANCEL,
                 _("_Save"), GTK_RESPONSE_ACCEPT, NULL);

    file_chooser = GTK_FILE_CHOOSER (dialog);

    gtk_dialog_set_default_response (
        GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);

    gtk_file_chooser_set_local_only (file_chooser, FALSE);
    gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);

    if (suggestion != NULL) {
        gchar *current_name;

        current_name = g_strdup (suggestion);
        e_filename_make_safe (current_name);
        gtk_file_chooser_set_current_name (file_chooser, current_name);
        g_free (current_name);
    }

    if (filters != NULL) {
        gchar **flts = g_strsplit (filters, ";", -1);
        gint i;

        for (i = 0; flts && flts[i]; i++) {
            GtkFileFilter *filter = gtk_file_filter_new ();
            gchar *flt = flts[i];
            gchar *delim = strchr (flt, ':'), *next = NULL;

            if (delim) {
                *delim = 0;
                next = strchr (delim + 1, ',');
            }

            gtk_file_filter_add_pattern (filter, flt);
            if (g_ascii_strcasecmp (flt, "*.mbox") == 0)
                gtk_file_filter_set_name (
                    filter, _("Berkeley Mailbox (mbox)"));
            else if (g_ascii_strcasecmp (flt, "*.vcf") == 0)
                gtk_file_filter_set_name (
                    filter, _("vCard (.vcf)"));
            else if (g_ascii_strcasecmp (flt, "*.ics") == 0)
                gtk_file_filter_set_name (
                    filter, _("iCalendar (.ics)"));
            else
                gtk_file_filter_set_name (filter, flt);

            while (delim) {
                delim++;
                if (next)
                    *next = 0;

                gtk_file_filter_add_mime_type (filter, delim);

                delim = next;
                if (next)
                    next = strchr (next + 1, ',');
            }

            gtk_file_chooser_add_filter (file_chooser, filter);
        }

        if (flts && flts[0]) {
            GtkFileFilter *filter = gtk_file_filter_new ();

            gtk_file_filter_add_pattern (filter, "*");
            gtk_file_filter_set_name (filter, _("All Files (*)"));
            gtk_file_chooser_add_filter (file_chooser, filter);
        }

        g_strfreev (flts);
    }

    /* Allow further customizations before running the dialog. */
    if (customize_func != NULL)
        customize_func (dialog, customize_data);

    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
        chosen_file = gtk_file_chooser_get_file (file_chooser);

    gtk_widget_destroy (dialog);

    return chosen_file;
}