summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/MUC')
-rw-r--r--Swiften/MUC/MUC.cpp70
-rw-r--r--Swiften/MUC/MUC.h59
-rw-r--r--Swiften/MUC/MUCBookmark.h28
-rw-r--r--Swiften/MUC/MUCBookmarkManager.cpp39
-rw-r--r--Swiften/MUC/MUCBookmarkManager.h28
-rw-r--r--Swiften/MUC/MUCOccupant.cpp15
-rw-r--r--Swiften/MUC/MUCOccupant.h21
-rw-r--r--Swiften/MUC/MUCRegistry.cpp8
-rw-r--r--Swiften/MUC/MUCRegistry.h12
9 files changed, 280 insertions, 0 deletions
diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp
new file mode 100644
index 0000000..3c06c7a
--- /dev/null
+++ b/Swiften/MUC/MUC.cpp
@@ -0,0 +1,70 @@
+#include "Swiften/MUC/MUC.h"
+
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Presence/PresenceSender.h"
+#include "Swiften/Client/StanzaChannel.h"
+#include "Swiften/Elements/IQ.h"
+#include "Swiften/Elements/MUCPayload.h"
+
+namespace Swift {
+
+typedef std::pair<String, MUCOccupant> StringMUCOccupantPair;
+
+MUC::MUC(StanzaChannel* stanzaChannel, PresenceSender* presenceSender, const JID &muc) : ownMUCJID(muc), stanzaChannel(stanzaChannel), presenceSender(presenceSender) {
+ scopedConnection_ = stanzaChannel->onPresenceReceived.connect(boost::bind(&MUC::handleIncomingPresence, this, _1));
+}
+
+void MUC::joinAs(const String &nick) {
+ firstPresenceSeen = false;
+
+ ownMUCJID = JID(ownMUCJID.getNode(), ownMUCJID.getDomain(), nick);
+
+ boost::shared_ptr<Presence> joinPresence(new Presence());
+ joinPresence->setTo(ownMUCJID);
+ joinPresence->addPayload(boost::shared_ptr<Payload>(new MUCPayload()));
+ presenceSender->sendPresence(joinPresence);
+}
+
+void MUC::part() {
+ presenceSender->removeDirectedPresenceReceiver(ownMUCJID);
+}
+
+void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) {
+ if (!isFromMUC(presence->getFrom())) {
+ return;
+ }
+
+ if (!firstPresenceSeen) {
+ if (presence->getType() == Presence::Error) {
+ onJoinComplete(JoinFailed);
+ return;
+ }
+ firstPresenceSeen = true;
+ onJoinComplete(JoinSucceeded);
+ presenceSender->addDirectedPresenceReceiver(ownMUCJID);
+ }
+
+ String nick = presence->getFrom().getResource();
+ if (nick.isEmpty()) {
+ return;
+ }
+ if (presence->getType() == Presence::Unavailable) {
+ std::map<String,MUCOccupant>::iterator i = occupants.find(nick);
+ if (i != occupants.end()) {
+ onOccupantLeft(i->second, Part, "");
+ occupants.erase(i);
+ }
+ }
+ else if (presence->getType() == Presence::Available) {
+ std::pair<std::map<String,MUCOccupant>::iterator, bool> result = occupants.insert(std::make_pair(nick, MUCOccupant(nick)));
+ if (result.second) {
+ onOccupantJoined(result.first->second);
+ }
+ onOccupantPresenceChange(presence);
+ }
+}
+
+
+}
diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h
new file mode 100644
index 0000000..1ef974f
--- /dev/null
+++ b/Swiften/MUC/MUC.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#include "Swiften/JID/JID.h"
+#include "Swiften/Base/String.h"
+#include "Swiften/Elements/Message.h"
+#include "Swiften/Elements/Presence.h"
+#include "Swiften/MUC/MUCOccupant.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signals.hpp>
+#include <boost/signals/connection.hpp>
+
+#include <map>
+
+namespace Swift {
+ class StanzaChannel;
+ class PresenceSender;
+
+ class MUC {
+ public:
+ enum JoinResult { JoinSucceeded, JoinFailed };
+ enum LeavingType { Part };
+
+ public:
+ MUC(StanzaChannel* stanzaChannel, PresenceSender* presenceSender, const JID &muc);
+
+ void joinAs(const String &nick);
+ String getCurrentNick();
+ void part();
+ void handleIncomingMessage(boost::shared_ptr<Message> message);
+
+ public:
+ boost::signal<void (JoinResult)> onJoinComplete;
+ boost::signal<void (boost::shared_ptr<Presence>)> onOccupantPresenceChange;
+ boost::signal<void (const MUCOccupant&)> onOccupantJoined;
+ /**Occupant, type, and reason. */
+ boost::signal<void (const MUCOccupant&, LeavingType, const String&)> onOccupantLeft;
+
+ private:
+ bool isFromMUC(const JID& j) const {
+ return ownMUCJID.equals(j, JID::WithoutResource);
+ }
+
+ const String& getOwnNick() const {
+ return ownMUCJID.getResource();
+ }
+
+ private:
+ void handleIncomingPresence(boost::shared_ptr<Presence> presence);
+
+ private:
+ JID ownMUCJID;
+ StanzaChannel* stanzaChannel;
+ PresenceSender* presenceSender;
+ std::map<String, MUCOccupant> occupants;
+ bool firstPresenceSeen;
+ boost::bsignals::scoped_connection scopedConnection_;
+ };
+}
diff --git a/Swiften/MUC/MUCBookmark.h b/Swiften/MUC/MUCBookmark.h
new file mode 100644
index 0000000..439e716
--- /dev/null
+++ b/Swiften/MUC/MUCBookmark.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <boost/optional.hpp>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/JID/JID.h"
+
+namespace Swift {
+ class MUCBookmark {
+ public:
+ MUCBookmark(const JID& room, const String& bookmarkName) : room_(room), name_(bookmarkName){};
+ void setAutojoin(bool enabled) {autojoin_ = enabled;};
+ void setNick(const boost::optional<String>& nick) {nick_ = nick;};
+ void setPassword(const boost::optional<String>& password) {password_ = password;};
+ bool getAutojoin() const {return autojoin_;};
+ const boost::optional<String>& getNick() const {return nick_;};
+ const boost::optional<String>& getPassword() const {return password_;};
+ const String& getName() const {return name_;};
+ const JID& getRoom() const {return room_;};
+ private:
+ JID room_;
+ String name_;
+ boost::optional<String> nick_;
+ boost::optional<String> password_;
+ bool autojoin_;
+ };
+}
+
diff --git a/Swiften/MUC/MUCBookmarkManager.cpp b/Swiften/MUC/MUCBookmarkManager.cpp
new file mode 100644
index 0000000..f9295e2
--- /dev/null
+++ b/Swiften/MUC/MUCBookmarkManager.cpp
@@ -0,0 +1,39 @@
+#include "MUCBookmarkManager.h"
+
+#include "Swiften/Queries/IQRouter.h"
+
+namespace Swift {
+
+MUCBookmarkManager::MUCBookmarkManager(IQRouter* iqRouter) {
+ iqRouter_ = iqRouter;
+}
+
+void MUCBookmarkManager::addBookmark(boost::shared_ptr<MUCBookmark> bookmark) {
+ bookmarks_.push_back(bookmark);
+ flush();
+ onBookmarkAdded(bookmark);
+}
+
+
+void MUCBookmarkManager::removeBookmark(boost::shared_ptr<MUCBookmark> bookmark) {
+ std::vector<boost::shared_ptr<MUCBookmark> >::iterator it;
+ for (it = bookmarks_.begin(); it != bookmarks_.end(); it++) {
+ if ((*it).get() == bookmark.get()) {
+ bookmarks_.erase(it);
+ onBookmarkRemoved(bookmark);
+ return;
+ }
+ }
+ assert(false);
+ flush();
+}
+
+void MUCBookmarkManager::flush() {
+ //FIXME: some code may be useful
+}
+
+const std::vector<boost::shared_ptr<MUCBookmark> >& MUCBookmarkManager::getBookmarks() {
+ return bookmarks_;
+}
+
+}
diff --git a/Swiften/MUC/MUCBookmarkManager.h b/Swiften/MUC/MUCBookmarkManager.h
new file mode 100644
index 0000000..ade2e3e
--- /dev/null
+++ b/Swiften/MUC/MUCBookmarkManager.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signals.hpp>
+
+#include "Swiften/MUC/MUCBookmark.h"
+
+namespace Swift {
+ class IQRouter;
+ class MUCBookmarkManager {
+ public:
+ MUCBookmarkManager(IQRouter* iqRouter);
+ void addBookmark(boost::shared_ptr<MUCBookmark> bookmark);
+ void removeBookmark(boost::shared_ptr<MUCBookmark> bookmark);
+ /** Call flush after editing an existing bookmark. */
+ void flush();
+ /** Returns pointers to the bookmarks. These can be edited, and then flush()ed.*/
+ const std::vector<boost::shared_ptr<MUCBookmark> >& getBookmarks();
+ boost::signal<void (boost::shared_ptr<MUCBookmark>)> onBookmarkAdded;
+ boost::signal<void (boost::shared_ptr<MUCBookmark>)> onBookmarkRemoved;
+ private:
+
+ std::vector<boost::shared_ptr<MUCBookmark> > bookmarks_;
+ IQRouter* iqRouter_;
+ };
+}
diff --git a/Swiften/MUC/MUCOccupant.cpp b/Swiften/MUC/MUCOccupant.cpp
new file mode 100644
index 0000000..6ed8591
--- /dev/null
+++ b/Swiften/MUC/MUCOccupant.cpp
@@ -0,0 +1,15 @@
+#include "Swiften/MUC/MUCOccupant.h"
+
+namespace Swift {
+
+MUCOccupant::MUCOccupant(const String &nick) : nick_(nick) {
+}
+
+MUCOccupant::~MUCOccupant() {
+}
+
+String MUCOccupant::getNick() const {
+ return nick_;
+}
+
+}
diff --git a/Swiften/MUC/MUCOccupant.h b/Swiften/MUC/MUCOccupant.h
new file mode 100644
index 0000000..22e58ac
--- /dev/null
+++ b/Swiften/MUC/MUCOccupant.h
@@ -0,0 +1,21 @@
+#ifndef SWIFTEN_MUCOccupant_H
+#define SWIFTEN_MUCOccupant_H
+
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class Client;
+
+ class MUCOccupant {
+ public:
+ MUCOccupant(const String &nick);
+ ~MUCOccupant();
+
+ String getNick() const;
+
+ private:
+ String nick_;
+ };
+}
+
+#endif
diff --git a/Swiften/MUC/MUCRegistry.cpp b/Swiften/MUC/MUCRegistry.cpp
new file mode 100644
index 0000000..95bab08
--- /dev/null
+++ b/Swiften/MUC/MUCRegistry.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/MUC/MUCRegistry.h"
+
+namespace Swift {
+
+MUCRegistry::~MUCRegistry() {
+}
+
+}
diff --git a/Swiften/MUC/MUCRegistry.h b/Swiften/MUC/MUCRegistry.h
new file mode 100644
index 0000000..a843abb
--- /dev/null
+++ b/Swiften/MUC/MUCRegistry.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace Swift {
+ class JID;
+
+ class MUCRegistry {
+ public:
+ virtual ~MUCRegistry();
+
+ virtual bool isMUC(const JID&) const = 0;
+ };
+}