Added Bits Of Binary (XEP-0231) support
[iris.git] / src / xmpp / xmpp-im / types.cpp
blob6496e7c711b977349d608d7389d763919a34a402
1 /*
2 * types.cpp - IM data types
3 * Copyright (C) 2003 Justin Karneges
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "im.h"
22 #include "xmpp_features.h"
24 #include <qmap.h>
25 #include <qapplication.h>
26 //Added by qt3to4:
27 #include <QList>
29 #include "xmpp_xmlcommon.h"
30 #include "xmpp_bitsofbinary.h"
31 #define NS_XML "http://www.w3.org/XML/1998/namespace"
33 namespace XMPP
36 //----------------------------------------------------------------------------
37 // Url
38 //----------------------------------------------------------------------------
39 class Url::Private
41 public:
42 QString url;
43 QString desc;
46 //! \brief Construct Url object with a given URL and Description.
47 //!
48 //! This function will construct a Url object.
49 //! \param QString - url (default: empty string)
50 //! \param QString - description of url (default: empty string)
51 //! \sa setUrl() setDesc()
52 Url::Url(const QString &url, const QString &desc)
54 d = new Private;
55 d->url = url;
56 d->desc = desc;
59 //! \brief Construct Url object.
60 //!
61 //! Overloaded constructor which will constructs a exact copy of the Url object that was passed to the constructor.
62 //! \param Url - Url Object
63 Url::Url(const Url &from)
65 d = new Private;
66 *this = from;
69 //! \brief operator overloader needed for d pointer (Internel).
70 Url & Url::operator=(const Url &from)
72 *d = *from.d;
73 return *this;
76 //! \brief destroy Url object.
77 Url::~Url()
79 delete d;
82 //! \brief Get url information.
83 //!
84 //! Returns url information.
85 QString Url::url() const
87 return d->url;
90 //! \brief Get Description information.
91 //!
92 //! Returns desction of the URL.
93 QString Url::desc() const
95 return d->desc;
98 //! \brief Set Url information.
99 //!
100 //! Set url information.
101 //! \param url - url string (eg: http://psi.affinix.com/)
102 void Url::setUrl(const QString &url)
104 d->url = url;
107 //! \brief Set Description information.
109 //! Set description of the url.
110 //! \param desc - description of url
111 void Url::setDesc(const QString &desc)
113 d->desc = desc;
116 //----------------------------------------------------------------------------
117 // Address
118 //----------------------------------------------------------------------------
120 //! \brief Construct Address object with a given Type and Jid.
122 //! This function will construct a Address object.
123 //! \param Type - type (default: Unknown)
124 //! \param Jid - specify address (default: empty string)
125 //! \sa setType() setJid()
126 Address::Address(Type type, const Jid & jid)
127 : v_delivered(false)
129 v_type = type;
130 v_jid = jid;
131 v_delivered = false;
134 Address::Address(const QDomElement& e)
135 : v_delivered(false)
137 fromXml(e);
140 void Address::fromXml(const QDomElement& t)
142 setJid(t.attribute("jid"));
143 setUri(t.attribute("uri"));
144 setNode(t.attribute("node"));
145 setDesc(t.attribute("desc"));
146 setDelivered(t.attribute("delivered") == "true");
147 QString type = t.attribute("type");
148 if (type == "to")
149 setType(To);
150 else if (type == "cc")
151 setType(Cc);
152 else if (type == "bcc")
153 setType(Bcc);
154 else if (type == "replyto")
155 setType(ReplyTo);
156 else if (type == "replyroom")
157 setType(ReplyRoom);
158 else if (type == "noreply")
159 setType(NoReply);
160 else if (type == "ofrom")
161 setType(OriginalFrom);
162 else if (type == "oto")
163 setType(OriginalTo);
166 QDomElement Address::toXml(Stanza& s) const
168 QDomElement e = s.createElement("http://jabber.org/protocol/address", "address");
169 if(!jid().isEmpty())
170 e.setAttribute("jid", jid().full());
171 if(!uri().isEmpty())
172 e.setAttribute("uri", uri());
173 if(!node().isEmpty())
174 e.setAttribute("node", node());
175 if(!desc().isEmpty())
176 e.setAttribute("desc", desc());
177 if(delivered())
178 e.setAttribute("delivered", "true");
179 switch (type()) {
180 case To:
181 e.setAttribute("type", "to");
182 break;
183 case Cc:
184 e.setAttribute("type", "cc");
185 break;
186 case Bcc:
187 e.setAttribute("type", "bcc");
188 break;
189 case ReplyTo:
190 e.setAttribute("type", "replyto");
191 break;
192 case ReplyRoom:
193 e.setAttribute("type", "replyroom");
194 break;
195 case NoReply:
196 e.setAttribute("type", "noreply");
197 break;
198 case OriginalFrom:
199 e.setAttribute("type", "ofrom");
200 break;
201 case OriginalTo:
202 e.setAttribute("type", "oto");
203 break;
204 case Unknown:
205 // Add nothing
206 break;
208 return e;
211 //! \brief Get Jid information.
213 //! Returns jid information.
214 const Jid& Address::jid() const
216 return v_jid;
219 //! \brief Get Uri information.
221 //! Returns desction of the Address.
222 const QString& Address::uri() const
224 return v_uri;
227 //! \brief Get Node information.
229 //! Returns node of the Address.
230 const QString& Address::node() const
232 return v_node;
235 //! \brief Get Description information.
237 //! Returns desction of the Address.
238 const QString& Address::desc() const
240 return v_desc;
243 //! \brief Get Delivered information.
245 //! Returns delivered of the Address.
246 bool Address::delivered() const
248 return v_delivered;
251 //! \brief Get Type information.
253 //! Returns type of the Address.
254 Address::Type Address::type() const
256 return v_type;
259 //! \brief Set Address information.
261 //! Set jid information.
262 //! \param jid - jid
263 void Address::setJid(const Jid &jid)
265 v_jid = jid;
268 //! \brief Set Address information.
270 //! Set uri information.
271 //! \param uri - url string (eg: http://psi.affinix.com/)
272 void Address::setUri(const QString &uri)
274 v_uri = uri;
277 //! \brief Set Node information.
279 //! Set node information.
280 //! \param node - node string
281 void Address::setNode(const QString &node)
283 v_node = node;
286 //! \brief Set Description information.
288 //! Set description of the url.
289 //! \param desc - description of url
290 void Address::setDesc(const QString &desc)
292 v_desc = desc;
295 //! \brief Set delivered information.
297 //! Set delivered information.
298 //! \param delivered - delivered flag
299 void Address::setDelivered(bool delivered)
301 v_delivered = delivered;
304 //! \brief Set Type information.
306 //! Set type information.
307 //! \param type - type
308 void Address::setType(Type type)
310 v_type = type;
313 //----------------------------------------------------------------------------
314 // RosterExchangeItem
315 //----------------------------------------------------------------------------
317 RosterExchangeItem::RosterExchangeItem(const Jid& jid, const QString& name, const QStringList& groups, Action action) : jid_(jid), name_(name), groups_(groups), action_(action)
321 RosterExchangeItem::RosterExchangeItem(const QDomElement& el) : action_(Add)
323 fromXml(el);
326 const Jid& RosterExchangeItem::jid() const
328 return jid_;
331 RosterExchangeItem::Action RosterExchangeItem::action() const
333 return action_;
336 const QString& RosterExchangeItem::name() const
338 return name_;
341 const QStringList& RosterExchangeItem::groups() const
343 return groups_;
346 bool RosterExchangeItem::isNull() const
348 return jid_.isEmpty();
351 void RosterExchangeItem::setJid(const Jid& jid)
353 jid_ = jid;
356 void RosterExchangeItem::setAction(Action action)
358 action_ = action;
361 void RosterExchangeItem::setName(const QString& name)
363 name_ = name;
366 void RosterExchangeItem::setGroups(const QStringList& groups)
368 groups_ = groups;
371 QDomElement RosterExchangeItem::toXml(Stanza& s) const
373 QDomElement e = s.createElement("http://jabber.org/protocol/rosterx", "item");
374 e.setAttribute("jid", jid().full());
375 if (!name().isEmpty())
376 e.setAttribute("name", name());
377 switch(action()) {
378 case Add:
379 e.setAttribute("action","add");
380 break;
381 case Delete:
382 e.setAttribute("action","delete");
383 break;
384 case Modify:
385 e.setAttribute("action","modify");
386 break;
388 foreach(QString group, groups_) {
389 e.appendChild(s.createTextElement("http://jabber.org/protocol/rosterx", "group",group));
391 return e;
394 void RosterExchangeItem::fromXml(const QDomElement& e)
396 setJid(e.attribute("jid"));
397 setName(e.attribute("name"));
398 if (e.attribute("action") == "delete") {
399 setAction(Delete);
401 else if (e.attribute("action") == "modify") {
402 setAction(Modify);
404 else {
405 setAction(Add);
407 QDomNodeList nl = e.childNodes();
408 for(int n = 0; n < nl.count(); ++n) {
409 QDomElement g = nl.item(n).toElement();
410 if (!g.isNull() && g.tagName() == "group") {
411 groups_ += g.text();
417 //----------------------------------------------------------------------------
418 // MUCItem
419 //----------------------------------------------------------------------------
420 MUCItem::MUCItem(Role r, Affiliation a) : affiliation_(a), role_(r)
424 MUCItem::MUCItem(const QDomElement& el) : affiliation_(UnknownAffiliation), role_(UnknownRole)
426 fromXml(el);
429 void MUCItem::setNick(const QString& n)
431 nick_ = n;
434 void MUCItem::setJid(const Jid& j)
436 jid_ = j;
439 void MUCItem::setAffiliation(Affiliation a)
441 affiliation_ = a;
444 void MUCItem::setRole(Role r)
446 role_ = r;
449 void MUCItem::setActor(const Jid& a)
451 actor_ = a;
454 void MUCItem::setReason(const QString& r)
456 reason_ = r;
459 const QString& MUCItem::nick() const
461 return nick_;
464 const Jid& MUCItem::jid() const
466 return jid_;
469 MUCItem::Affiliation MUCItem::affiliation() const
471 return affiliation_;
474 MUCItem::Role MUCItem::role() const
476 return role_;
479 const Jid& MUCItem::actor() const
481 return actor_;
484 const QString& MUCItem::reason() const
486 return reason_;
489 void MUCItem::fromXml(const QDomElement& e)
491 if (e.tagName() != "item")
492 return;
494 jid_ = Jid(e.attribute("jid"));
495 nick_ = e.attribute("nick");
497 // Affiliation
498 if (e.attribute("affiliation") == "owner") {
499 affiliation_ = Owner;
501 else if (e.attribute("affiliation") == "admin") {
502 affiliation_ = Admin;
504 else if (e.attribute("affiliation") == "member") {
505 affiliation_ = Member;
507 else if (e.attribute("affiliation") == "outcast") {
508 affiliation_ = Outcast;
510 else if (e.attribute("affiliation") == "none") {
511 affiliation_ = NoAffiliation;
514 // Role
515 if (e.attribute("role") == "moderator") {
516 role_ = Moderator;
518 else if (e.attribute("role") == "participant") {
519 role_ = Participant;
521 else if (e.attribute("role") == "visitor") {
522 role_ = Visitor;
524 else if (e.attribute("role") == "none") {
525 role_ = NoRole;
528 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
529 QDomElement i = n.toElement();
530 if(i.isNull())
531 continue;
533 if (i.tagName() == "actor")
534 actor_ = Jid(i.attribute("jid"));
535 else if (i.tagName() == "reason")
536 reason_ = i.text();
540 QDomElement MUCItem::toXml(QDomDocument& d)
542 QDomElement e = d.createElement("item");
544 if (!nick_.isEmpty())
545 e.setAttribute("nick",nick_);
547 if (!jid_.isEmpty())
548 e.setAttribute("jid",jid_.full());
550 if (!reason_.isEmpty())
551 e.appendChild(textTag(&d,"reason",reason_));
553 switch (affiliation_) {
554 case NoAffiliation:
555 e.setAttribute("affiliation","none");
556 break;
557 case Owner:
558 e.setAttribute("affiliation","owner");
559 break;
560 case Admin:
561 e.setAttribute("affiliation","admin");
562 break;
563 case Member:
564 e.setAttribute("affiliation","member");
565 break;
566 case Outcast:
567 e.setAttribute("affiliation","outcast");
568 break;
569 default:
570 break;
572 switch (role_) {
573 case NoRole:
574 e.setAttribute("role","none");
575 break;
576 case Moderator:
577 e.setAttribute("role","moderator");
578 break;
579 case Participant:
580 e.setAttribute("role","participant");
581 break;
582 case Visitor:
583 e.setAttribute("role","visitor");
584 break;
585 default:
586 break;
589 return e;
592 bool MUCItem::operator==(const MUCItem& o)
594 return !nick_.compare(o.nick_) && ((!jid_.isValid() && !o.jid_.isValid()) || jid_.compare(o.jid_,true)) && ((!actor_.isValid() && !o.actor_.isValid()) || actor_.compare(o.actor_,true)) && affiliation_ == o.affiliation_ && role_ == o.role_ && !reason_.compare(o.reason_);
597 //----------------------------------------------------------------------------
598 // MUCInvite
599 //----------------------------------------------------------------------------
601 MUCInvite::MUCInvite() : cont_(false)
605 MUCInvite::MUCInvite(const Jid& to, const QString& reason) : to_(to), reason_(reason), cont_(false)
609 MUCInvite::MUCInvite(const QDomElement& e) : cont_(false)
611 fromXml(e);
614 const Jid& MUCInvite::from() const
616 return from_;
619 void MUCInvite::setFrom(const Jid& j)
621 from_ = j;
624 const Jid& MUCInvite::to() const
626 return to_;
629 void MUCInvite::setTo(const Jid& j)
631 to_ = j;
634 const QString& MUCInvite::reason() const
636 return reason_;
639 void MUCInvite::setReason(const QString& r)
641 reason_ = r;
644 bool MUCInvite::cont() const
646 return cont_;
649 void MUCInvite::setCont(bool b)
651 cont_ = b;
654 void MUCInvite::fromXml(const QDomElement& e)
656 if (e.tagName() != "invite")
657 return;
659 from_ = e.attribute("from");
660 to_ = e.attribute("to");
661 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
662 QDomElement i = n.toElement();
663 if(i.isNull())
664 continue;
666 if (i.tagName() == "continue")
667 cont_ = true;
668 else if (i.tagName() == "reason")
669 reason_ = i.text();
673 QDomElement MUCInvite::toXml(QDomDocument& d) const
675 QDomElement invite = d.createElement("invite");
676 if (!to_.isEmpty()) {
677 invite.setAttribute("to",to_.full());
679 if (!from_.isEmpty()) {
680 invite.setAttribute("from",from_.full());
682 if (!reason_.isEmpty()) {
683 invite.appendChild(textTag(&d, "reason", reason_));
685 if (cont_) {
686 invite.appendChild(d.createElement("continue"));
688 return invite;
691 bool MUCInvite::isNull() const
693 return to_.isEmpty() && from_.isEmpty();
696 //----------------------------------------------------------------------------
697 // MUCDecline
698 //----------------------------------------------------------------------------
700 MUCDecline::MUCDecline()
704 MUCDecline::MUCDecline(const QDomElement& e)
706 fromXml(e);
709 const Jid& MUCDecline::from() const
711 return from_;
714 void MUCDecline::setFrom(const Jid& j)
716 from_ = j;
719 const Jid& MUCDecline::to() const
721 return to_;
724 void MUCDecline::setTo(const Jid& j)
726 to_ = j;
729 const QString& MUCDecline::reason() const
731 return reason_;
734 void MUCDecline::setReason(const QString& r)
736 reason_ = r;
739 void MUCDecline::fromXml(const QDomElement& e)
741 if (e.tagName() != "decline")
742 return;
744 from_ = e.attribute("from");
745 to_ = e.attribute("to");
746 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
747 QDomElement i = n.toElement();
748 if(i.isNull())
749 continue;
751 if (i.tagName() == "reason")
752 reason_ = i.text();
756 QDomElement MUCDecline::toXml(QDomDocument& d) const
758 QDomElement decline = d.createElement("decline");
759 if (!to_.isEmpty()) {
760 decline.setAttribute("to",to_.full());
762 if (!from_.isEmpty()) {
763 decline.setAttribute("from",from_.full());
765 if (!reason_.isEmpty()) {
766 decline.appendChild(textTag(&d, "reason", reason_));
768 return decline;
771 bool MUCDecline::isNull() const
773 return to_.isEmpty() && from_.isEmpty();
776 //----------------------------------------------------------------------------
777 // MUCDestroy
778 //----------------------------------------------------------------------------
780 MUCDestroy::MUCDestroy()
784 MUCDestroy::MUCDestroy(const QDomElement& e)
786 fromXml(e);
789 const Jid& MUCDestroy::jid() const
791 return jid_;
794 void MUCDestroy::setJid(const Jid& j)
796 jid_ = j;
799 const QString& MUCDestroy::reason() const
801 return reason_;
804 void MUCDestroy::setReason(const QString& r)
806 reason_ = r;
809 void MUCDestroy::fromXml(const QDomElement& e)
811 if (e.tagName() != "destroy")
812 return;
814 jid_ = e.attribute("jid");
815 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
816 QDomElement i = n.toElement();
817 if(i.isNull())
818 continue;
820 if (i.tagName() == "reason")
821 reason_ = i.text();
825 QDomElement MUCDestroy::toXml(QDomDocument& d) const
827 QDomElement destroy = d.createElement("destroy");
828 if (!jid_.isEmpty()) {
829 destroy.setAttribute("jid",jid_.full());
831 if (!reason_.isEmpty()) {
832 destroy.appendChild(textTag(&d, "reason", reason_));
834 return destroy;
837 //----------------------------------------------------------------------------
838 // HTMLElement
839 //----------------------------------------------------------------------------
840 HTMLElement::HTMLElement()
844 HTMLElement::HTMLElement(const QDomElement &body) { setBody(body); }
846 void HTMLElement::setBody(const QDomElement &body)
848 body_ = doc_.importNode(body, true).toElement();
851 const QDomElement& HTMLElement::body() const
853 return body_;
857 * Returns the string reperesentation of the HTML element.
858 * By default, this is of the form <body ...>...</body>, but the
859 * root tag can be modified using a parameter.
861 * \param rootTagName the tagname of the root element to use.
863 QString HTMLElement::toString(const QString &rootTagName) const
865 // create a copy of the body_ node,
866 // get rid of the xmlns attribute and
867 // change the root node name
868 QDomElement e = body_.cloneNode().toElement();
869 e.setTagName(rootTagName);
871 // instead of using:
872 // QDomDocument msg;
873 // msg.appendChild(e);
874 // return msg.toString();
875 // call Stream::xmlToString, to remove unwanted namespace attributes
876 return(Stream::xmlToString(e));
879 QString HTMLElement::text() const
881 return body_.text();
885 //----------------------------------------------------------------------------
886 // Message
887 //----------------------------------------------------------------------------
888 class Message::Private
890 public:
891 Jid to, from;
892 QString id, type, lang;
894 StringMap subject, body;
895 QString thread;
896 bool threadSend;
897 Stanza::Error error;
899 // extensions
900 QDateTime timeStamp;
901 bool timeStampSend;
902 UrlList urlList;
903 AddressList addressList;
904 RosterExchangeItems rosterExchangeItems;
905 QList<MsgEvent> eventList;
906 QString pubsubNode;
907 QList<PubSubItem> pubsubItems;
908 QList<PubSubRetraction> pubsubRetractions;
909 QString eventId;
910 QString xencrypted, invite;
911 ChatState chatState;
912 MessageReceipt messageReceipt;
913 QString nick;
914 HttpAuthRequest httpAuthRequest;
915 XData xdata;
916 QMap<QString,HTMLElement> htmlElements;
917 QDomElement sxe;
918 QList<BoBData> bobDataList;
920 QList<int> mucStatuses;
921 QList<MUCInvite> mucInvites;
922 MUCDecline mucDecline;
923 QString mucPassword;
925 bool spooled, wasEncrypted;
928 //! \brief Constructs Message with given Jid information.
930 //! This function will construct a Message container.
931 //! \param to - specify reciver (default: empty string)
932 Message::Message(const Jid &to)
934 d = new Private;
935 d->to = to;
936 d->spooled = false;
937 d->threadSend = false;
938 d->timeStampSend = false;
939 d->wasEncrypted = false;
940 /*d->flag = false;
941 d->spooled = false;
942 d->wasEncrypted = false;
943 d->errorCode = -1;*/
944 d->chatState = StateNone;
945 d->messageReceipt = ReceiptNone;
948 //! \brief Constructs a copy of Message object
950 //! Overloaded constructor which will constructs a exact copy of the Message
951 //! object that was passed to the constructor.
952 //! \param from - Message object you want to copy
953 Message::Message(const Message &from)
955 d = new Private;
956 *this = from;
959 //! \brief Required for internel use.
960 Message & Message::operator=(const Message &from)
962 *d = *from.d;
963 return *this;
966 //! \brief Destroy Message object.
967 Message::~Message()
969 delete d;
972 //! \brief Return receiver's Jid information.
973 Jid Message::to() const
975 return d->to;
978 //! \brief Return sender's Jid information.
979 Jid Message::from() const
981 return d->from;
984 QString Message::id() const
986 return d->id;
989 //! \brief Return type information
990 QString Message::type() const
992 return d->type;
995 QString Message::lang() const
997 return d->lang;
1000 //! \brief Return subject information.
1001 QString Message::subject(const QString &lang) const
1003 return d->subject[lang];
1006 //! \brief Return body information.
1008 //! This function will return a plain text or the Richtext version if it
1009 //! it exists.
1010 //! \param rich - Returns richtext if true and plain text if false. (default: false)
1011 //! \note Richtext is in Qt's richtext format and not in xhtml.
1012 QString Message::body(const QString &lang) const
1014 if (d->body.empty())
1015 return "";
1016 else if (d->body.contains(lang))
1017 return d->body[lang];
1018 else
1019 return d->body.begin().value();
1022 //! \brief Return xhtml body.
1024 //! This function will return the richtext version of the body, if
1025 //! available.
1026 //! \param lang - body language
1027 //! \note The return string is in xhtml
1028 HTMLElement Message::html(const QString &lang) const
1030 if(containsHTML()) {
1031 if (d->htmlElements.contains(lang))
1032 return d->htmlElements[lang];
1033 else
1034 return d->htmlElements.begin().value();
1036 else
1037 return HTMLElement();
1040 //! \brief Tells if message has xhtml-im items.
1042 //! Returns true if there is at least one xhtml-im body
1043 //! in the message.
1044 bool Message::containsHTML() const
1046 return !(d->htmlElements.isEmpty());
1049 QString Message::thread() const
1051 return d->thread;
1054 Stanza::Error Message::error() const
1056 return d->error;
1059 //! \brief Set receivers information
1061 //! \param to - Receivers Jabber id
1062 void Message::setTo(const Jid &j)
1064 d->to = j;
1065 //d->flag = false;
1068 void Message::setFrom(const Jid &j)
1070 d->from = j;
1071 //d->flag = false;
1074 void Message::setId(const QString &s)
1076 d->id = s;
1079 //! \brief Set Type of message
1081 //! \param type - type of message your going to send
1082 void Message::setType(const QString &s)
1084 d->type = s;
1085 //d->flag = false;
1088 void Message::setLang(const QString &s)
1090 d->lang = s;
1093 //! \brief Set subject
1095 //! \param subject - Subject information
1096 void Message::setSubject(const QString &s, const QString &lang)
1098 d->subject[lang] = s;
1099 //d->flag = false;
1102 //! \brief Set body
1104 //! \param body - body information
1105 //! \param rich - set richtext if true and set plaintext if false.
1106 //! \note Richtext support will be implemented in the future... Sorry.
1107 void Message::setBody(const QString &s, const QString &lang)
1109 d->body[lang] = s;
1110 //d->flag = false;
1113 //! \brief Set xhtml body
1115 //! \param s - body node
1116 //! \param lang - body language
1117 //! \note The body should be in xhtml.
1118 void Message::setHTML(const HTMLElement &e, const QString &lang)
1120 d->htmlElements[lang] = e;
1123 void Message::setThread(const QString &s, bool send)
1125 d->threadSend = send;
1126 d->thread = s;
1129 void Message::setError(const Stanza::Error &err)
1131 d->error = err;
1134 const QString& Message::pubsubNode() const
1136 return d->pubsubNode;
1139 const QList<PubSubItem>& Message::pubsubItems() const
1141 return d->pubsubItems;
1144 const QList<PubSubRetraction>& Message::pubsubRetractions() const
1146 return d->pubsubRetractions;
1149 QDateTime Message::timeStamp() const
1151 return d->timeStamp;
1154 void Message::setTimeStamp(const QDateTime &ts, bool send)
1156 d->timeStampSend = send;
1157 d->timeStamp = ts;
1160 //! \brief Return list of urls attached to message.
1161 UrlList Message::urlList() const
1163 return d->urlList;
1166 //! \brief Add Url to the url list.
1168 //! \param url - url to append
1169 void Message::urlAdd(const Url &u)
1171 d->urlList += u;
1174 //! \brief clear out the url list.
1175 void Message::urlsClear()
1177 d->urlList.clear();
1180 //! \brief Set urls to send
1182 //! \param urlList - list of urls to send
1183 void Message::setUrlList(const UrlList &list)
1185 d->urlList = list;
1188 //! \brief Return list of addresses attached to message.
1189 AddressList Message::addresses() const
1191 return d->addressList;
1194 //! \brief Add Address to the address list.
1196 //! \param address - address to append
1197 void Message::addAddress(const Address &a)
1199 d->addressList += a;
1202 //! \brief clear out the address list.
1203 void Message::clearAddresses()
1205 d->addressList.clear();
1208 AddressList Message::findAddresses(Address::Type t) const
1210 AddressList matches;
1211 foreach(Address a, d->addressList) {
1212 if (a.type() == t)
1213 matches.append(a);
1215 return matches;
1218 //! \brief Set addresses to send
1220 //! \param list - list of addresses to send
1221 void Message::setAddresses(const AddressList &list)
1223 d->addressList = list;
1226 const RosterExchangeItems& Message::rosterExchangeItems() const
1228 return d->rosterExchangeItems;
1231 void Message::setRosterExchangeItems(const RosterExchangeItems& items)
1233 d->rosterExchangeItems = items;
1236 QString Message::eventId() const
1238 return d->eventId;
1241 void Message::setEventId(const QString& id)
1243 d->eventId = id;
1246 bool Message::containsEvents() const
1248 return !d->eventList.isEmpty();
1251 bool Message::containsEvent(MsgEvent e) const
1253 return d->eventList.contains(e);
1256 void Message::addEvent(MsgEvent e)
1258 if (!d->eventList.contains(e)) {
1259 if (e == CancelEvent || containsEvent(CancelEvent))
1260 d->eventList.clear(); // Reset list
1261 d->eventList += e;
1265 ChatState Message::chatState() const
1267 return d->chatState;
1270 void Message::setChatState(ChatState state)
1272 d->chatState = state;
1275 MessageReceipt Message::messageReceipt() const
1277 return d->messageReceipt;
1280 void Message::setMessageReceipt(MessageReceipt messageReceipt)
1282 d->messageReceipt = messageReceipt;
1285 QString Message::xencrypted() const
1287 return d->xencrypted;
1290 void Message::setXEncrypted(const QString &s)
1292 d->xencrypted = s;
1295 const QList<int>& Message::getMUCStatuses() const
1297 return d->mucStatuses;
1300 void Message::addMUCStatus(int i)
1302 d->mucStatuses += i;
1305 void Message::addMUCInvite(const MUCInvite& i)
1307 d->mucInvites += i;
1310 const QList<MUCInvite>& Message::mucInvites() const
1312 return d->mucInvites;
1315 void Message::setMUCDecline(const MUCDecline& de)
1317 d->mucDecline = de;
1320 const MUCDecline& Message::mucDecline() const
1322 return d->mucDecline;
1325 const QString& Message::mucPassword() const
1327 return d->mucPassword;
1330 void Message::setMUCPassword(const QString& p)
1332 d->mucPassword = p;
1335 QString Message::invite() const
1337 return d->invite;
1340 void Message::setInvite(const QString &s)
1342 d->invite = s;
1345 const QString& Message::nick() const
1347 return d->nick;
1350 void Message::setNick(const QString& n)
1352 d->nick = n;
1355 void Message::setHttpAuthRequest(const HttpAuthRequest &req)
1357 d->httpAuthRequest = req;
1360 HttpAuthRequest Message::httpAuthRequest() const
1362 return d->httpAuthRequest;
1365 void Message::setForm(const XData &form)
1367 d->xdata = form;
1370 const XData& Message::getForm() const
1372 return d->xdata;
1375 const QDomElement& Message::sxe() const
1377 return d->sxe;
1380 void Message::setSxe(const QDomElement& e)
1382 d->sxe = e;
1385 void Message::addBoBData(const BoBData &bob)
1387 d->bobDataList.append(bob);
1390 QList<BoBData> Message::bobDataList() const
1392 return d->bobDataList;
1395 bool Message::spooled() const
1397 return d->spooled;
1400 void Message::setSpooled(bool b)
1402 d->spooled = b;
1405 bool Message::wasEncrypted() const
1407 return d->wasEncrypted;
1410 void Message::setWasEncrypted(bool b)
1412 d->wasEncrypted = b;
1415 Stanza Message::toStanza(Stream *stream) const
1417 Stanza s = stream->createStanza(Stanza::Message, d->to, d->type);
1418 if(!d->from.isEmpty())
1419 s.setFrom(d->from);
1420 if(!d->id.isEmpty())
1421 s.setId(d->id);
1422 if(!d->lang.isEmpty())
1423 s.setLang(d->lang);
1425 StringMap::ConstIterator it;
1426 for(it = d->subject.begin(); it != d->subject.end(); ++it) {
1427 const QString &str = (*it);
1428 if(!str.isEmpty()) {
1429 QDomElement e = s.createTextElement(s.baseNS(), "subject", str);
1430 if(!it.key().isEmpty())
1431 e.setAttributeNS(NS_XML, "xml:lang", it.key());
1432 s.appendChild(e);
1435 for(it = d->body.begin(); it != d->body.end(); ++it) {
1436 const QString &str = (*it);
1437 if(!str.isEmpty()) {
1438 QDomElement e = s.createTextElement(s.baseNS(), "body", str);
1439 if(!it.key().isEmpty())
1440 e.setAttributeNS(NS_XML, "xml:lang", it.key());
1441 s.appendChild(e);
1445 if (containsHTML()) {
1446 QDomElement html = s.createElement("http://jabber.org/protocol/xhtml-im", "html");
1447 s.appendChild(html);
1448 foreach (HTMLElement el, d->htmlElements) {
1449 html.appendChild(s.doc().importNode(el.body(), true).toElement());
1453 if(d->type == "error")
1454 s.setError(d->error);
1456 // thread
1457 if(d->threadSend && !d->thread.isEmpty()) {
1458 QDomElement e = s.createTextElement(s.baseNS(), "thread", d->thread);
1459 s.appendChild(e);
1462 // timestamp
1463 if(d->timeStampSend && !d->timeStamp.isNull()) {
1464 QDomElement e = s.createElement("urn:xmpp:delay", "delay");
1465 e.setAttribute("stamp", d->timeStamp.toUTC().toString(Qt::ISODate) + "Z");
1466 s.appendChild(e);
1468 e = s.createElement("jabber:x:delay", "x");
1469 e.setAttribute("stamp", TS2stamp(d->timeStamp.toUTC()));
1470 s.appendChild(e);
1473 // urls
1474 for(QList<Url>::ConstIterator uit = d->urlList.begin(); uit != d->urlList.end(); ++uit) {
1475 QDomElement x = s.createElement("jabber:x:oob", "x");
1476 x.appendChild(s.createTextElement("jabber:x:oob", "url", (*uit).url()));
1477 if(!(*uit).desc().isEmpty())
1478 x.appendChild(s.createTextElement("jabber:x:oob", "desc", (*uit).desc()));
1479 s.appendChild(x);
1482 // events
1483 if (!d->eventList.isEmpty()) {
1484 QDomElement x = s.createElement("jabber:x:event", "x");
1486 if (d->body.isEmpty()) {
1487 if (d->eventId.isEmpty())
1488 x.appendChild(s.createElement("jabber:x:event","id"));
1489 else
1490 x.appendChild(s.createTextElement("jabber:x:event","id",d->eventId));
1493 for(QList<MsgEvent>::ConstIterator ev = d->eventList.begin(); ev != d->eventList.end(); ++ev) {
1494 switch (*ev) {
1495 case OfflineEvent:
1496 x.appendChild(s.createElement("jabber:x:event", "offline"));
1497 break;
1498 case DeliveredEvent:
1499 x.appendChild(s.createElement("jabber:x:event", "delivered"));
1500 break;
1501 case DisplayedEvent:
1502 x.appendChild(s.createElement("jabber:x:event", "displayed"));
1503 break;
1504 case ComposingEvent:
1505 x.appendChild(s.createElement("jabber:x:event", "composing"));
1506 break;
1507 case CancelEvent:
1508 // Add nothing
1509 break;
1512 s.appendChild(x);
1515 // chat state
1516 QString chatStateNS = "http://jabber.org/protocol/chatstates";
1517 if (d->chatState != StateNone) {
1518 switch(d->chatState) {
1519 case StateActive:
1520 s.appendChild(s.createElement(chatStateNS, "active"));
1521 break;
1522 case StateComposing:
1523 s.appendChild(s.createElement(chatStateNS, "composing"));
1524 break;
1525 case StatePaused:
1526 s.appendChild(s.createElement(chatStateNS, "paused"));
1527 break;
1528 case StateInactive:
1529 s.appendChild(s.createElement(chatStateNS, "inactive"));
1530 break;
1531 case StateGone:
1532 s.appendChild(s.createElement(chatStateNS, "gone"));
1533 break;
1534 default:
1535 break;
1539 // message receipt
1540 QString messageReceiptNS = "urn:xmpp:receipts";
1541 if (d->messageReceipt != ReceiptNone) {
1542 switch(d->messageReceipt) {
1543 case ReceiptRequest:
1544 s.appendChild(s.createElement(messageReceiptNS, "request"));
1545 break;
1546 case ReceiptReceived:
1547 s.appendChild(s.createElement(messageReceiptNS, "received"));
1548 break;
1549 default:
1550 break;
1554 // xencrypted
1555 if(!d->xencrypted.isEmpty())
1556 s.appendChild(s.createTextElement("jabber:x:encrypted", "x", d->xencrypted));
1558 // addresses
1559 if (!d->addressList.isEmpty()) {
1560 QDomElement as = s.createElement("http://jabber.org/protocol/address","addresses");
1561 foreach(Address a, d->addressList) {
1562 as.appendChild(a.toXml(s));
1564 s.appendChild(as);
1567 // roster item exchange
1568 if (!d->rosterExchangeItems.isEmpty()) {
1569 QDomElement rx = s.createElement("http://jabber.org/protocol/rosterx","x");
1570 foreach(RosterExchangeItem r, d->rosterExchangeItems) {
1571 rx.appendChild(r.toXml(s));
1573 s.appendChild(rx);
1576 // invite
1577 if(!d->invite.isEmpty()) {
1578 QDomElement e = s.createElement("jabber:x:conference", "x");
1579 e.setAttribute("jid", d->invite);
1580 s.appendChild(e);
1583 // nick
1584 if(!d->nick.isEmpty()) {
1585 s.appendChild(s.createTextElement("http://jabber.org/protocol/nick", "nick", d->nick));
1588 // sxe
1589 if(!d->sxe.isNull()) {
1590 s.appendChild(d->sxe);
1593 // muc
1594 if(!d->mucInvites.isEmpty()) {
1595 QDomElement e = s.createElement("http://jabber.org/protocol/muc#user","x");
1596 foreach(MUCInvite i, d->mucInvites) {
1597 e.appendChild(i.toXml(s.doc()));
1599 if (!d->mucPassword.isEmpty()) {
1600 e.appendChild(s.createTextElement("http://jabber.org/protocol/muc#user","password",d->mucPassword));
1602 s.appendChild(e);
1604 else if(!d->mucDecline.isNull()) {
1605 QDomElement e = s.createElement("http://jabber.org/protocol/muc#user","x");
1606 e.appendChild(d->mucDecline.toXml(s.doc()));
1607 s.appendChild(e);
1610 // http auth
1611 if(!d->httpAuthRequest.isEmpty()) {
1612 s.appendChild(d->httpAuthRequest.toXml(s.doc()));
1615 // data form
1616 if(!d->xdata.fields().empty() || (d->xdata.type() == XData::Data_Cancel)) {
1617 bool submit = (d->xdata.type() == XData::Data_Submit) || (d->xdata.type() == XData::Data_Cancel);
1618 s.appendChild(d->xdata.toXml(&s.doc(), submit));
1621 // bits of binary
1622 foreach(const BoBData &bd, d->bobDataList) {
1623 s.appendChild(bd.toXml(&s.doc()));
1626 return s;
1630 \brief Create Message from Stanza \a s, using given \a timeZoneOffset (old style)
1632 bool Message::fromStanza(const Stanza &s, int timeZoneOffset)
1634 return fromStanza(s, true, timeZoneOffset);
1638 \brief Create Message from Stanza \a s
1640 bool Message::fromStanza(const Stanza &s)
1642 return fromStanza(s, false, 0);
1646 \brief Create Message from Stanza \a s
1648 If \a useTimeZoneOffset is true, \a timeZoneOffset is used when converting between UTC and local time (old style).
1649 Else, \a timeZoneOffset is ignored and Qt is used to do the conversion (new style).
1651 This function exists to make transition between old and new style easier.
1653 bool Message::fromStanza(const Stanza &s, bool useTimeZoneOffset, int timeZoneOffset)
1655 if(s.kind() != Stanza::Message)
1656 return false;
1658 setTo(s.to());
1659 setFrom(s.from());
1660 setId(s.id());
1661 setType(s.type());
1662 setLang(s.lang());
1664 d->subject.clear();
1665 d->body.clear();
1666 d->htmlElements.clear();
1667 d->thread = QString();
1669 QDomElement root = s.element();
1671 XDomNodeList nl = root.childNodes();
1672 int n;
1673 for(n = 0; n < nl.count(); ++n) {
1674 QDomNode i = nl.item(n);
1675 if(i.isElement()) {
1676 QDomElement e = i.toElement();
1677 if(e.namespaceURI() == s.baseNS()) {
1678 if(e.tagName() == "subject") {
1679 QString lang = e.attributeNS(NS_XML, "lang", "");
1680 d->subject[lang] = e.text();
1682 else if(e.tagName() == "body") {
1683 QString lang = e.attributeNS(NS_XML, "lang", "");
1684 d->body[lang] = e.text();
1686 else if(e.tagName() == "thread")
1687 d->thread = e.text();
1689 else if(e.tagName() == "event" && e.namespaceURI() == "http://jabber.org/protocol/pubsub#event") {
1690 for(QDomNode enode = e.firstChild(); !enode.isNull(); enode = enode.nextSibling()) {
1691 QDomElement eel = enode.toElement();
1692 if (eel.tagName() == "items") {
1693 d->pubsubNode = eel.attribute("node");
1694 for(QDomNode inode = eel.firstChild(); !inode.isNull(); inode = inode.nextSibling()) {
1695 QDomElement o = inode.toElement();
1696 if (o.tagName() == "item") {
1697 for(QDomNode j = o.firstChild(); !j.isNull(); j = j.nextSibling()) {
1698 QDomElement item = j.toElement();
1699 if (!item.isNull()) {
1700 d->pubsubItems += PubSubItem(o.attribute("id"),item);
1704 if (o.tagName() == "retract") {
1705 d->pubsubRetractions += PubSubRetraction(o.attribute("id"));
1711 else {
1712 //printf("extension element: [%s]\n", e.tagName().latin1());
1717 if(s.type() == "error")
1718 d->error = s.error();
1720 // Bits of Binary XEP-0231
1721 nl = childElementsByTagNameNS(root, "urn:xmpp:bob", "data");
1722 for(n = 0; n < nl.count(); ++n) {
1723 addBoBData(BoBData(nl.item(n).toElement()));
1726 // xhtml-im
1727 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/xhtml-im", "html");
1728 if (nl.count()) {
1729 nl = nl.item(0).childNodes();
1730 for(n = 0; n < nl.count(); ++n) {
1731 QDomElement e = nl.item(n).toElement();
1732 if (e.tagName() == "body" && e.namespaceURI() == "http://www.w3.org/1999/xhtml") {
1733 QString lang = e.attributeNS(NS_XML, "lang", "");
1734 d->htmlElements[lang] = e;
1739 // timestamp
1740 QDomElement t = childElementsByTagNameNS(root, "urn:xmpp:delay", "delay").item(0).toElement();
1741 QDateTime stamp;
1742 if (!t.isNull()) {
1743 stamp = QDateTime::fromString(t.attribute("stamp").left(19), Qt::ISODate);
1744 } else {
1745 t = childElementsByTagNameNS(root, "jabber:x:delay", "x").item(0).toElement();
1746 if (!t.isNull()) {
1747 stamp = stamp2TS(t.attribute("stamp"));
1750 if (!stamp.isNull()) {
1751 if (useTimeZoneOffset) {
1752 d->timeStamp = stamp.addSecs(timeZoneOffset * 3600);
1753 } else {
1754 stamp.setTimeSpec(Qt::UTC);
1755 d->timeStamp = stamp.toLocalTime();
1757 d->spooled = true;
1759 else {
1760 d->timeStamp = QDateTime::currentDateTime();
1761 d->spooled = false;
1764 // urls
1765 d->urlList.clear();
1766 nl = childElementsByTagNameNS(root, "jabber:x:oob", "x");
1767 for(n = 0; n < nl.count(); ++n) {
1768 QDomElement t = nl.item(n).toElement();
1769 Url u;
1770 u.setUrl(t.elementsByTagName("url").item(0).toElement().text());
1771 u.setDesc(t.elementsByTagName("desc").item(0).toElement().text());
1772 d->urlList += u;
1775 // events
1776 d->eventList.clear();
1777 nl = childElementsByTagNameNS(root, "jabber:x:event", "x");
1778 if (nl.count()) {
1779 nl = nl.item(0).childNodes();
1780 for(n = 0; n < nl.count(); ++n) {
1781 QString evtag = nl.item(n).toElement().tagName();
1782 if (evtag == "id") {
1783 d->eventId = nl.item(n).toElement().text();
1785 else if (evtag == "displayed")
1786 d->eventList += DisplayedEvent;
1787 else if (evtag == "composing")
1788 d->eventList += ComposingEvent;
1789 else if (evtag == "delivered")
1790 d->eventList += DeliveredEvent;
1792 if (d->eventList.isEmpty())
1793 d->eventList += CancelEvent;
1796 // Chat states
1797 QString chatStateNS = "http://jabber.org/protocol/chatstates";
1798 t = childElementsByTagNameNS(root, chatStateNS, "active").item(0).toElement();
1799 if(!t.isNull())
1800 d->chatState = StateActive;
1801 t = childElementsByTagNameNS(root, chatStateNS, "composing").item(0).toElement();
1802 if(!t.isNull())
1803 d->chatState = StateComposing;
1804 t = childElementsByTagNameNS(root, chatStateNS, "paused").item(0).toElement();
1805 if(!t.isNull())
1806 d->chatState = StatePaused;
1807 t = childElementsByTagNameNS(root, chatStateNS, "inactive").item(0).toElement();
1808 if(!t.isNull())
1809 d->chatState = StateInactive;
1810 t = childElementsByTagNameNS(root, chatStateNS, "gone").item(0).toElement();
1811 if(!t.isNull())
1812 d->chatState = StateGone;
1814 // message receipts
1815 QString messageReceiptNS = "urn:xmpp:receipts";
1816 t = childElementsByTagNameNS(root, messageReceiptNS, "request").item(0).toElement();
1817 if(!t.isNull())
1818 d->messageReceipt = ReceiptRequest;
1819 t = childElementsByTagNameNS(root, messageReceiptNS, "received").item(0).toElement();
1820 if(!t.isNull())
1821 d->messageReceipt = ReceiptReceived;
1823 // xencrypted
1824 t = childElementsByTagNameNS(root, "jabber:x:encrypted", "x").item(0).toElement();
1825 if(!t.isNull())
1826 d->xencrypted = t.text();
1827 else
1828 d->xencrypted = QString();
1830 // addresses
1831 d->addressList.clear();
1832 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/address", "addresses");
1833 if (nl.count()) {
1834 QDomElement t = nl.item(0).toElement();
1835 nl = t.elementsByTagName("address");
1836 for(n = 0; n < nl.count(); ++n) {
1837 d->addressList += Address(nl.item(n).toElement());
1841 // roster item exchange
1842 d->rosterExchangeItems.clear();
1843 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/rosterx", "x");
1844 if (nl.count()) {
1845 QDomElement t = nl.item(0).toElement();
1846 nl = t.elementsByTagName("item");
1847 for(n = 0; n < nl.count(); ++n) {
1848 RosterExchangeItem it = RosterExchangeItem(nl.item(n).toElement());
1849 if (!it.isNull())
1850 d->rosterExchangeItems += it;
1854 // invite
1855 t = childElementsByTagNameNS(root, "jabber:x:conference", "x").item(0).toElement();
1856 if(!t.isNull())
1857 d->invite = t.attribute("jid");
1858 else
1859 d->invite = QString();
1861 // nick
1862 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/nick", "nick").item(0).toElement();
1863 if(!t.isNull())
1864 d->nick = t.text();
1865 else
1866 d->nick = QString();
1868 // sxe
1869 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/sxe", "sxe").item(0).toElement();
1870 if(!t.isNull())
1871 d->sxe = t;
1872 else
1873 d->sxe = QDomElement();
1875 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/muc#user", "x").item(0).toElement();
1876 if(!t.isNull()) {
1877 for(QDomNode muc_n = t.firstChild(); !muc_n.isNull(); muc_n = muc_n.nextSibling()) {
1878 QDomElement muc_e = muc_n.toElement();
1879 if(muc_e.isNull())
1880 continue;
1881 if (muc_e.tagName() == "status") {
1882 addMUCStatus(muc_e.attribute("code").toInt());
1884 else if (muc_e.tagName() == "invite") {
1885 MUCInvite inv(muc_e);
1886 if (!inv.isNull())
1887 addMUCInvite(inv);
1889 else if (muc_e.tagName() == "decline") {
1890 setMUCDecline(MUCDecline(muc_e));
1892 else if (muc_e.tagName() == "password") {
1893 setMUCPassword(muc_e.text());
1898 // http auth
1899 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/http-auth", "confirm").item(0).toElement();
1900 if(!t.isNull()){
1901 d->httpAuthRequest = HttpAuthRequest(t);
1903 else {
1904 d->httpAuthRequest = HttpAuthRequest();
1907 // data form
1908 t = childElementsByTagNameNS(root, "jabber:x:data", "x").item(0).toElement();
1909 if(!t.isNull()){
1910 d->xdata.fromXml(t);
1913 return true;
1917 Error object used to deny a request.
1919 Stanza::Error HttpAuthRequest::denyError(Stanza::Error::Auth, Stanza::Error::NotAuthorized);
1922 Constructs request of resource URL \a u, made by method \a m, with transaction id \a i.
1924 HttpAuthRequest::HttpAuthRequest(const QString &m, const QString &u, const QString &i) : method_(m), url_(u), id_(i), hasId_(true)
1929 Constructs request of resource URL \a u, made by method \a m, without transaction id.
1931 HttpAuthRequest::HttpAuthRequest(const QString &m, const QString &u) : method_(m), url_(u), hasId_(false)
1936 Constructs request object by reading XML <confirm/> element \a e.
1938 HttpAuthRequest::HttpAuthRequest(const QDomElement &e)
1940 fromXml(e);
1944 Returns true is object is empty (not valid).
1946 bool HttpAuthRequest::isEmpty() const
1948 return method_.isEmpty() && url_.isEmpty();
1952 Sets request method.
1954 void HttpAuthRequest::setMethod(const QString& m)
1956 method_ = m;
1960 Sets requested URL.
1962 void HttpAuthRequest::setUrl(const QString& u)
1964 url_ = u;
1968 Sets transaction identifier.
1970 void HttpAuthRequest::setId(const QString& i)
1972 id_ = i;
1973 hasId_ = true;
1977 Returns request method.
1979 QString HttpAuthRequest::method() const
1981 return method_;
1985 Returns requested URL.
1987 QString HttpAuthRequest::url() const
1989 return url_;
1993 Returns transaction identifier.
1994 Empty QString may mean both empty id or no id. Use hasId() to tell the difference.
1996 QString HttpAuthRequest::id() const
1998 return id_;
2002 Returns true if the request contains transaction id.
2004 bool HttpAuthRequest::hasId() const
2006 return hasId_;
2010 Returns XML element representing the request.
2011 If object is empty, this function returns empty element.
2013 QDomElement HttpAuthRequest::toXml(QDomDocument &doc) const
2015 QDomElement e;
2016 if(isEmpty())
2017 return e;
2019 e = doc.createElementNS("http://jabber.org/protocol/http-auth", "confirm");
2020 e.setAttribute("xmlns", "http://jabber.org/protocol/http-auth");
2022 if(hasId_)
2023 e.setAttribute("id", id_);
2024 e.setAttribute("method", method_);
2025 e.setAttribute("url", url_);
2027 return e;
2031 Reads request data from XML element \a e.
2033 bool HttpAuthRequest::fromXml(const QDomElement &e)
2035 if(e.tagName() != "confirm")
2036 return false;
2038 hasId_ = e.hasAttribute("id");
2039 if(hasId_)
2040 id_ = e.attribute("id");
2042 method_ = e.attribute("method");
2043 url_ = e.attribute("url");
2045 return true;
2048 //---------------------------------------------------------------------------
2049 // Subscription
2050 //---------------------------------------------------------------------------
2051 Subscription::Subscription(SubType type)
2053 value = type;
2056 int Subscription::type() const
2058 return value;
2061 QString Subscription::toString() const
2063 switch(value) {
2064 case Remove:
2065 return "remove";
2066 case Both:
2067 return "both";
2068 case From:
2069 return "from";
2070 case To:
2071 return "to";
2072 case None:
2073 default:
2074 return "none";
2078 bool Subscription::fromString(const QString &s)
2080 if(s == "remove")
2081 value = Remove;
2082 else if(s == "both")
2083 value = Both;
2084 else if(s == "from")
2085 value = From;
2086 else if(s == "to")
2087 value = To;
2088 else if(s == "none")
2089 value = None;
2090 else
2091 return false;
2093 return true;
2097 //---------------------------------------------------------------------------
2098 // Status
2099 //---------------------------------------------------------------------------
2101 Status::Status(const QString &show, const QString &status, int priority, bool available)
2103 v_isAvailable = available;
2104 v_show = show;
2105 v_status = status;
2106 v_priority = priority;
2107 v_timeStamp = QDateTime::currentDateTime();
2108 v_isInvisible = false;
2109 v_hasPhotoHash = false;
2110 v_isMUC = false;
2111 v_hasMUCItem = false;
2112 v_hasMUCDestroy = false;
2113 v_mucHistoryMaxChars = -1;
2114 v_mucHistoryMaxStanzas = -1;
2115 v_mucHistorySeconds = -1;
2116 ecode = -1;
2119 Status::Status(Type type, const QString& status, int priority)
2121 v_status = status;
2122 v_priority = priority;
2123 v_timeStamp = QDateTime::currentDateTime();
2124 v_hasPhotoHash = false;
2125 v_isMUC = false;
2126 v_hasMUCItem = false;
2127 v_hasMUCDestroy = false;
2128 v_mucHistoryMaxChars = -1;
2129 v_mucHistoryMaxStanzas = -1;
2130 v_mucHistorySeconds = -1;
2131 ecode = -1;
2132 setType(type);
2135 Status::~Status()
2139 bool Status::hasError() const
2141 return (ecode != -1);
2144 void Status::setError(int code, const QString &str)
2146 ecode = code;
2147 estr = str;
2150 void Status::setIsAvailable(bool available)
2152 v_isAvailable = available;
2155 void Status::setIsInvisible(bool invisible)
2157 v_isInvisible = invisible;
2160 void Status::setPriority(int x)
2162 v_priority = x;
2165 void Status::setType(Status::Type _type)
2167 bool available = true;
2168 bool invisible = false;
2169 QString show;
2170 switch(_type) {
2171 case Away: show = "away"; break;
2172 case FFC: show = "chat"; break;
2173 case XA: show = "xa"; break;
2174 case DND: show = "dnd"; break;
2175 case Offline: available = false; break;
2176 case Invisible: invisible = true; break;
2177 default: break;
2179 setShow(show);
2180 setIsAvailable(available);
2181 setIsInvisible(invisible);
2184 void Status::setType(QString stat)
2186 if (stat == "offline")
2187 setType(XMPP::Status::Offline);
2188 else if (stat == "online")
2189 setType(XMPP::Status::Online);
2190 else if (stat == "away")
2191 setType(XMPP::Status::Away);
2192 else if (stat == "xa")
2193 setType(XMPP::Status::XA);
2194 else if (stat == "dnd")
2195 setType(XMPP::Status::DND);
2196 else if (stat == "invisible")
2197 setType(XMPP::Status::Invisible);
2198 else if (stat == "chat")
2199 setType(XMPP::Status::FFC);
2200 else
2201 setType(XMPP::Status::Away);
2204 void Status::setShow(const QString & _show)
2206 v_show = _show;
2209 void Status::setStatus(const QString & _status)
2211 v_status = _status;
2214 void Status::setTimeStamp(const QDateTime & _timestamp)
2216 v_timeStamp = _timestamp;
2219 void Status::setKeyID(const QString &key)
2221 v_key = key;
2224 void Status::setXSigned(const QString &s)
2226 v_xsigned = s;
2229 void Status::setSongTitle(const QString & _songtitle)
2231 v_songTitle = _songtitle;
2234 void Status::setCapsNode(const QString & _capsNode)
2236 v_capsNode = _capsNode;
2239 void Status::setCapsVersion(const QString & _capsVersion)
2241 v_capsVersion = _capsVersion;
2244 void Status::setCapsExt(const QString & _capsExt)
2246 v_capsExt = _capsExt;
2249 void Status::setMUC()
2251 v_isMUC = true;
2254 void Status::setMUCItem(const MUCItem& i)
2256 v_hasMUCItem = true;
2257 v_mucItem = i;
2260 void Status::setMUCDestroy(const MUCDestroy& i)
2262 v_hasMUCDestroy = true;
2263 v_mucDestroy = i;
2266 void Status::setMUCHistory(int maxchars, int maxstanzas, int seconds)
2268 v_mucHistoryMaxChars = maxchars;
2269 v_mucHistoryMaxStanzas = maxstanzas;
2270 v_mucHistorySeconds = seconds;
2274 const QString& Status::photoHash() const
2276 return v_photoHash;
2279 void Status::setPhotoHash(const QString& h)
2281 v_photoHash = h;
2282 v_hasPhotoHash = true;
2285 bool Status::hasPhotoHash() const
2287 return v_hasPhotoHash;
2290 void Status::addBoBData(const BoBData &bob)
2292 v_bobDataList.append(bob);
2295 QList<BoBData> Status::bobDataList() const
2297 return v_bobDataList;
2300 bool Status::isAvailable() const
2302 return v_isAvailable;
2305 bool Status::isAway() const
2307 return (v_show == "away" || v_show == "xa" || v_show == "dnd");
2310 bool Status::isInvisible() const
2312 return v_isInvisible;
2315 int Status::priority() const
2317 return v_priority;
2320 Status::Type Status::type() const
2322 Status::Type type = Status::Online;
2323 if (!isAvailable()) {
2324 type = Status::Offline;
2326 else if (isInvisible()) {
2327 type = Status::Invisible;
2329 else {
2330 QString s = show();
2331 if (s == "away")
2332 type = Status::Away;
2333 else if (s == "xa")
2334 type = Status::XA;
2335 else if (s == "dnd")
2336 type = Status::DND;
2337 else if (s == "chat")
2338 type = Status::FFC;
2340 return type;
2343 QString Status::typeString() const
2345 QString stat;
2346 switch(type()) {
2347 case XMPP::Status::Offline: stat = "offline"; break;
2348 case XMPP::Status::Online: stat = "online"; break;
2349 case XMPP::Status::Away: stat = "away"; break;
2350 case XMPP::Status::XA: stat = "xa"; break;
2351 case XMPP::Status::DND: stat = "dnd"; break;
2352 case XMPP::Status::Invisible: stat = "invisible"; break;
2353 case XMPP::Status::FFC: stat = "chat"; break;
2354 default: stat = "away";
2356 return stat;
2359 const QString & Status::show() const
2361 return v_show;
2363 const QString & Status::status() const
2365 return v_status;
2368 QDateTime Status::timeStamp() const
2370 return v_timeStamp;
2373 const QString & Status::keyID() const
2375 return v_key;
2378 const QString & Status::xsigned() const
2380 return v_xsigned;
2383 const QString & Status::songTitle() const
2385 return v_songTitle;
2388 const QString & Status::capsNode() const
2390 return v_capsNode;
2393 const QString & Status::capsVersion() const
2395 return v_capsVersion;
2398 const QString & Status::capsExt() const
2400 return v_capsExt;
2403 bool Status::isMUC() const
2405 return v_isMUC || !v_mucPassword.isEmpty() || hasMUCHistory();
2408 bool Status::hasMUCItem() const
2410 return v_hasMUCItem;
2413 const MUCItem& Status::mucItem() const
2415 return v_mucItem;
2418 bool Status::hasMUCDestroy() const
2420 return v_hasMUCDestroy;
2423 const MUCDestroy& Status::mucDestroy() const
2425 return v_mucDestroy;
2428 const QList<int>& Status::getMUCStatuses() const
2430 return v_mucStatuses;
2433 void Status::addMUCStatus(int i)
2435 v_mucStatuses += i;
2438 const QString& Status::mucPassword() const
2440 return v_mucPassword;
2443 bool Status::hasMUCHistory() const
2445 return v_mucHistoryMaxChars >= 0 || v_mucHistoryMaxStanzas >= 0 || v_mucHistorySeconds >= 0;
2448 int Status::mucHistoryMaxChars() const
2450 return v_mucHistoryMaxChars;
2453 int Status::mucHistoryMaxStanzas() const
2455 return v_mucHistoryMaxStanzas;
2458 int Status::mucHistorySeconds() const
2460 return v_mucHistorySeconds;
2463 void Status::setMUCPassword(const QString& i)
2465 v_mucPassword = i;
2468 int Status::errorCode() const
2470 return ecode;
2473 const QString & Status::errorString() const
2475 return estr;
2479 //---------------------------------------------------------------------------
2480 // Resource
2481 //---------------------------------------------------------------------------
2482 Resource::Resource(const QString &name, const Status &stat)
2484 v_name = name;
2485 v_status = stat;
2488 Resource::~Resource()
2492 const QString & Resource::name() const
2494 return v_name;
2497 int Resource::priority() const
2499 return v_status.priority();
2502 const Status & Resource::status() const
2504 return v_status;
2507 void Resource::setName(const QString & _name)
2509 v_name = _name;
2512 void Resource::setStatus(const Status & _status)
2514 v_status = _status;
2518 //---------------------------------------------------------------------------
2519 // ResourceList
2520 //---------------------------------------------------------------------------
2521 ResourceList::ResourceList()
2522 :QList<Resource>()
2526 ResourceList::~ResourceList()
2530 ResourceList::Iterator ResourceList::find(const QString & _find)
2532 for(ResourceList::Iterator it = begin(); it != end(); ++it) {
2533 if((*it).name() == _find)
2534 return it;
2537 return end();
2540 ResourceList::Iterator ResourceList::priority()
2542 ResourceList::Iterator highest = end();
2544 for(ResourceList::Iterator it = begin(); it != end(); ++it) {
2545 if(highest == end() || (*it).priority() > (*highest).priority())
2546 highest = it;
2549 return highest;
2552 ResourceList::ConstIterator ResourceList::find(const QString & _find) const
2554 for(ResourceList::ConstIterator it = begin(); it != end(); ++it) {
2555 if((*it).name() == _find)
2556 return it;
2559 return end();
2562 ResourceList::ConstIterator ResourceList::priority() const
2564 ResourceList::ConstIterator highest = end();
2566 for(ResourceList::ConstIterator it = begin(); it != end(); ++it) {
2567 if(highest == end() || (*it).priority() > (*highest).priority())
2568 highest = it;
2571 return highest;
2575 //---------------------------------------------------------------------------
2576 // RosterItem
2577 //---------------------------------------------------------------------------
2578 RosterItem::RosterItem(const Jid &_jid)
2580 v_jid = _jid;
2581 v_push = false;
2584 RosterItem::~RosterItem()
2588 const Jid & RosterItem::jid() const
2590 return v_jid;
2593 const QString & RosterItem::name() const
2595 return v_name;
2598 const QStringList & RosterItem::groups() const
2600 return v_groups;
2603 const Subscription & RosterItem::subscription() const
2605 return v_subscription;
2608 const QString & RosterItem::ask() const
2610 return v_ask;
2613 bool RosterItem::isPush() const
2615 return v_push;
2618 bool RosterItem::inGroup(const QString &g) const
2620 for(QStringList::ConstIterator it = v_groups.begin(); it != v_groups.end(); ++it) {
2621 if(*it == g)
2622 return true;
2624 return false;
2627 void RosterItem::setJid(const Jid &_jid)
2629 v_jid = _jid;
2632 void RosterItem::setName(const QString &_name)
2634 v_name = _name;
2637 void RosterItem::setGroups(const QStringList &_groups)
2639 v_groups = _groups;
2642 void RosterItem::setSubscription(const Subscription &type)
2644 v_subscription = type;
2647 void RosterItem::setAsk(const QString &_ask)
2649 v_ask = _ask;
2652 void RosterItem::setIsPush(bool b)
2654 v_push = b;
2657 bool RosterItem::addGroup(const QString &g)
2659 if(inGroup(g))
2660 return false;
2662 v_groups += g;
2663 return true;
2666 bool RosterItem::removeGroup(const QString &g)
2668 for(QStringList::Iterator it = v_groups.begin(); it != v_groups.end(); ++it) {
2669 if(*it == g) {
2670 v_groups.erase(it);
2671 return true;
2675 return false;
2678 QDomElement RosterItem::toXml(QDomDocument *doc) const
2680 QDomElement item = doc->createElement("item");
2681 item.setAttribute("jid", v_jid.full());
2682 item.setAttribute("name", v_name);
2683 item.setAttribute("subscription", v_subscription.toString());
2684 if(!v_ask.isEmpty())
2685 item.setAttribute("ask", v_ask);
2686 for(QStringList::ConstIterator it = v_groups.begin(); it != v_groups.end(); ++it)
2687 item.appendChild(textTag(doc, "group", *it));
2689 return item;
2692 bool RosterItem::fromXml(const QDomElement &item)
2694 if(item.tagName() != "item")
2695 return false;
2696 Jid j(item.attribute("jid"));
2697 if(!j.isValid())
2698 return false;
2699 QString na = item.attribute("name");
2700 Subscription s;
2701 if(!s.fromString(item.attribute("subscription")) )
2702 return false;
2703 QStringList g;
2704 for(QDomNode n = item.firstChild(); !n.isNull(); n = n.nextSibling()) {
2705 QDomElement i = n.toElement();
2706 if(i.isNull())
2707 continue;
2708 if(i.tagName() == "group")
2709 g += tagContent(i);
2711 QString a = item.attribute("ask");
2713 v_jid = j;
2714 v_name = na;
2715 v_subscription = s;
2716 v_groups = g;
2717 v_ask = a;
2719 return true;
2723 //---------------------------------------------------------------------------
2724 // Roster
2725 //---------------------------------------------------------------------------
2726 Roster::Roster()
2727 :QList<RosterItem>()
2731 Roster::~Roster()
2735 Roster::Iterator Roster::find(const Jid &j)
2737 for(Roster::Iterator it = begin(); it != end(); ++it) {
2738 if((*it).jid().compare(j))
2739 return it;
2742 return end();
2745 Roster::ConstIterator Roster::find(const Jid &j) const
2747 for(Roster::ConstIterator it = begin(); it != end(); ++it) {
2748 if((*it).jid().compare(j))
2749 return it;
2752 return end();
2756 //---------------------------------------------------------------------------
2757 // FormField
2758 //---------------------------------------------------------------------------
2759 FormField::FormField(const QString &type, const QString &value)
2761 v_type = misc;
2762 if(!type.isEmpty()) {
2763 int x = tagNameToType(type);
2764 if(x != -1)
2765 v_type = x;
2767 v_value = value;
2770 FormField::~FormField()
2774 int FormField::type() const
2776 return v_type;
2779 QString FormField::realName() const
2781 return typeToTagName(v_type);
2784 QString FormField::fieldName() const
2786 switch(v_type) {
2787 case username: return QObject::tr("Username");
2788 case nick: return QObject::tr("Nickname");
2789 case password: return QObject::tr("Password");
2790 case name: return QObject::tr("Name");
2791 case first: return QObject::tr("First Name");
2792 case last: return QObject::tr("Last Name");
2793 case email: return QObject::tr("E-mail");
2794 case address: return QObject::tr("Address");
2795 case city: return QObject::tr("City");
2796 case state: return QObject::tr("State");
2797 case zip: return QObject::tr("Zipcode");
2798 case phone: return QObject::tr("Phone");
2799 case url: return QObject::tr("URL");
2800 case date: return QObject::tr("Date");
2801 case misc: return QObject::tr("Misc");
2802 default: return "";
2806 bool FormField::isSecret() const
2808 return (type() == password);
2811 const QString & FormField::value() const
2813 return v_value;
2816 void FormField::setType(int x)
2818 v_type = x;
2821 bool FormField::setType(const QString &in)
2823 int x = tagNameToType(in);
2824 if(x == -1)
2825 return false;
2827 v_type = x;
2828 return true;
2831 void FormField::setValue(const QString &in)
2833 v_value = in;
2836 int FormField::tagNameToType(const QString &in) const
2838 if(!in.compare("username")) return username;
2839 if(!in.compare("nick")) return nick;
2840 if(!in.compare("password")) return password;
2841 if(!in.compare("name")) return name;
2842 if(!in.compare("first")) return first;
2843 if(!in.compare("last")) return last;
2844 if(!in.compare("email")) return email;
2845 if(!in.compare("address")) return address;
2846 if(!in.compare("city")) return city;
2847 if(!in.compare("state")) return state;
2848 if(!in.compare("zip")) return zip;
2849 if(!in.compare("phone")) return phone;
2850 if(!in.compare("url")) return url;
2851 if(!in.compare("date")) return date;
2852 if(!in.compare("misc")) return misc;
2854 return -1;
2857 QString FormField::typeToTagName(int type) const
2859 switch(type) {
2860 case username: return "username";
2861 case nick: return "nick";
2862 case password: return "password";
2863 case name: return "name";
2864 case first: return "first";
2865 case last: return "last";
2866 case email: return "email";
2867 case address: return "address";
2868 case city: return "city";
2869 case state: return "state";
2870 case zip: return "zipcode";
2871 case phone: return "phone";
2872 case url: return "url";
2873 case date: return "date";
2874 case misc: return "misc";
2875 default: return "";
2880 //---------------------------------------------------------------------------
2881 // Form
2882 //---------------------------------------------------------------------------
2883 Form::Form(const Jid &j)
2884 :QList<FormField>()
2886 setJid(j);
2889 Form::~Form()
2893 Jid Form::jid() const
2895 return v_jid;
2898 QString Form::instructions() const
2900 return v_instructions;
2903 QString Form::key() const
2905 return v_key;
2908 void Form::setJid(const Jid &j)
2910 v_jid = j;
2913 void Form::setInstructions(const QString &s)
2915 v_instructions = s;
2918 void Form::setKey(const QString &s)
2920 v_key = s;
2924 //---------------------------------------------------------------------------
2925 // SearchResult
2926 //---------------------------------------------------------------------------
2927 SearchResult::SearchResult(const Jid &jid)
2929 setJid(jid);
2932 SearchResult::~SearchResult()
2936 const Jid & SearchResult::jid() const
2938 return v_jid;
2941 const QString & SearchResult::nick() const
2943 return v_nick;
2946 const QString & SearchResult::first() const
2948 return v_first;
2951 const QString & SearchResult::last() const
2953 return v_last;
2956 const QString & SearchResult::email() const
2958 return v_email;
2961 void SearchResult::setJid(const Jid &jid)
2963 v_jid = jid;
2966 void SearchResult::setNick(const QString &nick)
2968 v_nick = nick;
2971 void SearchResult::setFirst(const QString &first)
2973 v_first = first;
2976 void SearchResult::setLast(const QString &last)
2978 v_last = last;
2981 void SearchResult::setEmail(const QString &email)
2983 v_email = email;
2986 PubSubItem::PubSubItem()
2990 PubSubItem::PubSubItem(const QString& id, const QDomElement& payload) : id_(id), payload_(payload)
2994 const QString& PubSubItem::id() const
2996 return id_;
2999 const QDomElement& PubSubItem::payload() const
3001 return payload_;
3005 PubSubRetraction::PubSubRetraction()
3009 PubSubRetraction::PubSubRetraction(const QString& id) : id_(id)
3013 const QString& PubSubRetraction::id() const
3015 return id_;