aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/gui/dialogs/comp-editor.c21
-rw-r--r--plugins/mail-to-task/mail-to-task.c21
-rw-r--r--widgets/misc/e-attachment-store.c145
-rw-r--r--widgets/misc/e-attachment-store.h1
4 files changed, 116 insertions, 72 deletions
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index eaf779df33..fc062a0de9 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -43,6 +43,7 @@
#include <e-util/e-util-private.h>
#include <shell/e-shell.h>
+#include <libedataserver/e-data-server-util.h>
#include <libecal/e-cal-client.h>
#include <libecal/e-cal-client-view.h>
@@ -302,7 +303,7 @@ get_attachment_list (CompEditor *editor)
GSList *list = NULL;
const gchar *comp_uid = NULL;
const gchar *local_store;
- gchar *path;
+ gchar *filename_prefix, *tmp;
gint ii;
struct {
@@ -311,6 +312,9 @@ get_attachment_list (CompEditor *editor)
GtkWindow *parent;
} status;
+ e_cal_component_get_uid (editor->priv->comp, &comp_uid);
+ g_return_val_if_fail (comp_uid != NULL, NULL);
+
status.uris = NULL;
status.done = FALSE;
status.parent = g_object_ref (editor);
@@ -318,17 +322,20 @@ get_attachment_list (CompEditor *editor)
view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
store = e_attachment_view_get_store (view);
+ tmp = g_strdup (comp_uid);
+ e_filename_make_safe (tmp);
+ filename_prefix = g_strconcat (tmp, "-", NULL);
+ g_free (tmp);
+
local_store = e_cal_client_get_local_attachment_store (editor->priv->cal_client);
- e_cal_component_get_uid (editor->priv->comp, &comp_uid);
- path = g_build_path ("/", local_store, comp_uid, NULL);
- destination = g_file_new_for_path (path);
- g_free (path);
+ destination = g_file_new_for_path (local_store);
e_attachment_store_save_async (
- store, destination, (GAsyncReadyCallback)
- attachment_save_finished, &status);
+ store, destination, filename_prefix,
+ (GAsyncReadyCallback) attachment_save_finished, &status);
g_object_unref (destination);
+ g_free (filename_prefix);
/* We can't return until we have results, so crank
* the main loop until the callback gets triggered. */
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index eb9e762b75..1d9f1fa0d0 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -37,6 +37,7 @@
#include <libecal/e-cal-client.h>
#include <libecal/e-cal-component.h>
#include <libedataserver/e-account.h>
+#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-flag.h>
#include <libedataserverui/e-source-selector-dialog.h>
#include <libedataserverui/e-client-utils.h>
@@ -400,8 +401,8 @@ set_attachments (ECalClient *client,
GSList *uri_list = NULL;
const gchar *comp_uid = NULL;
const gchar *local_store;
+ gchar *filename_prefix, *tmp;
gint ii, n_parts;
- gchar *path;
struct _att_async_cb_data cb_data;
cb_data.flag = e_flag_new ();
@@ -416,11 +417,15 @@ set_attachments (ECalClient *client,
return;
e_cal_component_get_uid (comp, &comp_uid);
- local_store = e_cal_client_get_local_attachment_store (client);
- path = g_build_path ("/", local_store, comp_uid, NULL);
+ g_return_if_fail (comp_uid != NULL);
- destination = g_file_new_for_path (path);
- g_free (path);
+ tmp = g_strdup (comp_uid);
+ e_filename_make_safe (tmp);
+ filename_prefix = g_strconcat (tmp, "-", NULL);
+ g_free (tmp);
+
+ local_store = e_cal_client_get_local_attachment_store (client);
+ destination = g_file_new_for_path (local_store);
/* Create EAttachments from the MIME parts and add them to the
* attachment store. */
@@ -457,8 +462,10 @@ set_attachments (ECalClient *client,
e_flag_clear (cb_data.flag);
e_attachment_store_save_async (
- store, destination, (GAsyncReadyCallback)
- attachment_save_finished, &cb_data);
+ store, destination, filename_prefix,
+ (GAsyncReadyCallback) attachment_save_finished, &cb_data);
+
+ g_free (filename_prefix);
/* We can't return until we have results. */
e_flag_wait (cb_data.flag);
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c
index a1e1fa2586..8db9f2af80 100644
--- a/widgets/misc/e-attachment-store.c
+++ b/widgets/misc/e-attachment-store.c
@@ -1068,6 +1068,7 @@ typedef struct _SaveContext SaveContext;
struct _SaveContext {
GSimpleAsyncResult *simple;
GFile *destination;
+ gchar *filename_prefix;
GFile *fresh_directory;
GFile *trash_directory;
GList *attachment_list;
@@ -1079,6 +1080,7 @@ struct _SaveContext {
static SaveContext *
attachment_store_save_context_new (EAttachmentStore *store,
GFile *destination,
+ const gchar *filename_prefix,
GAsyncReadyCallback callback,
gpointer user_data)
{
@@ -1101,6 +1103,7 @@ attachment_store_save_context_new (EAttachmentStore *store,
save_context = g_slice_new0 (SaveContext);
save_context->simple = simple;
save_context->destination = g_object_ref (destination);
+ save_context->filename_prefix = g_strdup (filename_prefix);
save_context->attachment_list = attachment_list;
save_context->uris = uris;
@@ -1123,6 +1126,9 @@ attachment_store_save_context_free (SaveContext *save_context)
save_context->destination = NULL;
}
+ g_free (save_context->filename_prefix);
+ save_context->filename_prefix = NULL;
+
if (save_context->fresh_directory) {
g_object_unref (save_context->fresh_directory);
save_context->fresh_directory = NULL;
@@ -1139,6 +1145,56 @@ attachment_store_save_context_free (SaveContext *save_context)
}
static void
+attachment_store_move_file (SaveContext *save_context, GFile *source, GFile *destination, GError **error)
+{
+ gchar *tmpl;
+ gchar *path;
+
+ g_return_if_fail (save_context != NULL);
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (destination != NULL);
+ g_return_if_fail (error != NULL);
+
+ /* Attachments are all saved to a temporary directory.
+ * Now we need to move the existing destination directory
+ * out of the way (if it exists). Instead of testing for
+ * existence we'll just attempt the move and ignore any
+ * G_IO_ERROR_NOT_FOUND errors. */
+
+ /* First, however, we need another temporary directory to
+ * move the existing destination directory to. Note we're
+ * not actually creating the directory yet, just picking a
+ * name for it. The usual raciness with this approach
+ * applies here (read up on mktemp(3)), but worst case is
+ * we get a spurious G_IO_ERROR_WOULD_MERGE error and the
+ * user has to try saving attachments again. */
+ tmpl = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
+ path = e_mktemp (tmpl);
+ g_free (tmpl);
+
+ save_context->trash_directory = g_file_new_for_path (path);
+ g_free (path);
+
+ /* XXX No asynchronous move operation in GIO? */
+ g_file_move (
+ destination,
+ save_context->trash_directory,
+ G_FILE_COPY_NONE, NULL, NULL, NULL, error);
+
+ if (*error != NULL && !g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ return;
+
+ g_clear_error (error);
+
+ /* Now we can move the file from the temporary directory
+ * to the user-specified destination. */
+ g_file_move (
+ source,
+ destination,
+ G_FILE_COPY_NONE, NULL, NULL, NULL, error);
+}
+
+static void
attachment_store_save_cb (EAttachment *attachment,
GAsyncResult *result,
SaveContext *save_context)
@@ -1146,8 +1202,6 @@ attachment_store_save_cb (EAttachment *attachment,
GSimpleAsyncResult *simple;
GFile *file;
gchar **uris;
- gchar *template;
- gchar *path;
GError *error = NULL;
file = e_attachment_save_finish (attachment, result, &error);
@@ -1161,18 +1215,35 @@ attachment_store_save_cb (EAttachment *attachment,
/* Assemble the file's final URI from its basename. */
gchar *basename;
gchar *uri;
+ GFile *source = NULL, *destination = NULL;
basename = g_file_get_basename (file);
g_object_unref (file);
+ source = g_file_get_child (save_context->fresh_directory, basename);
+
+ if (save_context->filename_prefix && *save_context->filename_prefix) {
+ gchar *tmp = basename;
+
+ basename = g_strconcat (save_context->filename_prefix, basename, NULL);
+ g_free (tmp);
+ }
+
file = save_context->destination;
- file = g_file_get_child (file, basename);
- uri = g_file_get_uri (file);
- g_object_unref (file);
+ destination = g_file_get_child (file, basename);
+ uri = g_file_get_uri (destination);
- save_context->uris[save_context->index++] = uri;
+ /* move them file-by-file */
+ attachment_store_move_file (save_context, source, destination, &error);
- } else if (error != NULL) {
+ if (!error)
+ save_context->uris[save_context->index++] = uri;
+
+ g_object_unref (source);
+ g_object_unref (destination);
+ }
+
+ if (error != NULL) {
/* If this is the first error, cancel the other jobs. */
if (save_context->error == NULL) {
g_propagate_error (&save_context->error, error);
@@ -1189,8 +1260,7 @@ attachment_store_save_cb (EAttachment *attachment,
g_warning ("%s", error->message);
}
- if (error != NULL)
- g_error_free (error);
+ g_clear_error (&error);
/* If there's still jobs running, let them finish. */
if (save_context->attachment_list != NULL)
@@ -1212,53 +1282,6 @@ attachment_store_save_cb (EAttachment *attachment,
return;
}
- /* Attachments are all saved to a temporary directory.
- * Now we need to move the existing destination directory
- * out of the way (if it exists). Instead of testing for
- * existence we'll just attempt the move and ignore any
- * G_IO_ERROR_NOT_FOUND errors. */
-
- /* First, however, we need another temporary directory to
- * move the existing destination directory to. Note we're
- * not actually creating the directory yet, just picking a
- * name for it. The usual raciness with this approach
- * applies here (read up on mktemp(3)), but worst case is
- * we get a spurious G_IO_ERROR_WOULD_MERGE error and the
- * user has to try saving attachments again. */
- template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
- path = e_mktemp (template);
- g_free (template);
-
- save_context->trash_directory = g_file_new_for_path (path);
- g_free (path);
-
- /* XXX No asynchronous move operation in GIO? */
- g_file_move (
- save_context->destination,
- save_context->trash_directory,
- G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
-
- if (error != NULL && !g_error_matches (
- error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
-
- simple = save_context->simple;
- g_simple_async_result_set_from_error (simple, error);
- g_simple_async_result_complete (simple);
-
- attachment_store_save_context_free (save_context);
- g_error_free (error);
- return;
- }
-
- g_clear_error (&error);
-
- /* Now we can move the first temporary directory containing
- * the newly saved files to the user-specified destination. */
- g_file_move (
- save_context->fresh_directory,
- save_context->destination,
- G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
-
if (error != NULL) {
simple = save_context->simple;
g_simple_async_result_set_from_error (simple, error);
@@ -1269,6 +1292,9 @@ attachment_store_save_cb (EAttachment *attachment,
return;
}
+ /* clean-up left directory */
+ g_file_delete (save_context->fresh_directory, NULL, NULL);
+
/* And the URI list. */
uris = save_context->uris;
save_context->uris = NULL;
@@ -1279,10 +1305,13 @@ attachment_store_save_cb (EAttachment *attachment,
attachment_store_save_context_free (save_context);
}
-
+/*
+ * @filename_prefix: prefix to use for a file name; can be %NULL for none
+ **/
void
e_attachment_store_save_async (EAttachmentStore *store,
GFile *destination,
+ const gchar *filename_prefix,
GAsyncReadyCallback callback,
gpointer user_data)
{
@@ -1296,7 +1325,7 @@ e_attachment_store_save_async (EAttachmentStore *store,
g_return_if_fail (G_IS_FILE (destination));
save_context = attachment_store_save_context_new (
- store, destination, callback, user_data);
+ store, destination, filename_prefix, callback, user_data);
attachment_list = save_context->attachment_list;
diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h
index a7839aca71..cdf33f507a 100644
--- a/widgets/misc/e-attachment-store.h
+++ b/widgets/misc/e-attachment-store.h
@@ -128,6 +128,7 @@ gboolean e_attachment_store_load_finish (EAttachmentStore *store,
GError **error);
void e_attachment_store_save_async (EAttachmentStore *store,
GFile *destination,
+ const gchar *filename_prefix,
GAsyncReadyCallback callback,
gpointer user_data);
gchar ** e_attachment_store_save_finish (EAttachmentStore *store,