* Fixed modest_text_utils_get_display_address, now the original string is not modifi...
authorSergio Villar Senin <svillar@igalia.com>
Mon, 15 Oct 2007 11:48:03 +0000 (11:48 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Mon, 15 Oct 2007 11:48:03 +0000 (11:48 +0000)
* Added notification removal support
* Added notification grouping support
* Replaced the old modest_platform_on_new_header_received by modest_platform_on_new_headers_received
* Fixed ModestConf's set_list method

pmo-trunk-r3505

src/gnome/modest-platform.c
src/maemo/modest-platform.c
src/modest-conf.c
src/modest-defs.h
src/modest-main.c
src/modest-platform.h
src/modest-text-utils.c
src/modest-text-utils.h
src/modest-ui-actions.c
src/widgets/modest-header-view-render.c

index fd191dc..2f62ecc 100644 (file)
@@ -216,8 +216,9 @@ modest_platform_get_global_settings_dialog ()
        return modest_gnome_global_settings_dialog_new ();
 }
 
+
 void 
-modest_platform_on_new_header_received (TnyHeader *header)
+modest_platform_on_new_headers_received (TnyList *header_list)
 {
        /* TODO: implement this */
        g_print ("--------------- NEW MESSAGE ARRIVED ---------------\n");
index 5f32af6..a07ce84 100644 (file)
 #define HILDON_OSSO_URI_ACTION "uri-action"
 #define URI_ACTION_COPY "copy:"
 
+/* The maximun number of notifications that could be shown in the
+   desktop. It's specified by the specs and limited by the screen
+   size */
+#define MAX_NOTIFICATIONS 6
+
 static osso_context_t *osso_context = NULL;
 
 static void    
@@ -1215,71 +1220,146 @@ modest_platform_set_update_interval (guint minutes)
        return TRUE;
 }
 
-GtkWidget * 
-modest_platform_get_global_settings_dialog ()
-{
-       return modest_maemo_global_settings_dialog_new ();
-}
-
 void 
-modest_platform_on_new_header_received (TnyHeader *header)
+modest_platform_on_new_headers_received (TnyList *header_list) 
 {
 #ifdef MODEST_HAVE_HILDON_NOTIFY
        HildonNotification *notification;
-       gchar *url = NULL;
-       TnyFolder *folder = NULL;
-       const gchar *subject;
-
-       subject = tny_header_get_subject (header);
-       if (!subject || strlen(subject) == 0)
-               subject = _("mail_va_no_subject");
+       TnyIterator *iter;
+       GSList *notifications_list = NULL;
+
+       /* Get previous notifications ids */
+       notifications_list = modest_conf_get_list (modest_runtime_get_conf (), 
+                                                  MODEST_CONF_NOTIFICATION_IDS, 
+                                                  MODEST_CONF_VALUE_INT, NULL);
+
+       iter = tny_list_create_iterator (header_list);
+       while (!tny_iterator_is_done (iter)) {
+               gchar *url = NULL, *display_address = NULL, *display_date = NULL, *summary = NULL;
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+               TnyFolder *folder = tny_header_get_folder (header);
+               gboolean first_notification = TRUE;
+               gint notif_id;
        
-       notification = hildon_notification_new (tny_header_get_from (header),
-                                               subject,
-                                               "qgn_list_messagin",
-                                               NULL);
-
-       folder = tny_header_get_folder (header);
-       url = g_strdup_printf ("%s/%s", 
-                              tny_folder_get_url_string (folder), 
-                              tny_header_get_uid (header));
-       g_object_unref (folder);
-
-       hildon_notification_add_dbus_action(notification,
-                                           "default",
-                                           "Cancel",
-                                           MODEST_DBUS_SERVICE,
-                                           MODEST_DBUS_OBJECT,
-                                           MODEST_DBUS_IFACE,
-                                           MODEST_DBUS_METHOD_OPEN_MESSAGE,
-                                           G_TYPE_STRING, url,
-                                           -1);
-       g_free (url);
+               display_date = modest_text_utils_get_display_date (tny_header_get_date_received (header));
+               display_address = modest_text_utils_get_display_address (tny_header_get_from (header));
+               summary = g_strdup_printf ("%s - %s", display_date, display_address);
+               notification = hildon_notification_new (summary,
+                                                       tny_header_get_subject (header),
+                                                       "qgn_list_messagin",
+                                                       "email.arrive");
+               
+               /* Create the message URL */
+               url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder), 
+                                      tny_header_get_uid (header));
+
+               hildon_notification_add_dbus_action(notification,
+                                                   "default",
+                                                   "Cancel",
+                                                   MODEST_DBUS_SERVICE,
+                                                   MODEST_DBUS_OBJECT,
+                                                   MODEST_DBUS_IFACE,
+                                                   MODEST_DBUS_METHOD_OPEN_MESSAGE,
+                                                   G_TYPE_STRING, url,
+                                                   -1);
+
+               /* Play sound if the user wants. Show the LED
+                  pattern. Show and play just one */
+               if (G_UNLIKELY (first_notification)) {
+                       first_notification = FALSE;
+                       if (modest_conf_get_bool (modest_runtime_get_conf (),
+                                                 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE,
+                                                 NULL))  {
+                               notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
+                                                                   "sound-file", "/usr/share/sounds/ui-new_email.wav");
+                       }
+
+                       /* Set the led pattern */
+                       notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
+                                                           "dialog-type", 4);
+                       notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
+                                                           "led-pattern",
+                                                           "PatternCommunicationEmail");                       
+               }
+
+               /* Notify. We need to do this in an idle because this function
+                  could be called from a thread */
+               notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
+
+               /* Save id in the list */
+               g_object_get(G_OBJECT(notification), "id", &notif_id, NULL);
+               notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
+               /* We don't listen for the "closed" signal, because we
+                  don't care about if the notification was removed or
+                  not to store the list in gconf */
        
-       /* Play sound if the user wants */
-       if (modest_conf_get_bool (modest_runtime_get_conf (), 
-                                 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE, 
-                                 NULL)) {
-               hildon_notification_set_sound (HILDON_NOTIFICATION(notification),
-                                              "/usr/share/sounds/ui-new_email.wav");
+               /* Free & carry on */
+               g_free (display_date);
+               g_free (display_address);
+               g_free (summary);
+               g_free (url);
+               g_object_unref (folder);
+               g_object_unref (header);
+               tny_iterator_next (iter);
        }
+       g_object_unref (iter);
+
+       /* Save the ids */
+       modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS, 
+                             notifications_list, MODEST_CONF_VALUE_INT, NULL);
+
+       g_slist_free (notifications_list);
        
-       /* Set the led pattern */
-       notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION(notification),
-                                           "dialog-type", 4);
-       notify_notification_set_hint_string(NOTIFY_NOTIFICATION(notification), 
-                                           "led-pattern", 
-                                           "PatternCommunicationEmail");
-
-       /* Notify. We need to do this in an idle because this function
-          could be called from a thread */
-       if (!notify_notification_show (NOTIFY_NOTIFICATION(notification), NULL))
-               g_error ("Failed to send notification");
-       
-       g_object_unref (notification);
 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
 }
 
+void
+modest_platform_remove_new_mail_notifications (void) 
+{
+#ifdef MODEST_HAVE_HILDON_NOTIFY
+       GSList *notif_list = NULL;
+
+       /* Get previous notifications ids */
+       notif_list = modest_conf_get_list (modest_runtime_get_conf (), 
+                                          MODEST_CONF_NOTIFICATION_IDS, 
+                                          MODEST_CONF_VALUE_INT, NULL);
+
+        while (notif_list) {
+               gint notif_id;
+               NotifyNotification *notif;
+
+               /* Nasty HACK to remove the notifications, set the id
+                  of the existing ones and then close them */
+               notif_id = GPOINTER_TO_INT(notif_list->data);
+               notif = notify_notification_new("dummy", NULL, NULL, NULL);
+               g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
+
+               /* Close the notification, note that some ids could be
+                  already invalid, but we don't care because it does
+                  not fail */
+               notify_notification_close(notif, NULL);
+               g_object_unref(notif);
+
+               /* Delete the link, it's like going to the next */
+               notif_list = g_slist_delete_link (notif_list, notif_list);
+        }
+
+       /* Save the ids */
+       modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS, 
+                             notif_list, MODEST_CONF_VALUE_INT, NULL);
+
+       g_slist_free (notif_list);
+
+#endif /* MODEST_HAVE_HILDON_NOTIFY */
+}
+
+
+
+GtkWidget * 
+modest_platform_get_global_settings_dialog ()
+{
+       return modest_maemo_global_settings_dialog_new ();
+}
 
 void
 modest_platform_show_help (GtkWindow *parent_window, 
index 90946b9..e8fc818 100644 (file)
@@ -309,7 +309,6 @@ modest_conf_set_list (ModestConf* self, const gchar* key,
 {
        ModestConfPrivate *priv;
        GConfValueType gconf_type;
-       gboolean result;
        
        g_return_val_if_fail (self, FALSE);
        g_return_val_if_fail (key, FALSE);
@@ -317,31 +316,8 @@ modest_conf_set_list (ModestConf* self, const gchar* key,
        priv = MODEST_CONF_GET_PRIVATE(self);
 
        gconf_type = modest_conf_type_to_gconf_type (list_type, err);
-       if (*err)
-               return FALSE;
 
-       result = gconf_client_set_list (priv->gconf_client, key, gconf_type, val, err);
-       if(*err) {
-               g_warning("gconf_client_set_list() failed with key=%s. error=%s", key,
-                         (*err)->message);
-               result = FALSE;
-       }
-       
-       /* TODO: Remove this, when we fix the problem: */
-       /* This shows that sometimes set_list fails, while saying that it succeeded: */
-       if (result) {
-               const gint debug_list_length_start = g_slist_length(val);
-               GSList* debug_list = gconf_client_get_list(priv->gconf_client, key, gconf_type, err);
-               const gint debug_list_length_after = g_slist_length(debug_list);
-              
-               if(debug_list_length_start != debug_list_length_after)
-                       g_warning("modest_conf_set_list(): The list length after setting is "
-                                 "not the same as the specified list. key=%s. "
-                                 "We think that we fixed this, so tell us if you see this.", key);
-               g_slist_free(debug_list);
-       }
-       
-       return result;
+       return gconf_client_set_list (priv->gconf_client, key, gconf_type, val, err);
 }
 
 
index 740d849..e584fd5 100644 (file)
 #define MODEST_CONF_REPLY_TYPE           MODEST_CONF_NAMESPACE "/reply_type"        /*  int  */
 #define MODEST_CONF_FORWARD_TYPE         MODEST_CONF_NAMESPACE "/forward_type"      /*  int  */
 
+/* Notification ids */
+#define MODEST_CONF_NOTIFICATION_IDS MODEST_CONF_NAMESPACE "/notification_ids"      /* list of ints */
+
 #endif /*__MODEST_DEFS_H__*/
index 9bb9588..4ca4f15 100644 (file)
@@ -32,6 +32,7 @@
 #include <glib.h>
 #include <modest-runtime.h>
 #include <modest-init.h>
+#include "modest-platform.h"
 #include <gdk/gdk.h>
 #include <widgets/modest-main-window.h>
 #include <string.h>
@@ -84,14 +85,21 @@ main (int argc, char *argv[])
         * The UI will be shown later (or just after starting if no otehr D-Bus method was used),
         * when we receive the "top_application" D-Bus method.
         */
-       if (show_ui_without_top_application_method)
+       if (show_ui_without_top_application_method) {
                gtk_widget_show_all (GTK_WIDGET(win));
+
+               /* Remove new mail notifications if exist */
+               modest_platform_remove_new_mail_notifications ();
+       }
        
        gtk_main ();
 
 cleanup:
        gdk_threads_leave ();
 
+       /* Remove new mail notifications if exist */
+/*     modest_platform_remove_new_mail_notifications (); */
+
        if (!modest_init_uninit ()) {
                g_printerr ("modest: modest_init_uninit failed\n");
                retval = 1;
index e1f35ba..e9715b5 100644 (file)
@@ -275,8 +275,14 @@ gboolean modest_platform_set_update_interval (guint minutes);
  **/
 GtkWidget* modest_platform_get_global_settings_dialog (void);
 
-void modest_platform_on_new_header_received (TnyHeader *header);
-
+/**
+ * modest_platform_on_new_headers_received:
+ * @header_list: the list of new received headers
+ *
+ * Performs the required actions when new headers are
+ * received. Tipically it's useful for showing new email notifications
+ **/
+void modest_platform_on_new_headers_received (TnyList *header_list);
 
 /**
  * modest_platform_show_help:
@@ -367,6 +373,13 @@ gboolean modest_platform_run_certificate_conformation_dialog (const gchar* serve
 gboolean modest_platform_run_alert_dialog (const gchar* prompt, gboolean is_question);
 
 
+/**
+ * modest_platform_remove_new_mail_notifications:
+ *
+ * Removes all the active new mail notifications
+ **/
+void modest_platform_remove_new_mail_notifications (void);
+
 G_END_DECLS
 
 #endif /* __MODEST_PLATFORM_UTILS_H__ */
index 8a83e60..9bf3de2 100644 (file)
@@ -953,36 +953,35 @@ hyperlinkify_plain_text (GString *txt)
 }
 
 
-
 gchar*
-modest_text_utils_get_display_address (gchar *address)
+modest_text_utils_get_display_address (const gchar *address)
 {
-       gchar *cursor;
+       gchar *display;
+       gchar **tokens;
+       gint i = 0;
        
        if (!address)
                return NULL;
-       
+
        g_return_val_if_fail (g_utf8_validate (address, -1, NULL), NULL);
        
-       g_strchug (address); /* remove leading whitespace */
+       tokens = g_strsplit_set ((const gchar*) address, "<>()", 3);
 
-       /*  <email@address> from display name */
-       cursor = g_strstr_len (address, strlen(address), "<");
-       if (cursor == address) /* there's nothing else? leave it */
-               return address;
-       if (cursor) 
-               cursor[0]='\0';
+       /* Note that if any of the delimiters is the first character
+          then g_strsplit_set will return "" as the first string */
+       while (tokens[i] != NULL) {
+               if (strlen ((char *) (tokens[i])) != 0)
+                       break;
+               i++;
+       }
 
-       /* remove (bla bla) from display name */
-       cursor = g_strstr_len (address, strlen(address), "(");
-       if (cursor == address) /* there's nothing else? leave it */
-               return address;
-       if (cursor) 
-               cursor[0]='\0';
+       display = g_strdup (tokens [i]);
+       g_strchug (display);
 
-       g_strchomp (address); /* remove trailing whitespace */
+       /* Free the other tokens */
+       g_strfreev (tokens);
 
-       return address;
+       return display;
 }
 
 gchar *
index f39dfc2..c51499b 100644 (file)
@@ -41,6 +41,7 @@
 #define _FM(str) dgettext("hildon-fm",str)
 #define _CS(str) dgettext("hildon-common-strings",str)
 #define _HL(str) dgettext("hildon-libs",str)
+#define _MD(str) dgettext("maemo-af-desktop",str)
 
 /* Forbidden char arrays */
 extern const gchar account_title_forbidden_chars[];
@@ -203,13 +204,10 @@ size_t modest_text_utils_strftime(char *s, size_t max, const char  *fmt, time_t
  * ie. removes "<...>" and "(...)" parts
  * the change is in-place; removes leading/trailing whitespace
  * 
- * Returns: the new address of the string; this new string
- * is _NOT_ newly allocated, so should not be freed. (remember
- * the old address of the parameter if that one needs to be freed)
- * 
- * NULL in case of error or if address == NULL
+ * Returns: a new allocated string with the display address. NULL in
+ * case of error or if address == NULL
  */
-gchar* modest_text_utils_get_display_address (gchar *address);
+gchar* modest_text_utils_get_display_address (const gchar *address);
 
 /**
  * modest_text_utils_get_email_address:
index 13e4ee9..e4798cf 100644 (file)
@@ -1629,19 +1629,8 @@ new_messages_arrived (ModestMailOperation *self,
        }       
 
        /* Notify new messages have been downloaded */
-       if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
-               TnyIterator *iter = tny_list_create_iterator (new_headers);
-               do {
-                       TnyHeader *header =  NULL;
-
-                       header = TNY_HEADER (tny_iterator_get_current (iter));
-                       modest_platform_on_new_header_received (header);
-                       g_object_unref (header);
-
-                       tny_iterator_next (iter);
-               } while (!tny_iterator_is_done (iter));
-               g_object_unref (iter);
-       }
+       if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
+               modest_platform_on_new_headers_received (new_headers);
 }
 
 /*
index 019ab32..2f8b599 100644 (file)
@@ -257,11 +257,14 @@ _modest_header_view_date_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer
 }
 
 void
-_modest_header_view_sender_receiver_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
-                           GtkTreeModel *tree_model,  GtkTreeIter *iter,  gboolean is_sender)
+_modest_header_view_sender_receiver_cell_data  (GtkTreeViewColumn *column,  
+                                               GtkCellRenderer *renderer,
+                                               GtkTreeModel *tree_model,  
+                                               GtkTreeIter *iter,  
+                                               gboolean is_sender)
 {
        TnyHeaderFlags flags;
-       gchar *address;
+       gchar *address, *display_address;
        gint sender_receiver_col;
 
        if (is_sender)
@@ -274,10 +277,12 @@ _modest_header_view_sender_receiver_cell_data  (GtkTreeViewColumn *column,  GtkC
                            TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
                            -1);
        
+       display_address = modest_text_utils_get_display_address (address);
        g_object_set (G_OBJECT(renderer),
                      "text",
-                     modest_text_utils_get_display_address (address),
+                     display_address,
                      NULL);
+       g_free (display_address);
        g_free (address);
        set_common_flags (renderer, flags);
 }
@@ -300,7 +305,7 @@ _modest_header_view_compact_header_cell_data  (GtkTreeViewColumn *column,  GtkCe
        
        TnyHeaderFlags flags = 0;
        TnyHeaderFlags prior_flags = 0;
-       gchar *address = NULL;
+       gchar *address = NULL, *display_address;
        gchar *subject = NULL;
        gchar *header = NULL;
        time_t date = 0;
@@ -371,10 +376,12 @@ _modest_header_view_compact_header_cell_data  (GtkTreeViewColumn *column,  GtkCe
 
        /* FIXME: we hardcode the color to #666666; instead we should use SecondaryTextColour from the
         * theme (gtkrc file) */
+       display_address = modest_text_utils_get_display_address (address);
        header = g_markup_printf_escaped ("<span size='small' foreground='#666666'>%s</span>",
-                                         modest_text_utils_get_display_address (address));
+                                         display_address);
+       g_free (display_address);
        g_free (address);
-       address = NULL;
+       address = display_address = NULL;
        g_object_set (G_OBJECT (recipient_cell),
                      "markup", header,
                      NULL);