123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559 |
- /*
- * Copyright (C) 2008-2012 The QXmpp developers
- *
- * Author:
- * Manjeet Dahiya
- *
- * Source:
- * http://code.google.com/p/qxmpp
- *
- * This file is a part of QXmpp library.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- */
- #include "QXmppPresence.h"
- #include "QXmppUtils.h"
- #include <QtDebug>
- #include <QDomElement>
- #include <QXmlStreamWriter>
- #include "QXmppConstants.h"
- static const char* presence_types[] = {
- "error",
- "",
- "unavailable",
- "subscribe",
- "subscribed",
- "unsubscribe",
- "unsubscribed",
- "probe"
- };
- static const char* presence_shows[] = {
- "",
- "away",
- "xa",
- "dnd",
- "chat",
- "invisible"
- };
- class QXmppPresencePrivate : public QSharedData
- {
- public:
- QXmppPresence::AvailableStatusType availableStatusType;
- QXmppPresence::Type type;
- QXmppPresence::Status status;
- /// XEP-0153: vCard-Based Avatars
- /// photoHash: the SHA1 hash of the avatar image data itself (not the base64-encoded version)
- /// in accordance with RFC 3174
- QByteArray photoHash;
- QXmppPresence::VCardUpdateType vCardUpdateType;
- // XEP-0115: Entity Capabilities
- QString capabilityHash;
- QString capabilityNode;
- QByteArray capabilityVer;
- // Legacy XEP-0115: Entity Capabilities
- QStringList capabilityExt;
- // XEP-0045: Multi-User Chat
- QXmppMucItem mucItem;
- QString mucPassword;
- QList<int> mucStatusCodes;
- bool mucSupported;
- };
- /// Constructs a QXmppPresence.
- ///
- /// \param type
- QXmppPresence::QXmppPresence(QXmppPresence::Type type)
- : d(new QXmppPresencePrivate)
- {
- d->type = type;
- d->mucSupported = false;
- d->vCardUpdateType = VCardUpdateNone;
- }
- /// Constructs a copy of \a other.
- QXmppPresence::QXmppPresence(const QXmppPresence &other)
- : QXmppStanza(other)
- , d(other.d)
- {
- }
- /// Destroys a QXmppPresence.
- QXmppPresence::~QXmppPresence()
- {
- }
- /// Assigns \a other to this presence.
- QXmppPresence &QXmppPresence::operator=(const QXmppPresence &other)
- {
- QXmppStanza::operator=(other);
- d = other.d;
- return *this;
- }
- /// Returns the availability status type, for instance busy or away.
- ///
- /// This will not tell you whether a contact is connected, check whether
- /// type() is QXmppPresence::Available instead.
- QXmppPresence::AvailableStatusType QXmppPresence::availableStatusType() const
- {
- return static_cast<QXmppPresence::AvailableStatusType>(d->status.type());
- }
- /// Sets the availability status type, for instance busy or away.
- void QXmppPresence::setAvailableStatusType(AvailableStatusType type)
- {
- d->status.setType(static_cast<QXmppPresence::Status::Type>(type));
- }
- /// Returns the priority level of the resource.
- int QXmppPresence::priority() const
- {
- return d->status.priority();
- }
- /// Sets the \a priority level of the resource.
- void QXmppPresence::setPriority(int priority)
- {
- d->status.setPriority(priority);
- }
- /// Returns the status text, a textual description of the user's status.
- QString QXmppPresence::statusText() const
- {
- return d->status.statusText();
- }
- /// Sets the status text, a textual description of the user's status.
- ///
- /// \param statusText The status text, for example "Gone fishing".
- void QXmppPresence::setStatusText(const QString& statusText)
- {
- d->status.setStatusText(statusText);
- }
- /// Returns the presence type.
- ///
- /// You can use this method to determine the action which needs to be
- /// taken in response to receiving the presence. For instance, if the type is
- /// QXmppPresence::Available or QXmppPresence::Unavailable, you could update
- /// the icon representing a contact's availability.
- QXmppPresence::Type QXmppPresence::type() const
- {
- return d->type;
- }
- /// Sets the presence type.
- ///
- /// \param type
- void QXmppPresence::setType(QXmppPresence::Type type)
- {
- d->type = type;
- }
- /// \cond
- void QXmppPresence::parse(const QDomElement &element)
- {
- QXmppStanza::parse(element);
- const QString type = element.attribute("type");
- for (int i = Error; i <= Probe; i++) {
- if (type == presence_types[i]) {
- d->type = static_cast<Type>(i);
- break;
- }
- }
- d->status.parse(element);
- QXmppElementList extensions;
- QDomElement xElement = element.firstChildElement();
- d->vCardUpdateType = VCardUpdateNone;
- while(!xElement.isNull())
- {
- // XEP-0045: Multi-User Chat
- if(xElement.namespaceURI() == ns_muc) {
- d->mucSupported = true;
- d->mucPassword = xElement.firstChildElement("password").text();
- }
- else if(xElement.namespaceURI() == ns_muc_user)
- {
- QDomElement itemElement = xElement.firstChildElement("item");
- d->mucItem.parse(itemElement);
- QDomElement statusElement = xElement.firstChildElement("status");
- d->mucStatusCodes.clear();
- while (!statusElement.isNull()) {
- d->mucStatusCodes << statusElement.attribute("code").toInt();
- statusElement = statusElement.nextSiblingElement("status");
- }
- }
- // XEP-0153: vCard-Based Avatars
- else if(xElement.namespaceURI() == ns_vcard_update)
- {
- QDomElement photoElement = xElement.firstChildElement("photo");
- if(!photoElement.isNull())
- {
- d->photoHash = QByteArray::fromHex(photoElement.text().toAscii());
- if(d->photoHash.isEmpty())
- d->vCardUpdateType = VCardUpdateNoPhoto;
- else
- d->vCardUpdateType = VCardUpdateValidPhoto;
- }
- else
- {
- d->photoHash = QByteArray();
- d->vCardUpdateType = VCardUpdateNotReady;
- }
- }
- // XEP-0115: Entity Capabilities
- else if(xElement.tagName() == "c" && xElement.namespaceURI() == ns_capabilities)
- {
- d->capabilityNode = xElement.attribute("node");
- d->capabilityVer = QByteArray::fromBase64(xElement.attribute("ver").toAscii());
- d->capabilityHash = xElement.attribute("hash");
- d->capabilityExt = xElement.attribute("ext").split(" ", QString::SkipEmptyParts);
- }
- else if (xElement.tagName() == "addresses")
- {
- }
- else if (xElement.tagName() == "error")
- {
- }
- else if (xElement.tagName() == "show")
- {
- }
- else if (xElement.tagName() == "status")
- {
- }
- else if (xElement.tagName() == "priority")
- {
- }
- else
- {
- // other extensions
- extensions << QXmppElement(xElement);
- }
- xElement = xElement.nextSiblingElement();
- }
- setExtensions(extensions);
- }
- void QXmppPresence::toXml(QXmlStreamWriter *xmlWriter) const
- {
- xmlWriter->writeStartElement("presence");
- helperToXmlAddAttribute(xmlWriter,"xml:lang", lang());
- helperToXmlAddAttribute(xmlWriter,"id", id());
- helperToXmlAddAttribute(xmlWriter,"to", to());
- helperToXmlAddAttribute(xmlWriter,"from", from());
- helperToXmlAddAttribute(xmlWriter,"type", presence_types[d->type]);
- d->status.toXml(xmlWriter);
- error().toXml(xmlWriter);
- // XEP-0045: Multi-User Chat
- if(d->mucSupported) {
- xmlWriter->writeStartElement("x");
- xmlWriter->writeAttribute("xmlns", ns_muc);
- if (!d->mucPassword.isEmpty())
- xmlWriter->writeTextElement("password", d->mucPassword);
- xmlWriter->writeEndElement();
- }
- if(!d->mucItem.isNull() || !d->mucStatusCodes.isEmpty())
- {
- xmlWriter->writeStartElement("x");
- xmlWriter->writeAttribute("xmlns", ns_muc_user);
- if (!d->mucItem.isNull())
- d->mucItem.toXml(xmlWriter);
- foreach (int code, d->mucStatusCodes) {
- xmlWriter->writeStartElement("status");
- xmlWriter->writeAttribute("code", QString::number(code));
- xmlWriter->writeEndElement();
- }
- xmlWriter->writeEndElement();
- }
- // XEP-0153: vCard-Based Avatars
- if(d->vCardUpdateType != VCardUpdateNone)
- {
- xmlWriter->writeStartElement("x");
- xmlWriter->writeAttribute("xmlns", ns_vcard_update);
- switch(d->vCardUpdateType)
- {
- case VCardUpdateNoPhoto:
- helperToXmlAddTextElement(xmlWriter, "photo", "");
- break;
- case VCardUpdateValidPhoto:
- helperToXmlAddTextElement(xmlWriter, "photo", d->photoHash.toHex());
- break;
- case VCardUpdateNotReady:
- break;
- default:
- break;
- }
- xmlWriter->writeEndElement();
- }
- if(!d->capabilityNode.isEmpty() && !d->capabilityVer.isEmpty()
- && !d->capabilityHash.isEmpty())
- {
- xmlWriter->writeStartElement("c");
- xmlWriter->writeAttribute("xmlns", ns_capabilities);
- helperToXmlAddAttribute(xmlWriter, "hash", d->capabilityHash);
- helperToXmlAddAttribute(xmlWriter, "node", d->capabilityNode);
- helperToXmlAddAttribute(xmlWriter, "ver", d->capabilityVer.toBase64());
- xmlWriter->writeEndElement();
- }
- // other extensions
- QXmppStanza::extensionsToXml(xmlWriter);
- xmlWriter->writeEndElement();
- }
- /// \endcond
- /// Returns the photo-hash of the VCardUpdate.
- ///
- /// \return QByteArray
- QByteArray QXmppPresence::photoHash() const
- {
- return d->photoHash;
- }
- /// Sets the photo-hash of the VCardUpdate.
- ///
- /// \param photoHash as QByteArray
- void QXmppPresence::setPhotoHash(const QByteArray& photoHash)
- {
- d->photoHash = photoHash;
- }
- /// Returns the type of VCardUpdate
- ///
- /// \return VCardUpdateType
- QXmppPresence::VCardUpdateType QXmppPresence::vCardUpdateType() const
- {
- return d->vCardUpdateType;
- }
- /// Sets the type of VCardUpdate
- ///
- /// \param type VCardUpdateType
- void QXmppPresence::setVCardUpdateType(VCardUpdateType type)
- {
- d->vCardUpdateType = type;
- }
- /// XEP-0115: Entity Capabilities
- QString QXmppPresence::capabilityHash() const
- {
- return d->capabilityHash;
- }
- /// XEP-0115: Entity Capabilities
- void QXmppPresence::setCapabilityHash(const QString& hash)
- {
- d->capabilityHash = hash;
- }
- /// XEP-0115: Entity Capabilities
- QString QXmppPresence::capabilityNode() const
- {
- return d->capabilityNode;
- }
- /// XEP-0115: Entity Capabilities
- void QXmppPresence::setCapabilityNode(const QString& node)
- {
- d->capabilityNode = node;
- }
- /// XEP-0115: Entity Capabilities
- QByteArray QXmppPresence::capabilityVer() const
- {
- return d->capabilityVer;
- }
- /// XEP-0115: Entity Capabilities
- void QXmppPresence::setCapabilityVer(const QByteArray& ver)
- {
- d->capabilityVer = ver;
- }
- /// Legacy XEP-0115: Entity Capabilities
- QStringList QXmppPresence::capabilityExt() const
- {
- return d->capabilityExt;
- }
- /// Returns the MUC item.
- QXmppMucItem QXmppPresence::mucItem() const
- {
- return d->mucItem;
- }
- /// Sets the MUC item.
- ///
- /// \param item
- void QXmppPresence::setMucItem(const QXmppMucItem &item)
- {
- d->mucItem = item;
- }
- /// Returns the password used to join a MUC room.
- QString QXmppPresence::mucPassword() const
- {
- return d->mucPassword;
- }
- /// Sets the password used to join a MUC room.
- void QXmppPresence::setMucPassword(const QString &password)
- {
- d->mucPassword = password;
- }
- /// Returns the MUC status codes.
- QList<int> QXmppPresence::mucStatusCodes() const
- {
- return d->mucStatusCodes;
- }
- /// Sets the MUC status codes.
- ///
- /// \param codes
- void QXmppPresence::setMucStatusCodes(const QList<int> &codes)
- {
- d->mucStatusCodes = codes;
- }
- /// Returns true if the sender has indicated MUC support.
- bool QXmppPresence::isMucSupported() const
- {
- return d->mucSupported;
- }
- /// Sets whether MUC is \a supported.
- void QXmppPresence::setMucSupported(bool supported)
- {
- d->mucSupported = supported;
- }
- /// \cond
- const QXmppPresence::Status& QXmppPresence::status() const
- {
- return d->status;
- }
- QXmppPresence::Status& QXmppPresence::status()
- {
- return d->status;
- }
- void QXmppPresence::setStatus(const QXmppPresence::Status& status)
- {
- d->status = status;
- }
- QXmppPresence::Status::Status(QXmppPresence::Status::Type type,
- const QString statusText, int priority) :
- m_type(type),
- m_statusText(statusText), m_priority(priority)
- {
- }
- QXmppPresence::Status::Type QXmppPresence::Status::type() const
- {
- return m_type;
- }
- void QXmppPresence::Status::setType(QXmppPresence::Status::Type type)
- {
- m_type = type;
- }
- QString QXmppPresence::Status::statusText() const
- {
- return m_statusText;
- }
- void QXmppPresence::Status::setStatusText(const QString& str)
- {
- m_statusText = str;
- }
- int QXmppPresence::Status::priority() const
- {
- return m_priority;
- }
- void QXmppPresence::Status::setPriority(int priority)
- {
- m_priority = priority;
- }
- void QXmppPresence::Status::parse(const QDomElement &element)
- {
- const QString show = element.firstChildElement("show").text();
- for (int i = Online; i <= Invisible; i++) {
- if (show == presence_shows[i]) {
- m_type = static_cast<Type>(i);
- break;
- }
- }
- m_statusText = element.firstChildElement("status").text();
- m_priority = element.firstChildElement("priority").text().toInt();
- }
- void QXmppPresence::Status::toXml(QXmlStreamWriter *xmlWriter) const
- {
- const QString show = presence_shows[m_type];
- if (!show.isEmpty())
- helperToXmlAddTextElement(xmlWriter, "show", show);
- if (!m_statusText.isEmpty())
- helperToXmlAddTextElement(xmlWriter, "status", m_statusText);
- if (m_priority != 0)
- helperToXmlAddTextElement(xmlWriter, "priority", QString::number(m_priority));
- }
- /// \endcond
|