aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2011-04-29 00:08:47 +0000
committerJeremy Lainé <jeremy.laine@m4x.org>2011-04-29 00:08:47 +0000
commit32a5e7921021f89f694a7906afd21967ca6fb8b5 (patch)
tree02fcfefc9ea61797a8d9b9671df12a3a49106e10 /src
parentf999dd4bb51b23b2628f12724dd408f1ea2bb5b1 (diff)
downloadqxmpp-32a5e7921021f89f694a7906afd21967ca6fb8b5.tar.gz
* add error handling to QXmppMucRoom
* reflect client presence in room
Diffstat (limited to 'src')
-rw-r--r--src/QXmppMucManager.cpp90
-rw-r--r--src/QXmppMucManager.h18
2 files changed, 91 insertions, 17 deletions
diff --git a/src/QXmppMucManager.cpp b/src/QXmppMucManager.cpp
index e4aedc43..d8e68fb3 100644
--- a/src/QXmppMucManager.cpp
+++ b/src/QXmppMucManager.cpp
@@ -22,6 +22,7 @@
*/
#include <QDomElement>
+#include <QMap>
#include "QXmppClient.h"
#include "QXmppConstants.h"
@@ -30,6 +31,12 @@
#include "QXmppMucManager.h"
#include "QXmppUtils.h"
+class QXmppMucManagerPrivate
+{
+public:
+ QMap<QString, QXmppMucRoom*> rooms;
+};
+
class QXmppMucRoomPrivate
{
public:
@@ -45,16 +52,31 @@ public:
QString subject;
};
+/// Constructs a new QXmppMucManager.
+
+QXmppMucManager::QXmppMucManager()
+{
+ d = new QXmppMucManagerPrivate;
+}
+
+
+/// Destroys a new QXmppMucManager.
+
+QXmppMucManager::~QXmppMucManager()
+{
+ delete d;
+}
+
/// Adds the given chat room to the set of manged rooms.
///
/// \param roomJid
QXmppMucRoom *QXmppMucManager::addRoom(const QString &roomJid)
{
- QXmppMucRoom *room = m_rooms.value(roomJid);
+ QXmppMucRoom *room = d->rooms.value(roomJid);
if (!room) {
room = new QXmppMucRoom(client(), roomJid, this);
- m_rooms.insert(roomJid, room);
+ d->rooms.insert(roomJid, room);
}
return room;
}
@@ -64,7 +86,7 @@ void QXmppMucManager::setClient(QXmppClient* client)
QXmppClientExtension::setClient(client);
bool check = connect(client, SIGNAL(messageReceived(QXmppMessage)),
- this, SLOT(messageReceived(QXmppMessage)));
+ this, SLOT(_q_messageReceived(QXmppMessage)));
Q_ASSERT(check);
}
@@ -87,7 +109,7 @@ bool QXmppMucManager::handleStanza(const QDomElement &element)
QXmppMucAdminIq iq;
iq.parse(element);
- QXmppMucRoom *room = m_rooms.value(iq.from());
+ QXmppMucRoom *room = d->rooms.value(iq.from());
if (room && iq.type() == QXmppIq::Result) {
foreach (const QXmppMucAdminIq::Item &item, iq.items()) {
const QString jid = item.jid();
@@ -103,7 +125,7 @@ bool QXmppMucManager::handleStanza(const QDomElement &element)
QXmppMucOwnerIq iq;
iq.parse(element);
- QXmppMucRoom *room = m_rooms.value(iq.from());
+ QXmppMucRoom *room = d->rooms.value(iq.from());
if (room && iq.type() == QXmppIq::Result && !iq.form().isNull())
emit room->configurationReceived(iq.form());
return true;
@@ -112,7 +134,7 @@ bool QXmppMucManager::handleStanza(const QDomElement &element)
return false;
}
-void QXmppMucManager::messageReceived(const QXmppMessage &msg)
+void QXmppMucManager::_q_messageReceived(const QXmppMessage &msg)
{
if (msg.type() != QXmppMessage::Normal)
return;
@@ -123,7 +145,7 @@ void QXmppMucManager::messageReceived(const QXmppMessage &msg)
if (extension.tagName() == "x" && extension.attribute("xmlns") == ns_conference)
{
const QString roomJid = extension.attribute("jid");
- if (!roomJid.isEmpty() && !m_rooms.contains(roomJid))
+ if (!roomJid.isEmpty() && !d->rooms.contains(roomJid))
emit invitationReceived(roomJid, msg.from(), extension.attribute("reason"));
break;
}
@@ -212,6 +234,27 @@ bool QXmppMucRoom::join()
return d->client->sendPacket(packet);
}
+/// Kicks the specified user from the chat room.
+///
+/// \param jid
+///
+/// \return true if the request was sent, false otherwise
+
+bool QXmppMucRoom::kick(const QString &jid, const QString &reason)
+{
+ QXmppMucAdminIq::Item item;
+ item.setNick(jidToResource(jid));
+ item.setRole(QXmppMucAdminIq::Item::NoRole);
+ item.setReason(reason);
+
+ QXmppMucAdminIq iq;
+ iq.setType(QXmppIq::Set);
+ iq.setTo(d->jid);
+ iq.setItems(QList<QXmppMucAdminIq::Item>() << item);
+
+ return d->client->sendPacket(iq);
+}
+
/// Leaves the chat room.
///
/// \return true if the request was sent, false otherwise
@@ -319,6 +362,14 @@ QXmppPresence::Status QXmppMucRoom::status() const
void QXmppMucRoom::setStatus(const QXmppPresence::Status &status)
{
d->status = status;
+
+ if (isJoined()) {
+ QXmppPresence packet;
+ packet.setTo(d->ownJid());
+ packet.setType(QXmppPresence::Available);
+ packet.setStatus(status);
+ d->client->sendPacket(packet);
+ }
}
/// Returns the room's subject.
@@ -467,7 +518,12 @@ void QXmppMucRoom::_q_messageReceived(const QXmppMessage &message)
void QXmppMucRoom::_q_presenceReceived(const QXmppPresence &presence)
{
const QString jid = presence.from();
- if (jidToBareJid(jid)!= d->jid)
+
+ // if our own presence changes, reflect it in the chat room
+ if (jid == d->client->configuration().jid())
+ setStatus(presence.status());
+
+ if (jidToBareJid(jid) != d->jid)
return;
if (presence.type() == QXmppPresence::Available) {
@@ -518,8 +574,10 @@ void QXmppMucRoom::_q_presenceReceived(const QXmppPresence &presence)
QXmppElement status = extension.firstChildElement("status");
while (!status.isNull()) {
if (status.attribute("code").toInt() == 307) {
- QXmppElement reason = extension.firstChildElement("item").firstChildElement("reason");
- emit kicked(reason.value());
+ // emit kick
+ const QString actor = extension.firstChildElement("item").firstChildElement("actor").attribute("jid");
+ const QString reason = extension.firstChildElement("item").firstChildElement("reason").value();
+ emit kicked(actor, reason);
break;
}
status = status.nextSiblingElement("status");
@@ -532,4 +590,16 @@ void QXmppMucRoom::_q_presenceReceived(const QXmppPresence &presence)
}
}
}
+ else if (presence.type() == QXmppPresence::Error) {
+ foreach (const QXmppElement &extension, presence.extensions()) {
+ if (extension.tagName() == "x" && extension.attribute("xmlns") == ns_muc) {
+ // emit error
+ emit error(presence.error());
+
+ // notify the user we left the room
+ emit left();
+ break;
+ }
+ }
+ }
}
diff --git a/src/QXmppMucManager.h b/src/QXmppMucManager.h
index cf0dcd44..940ec386 100644
--- a/src/QXmppMucManager.h
+++ b/src/QXmppMucManager.h
@@ -24,16 +24,13 @@
#ifndef QXMPPMUCMANAGER_H
#define QXMPPMUCMANAGER_H
-#include <QMap>
-
#include "QXmppClientExtension.h"
#include "QXmppMucIq.h"
#include "QXmppPresence.h"
class QXmppDataForm;
class QXmppMessage;
-class QXmppMucAdminIq;
-class QXmppMucOwnerIq;
+class QXmppMucManagerPrivate;
class QXmppMucRoom;
class QXmppMucRoomPrivate;
@@ -63,6 +60,9 @@ class QXmppMucManager : public QXmppClientExtension
Q_OBJECT
public:
+ QXmppMucManager();
+ ~QXmppMucManager();
+
QXmppMucRoom *addRoom(const QString &roomJid);
/// \cond
@@ -80,10 +80,10 @@ protected:
/// \endcond
private slots:
- void messageReceived(const QXmppMessage &message);
+ void _q_messageReceived(const QXmppMessage &message);
private:
- QMap<QString, QXmppMucRoom*> m_rooms;
+ QXmppMucManagerPrivate *d;
};
/// \brief The QXmppMucRoom class represents a multi-user chat room
@@ -137,11 +137,14 @@ signals:
/// This signal is emitted when the configuration form for the room is received.
void configurationReceived(const QXmppDataForm &configuration);
+ /// This signal is emitted when an error is encountered.
+ void error(const QXmppStanza::Error &error);
+
/// This signal is emitted once you have joined the room.
void joined();
/// This signal is emitted if you get kicked from the room.
- void kicked(const QString &reason);
+ void kicked(const QString &jid, const QString &reason);
/// This signal is emiited once you have left the room.
void left();
@@ -166,6 +169,7 @@ signals:
public slots:
bool join();
+ bool kick(const QString &jid, const QString &reason);
bool leave();
bool requestConfiguration();
bool requestPermissions();