* Added Progress Object
authorSergio Villar Senin <svillar@igalia.com>
Mon, 2 Apr 2007 08:29:13 +0000 (08:29 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Mon, 2 Apr 2007 08:29:13 +0000 (08:29 +0000)
* Added Gnome info bar
* Ported mail operation calls to the new design
* Removed non-common code from UI actions

pmo-trunk-r1470

19 files changed:
src/Makefile.am
src/gnome/Makefile.am
src/gnome/modest-gnome-info-bar.c [new file with mode: 0644]
src/gnome/modest-gnome-info-bar.h [new file with mode: 0644]
src/gnome/modest-main-window-ui.h
src/gnome/modest-main-window.c
src/modest-mail-operation-queue.c
src/modest-mail-operation-queue.h
src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-marshal.list
src/modest-progress-object.c [new file with mode: 0644]
src/modest-progress-object.h [new file with mode: 0644]
src/modest-ui-actions.c
src/modest-ui-actions.h
src/widgets/Makefile.am
src/widgets/modest-folder-view.c
src/widgets/modest-header-view.c
src/widgets/modest-main-window.h

index 5ead243..2b7a7bc 100644 (file)
@@ -56,6 +56,8 @@ modest_SOURCES=\
        modest-pair.c\
        modest-pair.h\
        modest-platform.h\
+       modest-progress-object.c\
+       modest-progress-object.h\
        modest-protocol-info.c\
        modest-protocol-info.h\
        modest-runtime.c\
index a951862..70c9d0b 100644 (file)
@@ -27,13 +27,16 @@ libmodest_ui_la_SOURCES=              \
        modest-account-assistant.c    \
        modest-account-assistant.h    \
        modest-account-view-window.c  \
-       modest-address-book.c          \
+       modest-address-book.c         \
        modest-msg-edit-window.c      \
        modest-icon-names.h           \
+       modest-gnome-info-bar.c       \
+       modest-gnome-info-bar.h       \
        modest-main-window.c          \
        modest-main-window-ui.h       \
        modest-msg-view-window.c      \
        modest-platform.c             \
+       modest-platform.c             \
        modest-store-widget.c         \
        modest-store-widget.h         \
        modest-transport-widget.c     \
diff --git a/src/gnome/modest-gnome-info-bar.c b/src/gnome/modest-gnome-info-bar.c
new file mode 100644 (file)
index 0000000..bb16282
--- /dev/null
@@ -0,0 +1,322 @@
+/* modest-gnome-bar.c */
+
+/* insert (c)/licensing information) */
+
+#include "modest-gnome-info-bar.h"
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtkstatusbar.h>
+/* include other impl specific header files */
+
+/* 'private'/'protected' functions */
+static void modest_gnome_info_bar_class_init (ModestGnomeInfoBarClass *klass);
+static void modest_gnome_info_bar_init       (ModestGnomeInfoBar *obj);
+static void modest_gnome_info_bar_finalize   (GObject *obj);
+
+static void modest_gnome_info_bar_add_operation    (ModestProgressObject *self,
+                                                   ModestMailOperation  *mail_op);
+
+static void modest_gnome_info_bar_remove_operation (ModestProgressObject *self,
+                                                   ModestMailOperation  *mail_op);
+
+static void on_progress_changed                    (ModestMailOperation  *mail_op, 
+                                                   ModestGnomeInfoBar *self);
+
+static gboolean     progressbar_clean        (GtkProgressBar *bar);
+static gboolean     statusbar_clean          (GtkStatusbar *bar);
+
+/* list my signals  */
+enum {
+       /* MY_SIGNAL_1, */
+       /* MY_SIGNAL_2, */
+       LAST_SIGNAL
+};
+
+typedef struct _ObservableData ObservableData;
+struct _ObservableData {
+        guint signal_handler;
+        ModestMailOperation *mail_op;
+};
+
+typedef struct _ModestGnomeInfoBarPrivate ModestGnomeInfoBarPrivate;
+struct _ModestGnomeInfoBarPrivate {
+        GSList              *observables;
+        ModestMailOperation *current;
+
+       GtkWidget *status_bar;
+       GtkWidget *progress_bar;
+
+       guint status_bar_timeout;
+       guint progress_bar_timeout;
+};
+
+#define MODEST_GNOME_INFO_BAR_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+                                              MODEST_TYPE_GNOME_INFO_BAR, \
+                                              ModestGnomeInfoBarPrivate))
+/* globals */
+static GtkHBoxClass *parent_class = NULL;
+
+/* uncomment the following if you have defined any signals */
+/* static guint signals[LAST_SIGNAL] = {0}; */
+
+static void
+modest_progress_object_init (gpointer g, gpointer iface_data)
+{
+       ModestProgressObjectIface *klass = (ModestProgressObjectIface *)g;
+
+       klass->add_operation_func = modest_gnome_info_bar_add_operation;
+       klass->remove_operation_func = modest_gnome_info_bar_remove_operation;
+}
+
+GType
+modest_gnome_info_bar_get_type (void)
+{
+       static GType my_type = 0;
+       if (!my_type) {
+               static const GTypeInfo my_info = {
+                       sizeof(ModestGnomeInfoBarClass),
+                       NULL,           /* base init */
+                       NULL,           /* base finalize */
+                       (GClassInitFunc) modest_gnome_info_bar_class_init,
+                       NULL,           /* class finalize */
+                       NULL,           /* class data */
+                       sizeof(ModestGnomeInfoBar),
+                       1,              /* n_preallocs */
+                       (GInstanceInitFunc) modest_gnome_info_bar_init,
+                       NULL
+               };
+
+               static const GInterfaceInfo modest_progress_object_info = 
+               {
+                 (GInterfaceInitFunc) modest_progress_object_init, /* interface_init */
+                 NULL,         /* interface_finalize */
+                 NULL          /* interface_data */
+               };
+
+               my_type = g_type_register_static (GTK_TYPE_HBOX,
+                                                 "ModestGnomeInfoBar",
+                                                 &my_info, 0);
+
+               g_type_add_interface_static (my_type, MODEST_TYPE_PROGRESS_OBJECT, 
+                                            &modest_progress_object_info);
+       }
+       return my_type;
+}
+
+static void
+modest_gnome_info_bar_class_init (ModestGnomeInfoBarClass *klass)
+{
+       GObjectClass *gobject_class;
+       gobject_class = (GObjectClass*) klass;
+
+       parent_class            = g_type_class_peek_parent (klass);
+       gobject_class->finalize = modest_gnome_info_bar_finalize;
+
+       g_type_class_add_private (gobject_class, sizeof(ModestGnomeInfoBarPrivate));
+}
+
+static void
+modest_gnome_info_bar_init (ModestGnomeInfoBar *obj)
+{
+       ModestGnomeInfoBarPrivate *priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE(obj);
+
+       priv->observables = NULL;
+       priv->current = NULL;
+
+       /* Status bar */
+       priv->status_bar = gtk_statusbar_new ();
+        gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (priv->status_bar), FALSE);
+
+       /* Progress bar */
+       priv->progress_bar = gtk_progress_bar_new ();
+       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress_bar), 1.0);
+       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (priv->progress_bar),
+                                       PANGO_ELLIPSIZE_END);
+
+       /* Timeouts */
+       priv->status_bar_timeout = 0;
+       priv->progress_bar_timeout = 0;
+
+       /* Pack */
+       gtk_box_pack_start (GTK_BOX (obj), priv->status_bar, TRUE, TRUE, 0);
+       gtk_box_pack_start (GTK_BOX (obj), priv->progress_bar, FALSE, FALSE, 0);
+}
+
+static void
+destroy_observable_data (ObservableData *data)
+{
+       g_signal_handler_disconnect (data->mail_op, data->signal_handler);
+       g_object_unref (data->mail_op);
+}
+
+static void
+modest_gnome_info_bar_finalize (GObject *obj)
+{
+       ModestGnomeInfoBarPrivate *priv;
+
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE(obj);
+       if (priv->observables) {
+               GSList *tmp;
+
+               for (tmp = priv->observables; tmp; tmp = g_slist_next (tmp)) {
+                       destroy_observable_data ((ObservableData *) tmp->data);
+                       g_free (tmp->data);
+               }
+               g_slist_free (priv->observables);
+               priv->observables = NULL;
+       }
+
+       if (priv->status_bar_timeout > 0) {
+               g_source_remove (priv->status_bar_timeout);
+               priv->status_bar_timeout = 0;
+       }
+
+       if (priv->progress_bar_timeout > 0) {
+               g_source_remove (priv->progress_bar_timeout);
+               priv->progress_bar_timeout = 0;
+       }
+
+       G_OBJECT_CLASS(parent_class)->finalize (obj);
+}
+
+GtkWidget *
+modest_gnome_info_bar_new (void)
+{
+       return GTK_WIDGET (g_object_new (MODEST_TYPE_GNOME_INFO_BAR, NULL));
+}
+
+static void 
+modest_gnome_info_bar_add_operation (ModestProgressObject *self,
+                                    ModestMailOperation  *mail_op)
+{
+       ModestGnomeInfoBar *me;
+       ObservableData *data;
+       ModestGnomeInfoBarPrivate *priv;
+
+       me = MODEST_GNOME_INFO_BAR (self);
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (me);
+
+       data = g_malloc0 (sizeof (ObservableData));
+       data->mail_op = g_object_ref (mail_op);
+       data->signal_handler = g_signal_connect (data->mail_op, 
+                                                "progress-changed",
+                                                G_CALLBACK (on_progress_changed),
+                                                me);
+
+       if (priv->observables == NULL) {
+               priv->current = mail_op;
+       }
+       priv->observables = g_slist_append (priv->observables, data);
+}
+
+static gint
+compare_observable_data (ObservableData *data1, ObservableData *data2)
+{
+       if (data1->mail_op == data2->mail_op)
+               return 0;
+       else 
+               return 1;
+}
+
+static void 
+modest_gnome_info_bar_remove_operation (ModestProgressObject *self,
+                                       ModestMailOperation  *mail_op)
+{
+       ModestGnomeInfoBar *me;
+       ModestGnomeInfoBarPrivate *priv;
+       GSList *link;
+
+       me = MODEST_GNOME_INFO_BAR (self);
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (me);
+
+       link = g_slist_find_custom (priv->observables,
+                                   mail_op,
+                                   (GCompareFunc) compare_observable_data);
+
+       /* Remove the item */
+       if (link) {
+               priv->observables = g_slist_remove_link (priv->observables, link);
+               destroy_observable_data ((ObservableData *) link->data);
+       }
+
+       /* Update the current mail operation */
+       if (priv->current == mail_op) {
+               if (priv->observables)
+                       priv->current = ((ObservableData *) priv->observables->data)->mail_op;
+               else
+                       priv->current = NULL;
+
+               /* Refresh the view */
+               progressbar_clean (GTK_PROGRESS_BAR (priv->progress_bar));
+       }
+}
+
+static void 
+on_progress_changed (ModestMailOperation  *mail_op, 
+                    ModestGnomeInfoBar *self)
+{
+       ModestGnomeInfoBarPrivate *priv;
+
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
+
+       /* If the mail operation is the currently shown one */
+       if (priv->current == mail_op) {
+               gchar *msg = NULL;
+
+               msg = g_strdup_printf ("Mail operation %d of %d",
+                                      modest_mail_operation_get_task_done (mail_op),
+                                      modest_mail_operation_get_task_total (mail_op));
+               modest_gnome_info_bar_set_message (self, msg);
+               g_free (msg);
+       }
+}
+
+static gboolean
+progressbar_clean (GtkProgressBar *bar)
+{
+       gtk_progress_bar_set_fraction (bar, 0);
+       gtk_progress_bar_set_text (bar, 0);
+       return FALSE;
+}
+
+static gboolean
+statusbar_clean (GtkStatusbar *bar)
+{
+       gtk_statusbar_push (bar, 0, "");
+       return FALSE;
+}
+
+void 
+modest_gnome_info_bar_set_message    (ModestGnomeInfoBar *self,
+                                     const gchar *message)
+{
+       ModestGnomeInfoBarPrivate *priv;
+
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
+
+       /* Set a message. Clean it after 2.5 seconds */
+       gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar), 0, message);
+       priv->status_bar_timeout = g_timeout_add (2500, 
+                                                 (GSourceFunc) statusbar_clean, 
+                                                 priv->status_bar);
+}
+
+void 
+modest_gnome_info_bar_set_progress   (ModestGnomeInfoBar *self,
+                                     const gchar *message,
+                                     gint done,
+                                     gint total)
+{
+       ModestGnomeInfoBarPrivate *priv;
+
+       priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
+
+       /* Set progress */
+       if (total != 0)
+               gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress_bar),
+                                              (gdouble)done/(gdouble)total);
+       else
+               gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progress_bar));
+
+       /* Set text */
+       gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progress_bar), message);
+}
diff --git a/src/gnome/modest-gnome-info-bar.h b/src/gnome/modest-gnome-info-bar.h
new file mode 100644 (file)
index 0000000..bee3024
--- /dev/null
@@ -0,0 +1,69 @@
+/* modest-gnome-bar.h */
+/* insert (c)/licensing information) */
+
+#ifndef __MODEST_GNOME_INFO_BAR_H__
+#define __MODEST_GNOME_INFO_BAR_H__
+
+#include <gtk/gtkhbox.h>
+#include "modest-progress-object.h"
+/* other include files */
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_GNOME_INFO_BAR             (modest_gnome_info_bar_get_type())
+#define MODEST_GNOME_INFO_BAR(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_GNOME_INFO_BAR,ModestGnomeInfoBar))
+#define MODEST_GNOME_INFO_BAR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_GNOME_INFO_BAR,ModestProgressObject))
+#define MODEST_IS_GNOME_INFO_BAR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_GNOME_INFO_BAR))
+#define MODEST_IS_GNOME_INFO_BAR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_GNOME_INFO_BAR))
+#define MODEST_GNOME_INFO_BAR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_GNOME_INFO_BAR,ModestGnomeInfoBarClass))
+
+typedef struct _ModestGnomeInfoBar      ModestGnomeInfoBar;
+typedef struct _ModestGnomeInfoBarClass ModestGnomeInfoBarClass;
+
+struct _ModestGnomeInfoBar {
+        GtkHBox parent;
+};
+
+struct _ModestGnomeInfoBarClass {
+       GtkHBoxClass parent_class;
+};
+
+/* member functions */
+GType         modest_gnome_info_bar_get_type       (void) G_GNUC_CONST;
+
+/* typical parameter-less _new function */
+GtkWidget*    modest_gnome_info_bar_new            (void);
+
+/**
+ * modest_gnome_info_bar_new:
+ * @void: 
+ * 
+ * Sets a text in the status bar of the widget
+ * 
+ * Return value: 
+ **/
+void          modest_gnome_info_bar_set_message    (ModestGnomeInfoBar *self,
+                                                   const gchar *message);
+
+
+/**
+ * modest_gnome_info_bar_set_progress:
+ * @self: 
+ * @message: 
+ * @done: 
+ * @total: 
+ * 
+ * Causes the progress bar of the widget to fill in the amount of work
+ * done of a given total. If message is supplied then it'll be
+ * superimposed on the progress bar
+ **/
+void          modest_gnome_info_bar_set_progress   (ModestGnomeInfoBar *self,
+                                                   const gchar *message,
+                                                   gint done,
+                                                   gint total);
+
+G_END_DECLS
+
+#endif /* __MODEST_GNOME_INFO_BAR_H__ */
+
index ce2f341..61a51ea 100644 (file)
@@ -72,7 +72,7 @@ static const GtkActionEntry modest_action_entries [] = {
        { "ActionsReplyAll",    MODEST_STOCK_REPLY_ALL, N_("Reply to all"),   NULL, N_("Reply to all"), G_CALLBACK (modest_ui_actions_on_reply_all) },
        { "ActionsForward",     MODEST_STOCK_FORWARD, N_("_Forward"),       NULL, N_("Forward a message"), G_CALLBACK (modest_ui_actions_on_forward) },
        { "ActionsBounce",      NULL, N_("_Bounce"),        NULL, N_("Bounce a message"),          NULL },
-       { "ActionsSendReceive", GTK_STOCK_REFRESH, N_("Send/Receive"),   NULL, N_("Send and receive messages"), NULL },
+       { "ActionsSendReceive", GTK_STOCK_REFRESH, N_("Send/Receive"),   NULL, N_("Send and receive messages"), G_CALLBACK (modest_ui_actions_on_send_receive) },
        { "ActionsDelete",      GTK_STOCK_DELETE, N_("Delete message"), NULL, N_("Delete messages"), G_CALLBACK (modest_ui_actions_on_delete) },
        { "ActionsFolderNew",   NULL, N_("New Folder"),   NULL, N_("Create a new folder"), G_CALLBACK (modest_ui_actions_on_new_folder) },
        { "ActionsFolderDelete",   NULL, N_("Delete Folder"),   NULL, N_("Delete the folder"), G_CALLBACK (modest_ui_actions_on_delete_folder) },
index b8cc009..fde4d4c 100644 (file)
@@ -45,6 +45,7 @@
 #include <modest-tny-msg.h>
 #include "modest-mail-operation.h"
 #include "modest-icon-names.h"
+#include "modest-gnome-info-bar.h"
 
 /* 'private'/'protected' functions */
 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
@@ -69,6 +70,16 @@ static gboolean     show_context_popup_menu             (ModestMainWindow *windo
 
 static void         connect_signals                      (ModestMainWindow *self);
 
+static void         on_queue_changed                     (ModestMailOperationQueue *queue,
+                                                         ModestMailOperation *mail_op,
+                                                         ModestMailOperationQueueNotification type,
+                                                         ModestMainWindow *self);
+
+static void         on_header_status_update              (ModestHeaderView *header_view, 
+                                                         const gchar *msg, 
+                                                         gint num, 
+                                                         gint total,  
+                                                         ModestMainWindow *main_window);
 
 /* list my signals */
 enum {
@@ -80,12 +91,12 @@ enum {
 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
 struct _ModestMainWindowPrivate {
 
-       GtkWidget *folder_paned;
-       GtkWidget *msg_paned;
-       GtkWidget *main_paned;
+       GtkWidget        *folder_paned;
+       GtkWidget        *msg_paned;
+       GtkWidget        *main_paned;
        
-       GtkWidget *online_toggle;
-       GtkWidget *folder_info_label;
+       GtkWidget        *online_toggle;
+       GtkWidget        *folder_info_label;
 
        ModestHeaderView *header_view;
        ModestFolderView *folder_view;
@@ -94,6 +105,8 @@ struct _ModestMainWindowPrivate {
        GtkWidget        *status_bar;
        GtkWidget        *progress_bar;
 
+       GSList           *progress_widgets;
+       GtkWidget        *main_bar;
 };
 
 
@@ -166,10 +179,11 @@ modest_main_window_init (ModestMainWindow *obj)
        priv->folder_paned = NULL;
        priv->msg_paned    = NULL;
        priv->main_paned   = NULL;      
+       priv->progress_widgets = NULL;
 
        account_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
 
-       /* online/offline combo */
+       /* online/offline toggle */
        priv->online_toggle = gtk_toggle_button_new ();
        online  = tny_device_is_online (modest_runtime_get_device());
        icon    = gtk_image_new_from_icon_name (online ? GTK_STOCK_CONNECT : GTK_STOCK_DISCONNECT,
@@ -177,20 +191,16 @@ modest_main_window_init (ModestMainWindow *obj)
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->online_toggle), online);
        gtk_button_set_image (GTK_BUTTON(priv->online_toggle),icon);
 
-       /* label with number of items, unread items for 
-          the current folder */
-       priv->folder_info_label = gtk_label_new (NULL);
-
-       /* status bar */
-       priv->status_bar   = gtk_statusbar_new ();
-        gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(priv->status_bar),
-                                           FALSE);
+       /* Paned */
+       priv->folder_paned = gtk_vpaned_new ();
+       priv->main_paned = gtk_hpaned_new ();
+       priv->msg_paned = gtk_vpaned_new ();
 
-       /* progress bar */
-       priv->progress_bar = gtk_progress_bar_new ();
-       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(priv->progress_bar), 1.0);
-       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(priv->progress_bar),
-                                       PANGO_ELLIPSIZE_END);
+       /* Main bar */
+       priv->folder_info_label = gtk_label_new (NULL);
+       priv->main_bar = modest_gnome_info_bar_new ();
+       priv->progress_widgets = g_slist_prepend (priv->progress_widgets, 
+                                                         priv->main_bar);
 
        /* msg preview */
        priv->msg_preview = MODEST_MSG_VIEW(modest_msg_view_new (NULL));
@@ -241,10 +251,6 @@ modest_main_window_get_child_widget (ModestMainWindow *self,
                widget = (GtkWidget*)priv->folder_view; break;
        case MODEST_WIDGET_TYPE_MSG_PREVIEW:
                widget = (GtkWidget*)priv->msg_preview; break;
-       case MODEST_WIDGET_TYPE_STATUS_BAR:
-               widget = (GtkWidget*)priv->status_bar; break;
-       case MODEST_WIDGET_TYPE_PROGRESS_BAR:
-               widget = (GtkWidget*)priv->progress_bar; break;
        default:
                g_return_val_if_reached (NULL);
                return NULL;
@@ -391,7 +397,7 @@ connect_signals (ModestMainWindow *self)
 
        /* header view */
        g_signal_connect (G_OBJECT(priv->header_view), "status_update",
-                         G_CALLBACK(modest_ui_actions_on_header_status_update), self);
+                         G_CALLBACK(on_header_status_update), self);
        g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
                          G_CALLBACK(modest_ui_actions_on_header_selected), self);
        g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
@@ -422,6 +428,12 @@ connect_signals (ModestMainWindow *self)
                          G_CALLBACK(on_connection_changed), self);
        g_signal_connect (G_OBJECT(priv->online_toggle), "toggled",
                          G_CALLBACK(on_online_toggle_toggled), self);
+
+       /* Mail Operation Queue */
+       g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
+                         "queue-changed",
+                         G_CALLBACK (on_queue_changed),
+                         self);
        
        /* window */
        g_signal_connect (G_OBJECT(self), "destroy", G_CALLBACK(on_destroy), NULL);
@@ -474,7 +486,6 @@ modest_main_window_new (void)
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
        
-       /* ***************** */
        parent_priv->ui_manager = gtk_ui_manager_new();
        action_group = gtk_action_group_new ("ModestMainWindowActions");
        
@@ -495,7 +506,6 @@ modest_main_window_new (void)
                g_error_free (error);
                error = NULL;
        }
-       /* *************** */
 
        /* Add accelerators */
        gtk_window_add_accel_group (GTK_WINDOW (obj), 
@@ -505,29 +515,25 @@ modest_main_window_new (void)
        parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
        parent_priv->menubar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar");
 
-       gtk_toolbar_set_tooltips (GTK_TOOLBAR (parent_priv->toolbar), TRUE);    
+       gtk_toolbar_set_tooltips (GTK_TOOLBAR (parent_priv->toolbar), TRUE);
        folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view), FALSE);
-       header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view), FALSE);                    
+       header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view), FALSE);
 
-       /* paned */
-       priv->folder_paned = gtk_vpaned_new ();
-       priv->msg_paned = gtk_vpaned_new ();
-       priv->main_paned = gtk_hpaned_new ();
+       /* Paned */
        preview_scroll = gtk_scrolled_window_new (NULL, NULL);
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (preview_scroll), 
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (preview_scroll),
                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
        gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
        gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
        gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
-       gtk_container_add (GTK_CONTAINER (preview_scroll), 
+       gtk_container_add (GTK_CONTAINER (preview_scroll),
                           GTK_WIDGET(priv->msg_preview));
        gtk_paned_add2 (GTK_PANED(priv->msg_paned), preview_scroll);
 
-       /* status bar / progress */
+       /* Main Bar */
        status_hbox = gtk_hbox_new (FALSE, 0);
        gtk_box_pack_start (GTK_BOX(status_hbox), priv->folder_info_label, FALSE,FALSE, 6);
-       gtk_box_pack_start (GTK_BOX(status_hbox), priv->status_bar, TRUE, TRUE, 0);
-       gtk_box_pack_start (GTK_BOX(status_hbox), priv->progress_bar,FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX(status_hbox), priv->main_bar, TRUE, TRUE, 0);
        gtk_box_pack_start (GTK_BOX(status_hbox), priv->online_toggle,FALSE, FALSE, 0);
 
        /* putting it all together... */
@@ -633,3 +639,55 @@ show_context_popup_menu (ModestMainWindow *window,
        }
        return TRUE;
 }
+
+static void
+on_queue_changed (ModestMailOperationQueue *queue,
+                 ModestMailOperation *mail_op,
+                 ModestMailOperationQueueNotification type,
+                 ModestMainWindow *self)
+{
+       GSList *tmp;
+       ModestMainWindowPrivate *priv;
+
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
+
+       tmp = priv->progress_widgets;
+
+       switch (type) {
+       case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
+               while (tmp) {
+                       modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
+                                                             mail_op);
+                       tmp = g_slist_next (tmp);
+               }
+               break;
+       case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
+               while (tmp) {
+                       modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
+                                                                mail_op);
+                       tmp = g_slist_next (tmp);
+               }
+               break;
+       }
+}
+
+static void
+on_header_status_update (ModestHeaderView *header_view, 
+                        const gchar *msg, gint num, 
+                        gint total,  ModestMainWindow *self)
+{
+       ModestMainWindowPrivate *priv;
+       gchar *txt;
+
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
+
+       /* Set progress */
+       txt = g_strdup_printf (_("Downloading %d of %d"), num, total);
+       modest_gnome_info_bar_set_progress (MODEST_GNOME_INFO_BAR (priv->main_bar), 
+                                           (const gchar*) txt,
+                                           num, total);
+       g_free (txt);
+       
+       /* Set status message */
+       modest_gnome_info_bar_set_message (MODEST_GNOME_INFO_BAR (priv->main_bar), msg);
+}
index a273b83..cf536b9 100644 (file)
@@ -28,7 +28,9 @@
  */
 
 #include "config.h"
+#include "modest-marshal.h"
 #include "modest-mail-operation-queue.h"
+#include "modest-runtime.h"
 
 /* 'private'/'protected' functions */
 static void modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass);
@@ -43,9 +45,8 @@ static void modest_mail_operation_queue_cancel_no_block         (ModestMailOpera
 
 /* list my signals  */
 enum {
-       /* MY_SIGNAL_1, */
-       /* MY_SIGNAL_2, */
-       LAST_SIGNAL
+       QUEUE_CHANGED_SIGNAL,
+       NUM_SIGNALS
 };
 
 typedef struct _ModestMailOperationQueuePrivate ModestMailOperationQueuePrivate;
@@ -59,8 +60,7 @@ struct _ModestMailOperationQueuePrivate {
 /* globals */
 static GObjectClass *parent_class = NULL;
 
-/* uncomment the following if you have defined any signals */
-/* static guint signals[LAST_SIGNAL] = {0}; */
+static guint signals[NUM_SIGNALS] = {0};
 
 GType
 modest_mail_operation_queue_get_type (void)
@@ -98,6 +98,24 @@ modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass)
        gobject_class->finalize    = modest_mail_operation_queue_finalize;
 
        g_type_class_add_private (gobject_class, sizeof(ModestMailOperationQueuePrivate));
+
+       /**
+        * ModestMailOperationQueue::queue-changed
+        * @self: the #ModestMailOperationQueue that emits the signal
+        * @mail_op: the #ModestMailOperation affected
+        * @type: the type of change in the queue
+        * @user_data: user data set when the signal handler was connected
+        *
+        * Emitted whenever the contents of the queue change
+        */
+       signals[QUEUE_CHANGED_SIGNAL] =
+               g_signal_new ("queue-changed",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ModestMailOperationQueueClass, queue_changed),
+                             NULL, NULL,
+                             modest_marshal_VOID__POINTER_INT,
+                             G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT);
 }
 
 static void
@@ -154,6 +172,10 @@ modest_mail_operation_queue_add (ModestMailOperationQueue *self,
        g_mutex_lock (priv->queue_lock);
        g_queue_push_tail (priv->op_queue, g_object_ref (mail_op));
        g_mutex_unlock (priv->queue_lock);
+
+       /* Notify observers */
+       g_signal_emit (self, signals[QUEUE_CHANGED_SIGNAL], 0,
+                      mail_op, MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED);
 }
 
 void 
@@ -170,6 +192,25 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self,
        g_mutex_lock (priv->queue_lock);
        g_queue_remove (priv->op_queue, mail_op);
        g_mutex_unlock (priv->queue_lock);
+
+       /* HACK see the documentation of the function. Remove this
+          call when tinymail provides accurate progress values */
+       _modest_mail_operation_notify_end (mail_op);
+
+       /* Notify observers */
+       g_signal_emit (self, signals[QUEUE_CHANGED_SIGNAL], 0,
+                      mail_op, MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED);
+
+       /* TODO: errors? */
+       {
+               const GError *err = modest_mail_operation_get_error (mail_op);
+               if (err)
+                       g_warning (err->message);
+       }
+
+       /* Free object */
+       g_object_unref (G_OBJECT (mail_op));
+       modest_runtime_verify_object_death (mail_op, "");
 }
 
 
index 7a0759e..bbc33c0 100644 (file)
@@ -45,6 +45,11 @@ G_BEGIN_DECLS
 #define MODEST_IS_MAIL_OPERATION_QUEUE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_MAIL_OPERATION_QUEUE))
 #define MODEST_MAIL_OPERATION_QUEUE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_MAIL_OPERATION_QUEUE,ModestMailOperationQueueClass))
 
+typedef enum _ModestMailOperationQueueNotification {
+       MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED,
+       MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED
+} ModestMailOperationQueueNotification;
+
 typedef struct _ModestMailOperationQueue      ModestMailOperationQueue;
 typedef struct _ModestMailOperationQueueClass ModestMailOperationQueueClass;
 
@@ -54,6 +59,11 @@ struct _ModestMailOperationQueue {
 
 struct _ModestMailOperationQueueClass {
        GObjectClass parent_class;
+
+       /* Signals */
+       void (*queue_changed) (ModestMailOperationQueue *self, 
+                              ModestMailOperation *mail_op,
+                              ModestMailOperationQueueNotification type);
 };
 
 /* member functions */
index c4d5b05..cdde44a 100644 (file)
@@ -54,15 +54,6 @@ static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
 static void modest_mail_operation_init       (ModestMailOperation *obj);
 static void modest_mail_operation_finalize   (GObject *obj);
 
-static void     status_update_cb     (TnyFolder *folder, 
-                                     const gchar *what, 
-                                     gint status, 
-                                     gint oftotal,
-                                     gpointer user_data);
-static void     folder_refresh_cb    (TnyFolder *folder, 
-                                     gboolean canceled,
-                                     GError **err,
-                                     gpointer user_data);
 static void     update_folders_cb    (TnyFolderStore *self, 
                                      TnyList *list, 
                                      GError **err, 
@@ -101,6 +92,15 @@ typedef struct _RefreshFolderAsyncHelper
 
 } RefreshFolderAsyncHelper;
 
+typedef struct _XFerMsgAsyncHelper
+{
+       ModestMailOperation *mail_op;
+       TnyList *headers;
+       TnyFolder *dest_folder;
+
+} XFerMsgAsyncHelper;
+
+
 /* globals */
 static GObjectClass *parent_class = NULL;
 
@@ -149,7 +149,7 @@ modest_mail_operation_class_init (ModestMailOperationClass *klass)
         * Emitted when the progress of a mail operation changes
         */
        signals[PROGRESS_CHANGED_SIGNAL] = 
-               g_signal_new ("progress_changed",
+               g_signal_new ("progress-changed",
                              G_TYPE_FROM_CLASS (gobject_class),
                              G_SIGNAL_RUN_FIRST,
                              G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed),
@@ -202,6 +202,7 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
        
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
+       g_return_if_fail (TNY_IS_MSG (msg));
        
        send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
        if (!TNY_IS_SEND_QUEUE(send_queue))
@@ -216,6 +217,9 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
                } else
                        g_message ("modest: message added to send queue");
        }
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 }
 
 void
@@ -253,79 +257,46 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                g_printerr ("modest: failed to create a new msg\n");
                return;
        }
-       
+
+       /* Call mail operation */
        modest_mail_operation_send_mail (self, transport_account, new_msg);
 
-       g_object_unref (G_OBJECT(new_msg));
+       /* Free */
+       g_object_unref (G_OBJECT (new_msg));
 }
 
 static void
-status_update_cb (TnyFolder *folder, const gchar *what, gint status, gint oftotal, gpointer user_data) 
+recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
 {
-       g_print ("%s status: %d, of total %d\n", what, status, oftotal);
-}
+       TnyIterator *iter;
+       TnyList *folders = tny_simple_list_new ();
 
-static void
-folder_refresh_cb (TnyFolder *folder, gboolean canceled, GError **err, gpointer user_data)
-{
-       ModestMailOperation *self = NULL;
-       ModestMailOperationPrivate *priv = NULL;
-       RefreshFolderAsyncHelper *helper;
+       tny_folder_store_get_folders (store, folders, query, NULL);
+       iter = tny_list_create_iterator (folders);
 
-       helper = (RefreshFolderAsyncHelper *) user_data;
-       self = MODEST_MAIL_OPERATION (helper->mail_op);
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+       while (!tny_iterator_is_done (iter)) {
 
-       if ((canceled && *err) || *err) {
-               priv->error = g_error_copy (*err);
-               helper->failed++;
-       } else if (canceled) {
-               helper->canceled++;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
-                            _("Error trying to refresh folder %s. Operation canceled"),
-                            tny_folder_get_name (folder));
-       } else {
-               priv->done++;
-       }
+               TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
 
-       if (priv->done == priv->total)
-               priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-       else if ((priv->done + helper->canceled + helper->failed) == priv->total) {
-               if (helper->failed == priv->total)
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               else if (helper->failed == priv->total)
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
-               else
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
-       }
-       tny_iterator_next (helper->iter);
-       if (tny_iterator_is_done (helper->iter)) {
-               TnyList *list;
-               list = tny_iterator_get_list (helper->iter);
-               g_object_unref (G_OBJECT (helper->iter));
-               g_object_unref (G_OBJECT (list));
-               g_slice_free (RefreshFolderAsyncHelper, helper);
-       } else {
-               TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (helper->iter));
-               if (folder) {
-                       g_message ("modest: refreshing folder %s",
-                                  tny_folder_get_name (folder));
-                       tny_folder_refresh_async (folder, folder_refresh_cb, status_update_cb, helper);
-                       g_object_unref (G_OBJECT(folder)); // FIXME: don't unref yet
-               }
+               tny_list_prepend (all_folders, G_OBJECT (folder));
+
+               recurse_folders (folder, query, all_folders);
+           
+               g_object_unref (G_OBJECT (folder));
+
+               tny_iterator_next (iter);
        }
-       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
+        g_object_unref (G_OBJECT (iter));
+        g_object_unref (G_OBJECT (folders));
 }
 
-
 static void
 update_folders_cb (TnyFolderStore *folder_store, TnyList *list, GError **err, gpointer user_data)
 {
        ModestMailOperation *self;
        ModestMailOperationPrivate *priv;
-       RefreshFolderAsyncHelper *helper;
-       TnyFolder *folder;
+       TnyIterator *iter;
+       TnyList *all_folders;
        
        self  = MODEST_MAIL_OPERATION (user_data);
        priv  = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
@@ -333,27 +304,58 @@ update_folders_cb (TnyFolderStore *folder_store, TnyList *list, GError **err, gp
        if (*err) {
                priv->error = g_error_copy (*err);
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               return;
+               goto out;
        }
 
-       priv->total = tny_list_get_length (list);
-       priv->done = 0;
-       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       /* Get all the folders We can do it synchronously because
+          we're already running in a different thread than the UI */
+       all_folders = tny_list_copy (list);
+       iter = tny_list_create_iterator (all_folders);
+       while (!tny_iterator_is_done (iter)) {
+               TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
 
-       helper = g_slice_new0 (RefreshFolderAsyncHelper);
-       helper->mail_op = self;
-       helper->iter = tny_list_create_iterator (list);
-       helper->failed = 0;
-       helper->canceled = 0;
-
-       /* Async refresh folders */
-       folder = TNY_FOLDER (tny_iterator_get_current (helper->iter));
-       if (folder) {
-               g_message ("modest: refreshing folder %s", tny_folder_get_name (folder));
-               tny_folder_refresh_async (folder, folder_refresh_cb,
-                                         status_update_cb, helper);
+               recurse_folders (folder, NULL, all_folders);
+               tny_iterator_next (iter);
        }
-       //g_object_unref (G_OBJECT(folder)); /* FIXME -==> don't unref yet... */
+       g_object_unref (G_OBJECT (iter));
+
+       /* Refresh folders */
+       iter = tny_list_create_iterator (all_folders);
+       priv->total = tny_list_get_length (all_folders);
+
+       while (!tny_iterator_is_done (iter) && !priv->error) {
+
+               TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
+
+               /* Refresh the folder */
+               tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
+
+               if (priv->error) {
+                       priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               } else {        
+                       /* Update status and notify */
+                       priv->done++;
+                       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
+               }
+    
+               g_object_unref (G_OBJECT (folder));
+           
+               tny_iterator_next (iter);
+       }
+
+       g_object_unref (G_OBJECT (iter));
+ out:
+       g_object_unref (G_OBJECT (list));
+
+       /* Check if the operation was a success */
+       if (priv->done == priv->total && !priv->error)
+               priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
+       /* Free */
+       g_object_unref (G_OBJECT (folder_store));
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 }
 
 gboolean
@@ -362,25 +364,24 @@ modest_mail_operation_update_account (ModestMailOperation *self,
 {
        ModestMailOperationPrivate *priv;
        TnyList *folders;
-       TnyFolderStoreQuery *query;
 
        g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
        g_return_val_if_fail (TNY_IS_STORE_ACCOUNT(store_account), FALSE);
 
+       /* Pick async call reference */
+       g_object_ref (store_account);
+
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
 
+       priv->total = 0;
+       priv->done  = 0;
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+
        /* Get subscribed folders & refresh them */
        folders = TNY_LIST (tny_simple_list_new ());
-       query = NULL; //tny_folder_store_query_new ();
 
-       /* FIXME: is this needed? */
-//     tny_device_force_online (TNY_DEVICE(modest_runtime_get_device()));
-       
-       /* FIXME: let query be NULL: do it for all */ 
-       //tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
        tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
-                                           folders, update_folders_cb, query, self);
-       //g_object_unref (query); /* FIXME */
+                                           folders, update_folders_cb, NULL, self);
        
        return TRUE;
 }
@@ -476,7 +477,6 @@ modest_mail_operation_create_folder (ModestMailOperation *self,
 {
        ModestMailOperationPrivate *priv;
        TnyFolder *new_folder = NULL;
-       //TnyStoreAccount *store_account;
 
        g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
        g_return_val_if_fail (name, NULL);
@@ -487,12 +487,8 @@ modest_mail_operation_create_folder (ModestMailOperation *self,
        new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
        CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, return NULL);
 
-/*     /\* Subscribe to folder *\/ */
-/*     if (!tny_folder_is_subscribed (new_folder)) { */
-/*             store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (TNY_FOLDER (parent))); */
-/*             tny_store_account_subscribe (store_account, new_folder); */
-/*             g_object_unref (G_OBJECT (store_account)); */
-/*     } */
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 
        return new_folder;
 }
@@ -533,6 +529,9 @@ modest_mail_operation_remove_folder (ModestMailOperation *self,
                        g_object_unref (G_OBJECT (parent));
        }
        g_object_unref (G_OBJECT (account));
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 }
 
 void
@@ -550,11 +549,15 @@ modest_mail_operation_rename_folder (ModestMailOperation *self,
 
        /* FIXME: better error handling */
        if (strrchr (name, '/') != NULL)
-               return;
+               goto out;
 
        /* Rename. Camel handles folder subscription/unsubscription */
        tny_folder_set_name (folder, name, &(priv->error));
-       CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, return);
+       CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, goto out);
+
+ out:
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
  }
 
 TnyFolder *
@@ -564,6 +567,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
                                   gboolean delete_original)
 {
        ModestMailOperationPrivate *priv;
+       TnyFolder *new_folder;
 
        g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
        g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
@@ -571,11 +575,16 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
-       return tny_folder_copy (folder, 
-                               parent, 
-                               tny_folder_get_name (folder), 
-                               delete_original, 
-                               &(priv->error));
+       new_folder = tny_folder_copy (folder,
+                                     parent,
+                                     tny_folder_get_name (folder),
+                                     delete_original, 
+                                     &(priv->error));
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
+
+       return new_folder;
 }
 
 
@@ -589,11 +598,16 @@ modest_mail_operation_remove_msg (ModestMailOperation *self,
                                  gboolean remove_to_trash)
 {
        TnyFolder *folder;
+       ModestMailOperationPrivate *priv;
 
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_HEADER (header));
 
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
        folder = tny_header_get_folder (header);
 
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+
        /* Delete or move to trash */
        if (remove_to_trash) {
                TnyFolder *trash_folder;
@@ -618,20 +632,34 @@ modest_mail_operation_remove_msg (ModestMailOperation *self,
 
                g_object_unref (G_OBJECT (store_account));
        } else {
-               tny_folder_remove_msg (folder, header, NULL); /* FIXME */
-               tny_folder_sync(folder, TRUE, NULL); /* FIXME */
+               tny_folder_remove_msg (folder, header, &(priv->error));
+               if (!priv->error)
+                       tny_folder_sync(folder, TRUE, &(priv->error));
        }
 
+       /* Set status */
+       if (!priv->error)
+               priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+       else
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+
        /* Free */
-       g_object_unref (folder);
+       g_object_unref (G_OBJECT (folder));
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 }
 
 static void
 transfer_msgs_cb (TnyFolder *folder, GError **err, gpointer user_data)
 {
+       XFerMsgAsyncHelper *helper;
+       ModestMailOperation *self;
        ModestMailOperationPrivate *priv;
 
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(user_data);
+       helper = (XFerMsgAsyncHelper *) user_data;
+       self = helper->mail_op;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
        if (*err) {
                priv->error = g_error_copy (*err);
@@ -642,10 +670,17 @@ transfer_msgs_cb (TnyFolder *folder, GError **err, gpointer user_data)
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
        }
 
-       g_signal_emit (G_OBJECT (user_data), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
+       /* Free */
+       g_object_unref (helper->headers);
+       g_object_unref (helper->dest_folder);
+       g_object_unref (folder);
+       g_free (helper);
+
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
 }
 
-gboolean
+void
 modest_mail_operation_xfer_msg (ModestMailOperation *self,
                                TnyHeader *header, 
                                TnyFolder *folder, 
@@ -654,28 +689,116 @@ modest_mail_operation_xfer_msg (ModestMailOperation *self,
        ModestMailOperationPrivate *priv;
        TnyFolder *src_folder;
        TnyList *headers;
+       XFerMsgAsyncHelper *helper;
 
-       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
-       g_return_val_if_fail (TNY_IS_HEADER (header), FALSE);
-       g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE);
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (TNY_IS_HEADER (header));
+       g_return_if_fail (TNY_IS_FOLDER (folder));
+
+       /* Pick references for async calls */
+       g_object_ref (folder);
 
-       src_folder = tny_header_get_folder (header);
        headers = tny_simple_list_new ();
+       tny_list_prepend (headers, G_OBJECT (header));
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        priv->total = 1;
        priv->done = 0;
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
 
-       tny_list_prepend (headers, G_OBJECT (header));
-       tny_folder_transfer_msgs_async (src_folder, headers, folder, 
-                                       delete_original, transfer_msgs_cb, 
-                                       g_object_ref(self));
+       /* Create the helper */
+       helper = g_malloc0 (sizeof (XFerMsgAsyncHelper));
+       helper->mail_op = self;
+       helper->dest_folder = folder;
+       helper->headers = headers;
+
+       src_folder = tny_header_get_folder (header);
+       tny_folder_transfer_msgs_async (src_folder, 
+                                       headers, 
+                                       folder, 
+                                       delete_original, 
+                                       transfer_msgs_cb, 
+                                       helper);
+}
+
+static void
+on_refresh_folder (TnyFolder   *folder, 
+                  gboolean     cancelled, 
+                  GError     **error,
+                  gpointer     user_data)
+{
+       ModestMailOperation *self;
+       ModestMailOperationPrivate *priv;
+
+       self = MODEST_MAIL_OPERATION (user_data);
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+       if (*error) {
+               priv->error = g_error_copy (*error);
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               goto out;
+       }
+
+       if (cancelled) {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
+               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                            MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
+                            _("Error trying to refresh the contents of %s"),
+                            tny_folder_get_name (folder));
+               goto out;
+       }
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
 
+ out:
        /* Free */
-       /* FIXME: don't free 'm yet */
-       ///g_object_unref (headers);
-       ///g_object_unref (src_folder);
+       g_object_unref (folder);
 
-       return TRUE;
+       /* Notify the queue */
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
+}
+
+static void
+on_refresh_folder_status_update (TnyFolder *folder, const gchar *msg,
+                                gint num, gint total,  gpointer user_data)
+{
+       ModestMailOperation *self;
+       ModestMailOperationPrivate *priv;
+
+       self = MODEST_MAIL_OPERATION (user_data);
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+       priv->done = num;
+       priv->total = total;
+
+       if (num == 1 && total == 100)
+               return;
+
+       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
+}
+
+void 
+modest_mail_operation_refresh_folder  (ModestMailOperation *self,
+                                      TnyFolder *folder)
+{
+       ModestMailOperationPrivate *priv;
+
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+       /* Pick a reference */
+       g_object_ref (folder);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+
+       /* Refresh the folder */
+       tny_folder_refresh_async (folder,
+                                 on_refresh_folder,
+                                 on_refresh_folder_status_update,
+                                 self);
+}
+
+void
+_modest_mail_operation_notify_end (ModestMailOperation *self)
+{
+       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
 }
index c5f49fb..a2c318d 100644 (file)
@@ -135,15 +135,17 @@ void    modest_mail_operation_send_new_mail   (ModestMailOperation *self,
  * #ModestMailOperationQueue and then free it. The caller will be
  * notified by the "progress_changed" signal each time the progress of
  * the operation changes.
+ *
+ * Note that the store account passed as parametter will be freed by
+ * the mail operation so you must pass a new reference
+ *
  * Example
  * <informalexample><programlisting>
  * queue = modest_tny_platform_factory_get_modest_mail_operation_queue_instance (fact)
  * mail_op = modest_mail_operation_new ();
- * g_signal_connect (G_OBJECT (mail_op), "progress_changed", G_CALLBACK(on_progress_changed), queue);
- * if (modest_mail_operation_update_account (mail_op, account))
- * {
- *     modest_mail_operation_queue_add (queue, mail_op);
- * }
+ * g_signal_connect (G_OBJECT (mail_op), "progress_changed", G_CALLBACK(on_progress_changed), NULL);
+ * modest_mail_operation_queue_add (queue, mail_op);
+ * modest_mail_operation_update_account (mail_op, account)
  * g_object_unref (G_OBJECT (mail_op));
  * </programlisting></informalexample>
  * 
@@ -246,17 +248,16 @@ TnyFolder*    modest_mail_operation_xfer_folder    (ModestMailOperation *self,
  * <informalexample><programlisting>
  * queue = modest_tny_platform_factory_get_modest_mail_operation_queue_instance (fact);
  * mail_op = modest_mail_operation_new ();
- * if (modest_mail_operation_xfer_msg (mail_op, header, folder, TRUE))
- * {
- *     g_signal_connect (G_OBJECT (mail_op), "progress_changed", G_CALLBACK(on_progress_changed), queue);
- *     modest_mail_operation_queue_add (queue, mail_op);
- * }
+ * modest_mail_operation_queue_add (queue, mail_op);
+ * g_signal_connect (G_OBJECT (mail_op), "progress_changed", G_CALLBACK(on_progress_changed), queue);
+ *
+ * modest_mail_operation_xfer_msg (mail_op, header, folder, TRUE);
+ * 
  * g_object_unref (G_OBJECT (mail_op));
  * </programlisting></informalexample>
  *
- * Returns: TRUE if the mail operation could be started, or FALSE otherwise
  **/
-gboolean      modest_mail_operation_xfer_msg       (ModestMailOperation *self,
+void          modest_mail_operation_xfer_msg       (ModestMailOperation *self,
                                                    TnyHeader *header, 
                                                    TnyFolder *folder,
                                                    gboolean delete_original);
@@ -313,7 +314,7 @@ guint     modest_mail_operation_get_task_total     (ModestMailOperation *self);
  * 
  * Returns: TRUE if the operation is finished, FALSE otherwise
  **/
-gboolean                  modest_mail_operation_is_finished (ModestMailOperation *self);
+gboolean  modest_mail_operation_is_finished        (ModestMailOperation *self);
 
 /**
  * modest_mail_operation_is_finished:
@@ -344,7 +345,29 @@ const GError*             modest_mail_operation_get_error   (ModestMailOperation
  * 
  * Returns: TRUE if the operation was succesfully canceled, FALSE otherwise
  **/
-gboolean                  modest_mail_operation_cancel      (ModestMailOperation *self);
+gboolean  modest_mail_operation_cancel          (ModestMailOperation *self);
+
+/**
+ * modest_mail_operation_refresh_folder
+ * @self: a #ModestMailOperation
+ * @folder: the #TnyFolder to refresh
+ * 
+ * Refreshes the contents of a folder
+ */
+void      modest_mail_operation_refresh_folder  (ModestMailOperation *self,
+                                                TnyFolder *folder);
+
+/**
+ *
+ * This function is a workarround. It emits the progress-changed
+ * signal. It's used by the mail operation queue to notify the
+ * observers attached to that signal that the operation finished. We
+ * need to use that for the moment because tinymail does not give us
+ * the progress of a given operation very well. So we must delete it
+ * when tinymail has that functionality and remove the call to it in
+ * the queue as well.
+ */
+void _modest_mail_operation_notify_end (ModestMailOperation *self);
 
 G_END_DECLS
 
index 85f3d34..efa3bdf 100644 (file)
@@ -6,3 +6,4 @@ VOID:STRING,INT
 VOID:STRING,INT,INT
 VOID:STRING,BOOL
 VOID:STRING,STRING,BOOL
+VOID:POINTER,INT
diff --git a/src/modest-progress-object.c b/src/modest-progress-object.c
new file mode 100644 (file)
index 0000000..11d1c5c
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "modest-progress-object.h"
+
+static void modest_progress_object_base_init (gpointer g_class);
+
+void
+modest_progress_object_add_operation (ModestProgressObject *self, 
+                                           ModestMailOperation *mail_op)
+{
+       return MODEST_PROGRESS_OBJECT_GET_IFACE (self)->add_operation_func (self, mail_op);
+}
+
+void
+modest_progress_object_remove_operation (ModestProgressObject *self, 
+                                              ModestMailOperation *mail_op)
+{
+       return MODEST_PROGRESS_OBJECT_GET_IFACE (self)->remove_operation_func (self, mail_op);
+}
+
+static void
+modest_progress_object_base_init (gpointer g_class)
+{
+       static gboolean initialized = FALSE;
+       if (!initialized) {
+       /* create interface signals here */
+               initialized = TRUE;
+       }
+}
+GType
+modest_progress_object_get_type (void)
+{
+       static GType my_type = 0;
+       if (!my_type) {
+               static const GTypeInfo my_info = {
+                       sizeof(ModestProgressObjectIface),
+                       modest_progress_object_base_init,               /* base init */
+                       NULL,           /* base finalize */
+                       NULL,           /* class_init */
+                       NULL,           /* class finalize */
+                       NULL,           /* class data */
+                       0,
+                       0,              /* n_preallocs */
+                       NULL,           /* instance init */
+               };
+               my_type = g_type_register_static (G_TYPE_INTERFACE,
+                                                 "ModestProgressObject",
+                                                 &my_info, 0);
+               g_type_interface_add_prerequisite (my_type, G_TYPE_OBJECT);
+       }
+       return my_type;
+}
+
diff --git a/src/modest-progress-object.h b/src/modest-progress-object.h
new file mode 100644 (file)
index 0000000..6ced675
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MODEST_PROGRESS_OBJECT_H__
+#define __MODEST_PROGRESS_OBJECT_H__
+
+/* other include files */
+#include "modest-mail-operation.h"
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_PROGRESS_OBJECT             (modest_progress_object_get_type())
+#define MODEST_PROGRESS_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_PROGRESS_OBJECT,ModestProgressObject))
+#define MODEST_IS_PROGRESS_OBJECT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_PROGRESS_OBJECT))
+#define MODEST_PROGRESS_OBJECT_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst),MODEST_TYPE_PROGRESS_OBJECT,ModestProgressObjectIface))
+
+typedef struct _ModestProgressObject      ModestProgressObject;
+typedef struct _ModestProgressObjectIface ModestProgressObjectIface;
+
+struct _ModestProgressObjectIface {
+       GTypeInterface parent;
+
+       /* the 'vtable': declare function pointers here, eg.: */
+       void (*add_operation_func) (ModestProgressObject *self, ModestMailOperation *mail_op);
+       void (*remove_operation_func) (ModestProgressObject *self, ModestMailOperation *mail_op);
+};
+
+GType     modest_progress_object_get_type            (void) G_GNUC_CONST;
+
+void      modest_progress_object_add_operation       (ModestProgressObject *self,
+                                                     ModestMailOperation  *mail_op);
+
+void      modest_progress_object_remove_operation    (ModestProgressObject *self,
+                                                     ModestMailOperation  *mail_op);
+
+
+G_END_DECLS
+
+#endif /* __MODEST_PROGRESS_OBJECT_H__ */
index 7aec591..57e10fe 100644 (file)
@@ -158,26 +158,24 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
                        header = TNY_HEADER (tny_iterator_get_current (iter));
                        /* TODO: thick grain mail operation involving
                           a list of objects. Composite pattern ??? */
-                       mail_op = modest_mail_operation_new ();
-
                        /* TODO: add confirmation dialog */
+                       mail_op = modest_mail_operation_new ();
+                       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                        mail_op);
 
-                       /* Move to trash. TODO: Still not supported */
+                       /* Always delete. TODO: Move to trash still not supported */
                        modest_mail_operation_remove_msg (mail_op, header, FALSE);
 
-                       if (modest_mail_operation_get_status (mail_op) !=
-                           MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
-                               const GError *error;
-                               error = modest_mail_operation_get_error (mail_op);
-                               if (error)
-                                       g_warning (error->message);
-                       }
-
+                       /* Frees */
                        g_object_unref (G_OBJECT (mail_op));
-                       g_object_unref (header);
+                       g_object_unref (G_OBJECT (header));
+
                        tny_iterator_next (iter);
 
                } while (!tny_iterator_is_done (iter));
+
+               /* Free iter */
+               g_object_unref (G_OBJECT (iter));
        }
 }
 
@@ -560,11 +558,14 @@ modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
                return;
        }
 
+       /* Create the mail operation */
        mail_op = modest_mail_operation_new ();
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
        modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
 
-       g_object_unref (G_OBJECT(tny_account));
-       /* g_object_unref (G_OBJECT(mail_op)); FIXME: this is still in use... */
+       /* Frees */
+       g_object_unref (G_OBJECT (tny_account));
+       g_object_unref (G_OBJECT (mail_op));
 }
 
 
@@ -585,7 +586,8 @@ modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
        conf = modest_runtime_get_conf ();
        
        /* what is saved/restored is depending on the style; thus; we save with
-        * old style, then update the style, and restore for this new style*/
+        * old style, then update the style, and restore for this new style
+        */
        modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
        
        if (modest_header_view_get_style
@@ -814,56 +816,6 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
        }
 }
 
-
-/****************************************************/
-/*
- * below some stuff to clearup statusbar messages after 1,5 seconds....
- */
-static gboolean
-progress_bar_clean (GtkWidget *bar)
-{
-       if (GTK_IS_PROGRESS_BAR(bar)) {
-               gtk_progress_bar_set_text     (GTK_PROGRESS_BAR(bar), "");
-               gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(bar), 1.0);
-       }
-       return FALSE;
-}
-
-static gboolean
-statusbar_clean (GtkWidget *bar)
-{
-       if (GTK_IS_STATUSBAR(bar))
-               gtk_statusbar_push (GTK_STATUSBAR(bar), 0, "");
-       return FALSE;
-}
-
-
-static void
-statusbar_push (ModestMainWindow *main_window, guint context_id, const gchar *msg)
-{
-       if (!msg)
-               return;
-
-       GtkWidget *progress_bar, *status_bar;
-
-       progress_bar = modest_main_window_get_child_widget (main_window,
-                                                           MODEST_WIDGET_TYPE_PROGRESS_BAR);
-       status_bar = modest_main_window_get_child_widget (main_window,
-                                                         MODEST_WIDGET_TYPE_STATUS_BAR);
-       if (progress_bar) {
-               gtk_widget_show (progress_bar);
-               g_timeout_add (3000, (GSourceFunc)progress_bar_clean, progress_bar);
-       }
-       
-       if (status_bar) {
-               gtk_widget_show (status_bar);
-               gtk_statusbar_push (GTK_STATUSBAR(status_bar), 0, msg);
-               g_timeout_add (2500, (GSourceFunc)statusbar_clean, status_bar);
-       }
-
-}
-/****************************************************************************/
-
 void 
 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
                                     ModestWindow *win)
@@ -913,37 +865,6 @@ modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemTyp
                gdk_threads_leave ();
 }
 
-
-
-void
-modest_ui_actions_on_header_status_update (ModestHeaderView *header_view, 
-                                           const gchar *msg, gint num, 
-                                           gint total,  ModestMainWindow *main_window)
-{
-       char* txt;
-       GtkWidget *progress_bar;
-
-       g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
-
-       progress_bar = modest_main_window_get_child_widget (main_window, 
-                                                           MODEST_WIDGET_TYPE_PROGRESS_BAR);   
-       if (!progress_bar)
-               return;
-       
-       if (total != 0)
-               gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar),
-                                              (gdouble)num/(gdouble)total);
-       else
-               gtk_progress_bar_pulse (GTK_PROGRESS_BAR(progress_bar));
-
-       txt = g_strdup_printf (_("Downloading %d of %d"), num, total);
-       gtk_progress_bar_set_text (GTK_PROGRESS_BAR(progress_bar), txt);
-       g_free (txt);
-       
-       statusbar_push (main_window, 0, msg);
-}
-
-
 void
 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
                                     ModestWindow *win)
@@ -1012,8 +933,11 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
                return;
        }
        from = modest_account_mgr_get_from_string (account_mgr, account_name);
-               
+
+       /* Create the mail operation */         
        mail_operation = modest_mail_operation_new ();
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
+
        modest_mail_operation_send_new_mail (mail_operation,
                                             transport_account,
                                             from,
@@ -1027,13 +951,12 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
        /* Frees */
        g_free (from);
        g_free (account_name);
-       g_object_unref (G_OBJECT (mail_operation));
        g_object_unref (G_OBJECT (transport_account));
+       g_object_unref (G_OBJECT (mail_operation));
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
 
        /* Save settings and close the window */
-       /* save_settings (edit_window) */
        gtk_widget_destroy (GTK_WIDGET (edit_window));
 }
 
@@ -1228,18 +1151,16 @@ modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_windo
                        ModestMailOperation *mail_op;
 
                        mail_op = modest_mail_operation_new ();
+                       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
+                                                        mail_op);
+
                        new_folder = modest_mail_operation_create_folder (mail_op,
                                                                          TNY_FOLDER_STORE (parent_folder),
                                                                          (const gchar *) folder_name);
-                       if (new_folder) {
+                       if (new_folder) 
                                g_object_unref (new_folder);
-                       } else {
-                               const GError *error;
-                               error = modest_mail_operation_get_error (mail_op);
-                               if (error)
-                                       g_warning ("Error adding a subfolder: %s\n", error->message);
-                       }
                        g_object_unref (mail_op);
+                       g_free (folder_name);
                }
                g_object_unref (parent_folder);
        }
@@ -1268,19 +1189,17 @@ modest_ui_actions_on_rename_folder (GtkAction *action,
 
                if (folder_name != NULL && strlen (folder_name) > 0) {
                        ModestMailOperation *mail_op;
-                       const GError *error;
 
                        mail_op = modest_mail_operation_new ();
+                       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                        mail_op);
+
                        modest_mail_operation_rename_folder (mail_op,
                                                             folder,
                                                             (const gchar *) folder_name);
 
-                       error = modest_mail_operation_get_error (mail_op);
-                       if (error)
-                               /* TODO: notify error ? */
-                               g_warning ("Could not rename a folder: %s\n", error->message);
-
                        g_object_unref (mail_op);
+                       g_free (folder_name);
                }
                g_object_unref (folder);
        }
@@ -1292,7 +1211,6 @@ delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
        TnyFolder *folder;
        ModestMailOperation *mail_op;
        GtkWidget *folder_view;
-       const GError *error;
        
        g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
 
@@ -1304,12 +1222,10 @@ delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
        folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
        
        mail_op = modest_mail_operation_new ();
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                        mail_op);
        modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
 
-       error = modest_mail_operation_get_error (mail_op);
-       if (error)
-               g_warning ("%s\n", error->message);
-
        g_object_unref (G_OBJECT (mail_op));
        g_object_unref (G_OBJECT (folder));
 }
index 2add3e1..6c26497 100644 (file)
@@ -83,12 +83,6 @@ void     modest_ui_actions_on_item_not_found           (ModestHeaderView *header
                                                         ModestItemType type,
                                                         ModestWindow *window);
 
-void     modest_ui_actions_on_header_status_update     (ModestHeaderView *header_view, 
-                                                        const gchar *msg,
-                                                        gint num, 
-                                                        gint total, 
-                                                        ModestMainWindow *main_window);
-
 void     modest_ui_actions_on_msg_link_hover           (ModestMsgView *msgview, const gchar* link,
                                                        ModestWindow *win);
 
index 1a49d87..cb0ff4e 100644 (file)
@@ -28,7 +28,6 @@ libmodest_widgets_la_SOURCES=          \
        modest-combo-box.h             \
        modest-folder-view.c           \
        modest-folder-view.h           \
-       modest-header-view-priv.h      \
        modest-header-view-render.c    \
        modest-header-view.c           \
        modest-header-view.h           \
@@ -47,7 +46,7 @@ libmodest_widgets_la_SOURCES=          \
        modest-tny-stream-gtkhtml.c    \
        modest-tny-stream-gtkhtml.h    \
        modest-window.c                \
-       modest-window.h             
+       modest-window.h
 
 LDADD = \
        $(MODEST_GSTUFF_LIBS)                           \
index 62904fd..4e90143 100644 (file)
@@ -770,32 +770,31 @@ typedef struct _DndHelper {
 
 /*
  * This function is the callback of the
- * modest_mail_operation_xfer_msg() call. We check here if the message
- * was correctly asynchronously transfered
+ * modest_mail_operation_xfer_msg() and
+ * modest_mail_operation_xfer_folder() calls. We check here if the
+ * message/folder was correctly asynchronously transferred. The reason
+ * to use the same callback is that the code is the same, it only has
+ * to check that the operation went fine and then finalize the drag
+ * and drop action
  */
 static void
 on_progress_changed (ModestMailOperation *mail_op, gpointer user_data)
 {
-       ModestMailOperationQueue *queue;
-       gboolean success = FALSE;
+       gboolean success;
        DndHelper *helper;
 
        helper = (DndHelper *) user_data;
 
+       if (!modest_mail_operation_is_finished (mail_op))
+               return;
+
        if (modest_mail_operation_get_status (mail_op) == 
            MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
                success = TRUE;
        } else {
-               const GError *error;
-               error = modest_mail_operation_get_error (mail_op);
-               g_warning ("Error transferring messages: %s\n", error->message);
+               success = FALSE;
        }
 
-       /* Remove the mail operation */ 
-       queue = modest_runtime_get_mail_operation_queue ();
-       modest_mail_operation_queue_remove (queue, mail_op);
-       g_object_unref (G_OBJECT (mail_op));
-
        /* Notify the drag source. Never call delete, the monitor will
           do the job if needed */
        gtk_drag_finish (helper->context, success, FALSE, helper->time);
@@ -818,9 +817,7 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
 {
        TnyHeader *header;
        TnyFolder *folder;
-       ModestMailOperationQueue *queue;
        ModestMailOperation *mail_op;
-       gboolean started;
        GtkTreeIter source_iter, dest_iter;
 
        /* Get header */
@@ -836,23 +833,13 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
                            &folder, -1);
 
        /* Transfer message */
-       queue = modest_runtime_get_mail_operation_queue ();
        mail_op = modest_mail_operation_new ();
-       started = modest_mail_operation_xfer_msg (mail_op, header,
-                                                 folder, helper->delete_source);
-       if (started) {
-               g_signal_connect (G_OBJECT (mail_op), "progress_changed",
-                                 G_CALLBACK (on_progress_changed), helper);
-               modest_mail_operation_queue_add (queue, mail_op);
-       } else {
-               const GError *error;
-               error = modest_mail_operation_get_error (mail_op);
-               if (error)
-                       g_warning ("Error trying to transfer messages: %s\n",
-                                  error->message);
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
+                                        mail_op);
+       g_signal_connect (G_OBJECT (mail_op), "progress-changed",
+                         G_CALLBACK (on_progress_changed), helper);
 
-               g_slice_free (DndHelper, helper);
-       }
+       modest_mail_operation_xfer_msg (mail_op, header, folder, helper->delete_source);
 
        /* Frees */
        g_object_unref (G_OBJECT (mail_op));
@@ -873,20 +860,21 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
                                DndHelper        *helper)
 {
        ModestMailOperation *mail_op;
-       const GError *error;
        GtkTreeIter parent_iter, iter;
-       TnyFolder *folder;
        TnyFolderStore *parent_folder;
-       gboolean success = FALSE;
+       TnyFolder *folder;
 
        /* Check if the drag is possible */
-       if (!gtk_tree_path_compare (helper->source_row, dest_row))
-               goto out;
-
-       if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (dest_model),
+       if (!gtk_tree_path_compare (helper->source_row, dest_row) ||
+           !gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (dest_model),
                                                   dest_row,
-                                                  selection_data))
-               goto out;
+                                                  selection_data)) {
+
+               gtk_drag_finish (helper->context, FALSE, FALSE, helper->time);
+               gtk_tree_path_free (helper->source_row);        
+               g_slice_free (DndHelper, helper);
+               return;
+       }
 
        /* Get data */
        gtk_tree_model_get_iter (source_model, &parent_iter, dest_row);
@@ -900,26 +888,20 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
 
        /* Do the mail operation */
        mail_op = modest_mail_operation_new ();
-       modest_mail_operation_xfer_folder (mail_op, folder, parent_folder, 
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
+                                        mail_op);
+       g_signal_connect (G_OBJECT (mail_op), "progress-changed",
+                         G_CALLBACK (on_progress_changed), helper);
+
+       modest_mail_operation_xfer_folder (mail_op, 
+                                          folder, 
+                                          parent_folder,
                                           helper->delete_source);
 
+       /* Frees */
        g_object_unref (G_OBJECT (parent_folder));
        g_object_unref (G_OBJECT (folder));
-
-       error = modest_mail_operation_get_error (mail_op);
-       if (error) {
-               g_warning ("Error transferring folder: %s\n", error->message);
-               g_object_unref (G_OBJECT (mail_op));
-               goto out;
-       }
        g_object_unref (G_OBJECT (mail_op));
-       success = TRUE;
- out:
-       gtk_drag_finish (helper->context, success, FALSE, helper->time);
-
-       /* Free the helper */
-       gtk_tree_path_free (helper->source_row);        
-       g_slice_free (DndHelper, helper);
 }
 
 /*
index 0cc2325..e6ddf2d 100644 (file)
@@ -631,40 +631,54 @@ modest_header_view_set_model (GtkTreeView *header_view, GtkTreeModel *model)
 }
 
 static void
-on_refresh_folder (TnyFolder   *folder, 
-                  gboolean     cancelled, 
-                  GError     **error,
-                  gpointer     user_data)
+on_progress_changed (ModestMailOperation *mail_op,
+                    ModestHeaderView *self)
 {
-       if (cancelled) {
-/*             GtkTreeSelection *selection; */
-/*             selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (user_data)); */
-/*             gtk_tree_selection_unselect_all (selection); */
-               g_warning ("Operation cancelled %s\n", (*error) ? (*error)->message : "unknown");
-               return;
-       }
-}
-
-
-static void
-on_refresh_folder_status_update (TnyFolder *folder, const gchar *msg,
-                                gint num, gint total,  gpointer user_data)
-{
-       ModestHeaderView *self;
+       GtkTreeModel *sortable; 
        ModestHeaderViewPrivate *priv;
+       GList *cols, *cursor;
+       TnyList *headers;
 
-       self = MODEST_HEADER_VIEW(user_data);
-       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+       if (!modest_mail_operation_is_finished (mail_op))
+               return;
 
-       /* FIXME: this is a hack ==> tinymail gives us this when
-        * it has nothing better to do */
-       if (num == 1 && total == 100)
+       if (modest_mail_operation_get_error (mail_op))
                return;
        
-       g_signal_emit (G_OBJECT(self), signals[STATUS_UPDATE_SIGNAL],
-                      0, msg, num, total);
-}
+       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+       headers = TNY_LIST (tny_gtk_header_list_model_new ());
 
+       tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
+                                             priv->folder, TRUE);
+
+       sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
+       g_object_unref (G_OBJECT (headers));
+
+       /* install our special sorting functions */
+       cursor = cols = gtk_tree_view_get_columns (GTK_TREE_VIEW(self));
+       while (cursor) {
+               gint col_id = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cursor->data),
+                                                                MODEST_HEADER_VIEW_COLUMN));
+               gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable),
+                                                col_id,
+                                                (GtkTreeIterCompareFunc) cmp_rows,
+                                                cursor->data, NULL);
+               cursor = g_list_next(cursor);
+       }
+       g_list_free (cols);
+
+       /* Set new model */
+       modest_header_view_set_model (GTK_TREE_VIEW (self), sortable);
+       g_object_unref (G_OBJECT (sortable));
+
+       /* Add a folder observer */
+       g_mutex_lock (priv->monitor_lock);
+       priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (priv->folder));
+       tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
+       tny_folder_monitor_start (priv->monitor);
+       g_mutex_unlock (priv->monitor_lock);
+}
 
 TnyFolder*
 modest_header_view_get_folder (ModestHeaderView *self)
@@ -731,6 +745,7 @@ void
 modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder)
 {
        ModestHeaderViewPrivate *priv;
+
        priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
 
        if (priv->folder) {
@@ -739,16 +754,31 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder)
        }
 
        if (folder) {
+               ModestMailOperation *mail_op;
+
                modest_header_view_set_folder_intern (self, folder);
+
+               /* Pick my reference. Nothing to do with the mail operation */
                priv->folder = g_object_ref (folder);
-               tny_folder_refresh_async (folder,
-                                         on_refresh_folder,
-                                         on_refresh_folder_status_update,
-                                         self);
 
                /* no message selected */
-               g_signal_emit (G_OBJECT(self), signals[HEADER_SELECTED_SIGNAL], 0,
-                              NULL);
+               g_signal_emit (G_OBJECT(self), signals[HEADER_SELECTED_SIGNAL], 0, NULL);
+
+               /* Create the mail operation */
+               mail_op = modest_mail_operation_new ();
+               modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                mail_op);
+
+               /* Register a mail operation observer */
+               g_signal_connect (mail_op, "progress-changed", 
+                                 G_CALLBACK (on_progress_changed), self);
+
+               /* Refresh the folder asynchronously */
+               modest_mail_operation_refresh_folder (mail_op, folder);
+
+               /* Free */
+               g_object_unref (mail_op);
+
        } else {
                g_mutex_lock (priv->monitor_lock);
                modest_header_view_set_model (GTK_TREE_VIEW (self), NULL); 
index 02df4db..79993f7 100644 (file)
@@ -88,8 +88,6 @@ typedef enum {
        MODEST_WIDGET_TYPE_HEADER_VIEW,
        MODEST_WIDGET_TYPE_FOLDER_VIEW,
        MODEST_WIDGET_TYPE_MSG_PREVIEW,
-       MODEST_WIDGET_TYPE_STATUS_BAR,
-       MODEST_WIDGET_TYPE_PROGRESS_BAR,
        
        MODEST_WIDGET_TYPE_NUM,
 } ModestWidgetType;