* Rewritten main window title handling
[modest] / src / maemo / modest-main-window.c
index c4d2559..54b0437 100644 (file)
 #include <glib/gi18n.h>
 #include <gtk/gtktreeviewcolumn.h>
 #include <tny-account-store-view.h>
-#include <modest-runtime.h>
-#include <string.h>
+#include <tny-simple-list.h>
 
-#include <widgets/modest-main-window.h>
-#include <widgets/modest-msg-edit-window.h>
-#include <widgets/modest-account-view-window.h>
+#include <string.h>
 
+#include "widgets/modest-main-window.h"
+#include "widgets/modest-msg-edit-window.h"
+#include "widgets/modest-account-view-window.h"
+#include "modest-runtime.h"
+#include "modest-account-mgr-helpers.h"
 #include "modest-platform.h"
 #include "modest-widget-memory.h"
 #include "modest-window-priv.h"
@@ -64,10 +66,17 @@ static void connect_signals (ModestMainWindow *self);
 static void restore_sizes (ModestMainWindow *self);
 static void save_sizes (ModestMainWindow *self);
 
-static void modest_main_window_create_toolbar (ModestWindow *window);
 static void modest_main_window_show_toolbar   (ModestWindow *window,
                                               gboolean show_toolbar);
 
+static void on_account_update                 (TnyAccountStore *account_store, 
+                                              gchar *account_name,
+                                              gpointer user_data);
+
+static gboolean on_inner_widgets_key_pressed  (GtkWidget *widget,
+                                              GdkEventKey *event,
+                                              gpointer user_data);
+
 /* list my signals */
 enum {
        /* MY_SIGNAL_1, */
@@ -80,7 +89,7 @@ struct _ModestMainWindowPrivate {
        GtkWidget *msg_paned;
        GtkWidget *main_paned;
        GtkWidget *main_vbox;
-       GtkWidget *progress_bar;
+       GtkWidget *accounts_popup;
 
        ModestHeaderView *header_view;
        ModestFolderView *folder_view;
@@ -143,43 +152,11 @@ modest_main_window_class_init (ModestMainWindowClass *klass)
        parent_class            = g_type_class_peek_parent (klass);
        gobject_class->finalize = modest_main_window_finalize;
 
-       modest_window_class->create_toolbar_func = modest_main_window_create_toolbar;
        modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
 
        g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
 }
 
-
-static void
-on_key_changed (ModestConf* conf, const gchar *key, ModestConfEvent event, ModestMainWindow *win)
-{
-       TnyAccount *account;
-       
-       if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME) != 0)
-               return; /* wrong key */
-       
-       /* ok, the device name changed; thus, we have to update the
-        * local folder account name*/
-       account =
-               modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
-                                                                    MODEST_LOCAL_FOLDERS_ACCOUNT_ID,
-                                                                    TNY_ACCOUNT_TYPE_STORE);
-       if (!account) {
-               g_printerr ("modest: could not get account\n");
-               return;
-       }
-
-       if (event == MODEST_CONF_EVENT_KEY_UNSET) 
-               tny_account_set_name (account, MODEST_LOCAL_FOLDERS_DEFAULT_DISPLAY_NAME);
-       else {
-               gchar *device_name = modest_conf_get_string (modest_runtime_get_conf(),
-                                                            MODEST_CONF_DEVICE_NAME, NULL);
-               tny_account_set_name (account, device_name);
-               g_free (device_name);
-       }
-       g_object_unref (G_OBJECT(account));     
-}
-
 static void
 modest_main_window_init (ModestMainWindow *obj)
 {
@@ -192,13 +169,8 @@ modest_main_window_init (ModestMainWindow *obj)
        priv->main_vbox    = NULL;
        priv->header_view  = NULL;
        priv->folder_view  = NULL;
+       priv->accounts_popup  = NULL;
        priv->style  = MODEST_MAIN_WINDOW_STYLE_SPLIT;
-
-       /* 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);
 }
 
 static void
@@ -307,8 +279,12 @@ connect_signals (ModestMainWindow *self)
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
        
        /* folder view */
+       g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
+                         G_CALLBACK(on_inner_widgets_key_pressed), self);
        g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
                          G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
+       g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
+                         G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
 
        menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewContextMenu");
        gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
@@ -322,23 +298,21 @@ connect_signals (ModestMainWindow *self)
                          G_CALLBACK(modest_ui_actions_on_header_activated), self);
        g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
                          G_CALLBACK(modest_ui_actions_on_item_not_found), self);
+       g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
+                         G_CALLBACK(on_inner_widgets_key_pressed), self);
 
        /* window */
        g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
        g_signal_connect (G_OBJECT (self), "window-state-event",
                          G_CALLBACK (modest_main_window_window_state_event),
                          NULL);
-
-
-       
-       /* modest_maemo_utils_get_device_name will probably change
-        * MODEST_CONF_DEVICE_NAME. If that happens, we update the local folders
-        * account name in the callback
-        */
-       g_signal_connect (G_OBJECT(modest_runtime_get_conf()), "key_changed",
-                         G_CALLBACK(on_key_changed), self);
-       
        g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
+
+       /* Track account changes. We need to refresh the toolbar */
+       g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
+                         "account_update",
+                         G_CALLBACK (on_account_update),
+                         self);
 }
 
 
@@ -513,6 +487,7 @@ modest_main_window_set_style (ModestMainWindow *self,
 
                /* Reparent header view with scrolled window */
                gtk_widget_reparent (scrolled_win, priv->main_vbox);
+
                break;
        case MODEST_MAIN_WINDOW_STYLE_SPLIT:
                /* Remove header view */
@@ -527,6 +502,9 @@ modest_main_window_set_style (ModestMainWindow *self,
                g_return_if_reached ();
        }
 
+       /* Let header view grab the focus */
+       gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
+
        /* Show changes */
        gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
 }
@@ -578,44 +556,171 @@ set_homogeneous (GtkWidget *widget,
 }
 
 static void 
-modest_main_window_create_toolbar (ModestWindow *self)
+modest_main_window_show_toolbar (ModestWindow *self,
+                                gboolean show_toolbar)
 {
-       GtkWidget *reply_button, *menu;
        ModestWindowPrivate *parent_priv;
+       GtkWidget *reply_button = NULL, *menu = NULL;
        
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
-       
-       /* Toolbar */
-       parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
-                                                         "/ToolBar");
-
-       /* Set homogeneous toolbar */
-       gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
-                              set_homogeneous, NULL);
-
-       /* Set reply button tap and hold menu */
-       reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
-                                                 "/ToolBar/ToolbarMessageReply");
-       menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolbarReplyContextMenu");
-       gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
+
+       if (!parent_priv->toolbar && show_toolbar) {
+               parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
+                                                                 "/ToolBar");
+
+               /* Set homogeneous toolbar */
+               gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
+                                      set_homogeneous, NULL);
+
+               /* Add to window */
+               hildon_window_add_toolbar (HILDON_WINDOW (self), 
+                                          GTK_TOOLBAR (parent_priv->toolbar));
+
+               /* Set reply button tap and hold menu */
+               reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
+                                                         "/ToolBar/ToolbarMessageReply");
+               menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
+                                                 "/ToolbarReplyContextMenu");
+               gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
+
+               /* Set send & receive button tap and hold menu */
+               on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
+                                  NULL, self);
+       }
+
+
+       if (show_toolbar)
+               gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
+       else
+               gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
 }
 
+/*
+ * TODO: modify the menu dinamically. Add handlers to each item of the
+ * menu when created
+ */
 static void 
-modest_main_window_show_toolbar (ModestWindow *self,
-                                gboolean show_toolbar)
+on_account_update (TnyAccountStore *account_store, 
+                  gchar *accout_name,
+                  gpointer user_data)
 {
+       ModestMainWindow *self;
+       ModestMainWindowPrivate *priv;
        ModestWindowPrivate *parent_priv;
-       
-       parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
+       TnyList *account_list;
+       GtkWidget *item, *send_receive_button;
+       TnyIterator *iter;
+       ModestAccountMgr *mgr;
+       gchar *default_account;
 
+       self = MODEST_MAIN_WINDOW (user_data);
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
+       parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
+
+       /* If there is no toolbar then exit */
        if (!parent_priv->toolbar)
                return;
 
-       if (show_toolbar) {
-               hildon_window_add_toolbar (HILDON_WINDOW (self), 
-                                          GTK_TOOLBAR (parent_priv->toolbar));
-               gtk_widget_show_all (GTK_WIDGET (self));
-       } else
-               hildon_window_remove_toolbar (HILDON_WINDOW (self),
-                                             GTK_TOOLBAR (parent_priv->toolbar));
+       if (priv->accounts_popup)
+               gtk_menu_detach (GTK_MENU (priv->accounts_popup));
+
+       /* Get accounts */
+       account_list = tny_simple_list_new ();
+       tny_account_store_get_accounts (account_store, 
+                                       account_list, 
+                                       TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
+
+       /* If there is only one account do not show any menu */
+       if (tny_list_get_length (account_list) <= 1)
+               goto free;
+       
+       /* Get send receive button */
+       send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
+                                                         "/ToolBar/ToolbarSendReceive");
+
+       /* Create the menu */
+       priv->accounts_popup = gtk_menu_new ();
+       item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
+       gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+       item = gtk_separator_menu_item_new ();
+       gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+
+       iter = tny_list_create_iterator (account_list);
+       mgr = modest_runtime_get_account_mgr ();
+       default_account = modest_account_mgr_get_default_account (mgr);
+
+       do {
+               TnyAccount *acc;
+               const gchar *acc_name;
+               gchar *display_name;
+
+               /* Create tool item */
+               acc = TNY_ACCOUNT (tny_iterator_get_current (iter));
+               acc_name = tny_account_get_name (acc);
+
+               /* Create display name */
+               if (!strcmp (default_account, acc_name))
+                       display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), acc_name);
+               else
+                       display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"), acc_name);
+
+               item = gtk_menu_item_new_with_label (display_name);
+
+               /* Free */
+               g_free (display_name);
+               g_object_unref (acc);
+
+               /* Append item */
+               gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+
+               /* Go to next */
+               tny_iterator_next (iter);
+
+       } while (!tny_iterator_is_done (iter));
+
+       g_object_unref (iter);
+
+       /* Mandatory in order to view the menu contents */
+       gtk_widget_show_all (priv->accounts_popup);
+
+       /* Setup tap_and_hold */
+       gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
+
+ free:
+
+       /* Free */
+       g_object_unref (account_list);
+}
+
+/* 
+ * This function manages the key events used to navigate between
+ * header and folder views (when the window is in split view)
+ *
+ * FROM         KEY        ACTION
+ * -------------------------------------------------
+ * HeaderView   GDK_Left   Move focus to folder view
+ * FolderView   GDK_Right  Move focus to header view
+ *
+ * There is no need to scroll to selected row, the widgets will be the
+ * responsibles of doing that (probably managing the focus-in event
+ */
+static gboolean 
+on_inner_widgets_key_pressed (GtkWidget *widget,
+                             GdkEventKey *event,
+                             gpointer user_data)
+{
+       ModestMainWindowPrivate *priv;
+
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
+
+       /* Do nothing if we're in SIMPLE style */
+       if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
+               return FALSE;
+
+       if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
+               gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
+       else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
+               gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
+
+       return FALSE;
 }