From 052f685338462a8c0c6d9785864e7549290d7037 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Tue, 21 Jul 2009 13:24:26 +0200
Subject: Show list of connected users.


diff --git a/Slimber/Cocoa/Menulet.h b/Slimber/Cocoa/Menulet.h
index dfe07a0..fabaa80 100644
--- a/Slimber/Cocoa/Menulet.h
+++ b/Slimber/Cocoa/Menulet.h
@@ -4,12 +4,13 @@
 	NSStatusItem* statusItem;
 	NSMenu* statusMenu;
 	NSImage* menuIcon;
+	NSArray* userNames;
 	BOOL selfOnline;
 }
 
 - (id) init;
 - (void) updateMenu;
-- (void) setUsersOnline: (BOOL) online;
+- (void) setUserNames: (NSArray*) names;
 - (void) setSelfConnected: (BOOL) online;
 
 @end
diff --git a/Slimber/Cocoa/Menulet.m b/Slimber/Cocoa/Menulet.m
index f72078e..9eda07c 100644
--- a/Slimber/Cocoa/Menulet.m
+++ b/Slimber/Cocoa/Menulet.m
@@ -12,7 +12,7 @@
 		[statusItem setToolTip: @"Slimber"];	
 		[statusItem setMenu: statusMenu];
 
-		[self setUsersOnline: NO];
+		userNames = [[NSArray alloc] init];
 		selfOnline = NO;
 
 		[self updateMenu];
@@ -26,13 +26,36 @@
 	[super dealloc];
 }
 
+- (void) updateIcon: (BOOL) online {
+	NSBundle* bundle = [NSBundle bundleForClass: [self class]];
+	NSString* path;
+	if (online) {
+		path = [bundle pathForResource: @"Online" ofType:@"png"];
+	}
+	else {
+		path = [bundle pathForResource: @"Offline" ofType:@"png"];
+	}
+	menuIcon = [[NSImage alloc] initWithContentsOfFile: path];
+	[statusItem setImage: menuIcon];
+}
+
 - (void) updateMenu {
 	while ([statusMenu numberOfItems] > 0) {
 		[statusMenu removeItemAtIndex: 0];
 	}
 
-	NSMenuItem* statusMenuItem = [[NSMenuItem alloc] initWithTitle: @"Online Users" action: NULL keyEquivalent: @""];
-	[statusMenu addItem: statusMenuItem];
+	if ([userNames count] > 0) {
+		[statusMenu addItem: [[NSMenuItem alloc] initWithTitle: @"Online users:" action: NULL keyEquivalent: @""]];
+		int i;
+		for (i = 0; i < [userNames count]; ++i) {
+			NSMenuItem* userItem = [[NSMenuItem alloc] initWithTitle: [@"  " stringByAppendingString: [userNames objectAtIndex: i]] action: NULL keyEquivalent: @""];
+			[statusMenu addItem: userItem];
+		}
+	}
+	else {
+		[statusMenu addItem: [[NSMenuItem alloc] initWithTitle: @"No online users" action: NULL keyEquivalent: @""]];
+	}
+	[self updateIcon: [userNames count] > 0];
 	[statusMenu addItem: [NSMenuItem separatorItem]];
 
 	NSMenuItem* loggedInItem;
@@ -50,22 +73,16 @@
 	[statusMenu addItem: exitMenuItem];
 }
 
-- (void) setUsersOnline: (BOOL) online {
-	NSBundle* bundle = [NSBundle bundleForClass: [self class]];
-	NSString* path;
-	if (online) {
-		path = [bundle pathForResource: @"Online" ofType:@"png"];
-	}
-	else {
-		path = [bundle pathForResource: @"Offline" ofType:@"png"];
-	}
-	menuIcon = [[NSImage alloc] initWithContentsOfFile: path];
-	[statusItem setImage: menuIcon];
-}
-
 - (void) setSelfConnected: (BOOL) online {
 	selfOnline = online;
 	[self updateMenu];
 }
 
+- (void) setUserNames: (NSArray*) names {
+	[names retain];
+	[userNames release];
+	userNames = names;
+	[self updateMenu];
+}
+
 @end
diff --git a/Slimber/Cocoa/Slimber.h b/Slimber/Cocoa/Slimber.h
index f5a02d7..7964581 100644
--- a/Slimber/Cocoa/Slimber.h
+++ b/Slimber/Cocoa/Slimber.h
@@ -2,8 +2,10 @@
 
 #include <string>
 #include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include "Swiften/LinkLocal/DNSSDService.h"
+#include "Swiften/LinkLocal/LinkLocalRoster.h"
 
 @class Menulet;
 namespace Swift {
@@ -17,9 +19,11 @@ class Slimber {
 
 	private:
 		void handleSelfConnected(bool b);
+		void handleRosterChanged();
 
 	private:
 		boost::shared_ptr<Swift::DNSSDService> dnsSDService;
+		boost::shared_ptr<Swift::LinkLocalRoster>linkLocalRoster;
 		Swift::Server* server;
 		Menulet* menulet;
 };
diff --git a/Slimber/Cocoa/Slimber.mm b/Slimber/Cocoa/Slimber.mm
index 74d95ef..d64cd58 100644
--- a/Slimber/Cocoa/Slimber.mm
+++ b/Slimber/Cocoa/Slimber.mm
@@ -1,5 +1,7 @@
 #include "Slimber/Cocoa/Slimber.h"
 
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Elements/RosterPayload.h"
 #include "Swiften/LinkLocal/AppleDNSSDService.h"
 #include "Slimber/Cocoa/Menulet.h"
 #include "Slimber/Server.h"
@@ -8,9 +10,15 @@ using namespace Swift;
 
 Slimber::Slimber() {
 	dnsSDService = boost::shared_ptr<AppleDNSSDService>(new AppleDNSSDService());
-	server = new Server(5222, 5562, dnsSDService);
+
+	linkLocalRoster = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService));
+	linkLocalRoster->onRosterChanged.connect(boost::bind(&Slimber::handleRosterChanged, this));
+
+	server = new Server(5222, 5562, linkLocalRoster, dnsSDService);
 	server->onSelfConnected.connect(boost::bind(&Slimber::handleSelfConnected, this, _1));
+
 	menulet = [[Menulet alloc] init];
+	handleRosterChanged();
 }
 
 Slimber::~Slimber() {
@@ -21,3 +29,16 @@ Slimber::~Slimber() {
 void Slimber::handleSelfConnected(bool b) {
 	[menulet setSelfConnected: b];
 }
+
+void Slimber::handleRosterChanged() {
+	NSMutableArray* names = [[NSMutableArray alloc] init];
+	boost::shared_ptr<RosterPayload> roster = linkLocalRoster->getRoster();
+	foreach(const RosterItemPayload& item, roster->getItems()) {
+		NSString* name = [NSString stringWithUTF8String: item.getName().getUTF8Data()];
+		[names addObject: name];
+		[name release];
+	}
+
+	[menulet setUserNames: names];
+	[names release];
+}
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
index 1922351..53c02a0 100644
--- a/Slimber/Server.cpp
+++ b/Slimber/Server.cpp
@@ -17,11 +17,12 @@
 
 namespace Swift {
 
-Server::Server(int clientConnectionPort, int linkLocalConnectionPort, boost::shared_ptr<DNSSDService> dnsSDService) : 
+Server::Server(int clientConnectionPort, int linkLocalConnectionPort, boost::shared_ptr<LinkLocalRoster> linkLocalRoster, boost::shared_ptr<DNSSDService> dnsSDService) : 
 		dnsSDServiceRegistered_(false), 
 		rosterRequested_(false), 
 		clientConnectionPort_(clientConnectionPort), 
 		linkLocalConnectionPort_(linkLocalConnectionPort),
+		linkLocalRoster_(linkLocalRoster),
 		dnsSDService_(dnsSDService) {
 	serverFromClientConnectionServer_ = 
 			boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
@@ -39,8 +40,6 @@ Server::Server(int clientConnectionPort, int linkLocalConnectionPort, boost::sha
 
 	dnsSDService_->onServiceRegistered.connect
 			(boost::bind(&Server::handleServiceRegistered, this, _1));
-	linkLocalRoster_ = boost::shared_ptr<LinkLocalRoster>(
-			new LinkLocalRoster(dnsSDService_));
 	linkLocalRoster_->onRosterChanged.connect(
 			boost::bind(&Server::handleRosterChanged, this, _1));
 	linkLocalRoster_->onPresenceChanged.connect(
diff --git a/Slimber/Server.h b/Slimber/Server.h
index 5ce9e31..d8b6c6c 100644
--- a/Slimber/Server.h
+++ b/Slimber/Server.h
@@ -24,7 +24,7 @@
 namespace Swift {
 	class Server {
 		public:
-			Server(int clientConnectionPort, int linkLocalConnectionPort, boost::shared_ptr<DNSSDService> dnsSDService);
+			Server(int clientConnectionPort, int linkLocalConnectionPort, boost::shared_ptr<LinkLocalRoster>, boost::shared_ptr<DNSSDService> dnsSDService);
 
 			boost::signal<void (bool)> onSelfConnected;
 
@@ -64,8 +64,8 @@ namespace Swift {
 			bool rosterRequested_;
 			int clientConnectionPort_;
 			int linkLocalConnectionPort_;
-			boost::shared_ptr<DNSSDService> dnsSDService_;
 			boost::shared_ptr<LinkLocalRoster> linkLocalRoster_;
+			boost::shared_ptr<DNSSDService> dnsSDService_;
 			boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer_;
 			boost::shared_ptr<ServerFromClientSession> serverFromClientSession_;
 			boost::shared_ptr<BoostConnectionServer> serverFromNetworkConnectionServer_;
-- 
cgit v0.10.2-6-g49f6