ekiga r6540 - in trunk: . lib/engine/gui/gtk-frontend lib/engine/presence/avahi lib/engine/presence/local-roster lib/engine/presence/skel



Author: jpuydt
Date: Wed Jul 30 19:12:17 2008
New Revision: 6540
URL: http://svn.gnome.org/viewvc/ekiga?rev=6540&view=rev

Log:
Added the populate_menu_for_group method to Ekiga::Heap, and added group renaming in the local roster

Modified:
   trunk/ChangeLog
   trunk/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
   trunk/lib/engine/presence/avahi/avahi-heap.cpp
   trunk/lib/engine/presence/avahi/avahi-heap.h
   trunk/lib/engine/presence/local-roster/local-heap.cpp
   trunk/lib/engine/presence/local-roster/local-heap.h
   trunk/lib/engine/presence/local-roster/local-presentity.cpp
   trunk/lib/engine/presence/local-roster/local-presentity.h
   trunk/lib/engine/presence/skel/heap.h

Modified: trunk/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
==============================================================================
--- trunk/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp	(original)
+++ trunk/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp	Wed Jul 30 19:12:17 2008
@@ -128,6 +128,9 @@
  */
 static void on_clicked_show_heap_menu (Ekiga::Heap* heap,
 				       GdkEventButton* event);
+static void on_clicked_show_heap_group_menu (Ekiga::Heap* heap,
+					     const std::string name,
+					     GdkEventButton* event);
 static void on_clicked_show_presentity_menu (Ekiga::Presentity* presentity,
 					     GdkEventButton* event);
 
@@ -321,6 +324,7 @@
  * PRE          : /
  */
 static void roster_view_gtk_find_iter_for_group (RosterViewGtk *view,
+						 Ekiga::Heap& heap,
                                                  GtkTreeIter *heap_iter,
                                                  const std::string name,
                                                  GtkTreeIter *iter);
@@ -374,7 +378,25 @@
 		      (gpointer) builder.menu);
   }
   g_object_ref_sink (G_OBJECT (builder.menu));
+}
 
+static void
+on_clicked_show_heap_group_menu (Ekiga::Heap* heap,
+				 const std::string name,
+				 GdkEventButton* event)
+{
+  MenuBuilderGtk builder;
+  heap->populate_menu_for_group (name, builder);
+  if (!builder.empty ()) {
+
+    gtk_widget_show_all (builder.menu);
+    gtk_menu_popup (GTK_MENU (builder.menu), NULL, NULL,
+		    NULL, NULL, event->button, event->time);
+    g_signal_connect (G_OBJECT (builder.menu), "hide",
+		      GTK_SIGNAL_FUNC (g_object_unref),
+		      (gpointer) builder.menu);
+  }
+  g_object_ref_sink (G_OBJECT (builder.menu));
 }
 
 static void
@@ -535,9 +557,11 @@
   if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 
     gint column_type;
+    gchar* name = NULL;
     Ekiga::Heap* heap = NULL;
     Ekiga::Presentity *presentity = NULL;
     gtk_tree_model_get (model, &iter,
+			COLUMN_NAME, &name,
 			COLUMN_TYPE, &column_type,
 			COLUMN_HEAP, &heap,
 			COLUMN_PRESENTITY, &presentity,
@@ -564,11 +588,20 @@
       break;
     }
 
-    case TYPE_GROUP:
+    case TYPE_GROUP: {
+
+      ToolbarBuilderGtk builder(self->priv->toolbar);
+      Ekiga::ShortMenuBuilder shorter(builder);
+      heap->populate_menu_for_group (name, shorter);
+      gtk_widget_show_all (self->priv->toolbar);
+      break;
+    }
     default:
       break;
     }
+
     g_signal_emit (self, signals[PRESENTITY_SELECTED_SIGNAL], 0, presentity);
+    g_free (name);
   }
 }
 
@@ -615,15 +648,8 @@
 
 	if (event->type == GDK_BUTTON_PRESS && event->button == 1 && name)
 	  on_clicked_fold (self, path, name);
-	/* FIXME: what about making it possible for a heap to have actions on groups?
-	 * It would allow for example (and optional to each Heap) group renaming,
-	 * or group invitations to a MUC or anything collaborative!
-	 * What is needed is :
-	 * - store_set the &heap when adding a group so we have access to it here in heap
-	 * - in this function we should also store_get on COLUMN_NAME to have the group name
-	 *   (don't forget the g_free!)
-	 * - add the proper populate_group_menu api to Ekiga::Heap
-	 */
+	if (event->type == GDK_BUTTON_PRESS && event->button == 3)
+	  on_clicked_show_heap_group_menu (heap, name, event);
 	break;
       case TYPE_PRESENTITY:
 
@@ -834,7 +860,8 @@
        group != groups.end ();
        group++) {
 
-    roster_view_gtk_find_iter_for_group (self, &heap_iter, *group, &group_iter);
+    roster_view_gtk_find_iter_for_group (self, heap, &heap_iter,
+					 *group, &group_iter);
     roster_view_gtk_find_iter_for_presentity (self, &group_iter, presentity, &iter);
 
     gtk_tree_store_set (self->priv->store, &iter,
@@ -850,7 +877,8 @@
 
   if (groups.empty ()) {
 
-    roster_view_gtk_find_iter_for_group (self, &heap_iter, _("Unsorted"), &group_iter);
+    roster_view_gtk_find_iter_for_group (self, heap, &heap_iter,
+					 _("Unsorted"), &group_iter);
     roster_view_gtk_find_iter_for_presentity (self, &group_iter, presentity, &iter);
     gtk_tree_store_set (self->priv->store, &iter,
 			COLUMN_TYPE, TYPE_PRESENTITY,
@@ -986,6 +1014,7 @@
 
 static void
 roster_view_gtk_find_iter_for_group (RosterViewGtk *view,
+				     Ekiga::Heap& heap,
                                      GtkTreeIter *heap_iter,
                                      const std::string name,
                                      GtkTreeIter *iter)
@@ -1013,6 +1042,7 @@
     gtk_tree_store_append (view->priv->store, iter, heap_iter);
     gtk_tree_store_set (view->priv->store, iter,
                         COLUMN_TYPE, TYPE_GROUP,
+			COLUMN_HEAP, &heap,
                         COLUMN_NAME, name.c_str (),
                         -1);
   }

Modified: trunk/lib/engine/presence/avahi/avahi-heap.cpp
==============================================================================
--- trunk/lib/engine/presence/avahi/avahi-heap.cpp	(original)
+++ trunk/lib/engine/presence/avahi/avahi-heap.cpp	Wed Jul 30 19:12:17 2008
@@ -128,12 +128,17 @@
 }
 
 bool
-Avahi::Heap::populate_menu (Ekiga::MenuBuilder &/*builder*/)
+Avahi::Heap::populate_menu (Ekiga::MenuBuilder& /*builder*/)
 {
-  /* FIXME */
   return false;
 }
 
+bool
+Avahi::Heap::populate_menu_for_group (const std::string /*name*/,
+				      Ekiga::MenuBuilder& /*builder*/)
+{
+  return false;
+}
 
 void
 Avahi::Heap::ClientCallback (AvahiClient *_client,

Modified: trunk/lib/engine/presence/avahi/avahi-heap.h
==============================================================================
--- trunk/lib/engine/presence/avahi/avahi-heap.h	(original)
+++ trunk/lib/engine/presence/avahi/avahi-heap.h	Wed Jul 30 19:12:17 2008
@@ -69,6 +69,9 @@
 
     bool populate_menu (Ekiga::MenuBuilder &builder);
 
+    bool populate_menu_for_group (const std::string name,
+				  Ekiga::MenuBuilder& builder);
+
     /* these should be private but are called from C code */
 
     void ClientCallback (AvahiClient *client,

Modified: trunk/lib/engine/presence/local-roster/local-heap.cpp
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-heap.cpp	(original)
+++ trunk/lib/engine/presence/local-roster/local-heap.cpp	Wed Jul 30 19:12:17 2008
@@ -75,11 +75,11 @@
 	  && child->name != NULL
 	  && xmlStrEqual (BAD_CAST ("entry"), child->name))
 	add (child);
-    
+
     g_free (c_raw);
 
     // Or create a new XML document
-  } 
+  }
   else {
 
     doc = xmlNewDoc (BAD_CAST "1.0");
@@ -113,6 +113,16 @@
 
 
 bool
+Local::Heap::populate_menu_for_group (const std::string name,
+				      Ekiga::MenuBuilder& builder)
+{
+  builder.add_action ("rename_group", _("Rename"),
+		      sigc::bind (sigc::mem_fun (this, &Local::Heap::on_rename_group), name));
+  return true;
+}
+
+
+bool
 Local::Heap::has_presentity_with_uri (const std::string uri) const
 {
   bool result = false;
@@ -294,3 +304,49 @@
 #endif
   }
 }
+
+void
+Local::Heap::on_rename_group (std::string name)
+{
+  Ekiga::FormRequestSimple request;
+
+  request.title (_("Rename group"));
+  request.instructions (_("Please edit this group name"));
+  request.text ("name", _("Name:"), name);
+
+  request.submitted.connect (sigc::bind<0>(sigc::mem_fun (this, &Local::Heap::rename_group_form_submitted), name));
+
+  if (!questions.handle_request (&request)) {
+
+    // FIXME: better error reporting
+#ifdef __GNUC__
+    std::cout << "Unhandled form request in "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}
+
+void
+Local::Heap::rename_group_form_submitted (std::string old_name,
+					  Ekiga::Form& result)
+{
+  try {
+    const std::string new_name = result.text ("name");
+
+    if ( !new_name.empty ()) {
+
+      for (iterator iter = begin ();
+	   iter != end ();
+	   ++iter) {
+
+	iter->rename_group (old_name, new_name);
+      }
+    }
+  } catch (Ekiga::Form::not_found) {
+
+#ifdef __GNUC__
+    std::cerr << "Invalid form submitted to "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}

Modified: trunk/lib/engine/presence/local-roster/local-heap.h
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-heap.h	(original)
+++ trunk/lib/engine/presence/local-roster/local-heap.h	Wed Jul 30 19:12:17 2008
@@ -87,13 +87,23 @@
 
 
     /** Populates the given Ekiga::MenuBuilder with the actions.
-     * Inherits from Ekiga::Heap.
+     * Inherited from Ekiga::Heap.
      * @param: A MenuBuilder.
      * @return: A populated menu.
      */
     bool populate_menu (Ekiga::MenuBuilder &);
 
 
+    /** Populates the given Ekiga::MenuBuilder with the actions.
+     * Inherited from Ekiga::Heap.
+     * @param: The name of the group on which to act.
+     * @param: A MenuBuilder.
+     * @return: A populated menu.
+     */
+    bool populate_menu_for_group (const std::string name,
+				  Ekiga::MenuBuilder& builder);
+
+
     /** Determines if the given uri is already present in the Heap.
      * @param: A string representing an uri.
      * @return: TRUE if that uri is already present in the Heap.
@@ -169,6 +179,16 @@
      */
     void new_presentity_form_submitted (Ekiga::Form &form);
 
+    /** Triggered when the user decides to rename a group.
+     * @param The group name
+     */
+    void on_rename_group (std::string name);
+
+    /**
+     */
+    void rename_group_form_submitted (std::string old_name,
+				      Ekiga::Form& result);
+
     Ekiga::ServiceCore &core;
     Ekiga::PresenceCore *presence_core;
     xmlDocPtr doc;

Modified: trunk/lib/engine/presence/local-roster/local-presentity.cpp
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-presentity.cpp	(original)
+++ trunk/lib/engine/presence/local-roster/local-presentity.cpp	Wed Jul 30 19:12:17 2008
@@ -301,6 +301,46 @@
 
 
 void
+Local::Presentity::rename_group (const std::string old_name,
+				 const std::string new_name)
+{
+  std::map<std::string, xmlNodePtr>::iterator iter
+    = group_nodes.find (old_name);
+
+  if (iter != group_nodes.end ()) {
+
+    if (group_nodes.find (new_name) != group_nodes.end ()) {
+
+      /* we're already in the new group */
+      xmlUnlinkNode (iter->second);
+      xmlFreeNode (iter->second);
+      group_nodes.erase (iter);
+    } else {
+
+      /* it is a real renaming */
+      xmlNodePtr group_node = iter->second;
+      robust_xmlNodeSetContent (node, &group_node,
+				"group", new_name.c_str ());
+      group_nodes.erase (iter);
+      group_nodes[new_name] = group_node;
+    }
+
+    groups.clear ();
+
+    for (std::map<std::string, xmlNodePtr>::iterator it = group_nodes.begin ();
+	 it != group_nodes.end ();
+	 ++it) {
+
+      groups.insert (iter->first);
+    }
+
+    updated.emit ();
+    trigger_saving.emit ();
+  }
+}
+
+
+void
 Local::Presentity::remove ()
 {
   presence_core->unfetch_presence (uri);

Modified: trunk/lib/engine/presence/local-roster/local-presentity.h
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-presentity.h	(original)
+++ trunk/lib/engine/presence/local-roster/local-presentity.h	Wed Jul 30 19:12:17 2008
@@ -128,6 +128,13 @@
     xmlNodePtr get_node () const;
 
 
+    /** Rename the given group, if this Presentity belongs to it
+     *
+     */
+    void rename_group (const std::string old_name,
+		       const std::string new_name);
+
+
     /** Remove the current node from the XML document,
      * emit the 'removed' signal so the different views
      * know we're going away, and finally emit 'trigger_saving'

Modified: trunk/lib/engine/presence/skel/heap.h
==============================================================================
--- trunk/lib/engine/presence/skel/heap.h	(original)
+++ trunk/lib/engine/presence/skel/heap.h	Wed Jul 30 19:12:17 2008
@@ -73,6 +73,14 @@
      */
     virtual bool populate_menu (MenuBuilder &) = 0;
 
+    /** Populates a menu with the actions possible on the given group
+     * of the Heap.
+     * @param The name of the group on which to act.
+     * @param The builder to populate.
+     */
+    virtual bool populate_menu_for_group (const std::string name,
+					  MenuBuilder&) = 0;
+
     /**
      * Signals on that object
      */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]