[maemo-commits] [maemo-commits] r12642 - in projects/haf/trunk/hildon-desktop: . data libhildondesktop src

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Wed Jul 4 14:31:55 EEST 2007
Author: lucasr
Date: 2007-07-04 14:31:30 +0300 (Wed, 04 Jul 2007)
New Revision: 12642

Added:
   projects/haf/trunk/hildon-desktop/data/notification-groups.conf
Modified:
   projects/haf/trunk/hildon-desktop/ChangeLog
   projects/haf/trunk/hildon-desktop/data/Makefile.am
   projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c
   projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h
   projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.c
   projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.h
   projects/haf/trunk/hildon-desktop/src/hd-switcher-menu.c
Log:
2007-07-04  Lucas Rocha  <lucas.rocha at nokia.com>

	* data/Makefile.am, data/notification-groups.conf: new notification
	grouping configuration file.
	* libhildondesktop/hildon-desktop-notification-manager.[ch]
	(hildon_desktop_notification_manager_call_dbus_callback): new method
	to send a dbus message from a string description. This is used by the
	notification group menu item to make the dbus call for the group.
	* src/hd-switcher-menu-item.[ch] (hd_switcher_menu_item_finalize,
	hd_switcher_menu_item_set_property, hd_switcher_menu_item_get_property,
	hd_switcher_menu_item_constructor, hd_switcher_menu_item_activate,
	hd_switcher_menu_item_button_release_event, 
	hd_switcher_menu_item_class_init, hd_switcher_menu_item_init,
	hd_switcher_menu_item_new_from_notification_group,
	hd_switcher_menu_item_compare_ids, hd_switcher_menu_item_has_id):
	new type of HDSwitcherMenuItem for notification group items.
	* src/hd-switcher-menu.c (hd_switcher_menu_free_notification_group,
	hd_switcher_menu_add_notification_group,
	hd_switcher_menu_add_notification_groups,
	hd_switcher_menu_reset_notification_group,
	hd_switcher_menu_reset_notification_groups,
	hd_switcher_menu_load_notification_groups,
	hd_switcher_menu_constructor, hd_switcher_menu_finalize,
	hd_switcher_menu_clear_item_activated,
	hd_switcher_menu_create_notifications_menu, 
	hd_switcher_menu_notification_deleted_cb): support for notification
	grouping based on a configuration file (notification-groups.conf).


Modified: projects/haf/trunk/hildon-desktop/ChangeLog
===================================================================
--- projects/haf/trunk/hildon-desktop/ChangeLog	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/ChangeLog	2007-07-04 11:31:30 UTC (rev 12642)
@@ -1,5 +1,33 @@
 2007-07-04  Lucas Rocha  <lucas.rocha at nokia.com>
 
+	* data/Makefile.am, data/notification-groups.conf: new notification
+	grouping configuration file.
+	* libhildondesktop/hildon-desktop-notification-manager.[ch]
+	(hildon_desktop_notification_manager_call_dbus_callback): new method
+	to send a dbus message from a string description. This is used by the
+	notification group menu item to make the dbus call for the group.
+	* src/hd-switcher-menu-item.[ch] (hd_switcher_menu_item_finalize,
+	hd_switcher_menu_item_set_property, hd_switcher_menu_item_get_property,
+	hd_switcher_menu_item_constructor, hd_switcher_menu_item_activate,
+	hd_switcher_menu_item_button_release_event, 
+	hd_switcher_menu_item_class_init, hd_switcher_menu_item_init,
+	hd_switcher_menu_item_new_from_notification_group,
+	hd_switcher_menu_item_compare_ids, hd_switcher_menu_item_has_id):
+	new type of HDSwitcherMenuItem for notification group items.
+	* src/hd-switcher-menu.c (hd_switcher_menu_free_notification_group,
+	hd_switcher_menu_add_notification_group,
+	hd_switcher_menu_add_notification_groups,
+	hd_switcher_menu_reset_notification_group,
+	hd_switcher_menu_reset_notification_groups,
+	hd_switcher_menu_load_notification_groups,
+	hd_switcher_menu_constructor, hd_switcher_menu_finalize,
+	hd_switcher_menu_clear_item_activated,
+	hd_switcher_menu_create_notifications_menu, 
+	hd_switcher_menu_notification_deleted_cb): support for notification
+	grouping based on a configuration file (notification-groups.conf).
+
+2007-07-04  Lucas Rocha  <lucas.rocha at nokia.com>
+
 	* policies/tasknavigator-policy.c (is_gap_plugin,
 	hd_ui_policy_module_filter_plugin_list): allow setting the position of
 	the applications menu plugin but keep it as mandatory.

Modified: projects/haf/trunk/hildon-desktop/data/Makefile.am
===================================================================
--- projects/haf/trunk/hildon-desktop/data/Makefile.am	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/data/Makefile.am	2007-07-04 11:31:30 UTC (rev 12642)
@@ -1,9 +1,10 @@
-hildondesktopconf_DATA = \
-	desktop.conf        \
-	tasknavigator.conf  \
-	home.conf           \
-	home-layout.conf    \
-	statusbar.conf
+hildondesktopconf_DATA =           \
+	desktop.conf               \
+	tasknavigator.conf         \
+	statusbar.conf             \
+	home.conf                  \
+	home-layout.conf           \
+	notification-groups.conf
 
 hildonnavigatordesktopentry_DATA = \
 	app-switcher.desktop       \

Added: projects/haf/trunk/hildon-desktop/data/notification-groups.conf
===================================================================
--- projects/haf/trunk/hildon-desktop/data/notification-groups.conf	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/data/notification-groups.conf	2007-07-04 11:31:30 UTC (rev 12642)
@@ -0,0 +1,5 @@
+[E-mail]
+Icon=qgn_list_gene_mail
+Category=email.arrive
+Label=tana_fi_more_messages
+DBus-Call=com.nokia.controlpanel /com/nokia/controlpanel com.nokia.controlpanel top_application

Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c	2007-07-04 11:31:30 UTC (rev 12642)
@@ -1621,3 +1621,22 @@
     while (gtk_list_store_remove (GTK_LIST_STORE (nm), &iter));
   }	  
 }
+
+void
+hildon_desktop_notification_manager_call_dbus_callback (HildonDesktopNotificationManager *nm,
+		                                        const gchar *dbus_call)
+{ 
+  DBusMessage *message;
+	
+  g_return_if_fail (HILDON_DESKTOP_IS_NOTIFICATION_MANAGER (nm));
+  g_return_if_fail (dbus_call != NULL);
+
+  message = hildon_desktop_notification_manager_message_from_desc (nm, dbus_call); 
+
+  if (message != NULL)
+  {
+    dbus_connection_send (dbus_g_connection_get_connection (nm->priv->connection), 
+    		          message, 
+    		          NULL);
+  }
+}

Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h	2007-07-04 11:31:30 UTC (rev 12642)
@@ -127,6 +127,9 @@
                                                                    guint                  id,
 								   const gchar           *action_id);
 
+void       hildon_desktop_notification_manager_call_dbus_callback (HildonDesktopNotificationManager *nm,
+		                                                   const gchar           *dbus_call);
+
 G_END_DECLS
 
 #endif /* __HILDON_DESKTOP_NOTIFICATION_MANAGER_H__ */

Modified: projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.c
===================================================================
--- projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.c	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.c	2007-07-04 11:31:30 UTC (rev 12642)
@@ -93,9 +93,11 @@
   MENU_PROP_SHOW_CLOSE,
   MENU_PROP_IS_BLINKING,
   MENU_PROP_NOT_ID,
+  MENU_PROP_NOT_IDS,
   MENU_PROP_NOT_SUMMARY,
   MENU_PROP_NOT_BODY,
-  MENU_PROP_NOT_ICON
+  MENU_PROP_NOT_ICON,
+  MENU_PROP_DBUS_CALLBACK
 };
 
 #define HD_SWITCHER_MENU_ITEM_GET_PRIVATE(obj) \
@@ -120,10 +122,13 @@
   HNAppPixbufAnimBlinker *blinker;
 
   gint       notification_id;
+  GList     *notification_ids;
   gchar     *notification_summary;
   gchar     *notification_body;
   GdkPixbuf *notification_icon;
 
+  gchar     *dbus_callback;
+  
   gboolean   was_topped;
 
   HildonDesktopNotificationManager *nm;
@@ -148,6 +153,12 @@
   if (priv->notification_body)
     g_free (priv->notification_body);	  
 
+  if (priv->notification_ids)
+    g_list_free (priv->notification_ids);
+  
+  if (priv->dbus_callback)
+    g_free (priv->dbus_callback);	  
+
   G_OBJECT_CLASS (hd_switcher_menu_item_parent_class)->finalize (gobject);
 }
 
@@ -177,6 +188,10 @@
       priv->notification_id = g_value_get_int (value);
       break;
       
+    case MENU_PROP_NOT_IDS:
+      priv->notification_ids = g_value_get_pointer (value);
+      break;
+      
     case MENU_PROP_NOT_SUMMARY:
       priv->notification_summary = g_strdup (g_value_get_string (value));
       break;
@@ -189,6 +204,10 @@
       priv->notification_icon = g_value_get_object (value);
       break;
       
+    case MENU_PROP_DBUS_CALLBACK:
+      priv->dbus_callback = g_strdup (g_value_get_string (value));
+      break; 
+      
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       break;
@@ -221,6 +240,10 @@
       g_value_set_int (value, priv->notification_id);
       break;
       
+    case MENU_PROP_NOT_IDS:
+      g_value_set_pointer (value, priv->notification_ids);
+      break;
+      
     case MENU_PROP_NOT_SUMMARY:
       g_value_set_string (value, priv->notification_summary);
       break;
@@ -233,6 +256,10 @@
       g_value_set_object (value, priv->notification_icon);
       break;
       
+    case MENU_PROP_DBUS_CALLBACK:
+      g_value_set_string (value, priv->dbus_callback);
+      break; 
+      
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       break;
@@ -417,8 +444,8 @@
     g_free (win_name);
   }
   else
+  if (priv->notification_id != -1)
   {
-    /* TODO: notification id*/
     if (priv->notification_icon)	 
       gtk_image_set_from_pixbuf 
         (GTK_IMAGE (priv->icon), priv->notification_icon);
@@ -429,8 +456,20 @@
 		        priv->notification_summary); /* TODO: Insert timestamp */
     gtk_label_set_text (GTK_LABEL (priv->label2),
 		    	priv->notification_body);
-  }	  
+  }
+  else
+  if (priv->notification_ids != NULL)
+  {
+    if (priv->notification_icon)	 
+      gtk_image_set_from_pixbuf 
+        (GTK_IMAGE (priv->icon), priv->notification_icon);
 
+    gtk_label_set_text (GTK_LABEL (priv->label), 
+		        priv->notification_summary);
+ 
+    gtk_widget_hide (priv->label2); 
+  }  
+
   if (priv->show_close)
   {
     HDSwitcherMenuItemClass *klass = HD_SWITCHER_MENU_ITEM_CLASS (G_OBJECT_GET_CLASS (gobject));
@@ -539,6 +578,30 @@
       g_error_free (error);
     } 
   }	  
+  else
+  if (HD_SWITCHER_MENU_ITEM (menu_item)->priv->notification_ids != NULL)
+  {
+    GList *l;
+    GError *error = NULL;
+
+    for (l = HD_SWITCHER_MENU_ITEM (menu_item)->priv->notification_ids; l; l = g_list_next (l))
+    {
+      gint id = GPOINTER_TO_INT (l->data);
+
+      hildon_desktop_notification_manager_close_notification
+        (HD_SWITCHER_MENU_ITEM (menu_item)->priv->nm, id, &error);
+
+      if (error)
+      {
+        g_warning ("We cannot close the notification!?!?!");
+        g_error_free (error);
+      } 
+    }
+
+    hildon_desktop_notification_manager_call_dbus_callback 
+      (HD_SWITCHER_MENU_ITEM (menu_item)->priv->nm, 
+       HD_SWITCHER_MENU_ITEM (menu_item)->priv->dbus_callback); 
+  }	  
 }
 
 static gboolean
@@ -584,7 +647,26 @@
 	g_error_free (error);
       }	     	 
     }	    
-    
+    else
+    if (menuitem->priv->notification_ids != NULL)
+    {
+      GList *l;
+      GError *error = NULL;
+
+      for (l = HD_SWITCHER_MENU_ITEM (menuitem)->priv->notification_ids; l; l = g_list_next (l))
+      {
+        gint id = GPOINTER_TO_INT (l->data);
+
+        hildon_desktop_notification_manager_close_notification
+          (HD_SWITCHER_MENU_ITEM (menuitem)->priv->nm, id, &error);
+
+        if (error)
+        {
+          g_warning ("We cannot close the notification!?!?!");
+          g_error_free (error);
+        } 
+      } 
+    } 
     return TRUE;
   }
   
@@ -696,7 +778,15 @@
 						      G_MAXINT,
 						      -1,
 						     (G_PARAM_CONSTRUCT | G_PARAM_READWRITE)));
+
   g_object_class_install_property (gobject_class,
+		  		   MENU_PROP_NOT_IDS,
+				   g_param_spec_pointer ("notification-ids",
+					   		 "List of ids of notifications",
+							 "The list of ids of the notifications",
+							 (G_PARAM_CONSTRUCT | G_PARAM_READWRITE)));
+ 
+  g_object_class_install_property (gobject_class,
 		  		   MENU_PROP_NOT_SUMMARY,
 				   g_param_spec_string ("notification-summary",
 					   		"Summary of notification",
@@ -720,6 +810,14 @@
 							GDK_TYPE_PIXBUF,
 							(G_PARAM_CONSTRUCT | G_PARAM_READWRITE))); 
  
+  g_object_class_install_property (gobject_class,
+		  		   MENU_PROP_DBUS_CALLBACK,
+				   g_param_spec_string ("dbus-callback",
+					   		"D-Bus callback for notification group",
+							"The DBus callback of the notification group",
+							"",
+							(G_PARAM_CONSTRUCT | G_PARAM_READWRITE)));
+ 
   g_type_class_add_private (klass, sizeof (HDSwitcherMenuItemPrivate));
 }
 
@@ -737,9 +835,11 @@
   priv->pixbuf_anim          = NULL;
   priv->info                 = NULL;
   priv->notification_id      = -1;
+  priv->notification_ids     = NULL;
   priv->notification_summary = 
   priv->notification_body    = NULL;
   priv->notification_icon    = NULL;
+  priv->dbus_callback        = NULL;
 
   priv->nm = 
     HILDON_DESKTOP_NOTIFICATION_MANAGER 
@@ -779,6 +879,25 @@
 		  NULL); 
 }	
 
+GtkWidget *
+hd_switcher_menu_item_new_from_notification_group (GList     *ids,
+					           GdkPixbuf *icon,
+					           gchar     *summary,
+						   gchar     *dbus_callback,
+					           gboolean   show_close)
+{
+
+  return 
+    g_object_new (HD_TYPE_SWITCHER_MENU_ITEM,
+		  "notification-id", -1, 
+		  "notification-ids", ids, 
+		  "notification-icon", icon,
+		  "notification-summary", summary, 
+		  "dbus-callback", dbus_callback, 
+		  "show-close", show_close,
+		  NULL); 
+}
+
 void
 hd_switcher_menu_item_set_entry_info (HDSwitcherMenuItem *menuitem,
   		                      HDWMEntryInfo        *info)
@@ -874,3 +993,25 @@
 
   return menuitem->priv->notification_id;
 }	
+
+static gint
+hd_switcher_menu_item_compare_ids (gconstpointer a, gconstpointer b)
+{
+  if (GPOINTER_TO_INT (a) == GPOINTER_TO_INT (b))
+    return 0;
+  else
+    return 1;
+}
+	
+gboolean 
+hd_switcher_menu_item_has_id (HDSwitcherMenuItem *menuitem, gint id)
+{
+  g_return_val_if_fail (HD_IS_SWITCHER_MENU_ITEM (menuitem), FALSE);
+
+  if (g_list_find_custom (menuitem->priv->notification_ids, 
+			  GINT_TO_POINTER (id), 
+			  hd_switcher_menu_item_compare_ids) != NULL)
+    return TRUE;
+  else
+    return FALSE;
+}	

Modified: projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.h
===================================================================
--- projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.h	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/src/hd-switcher-menu-item.h	2007-07-04 11:31:30 UTC (rev 12642)
@@ -74,6 +74,12 @@
                                         	          gchar     *body,
                                              	          gboolean   show_close);
 
+GtkWidget *  hd_switcher_menu_item_new_from_notification_group (GList     *ids,
+             		                                        GdkPixbuf *icon,
+                         		                        gchar     *summary,
+								gchar     *dbus_callback,
+                                             	                gboolean   show_close);
+
 void         hd_switcher_menu_item_set_entry_info  (HDSwitcherMenuItem *menuitem,
 					       HDWMEntryInfo   *info);
 HDWMEntryInfo *hd_switcher_menu_item_get_entry_info  (HDSwitcherMenuItem *menuitem);
@@ -83,6 +89,8 @@
 
 gint	     hd_switcher_menu_item_get_notification_id (HDSwitcherMenuItem *menuitem);
 
+gboolean     hd_switcher_menu_item_has_id (HDSwitcherMenuItem *menuitem, gint id);
+
 G_END_DECLS
 
 #endif /* HD_SWITCHER_MENU_ITEM_H */

Modified: projects/haf/trunk/hildon-desktop/src/hd-switcher-menu.c
===================================================================
--- projects/haf/trunk/hildon-desktop/src/hd-switcher-menu.c	2007-07-04 10:44:12 UTC (rev 12641)
+++ projects/haf/trunk/hildon-desktop/src/hd-switcher-menu.c	2007-07-04 11:31:30 UTC (rev 12642)
@@ -120,6 +120,16 @@
 
 G_DEFINE_TYPE (HDSwitcherMenu, hd_switcher_menu, TASKNAVIGATOR_TYPE_ITEM);
 
+typedef struct 
+{
+  gchar     *icon;
+  gchar     *category;
+  gchar     *label;
+  gchar     *dbus_callback;
+  gboolean   is_active;
+  GList     *notifications;
+} HDSwitcherMenuNotificationGroup;
+
 struct _HDSwitcherMenuPrivate
 {
   HildonDesktopPopupMenu *menu_applications;
@@ -147,6 +157,8 @@
 
   GtkWidget		   *window_dialog;
   GtkWidget		   *toggle_button;
+
+  GHashTable               *notification_groups;
   
   gint                      esd_socket;
 };
@@ -508,6 +520,193 @@
   g_list_free (children);
 }
 
+static void
+hd_switcher_menu_free_notification_group (gpointer user_data)
+{
+  HDSwitcherMenuNotificationGroup *ngroup;
+
+  ngroup = (HDSwitcherMenuNotificationGroup *) user_data;
+
+  if (ngroup->icon)
+    g_free (ngroup->icon);
+
+  if (ngroup->category)
+    g_free (ngroup->category);
+
+  if (ngroup->label)
+    g_free (ngroup->label);
+
+  if (ngroup->dbus_callback)
+    g_free (ngroup->dbus_callback);
+
+  if (ngroup->notifications)
+    g_list_free (ngroup->notifications);
+
+  g_free (ngroup);
+}
+
+static void
+hd_switcher_menu_add_notification_group (gpointer key,
+	             	                 gpointer value, 
+					 gpointer user_data)
+{
+  HDSwitcherMenuNotificationGroup *ngroup;
+  HDSwitcherMenu *switcher;
+  
+  ngroup = (HDSwitcherMenuNotificationGroup *) value;
+  switcher = (HDSwitcherMenu *) user_data;	
+ 
+  if (ngroup->is_active)
+  {
+    GtkWidget *menu_item;
+    GdkPixbuf *icon;
+    gchar *summary;
+	  
+    summary = g_strdup_printf (_(ngroup->label), 
+		               g_list_length (ngroup->notifications));
+    
+    icon = hd_switcher_menu_get_icon_from_theme (switcher, ngroup->icon, -1);
+    
+    hildon_desktop_popup_menu_add_item
+      (switcher->priv->menu_notifications,
+      GTK_MENU_ITEM (gtk_separator_menu_item_new ()));
+
+    menu_item = hd_switcher_menu_item_new_from_notification_group
+      (ngroup->notifications, icon, summary, ngroup->dbus_callback, TRUE);
+
+    hildon_desktop_popup_menu_add_item
+     (switcher->priv->menu_notifications, GTK_MENU_ITEM (menu_item));
+  }
+}
+
+static void
+hd_switcher_menu_add_notification_groups (HDSwitcherMenu *switcher)
+{
+  g_hash_table_foreach (switcher->priv->notification_groups, 
+		        hd_switcher_menu_add_notification_group,
+			switcher);
+}
+
+static void
+hd_switcher_menu_reset_notification_group (gpointer key,
+	             	                   gpointer value, 
+					   gpointer user_data)
+{
+  HDSwitcherMenuNotificationGroup *ngroup;
+  
+  ngroup = (HDSwitcherMenuNotificationGroup *) value;
+
+  ngroup->notifications = NULL;
+  ngroup->is_active = FALSE;
+}
+
+static void
+hd_switcher_menu_reset_notification_groups (HDSwitcherMenu *switcher)
+{
+  g_hash_table_foreach (switcher->priv->notification_groups, 
+		        hd_switcher_menu_reset_notification_group,
+			switcher);
+}
+
+static void
+hd_switcher_menu_load_notification_groups (HDSwitcherMenu *switcher)
+{
+  GKeyFile *keyfile;
+  gchar **groups;
+  GError *error = NULL;
+  gint i;
+
+  keyfile = g_key_file_new ();
+
+  g_key_file_load_from_file (keyfile,
+                             HD_DESKTOP_CONFIG_PATH "/notification-groups.conf",
+                             G_KEY_FILE_NONE,
+                             &error);
+
+  if (error)
+  {
+    g_warning ("Error loading notification groups file: %s", error->message);
+    g_error_free (error);
+    
+    return;
+  }
+
+  groups = g_key_file_get_groups (keyfile, NULL);
+
+  for (i = 0; groups[i]; i++)
+  {
+    HDSwitcherMenuNotificationGroup *ngroup;
+
+    ngroup = g_new0 (HDSwitcherMenuNotificationGroup, 1);
+
+    ngroup->icon = g_key_file_get_string (keyfile,
+		    			  groups[i],
+					  "Icon",
+					  &error);
+
+    if (error)
+    {
+      g_warning ("Error loading notification groups file: %s", error->message);
+      hd_switcher_menu_free_notification_group (ngroup);
+      g_error_free (error);
+      error = NULL;
+      continue;
+    }
+
+    ngroup->category = g_key_file_get_string (keyfile,
+		    			      groups[i],
+					      "Category",
+					      &error);
+
+    if (error)
+    {
+      g_warning ("Error loading notification groups file: %s", error->message);
+      hd_switcher_menu_free_notification_group (ngroup);
+      g_error_free (error);
+      error = NULL;
+      continue;
+    }      
+
+    ngroup->label = g_key_file_get_string (keyfile,
+		    			   groups[i],
+					   "Label",
+					   &error);
+
+    if (error)
+    {
+      g_warning ("Error loading notification groups file: %s", error->message);
+      hd_switcher_menu_free_notification_group (ngroup);
+      g_error_free (error);
+      error = NULL;
+      continue;
+    }
+
+    ngroup->dbus_callback = g_key_file_get_string (keyfile,
+		    			           groups[i],
+					           "DBus-Call",
+					           &error);
+
+    if (error)
+    {
+      g_warning ("Error loading notification groups file: %s", error->message);
+      hd_switcher_menu_free_notification_group (ngroup);
+      g_error_free (error);
+      error = NULL;
+      continue;
+    }
+
+    ngroup->is_active = FALSE;
+    ngroup->notifications = NULL;
+    
+    g_hash_table_insert (switcher->priv->notification_groups, 
+		         ngroup->category, 
+			 ngroup); 
+  }
+
+  g_free (groups);
+  g_key_file_free (keyfile);
+}
+	
 static GObject *
 hd_switcher_menu_constructor (GType gtype,
 			      guint n_params,
@@ -737,12 +936,20 @@
                           G_CALLBACK (hd_switcher_menu_item_activated),
                           (gpointer)switcher); 
 
+  switcher->priv->notification_groups = 
+          g_hash_table_new_full (g_str_hash, 
+	  		         g_str_equal,
+			         (GDestroyNotify) g_free,
+			         (GDestroyNotify) hd_switcher_menu_free_notification_group);
+
+  hd_switcher_menu_load_notification_groups (switcher);
+  
   hd_switcher_menu_create_notifications_menu (switcher);
 
   hd_switcher_menu_check_content (switcher);
 
   switcher->priv->window_dialog = NULL;
-  
+
   return object;
 }
 
@@ -809,7 +1016,13 @@
   g_object_unref (switcher->priv->icon_theme);
 
   hn_as_sound_deinit (switcher->priv->esd_socket); 
-  
+
+  if (switcher->priv->notification_groups)
+  {
+    g_hash_table_destroy (switcher->priv->notification_groups);
+    switcher->priv->notification_groups = NULL;
+  }
+	  
   G_OBJECT_CLASS (hd_switcher_menu_parent_class)->finalize (object);
 }
 
@@ -873,6 +1086,7 @@
   {
     hildon_desktop_notification_manager_close_all (switcher->nm);
     gtk_widget_destroy (switcher->priv->clear_events_menu_item);
+    switcher->priv->clear_events_menu_item = NULL;
   }
 }
 	
@@ -1241,13 +1455,11 @@
   GtkTreeModel *nm = GTK_TREE_MODEL (switcher->nm);
   GList *children = NULL, *l;
   GtkTreeIter  iter;	
- 
+
   children =
     hildon_desktop_popup_menu_get_children (switcher->priv->menu_notifications);
 
-  /* FIXME: it should use the screen height instead of number of items */
-  if (g_list_length (children) > 9 || 
-      gtk_tree_model_iter_n_children (nm, NULL) >= AS_ITEMS_LIMIT)
+  if (gtk_tree_model_iter_n_children (nm, NULL) >= AS_ITEMS_LIMIT)
   {
     hd_switcher_menu_add_clear_notifications_button (switcher);
     first_item = switcher->priv->clear_events_menu_item;
@@ -1271,44 +1483,91 @@
 
   if (gtk_tree_model_get_iter_first (nm, &iter))
   {
-    gint id;
     GdkPixbuf *icon;
+    HDSwitcherMenuNotificationGroup *ngroup;
+    GHashTable *hints;
+    GValue *hint;
     gchar *summary, *body;
     gboolean ack;
+    gint id;
 
+    if (switcher->priv->clear_events_menu_item)
+    {
+      do
+      {
+        gtk_tree_model_get (nm,
+                            &iter,
+                            HD_NM_COL_ID, &id,
+                            HD_NM_COL_HINTS, &hints,
+                            -1);
+
+	hint = g_hash_table_lookup (hints, "category");
+
+	ngroup = 
+	  g_hash_table_lookup (switcher->priv->notification_groups, 
+	                       g_value_get_string (hint));
+
+	if (ngroup != NULL)
+        {
+	  ngroup->notifications = 
+            g_list_prepend (ngroup->notifications, GINT_TO_POINTER (id));
+
+	  ngroup->is_active = 
+            (g_list_length (ngroup->notifications) > 1);
+	}
+      }
+      while (gtk_tree_model_iter_next (nm, &iter));
+
+      hd_switcher_menu_add_notification_groups (switcher);
+
+      gtk_tree_model_get_iter_first (nm, &iter);
+    }
+   
     do
     {
-      if (first_item)
-        hildon_desktop_popup_menu_add_item
-          (switcher->priv->menu_notifications,
-          GTK_MENU_ITEM (gtk_separator_menu_item_new ()));
-
       gtk_tree_model_get (nm,
                           &iter,
                           HD_NM_COL_ID, &id,
                           HD_NM_COL_ICON, &icon,
                           HD_NM_COL_SUMMARY, &summary,
                           HD_NM_COL_BODY, &body,
+                          HD_NM_COL_HINTS, &hints,
                           HD_NM_COL_ACK, &ack,
                           -1); 
 
-      menu_item =
-        hd_switcher_menu_item_new_from_notification
-         (id, icon, summary, body, TRUE);
+      hint = g_hash_table_lookup (hints, "category");
+      
+      ngroup = 
+        g_hash_table_lookup (switcher->priv->notification_groups, 
+                             g_value_get_string (hint));
 
-      hd_switcher_menu_item_set_blinking (HD_SWITCHER_MENU_ITEM (menu_item), !ack);
+      if (ngroup == NULL || !ngroup->is_active)
+      {
+        if (first_item)
+          hildon_desktop_popup_menu_add_item
+            (switcher->priv->menu_notifications,
+            GTK_MENU_ITEM (gtk_separator_menu_item_new ()));
 
-      hildon_desktop_popup_menu_add_item
-       (switcher->priv->menu_notifications, GTK_MENU_ITEM (menu_item));
+        menu_item =
+          hd_switcher_menu_item_new_from_notification
+           (id, icon, summary, body, TRUE);
 
-      if (!ack)
-        hd_switcher_menu_replace_blinking_icon (switcher, icon);
+        hd_switcher_menu_item_set_blinking (HD_SWITCHER_MENU_ITEM (menu_item), !ack);
 
-      if (!first_item)
-	first_item = menu_item;
+        hildon_desktop_popup_menu_add_item
+         (switcher->priv->menu_notifications, GTK_MENU_ITEM (menu_item));
+
+        if (!ack)
+          hd_switcher_menu_replace_blinking_icon (switcher, icon);
+
+        if (!first_item)
+	  first_item = menu_item;
+      }
     }
     while (gtk_tree_model_iter_next (nm, &iter));
 
+    hd_switcher_menu_reset_notification_groups (switcher);
+    
     hd_switcher_menu_scroll_to (NULL, switcher);
   }
 
@@ -1834,16 +2093,22 @@
   
   for (l = children; l != NULL; l = g_list_next (l))
   {
-    if (!GTK_IS_SEPARATOR_MENU_ITEM (l->data))	  
+    if (HD_IS_SWITCHER_MENU_ITEM (l->data))	  
     {
-      GtkMenuItem *separator = NULL;
-      gint _id =
+      GtkMenuItem *menu_item = NULL, *separator = NULL;
+      gint _id = 
         hd_switcher_menu_item_get_notification_id (HD_SWITCHER_MENU_ITEM (l->data));
-	  
-      if (_id == id)      
+      
+      if ((_id != -1 && _id == id) ||
+          (hd_switcher_menu_item_has_id (HD_SWITCHER_MENU_ITEM (l->data), id)))      
       {
+        menu_item = GTK_MENU_ITEM (l->data);
+      }
+
+      if (menu_item)
+      {
         hildon_desktop_popup_menu_remove_item (switcher->priv->menu_notifications,
-	                                       GTK_MENU_ITEM (l->data));
+	                                       menu_item);
 
         if (l == children)
 	{
@@ -1861,12 +2126,11 @@
 	  				         separator);
 
         break;
-      }	    
+      }
     }
-  }	  
+  }
 
-  /* FIXME: it should use the screen height instead of number of items */
-  if (g_list_length (children) - 2 < 2 * (AS_ITEMS_LIMIT + 1) - 1)
+  if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (switcher->nm), NULL) <= AS_ITEMS_LIMIT)
   {
     if (switcher->priv->clear_events_menu_item)
     {
@@ -1875,7 +2139,8 @@
       clear_child = g_list_last (children);
       
       gtk_widget_destroy (switcher->priv->clear_events_menu_item);
-
+      switcher->priv->clear_events_menu_item = NULL;
+      
       if (clear_child->prev && GTK_IS_SEPARATOR_MENU_ITEM (clear_child->prev->data))
         hildon_desktop_popup_menu_remove_item (switcher->priv->menu_notifications,
         				       GTK_MENU_ITEM (clear_child->prev->data));


More information about the maemo-commits mailing list