aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2014-03-24 21:26:24 +0800
committerMatthew Barnes <mbarnes@redhat.com>2014-03-27 08:24:34 +0800
commit5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1 (patch)
tree35b06eab2d6795026fbf63c27bf5cedb9dc29db8
parentb6cf2c3763b1d51f8824ee14e226b6adb40e7e1b (diff)
downloadgsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar.gz
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar.bz2
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar.lz
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar.xz
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.tar.zst
gsoc2013-evolution-5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1.zip
Add EMailFolderCreateDialog.
Subclass of EMFolderSelector, replaces em_folder_utils_create_folder().
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/e-mail-folder-create-dialog.c498
-rw-r--r--mail/e-mail-folder-create-dialog.h76
-rw-r--r--mail/em-folder-selector.c181
-rw-r--r--mail/em-folder-selector.h2
-rw-r--r--mail/em-folder-utils.c164
-rw-r--r--mail/em-folder-utils.h4
-rw-r--r--modules/mail/e-mail-shell-backend.c40
-rw-r--r--modules/mail/e-mail-shell-view-actions.c46
-rw-r--r--modules/mail/e-mail-shell-view-private.h1
10 files changed, 702 insertions, 312 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index e5cc9daf34..d40922e605 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -84,6 +84,7 @@ mailinclude_HEADERS = \
e-mail-display-popup-extension.h \
e-mail-enums.h \
e-mail-enumtypes.h \
+ e-mail-folder-create-dialog.h \
e-mail-folder-pane.h \
e-mail-junk-options.h \
e-mail-label-action.h \
@@ -160,6 +161,7 @@ libevolution_mail_la_SOURCES = \
e-mail-display.c \
e-mail-display-popup-extension.c \
e-mail-enumtypes.c \
+ e-mail-folder-create-dialog.c \
e-mail-folder-pane.c \
e-mail-junk-options.c \
e-mail-label-action.c \
diff --git a/mail/e-mail-folder-create-dialog.c b/mail/e-mail-folder-create-dialog.c
new file mode 100644
index 0000000000..bca14de1d9
--- /dev/null
+++ b/mail/e-mail-folder-create-dialog.c
@@ -0,0 +1,498 @@
+/*
+ * e-mail-folder-create-dialog.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.
+ *
+ * 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "e-mail-folder-create-dialog.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include "em-vfolder-editor-rule.h"
+#include "mail-vfolder-ui.h"
+
+#define E_MAIL_FOLDER_CREATE_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_FOLDER_CREATE_DIALOG, EMailFolderCreateDialogPrivate))
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EMailFolderCreateDialogPrivate {
+ EMailUISession *session;
+ GtkWidget *name_entry;
+};
+
+struct _AsyncContext {
+ EMailFolderCreateDialog *dialog;
+ EActivity *activity;
+};
+
+enum {
+ PROP_0,
+ PROP_SESSION
+};
+
+enum {
+ FOLDER_CREATED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EMailFolderCreateDialog,
+ e_mail_folder_create_dialog,
+ EM_TYPE_FOLDER_SELECTOR)
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ g_clear_object (&async_context->dialog);
+ g_clear_object (&async_context->activity);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+mail_folder_create_dialog_create_folder_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EMailFolderCreateDialog *dialog;
+ EActivity *activity;
+ EAlertSink *alert_sink;
+ GdkWindow *gdk_window;
+ AsyncContext *async_context;
+ GError *local_error = NULL;
+
+ async_context = (AsyncContext *) user_data;
+
+ dialog = async_context->dialog;
+ activity = async_context->activity;
+ alert_sink = e_activity_get_alert_sink (activity);
+
+ /* Set the cursor back to normal. */
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (dialog));
+ gdk_window_set_cursor (gdk_window, NULL);
+
+ e_mail_store_create_folder_finish (
+ CAMEL_STORE (source_object), result, &local_error);
+
+ /* Ignore cancellations. */
+ if (e_activity_handle_cancellation (activity, local_error)) {
+ g_error_free (local_error);
+
+ } else if (local_error != NULL) {
+ e_alert_submit (
+ alert_sink,
+ "system:simple-error",
+ local_error->message, NULL);
+ g_error_free (local_error);
+
+ } else {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
+
+ async_context_free (async_context);
+}
+
+static void
+mail_folder_create_dialog_create_folder (EMailFolderCreateDialog *dialog)
+{
+ CamelStore *store = NULL;
+ gchar *create_folder_name;
+ gchar *parent_folder_name = NULL;
+ const gchar *text;
+
+ em_folder_selector_get_selected (
+ EM_FOLDER_SELECTOR (dialog), &store, &parent_folder_name);
+
+ g_return_if_fail (store != NULL);
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->priv->name_entry));
+
+ if (parent_folder_name != NULL) {
+ create_folder_name = g_strconcat (
+ parent_folder_name, "/", text, NULL);
+ } else {
+ create_folder_name = g_strdup (text);
+ }
+
+ /* For the vfolder store, we just open the editor window. */
+ if (CAMEL_IS_VEE_STORE (store)) {
+ EMailUISession *session;
+ EFilterRule *rule;
+
+ session = e_mail_folder_create_dialog_get_session (dialog);
+ rule = em_vfolder_editor_rule_new (E_MAIL_SESSION (session));
+ e_filter_rule_set_name (rule, create_folder_name);
+ vfolder_gui_add_rule (EM_VFOLDER_RULE (rule));
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ } else {
+ AsyncContext *async_context;
+ EActivity *activity;
+ GCancellable *cancellable;
+ GdkCursor *gdk_cursor;
+ GdkWindow *gdk_window;
+
+ /* Make the cursor appear busy. */
+ gdk_cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (dialog));
+ gdk_window_set_cursor (gdk_window, gdk_cursor);
+ g_object_unref (gdk_cursor);
+
+ activity = em_folder_selector_new_activity (
+ EM_FOLDER_SELECTOR (dialog));
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->dialog = g_object_ref (dialog);
+ async_context->activity = g_object_ref (activity);
+
+ cancellable = e_activity_get_cancellable (activity);
+
+ e_mail_store_create_folder (
+ store, create_folder_name,
+ G_PRIORITY_DEFAULT, cancellable,
+ mail_folder_create_dialog_create_folder_cb,
+ async_context);
+
+ g_object_unref (activity);
+ }
+
+ g_free (create_folder_name);
+ g_free (parent_folder_name);
+
+ g_object_unref (store);
+}
+
+static gboolean
+mail_folder_create_dialog_inputs_are_valid (EMailFolderCreateDialog *dialog)
+{
+ GtkEntry *entry;
+ const gchar *original_text;
+ gchar *stripped_text;
+ gboolean folder_or_store_is_selected;
+ gboolean inputs_are_valid;
+
+ entry = GTK_ENTRY (dialog->priv->name_entry);
+
+ original_text = gtk_entry_get_text (entry);
+ stripped_text = e_util_strdup_strip (original_text);
+
+ folder_or_store_is_selected =
+ em_folder_selector_get_selected (
+ EM_FOLDER_SELECTOR (dialog), NULL, NULL);
+
+ inputs_are_valid =
+ folder_or_store_is_selected &&
+ (stripped_text != NULL) &&
+ (strchr (stripped_text, '/') == NULL);
+
+ g_free (stripped_text);
+
+ return inputs_are_valid;
+}
+
+static void
+mail_folder_create_dialog_entry_activate_cb (GtkEntry *entry,
+ EMailFolderCreateDialog *dialog)
+{
+ if (mail_folder_create_dialog_inputs_are_valid (dialog))
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+static void
+mail_folder_create_dialog_entry_changed_cb (GtkEntry *entry,
+ EMailFolderCreateDialog *dialog)
+{
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK,
+ mail_folder_create_dialog_inputs_are_valid (dialog));
+}
+
+static void
+mail_folder_create_dialog_set_session (EMailFolderCreateDialog *dialog,
+ EMailUISession *session)
+{
+ g_return_if_fail (E_IS_MAIL_UI_SESSION (session));
+ g_return_if_fail (dialog->priv->session == NULL);
+
+ dialog->priv->session = g_object_ref (session);
+}
+
+static void
+mail_folder_create_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SESSION:
+ mail_folder_create_dialog_set_session (
+ E_MAIL_FOLDER_CREATE_DIALOG (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_folder_create_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_folder_create_dialog_get_session (
+ E_MAIL_FOLDER_CREATE_DIALOG (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_folder_create_dialog_dispose (GObject *object)
+{
+ EMailFolderCreateDialogPrivate *priv;
+
+ priv = E_MAIL_FOLDER_CREATE_DIALOG_GET_PRIVATE (object);
+
+ g_clear_object (&priv->session);
+ g_clear_object (&priv->name_entry);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_folder_create_dialog_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_folder_create_dialog_constructed (GObject *object)
+{
+ EMailFolderCreateDialog *dialog;
+ EMailAccountStore *account_store;
+ EMailUISession *session;
+ EMFolderTree *folder_tree;
+ EMFolderTreeModel *model;
+ GQueue queue = G_QUEUE_INIT;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ dialog = E_MAIL_FOLDER_CREATE_DIALOG (object);
+ session = e_mail_folder_create_dialog_get_session (dialog);
+ model = em_folder_selector_get_model (EM_FOLDER_SELECTOR (dialog));
+
+ /* Populate the tree model before chaining up, since the
+ * subclass will immediately try to restore the tree state. */
+
+ account_store = e_mail_ui_session_get_account_store (session);
+ e_mail_account_store_queue_enabled_services (account_store, &queue);
+
+ while (!g_queue_is_empty (&queue)) {
+ CamelService *service;
+ CamelStoreFlags flags;
+
+ service = g_queue_pop_head (&queue);
+ g_warn_if_fail (CAMEL_IS_STORE (service));
+
+ flags = CAMEL_STORE (service)->flags;
+ if ((flags & CAMEL_STORE_CAN_EDIT_FOLDERS) == 0)
+ continue;
+
+ em_folder_tree_model_add_store (model, CAMEL_STORE (service));
+ }
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_folder_create_dialog_parent_class)->
+ constructed (object);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Create Folder"));
+
+ em_folder_selector_set_caption (
+ EM_FOLDER_SELECTOR (dialog),
+ _("Specify where to create the folder:"));
+
+ em_folder_selector_set_default_button_label (
+ EM_FOLDER_SELECTOR (dialog), _("C_reate"));
+
+ folder_tree = em_folder_selector_get_folder_tree (
+ EM_FOLDER_SELECTOR (dialog));
+ em_folder_tree_set_excluded (folder_tree, EMFT_EXCLUDE_NOINFERIORS);
+
+ /* Add a folder name entry field to the dialog. */
+
+ container = em_folder_selector_get_content_area (
+ EM_FOLDER_SELECTOR (dialog));
+
+ widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_label_new_with_mnemonic (_("Folder _name:"));
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ dialog->priv->name_entry = g_object_ref (widget);
+ gtk_widget_grab_focus (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "activate",
+ G_CALLBACK (mail_folder_create_dialog_entry_activate_cb),
+ dialog);
+
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (mail_folder_create_dialog_entry_changed_cb),
+ dialog);
+}
+
+static void
+mail_folder_create_dialog_response (GtkDialog *dialog,
+ gint response_id)
+{
+ /* Do not chain up. GtkDialog does not implement this method. */
+
+ switch (response_id) {
+ case GTK_RESPONSE_OK:
+ mail_folder_create_dialog_create_folder (
+ E_MAIL_FOLDER_CREATE_DIALOG (dialog));
+ break;
+ case GTK_RESPONSE_CANCEL:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+mail_folder_create_dialog_folder_selected (EMFolderSelector *selector,
+ CamelStore *store,
+ const gchar *folder_name)
+{
+ EMailFolderCreateDialog *dialog;
+
+ /* Do not chain up. This overrides the subclass behavior. */
+
+ dialog = E_MAIL_FOLDER_CREATE_DIALOG (selector);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK,
+ mail_folder_create_dialog_inputs_are_valid (dialog));
+}
+
+static void
+e_mail_folder_create_dialog_class_init (EMailFolderCreateDialogClass *class)
+{
+ GObjectClass *object_class;
+ GtkDialogClass *dialog_class;
+ EMFolderSelectorClass *selector_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailFolderCreateDialogPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_folder_create_dialog_set_property;
+ object_class->get_property = mail_folder_create_dialog_get_property;
+ object_class->dispose = mail_folder_create_dialog_dispose;
+ object_class->constructed = mail_folder_create_dialog_constructed;
+
+ dialog_class = GTK_DIALOG_CLASS (class);
+ dialog_class->response = mail_folder_create_dialog_response;
+
+ selector_class = EM_FOLDER_SELECTOR_CLASS (class);
+ selector_class->folder_selected = mail_folder_create_dialog_folder_selected;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "An EMailUISession from which "
+ "to list enabled mail stores",
+ E_TYPE_MAIL_UI_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[FOLDER_CREATED] = g_signal_new (
+ "folder-created",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailFolderCreateDialogClass, folder_created),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 2,
+ CAMEL_TYPE_STORE,
+ G_TYPE_STRING);
+}
+
+static void
+e_mail_folder_create_dialog_init (EMailFolderCreateDialog *dialog)
+{
+ dialog->priv = E_MAIL_FOLDER_CREATE_DIALOG_GET_PRIVATE (dialog);
+}
+
+GtkWidget *
+e_mail_folder_create_dialog_new (GtkWindow *parent,
+ EMailUISession *session)
+{
+ GtkWidget *dialog;
+ EMFolderTreeModel *model;
+
+ g_return_val_if_fail (E_IS_MAIL_UI_SESSION (session), NULL);
+
+ /* XXX The folder tree model is a construct-only property in
+ * EMFolderSelector, so create an empty model here and then
+ * populate it during instance initialization. Already too
+ * much logic here for a "new" function, but works for now. */
+
+ model = em_folder_tree_model_new ();
+ em_folder_tree_model_set_session (model, E_MAIL_SESSION (session));
+
+ dialog = g_object_new (
+ E_TYPE_MAIL_FOLDER_CREATE_DIALOG,
+ "transient-for", parent,
+ "model", model,
+ "session", session, NULL);
+
+ g_object_unref (model);
+
+ return dialog;
+}
+
+EMailUISession *
+e_mail_folder_create_dialog_get_session (EMailFolderCreateDialog *dialog)
+{
+ g_return_val_if_fail (E_IS_MAIL_FOLDER_CREATE_DIALOG (dialog), NULL);
+
+ return dialog->priv->session;
+}
+
diff --git a/mail/e-mail-folder-create-dialog.h b/mail/e-mail-folder-create-dialog.h
new file mode 100644
index 0000000000..f0db614a98
--- /dev/null
+++ b/mail/e-mail-folder-create-dialog.h
@@ -0,0 +1,76 @@
+/*
+ * e-mail-folder-create-dialog.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.
+ *
+ * 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef E_MAIL_FOLDER_CREATE_DIALOG_H
+#define E_MAIL_FOLDER_CREATE_DIALOG_H
+
+#include <mail/em-folder-selector.h>
+#include <mail/e-mail-ui-session.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_FOLDER_CREATE_DIALOG \
+ (e_mail_folder_create_dialog_get_type ())
+#define E_MAIL_FOLDER_CREATE_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_FOLDER_CREATE_DIALOG, EMailFolderCreateDialog))
+#define E_MAIL_FOLDER_CREATE_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_FOLDER_CREATE_DIALOG, EMailFolderCreateDialogClass))
+#define E_IS_MAIL_FOLDER_CREATE_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_FOLDER_CREATE_DIALOG))
+#define E_IS_MAIL_FOLDER_CREATE_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_FOLDER_CREATE_DIALOG))
+#define E_MAIL_FOLDER_CREATE_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_FOLDER_CREATE_DIALOG, EMailFolderCreateDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailFolderCreateDialog EMailFolderCreateDialog;
+typedef struct _EMailFolderCreateDialogClass EMailFolderCreateDialogClass;
+typedef struct _EMailFolderCreateDialogPrivate EMailFolderCreateDialogPrivate;
+
+struct _EMailFolderCreateDialog {
+ EMFolderSelector parent;
+ EMailFolderCreateDialogPrivate *priv;
+};
+
+struct _EMailFolderCreateDialogClass {
+ EMFolderSelectorClass parent_class;
+
+ /* Signals */
+ void (*folder_created)
+ (EMailFolderCreateDialog *dialog,
+ CamelStore *store,
+ const gchar *folder_name);
+};
+
+GType e_mail_folder_create_dialog_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_folder_create_dialog_new
+ (GtkWindow *parent,
+ EMailUISession *session);
+EMailUISession *
+ e_mail_folder_create_dialog_get_session
+ (EMailFolderCreateDialog *dialog);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FOLDER_CREATE_DIALOG_H */
+
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index fcdd66e007..1a512f707f 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -29,6 +29,7 @@
#include <e-util/e-util.h>
#include <libemail-engine/libemail-engine.h>
+#include "e-mail-folder-create-dialog.h"
#include "em-folder-tree.h"
#include "em-folder-utils.h"
#include "em-utils.h"
@@ -49,7 +50,6 @@ struct _EMFolderSelectorPrivate {
GtkWidget *content_area;
GtkWidget *tree_view_frame;
- GtkEntry *name_entry;
gchar *selected_uri;
gboolean can_create;
@@ -85,28 +85,6 @@ G_DEFINE_TYPE_WITH_CODE (
em_folder_selector_alert_sink_init))
static void
-folder_selector_create_name_changed (GtkEntry *entry,
- EMFolderSelector *selector)
-{
- EMFolderTree *folder_tree;
- gchar *path;
- const gchar *text = NULL;
- gboolean active;
-
- if (gtk_entry_get_text_length (selector->priv->name_entry) > 0)
- text = gtk_entry_get_text (selector->priv->name_entry);
-
- folder_tree = em_folder_selector_get_folder_tree (selector);
-
- path = em_folder_tree_get_selected_uri (folder_tree);
- active = text && path && !strchr (text, '/');
- g_free (path);
-
- gtk_dialog_set_response_sensitive (
- GTK_DIALOG (selector), GTK_RESPONSE_OK, active);
-}
-
-static void
folder_selector_selected_cb (EMFolderTree *emft,
CamelStore *store,
const gchar *folder_name,
@@ -127,26 +105,60 @@ folder_selector_activated_cb (EMFolderTree *emft,
}
static void
+folder_selector_folder_created_cb (EMailFolderCreateDialog *dialog,
+ CamelStore *store,
+ const gchar *folder_name,
+ GWeakRef *folder_tree_weak_ref)
+{
+ EMFolderTree *folder_tree;
+
+ folder_tree = g_weak_ref_get (folder_tree_weak_ref);
+
+ if (folder_tree != NULL) {
+ gchar *folder_uri;
+
+ /* Select the newly created folder. */
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+ em_folder_tree_set_selected (folder_tree, folder_uri, TRUE);
+ g_free (folder_uri);
+
+ g_object_unref (folder_tree);
+ }
+}
+
+static void
folder_selector_action_add_cb (ETreeViewFrame *tree_view_frame,
GtkAction *action,
EMFolderSelector *selector)
{
- EMFolderTree *folder_tree;
+ GtkWidget *new_dialog;
EMailSession *session;
- const gchar *uri;
+ EMFolderTree *folder_tree;
+ const gchar *initial_uri;
folder_tree = em_folder_selector_get_folder_tree (selector);
+ session = em_folder_tree_get_session (folder_tree);
- g_object_set_data (
- G_OBJECT (folder_tree),
- "select", GUINT_TO_POINTER (1));
+ new_dialog = e_mail_folder_create_dialog_new (
+ GTK_WINDOW (selector),
+ E_MAIL_UI_SESSION (session));
- session = em_folder_tree_get_session (folder_tree);
+ gtk_window_set_modal (GTK_WINDOW (new_dialog), TRUE);
+
+ g_signal_connect_data (
+ new_dialog, "folder-created",
+ G_CALLBACK (folder_selector_folder_created_cb),
+ e_weak_ref_new (folder_tree),
+ (GClosureNotify) e_weak_ref_free, 0);
+
+ initial_uri = em_folder_selector_get_selected_uri (selector);
- uri = em_folder_selector_get_selected_uri (selector);
+ folder_tree = em_folder_selector_get_folder_tree (
+ EM_FOLDER_SELECTOR (new_dialog));
- em_folder_utils_create_folder (
- GTK_WINDOW (selector), session, folder_tree, uri);
+ em_folder_tree_set_selected (folder_tree, initial_uri, FALSE);
+
+ gtk_widget_show (new_dialog);
}
static void
@@ -392,14 +404,9 @@ folder_selector_folder_selected (EMFolderSelector *selector,
CamelStore *store,
const gchar *folder_name)
{
- if (selector->priv->name_entry != NULL) {
- folder_selector_create_name_changed (
- selector->priv->name_entry, selector);
- } else {
- gtk_dialog_set_response_sensitive (
- GTK_DIALOG (selector), GTK_RESPONSE_OK,
- (store != NULL) && (folder_name != NULL));
- }
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (selector), GTK_RESPONSE_OK,
+ (store != NULL) && (folder_name != NULL));
}
static void
@@ -531,87 +538,6 @@ em_folder_selector_new (GtkWindow *parent,
"model", model, NULL);
}
-static void
-folder_selector_create_name_activate (GtkEntry *entry,
- EMFolderSelector *selector)
-{
- if (gtk_entry_get_text_length (selector->priv->name_entry) > 0) {
- EMFolderTree *folder_tree;
- gchar *path;
- const gchar *text;
- gboolean emit_response;
-
- text = gtk_entry_get_text (selector->priv->name_entry);
-
- folder_tree = em_folder_selector_get_folder_tree (selector);
- path = em_folder_tree_get_selected_uri (folder_tree);
-
- emit_response =
- (path != NULL) &&
- (text != NULL) &&
- (strchr (text, '/') == NULL);
-
- if (emit_response) {
- g_signal_emit_by_name (
- selector, "response", GTK_RESPONSE_OK);
- }
-
- g_free (path);
- }
-}
-
-GtkWidget *
-em_folder_selector_create_new (GtkWindow *parent,
- EMFolderTreeModel *model)
-{
- EMFolderSelector *selector;
- EMFolderTree *folder_tree;
- GtkWidget *container;
- GtkWidget *widget;
- GtkLabel *label;
-
- g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
-
- selector = g_object_new (
- EM_TYPE_FOLDER_SELECTOR,
- "transient-for", parent,
- "model", model,
- "default-button-label", _("C_reate"), NULL);
-
- folder_tree = em_folder_selector_get_folder_tree (selector);
- em_folder_tree_set_excluded (folder_tree, EMFT_EXCLUDE_NOINFERIORS);
-
- container = selector->priv->content_area;
-
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
- gtk_widget_show (widget);
-
- container = widget;
-
- widget = gtk_label_new_with_mnemonic (_("Folder _name:"));
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- gtk_widget_show (widget);
-
- label = GTK_LABEL (widget);
-
- widget = gtk_entry_new ();
- gtk_label_set_mnemonic_widget (label, widget);
- gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
- selector->priv->name_entry = GTK_ENTRY (widget);
- gtk_widget_grab_focus (widget);
- gtk_widget_show (widget);
-
- g_signal_connect (
- widget, "changed",
- G_CALLBACK (folder_selector_create_name_changed), selector);
- g_signal_connect (
- widget, "activate",
- G_CALLBACK (folder_selector_create_name_activate), selector);
-
- return GTK_WIDGET (selector);
-}
-
/**
* em_folder_selector_get_can_create:
* @selector: an #EMFolderSelector
@@ -871,19 +797,6 @@ em_folder_selector_get_selected_uri (EMFolderSelector *selector)
if (uri == NULL)
return NULL;
- if (selector->priv->name_entry != NULL) {
- const gchar *name;
- gchar *temp_uri, *escaped_name;
-
- name = gtk_entry_get_text (selector->priv->name_entry);
- escaped_name = g_uri_escape_string (name, NULL, TRUE);
- temp_uri = g_strconcat (uri, "/", escaped_name, NULL);
-
- g_free (escaped_name);
- g_free (uri);
- uri = temp_uri;
- }
-
g_free (selector->priv->selected_uri);
selector->priv->selected_uri = uri; /* takes ownership */
diff --git a/mail/em-folder-selector.h b/mail/em-folder-selector.h
index bb093be8e9..8093d71d9a 100644
--- a/mail/em-folder-selector.h
+++ b/mail/em-folder-selector.h
@@ -68,8 +68,6 @@ struct _EMFolderSelectorClass {
GType em_folder_selector_get_type (void);
GtkWidget * em_folder_selector_new (GtkWindow *parent,
EMFolderTreeModel *model);
-GtkWidget * em_folder_selector_create_new (GtkWindow *parent,
- EMFolderTreeModel *model);
gboolean em_folder_selector_get_can_create
(EMFolderSelector *selector);
void em_folder_selector_set_can_create
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index b3d754369d..479d8783f6 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -51,24 +51,6 @@
#define d(x)
-typedef struct _AsyncContext AsyncContext;
-
-struct _AsyncContext {
- EMFolderTree *folder_tree;
- gchar *folder_uri;
-};
-
-static void
-async_context_free (AsyncContext *context)
-{
- if (context->folder_tree != NULL)
- g_object_unref (context->folder_tree);
-
- g_free (context->folder_uri);
-
- g_slice_free (AsyncContext, context);
-}
-
static gboolean
emfu_is_special_local_folder (const gchar *name)
{
@@ -530,152 +512,6 @@ em_folder_utils_copy_folder (GtkWindow *parent,
gtk_widget_destroy (dialog);
}
-static void
-new_folder_created_cb (CamelStore *store,
- GAsyncResult *result,
- AsyncContext *context)
-{
- GError *error = NULL;
-
- e_mail_store_create_folder_finish (store, result, &error);
-
- /* FIXME Use an EActivity here. */
- if (error != NULL) {
- e_notice (NULL, GTK_MESSAGE_ERROR, "%s", error->message);
- g_error_free (error);
-
- } else if (context->folder_tree != NULL) {
- gpointer data;
- gboolean expand_only;
-
- /* XXX What in the hell kind of lazy hack is this? */
- data = g_object_get_data (
- G_OBJECT (context->folder_tree), "select");
- expand_only = GPOINTER_TO_INT (data) ? FALSE : TRUE;
-
- em_folder_tree_set_selected (
- context->folder_tree,
- context->folder_uri, expand_only);
- }
-
- async_context_free (context);
-}
-
-void
-em_folder_utils_create_folder (GtkWindow *parent,
- EMailSession *session,
- EMFolderTree *emft,
- const gchar *initial_uri)
-{
- EMFolderSelector *selector;
- EMFolderTree *folder_tree;
- EMFolderTreeModel *model;
- EMailAccountStore *account_store;
- CamelStore *store = NULL;
- GtkWidget *dialog;
- GQueue queue = G_QUEUE_INIT;
- const gchar *caption;
- const gchar *folder_uri;
- gchar *folder_name = NULL;
- GError *error = NULL;
-
- g_return_if_fail (GTK_IS_WINDOW (parent));
- g_return_if_fail (E_IS_MAIL_SESSION (session));
-
- model = em_folder_tree_model_new ();
- em_folder_tree_model_set_session (model, session);
-
- account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session));
- e_mail_account_store_queue_enabled_services (account_store, &queue);
-
- while (!g_queue_is_empty (&queue)) {
- CamelService *service;
- CamelStoreFlags flags;
-
- service = g_queue_pop_head (&queue);
- g_warn_if_fail (CAMEL_IS_STORE (service));
-
- flags = CAMEL_STORE (service)->flags;
- if ((flags & CAMEL_STORE_CAN_EDIT_FOLDERS) == 0)
- continue;
-
- em_folder_tree_model_add_store (model, CAMEL_STORE (service));
- }
-
- dialog = em_folder_selector_create_new (parent, model);
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Create Folder"));
-
- g_object_unref (model);
-
- selector = EM_FOLDER_SELECTOR (dialog);
-
- caption = _("Specify where to create the folder:");
- em_folder_selector_set_caption (selector, caption);
-
- folder_tree = em_folder_selector_get_folder_tree (selector);
-
- if (initial_uri != NULL)
- em_folder_tree_set_selected (folder_tree, initial_uri, FALSE);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
- goto exit;
-
- folder_uri = em_folder_selector_get_selected_uri (selector);
- g_return_if_fail (folder_uri != NULL);
-
- e_mail_folder_uri_parse (
- CAMEL_SESSION (session), folder_uri,
- &store, &folder_name, &error);
-
- /* XXX This is unlikely to fail since the URI comes straight from
- * EMFolderSelector, but leave a breadcrumb if it does fail. */
- if (error != NULL) {
- g_warn_if_fail (store == NULL);
- g_warn_if_fail (folder_name == NULL);
- e_notice (parent, GTK_MESSAGE_ERROR, "%s", error->message);
- g_error_free (error);
- goto exit;
- }
-
- g_return_if_fail (folder_name != NULL);
-
- /* HACK: we need to create vfolders using the vfolder editor */
- if (CAMEL_IS_VEE_STORE (store)) {
- EFilterRule *rule;
- const gchar *skip_slash;
-
- if (*folder_name == '/')
- skip_slash = folder_name + 1;
- else
- skip_slash = folder_name;
-
- rule = em_vfolder_editor_rule_new (session);
- e_filter_rule_set_name (rule, skip_slash);
- vfolder_gui_add_rule (EM_VFOLDER_RULE (rule));
- } else {
- AsyncContext *context;
-
- context = g_slice_new0 (AsyncContext);
- context->folder_uri = e_mail_folder_uri_build (store, folder_name);
-
- if (EM_IS_FOLDER_TREE (emft))
- context->folder_tree = g_object_ref (emft);
-
- /* FIXME Not passing a GCancellable. */
- e_mail_store_create_folder (
- store, folder_name, G_PRIORITY_DEFAULT, NULL,
- (GAsyncReadyCallback) new_folder_created_cb,
- context);
- }
-
- g_free (folder_name);
- g_object_unref (store);
-
-exit:
- gtk_widget_destroy (dialog);
-}
-
const gchar *
em_folder_utils_get_icon_name (guint32 flags)
{
diff --git a/mail/em-folder-utils.h b/mail/em-folder-utils.h
index 3d034ac928..7b9f66664c 100644
--- a/mail/em-folder-utils.h
+++ b/mail/em-folder-utils.h
@@ -44,10 +44,6 @@ void em_folder_utils_copy_folder (GtkWindow *parent,
EAlertSink *alert_sink,
const gchar *folder_uri,
gboolean delete);
-void em_folder_utils_create_folder (GtkWindow *parent,
- EMailSession *session,
- EMFolderTree *emft,
- const gchar *initial_uri);
const gchar * em_folder_utils_get_icon_name (guint32 flags);
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index b8afd2c2d3..e74086f204 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -34,9 +34,9 @@
#include <mail/e-mail-browser.h>
#include <mail/e-mail-config-assistant.h>
#include <mail/e-mail-config-window.h>
+#include <mail/e-mail-folder-create-dialog.h>
#include <mail/e-mail-reader.h>
#include <mail/em-composer-utils.h>
-#include <mail/em-folder-utils.h>
#include <mail/em-utils.h>
#include <mail/mail-send-recv.h>
#include <mail/mail-vfolder-ui.h>
@@ -194,6 +194,28 @@ mail_shell_backend_mail_icon_cb (EShellWindow *shell_window,
}
static void
+mail_shell_backend_folder_created_cb (EMailFolderCreateDialog *dialog,
+ CamelStore *store,
+ const gchar *folder_name,
+ GWeakRef *folder_tree_weak_ref)
+{
+ EMFolderTree *folder_tree;
+
+ folder_tree = g_weak_ref_get (folder_tree_weak_ref);
+
+ if (folder_tree != NULL) {
+ gchar *folder_uri;
+
+ /* Select the newly created folder. */
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+ em_folder_tree_set_selected (folder_tree, folder_uri, FALSE);
+ g_free (folder_uri);
+
+ g_object_unref (folder_tree);
+ }
+}
+
+static void
action_mail_folder_new_cb (GtkAction *action,
EShellWindow *shell_window)
{
@@ -202,6 +224,7 @@ action_mail_folder_new_cb (GtkAction *action,
EMailSession *session;
EShellSidebar *shell_sidebar;
EShellView *shell_view;
+ GtkWidget *dialog;
const gchar *view_name;
/* Take care not to unnecessarily load the mail shell view. */
@@ -231,8 +254,19 @@ action_mail_folder_new_cb (GtkAction *action,
session = em_folder_tree_get_session (folder_tree);
exit:
- em_folder_utils_create_folder (
- GTK_WINDOW (shell_window), session, folder_tree, NULL);
+ dialog = e_mail_folder_create_dialog_new (
+ GTK_WINDOW (shell_window),
+ E_MAIL_UI_SESSION (session));
+
+ if (folder_tree != NULL) {
+ g_signal_connect_data (
+ dialog, "folder-created",
+ G_CALLBACK (mail_shell_backend_folder_created_cb),
+ e_weak_ref_new (folder_tree),
+ (GClosureNotify) e_weak_ref_free, 0);
+ }
+
+ gtk_widget_show (GTK_WIDGET (dialog));
}
static void
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index a93191cf7c..76159950a5 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -25,6 +25,28 @@
#include "e-mail-shell-view-private.h"
static void
+mail_shell_view_folder_created_cb (EMailFolderCreateDialog *dialog,
+ CamelStore *store,
+ const gchar *folder_name,
+ GWeakRef *folder_tree_weak_ref)
+{
+ EMFolderTree *folder_tree;
+
+ folder_tree = g_weak_ref_get (folder_tree_weak_ref);
+
+ if (folder_tree != NULL) {
+ gchar *folder_uri;
+
+ /* Select the newly created folder. */
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+ em_folder_tree_set_selected (folder_tree, folder_uri, FALSE);
+ g_free (folder_uri);
+
+ g_object_unref (folder_tree);
+ }
+}
+
+static void
action_mail_account_disable_cb (GtkAction *action,
EMailShellView *mail_shell_view)
{
@@ -775,7 +797,9 @@ action_mail_folder_new_cb (GtkAction *action,
EMailSession *session;
EMailShellSidebar *mail_shell_sidebar;
EMFolderTree *folder_tree;
- gchar *selected_uri;
+ GtkWidget *dialog;
+ CamelStore *store = NULL;
+ gchar *folder_name = NULL;
shell_view = E_SHELL_VIEW (mail_shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
@@ -784,13 +808,25 @@ action_mail_folder_new_cb (GtkAction *action,
folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
session = em_folder_tree_get_session (folder_tree);
- selected_uri = em_folder_tree_get_selected_uri (folder_tree);
- em_folder_utils_create_folder (
+ dialog = e_mail_folder_create_dialog_new (
GTK_WINDOW (shell_window),
- session, folder_tree, selected_uri);
+ E_MAIL_UI_SESSION (session));
- g_free (selected_uri);
+ g_signal_connect_data (
+ dialog, "folder-created",
+ G_CALLBACK (mail_shell_view_folder_created_cb),
+ e_weak_ref_new (folder_tree),
+ (GClosureNotify) e_weak_ref_free, 0);
+
+ if (em_folder_tree_get_selected (folder_tree, &store, &folder_name)) {
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog), store, folder_name);
+ g_object_unref (store);
+ g_free (folder_name);
+ }
+
+ gtk_widget_show (GTK_WIDGET (dialog));
}
static void
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
index 377ebd8025..2925f4e63c 100644
--- a/modules/mail/e-mail-shell-view-private.h
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -27,6 +27,7 @@
#include <gtkhtml/gtkhtml.h>
#include <camel/camel-search-private.h> /* for camel_search_word */
+#include <mail/e-mail-folder-create-dialog.h>
#include <mail/e-mail-label-action.h>
#include <mail/e-mail-label-dialog.h>
#include <mail/e-mail-label-list-store.h>