summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Slimber')
-rw-r--r--Slimber/Cocoa/CocoaController.h11
-rw-r--r--Slimber/Cocoa/CocoaController.mm19
-rw-r--r--Slimber/Cocoa/CocoaMenulet.h23
-rw-r--r--Slimber/Cocoa/CocoaMenulet.mm66
-rw-r--r--Slimber/Cocoa/MainController.h9
-rw-r--r--Slimber/Cocoa/MainController.mm15
-rw-r--r--Slimber/Cocoa/MainMenu.xib6
-rw-r--r--Slimber/Cocoa/Makefile.inc11
-rw-r--r--Slimber/Cocoa/Menulet.h17
-rw-r--r--Slimber/Cocoa/Menulet.m105
-rw-r--r--Slimber/MainController.cpp (renamed from Slimber/Cocoa/Slimber.mm)46
-rw-r--r--Slimber/MainController.h (renamed from Slimber/Cocoa/Slimber.h)21
-rw-r--r--Slimber/Makefile.inc5
-rw-r--r--Slimber/Menulet.cpp4
-rw-r--r--Slimber/Menulet.h15
-rw-r--r--Slimber/MenuletController.cpp49
-rw-r--r--Slimber/MenuletController.h30
17 files changed, 264 insertions, 188 deletions
diff --git a/Slimber/Cocoa/CocoaController.h b/Slimber/Cocoa/CocoaController.h
new file mode 100644
index 0000000..f4be87d
--- /dev/null
+++ b/Slimber/Cocoa/CocoaController.h
@@ -0,0 +1,11 @@
+#include <Cocoa/Cocoa.h>
+
+class MainController;
+class CocoaMenulet;
+
+@interface CocoaController : NSObject {
+ CocoaMenulet* menulet;
+ MainController* main;
+}
+
+@end
diff --git a/Slimber/Cocoa/CocoaController.mm b/Slimber/Cocoa/CocoaController.mm
new file mode 100644
index 0000000..437d85a
--- /dev/null
+++ b/Slimber/Cocoa/CocoaController.mm
@@ -0,0 +1,19 @@
+#include "Slimber/Cocoa/CocoaController.h"
+
+#include "Slimber/MainController.h"
+#include "Slimber/Cocoa/CocoaMenulet.h"
+
+@implementation CocoaController
+
+- (void) dealloc {
+ delete main;
+ delete menulet;
+ [super dealloc];
+}
+
+- (void) awakeFromNib {
+ menulet = new CocoaMenulet();
+ main = new MainController(menulet);
+}
+
+@end
diff --git a/Slimber/Cocoa/CocoaMenulet.h b/Slimber/Cocoa/CocoaMenulet.h
new file mode 100644
index 0000000..86f0eaa
--- /dev/null
+++ b/Slimber/Cocoa/CocoaMenulet.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <Cocoa/Cocoa.h>
+
+#include "Slimber/Menulet.h"
+
+class CocoaMenulet : public Menulet {
+ public:
+ CocoaMenulet();
+ ~CocoaMenulet();
+
+ private:
+ virtual void clear();
+ virtual void addItem(const Swift::String& name, const Swift::String& icon);
+ virtual void addSeparator();
+ void setIcon(const Swift::String& icon);
+ virtual void addAboutItem();
+ virtual void addExitItem();
+
+ private:
+ NSStatusItem* statusItem;
+ NSMenu* menu;
+};
diff --git a/Slimber/Cocoa/CocoaMenulet.mm b/Slimber/Cocoa/CocoaMenulet.mm
new file mode 100644
index 0000000..c159aa8
--- /dev/null
+++ b/Slimber/Cocoa/CocoaMenulet.mm
@@ -0,0 +1,66 @@
+#include "Slimber/Cocoa/CocoaMenulet.h"
+
+using namespace Swift;
+
+CocoaMenulet::CocoaMenulet() {
+ menu = [[NSMenu alloc] init];
+
+ statusItem = [[[NSStatusBar systemStatusBar]
+ statusItemWithLength: NSVariableStatusItemLength] retain];
+ [statusItem setHighlightMode: YES];
+ [statusItem setEnabled: YES];
+ [statusItem setToolTip: @"Slimber"];
+ [statusItem setMenu: menu];
+}
+
+CocoaMenulet::~CocoaMenulet() {
+ [statusItem release];
+ [menu release];
+}
+
+void CocoaMenulet::setIcon(const String& icon) {
+ NSString* path = [[NSBundle mainBundle] pathForResource:
+ [NSString stringWithUTF8String: icon.getUTF8Data()] ofType:@"png"];
+ NSImage* image = [[NSImage alloc] initWithContentsOfFile: path];
+ [statusItem setImage: image];
+ [image release];
+}
+
+void CocoaMenulet::clear() {
+ while ([menu numberOfItems] > 0) {
+ [menu removeItemAtIndex: 0];
+ }
+}
+
+void CocoaMenulet::addItem(const Swift::String& name, const String& icon) {
+ NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:
+ [NSString stringWithUTF8String: name.getUTF8Data()]
+ action: NULL keyEquivalent: @""];
+ if (!icon.isEmpty()) {
+ NSString* path = [[NSBundle mainBundle] pathForResource:
+ [NSString stringWithUTF8String: icon.getUTF8Data()] ofType:@"png"];
+ NSImage* image = [[NSImage alloc] initWithContentsOfFile: path];
+ [item setImage: [[NSImage alloc] initWithContentsOfFile: path]];
+ [image release];
+ }
+ [menu addItem: item];
+ [item release];
+}
+
+void CocoaMenulet::addAboutItem() {
+ NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"About Slimber" action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
+ [item setTarget: [NSApplication sharedApplication]];
+ [menu addItem: item];
+ [item release];
+}
+
+void CocoaMenulet::addExitItem() {
+ NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"Exit" action: @selector(terminate:) keyEquivalent: @""];
+ [item setTarget: [NSApplication sharedApplication]];
+ [menu addItem: item];
+ [item release];
+}
+
+void CocoaMenulet::addSeparator() {
+ [menu addItem: [NSMenuItem separatorItem]];
+}
diff --git a/Slimber/Cocoa/MainController.h b/Slimber/Cocoa/MainController.h
deleted file mode 100644
index c6e20c5..0000000
--- a/Slimber/Cocoa/MainController.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <Cocoa/Cocoa.h>
-
-class Slimber;
-
-@interface MainController : NSObject {
- Slimber* slimber;
-}
-
-@end
diff --git a/Slimber/Cocoa/MainController.mm b/Slimber/Cocoa/MainController.mm
deleted file mode 100644
index 30b7a16..0000000
--- a/Slimber/Cocoa/MainController.mm
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "MainController.h"
-#include "Slimber.h"
-
-@implementation MainController
-
-- (void) dealloc {
- delete slimber;
- [super dealloc];
-}
-
-- (void) awakeFromNib {
- slimber = new Slimber();
-}
-
-@end
diff --git a/Slimber/Cocoa/MainMenu.xib b/Slimber/Cocoa/MainMenu.xib
index 50e4ca3..bed7223 100644
--- a/Slimber/Cocoa/MainMenu.xib
+++ b/Slimber/Cocoa/MainMenu.xib
@@ -180,7 +180,7 @@
<string key="NSName">_NSMainMenu</string>
</object>
<object class="NSCustomObject" id="16040424">
- <string key="NSClassName">MainController</string>
+ <string key="NSClassName">CocoaController</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
@@ -482,11 +482,11 @@
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.1+">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
- <string key="className">MainController</string>
+ <string key="className">CocoaController</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBDocumentRelativeSource</string>
- <string key="minorKey">MainController.h</string>
+ <string key="minorKey">CocoaController.h</string>
</object>
</object>
</object>
diff --git a/Slimber/Cocoa/Makefile.inc b/Slimber/Cocoa/Makefile.inc
index 8cd72cd..6d225a7 100644
--- a/Slimber/Cocoa/Makefile.inc
+++ b/Slimber/Cocoa/Makefile.inc
@@ -2,10 +2,9 @@ SLIMBER_COCOA_TARGET = Slimber/Cocoa/Slimber.app
SLIMBER_COCOA_BINARY = \
Slimber/Cocoa/Slimber
SLIMBER_COCOA_SOURCES = \
- Slimber/Cocoa/MainController.mm \
- Slimber/Cocoa/Slimber.mm \
Slimber/Cocoa/main.mm \
- Slimber/Cocoa/Menulet.m
+ Slimber/Cocoa/CocoaController.mm \
+ Slimber/Cocoa/CocoaMenulet.mm
SLIMBER_COCOA_XIBS = \
Slimber/Cocoa/MainMenu.xib
SLIMBER_COCOA_RESOURCES = \
@@ -26,8 +25,8 @@ CLEANFILES += \
$(SLIMBER_COCOA_NIBS) \
$(SLIMBER_COCOA_TARGET) \
$(SLIMBER_COCOA_BINARY)
-//DEPS += \
-// $(SLIMBER_COCOA_SOURCES:.m=.dep) \
+DEPS += \
+ $(SLIMBER_COCOA_SOURCES:.mm=.dep)
.PHONY: slimber-cocoa
slimber-cocoa: $(SLIMBER_COCOA_TARGET)
@@ -42,5 +41,5 @@ $(SLIMBER_COCOA_TARGET): $(SLIMBER_COCOA_BINARY) $(SLIMBER_COCOA_NIBS) Slimber/C
cp $(SLIMBER_COCOA_NIBS) $(SLIMBER_COCOA_TARGET)/Contents/Resources
cp $(SLIMBER_COCOA_RESOURCES) $(SLIMBER_COCOA_TARGET)/Contents/Resources
-$(SLIMBER_COCOA_BINARY): $(SLIMBER_COCOA_OBJECTS) $(SWIFTEN_TARGET) $(SLIMBER_TRGET)
+$(SLIMBER_COCOA_BINARY): $(SLIMBER_COCOA_OBJECTS) $(SWIFTEN_TARGET) $(SLIMBER_TARGET)
$(QUIET_LINK)$(CXX) -o $@ $(SLIMBER_COCOA_OBJECTS) $(LDFLAGS) $(SLIMBER_TARGET) $(SWIFTEN_TARGET) $(LIBS) -framework Cocoa
diff --git a/Slimber/Cocoa/Menulet.h b/Slimber/Cocoa/Menulet.h
deleted file mode 100644
index 823213f..0000000
--- a/Slimber/Cocoa/Menulet.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <Cocoa/Cocoa.h>
-
-@interface Menulet : NSObject {
- NSStatusItem* statusItem;
- NSMenu* statusMenu;
- NSImage* menuIcon;
- NSArray* userNames;
- BOOL xmppOnline;
- NSString* xmppStatus;
-}
-
-- (id) init;
-- (void) updateMenu;
-- (void) setUserNames: (NSArray*) names;
-- (void) setXMPPStatus: (NSString*) status online: (BOOL) online;
-
-@end
diff --git a/Slimber/Cocoa/Menulet.m b/Slimber/Cocoa/Menulet.m
deleted file mode 100644
index 2a62992..0000000
--- a/Slimber/Cocoa/Menulet.m
+++ /dev/null
@@ -1,105 +0,0 @@
-#import "Menulet.h"
-
-@implementation Menulet
-
-- (id) init {
- if ([super init]) {
- statusMenu = [[NSMenu alloc] init];
-
- statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength: NSVariableStatusItemLength] retain];
- [statusItem setHighlightMode: YES];
- [statusItem setEnabled: YES];
- [statusItem setToolTip: @"Slimber"];
- [statusItem setMenu: statusMenu];
-
- xmppStatus = @"";
- xmppOnline = NO;
- userNames = [[NSArray alloc] init];
-
- [self updateMenu];
- }
- return self;
-}
-
-- (void) dealloc {
- [statusItem release];
- [menuIcon release];
- [super dealloc];
-}
-
-- (void) updateIcon: (BOOL) online {
- NSBundle* bundle = [NSBundle bundleForClass: [self class]];
- NSString* path;
- if (online) {
- path = [bundle pathForResource: @"UsersOnline" ofType:@"png"];
- }
- else {
- path = [bundle pathForResource: @"UsersOffline" ofType:@"png"];
- }
- [statusItem setImage: [[NSImage alloc] initWithContentsOfFile: path]];
-}
-
-- (void) updateMenu {
- // Clear the menu
- while ([statusMenu numberOfItems] > 0) {
- [statusMenu removeItemAtIndex: 0];
- }
-
- // User items
- if ([userNames count] > 0) {
- [statusMenu addItem: [[NSMenuItem alloc] initWithTitle: @"Online users:" action: NULL keyEquivalent: @""]];
- int i;
- for (i = 0; i < [userNames count]; ++i) {
- NSString* text = [NSString stringWithFormat: @" %@", [userNames objectAtIndex: i]];
- NSMenuItem* userItem = [[NSMenuItem alloc] initWithTitle: text action: NULL keyEquivalent: @""];
- [statusMenu addItem: userItem];
- [userItem release];
- }
- }
- else {
- [statusMenu addItem: [[NSMenuItem alloc] initWithTitle: @"No online users" action: NULL keyEquivalent: @""]];
- }
- [self updateIcon: [userNames count] > 0];
- [statusMenu addItem: [NSMenuItem separatorItem]];
-
- // Self item
- NSMenuItem* loggedInItem;
- NSBundle* bundle = [NSBundle bundleForClass: [self class]];
- NSString* path;
- loggedInItem = [[NSMenuItem alloc] initWithTitle: xmppStatus action: NULL keyEquivalent: @""];
- if (xmppOnline) {
- path = [bundle pathForResource: @"Online" ofType:@"png"];
- }
- else {
- path = [bundle pathForResource: @"Offline" ofType:@"png"];
- }
- [loggedInItem setImage: [[NSImage alloc] initWithContentsOfFile: path]];
- [statusMenu addItem: loggedInItem];
- [statusMenu addItem: [NSMenuItem separatorItem]];
-
- // About menu
- NSMenuItem* aboutMenuItem = [[NSMenuItem alloc] initWithTitle: @"About Slimber" action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
- [aboutMenuItem setTarget: [NSApplication sharedApplication]];
- [statusMenu addItem: aboutMenuItem];
- [statusMenu addItem: [NSMenuItem separatorItem]];
-
- // Exit item
- NSMenuItem* exitMenuItem = [[NSMenuItem alloc] initWithTitle: @"Exit" action: @selector(terminate:) keyEquivalent: @""];
- [exitMenuItem setTarget: [NSApplication sharedApplication]];
- [statusMenu addItem: exitMenuItem];
-}
-
-- (void) setXMPPStatus: (NSString*) status online: (BOOL) online {
- xmppStatus = status; // TODO: Should I retain status?
- xmppOnline = online;
- [self updateMenu];
-}
-
-- (void) setUserNames: (NSArray*) names {
- [names retain];
- [userNames release];
- userNames = names;
- [self updateMenu];
-}
-
-@end
diff --git a/Slimber/Cocoa/Slimber.mm b/Slimber/MainController.cpp
index 9e15614..2d196a5 100644
--- a/Slimber/Cocoa/Slimber.mm
+++ b/Slimber/MainController.cpp
@@ -1,4 +1,4 @@
-#include "Slimber/Cocoa/Slimber.h"
+#include "Slimber/MainController.h"
#include <boost/bind.hpp>
@@ -7,23 +7,24 @@
#include "Swiften/LinkLocal/LinkLocalService.h"
#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h"
#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h"
-#include "Slimber/Cocoa/Menulet.h"
#include "Slimber/Server.h"
#include "Slimber/FileVCardCollection.h"
+#include "Slimber/MenuletController.h"
+#include "Slimber/Menulet.h"
using namespace Swift;
-Slimber::Slimber() {
+MainController::MainController(Menulet* menulet) : menulet(menulet) {
dnsSDQuerier = boost::shared_ptr<BonjourQuerier>(new BonjourQuerier());
dnsSDQuerier->start();
linkLocalServiceBrowser = new LinkLocalServiceBrowser(dnsSDQuerier);
linkLocalServiceBrowser->onServiceAdded.connect(
- boost::bind(&Slimber::handleServicesChanged, this));
+ boost::bind(&MainController::handleServicesChanged, this));
linkLocalServiceBrowser->onServiceRemoved.connect(
- boost::bind(&Slimber::handleServicesChanged, this));
+ boost::bind(&MainController::handleServicesChanged, this));
linkLocalServiceBrowser->onServiceChanged.connect(
- boost::bind(&Slimber::handleServicesChanged, this));
+ boost::bind(&MainController::handleServicesChanged, this));
linkLocalServiceBrowser->start();
vCardCollection = new FileVCardCollection(
@@ -31,19 +32,20 @@ Slimber::Slimber() {
server = new Server(5222, 5562, linkLocalServiceBrowser, vCardCollection);
server->onStopped.connect(
- boost::bind(&Slimber::handleServerStopped, this, _1));
+ boost::bind(&MainController::handleServerStopped, this, _1));
server->onSelfConnected.connect(
- boost::bind(&Slimber::handleSelfConnected, this, _1));
+ boost::bind(&MainController::handleSelfConnected, this, _1));
+
+ menuletController = new MenuletController(menulet);
- menulet = [[Menulet alloc] init];
handleSelfConnected(false);
handleServicesChanged();
server->start();
}
-Slimber::~Slimber() {
- [menulet release];
+MainController::~MainController() {
+ delete menuletController;
delete server;
delete vCardCollection;
linkLocalServiceBrowser->stop();
@@ -51,30 +53,28 @@ Slimber::~Slimber() {
dnsSDQuerier->stop();
}
-void Slimber::handleSelfConnected(bool b) {
+void MainController::handleSelfConnected(bool b) {
if (b) {
- [menulet setXMPPStatus: @"You are logged in" online: true];
+ menuletController->setXMPPStatus("You are logged in", MenuletController::Online);
}
else {
- [menulet setXMPPStatus: @"You are not logged in" online: false];
+ menuletController->setXMPPStatus("You are not logged in", MenuletController::Offline);
}
}
-void Slimber::handleServicesChanged() {
- NSMutableArray* names = [[NSMutableArray alloc] init];
+void MainController::handleServicesChanged() {
+ std::vector<String> names;
foreach(const LinkLocalService& service, linkLocalServiceBrowser->getServices()) {
- [names addObject: [NSString stringWithUTF8String: service.getDescription().getUTF8Data()]];
+ names.push_back(service.getDescription());
}
-
- [menulet setUserNames: names];
- [names release];
+ menuletController->setUserNames(names);
}
-void Slimber::handleServerStopped(boost::optional<ServerError> error) {
+void MainController::handleServerStopped(boost::optional<ServerError> error) {
if (error) {
- [menulet setXMPPStatus: @"XMPP Server Error." online: false];
+ menuletController->setXMPPStatus("XMPP Server Error", MenuletController::Offline);
}
else {
- [menulet setXMPPStatus: @"XMPP Server Not Runnning." online: false];
+ menuletController->setXMPPStatus("XMPP Server Not Running", MenuletController::Offline);
}
}
diff --git a/Slimber/Cocoa/Slimber.h b/Slimber/MainController.h
index fdce501..8d355fe 100644
--- a/Slimber/Cocoa/Slimber.h
+++ b/Slimber/MainController.h
@@ -5,18 +5,20 @@
#include "Slimber/ServerError.h"
-@class Menulet;
namespace Swift {
- class Server;
- class VCardCollection;
+ class DNSSDQuerier;
class LinkLocalServiceBrowser;
- class BonjourQuerier;
+ class VCardCollection;
+ class Server;
}
-class Slimber {
+class MenuletController;
+class Menulet;
+
+class MainController {
public:
- Slimber();
- ~Slimber();
+ MainController(Menulet* menulet);
+ virtual ~MainController();
private:
void handleSelfConnected(bool b);
@@ -24,9 +26,10 @@ class Slimber {
void handleServerStopped(boost::optional<Swift::ServerError> error);
private:
- boost::shared_ptr<Swift::BonjourQuerier> dnsSDQuerier;
+ Menulet* menulet;
+ boost::shared_ptr<Swift::DNSSDQuerier> dnsSDQuerier;
Swift::LinkLocalServiceBrowser* linkLocalServiceBrowser;
Swift::VCardCollection* vCardCollection;
Swift::Server* server;
- Menulet* menulet;
+ MenuletController* menuletController;
};
diff --git a/Slimber/Makefile.inc b/Slimber/Makefile.inc
index 16fcb8f..2821d18 100644
--- a/Slimber/Makefile.inc
+++ b/Slimber/Makefile.inc
@@ -3,7 +3,10 @@ SLIMBER_SOURCES = \
Slimber/LinkLocalPresenceManager.cpp \
Slimber/FileVCardCollection.cpp \
Slimber/VCardCollection.cpp \
- Slimber/Server.cpp
+ Slimber/Server.cpp \
+ Slimber/MainController.cpp \
+ Slimber/MenuletController.cpp \
+ Slimber/Menulet.cpp
SLIMBER_OBJECTS = \
$(SLIMBER_SOURCES:.cpp=.o)
diff --git a/Slimber/Menulet.cpp b/Slimber/Menulet.cpp
new file mode 100644
index 0000000..bdadb98
--- /dev/null
+++ b/Slimber/Menulet.cpp
@@ -0,0 +1,4 @@
+#include "Slimber/Menulet.h"
+
+Menulet::~Menulet() {
+}
diff --git a/Slimber/Menulet.h b/Slimber/Menulet.h
new file mode 100644
index 0000000..631fbbd
--- /dev/null
+++ b/Slimber/Menulet.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Swiften/Base/String.h"
+
+class Menulet {
+ public:
+ virtual ~Menulet();
+
+ virtual void clear() = 0;
+ virtual void addItem(const Swift::String& name, const Swift::String& icon = Swift::String()) = 0;
+ virtual void addAboutItem() = 0;
+ virtual void addExitItem() = 0;
+ virtual void addSeparator() = 0;
+ virtual void setIcon(const Swift::String&) = 0;
+};
diff --git a/Slimber/MenuletController.cpp b/Slimber/MenuletController.cpp
new file mode 100644
index 0000000..09face5
--- /dev/null
+++ b/Slimber/MenuletController.cpp
@@ -0,0 +1,49 @@
+#include "Slimber/MenuletController.h"
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Base/String.h"
+#include "Slimber/Menulet.h"
+
+#include <iostream>
+
+using namespace Swift;
+
+MenuletController::MenuletController(Menulet* menulet) :
+ menulet(menulet), xmppStatus(Offline) {
+ update();
+}
+
+MenuletController::~MenuletController() {
+}
+
+void MenuletController::setXMPPStatus(const String& message, Status status) {
+ xmppStatus = status;
+ xmppStatusMessage = message;
+ update();
+}
+
+void MenuletController::setUserNames(const std::vector<String>& users) {
+ linkLocalUsers = users;
+ update();
+}
+
+void MenuletController::update() {
+ menulet->clear();
+ if (linkLocalUsers.empty()) {
+ menulet->setIcon("UsersOffline");
+ menulet->addItem("No online users");
+ }
+ else {
+ menulet->setIcon("UsersOnline");
+ menulet->addItem("Online users:");
+ foreach(const String& user, linkLocalUsers) {
+ menulet->addItem(user);
+ }
+ }
+ menulet->addSeparator();
+ menulet->addItem(xmppStatusMessage, (xmppStatus == Online ? "Online" : "Offline"));
+ menulet->addSeparator();
+ menulet->addAboutItem();
+ menulet->addSeparator();
+ menulet->addExitItem();
+}
diff --git a/Slimber/MenuletController.h b/Slimber/MenuletController.h
new file mode 100644
index 0000000..4073900
--- /dev/null
+++ b/Slimber/MenuletController.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <vector>
+
+#include "Swiften/Base/String.h"
+
+class Menulet;
+
+class MenuletController {
+ public:
+ enum Status {
+ Online,
+ Offline
+ };
+
+ MenuletController(Menulet*);
+ virtual ~MenuletController();
+
+ void setXMPPStatus(const Swift::String& message, Status status);
+ void setUserNames(const std::vector<Swift::String>&);
+
+ private:
+ void update();
+
+ private:
+ Menulet* menulet;
+ Status xmppStatus;
+ Swift::String xmppStatusMessage;
+ std::vector<Swift::String> linkLocalUsers;
+};