2007-07-09 Murray Cumming <murrayc@murrayc.com>
[modest] / src / maemo / modest-main-window.c
index 3c19dd0..6aaeb53 100644 (file)
 #include <tny-list.h>
 #include <tny-iterator.h>
 #include <tny-maemo-conic-device.h>
+#include <tny-error.h>
 #include "modest-hildon-includes.h"
 #include "modest-defs.h"
 #include <string.h>
-
+#include "widgets/modest-header-view-priv.h"
 #include "widgets/modest-main-window.h"
 #include "widgets/modest-msg-edit-window.h"
 #include "widgets/modest-account-view-window.h"
@@ -61,6 +62,7 @@
 #include "modest-text-utils.h"
 #include "modest-ui-dimming-manager.h"
 #include "maemo/modest-osso-state-saving.h"
+#include "modest-text-utils.h"
 
 #ifdef MODEST_HAVE_HILDON0_WIDGETS
 #include <hildon-widgets/hildon-program.h>
@@ -246,8 +248,8 @@ static const GtkActionEntry modest_header_view_action_entries [] = {
        { "HeaderViewCSMCut",           NULL,  N_("mcen_me_inbox_cut"),         "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
        { "HeaderViewCSMCopy",          NULL,  N_("mcen_me_inbox_copy"),        "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
        { "HeaderViewCSMPaste",         NULL,  N_("mcen_me_inbox_paste"),       "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
-       { "HeaderViewCSMDelete",        NULL,  N_("mcen_me_inbox_delete"),      NULL,      NULL, G_CALLBACK (modest_ui_actions_on_delete) },
-       { "HeaderViewCSMCancelSending", NULL,  N_("mcen_me_outbox_cancelsend"), NULL,      NULL, NULL },
+       { "HeaderViewCSMDelete",        NULL,  N_("mcen_me_inbox_delete"),      NULL,      NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
+       { "HeaderViewCSMCancelSending", NULL,  N_("mcen_me_outbox_cancelsend"), NULL,      NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
        { "HeaderViewCSMHelp",          NULL,  N_("mcen_me_inbox_help"),        NULL,      NULL, G_CALLBACK (modest_ui_actions_on_help) },
 };
 
@@ -441,61 +443,70 @@ wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
 }
 
 
-static gboolean
-on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
-{
-       modest_window_save_state (MODEST_WINDOW(self));
-       return FALSE;
-}
-
-typedef struct
-{
-       ModestMainWindow *self;
-       TnySendQueue *queue;
-       TnyHeader *header;
-} OnResponseInfo;
+/* static gboolean */
+/* on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self) */
+/* { */
+/*     modest_window_save_state (MODEST_WINDOW(self)); */
+/*     return FALSE; */
+/* } */
 
 static void
-on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
+on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
 {
-       OnResponseInfo *info = (OnResponseInfo *) user_data;
-       ModestMainWindow *self = info->self;
-       TnyHeader *header = info->header;
-       TnySendQueue *queue = info->queue;
-
-       if (arg1 == GTK_RESPONSE_YES) {
-               TnyFolder *outbox = tny_send_queue_get_outbox (queue);
-               tny_folder_remove_msg (outbox, header, NULL);
-               tny_folder_sync (outbox, TRUE, NULL);
-               g_object_unref (outbox);
+       if (err) {
+               printf ("DEBUG: %s: err->code=%d, err->message=%s\n", __FUNCTION__, err->code, err->message);
        }
 
-       g_object_unref (queue);
-       g_object_unref (header);
-       g_object_unref (self);
-
-       gtk_widget_destroy (GTK_WIDGET (dialog));
-       g_slice_free (OnResponseInfo, info);
-}
-
-
-static void
-on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
-{
-       if (header) {
-               gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
-                       err->message, tny_header_get_subject (header));
-               OnResponseInfo *info = g_slice_new (OnResponseInfo);
-               GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
-                       GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
-               g_free (str);
-               info->queue = g_object_ref (self);
-               info->self = g_object_ref (user_data);
-               info->header = g_object_ref (header);
-               g_signal_connect (G_OBJECT (dialog), "response",
-                       G_CALLBACK (on_response), info);
-               gtk_widget_show_all (dialog);
+       /* Get the account name: */
+       const gchar* server_name = NULL;
+       
+       TnyCamelTransportAccount* server_account = tny_camel_send_queue_get_transport_account (
+               TNY_CAMEL_SEND_QUEUE (self));
+       if (server_account) {
+               server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
+                       
+               g_object_unref (server_account);
+               server_account = NULL;
+       }
+       
+       if (!server_name)
+               server_name = _("Unknown Server");      
+
+       /* Show the appropriate message text for the GError: */
+       gchar *message = NULL;
+       if (err) {
+               switch (err->code) {
+                       case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
+                               message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
+                               break;
+                       case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
+                               message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
+                               break;
+                       case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
+                               /* TODO: This logical ID seems more suitable for a wrong username or password than for a 
+                                * wrong authentication method. The user is unlikely to guess at the real cause.
+                                */
+                               message = g_strdup_printf (_("eemev_ni_ui_smtp_authentication_fail_error"), server_name);
+                               break;
+                       case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
+                       default:
+                               message = g_strdup (_("emev_ib_ui_smtp_send_error"));
+                               break;
+               }
+       } else {
+               message = g_strdup (_("emev_ib_ui_smtp_send_error"));
        }
+       
+       modest_maemo_show_information_note_and_forget (GTK_WINDOW (user_data), message);
+       g_free (message);
+       
+       /* TODO: Offer to remove the message, to avoid messages in future? */
+       /*
+       TnyFolder *outbox = tny_send_queue_get_outbox (queue);
+       tny_folder_remove_msg (outbox, header, NULL);
+       tny_folder_sync (outbox, TRUE, NULL);
+       g_object_unref (outbox);
+       */
 }
 
 typedef struct {
@@ -653,7 +664,7 @@ connect_signals (ModestMainWindow *self)
                          self);
        
        /* window */
-       g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
+/*     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);
@@ -795,7 +806,8 @@ modest_main_window_new (void)
        GError *error = NULL;
        ModestConf *conf = NULL;
        GtkAction *action = NULL;
-
+       GdkPixbuf *window_icon;
+       
        self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
@@ -806,8 +818,8 @@ modest_main_window_new (void)
        action_group = gtk_action_group_new ("ModestMainWindowActions");
        gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
 
-       menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
-       toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
+       menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
+       toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
 
        /* Add common actions */
        gtk_action_group_add_actions (action_group,
@@ -892,6 +904,11 @@ modest_main_window_new (void)
        modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
                                      MODEST_CONF_HEADER_VIEW_KEY);
 
+       /* Other style properties of header view */
+       g_object_set (G_OBJECT (priv->header_view), 
+                     "rules-hint", FALSE,
+                     NULL);
+
        /* Empty view */ 
        priv->empty_view = create_empty_view ();
                 
@@ -926,6 +943,12 @@ modest_main_window_new (void)
        g_signal_connect (G_OBJECT(self), "show",
                          G_CALLBACK (modest_main_window_on_show), folder_win);
                
+       /* Set window icon */
+       window_icon = modest_platform_get_icon (MODEST_APP_ICON);
+       if (window_icon) {
+               gtk_window_set_icon (GTK_WINDOW (self), window_icon);
+               g_object_unref (window_icon);
+       }
 
        restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
 
@@ -1268,7 +1291,9 @@ on_account_update (TnyAccountStore *account_store,
                
                ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
 
-               /* Create display name. The default account is shown differently */
+               /* Create display name. The UI specification specifies a different format string 
+                * to use for the default account, though both seem to be "%s", so 
+                * I don't see what the point is. murrayc. */
                if (default_account && account_data->account_name && 
                        !(strcmp (default_account, account_data->account_name) == 0)) {
                        display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), 
@@ -1294,7 +1319,7 @@ on_account_update (TnyAccountStore *account_store,
                        /* Add ui from account data. We allow 2^9-1 account
                           changes in a single execution because we're
                           downcasting the guint to a guint8 in order to use a
-                          GByteArray, it should be enough */
+                          GByteArray. It should be enough. */
                        item_name = g_strconcat (account_data->account_name, "Menu", NULL);
                        merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
                        priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
@@ -1526,10 +1551,15 @@ create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
        /* Size / Date */
        if (modest_tny_account_is_virtual_local_folders (account)
                || modest_tny_account_is_memory_card_account (account)) {
-               /* FIXME: format size */
-               label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
-                                                gray_color_markup, _("mcen_fi_rootfolder_size"), 
-                                                modest_tny_folder_store_get_local_size (folder_store));
+
+               gchar *size = modest_text_utils_get_display_size (
+                       modest_tny_folder_store_get_local_size (folder_store));
+               
+               label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
+                                                gray_color_markup, _("mcen_fi_rootfolder_size"),
+                                                size);
+               g_free (size);
+               
                label_w = gtk_label_new (NULL);
                gtk_label_set_markup (GTK_LABEL (label_w), label);
                gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
@@ -1947,7 +1977,7 @@ on_queue_changed (ModestMailOperationQueue *queue,
        /* Get toolbar mode from operation id*/
        op_type = modest_mail_operation_get_type_operation (mail_op);
        switch (op_type) {
-       case MODEST_MAIL_OPERATION_TYPE_SEND:
+/*     case MODEST_MAIL_OPERATION_TYPE_SEND: */
        case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
        case MODEST_MAIL_OPERATION_TYPE_OPEN:
                mode = TOOLBAR_MODE_TRANSFER;
@@ -2068,6 +2098,14 @@ on_folder_view_focus_in (GtkWidget *widget,
                         GdkEventFocus *event,
                         gpointer userdata)
 {
+       ModestMainWindow *main_window = NULL;
+       
+       g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
+       main_window = MODEST_MAIN_WINDOW (userdata);
+       
+       /* Update toolbar dimming state */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
+
        return FALSE;
 }
 
@@ -2076,8 +2114,12 @@ on_header_view_focus_in (GtkWidget *widget,
                         GdkEventFocus *event,
                         gpointer userdata)
 {
-       ModestMainWindow *main_window = MODEST_MAIN_WINDOW (userdata);
-       ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
+       ModestMainWindow *main_window = NULL;
+       ModestMainWindowPrivate *priv = NULL;
+
+       g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
+       main_window = MODEST_MAIN_WINDOW (userdata);
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
 
        if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
                TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
@@ -2096,6 +2138,11 @@ on_header_view_focus_in (GtkWidget *widget,
                g_object_unref (iterator);
                g_object_unref (selection);
        }
+
+
+       /* Update toolbar dimming state */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
+
        return FALSE;
 }
 
@@ -2166,3 +2213,32 @@ modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
        modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
 
 }
+
+gboolean 
+modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
+                                                  GtkTreeModel *model,
+                                                  GtkTreeRowReference *row_reference,
+                                                  ModestMainWindow *self)
+{
+       ModestMainWindowPrivate *priv = NULL;
+       GtkTreeModel *header_model = NULL;
+       GtkTreePath *path = NULL;
+
+       g_return_val_if_fail (MODEST_MSG_VIEW_WINDOW (view_window), FALSE);
+       g_return_val_if_fail (MODEST_MAIN_WINDOW (self), FALSE);
+       g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
+
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
+       header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
+
+       /* Do nothing if we changed the folder in the main view */
+       if (header_model != model)
+               return FALSE;
+
+       /* Select the message in the header view */
+       path = gtk_tree_row_reference_get_path (row_reference);
+       _modest_header_view_select_from_path (MODEST_HEADER_VIEW (priv->header_view), path);
+       gtk_tree_path_free (path);
+
+       return TRUE;
+}