aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-11-08 01:44:44 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-11-08 03:01:46 +0800
commit86ecfc50539ddef82205551c11a6a13b135bbab4 (patch)
treecc25ca582935748885a23d665a1d9e1bbc1d4d9c
parentaa66a17e401d73cbe394ed7f99bf73350e9b938b (diff)
downloadgsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar.gz
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar.bz2
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar.lz
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar.xz
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.tar.zst
gsoc2013-evolution-86ecfc50539ddef82205551c11a6a13b135bbab4.zip
Convert some "Save As" actions to run asynchronously.
This introduces e-shell-utils for miscellaneous utility functions that integrate with the shell or shell settings. First function is e_shell_run_save_dialog(), which automatically remembers the selected folder in the file chooser dialog. Also, kill some redundant save dialog functions, as well as some write-this-string-to-disk functions that block.
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c27
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h2
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c202
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h9
-rw-r--r--doc/reference/shell/eshell-sections.txt2
-rw-r--r--doc/reference/shell/tmpl/e-dialog-utils.sgml11
-rw-r--r--doc/reference/shell/tmpl/e-util.sgml10
-rw-r--r--doc/reference/shell/tmpl/eshell-unused.sgml19
-rw-r--r--e-util/e-dialog-utils.c32
-rw-r--r--e-util/e-dialog-utils.h3
-rw-r--r--e-util/e-file-utils.c39
-rw-r--r--e-util/e-util.c59
-rw-r--r--e-util/e-util.h2
-rw-r--r--modules/addressbook/e-book-shell-view-actions.c118
-rw-r--r--modules/addressbook/e-book-shell-view-private.h3
-rw-r--r--modules/calendar/e-cal-shell-view-actions.c32
-rw-r--r--modules/calendar/e-cal-shell-view-memopad.c31
-rw-r--r--modules/calendar/e-cal-shell-view-private.h2
-rw-r--r--modules/calendar/e-cal-shell-view-taskpad.c29
-rw-r--r--modules/calendar/e-memo-shell-view-actions.c29
-rw-r--r--modules/calendar/e-memo-shell-view-private.h2
-rw-r--r--modules/calendar/e-task-shell-view-actions.c30
-rw-r--r--modules/calendar/e-task-shell-view-private.h2
-rw-r--r--shell/Makefile.am5
-rw-r--r--shell/apps_evolution_shell.schemas.in4
-rw-r--r--shell/e-shell-utils.c100
-rw-r--r--shell/e-shell-utils.h42
-rw-r--r--shell/e-shell.c14
-rw-r--r--widgets/misc/e-attachment-store.c2
29 files changed, 466 insertions, 396 deletions
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 1583f26c92..280c4d3820 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -1289,33 +1289,6 @@ e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete)
}
void
-e_addressbook_view_save_as (EAddressbookView *view,
- gboolean all)
-{
- GList *list = NULL;
- EBook *book;
-
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-
- book = e_addressbook_model_get_book (view->priv->model);
-
- if (all) {
- EBookQuery *query;
-
- query = e_book_query_any_field_contains ("");
- e_book_get_contacts (book, query, &list, NULL);
- e_book_query_unref (query);
- } else
- list = e_addressbook_view_get_selected (view);
-
- if (list != NULL) {
- eab_contact_list_save (_("Save as vCard..."), list, NULL);
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
- }
-}
-
-void
e_addressbook_view_view (EAddressbookView *view)
{
EAddressbookModel *model;
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 4e0f82eeb0..ca709ff347 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -97,8 +97,6 @@ ESelectionModel *
EShellView * e_addressbook_view_get_shell_view
(EAddressbookView *view);
ESource * e_addressbook_view_get_source (EAddressbookView *view);
-void e_addressbook_view_save_as (EAddressbookView *view,
- gboolean all);
void e_addressbook_view_view (EAddressbookView *view);
void e_addressbook_view_print (EAddressbookView *view,
GtkPrintOperationAction action);
diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c
index 0aa63850a2..24fce0a99a 100644
--- a/addressbook/gui/widgets/eab-gui-util.c
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -196,105 +196,6 @@ eab_prompt_save_dialog (GtkWindow *parent)
return e_error_run (parent, "addressbook:prompt-save", NULL);
}
-static gint
-file_exists(GtkWindow *window, const gchar *filename)
-{
- GtkWidget *dialog;
- gint response;
- gchar * utf8_filename;
-
- utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
- dialog = gtk_message_dialog_new (window,
- 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- /* For Translators only: "it" refers to the filename %s. */
- _("%s already exists\nDo you want to overwrite it?"), utf8_filename);
- g_free (utf8_filename);
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- _("Overwrite"), GTK_RESPONSE_ACCEPT,
- NULL);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return response;
-}
-
-typedef struct {
- GtkWidget *filesel;
- gchar *vcard;
- gboolean has_multiple_contacts;
-} SaveAsInfo;
-
-static void
-save_it(GtkWidget *widget, SaveAsInfo *info)
-{
- const gchar *filename;
- gchar *uri;
- gint response = 0;
-
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (info->filesel));
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (info->filesel));
-
- if (filename && g_file_test (filename, G_FILE_TEST_EXISTS)) {
- response = file_exists(GTK_WINDOW (info->filesel), filename);
- switch (response) {
- case GTK_RESPONSE_ACCEPT : /* Overwrite */
- break;
- case GTK_RESPONSE_CANCEL : /* cancel */
- return;
- }
- }
-
- if (!e_write_file_uri (uri, info->vcard)) {
- gchar *err_str_ext;
- if (info->has_multiple_contacts) {
- /* more than one, finding the total number of contacts might
- * hit performance while saving large number of contacts
- */
- err_str_ext = ngettext ("contact", "contacts", 2);
- }
- else {
- err_str_ext = ngettext ("contact", "contacts", 1);
- }
-
- /* translators: Arguments, err_str_ext (item to be saved: "contact"/"contacts"),
- * destination file name, and error code will fill the placeholders
- * {0}, {1} and {2}, respectively in the error message formed
- */
- e_error_run (GTK_WINDOW (info->filesel), "addressbook:save-error",
- err_str_ext, filename, g_strerror (errno), NULL);
- gtk_widget_destroy(GTK_WIDGET(info->filesel));
- return;
- }
-
- gtk_widget_destroy(GTK_WIDGET(info->filesel));
-}
-
-static void
-close_it(GtkWidget *widget, SaveAsInfo *info)
-{
- gtk_widget_destroy (GTK_WIDGET (info->filesel));
-}
-
-static void
-destroy_it(gpointer data, GObject *where_the_object_was)
-{
- SaveAsInfo *info = data;
- g_free (info->vcard);
- g_free (info);
-}
-
-static void
-filechooser_response (GtkWidget *widget, gint response_id, SaveAsInfo *info)
-{
- if (response_id == GTK_RESPONSE_ACCEPT)
- save_it (widget, info);
- else
- close_it (widget, info);
-}
-
static gchar *
make_safe_filename (gchar *name)
{
@@ -381,99 +282,32 @@ eab_select_source (const gchar *title, const gchar *message, const gchar *select
}
void
-eab_contact_save (gchar *title, EContact *contact, GtkWindow *parent_window)
+eab_suggest_filename (GtkFileChooser *file_chooser,
+ GList *contact_list)
{
- GtkWidget *filesel;
- gchar *file;
- gchar *name;
- SaveAsInfo *info = g_new(SaveAsInfo, 1);
-
- name = e_contact_get (contact, E_CONTACT_FILE_AS);
- file = make_safe_filename (name);
-
- info->has_multiple_contacts = FALSE;
-
- filesel = gtk_file_chooser_dialog_new (title,
- parent_window,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_ACCEPT);
-
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filesel), g_get_home_dir ());
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filesel), file);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filesel), FALSE);
-
- info->filesel = filesel;
- info->vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-
- g_signal_connect (G_OBJECT (filesel), "response",
- G_CALLBACK (filechooser_response), info);
- g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
-
- if (parent_window) {
- gtk_window_set_transient_for (GTK_WINDOW (filesel),
- parent_window);
- gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
- }
+ gchar *current_name = NULL;
- gtk_widget_show(GTK_WIDGET(filesel));
- g_free (file);
-}
+ g_return_if_fail (GTK_IS_FILE_CHOOSER (file_chooser));
+ g_return_if_fail (contact_list != NULL);
-void
-eab_contact_list_save (gchar *title, GList *list, GtkWindow *parent_window)
-{
- GtkWidget *filesel;
- SaveAsInfo *info = g_new(SaveAsInfo, 1);
- gchar *file;
-
- filesel = gtk_file_chooser_dialog_new (title,
- parent_window,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_ACCEPT);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filesel), FALSE);
-
- /* Check if the list has more than one contact */
- if (g_list_next (list))
- info->has_multiple_contacts = TRUE;
- else
- info->has_multiple_contacts = FALSE;
+ if (g_list_length (contact_list) == 1) {
+ EContact *contact = E_CONTACT (contact_list->data);
+ gchar *string;
- /* This is a filename. Translators take note. */
- if (list && list->data && list->next == NULL) {
- gchar *name;
- name = e_contact_get (E_CONTACT (list->data), E_CONTACT_FILE_AS);
- if (!name)
- name = e_contact_get (E_CONTACT (list->data), E_CONTACT_FULL_NAME);
-
- file = make_safe_filename (name);
- } else {
- file = make_safe_filename (_("list"));
+ string = e_contact_get (contact, E_CONTACT_FILE_AS);
+ if (string == NULL)
+ string = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ if (string != NULL)
+ current_name = make_safe_filename (string);
+ g_free (string);
}
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filesel), g_get_home_dir ());
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filesel), file);
-
- info->filesel = filesel;
- info->vcard = eab_contact_list_to_string (list);
+ if (current_name == NULL)
+ current_name = make_safe_filename (_("list"));
- g_signal_connect (G_OBJECT (filesel), "response",
- G_CALLBACK (filechooser_response), info);
- g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
-
- if (parent_window) {
- gtk_window_set_transient_for (GTK_WINDOW (filesel),
- parent_window);
- gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
- }
+ gtk_file_chooser_set_current_name (file_chooser, current_name);
- gtk_widget_show(GTK_WIDGET(filesel));
- g_free (file);
+ g_free (current_name);
}
typedef struct ContactCopyProcess_ ContactCopyProcess;
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
index 7422eabb65..838343a357 100644
--- a/addressbook/gui/widgets/eab-gui-util.h
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -43,13 +43,8 @@ void eab_transfer_contacts (EBook *source,
gboolean delete_from_source,
GtkWindow *parent_window);
-void eab_contact_save (gchar *title,
- EContact *contact,
- GtkWindow *parent_window);
-
-void eab_contact_list_save (gchar *title,
- GList *list,
- GtkWindow *parent_window);
+void eab_suggest_filename (GtkFileChooser *file_chooser,
+ GList *contact_list);
GtkWidget *eab_create_image_chooser_widget (gchar *name, gchar *string1, gchar *string2, gint int1, gint int2);
diff --git a/doc/reference/shell/eshell-sections.txt b/doc/reference/shell/eshell-sections.txt
index b69e65f3fd..ae9ecaf0f6 100644
--- a/doc/reference/shell/eshell-sections.txt
+++ b/doc/reference/shell/eshell-sections.txt
@@ -360,7 +360,6 @@ e_datetime_format_format_tm
<FILE>e-dialog-utils</FILE>
<TITLE>Dialog Window Functions (Legacy)</TITLE>
e_notice
-e_file_dialog_save
e_file_get_save_filesel
e_file_can_save
e_file_check_local
@@ -554,7 +553,6 @@ e_str_compare
e_str_case_compare
e_collate_compare
e_int_compare
-e_write_file_uri
e_color_to_value
e_format_number
ESortCompareFunc
diff --git a/doc/reference/shell/tmpl/e-dialog-utils.sgml b/doc/reference/shell/tmpl/e-dialog-utils.sgml
index 55b595a51f..233bac2f49 100644
--- a/doc/reference/shell/tmpl/e-dialog-utils.sgml
+++ b/doc/reference/shell/tmpl/e-dialog-utils.sgml
@@ -28,17 +28,6 @@ Dialog Window Functions (Legacy)
@Varargs:
-<!-- ##### FUNCTION e_file_dialog_save ##### -->
-<para>
-
-</para>
-
-@parent:
-@title:
-@fname:
-@Returns:
-
-
<!-- ##### FUNCTION e_file_get_save_filesel ##### -->
<para>
diff --git a/doc/reference/shell/tmpl/e-util.sgml b/doc/reference/shell/tmpl/e-util.sgml
index 50af7459be..15d7d5f85c 100644
--- a/doc/reference/shell/tmpl/e-util.sgml
+++ b/doc/reference/shell/tmpl/e-util.sgml
@@ -176,16 +176,6 @@ Miscellaneous Utility Functions
@Returns:
-<!-- ##### FUNCTION e_write_file_uri ##### -->
-<para>
-
-</para>
-
-@filename:
-@data:
-@Returns:
-
-
<!-- ##### FUNCTION e_color_to_value ##### -->
<para>
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
index 99ad9d4067..2f908a761f 100644
--- a/doc/reference/shell/tmpl/eshell-unused.sgml
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -1850,6 +1850,16 @@ intelligent
@revision:
@Returns:
+<!-- ##### FUNCTION e_file_dialog_save ##### -->
+<para>
+
+</para>
+
+@parent:
+@title:
+@fname:
+@Returns:
+
<!-- ##### FUNCTION e_shell_backend_get_filename ##### -->
<para>
@@ -2254,6 +2264,15 @@ intelligent
@uri:
@Returns:
+<!-- ##### FUNCTION e_write_file_uri ##### -->
+<para>
+
+</para>
+
+@filename:
+@data:
+@Returns:
+
<!-- ##### FUNCTION es_event_get_type ##### -->
<para>
diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c
index 952d73f303..df0d8f5129 100644
--- a/e-util/e-dialog-utils.c
+++ b/e-util/e-dialog-utils.c
@@ -72,38 +72,6 @@ e_notice (gpointer parent, GtkMessageType type, const gchar *format, ...)
gtk_widget_destroy (dialog);
}
-gchar *
-e_file_dialog_save (GtkWindow *parent,
- const gchar *title,
- const gchar *fname)
-{
- GtkWidget *dialog;
- gchar *filename = NULL;
- gchar *uri;
-
- g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
-
- dialog = e_file_get_save_filesel (
- parent, title, fname, GTK_FILE_CHOOSER_ACTION_SAVE);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
- goto exit;
-
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
-
- if (e_file_can_save (GTK_WINDOW (dialog), uri)) {
- e_file_update_save_path (
- gtk_file_chooser_get_current_folder_uri (
- GTK_FILE_CHOOSER (dialog)), TRUE);
- filename = uri; /* FIXME This looks wrong. */
- }
-
-exit:
- gtk_widget_destroy (dialog);
-
- return filename;
-}
-
/**
* e_file_get_save_filesel:
* @parent: parent window
diff --git a/e-util/e-dialog-utils.h b/e-util/e-dialog-utils.h
index b4f305bdd5..2457f1c37a 100644
--- a/e-util/e-dialog-utils.h
+++ b/e-util/e-dialog-utils.h
@@ -29,9 +29,6 @@ void e_notice (gpointer parent,
GtkMessageType type,
const gchar *format,
...);
-gchar * e_file_dialog_save (GtkWindow *parent,
- const gchar *title,
- const gchar *fname);
GtkWidget * e_file_get_save_filesel (GtkWindow *parent,
const gchar *title,
const gchar *name,
diff --git a/e-util/e-file-utils.c b/e-util/e-file-utils.c
index f8adcc7a60..015da072f3 100644
--- a/e-util/e-file-utils.c
+++ b/e-util/e-file-utils.c
@@ -86,6 +86,24 @@ file_replace_contents_cb (GFile *file,
g_object_unref (activity);
}
+/**
+ * e_file_replace_contents_async:
+ * @file: input #GFile
+ * @contents: string of contents to replace the file with
+ * @length: the length of @contents in bytes
+ * @etag: a new entity tag for the @file, or %NULL
+ * @make_backup: %TRUE if a backup should be created
+ * @flags: a set of #GFileCreateFlags
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to the callback function
+ *
+ * This is a wrapper for g_file_replace_contents_async() that also returns
+ * an #EActivity to track the file operation. Cancelling the activity will
+ * cancel the file operation. See g_file_replace_contents_async() for more
+ * details.
+ *
+ * Returns: an #EActivity for the file operation
+ **/
EActivity *
e_file_replace_contents_async (GFile *file,
const gchar *contents,
@@ -111,9 +129,12 @@ e_file_replace_contents_async (GFile *file,
uri = g_file_get_uri (file);
filename = g_filename_from_uri (uri, &hostname, NULL);
- basename = g_filename_display_basename (filename);
+ if (filename != NULL)
+ basename = g_filename_display_basename (filename);
+ else
+ basename = g_strdup (_("(Unknown Filename)"));
- if (hostname != NULL) {
+ if (hostname == NULL) {
/* Translators: The string value is the basename of a file. */
format = _("Writing \"%s\"");
description = g_strdup_printf (format, basename);
@@ -151,6 +172,20 @@ e_file_replace_contents_async (GFile *file,
return activity;
}
+/**
+ * e_file_replace_contents_finish:
+ * @file: input #GFile
+ * @result: a #GAsyncResult
+ * @new_etag: return location for a new entity tag
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes an asynchronous replace of the given @file. See
+ * e_file_replace_contents_async(). Sets @new_etag to the new entity
+ * tag for the document, if present. Free it with g_free() when it is
+ * no longer needed.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ **/
gboolean
e_file_replace_contents_finish (GFile *file,
GAsyncResult *result,
diff --git a/e-util/e-util.c b/e-util/e-util.c
index bf1f387d15..9ad252a37d 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -618,65 +618,6 @@ e_int_compare (gconstpointer x, gconstpointer y)
return (nx == ny) ? 0 : (nx < ny) ? -1 : 1;
}
-gboolean
-e_write_file_uri (const gchar *filename,
- const gchar *data)
-{
- gboolean res;
- gsize length;
- GFile *file;
- GOutputStream *stream;
- GError *error = NULL;
-
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (data != NULL, FALSE);
-
- length = strlen (data);
-
- /* if it is uri, then create file for uri, otherwise for path */
- if (strstr (filename, "://"))
- file = g_file_new_for_uri (filename);
- else
- file = g_file_new_for_path (filename);
-
- if (!file) {
- g_warning ("Couldn't save item");
- return FALSE;
- }
-
- stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error));
- g_object_unref (file);
-
- if (!stream || error) {
- g_warning ("Couldn't save item%s%s", error ? ": " : "", error ? error->message : "");
-
- if (stream)
- g_object_unref (stream);
-
- if (error)
- g_error_free (error);
-
- return FALSE;
- }
-
- res = g_output_stream_write_all (stream, data, length, NULL, NULL, &error);
-
- if (error) {
- g_warning ("Couldn't save item: %s", error->message);
- g_clear_error (&error);
- }
-
- g_output_stream_close (stream, NULL, &error);
- g_object_unref (stream);
-
- if (error) {
- g_warning ("Couldn't close output stream: %s", error->message);
- g_error_free (error);
- }
-
- return res;
-}
-
/**
* e_color_to_value:
* color: a #GdkColor
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 88ebaa2af7..81ca05327c 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -81,8 +81,6 @@ gint e_collate_compare (gconstpointer x,
gconstpointer y);
gint e_int_compare (gconstpointer x,
gconstpointer y);
-gboolean e_write_file_uri (const gchar *filename,
- const gchar *data);
guint32 e_color_to_value (GdkColor *color);
/* This only makes a filename safe for usage as a filename.
diff --git a/modules/addressbook/e-book-shell-view-actions.c b/modules/addressbook/e-book-shell-view-actions.c
index c680c64ede..6882f29e6e 100644
--- a/modules/addressbook/e-book-shell-view-actions.c
+++ b/modules/addressbook/e-book-shell-view-actions.c
@@ -192,14 +192,75 @@ static void
action_address_book_save_as_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellBackend *shell_backend;
EBookShellContent *book_shell_content;
+ EAddressbookModel *model;
EAddressbookView *view;
+ EActivity *activity;
+ EBookQuery *query;
+ EBook *book;
+ GList *list = NULL;
+ GFile *file;
+ gchar *string;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
book_shell_content = book_shell_view->priv->book_shell_content;
view = e_book_shell_content_get_current_view (book_shell_content);
g_return_if_fail (view != NULL);
- e_addressbook_view_save_as (view, TRUE);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+
+ query = e_book_query_any_field_contains ("");
+ e_book_get_contacts (book, query, &list, NULL);
+ e_book_query_unref (query);
+
+ if (list == NULL)
+ goto exit;
+
+ file = e_shell_run_save_dialog (
+ shell, _("Save as vCard"),
+ (GtkCallback) eab_suggest_filename, list);
+ if (file == NULL)
+ goto exit;
+
+ string = eab_contact_list_to_string (list);
+ if (string == NULL) {
+ g_warning ("Could not convert contact list to a string");
+ g_object_unref (file);
+ goto exit;
+ }
+
+ /* XXX No callback means errors are discarded.
+ *
+ * There's an EError for this which I'm not using
+ * until I figure out a better way to display errors:
+ *
+ * "addressbook:save-error"
+ */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
+
+ g_object_unref (file);
+
+exit:
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
}
static void
@@ -454,14 +515,67 @@ static void
action_contact_save_as_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellBackend *shell_backend;
EBookShellContent *book_shell_content;
EAddressbookView *view;
+ EActivity *activity;
+ GList *list;
+ GFile *file;
+ gchar *string;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
book_shell_content = book_shell_view->priv->book_shell_content;
view = e_book_shell_content_get_current_view (book_shell_content);
g_return_if_fail (view != NULL);
- e_addressbook_view_save_as (view, FALSE);
+ list = e_addressbook_view_get_selected (view);
+
+ if (list == NULL)
+ goto exit;
+
+ file = e_shell_run_save_dialog (
+ shell, _("Save as vCard"),
+ (GtkCallback) eab_suggest_filename, list);
+ if (file == NULL)
+ goto exit;
+
+ string = eab_contact_list_to_string (list);
+ if (string == NULL) {
+ g_warning ("Could not convert contact list to a string");
+ g_object_unref (file);
+ goto exit;
+ }
+
+ /* XXX No callback means errors are discarded.
+ *
+ * There an EError for this which I'm not using
+ * until I figure out a better way to display errors:
+ *
+ * "addressbook:save-error"
+ */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
+
+ g_object_unref (file);
+
+exit:
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
}
static void
diff --git a/modules/addressbook/e-book-shell-view-private.h b/modules/addressbook/e-book-shell-view-private.h
index fa8624692a..c1aa300739 100644
--- a/modules/addressbook/e-book-shell-view-private.h
+++ b/modules/addressbook/e-book-shell-view-private.h
@@ -34,11 +34,14 @@
#include "e-util/e-util.h"
#include "e-util/e-binding.h"
+#include "e-util/e-file-utils.h"
#include "e-util/gconf-bridge.h"
#include "shell/e-shell-content.h"
#include "shell/e-shell-sidebar.h"
+#include "shell/e-shell-utils.h"
#include "misc/e-popup-action.h"
+#include "addressbook/util/eab-book-util.h"
#include "addressbook/gui/contact-editor/e-contact-editor.h"
#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
diff --git a/modules/calendar/e-cal-shell-view-actions.c b/modules/calendar/e-cal-shell-view-actions.c
index 408d02ffc3..4fa8b07eae 100644
--- a/modules/calendar/e-cal-shell-view-actions.c
+++ b/modules/calendar/e-cal-shell-view-actions.c
@@ -1065,8 +1065,10 @@ static void
action_event_save_as_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
+ EShell *shell;
EShellView *shell_view;
EShellWindow *shell_window;
+ EShellBackend *shell_backend;
ECalShellContent *cal_shell_content;
GnomeCalendarViewType view_type;
GnomeCalendar *calendar;
@@ -1074,12 +1076,15 @@ action_event_save_as_cb (GtkAction *action,
ECalendarViewEvent *event;
ECal *client;
icalcomponent *icalcomp;
+ EActivity *activity;
GList *selected;
- gchar *filename = NULL;
+ GFile *file;
gchar *string = NULL;
shell_view = E_SHELL_VIEW (cal_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
cal_shell_content = cal_shell_view->priv->cal_shell_content;
calendar = e_cal_shell_content_get_calendar (cal_shell_content);
@@ -1093,10 +1098,10 @@ action_event_save_as_cb (GtkAction *action,
client = event->comp_data->client;
icalcomp = event->comp_data->icalcomp;
- filename = e_file_dialog_save (
- GTK_WINDOW (shell_window), _("Save As..."), NULL);
- if (filename == NULL)
- goto exit;
+ file = e_shell_run_save_dialog (
+ shell, _("Save as iCalendar"), NULL, NULL);
+ if (file == NULL)
+ return;
string = e_cal_get_component_as_string (client, icalcomp);
if (string == NULL) {
@@ -1104,11 +1109,20 @@ action_event_save_as_cb (GtkAction *action,
goto exit;
}
- e_write_file_uri (filename, string);
+ /* XXX No callbacks means errors are discarded. */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
exit:
- g_free (filename);
- g_free (string);
+ g_object_unref (file);
g_list_free (selected);
}
@@ -1372,7 +1386,7 @@ static GtkActionEntry calendar_entries[] = {
{ "event-save-as",
GTK_STOCK_SAVE_AS,
- NULL,
+ N_("Save as iCalendar..."),
NULL,
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_event_save_as_cb) },
diff --git a/modules/calendar/e-cal-shell-view-memopad.c b/modules/calendar/e-cal-shell-view-memopad.c
index 7d4c1a501f..88cb53ff54 100644
--- a/modules/calendar/e-cal-shell-view-memopad.c
+++ b/modules/calendar/e-cal-shell-view-memopad.c
@@ -233,17 +233,22 @@ static void
action_calendar_memopad_save_as_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
+ EShell *shell;
EShellView *shell_view;
EShellWindow *shell_window;
+ EShellBackend *shell_backend;
ECalShellContent *cal_shell_content;
EMemoTable *memo_table;
ECalModelComponent *comp_data;
+ EActivity *activity;
GSList *list;
- gchar *filename;
+ GFile *file;
gchar *string;
shell_view = E_SHELL_VIEW (cal_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
cal_shell_content = cal_shell_view->priv->cal_shell_content;
memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
@@ -253,9 +258,9 @@ action_calendar_memopad_save_as_cb (GtkAction *action,
comp_data = list->data;
g_slist_free (list);
- filename = e_file_dialog_save (
- GTK_WINDOW (shell_window), _("Save as..."), NULL);
- if (filename == NULL)
+ file = e_shell_run_save_dialog (
+ shell, _("Save as iCalendar"), NULL, NULL);
+ if (file == NULL)
return;
/* XXX We only save the first selected memo. */
@@ -263,13 +268,23 @@ action_calendar_memopad_save_as_cb (GtkAction *action,
comp_data->client, comp_data->icalcomp);
if (string == NULL) {
g_warning ("Could not convert memo to a string.");
+ g_object_unref (file);
return;
}
- e_write_file_uri (filename, string);
+ /* XXX No callback means errors are discarded. */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
- g_free (filename);
- g_free (string);
+ g_object_unref (file);
}
static GtkActionEntry calendar_memopad_entries[] = {
@@ -332,7 +347,7 @@ static GtkActionEntry calendar_memopad_entries[] = {
{ "calendar-memopad-save-as",
GTK_STOCK_SAVE_AS,
- NULL,
+ N_("Save as iCalendar..."),
NULL,
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_calendar_memopad_save_as_cb) }
diff --git a/modules/calendar/e-cal-shell-view-private.h b/modules/calendar/e-cal-shell-view-private.h
index 690031198e..2ee0cff6a4 100644
--- a/modules/calendar/e-cal-shell-view-private.h
+++ b/modules/calendar/e-cal-shell-view-private.h
@@ -33,8 +33,10 @@
#include "e-util/e-binding.h"
#include "e-util/e-dialog-utils.h"
+#include "e-util/e-file-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-util.h"
+#include "shell/e-shell-utils.h"
#include "widgets/misc/e-popup-action.h"
#include "calendar/common/authentication.h"
diff --git a/modules/calendar/e-cal-shell-view-taskpad.c b/modules/calendar/e-cal-shell-view-taskpad.c
index 3e83e04fcc..5f2fd3ad0f 100644
--- a/modules/calendar/e-cal-shell-view-taskpad.c
+++ b/modules/calendar/e-cal-shell-view-taskpad.c
@@ -301,17 +301,22 @@ static void
action_calendar_taskpad_save_as_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
+ EShell *shell;
EShellView *shell_view;
EShellWindow *shell_window;
+ EShellBackend *shell_backend;
ECalShellContent *cal_shell_content;
ECalendarTable *task_table;
ECalModelComponent *comp_data;
+ EActivity *activity;
GSList *list;
- gchar *filename;
+ GFile *file;
gchar *string;
shell_view = E_SHELL_VIEW (cal_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
cal_shell_content = cal_shell_view->priv->cal_shell_content;
task_table = e_cal_shell_content_get_task_table (cal_shell_content);
@@ -321,22 +326,32 @@ action_calendar_taskpad_save_as_cb (GtkAction *action,
comp_data = list->data;
g_slist_free (list);
- filename = e_file_dialog_save (
- GTK_WINDOW (shell_window), _("Save as..."), NULL);
- if (filename == NULL)
+ file = e_shell_run_save_dialog (
+ shell, _("Save as iCalendar"), NULL, NULL);
+ if (file == NULL)
return;
string = e_cal_get_component_as_string (
comp_data->client, comp_data->icalcomp);
if (string == NULL) {
g_warning ("Could not convert task to a string");
+ g_object_unref (file);
return;
}
- e_write_file_uri (filename, string);
+ /* XXX No callback means errors are discarded. */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
- g_free (filename);
- g_free (string);
+ g_object_unref (file);
}
static GtkActionEntry calendar_taskpad_entries[] = {
diff --git a/modules/calendar/e-memo-shell-view-actions.c b/modules/calendar/e-memo-shell-view-actions.c
index ab8be53d04..31f12b3962 100644
--- a/modules/calendar/e-memo-shell-view-actions.c
+++ b/modules/calendar/e-memo-shell-view-actions.c
@@ -471,17 +471,22 @@ static void
action_memo_save_as_cb (GtkAction *action,
EMemoShellView *memo_shell_view)
{
+ EShell *shell;
EShellView *shell_view;
EShellWindow *shell_window;
+ EShellBackend *shell_backend;
EMemoShellContent *memo_shell_content;
EMemoTable *memo_table;
ECalModelComponent *comp_data;
+ EActivity *activity;
GSList *list;
- gchar *filename;
+ GFile *file;
gchar *string;
shell_view = E_SHELL_VIEW (memo_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
memo_shell_content = memo_shell_view->priv->memo_shell_content;
memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
@@ -491,9 +496,9 @@ action_memo_save_as_cb (GtkAction *action,
comp_data = list->data;
g_slist_free (list);
- filename = e_file_dialog_save (
- GTK_WINDOW (shell_window), _("Save as..."), NULL);
- if (filename == NULL)
+ file = e_shell_run_save_dialog (
+ shell, _("Save as iCalendar"), NULL, NULL);
+ if (file == NULL)
return;
/* XXX We only save the first selected memo. */
@@ -501,13 +506,23 @@ action_memo_save_as_cb (GtkAction *action,
comp_data->client, comp_data->icalcomp);
if (string == NULL) {
g_warning ("Could not convert memo to a string");
+ g_object_unref (file);
return;
}
- e_write_file_uri (filename, string);
+ /* XXX No callback means errors are discarded. */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
- g_free (filename);
- g_free (string);
+ g_object_unref (file);
}
static void
diff --git a/modules/calendar/e-memo-shell-view-private.h b/modules/calendar/e-memo-shell-view-private.h
index 276e6e5d30..37556943f2 100644
--- a/modules/calendar/e-memo-shell-view-private.h
+++ b/modules/calendar/e-memo-shell-view-private.h
@@ -31,9 +31,11 @@
#include "e-util/e-binding.h"
#include "e-util/e-dialog-utils.h"
+#include "e-util/e-file-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-util.h"
#include "e-util/gconf-bridge.h"
+#include "shell/e-shell-utils.h"
#include "widgets/misc/e-popup-action.h"
#include "calendar/gui/comp-util.h"
diff --git a/modules/calendar/e-task-shell-view-actions.c b/modules/calendar/e-task-shell-view-actions.c
index fb7b89b049..282d5a3e75 100644
--- a/modules/calendar/e-task-shell-view-actions.c
+++ b/modules/calendar/e-task-shell-view-actions.c
@@ -598,17 +598,22 @@ static void
action_task_save_as_cb (GtkAction *action,
ETaskShellView *task_shell_view)
{
+ EShell *shell;
EShellView *shell_view;
EShellWindow *shell_window;
+ EShellBackend *shell_backend;
ETaskShellContent *task_shell_content;
ECalendarTable *task_table;
ECalModelComponent *comp_data;
+ EActivity *activity;
GSList *list;
- gchar *filename;
+ GFile *file;
gchar *string;
shell_view = E_SHELL_VIEW (task_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
task_shell_content = task_shell_view->priv->task_shell_content;
task_table = e_task_shell_content_get_task_table (task_shell_content);
@@ -618,22 +623,33 @@ action_task_save_as_cb (GtkAction *action,
comp_data = list->data;
g_slist_free (list);
- filename = e_file_dialog_save (
- GTK_WINDOW (shell_window), _("Save as..."), NULL);
- if (filename == NULL)
+ file = e_shell_run_save_dialog (
+ shell, _("Save as iCalendar"), NULL, NULL);
+ if (file == NULL)
return;
+ /* XXX We only save the first selected task. */
string = e_cal_get_component_as_string (
comp_data->client, comp_data->icalcomp);
if (string == NULL) {
g_warning ("Could not convert task to a string");
+ g_object_unref (file);
return;
}
- e_write_file_uri (filename, string);
+ /* XXX No callback means errors are discarded. */
+ activity = e_file_replace_contents_async (
+ file, string, strlen (string), NULL, FALSE,
+ G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ /* Free the string when the activity is finalized. */
+ g_object_set_data_full (
+ G_OBJECT (activity),
+ "file-content", string,
+ (GDestroyNotify) g_free);
- g_free (filename);
- g_free (string);
+ g_object_unref (file);
}
static void
diff --git a/modules/calendar/e-task-shell-view-private.h b/modules/calendar/e-task-shell-view-private.h
index b369b4c948..38b03ae359 100644
--- a/modules/calendar/e-task-shell-view-private.h
+++ b/modules/calendar/e-task-shell-view-private.h
@@ -32,9 +32,11 @@
#include "e-util/e-binding.h"
#include "e-util/e-dialog-utils.h"
+#include "e-util/e-file-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-util.h"
#include "e-util/gconf-bridge.h"
+#include "shell/e-shell-utils.h"
#include "widgets/misc/e-popup-action.h"
#include "calendar/common/authentication.h"
diff --git a/shell/Makefile.am b/shell/Makefile.am
index d8eea3c5e3..608ecd314d 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -26,6 +26,7 @@ eshellinclude_HEADERS = \
e-shell-sidebar.h \
e-shell-switcher.h \
e-shell-taskbar.h \
+ e-shell-utils.h \
e-shell-view.h \
e-shell-window.h \
e-shell-window-actions.h \
@@ -59,7 +60,7 @@ libeshell_la_CPPFLAGS = \
libeshell_la_SOURCES = \
$(NM_SUPPORT_FILES) \
- $(IDL_GENERATED) \
+ $(eshellinclude_HEADERS) \
e-shell.c \
e-shell-backend.c \
e-shell-content.c \
@@ -67,11 +68,11 @@ libeshell_la_SOURCES = \
e-shell-sidebar.c \
e-shell-switcher.c \
e-shell-taskbar.c \
+ e-shell-utils.c \
e-shell-view.c \
e-shell-window.c \
e-shell-window-private.c \
e-shell-window-private.h \
- $(eshellinclude_HEADERS) \
e-shell-migrate.c \
e-shell-migrate.h \
e-shell-window-actions.c \
diff --git a/shell/apps_evolution_shell.schemas.in b/shell/apps_evolution_shell.schemas.in
index 157df8cb9e..b5aa3e6931 100644
--- a/shell/apps_evolution_shell.schemas.in
+++ b/shell/apps_evolution_shell.schemas.in
@@ -59,8 +59,8 @@
<!-- Initial GtkFileChooser Folder -->
<schema>
- <key>/schemas/apps/evolution/shell/current_folder</key>
- <applyto>/apps/evolution/shell/current_folder</applyto>
+ <key>/schemas/apps/evolution/shell/file_chooser_folder</key>
+ <applyto>/apps/evolution/shell/file_chooser_folder</applyto>
<owner>evolution</owner>
<type>string</type>
<locale name="C">
diff --git a/shell/e-shell-utils.c b/shell/e-shell-utils.c
new file mode 100644
index 0000000000..9d3d6f5fb4
--- /dev/null
+++ b/shell/e-shell-utils.c
@@ -0,0 +1,100 @@
+/*
+ * e-shell-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-utils.h"
+
+#include <glib/gi18n-lib.h>
+
+/**
+ * e_shell_run_save_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 save mode with the given title and
+ * returns the selected #GFile. It automatically remembers the selected
+ * folder. 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 save to, or %NULL
+ **/
+GFile *
+e_shell_run_save_dialog (EShell *shell,
+ const gchar *title,
+ GtkCallback customize_func,
+ gpointer customize_data)
+{
+ EShellSettings *shell_settings;
+ GtkFileChooser *file_chooser;
+ GFile *chosen_file = NULL;
+ GtkWidget *dialog;
+ GtkWindow *parent;
+ const gchar *property_name;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ property_name = "file-chooser-folder";
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ parent = e_shell_get_active_window (shell);
+
+ dialog = gtk_file_chooser_dialog_new (
+ title, parent,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
+
+ file_chooser = GTK_FILE_CHOOSER (dialog);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ gtk_file_chooser_set_local_only (file_chooser, FALSE);
+ gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);
+
+ /* Restore the current folder from the previous file chooser. */
+ uri = e_shell_settings_get_string (shell_settings, property_name);
+ if (uri != NULL)
+ gtk_file_chooser_set_current_folder_uri (file_chooser, uri);
+ g_free (uri);
+
+ /* 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_OK)
+ goto exit;
+
+ chosen_file = gtk_file_chooser_get_file (file_chooser);
+
+ /* Save the current folder for subsequent file choosers. */
+ uri = gtk_file_chooser_get_current_folder_uri (file_chooser);
+ e_shell_settings_set_string (shell_settings, property_name, uri);
+ g_free (uri);
+
+exit:
+ gtk_widget_destroy (dialog);
+
+ return chosen_file;
+}
diff --git a/shell/e-shell-utils.h b/shell/e-shell-utils.h
new file mode 100644
index 0000000000..6fedca8a4a
--- /dev/null
+++ b/shell/e-shell-utils.h
@@ -0,0 +1,42 @@
+/*
+ * e-shell-utils.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-utils
+ * @short_description: high-level utilities with shell integration
+ * @include: shell/e-shell-utils.h
+ **/
+
+#ifndef E_SHELL_UTILS_H
+#define E_SHELL_UTILS_H
+
+#include <shell/e-shell.h>
+
+G_BEGIN_DECLS
+
+GFile * e_shell_run_save_dialog (EShell *shell,
+ const gchar *title,
+ GtkCallback customize_func,
+ gpointer customize_data);
+
+G_END_DECLS
+
+#endif /* E_SHELL_UTILS_H */
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 61ce8d7c02..b0a1490148 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -903,16 +903,6 @@ shell_class_init (EShellClass *class)
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
-
- /* Install some application-wide settings. */
-
- e_shell_settings_install_property (
- g_param_spec_string (
- "file-chooser-folder",
- NULL,
- NULL,
- NULL,
- G_PARAM_READWRITE));
}
static void
@@ -950,6 +940,10 @@ shell_init (EShell *shell)
* otherwise the GConf bindings will not get set up. */
e_shell_settings_install_property_for_key (
+ "file-chooser-folder",
+ "/apps/evolution/shell/file_chooser_folder");
+
+ e_shell_settings_install_property_for_key (
"start-offline",
"/apps/evolution/shell/start_offline");
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c
index c99bdeab3f..4c87d65dd9 100644
--- a/widgets/misc/e-attachment-store.c
+++ b/widgets/misc/e-attachment-store.c
@@ -142,7 +142,7 @@ attachment_store_constructed (GObject *object)
bridge = gconf_bridge_get ();
- key = "/apps/evolution/shell/current_folder";
+ key = "/apps/evolution/shell/file_chooser_folder";
gconf_bridge_bind_property (bridge, key, object, "current-folder");
}