[evolution] Add EMailFolderCreateDialog.



commit 5ebf0fd3c3ff08fc34fb1157ac54c818661bf2a1
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Mar 24 09:26:24 2014 -0400

    Add EMailFolderCreateDialog.
    
    Subclass of EMFolderSelector, replaces em_folder_utils_create_folder().

 mail/Makefile.am                         |    2 +
 mail/e-mail-folder-create-dialog.c       |  498 ++++++++++++++++++++++++++++++
 mail/e-mail-folder-create-dialog.h       |   76 +++++
 mail/em-folder-selector.c                |  181 +++--------
 mail/em-folder-selector.h                |    2 -
 mail/em-folder-utils.c                   |  164 ----------
 mail/em-folder-utils.h                   |    4 -
 modules/mail/e-mail-shell-backend.c      |   40 +++-
 modules/mail/e-mail-shell-view-actions.c |   46 +++-
 modules/mail/e-mail-shell-view-private.h |    1 +
 10 files changed, 702 insertions(+), 312 deletions(-)
---
diff --git a/mail/Makefile.am b/mail/Makefile.am
index e5cc9da..d40922e 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 0000000..bca14de
--- /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 0000000..f0db614
--- /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 fcdd66e..1a512f7 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 bb093be..8093d71 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 b3d7543..479d878 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 3d034ac..7b9f666 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 b8afd2c..e74086f 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 a93191c..7615995 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 377ebd8..2925f4e 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>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]