summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2009-12-26 22:52:16 (GMT)
committerKevin Smith <git@kismith.co.uk>2009-12-26 22:52:16 (GMT)
commitc3bda61b09597a7944fbc382366bcdf998540e82 (patch)
treea710af80c7e494a60a2676d3595ba4ab3a5ccf79
parent21532c3557a3dc43f5f0376bf6554f6895c71a03 (diff)
downloadswift-c3bda61b09597a7944fbc382366bcdf998540e82.zip
swift-c3bda61b09597a7944fbc382366bcdf998540e82.tar.bz2
More thoroughly test the chat routing.
This adds in the behaviour for unbinding chats when the resource goes offline (only if there isn't already an unbound chatwindow). Resolves: #155
-rw-r--r--Swift/Controllers/ChatsManager.cpp38
-rw-r--r--Swift/Controllers/ChatsManager.h4
-rw-r--r--Swift/Controllers/UnitTest/ChatsManagerTest.cpp141
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h3
4 files changed, 166 insertions, 20 deletions
diff --git a/Swift/Controllers/ChatsManager.cpp b/Swift/Controllers/ChatsManager.cpp
index ef187f4..fe8efb3 100644
--- a/Swift/Controllers/ChatsManager.cpp
+++ b/Swift/Controllers/ChatsManager.cpp
@@ -1,139 +1,157 @@
#include "Swift/Controllers/ChatsManager.h"
+#include <boost/bind.hpp>
+
#include "Swiften/Client/Client.h"
#include "Swift/Controllers/ChatController.h"
#include "Swift/Controllers/EventController.h"
#include "Swift/Controllers/MUCController.h"
#include "Swiften/Presence/PresenceSender.h"
namespace Swift {
typedef std::pair<JID, ChatController*> JIDChatControllerPair;
typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender) : jid_(jid) {
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
iqRouter_ = iqRouter;
chatWindowFactory_ = chatWindowFactory;
treeWidgetFactory_ = treeWidgetFactory;
nickResolver_ = nickResolver;
presenceOracle_ = presenceOracle;
avatarManager_ = NULL;
serverDiscoInfo_ = serverDiscoInfo;
presenceSender_ = presenceSender;
+ presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1, _2));
}
ChatsManager::~ChatsManager() {
foreach (JIDChatControllerPair controllerPair, chatControllers_) {
delete controllerPair.second;
}
foreach (JIDMUCControllerPair controllerPair, mucControllers_) {
delete controllerPair.second;
}
}
+/**
+ * If a resource goes offline, release bound chatdialog to that resource.
+ */
+void ChatsManager::handlePresenceChange(boost::shared_ptr<Presence> /*oldPresence*/, boost::shared_ptr<Presence> newPresence) {
+ if (newPresence->getType() != Presence::Unavailable) return;
+ JID fullJID(newPresence->getFrom());
+ std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID);
+ if (it == chatControllers_.end()) return;
+ JID bareJID(fullJID.toBare());
+ //It doesn't make sense to have two unbound dialogs.
+ if (chatControllers_.find(bareJID) != chatControllers_.end()) return;
+ rebindControllerJID(fullJID, bareJID);
+}
+
void ChatsManager::setAvatarManager(AvatarManager* avatarManager) {
avatarManager_ = avatarManager;
}
// void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
// {
// boost::shared_ptr<RequestChatUIEvent> event = boost::dynamic_pointer_cast<RequestChatUIEvent>(rawEvent);
// if (event != NULL) {
// handleChatRequest(event->getContact());
// return;
// }
// }
// {
// boost::shared_ptr<JoinMUCUIEvent> event = boost::dynamic_pointer_cast<JoinMUCUIEvent>(rawEvent);
// if (event != NULL) {
// handleJoinMUCRequest(event->getRoom(), event->getNick());
// }
// }
// }
void ChatsManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) {
foreach (JIDChatControllerPair pair, chatControllers_) {
pair.second->setAvailableServerFeatures(info);
}
foreach (JIDMUCControllerPair pair, mucControllers_) {
pair.second->setAvailableServerFeatures(info);
}
}
void ChatsManager::setEnabled(bool enabled) {
foreach (JIDChatControllerPair controllerPair, chatControllers_) {
//printf("Setting enabled on %d to %d\n", controllerPair.second, enabled);
controllerPair.second->setEnabled(enabled);
}
foreach (JIDMUCControllerPair controllerPair, mucControllers_) {
controllerPair.second->setEnabled(enabled);
}
}
void ChatsManager::handleChatRequest(const String &contact) {
ChatController* controller = getChatController(JID(contact));
controller->showChatWindow();
controller->activateChatWindow();
}
ChatController* ChatsManager::getChatController(const JID &contact) {
- JID lookupContact(contact);
- if (chatControllers_.find(lookupContact) == chatControllers_.end()) {
- lookupContact = JID(contact.toBare());
- }
- if (chatControllers_.find(lookupContact) == chatControllers_.end()) {
- chatControllers_[contact] = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_);
- chatControllers_[contact]->setAvailableServerFeatures(serverDiscoInfo_);
- lookupContact = contact;
+ if (chatControllers_.find(contact) == chatControllers_.end()) {
+ //Need to look for an unboud window to bind first
+ JID bare(contact.toBare());
+ if (chatControllers_.find(bare) != chatControllers_.end()) {
+ rebindControllerJID(bare, contact);
+ } else {
+ chatControllers_[contact] = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_);
+ chatControllers_[contact]->setAvailableServerFeatures(serverDiscoInfo_);
+ }
}
- return chatControllers_[lookupContact];
+ return chatControllers_[contact];
}
-void ChatsManager::handleChatControllerJIDChanged(const JID& from, const JID& to) {
+void ChatsManager::rebindControllerJID(const JID& from, const JID& to) {
chatControllers_[to] = chatControllers_[from];
chatControllers_.erase(from);
}
void ChatsManager::handleJoinMUCRequest(const JID &muc, const String &nick) {
mucControllers_[muc] = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_);
mucControllers_[muc]->setAvailableServerFeatures(serverDiscoInfo_);
}
void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
JID jid = message->getFrom();
boost::shared_ptr<MessageEvent> event(new MessageEvent(message));
if (!event->isReadable()) {
return;
}
// Try to deliver it to a MUC
if (message->getType() == Message::Groupchat || message->getType() == Message::Error) {
std::map<JID, MUCController*>::iterator i = mucControllers_.find(jid.toBare());
if (i != mucControllers_.end()) {
i->second->handleIncomingMessage(event);
return;
}
else if (message->getType() == Message::Groupchat) {
//FIXME: Error handling - groupchat messages from an unknown muc.
return;
}
}
//if not a mucroom
eventController_->handleIncomingEvent(event);
getChatController(jid)->handleIncomingMessage(event);
}
bool ChatsManager::isMUC(const JID& jid) const {
return mucControllers_.find(jid.toBare()) != mucControllers_.end();
}
}
diff --git a/Swift/Controllers/ChatsManager.h b/Swift/Controllers/ChatsManager.h
index e897e59..260bd1d 100644
--- a/Swift/Controllers/ChatsManager.h
+++ b/Swift/Controllers/ChatsManager.h
@@ -1,54 +1,56 @@
#pragma once
#include <map>
#include <boost/shared_ptr.hpp>
#include "Swiften/Base/String.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Elements/Message.h"
+#include "Swiften/Elements/Presence.h"
#include "Swiften/JID/JID.h"
#include "Swiften/MUC/MUCRegistry.h"
namespace Swift {
class EventController;
class ChatController;
class MUCController;
class ChatWindowFactory;
class TreeWidgetFactory;
class NickResolver;
class PresenceOracle;
class AvatarManager;
class StanzaChannel;
class IQRouter;
class PresenceSender;
class ChatsManager : public MUCRegistry {
public:
ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender);
~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setEnabled(bool enabled);
void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<Message> message);
void handleChatRequest(const String& contact);
void handleJoinMUCRequest(const JID& muc, const String& nick);
private:
- void handleChatControllerJIDChanged(const JID& from, const JID& to);
+ void rebindControllerJID(const JID& from, const JID& to);
+ void handlePresenceChange(boost::shared_ptr<Presence> oldPresence, boost::shared_ptr<Presence> newPresence);
ChatController* getChatController(const JID &contact);
virtual bool isMUC(const JID& muc) const;
std::map<JID, MUCController*> mucControllers_;
std::map<JID, ChatController*> chatControllers_;
EventController* eventController_;
JID jid_;
StanzaChannel* stanzaChannel_;
IQRouter* iqRouter_;;
ChatWindowFactory* chatWindowFactory_;
TreeWidgetFactory* treeWidgetFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
PresenceSender* presenceSender_;
boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
};
}
diff --git a/Swift/Controllers/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/UnitTest/ChatsManagerTest.cpp
index 071cd5b..9df244f 100644
--- a/Swift/Controllers/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/UnitTest/ChatsManagerTest.cpp
@@ -1,144 +1,269 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include "3rdParty/hippomocks.h"
#include "Swift/Controllers/ChatsManager.h"
#include "Swift/Controllers/ChatWindow.h"
#include "Swift/Controllers/ChatWindowFactory.h"
#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Client/Client.h"
#include "Swift/Controllers/ChatController.h"
#include "Swift/Controllers/EventController.h"
#include "Swift/Controllers/MUCController.h"
#include "Swiften/Presence/PresenceSender.h"
#include "Swiften/Avatars/UnitTest/MockAvatarManager.h"
#include "Swift/Controllers/NickResolver.h"
#include "Swiften/Roster/XMPPRoster.h"
#include "Swift/Controllers/UnitTest/MockChatWindow.h"
#include "Swiften/Client/DummyStanzaChannel.h"
#include "Swiften/Queries/DummyIQChannel.h"
#include "Swiften/Presence/PresenceOracle.h"
using namespace Swift;
class ChatsManagerTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(ChatsManagerTest);
CPPUNIT_TEST(testFirstOpenWindowIncoming);
+ CPPUNIT_TEST(testSecondOpenWindowIncoming);
CPPUNIT_TEST(testFirstOpenWindowOutgoing);
CPPUNIT_TEST(testFirstOpenWindowBareToFull);
CPPUNIT_TEST(testSecondWindow);
+ CPPUNIT_TEST(testUnbindRebind);
+ CPPUNIT_TEST(testNoDuplicateUnbind);
CPPUNIT_TEST_SUITE_END();
public:
ChatsManagerTest() {};
void setUp() {
mocks_ = new MockRepository();
jid_ = JID("test@test.com/resource");
stanzaChannel_ = new DummyStanzaChannel();
iqChannel_ = new DummyIQChannel();
iqRouter_ = new IQRouter(iqChannel_);
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
treeWidgetFactory_ = NULL;
xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
nickResolver_ = new NickResolver(xmppRoster_);
presenceOracle_ = new PresenceOracle(stanzaChannel_);
serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
presenceSender_ = NULL;
manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_);
avatarManager_ = new MockAvatarManager();
manager_->setAvatarManager(avatarManager_);
};
void tearDown() {
delete manager_;
delete presenceSender_;
delete avatarManager_;
delete presenceOracle_;
delete nickResolver_;
delete treeWidgetFactory_;
delete stanzaChannel_;
delete iqChannel_;
delete iqRouter_;
delete mocks_;
}
void testFirstOpenWindowIncoming() {
JID messageJID("testling@test.com/resource1");
- ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID).Return(window);
boost::shared_ptr<Message> message(new Message());
message->setFrom(messageJID);
- message->setBody("This is a legible message.");
+ String body("This is a legible message. >HEH@)oeueu");
+ message->setBody(body);
manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_);
+ }
+
+ void testSecondOpenWindowIncoming() {
+ JID messageJID1("testling@test.com/resource1");
+
+ MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1).Return(window1);
+
+ boost::shared_ptr<Message> message1(new Message());
+ message1->setFrom(messageJID1);
+ String body1("This is a legible message. >HEH@)oeueu");
+ message1->setBody(body1);
+ manager_->handleIncomingMessage(message1);
+ CPPUNIT_ASSERT_EQUAL(body1, window1->lastMessageBody_);
+
+ JID messageJID2("testling@test.com/resource2");
+
+ MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2).Return(window2);
+
+ boost::shared_ptr<Message> message2(new Message());
+ message2->setFrom(messageJID2);
+ String body2("This is a legible message. .cmaulm.chul");
+ message2->setBody(body2);
+ manager_->handleIncomingMessage(message2);
+ CPPUNIT_ASSERT_EQUAL(body2, window2->lastMessageBody_);
}
void testFirstOpenWindowOutgoing() {
String messageJIDString("testling@test.com");
ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString)).Return(window);
manager_->handleChatRequest(messageJIDString);
}
void testFirstOpenWindowBareToFull() {
String bareJIDString("testling@test.com");
String fullJIDString("testling@test.com/resource1");
MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString)).Return(window);
manager_->handleChatRequest(bareJIDString);
boost::shared_ptr<Message> message(new Message());
message->setFrom(JID(fullJIDString));
- message->setBody("This is a legible message.");
+ String body("This is a legible message. mjuga3089gm8G(*>M)@*(");
+ message->setBody(body);
manager_->handleIncomingMessage(message);
- /*FIXME: check the message got through. For now, checking that there isn't a new window created is useful enough.*/
- //CPPUNIT_ASSERT_EQUAL(fullJIDString, window->name_);
+ CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_);
}
void testSecondWindow() {
String messageJIDString1("testling1@test.com");
-
ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1)).Return(window1);
-
manager_->handleChatRequest(messageJIDString1);
String messageJIDString2("testling2@test.com");
-
ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2)).Return(window2);
manager_->handleChatRequest(messageJIDString2);
}
+ /** Complete cycle.
+ Create unbound window.
+ Bind it.
+ Unbind it.
+ Rebind it.
+ */
+ void testUnbindRebind() {
+ String bareJIDString("testling@test.com");
+ String fullJIDString1("testling@test.com/resource1");
+ String fullJIDString2("testling@test.com/resource2");
+
+ MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString)).Return(window);
+ manager_->handleChatRequest(bareJIDString);
+
+ boost::shared_ptr<Message> message1(new Message());
+ message1->setFrom(JID(fullJIDString1));
+ String messageBody1("This is a legible message.");
+ message1->setBody(messageBody1);
+ manager_->handleIncomingMessage(message1);
+ CPPUNIT_ASSERT_EQUAL(messageBody1, window->lastMessageBody_);
+
+ boost::shared_ptr<Presence> jid1Online(new Presence());
+ jid1Online->setFrom(JID(fullJIDString1));
+ boost::shared_ptr<Presence> jid1Offline(new Presence());
+ jid1Offline->setFrom(JID(fullJIDString1));
+ jid1Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid1Online, jid1Offline);
+
+ boost::shared_ptr<Message> message2(new Message());
+ message2->setFrom(JID(fullJIDString2));
+ String messageBody2("This is another legible message.");
+ message2->setBody(messageBody2);
+ manager_->handleIncomingMessage(message2);
+ CPPUNIT_ASSERT_EQUAL(messageBody2, window->lastMessageBody_);
+ }
+
+ /**
+ Test that a second window isn't unbound where there's already an unbound one.
+ Bind 1
+ Bind 2
+ Unbind 1
+ Unbind 2 (but it doesn't)
+ Sent to bound 2
+ Rebind 1
+ */
+ void testNoDuplicateUnbind() {
+ JID messageJID1("testling@test.com/resource1");
+
+ MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1).Return(window1);
+
+ boost::shared_ptr<Message> message1(new Message());
+ message1->setFrom(messageJID1);
+ message1->setBody("This is a legible message1.");
+ manager_->handleIncomingMessage(message1);
+
+ JID messageJID2("testling@test.com/resource2");
+
+ MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2).Return(window2);
+
+ boost::shared_ptr<Message> message2(new Message());
+ message2->setFrom(messageJID2);
+ message2->setBody("This is a legible message2.");
+ manager_->handleIncomingMessage(message2);
+
+ boost::shared_ptr<Presence> jid1Online(new Presence());
+ jid1Online->setFrom(JID(messageJID1));
+ boost::shared_ptr<Presence> jid1Offline(new Presence());
+ jid1Offline->setFrom(JID(messageJID1));
+ jid1Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid1Online, jid1Offline);
+
+ boost::shared_ptr<Presence> jid2Online(new Presence());
+ jid2Online->setFrom(JID(messageJID2));
+ boost::shared_ptr<Presence> jid2Offline(new Presence());
+ jid2Offline->setFrom(JID(messageJID2));
+ jid2Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid2Online, jid2Offline);
+
+ JID messageJID3("testling@test.com/resource3");
+
+ boost::shared_ptr<Message> message3(new Message());
+ message3->setFrom(messageJID3);
+ String body3("This is a legible message3.");
+ message3->setBody(body3);
+ manager_->handleIncomingMessage(message3);
+ CPPUNIT_ASSERT_EQUAL(body3, window1->lastMessageBody_);
+
+ boost::shared_ptr<Message> message2b(new Message());
+ message2b->setFrom(messageJID2);
+ String body2b("This is a legible message2b.");
+ message2b->setBody(body2b);
+ manager_->handleIncomingMessage(message2b);
+ CPPUNIT_ASSERT_EQUAL(body2b, window2->lastMessageBody_);
+ }
private:
JID jid_;
ChatsManager* manager_;
StanzaChannel* stanzaChannel_;
IQChannel* iqChannel_;
IQRouter* iqRouter_;
EventController* eventController_;
ChatWindowFactory* chatWindowFactory_;
TreeWidgetFactory* treeWidgetFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
boost::shared_ptr<XMPPRoster> xmppRoster_;
PresenceSender* presenceSender_;
MockRepository* mocks_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 015bb9b..2625553 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -1,36 +1,37 @@
#pragma once
#include "Swift/Controllers/ChatWindow.h"
namespace Swift {
class MockChatWindow : public ChatWindow {
public:
MockChatWindow() {};
virtual ~MockChatWindow();
- virtual void addMessage(const String& /*message*/, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/) {};
+ virtual void addMessage(const String& message, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/) {lastMessageBody_ = message;};
virtual void addSystemMessage(const String& /*message*/) {};
virtual void addErrorMessage(const String& /*message*/) {};
virtual void setName(const String& name) {name_ = name;};
virtual void show() {};
virtual void activate() {};
virtual void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) {labels_ = labels;};
virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;};
virtual void setUnreadMessageCount(int /*count*/) {};
virtual void convertToMUC() {};
virtual TreeWidget *getTreeWidget() {return NULL;};
virtual void setSecurityLabelsError() {};
virtual SecurityLabel getSelectedSecurityLabel() {return SecurityLabel();};
virtual void setInputEnabled(bool /*enabled*/) {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
boost::signal<void (const String&)> onSendMessageRequest;
String name_;
+ String lastMessageBody_;
std::vector<SecurityLabel> labels_;
bool labelsEnabled_;
};
}