From b1cb5e20d49fdb3500fd76ea18dcbcc77bbba8ee Mon Sep 17 00:00:00 2001
From: Florian Zeitz <florob@babelmonkeys.de>
Date: Tue, 29 Jan 2013 22:30:08 +0100
Subject: [PATCH] Show presence's show value in roster

---
 data/gtk/roster.ui           | 10 +++---
 src/gui/gtk/JubGtkRosterUI.h |  1 -
 src/gui/gtk/JubGtkRosterUI.m | 66 +++++++++++++++++++++---------------
 3 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/data/gtk/roster.ui b/data/gtk/roster.ui
index cde8b89..a39890a 100644
--- a/data/gtk/roster.ui
+++ b/data/gtk/roster.ui
@@ -41,6 +41,8 @@
       <column type="gchararray"/>
       <!-- column-name jid -->
       <column type="gchararray"/>
+      <!-- column-name status -->
+      <column type="gchararray"/>
     </columns>
   </object>
   <object class="GtkTreeModelFilter" id="RosterTreeModelFilter">
@@ -230,22 +232,22 @@
                 </child>
                 <child>
                   <object class="GtkTreeViewColumn" id="RosterTreeViewColumn1">
-                    <property name="title" translatable="yes">Name</property>
+                    <property name="title" translatable="yes">Status</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderertext1"/>
                       <attributes>
-                        <attribute name="text">0</attribute>
+                        <attribute name="text">2</attribute>
                       </attributes>
                     </child>
                   </object>
                 </child>
                 <child>
                   <object class="GtkTreeViewColumn" id="RosterTreeViewColumn2">
-                    <property name="title" translatable="yes">JID</property>
+                    <property name="title" translatable="yes">Name</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderertext2"/>
                       <attributes>
-                        <attribute name="text">1</attribute>
+                        <attribute name="text">0</attribute>
                       </attributes>
                     </child>
                   </object>
diff --git a/src/gui/gtk/JubGtkRosterUI.h b/src/gui/gtk/JubGtkRosterUI.h
index 4b2e50a..5dd3682 100644
--- a/src/gui/gtk/JubGtkRosterUI.h
+++ b/src/gui/gtk/JubGtkRosterUI.h
@@ -16,7 +16,6 @@
 	OFMapTable *groupMap;
 	OFMutableDictionary *contactMap;
 	OFMutableDictionary *chatMap;
-	OFCountedSet *presences;
 	JubChatClient *client;
 }
 
diff --git a/src/gui/gtk/JubGtkRosterUI.m b/src/gui/gtk/JubGtkRosterUI.m
index 5826aa1..bc1b368 100644
--- a/src/gui/gtk/JubGtkRosterUI.m
+++ b/src/gui/gtk/JubGtkRosterUI.m
@@ -56,28 +56,17 @@ static void presence_changed(GtkComboBox *combo_box, gpointer data)
 static gboolean filter_roster_by_presence(GtkTreeModel *model,
     GtkTreeIter *iter, gpointer data)
 {
-	char *jid_s;
-	OFString *jid;
-	OFCountedSet *presences = data;
+	char *status;
+	gtk_tree_model_get(model, iter, 2, &status, -1);
 
-	gtk_tree_model_get(model, iter, 1, &jid_s, -1);
-
-	// Groups have no JID
-	if (!jid_s)
+	// Groups have no status
+	if (!status)
 		return TRUE;
 
-	jid = [[OFString alloc] initWithUTF8String: jid_s];
-
-	g_free(jid_s);
-
-	int num = [presences countForObject: jid];
-	if (num) {
-		[jid release];
-		return TRUE;
-	} else {
-		[jid release];
+	if (!strcmp(status, "unavailable"))
 		return FALSE;
-	}
+
+	return TRUE;
 }
 
 @implementation JubGtkRosterUI
@@ -94,7 +83,6 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 			  valueFunctions: rowRefFunctions];
 		contactMap = [[OFMutableDictionary alloc] init];
 		chatMap = [[OFMutableDictionary alloc] init];
-		presences = [[OFCountedSet alloc] init];
 		client = [client_ retain];
 
 		[client.contactManager addDelegate: self];
@@ -115,7 +103,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 		    gtk_builder_get_object(builder, "RosterTreeModelFilter"));
 
 		gtk_tree_model_filter_set_visible_func(roster_filter,
-		    filter_roster_by_presence, presences, NULL);
+		    filter_roster_by_presence, NULL, NULL);
 
 		roster_view = GTK_TREE_VIEW(gtk_builder_get_object(builder,
 			"RosterTreeView"));
@@ -145,7 +133,6 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 	[groupMap release];
 	[contactMap release];
 	[chatMap release];
-	[presences release];
 	[client release];
 
 	gtk_widget_destroy(roster_window);
@@ -247,11 +234,13 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 		if (item.name)
 			gtk_tree_store_set(roster_model, &contact_iter,
 			    0, [item.name UTF8String],
-			    1, [bareJID UTF8String], -1);
+			    1, [bareJID UTF8String],
+			    2, "unavailable", -1);
 		else
 			gtk_tree_store_set(roster_model, &contact_iter,
 			    0, [item.JID.node UTF8String],
-			    1, [bareJID UTF8String], -1);
+			    1, [bareJID UTF8String],
+			    2, "unavailable", -1);
 
 		contact_path = gtk_tree_model_get_path(GTK_TREE_MODEL(
 			roster_model), &contact_iter);
@@ -280,6 +269,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 		contact_path = gtk_tree_row_reference_get_path(contact_ref);
 		gtk_tree_model_get_iter(GTK_TREE_MODEL(roster_model),
 		    &contact_iter, contact_path);
+		gtk_tree_path_free(contact_path);
 
 		gtk_tree_store_remove(roster_model, &contact_iter);
 
@@ -358,12 +348,32 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 -   (void)contact: (XMPPContact*)contact
   didSendPresence: (XMPPPresence*)presence
 {
-	if ([presence.type isEqual: @"available"])
-		[presences addObject: [presence.from bareJID]];
-	else if ([presence.type isEqual: @"unavailable"])
-		[presences removeObject: [presence.from bareJID]];
-
 	g_idle_add_block(^{
+		GtkTreeIter iter;
+		GtkTreePath *path;
+		GtkTreeRowReference *ref;
+		OFString *bareJID = [contact.rosterItem.JID bareJID];
+		OFMapTable *contactRows = [contactMap objectForKey: bareJID];
+
+		for (OFString *group in contact.rosterItem.groups) {
+			ref = [contactRows valueForKey: group];
+			path = gtk_tree_row_reference_get_path(ref);
+			gtk_tree_model_get_iter(GTK_TREE_MODEL(roster_model),
+			    &iter, path);
+			gtk_tree_path_free(path);
+
+			if ([presence.type isEqual: @"available"])
+				if (presence.show != nil)
+					gtk_tree_store_set(roster_model, &iter,
+					    2, [presence.show UTF8String], -1);
+				else
+					gtk_tree_store_set(roster_model, &iter,
+					    2, "available", -1);
+			else if ([presence.type isEqual: @"unavailable"])
+				gtk_tree_store_set(roster_model, &iter,
+				    2, "unavailable", -1);
+		}
+
 		gtk_tree_model_filter_refilter(roster_filter);
 	});
 }
-- 
2.39.5