File indexing completed on 2024-06-02 04:07:09
0001 /* 0002 * types.cpp - IM data types 0003 * Copyright (C) 2003 Justin Karneges 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * either version 2 0009 of the License, or (at your option) any later version.1 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Lesser General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Lesser General Public 0017 * License along with this library; if not, write to the Free Software 0018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0019 * 0020 */ 0021 0022 #include "im.h" 0023 #include "protocol.h" 0024 #include "xmpp_features.h" 0025 0026 #include <QMap> 0027 #include <QApplication> 0028 //Added by qt3to4: 0029 #include <QList> 0030 0031 #include "xmpp_xmlcommon.h" 0032 #define NS_XML "http://www.w3.org/XML/1998/namespace" 0033 0034 namespace XMPP 0035 { 0036 0037 //---------------------------------------------------------------------------- 0038 // Url 0039 //---------------------------------------------------------------------------- 0040 class Url::Private 0041 { 0042 public: 0043 QString url; 0044 QString desc; 0045 }; 0046 0047 //! \brief Construct Url object with a given URL and Description. 0048 //! 0049 //! This function will construct a Url object. 0050 //! \param QString - url (default: empty string) 0051 //! \param QString - description of url (default: empty string) 0052 //! \sa setUrl() setDesc() 0053 Url::Url(const QString &url, const QString &desc) 0054 { 0055 d = new Private; 0056 d->url = url; 0057 d->desc = desc; 0058 } 0059 0060 //! \brief Construct Url object. 0061 //! 0062 //! Overloaded constructor which will constructs a exact copy of the Url object that was passed to the constructor. 0063 //! \param Url - Url Object 0064 Url::Url(const Url &from) 0065 { 0066 d = new Private; 0067 *this = from; 0068 } 0069 0070 //! \brief operator overloader needed for d pointer (Internel). 0071 Url & Url::operator=(const Url &from) 0072 { 0073 *d = *from.d; 0074 return *this; 0075 } 0076 0077 //! \brief destroy Url object. 0078 Url::~Url() 0079 { 0080 delete d; 0081 } 0082 0083 //! \brief Get url information. 0084 //! 0085 //! Returns url information. 0086 QString Url::url() const 0087 { 0088 return d->url; 0089 } 0090 0091 //! \brief Get Description information. 0092 //! 0093 //! Returns desction of the URL. 0094 QString Url::desc() const 0095 { 0096 return d->desc; 0097 } 0098 0099 //! \brief Set Url information. 0100 //! 0101 //! Set url information. 0102 //! \param url - url string (eg: http://psi.affinix.com/) 0103 void Url::setUrl(const QString &url) 0104 { 0105 d->url = url; 0106 } 0107 0108 //! \brief Set Description information. 0109 //! 0110 //! Set description of the url. 0111 //! \param desc - description of url 0112 void Url::setDesc(const QString &desc) 0113 { 0114 d->desc = desc; 0115 } 0116 0117 //---------------------------------------------------------------------------- 0118 // Address 0119 //---------------------------------------------------------------------------- 0120 0121 //! \brief Construct Address object with a given Type and Jid. 0122 //! 0123 //! This function will construct a Address object. 0124 //! \param Type - type (default: Unknown) 0125 //! \param Jid - specify address (default: empty string) 0126 //! \sa setType() setJid() 0127 Address::Address(Type type, const Jid & jid) 0128 : v_delivered(false) 0129 { 0130 v_type = type; 0131 v_jid = jid; 0132 v_delivered = false; 0133 } 0134 0135 Address::Address(const QDomElement& e) 0136 : v_delivered(false) 0137 { 0138 fromXml(e); 0139 } 0140 0141 void Address::fromXml(const QDomElement& t) 0142 { 0143 setJid(t.attribute("jid")); 0144 setUri(t.attribute("uri")); 0145 setNode(t.attribute("node")); 0146 setDesc(t.attribute("desc")); 0147 setDelivered(t.attribute("delivered") == "true"); 0148 QString type = t.attribute("type"); 0149 if (type == "to") 0150 setType(To); 0151 else if (type == "cc") 0152 setType(Cc); 0153 else if (type == "bcc") 0154 setType(Bcc); 0155 else if (type == "replyto") 0156 setType(ReplyTo); 0157 else if (type == "replyroom") 0158 setType(ReplyRoom); 0159 else if (type == "noreply") 0160 setType(NoReply); 0161 else if (type == "ofrom") 0162 setType(OriginalFrom); 0163 else if (type == "oto") 0164 setType(OriginalTo); 0165 } 0166 0167 QDomElement Address::toXml(Stanza& s) const 0168 { 0169 QDomElement e = s.createElement("http://jabber.org/protocol/address", "address"); 0170 if(!jid().isEmpty()) 0171 e.setAttribute("jid", jid().full()); 0172 if(!uri().isEmpty()) 0173 e.setAttribute("uri", uri()); 0174 if(!node().isEmpty()) 0175 e.setAttribute("node", node()); 0176 if(!desc().isEmpty()) 0177 e.setAttribute("desc", desc()); 0178 if(delivered()) 0179 e.setAttribute("delivered", "true"); 0180 switch (type()) { 0181 case To: 0182 e.setAttribute("type", "to"); 0183 break; 0184 case Cc: 0185 e.setAttribute("type", "cc"); 0186 break; 0187 case Bcc: 0188 e.setAttribute("type", "bcc"); 0189 break; 0190 case ReplyTo: 0191 e.setAttribute("type", "replyto"); 0192 break; 0193 case ReplyRoom: 0194 e.setAttribute("type", "replyroom"); 0195 break; 0196 case NoReply: 0197 e.setAttribute("type", "noreply"); 0198 break; 0199 case OriginalFrom: 0200 e.setAttribute("type", "ofrom"); 0201 break; 0202 case OriginalTo: 0203 e.setAttribute("type", "oto"); 0204 break; 0205 case Unknown: 0206 // Add nothing 0207 break; 0208 } 0209 return e; 0210 } 0211 0212 //! \brief Get Jid information. 0213 //! 0214 //! Returns jid information. 0215 const Jid& Address::jid() const 0216 { 0217 return v_jid; 0218 } 0219 0220 //! \brief Get Uri information. 0221 //! 0222 //! Returns desction of the Address. 0223 const QString& Address::uri() const 0224 { 0225 return v_uri; 0226 } 0227 0228 //! \brief Get Node information. 0229 //! 0230 //! Returns node of the Address. 0231 const QString& Address::node() const 0232 { 0233 return v_node; 0234 } 0235 0236 //! \brief Get Description information. 0237 //! 0238 //! Returns desction of the Address. 0239 const QString& Address::desc() const 0240 { 0241 return v_desc; 0242 } 0243 0244 //! \brief Get Delivered information. 0245 //! 0246 //! Returns delivered of the Address. 0247 bool Address::delivered() const 0248 { 0249 return v_delivered; 0250 } 0251 0252 //! \brief Get Type information. 0253 //! 0254 //! Returns type of the Address. 0255 Address::Type Address::type() const 0256 { 0257 return v_type; 0258 } 0259 0260 //! \brief Set Address information. 0261 //! 0262 //! Set jid information. 0263 //! \param jid - jid 0264 void Address::setJid(const Jid &jid) 0265 { 0266 v_jid = jid; 0267 } 0268 0269 //! \brief Set Address information. 0270 //! 0271 //! Set uri information. 0272 //! \param uri - url string (eg: http://psi.affinix.com/) 0273 void Address::setUri(const QString &uri) 0274 { 0275 v_uri = uri; 0276 } 0277 0278 //! \brief Set Node information. 0279 //! 0280 //! Set node information. 0281 //! \param node - node string 0282 void Address::setNode(const QString &node) 0283 { 0284 v_node = node; 0285 } 0286 0287 //! \brief Set Description information. 0288 //! 0289 //! Set description of the url. 0290 //! \param desc - description of url 0291 void Address::setDesc(const QString &desc) 0292 { 0293 v_desc = desc; 0294 } 0295 0296 //! \brief Set delivered information. 0297 //! 0298 //! Set delivered information. 0299 //! \param delivered - delivered flag 0300 void Address::setDelivered(bool delivered) 0301 { 0302 v_delivered = delivered; 0303 } 0304 0305 //! \brief Set Type information. 0306 //! 0307 //! Set type information. 0308 //! \param type - type 0309 void Address::setType(Type type) 0310 { 0311 v_type = type; 0312 } 0313 0314 //---------------------------------------------------------------------------- 0315 // RosterExchangeItem 0316 //---------------------------------------------------------------------------- 0317 0318 RosterExchangeItem::RosterExchangeItem(const Jid& jid, const QString& name, const QStringList& groups, Action action) : jid_(jid), name_(name), groups_(groups), action_(action) 0319 { 0320 } 0321 0322 RosterExchangeItem::RosterExchangeItem(const QDomElement& el) : action_(Add) 0323 { 0324 fromXml(el); 0325 } 0326 0327 const Jid& RosterExchangeItem::jid() const 0328 { 0329 return jid_; 0330 } 0331 0332 RosterExchangeItem::Action RosterExchangeItem::action() const 0333 { 0334 return action_; 0335 } 0336 0337 const QString& RosterExchangeItem::name() const 0338 { 0339 return name_; 0340 } 0341 0342 const QStringList& RosterExchangeItem::groups() const 0343 { 0344 return groups_; 0345 } 0346 0347 bool RosterExchangeItem::isNull() const 0348 { 0349 return jid_.isEmpty(); 0350 } 0351 0352 void RosterExchangeItem::setJid(const Jid& jid) 0353 { 0354 jid_ = jid; 0355 } 0356 0357 void RosterExchangeItem::setAction(Action action) 0358 { 0359 action_ = action; 0360 } 0361 0362 void RosterExchangeItem::setName(const QString& name) 0363 { 0364 name_ = name; 0365 } 0366 0367 void RosterExchangeItem::setGroups(const QStringList& groups) 0368 { 0369 groups_ = groups; 0370 } 0371 0372 QDomElement RosterExchangeItem::toXml(Stanza& s) const 0373 { 0374 QDomElement e = s.createElement("http://jabber.org/protocol/rosterx", "item"); 0375 e.setAttribute("jid", jid().full()); 0376 if (!name().isEmpty()) 0377 e.setAttribute("name", name()); 0378 switch(action()) { 0379 case Add: 0380 e.setAttribute("action","add"); 0381 break; 0382 case Delete: 0383 e.setAttribute("action","delete"); 0384 break; 0385 case Modify: 0386 e.setAttribute("action","modify"); 0387 break; 0388 } 0389 foreach(QString group, groups_) { 0390 e.appendChild(s.createTextElement("http://jabber.org/protocol/rosterx", "group",group)); 0391 } 0392 return e; 0393 } 0394 0395 void RosterExchangeItem::fromXml(const QDomElement& e) 0396 { 0397 setJid(e.attribute("jid")); 0398 setName(e.attribute("name")); 0399 if (e.attribute("action") == "delete") { 0400 setAction(Delete); 0401 } 0402 else if (e.attribute("action") == "modify") { 0403 setAction(Modify); 0404 } 0405 else { 0406 setAction(Add); 0407 } 0408 QDomNodeList nl = e.childNodes(); 0409 for(int n = 0; n < nl.count(); ++n) { 0410 QDomElement g = nl.item(n).toElement(); 0411 if (!g.isNull() && g.tagName() == "group") { 0412 groups_ += g.text(); 0413 } 0414 } 0415 } 0416 0417 0418 //---------------------------------------------------------------------------- 0419 // MUCItem 0420 //---------------------------------------------------------------------------- 0421 MUCItem::MUCItem(Role r, Affiliation a) : affiliation_(a), role_(r) 0422 { 0423 } 0424 0425 MUCItem::MUCItem(const QDomElement& el) : affiliation_(UnknownAffiliation), role_(UnknownRole) 0426 { 0427 fromXml(el); 0428 } 0429 0430 void MUCItem::setNick(const QString& n) 0431 { 0432 nick_ = n; 0433 } 0434 0435 void MUCItem::setJid(const Jid& j) 0436 { 0437 jid_ = j; 0438 } 0439 0440 void MUCItem::setAffiliation(Affiliation a) 0441 { 0442 affiliation_ = a; 0443 } 0444 0445 void MUCItem::setRole(Role r) 0446 { 0447 role_ = r; 0448 } 0449 0450 void MUCItem::setActor(const Jid& a) 0451 { 0452 actor_ = a; 0453 } 0454 0455 void MUCItem::setReason(const QString& r) 0456 { 0457 reason_ = r; 0458 } 0459 0460 const QString& MUCItem::nick() const 0461 { 0462 return nick_; 0463 } 0464 0465 const Jid& MUCItem::jid() const 0466 { 0467 return jid_; 0468 } 0469 0470 MUCItem::Affiliation MUCItem::affiliation() const 0471 { 0472 return affiliation_; 0473 } 0474 0475 MUCItem::Role MUCItem::role() const 0476 { 0477 return role_; 0478 } 0479 0480 const Jid& MUCItem::actor() const 0481 { 0482 return actor_; 0483 } 0484 0485 const QString& MUCItem::reason() const 0486 { 0487 return reason_; 0488 } 0489 0490 void MUCItem::fromXml(const QDomElement& e) 0491 { 0492 if (e.tagName() != "item") 0493 return; 0494 0495 jid_ = Jid(e.attribute("jid")); 0496 nick_ = e.attribute("nick"); 0497 0498 // Affiliation 0499 if (e.attribute("affiliation") == "owner") { 0500 affiliation_ = Owner; 0501 } 0502 else if (e.attribute("affiliation") == "admin") { 0503 affiliation_ = Admin; 0504 } 0505 else if (e.attribute("affiliation") == "member") { 0506 affiliation_ = Member; 0507 } 0508 else if (e.attribute("affiliation") == "outcast") { 0509 affiliation_ = Outcast; 0510 } 0511 else if (e.attribute("affiliation") == "none") { 0512 affiliation_ = NoAffiliation; 0513 } 0514 0515 // Role 0516 if (e.attribute("role") == "moderator") { 0517 role_ = Moderator; 0518 } 0519 else if (e.attribute("role") == "participant") { 0520 role_ = Participant; 0521 } 0522 else if (e.attribute("role") == "visitor") { 0523 role_ = Visitor; 0524 } 0525 else if (e.attribute("role") == "none") { 0526 role_ = NoRole; 0527 } 0528 0529 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { 0530 QDomElement i = n.toElement(); 0531 if(i.isNull()) 0532 continue; 0533 0534 if (i.tagName() == "actor") 0535 actor_ = Jid(i.attribute("jid")); 0536 else if (i.tagName() == "reason") 0537 reason_ = i.text(); 0538 } 0539 } 0540 0541 QDomElement MUCItem::toXml(QDomDocument& d) 0542 { 0543 QDomElement e = d.createElement("item"); 0544 0545 if (!nick_.isEmpty()) 0546 e.setAttribute("nick",nick_); 0547 0548 if (!jid_.isEmpty()) 0549 e.setAttribute("jid",jid_.full()); 0550 0551 if (!reason_.isEmpty()) 0552 e.appendChild(textTag(&d,"reason",reason_)); 0553 0554 switch (affiliation_) { 0555 case NoAffiliation: 0556 e.setAttribute("affiliation","none"); 0557 break; 0558 case Owner: 0559 e.setAttribute("affiliation","owner"); 0560 break; 0561 case Admin: 0562 e.setAttribute("affiliation","admin"); 0563 break; 0564 case Member: 0565 e.setAttribute("affiliation","member"); 0566 break; 0567 case Outcast: 0568 e.setAttribute("affiliation","outcast"); 0569 break; 0570 default: 0571 break; 0572 } 0573 switch (role_) { 0574 case NoRole: 0575 e.setAttribute("role","none"); 0576 break; 0577 case Moderator: 0578 e.setAttribute("role","moderator"); 0579 break; 0580 case Participant: 0581 e.setAttribute("role","participant"); 0582 break; 0583 case Visitor: 0584 e.setAttribute("role","visitor"); 0585 break; 0586 default: 0587 break; 0588 } 0589 0590 return e; 0591 } 0592 0593 bool MUCItem::operator==(const MUCItem& o) 0594 { 0595 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_); 0596 } 0597 0598 //---------------------------------------------------------------------------- 0599 // MUCInvite 0600 //---------------------------------------------------------------------------- 0601 0602 MUCInvite::MUCInvite() : cont_(false) 0603 { 0604 } 0605 0606 MUCInvite::MUCInvite(const Jid& to, const QString& reason) : to_(to), reason_(reason), cont_(false) 0607 { 0608 } 0609 0610 MUCInvite::MUCInvite(const QDomElement& e) : cont_(false) 0611 { 0612 fromXml(e); 0613 } 0614 0615 const Jid& MUCInvite::from() const 0616 { 0617 return from_; 0618 } 0619 0620 void MUCInvite::setFrom(const Jid& j) 0621 { 0622 from_ = j; 0623 } 0624 0625 const Jid& MUCInvite::to() const 0626 { 0627 return to_; 0628 } 0629 0630 void MUCInvite::setTo(const Jid& j) 0631 { 0632 to_ = j; 0633 } 0634 0635 const QString& MUCInvite::reason() const 0636 { 0637 return reason_; 0638 } 0639 0640 void MUCInvite::setReason(const QString& r) 0641 { 0642 reason_ = r; 0643 } 0644 0645 bool MUCInvite::cont() const 0646 { 0647 return cont_; 0648 } 0649 0650 void MUCInvite::setCont(bool b) 0651 { 0652 cont_ = b; 0653 } 0654 0655 void MUCInvite::fromXml(const QDomElement& e) 0656 { 0657 if (e.tagName() != "invite") 0658 return; 0659 0660 from_ = e.attribute("from"); 0661 to_ = e.attribute("to"); 0662 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { 0663 QDomElement i = n.toElement(); 0664 if(i.isNull()) 0665 continue; 0666 0667 if (i.tagName() == "continue") 0668 cont_ = true; 0669 else if (i.tagName() == "reason") 0670 reason_ = i.text(); 0671 } 0672 } 0673 0674 QDomElement MUCInvite::toXml(QDomDocument& d) const 0675 { 0676 QDomElement invite = d.createElement("invite"); 0677 if (!to_.isEmpty()) { 0678 invite.setAttribute("to",to_.full()); 0679 } 0680 if (!from_.isEmpty()) { 0681 invite.setAttribute("from",from_.full()); 0682 } 0683 if (!reason_.isEmpty()) { 0684 invite.appendChild(textTag(&d, "reason", reason_)); 0685 } 0686 if (cont_) { 0687 invite.appendChild(d.createElement("continue")); 0688 } 0689 return invite; 0690 } 0691 0692 bool MUCInvite::isNull() const 0693 { 0694 return to_.isEmpty() && from_.isEmpty(); 0695 } 0696 0697 //---------------------------------------------------------------------------- 0698 // MUCDecline 0699 //---------------------------------------------------------------------------- 0700 0701 MUCDecline::MUCDecline() 0702 { 0703 } 0704 0705 MUCDecline::MUCDecline(const QDomElement& e) 0706 { 0707 fromXml(e); 0708 } 0709 0710 const Jid& MUCDecline::from() const 0711 { 0712 return from_; 0713 } 0714 0715 void MUCDecline::setFrom(const Jid& j) 0716 { 0717 from_ = j; 0718 } 0719 0720 const Jid& MUCDecline::to() const 0721 { 0722 return to_; 0723 } 0724 0725 void MUCDecline::setTo(const Jid& j) 0726 { 0727 to_ = j; 0728 } 0729 0730 const QString& MUCDecline::reason() const 0731 { 0732 return reason_; 0733 } 0734 0735 void MUCDecline::setReason(const QString& r) 0736 { 0737 reason_ = r; 0738 } 0739 0740 void MUCDecline::fromXml(const QDomElement& e) 0741 { 0742 if (e.tagName() != "decline") 0743 return; 0744 0745 from_ = e.attribute("from"); 0746 to_ = e.attribute("to"); 0747 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { 0748 QDomElement i = n.toElement(); 0749 if(i.isNull()) 0750 continue; 0751 0752 if (i.tagName() == "reason") 0753 reason_ = i.text(); 0754 } 0755 } 0756 0757 QDomElement MUCDecline::toXml(QDomDocument& d) const 0758 { 0759 QDomElement decline = d.createElement("decline"); 0760 if (!to_.isEmpty()) { 0761 decline.setAttribute("to",to_.full()); 0762 } 0763 if (!from_.isEmpty()) { 0764 decline.setAttribute("from",from_.full()); 0765 } 0766 if (!reason_.isEmpty()) { 0767 decline.appendChild(textTag(&d, "reason", reason_)); 0768 } 0769 return decline; 0770 } 0771 0772 bool MUCDecline::isNull() const 0773 { 0774 return to_.isEmpty() && from_.isEmpty(); 0775 } 0776 0777 //---------------------------------------------------------------------------- 0778 // MUCDestroy 0779 //---------------------------------------------------------------------------- 0780 0781 MUCDestroy::MUCDestroy() 0782 { 0783 } 0784 0785 MUCDestroy::MUCDestroy(const QDomElement& e) 0786 { 0787 fromXml(e); 0788 } 0789 0790 const Jid& MUCDestroy::jid() const 0791 { 0792 return jid_; 0793 } 0794 0795 void MUCDestroy::setJid(const Jid& j) 0796 { 0797 jid_ = j; 0798 } 0799 0800 const QString& MUCDestroy::reason() const 0801 { 0802 return reason_; 0803 } 0804 0805 void MUCDestroy::setReason(const QString& r) 0806 { 0807 reason_ = r; 0808 } 0809 0810 void MUCDestroy::fromXml(const QDomElement& e) 0811 { 0812 if (e.tagName() != "destroy") 0813 return; 0814 0815 jid_ = e.attribute("jid"); 0816 for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { 0817 QDomElement i = n.toElement(); 0818 if(i.isNull()) 0819 continue; 0820 0821 if (i.tagName() == "reason") 0822 reason_ = i.text(); 0823 } 0824 } 0825 0826 QDomElement MUCDestroy::toXml(QDomDocument& d) const 0827 { 0828 QDomElement destroy = d.createElement("destroy"); 0829 if (!jid_.isEmpty()) { 0830 destroy.setAttribute("jid",jid_.full()); 0831 } 0832 if (!reason_.isEmpty()) { 0833 destroy.appendChild(textTag(&d, "reason", reason_)); 0834 } 0835 return destroy; 0836 } 0837 0838 //---------------------------------------------------------------------------- 0839 // HTMLElement 0840 //---------------------------------------------------------------------------- 0841 HTMLElement::HTMLElement() 0842 { 0843 } 0844 0845 HTMLElement::HTMLElement(const QDomElement &body) { setBody(body); } 0846 0847 void HTMLElement::setBody(const QDomElement &body) 0848 { 0849 body_ = doc_.importNode(body, true).toElement(); 0850 } 0851 0852 const QDomElement& HTMLElement::body() const 0853 { 0854 return body_; 0855 } 0856 0857 /** 0858 * Returns the string reperesentation of the HTML element. 0859 * By default, this is of the form <body ...>...</body>, but the 0860 * root tag can be modified using a parameter. 0861 * 0862 * \param rootTagName the tagname of the root element to use. 0863 */ 0864 QString HTMLElement::toString(const QString &rootTagName) const 0865 { 0866 // create a copy of the body_ node, 0867 // get rid of the xmlns attribute and 0868 // change the root node name 0869 QDomElement e = body_.cloneNode().toElement(); 0870 e.setTagName(rootTagName); 0871 0872 // instead of using: 0873 // QDomDocument msg; 0874 // msg.appendChild(e); 0875 // return msg.toString(); 0876 // call Stream::xmlToString, to remove unwanted namespace attributes 0877 return(Stream::xmlToString(e)); 0878 } 0879 0880 QString HTMLElement::text() const 0881 { 0882 return body_.text(); 0883 } 0884 0885 0886 //---------------------------------------------------------------------------- 0887 // Message 0888 //---------------------------------------------------------------------------- 0889 class Message::Private 0890 { 0891 public: 0892 Jid to, from; 0893 QString id, type, lang; 0894 0895 StringMap subject, body, xHTMLBody; 0896 0897 QString thread; 0898 bool threadSend; 0899 Stanza::Error error; 0900 0901 // extensions 0902 QDateTime timeStamp; 0903 bool timeStampSend; 0904 UrlList urlList; 0905 AddressList addressList; 0906 RosterExchangeItems rosterExchangeItems; 0907 QList<MsgEvent> eventList; 0908 QString pubsubNode; 0909 QList<PubSubItem> pubsubItems; 0910 QList<PubSubRetraction> pubsubRetractions; 0911 QString eventId; 0912 QString xencrypted, invite; 0913 ChatState chatState; 0914 MessageReceipt messageReceipt; 0915 QString nick; 0916 HttpAuthRequest httpAuthRequest; 0917 XData xdata; 0918 QMap<QString,HTMLElement> htmlElements; 0919 QDomElement sxe; 0920 0921 QList<int> mucStatuses; 0922 QList<MUCInvite> mucInvites; 0923 MUCDecline mucDecline; 0924 QString mucPassword; 0925 0926 bool spooled, wasEncrypted; 0927 }; 0928 0929 //! \brief Constructs Message with given Jid information. 0930 //! 0931 //! This function will construct a Message container. 0932 //! \param to - specify reciver (default: empty string) 0933 Message::Message(const Jid &to) 0934 { 0935 d = new Private; 0936 d->to = to; 0937 d->spooled = false; 0938 d->threadSend = false; 0939 d->timeStampSend = false; 0940 d->wasEncrypted = false; 0941 /*d->flag = false; 0942 d->spooled = false; 0943 d->wasEncrypted = false; 0944 d->errorCode = -1;*/ 0945 d->chatState = StateNone; 0946 d->messageReceipt = ReceiptNone; 0947 } 0948 0949 //! \brief Constructs a copy of Message object 0950 //! 0951 //! Overloaded constructor which will constructs a exact copy of the Message 0952 //! object that was passed to the constructor. 0953 //! \param from - Message object you want to copy 0954 Message::Message(const Message &from) 0955 { 0956 d = new Private; 0957 *this = from; 0958 } 0959 0960 //! \brief Required for internel use. 0961 Message & Message::operator=(const Message &from) 0962 { 0963 *d = *from.d; 0964 return *this; 0965 } 0966 0967 //! \brief Destroy Message object. 0968 Message::~Message() 0969 { 0970 delete d; 0971 } 0972 0973 //! \brief Return receiver's Jid information. 0974 Jid Message::to() const 0975 { 0976 return d->to; 0977 } 0978 0979 //! \brief Return sender's Jid information. 0980 Jid Message::from() const 0981 { 0982 return d->from; 0983 } 0984 0985 QString Message::id() const 0986 { 0987 return d->id; 0988 } 0989 0990 //! \brief Return type information 0991 QString Message::type() const 0992 { 0993 return d->type; 0994 } 0995 0996 QString Message::lang() const 0997 { 0998 return d->lang; 0999 } 1000 1001 //! \brief Return subject information. 1002 QString Message::subject(const QString &lang) const 1003 { 1004 return d->subject[lang]; 1005 } 1006 1007 //! \brief Return body information. 1008 //! 1009 //! This function will return a plain text or the Richtext version if it 1010 //! it exists. 1011 //! \param rich - Returns richtext if true and plain text if false. (default: false) 1012 //! \note Richtext is in Qt's richtext format and not in xhtml. 1013 QString Message::body(const QString &lang) const 1014 { 1015 if (d->body.empty()) 1016 return ""; 1017 else if (d->body.contains(lang)) 1018 return d->body[lang]; 1019 else 1020 return d->body.begin().value(); 1021 } 1022 1023 //! \brief Return xhtml body. 1024 //! 1025 //! This function will return the richtext version of the body, if 1026 //! available. 1027 //! \param lang - body language 1028 //! \note The return string is in xhtml 1029 HTMLElement Message::html(const QString &lang) const 1030 { 1031 /* if(containsHTML()) { 1032 if (d->htmlElements.contains(lang)) 1033 return d->htmlElements[lang]; 1034 else 1035 return d->htmlElements.begin().value(); 1036 } 1037 else*/ 1038 return HTMLElement(); 1039 } 1040 QString Message::thread() const 1041 { 1042 return d->thread; 1043 } 1044 1045 Stanza::Error Message::error() const 1046 { 1047 return d->error; 1048 } 1049 1050 //! \brief Set receivers information 1051 //! 1052 //! \param to - Receivers Jabber id 1053 void Message::setTo(const Jid &j) 1054 { 1055 d->to = j; 1056 //d->flag = false; 1057 } 1058 1059 void Message::setFrom(const Jid &j) 1060 { 1061 d->from = j; 1062 //d->flag = false; 1063 } 1064 1065 void Message::setId(const QString &s) 1066 { 1067 d->id = s; 1068 } 1069 1070 //! \brief Set Type of message 1071 //! 1072 //! \param type - type of message your going to send 1073 void Message::setType(const QString &s) 1074 { 1075 d->type = s; 1076 //d->flag = false; 1077 } 1078 1079 void Message::setLang(const QString &s) 1080 { 1081 d->lang = s; 1082 } 1083 1084 //! \brief Set subject 1085 //! 1086 //! \param subject - Subject information 1087 void Message::setSubject(const QString &s, const QString &lang) 1088 { 1089 d->subject[lang] = s; 1090 //d->flag = false; 1091 } 1092 1093 //! \brief Set body 1094 //! 1095 //! \param body - body information 1096 //! \param rich - set richtext if true and set plaintext if false. 1097 //! \note Richtext support will be implemented in the future... Sorry. 1098 void Message::setBody(const QString &s, const QString &lang) 1099 { 1100 d->body[lang] = s; 1101 //d->flag = false; 1102 } 1103 1104 void Message::setThread(const QString &s, bool send) 1105 { 1106 d->threadSend = send; 1107 d->thread = s; 1108 } 1109 1110 void Message::setError(const Stanza::Error &err) 1111 { 1112 d->error = err; 1113 } 1114 1115 const QString& Message::pubsubNode() const 1116 { 1117 return d->pubsubNode; 1118 } 1119 1120 const QList<PubSubItem>& Message::pubsubItems() const 1121 { 1122 return d->pubsubItems; 1123 } 1124 1125 const QList<PubSubRetraction>& Message::pubsubRetractions() const 1126 { 1127 return d->pubsubRetractions; 1128 } 1129 1130 QDateTime Message::timeStamp() const 1131 { 1132 return d->timeStamp; 1133 } 1134 1135 void Message::setTimeStamp(const QDateTime &ts, bool send) 1136 { 1137 d->timeStampSend = send; 1138 d->timeStamp = ts; 1139 } 1140 1141 //! \brief Return list of urls attached to message. 1142 UrlList Message::urlList() const 1143 { 1144 return d->urlList; 1145 } 1146 1147 //! \brief Add Url to the url list. 1148 //! 1149 //! \param url - url to append 1150 void Message::urlAdd(const Url &u) 1151 { 1152 d->urlList += u; 1153 } 1154 1155 //! \brief clear out the url list. 1156 void Message::urlsClear() 1157 { 1158 d->urlList.clear(); 1159 } 1160 1161 //! \brief Set urls to send 1162 //! 1163 //! \param urlList - list of urls to send 1164 void Message::setUrlList(const UrlList &list) 1165 { 1166 d->urlList = list; 1167 } 1168 1169 //! \brief Return list of addresses attached to message. 1170 AddressList Message::addresses() const 1171 { 1172 return d->addressList; 1173 } 1174 1175 //! \brief Add Address to the address list. 1176 //! 1177 //! \param address - address to append 1178 void Message::addAddress(const Address &a) 1179 { 1180 d->addressList += a; 1181 } 1182 1183 //! \brief clear out the address list. 1184 void Message::clearAddresses() 1185 { 1186 d->addressList.clear(); 1187 } 1188 1189 AddressList Message::findAddresses(Address::Type t) const 1190 { 1191 AddressList matches; 1192 foreach(Address a, d->addressList) { 1193 if (a.type() == t) 1194 matches.append(a); 1195 } 1196 return matches; 1197 } 1198 1199 //! \brief Set addresses to send 1200 //! 1201 //! \param list - list of addresses to send 1202 void Message::setAddresses(const AddressList &list) 1203 { 1204 d->addressList = list; 1205 } 1206 1207 const RosterExchangeItems& Message::rosterExchangeItems() const 1208 { 1209 return d->rosterExchangeItems; 1210 } 1211 1212 void Message::setRosterExchangeItems(const RosterExchangeItems& items) 1213 { 1214 d->rosterExchangeItems = items; 1215 } 1216 1217 QString Message::eventId() const 1218 { 1219 return d->eventId; 1220 } 1221 1222 void Message::setEventId(const QString& id) 1223 { 1224 d->eventId = id; 1225 } 1226 1227 bool Message::containsEvents() const 1228 { 1229 return !d->eventList.isEmpty(); 1230 } 1231 1232 bool Message::containsEvent(MsgEvent e) const 1233 { 1234 return d->eventList.contains(e); 1235 } 1236 1237 void Message::addEvent(MsgEvent e) 1238 { 1239 if (!d->eventList.contains(e)) { 1240 if (e == CancelEvent || containsEvent(CancelEvent)) 1241 d->eventList.clear(); // Reset list 1242 d->eventList += e; 1243 } 1244 } 1245 1246 ChatState Message::chatState() const 1247 { 1248 return d->chatState; 1249 } 1250 1251 void Message::setChatState(ChatState state) 1252 { 1253 d->chatState = state; 1254 } 1255 1256 MessageReceipt Message::messageReceipt() const 1257 { 1258 return d->messageReceipt; 1259 } 1260 1261 void Message::setMessageReceipt(MessageReceipt messageReceipt) 1262 { 1263 d->messageReceipt = messageReceipt; 1264 } 1265 1266 QString Message::xencrypted() const 1267 { 1268 return d->xencrypted; 1269 } 1270 1271 void Message::setXEncrypted(const QString &s) 1272 { 1273 d->xencrypted = s; 1274 } 1275 1276 const QList<int>& Message::getMUCStatuses() const 1277 { 1278 return d->mucStatuses; 1279 } 1280 1281 void Message::addMUCStatus(int i) 1282 { 1283 d->mucStatuses += i; 1284 } 1285 1286 void Message::addMUCInvite(const MUCInvite& i) 1287 { 1288 d->mucInvites += i; 1289 } 1290 1291 const QList<MUCInvite>& Message::mucInvites() const 1292 { 1293 return d->mucInvites; 1294 } 1295 1296 void Message::setMUCDecline(const MUCDecline& de) 1297 { 1298 d->mucDecline = de; 1299 } 1300 1301 const MUCDecline& Message::mucDecline() const 1302 { 1303 return d->mucDecline; 1304 } 1305 1306 const QString& Message::mucPassword() const 1307 { 1308 return d->mucPassword; 1309 } 1310 1311 void Message::setMUCPassword(const QString& p) 1312 { 1313 d->mucPassword = p; 1314 } 1315 1316 QString Message::invite() const 1317 { 1318 return d->invite; 1319 } 1320 1321 void Message::setInvite(const QString &s) 1322 { 1323 d->invite = s; 1324 } 1325 1326 const QString& Message::nick() const 1327 { 1328 return d->nick; 1329 } 1330 1331 void Message::setNick(const QString& n) 1332 { 1333 d->nick = n; 1334 } 1335 1336 void Message::setHttpAuthRequest(const HttpAuthRequest &req) 1337 { 1338 d->httpAuthRequest = req; 1339 } 1340 1341 HttpAuthRequest Message::httpAuthRequest() const 1342 { 1343 return d->httpAuthRequest; 1344 } 1345 1346 void Message::setForm(const XData &form) 1347 { 1348 d->xdata = form; 1349 } 1350 1351 const XData& Message::getForm() const 1352 { 1353 return d->xdata; 1354 } 1355 1356 const QDomElement& Message::sxe() const 1357 { 1358 return d->sxe; 1359 } 1360 1361 void Message::setSxe(const QDomElement& e) 1362 { 1363 d->sxe = e; 1364 } 1365 1366 bool Message::spooled() const 1367 { 1368 return d->spooled; 1369 } 1370 1371 void Message::setSpooled(bool b) 1372 { 1373 d->spooled = b; 1374 } 1375 1376 bool Message::wasEncrypted() const 1377 { 1378 return d->wasEncrypted; 1379 } 1380 1381 void Message::setWasEncrypted(bool b) 1382 { 1383 d->wasEncrypted = b; 1384 } 1385 1386 Stanza Message::toStanza(Stream *stream) const 1387 { 1388 Stanza s = stream->createStanza(Stanza::Message, d->to, d->type); 1389 if(!d->from.isEmpty()) 1390 s.setFrom(d->from); 1391 if(!d->id.isEmpty()) 1392 s.setId(d->id); 1393 if(!d->lang.isEmpty()) 1394 s.setLang(d->lang); 1395 1396 StringMap::ConstIterator it; 1397 for(it = d->subject.constBegin(); it != d->subject.constEnd(); ++it) { 1398 const QString &str = (*it); 1399 if(!str.isEmpty()) { 1400 QDomElement e = s.createTextElement(s.baseNS(), "subject", str); 1401 if(!it.key().isEmpty()) 1402 e.setAttributeNS(NS_XML, "xml:lang", it.key()); 1403 s.appendChild(e); 1404 } 1405 } 1406 for(it = d->body.constBegin(); it != d->body.constEnd(); ++it) { 1407 const QString &str = (*it); 1408 if(!str.isEmpty()) { 1409 QDomElement e = s.createTextElement(s.baseNS(), "body", str); 1410 if(!it.key().isEmpty()) 1411 e.setAttributeNS(NS_XML, "xml:lang", it.key()); 1412 s.appendChild(e); 1413 } 1414 } 1415 if(d->type == "error") 1416 s.setError(d->error); 1417 1418 // thread 1419 if(d->threadSend && !d->thread.isEmpty()) { 1420 QDomElement e = s.createTextElement(s.baseNS(), "thread", d->thread); 1421 s.appendChild(e); 1422 } 1423 1424 // timestamp 1425 if(d->timeStampSend && !d->timeStamp.isNull()) { 1426 QDomElement e = s.createElement("jabber:x:delay", "x"); 1427 e.setAttribute("stamp", TS2stamp(d->timeStamp.toUTC())); 1428 s.appendChild(e); 1429 } 1430 1431 // urls 1432 for(QList<Url>::ConstIterator uit = d->urlList.constBegin(); uit != d->urlList.constEnd(); ++uit) { 1433 QDomElement x = s.createElement("jabber:x:oob", "x"); 1434 x.appendChild(s.createTextElement("jabber:x:oob", "url", (*uit).url())); 1435 if(!(*uit).desc().isEmpty()) 1436 x.appendChild(s.createTextElement("jabber:x:oob", "desc", (*uit).desc())); 1437 s.appendChild(x); 1438 } 1439 1440 // events 1441 if (!d->eventList.isEmpty()) { 1442 QDomElement x = s.createElement("jabber:x:event", "x"); 1443 1444 if (d->body.isEmpty()) { 1445 if (d->eventId.isEmpty()) 1446 x.appendChild(s.createElement("jabber:x:event","id")); 1447 else 1448 x.appendChild(s.createTextElement("jabber:x:event","id",d->eventId)); 1449 } 1450 1451 for(QList<MsgEvent>::ConstIterator ev = d->eventList.constBegin(); ev != d->eventList.constEnd(); ++ev) { 1452 switch (*ev) { 1453 case OfflineEvent: 1454 x.appendChild(s.createElement("jabber:x:event", "offline")); 1455 break; 1456 case DeliveredEvent: 1457 x.appendChild(s.createElement("jabber:x:event", "delivered")); 1458 break; 1459 case DisplayedEvent: 1460 x.appendChild(s.createElement("jabber:x:event", "displayed")); 1461 break; 1462 case ComposingEvent: 1463 x.appendChild(s.createElement("jabber:x:event", "composing")); 1464 break; 1465 case CancelEvent: 1466 // Add nothing 1467 break; 1468 } 1469 } 1470 s.appendChild(x); 1471 } 1472 1473 // chat state 1474 QString chatStateNS = "http://jabber.org/protocol/chatstates"; 1475 if (d->chatState != StateNone) { 1476 switch(d->chatState) { 1477 case StateActive: 1478 s.appendChild(s.createElement(chatStateNS, "active")); 1479 break; 1480 case StateComposing: 1481 s.appendChild(s.createElement(chatStateNS, "composing")); 1482 break; 1483 case StatePaused: 1484 s.appendChild(s.createElement(chatStateNS, "paused")); 1485 break; 1486 case StateInactive: 1487 s.appendChild(s.createElement(chatStateNS, "inactive")); 1488 break; 1489 case StateGone: 1490 s.appendChild(s.createElement(chatStateNS, "gone")); 1491 break; 1492 default: 1493 break; 1494 } 1495 } 1496 1497 // message receipt 1498 QString messageReceiptNS = "urn:xmpp:receipts"; 1499 if (d->messageReceipt != ReceiptNone) { 1500 switch(d->messageReceipt) { 1501 case ReceiptRequest: 1502 s.appendChild(s.createElement(messageReceiptNS, "request")); 1503 break; 1504 case ReceiptReceived: 1505 s.appendChild(s.createElement(messageReceiptNS, "received")); 1506 break; 1507 default: 1508 break; 1509 } 1510 } 1511 1512 // xencrypted 1513 if(!d->xencrypted.isEmpty()) 1514 s.appendChild(s.createTextElement("jabber:x:encrypted", "x", d->xencrypted)); 1515 1516 // addresses 1517 if (!d->addressList.isEmpty()) { 1518 QDomElement as = s.createElement("http://jabber.org/protocol/address","addresses"); 1519 foreach(Address a, d->addressList) { 1520 as.appendChild(a.toXml(s)); 1521 } 1522 s.appendChild(as); 1523 } 1524 1525 // roster item exchange 1526 if (!d->rosterExchangeItems.isEmpty()) { 1527 QDomElement rx = s.createElement("http://jabber.org/protocol/rosterx","x"); 1528 foreach(RosterExchangeItem r, d->rosterExchangeItems) { 1529 rx.appendChild(r.toXml(s)); 1530 } 1531 s.appendChild(rx); 1532 } 1533 1534 // invite 1535 if(!d->invite.isEmpty()) { 1536 QDomElement e = s.createElement("jabber:x:conference", "x"); 1537 e.setAttribute("jid", d->invite); 1538 s.appendChild(e); 1539 } 1540 1541 // nick 1542 if(!d->nick.isEmpty()) { 1543 s.appendChild(s.createTextElement("http://jabber.org/protocol/nick", "nick", d->nick)); 1544 } 1545 1546 // sxe 1547 if(!d->sxe.isNull()) { 1548 s.appendChild(d->sxe); 1549 } 1550 1551 // muc 1552 if(!d->mucInvites.isEmpty()) { 1553 QDomElement e = s.createElement("http://jabber.org/protocol/muc#user","x"); 1554 foreach(MUCInvite i, d->mucInvites) { 1555 e.appendChild(i.toXml(s.doc())); 1556 } 1557 if (!d->mucPassword.isEmpty()) { 1558 e.appendChild(s.createTextElement("http://jabber.org/protocol/muc#user","password",d->mucPassword)); 1559 } 1560 s.appendChild(e); 1561 } 1562 else if(!d->mucDecline.isNull()) { 1563 QDomElement e = s.createElement("http://jabber.org/protocol/muc#user","x"); 1564 e.appendChild(d->mucDecline.toXml(s.doc())); 1565 s.appendChild(e); 1566 } 1567 1568 // http auth 1569 if(!d->httpAuthRequest.isEmpty()) { 1570 s.appendChild(d->httpAuthRequest.toXml(s.doc())); 1571 } 1572 1573 // data form 1574 if(!d->xdata.fields().empty() || (d->xdata.type() == XData::Data_Cancel)) { 1575 bool submit = (d->xdata.type() == XData::Data_Submit) || (d->xdata.type() == XData::Data_Cancel); 1576 s.appendChild(d->xdata.toXml(&s.doc(), submit)); 1577 } 1578 1579 return s; 1580 } 1581 1582 bool Message::fromStanza(const Stanza &s, int timeZoneOffset) 1583 { 1584 if(s.kind() != Stanza::Message) 1585 return false; 1586 1587 setTo(s.to()); 1588 setFrom(s.from()); 1589 setId(s.id()); 1590 setType(s.type()); 1591 setLang(s.lang()); 1592 1593 d->subject.clear(); 1594 d->body.clear(); 1595 d->htmlElements.clear(); 1596 d->thread = QString(); 1597 1598 QDomElement root = s.element(); 1599 1600 XDomNodeList nl = root.childNodes(); 1601 int n; 1602 for(n = 0; n < nl.count(); ++n) { 1603 QDomNode i = nl.item(n); 1604 if(i.isElement()) { 1605 QDomElement e = i.toElement(); 1606 if(e.namespaceURI() == s.baseNS()) { 1607 if(e.tagName() == "subject") { 1608 QString lang = e.attributeNS(NS_XML, "lang", ""); 1609 d->subject[lang] = e.text(); 1610 } 1611 else if(e.tagName() == "body") { 1612 QString lang = e.attributeNS(NS_XML, "lang", ""); 1613 d->body[lang] = e.text(); 1614 } 1615 else if(e.tagName() == "thread") 1616 d->thread = e.text(); 1617 } 1618 else if(e.tagName() == "event" && e.namespaceURI() == "http://jabber.org/protocol/pubsub#event") { 1619 for(QDomNode enode = e.firstChild(); !enode.isNull(); enode = enode.nextSibling()) { 1620 QDomElement eel = enode.toElement(); 1621 if (eel.tagName() == "items") { 1622 d->pubsubNode = eel.attribute("node"); 1623 for(QDomNode inode = eel.firstChild(); !inode.isNull(); inode = inode.nextSibling()) { 1624 QDomElement o = inode.toElement(); 1625 if (o.tagName() == "item") { 1626 for(QDomNode j = o.firstChild(); !j.isNull(); j = j.nextSibling()) { 1627 QDomElement item = j.toElement(); 1628 if (!item.isNull()) { 1629 d->pubsubItems += PubSubItem(o.attribute("id"),item); 1630 } 1631 } 1632 } 1633 if (o.tagName() == "retract") { 1634 d->pubsubRetractions += PubSubRetraction(o.attribute("id")); 1635 } 1636 } 1637 } 1638 } 1639 } 1640 else { 1641 //printf("extension element: [%s]\n", e.tagName().latin1()); 1642 } 1643 } 1644 } 1645 1646 if(s.type() == "error") 1647 d->error = s.error(); 1648 1649 // xhtml-im 1650 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/xhtml-im", "html"); 1651 if (!nl.isEmpty()) { 1652 nl = nl.item(0).childNodes(); 1653 for(n = 0; n < nl.count(); ++n) { 1654 QDomElement e = nl.item(n).toElement(); 1655 if (e.tagName() == "body" && e.namespaceURI() == "http://www.w3.org/1999/xhtml") { 1656 QString lang = e.attributeNS(NS_XML, "lang", ""); 1657 d->htmlElements[lang] = e; 1658 } 1659 } 1660 } 1661 1662 // timestamp 1663 QDomElement t = childElementsByTagNameNS(root, "jabber:x:delay", "x").item(0).toElement(); 1664 if(!t.isNull()) { 1665 d->timeStamp = stamp2TS(t.attribute("stamp")); 1666 d->timeStamp = d->timeStamp.addSecs(timeZoneOffset * 3600); 1667 d->spooled = true; 1668 } 1669 else { 1670 d->timeStamp = QDateTime::currentDateTime(); 1671 d->spooled = false; 1672 } 1673 1674 // urls 1675 d->urlList.clear(); 1676 nl = childElementsByTagNameNS(root, "jabber:x:oob", "x"); 1677 for(n = 0; n < nl.count(); ++n) { 1678 QDomElement t = nl.item(n).toElement(); 1679 Url u; 1680 u.setUrl(t.elementsByTagName("url").item(0).toElement().text()); 1681 u.setDesc(t.elementsByTagName("desc").item(0).toElement().text()); 1682 d->urlList += u; 1683 } 1684 1685 // events 1686 d->eventList.clear(); 1687 nl = childElementsByTagNameNS(root, "jabber:x:event", "x"); 1688 if (!nl.isEmpty()) { 1689 nl = nl.item(0).childNodes(); 1690 for(n = 0; n < nl.count(); ++n) { 1691 QString evtag = nl.item(n).toElement().tagName(); 1692 if (evtag == "id") { 1693 d->eventId = nl.item(n).toElement().text(); 1694 } 1695 else if (evtag == "displayed") 1696 d->eventList += DisplayedEvent; 1697 else if (evtag == "composing") 1698 d->eventList += ComposingEvent; 1699 else if (evtag == "delivered") 1700 d->eventList += DeliveredEvent; 1701 } 1702 if (d->eventList.isEmpty()) 1703 d->eventList += CancelEvent; 1704 } 1705 1706 // Chat states 1707 QString chatStateNS = "http://jabber.org/protocol/chatstates"; 1708 t = childElementsByTagNameNS(root, chatStateNS, "active").item(0).toElement(); 1709 if(!t.isNull()) 1710 d->chatState = StateActive; 1711 t = childElementsByTagNameNS(root, chatStateNS, "composing").item(0).toElement(); 1712 if(!t.isNull()) 1713 d->chatState = StateComposing; 1714 t = childElementsByTagNameNS(root, chatStateNS, "paused").item(0).toElement(); 1715 if(!t.isNull()) 1716 d->chatState = StatePaused; 1717 t = childElementsByTagNameNS(root, chatStateNS, "inactive").item(0).toElement(); 1718 if(!t.isNull()) 1719 d->chatState = StateInactive; 1720 t = childElementsByTagNameNS(root, chatStateNS, "gone").item(0).toElement(); 1721 if(!t.isNull()) 1722 d->chatState = StateGone; 1723 1724 // message receipts 1725 QString messageReceiptNS = "urn:xmpp:receipts"; 1726 t = childElementsByTagNameNS(root, messageReceiptNS, "request").item(0).toElement(); 1727 if(!t.isNull()) 1728 d->messageReceipt = ReceiptRequest; 1729 t = childElementsByTagNameNS(root, messageReceiptNS, "received").item(0).toElement(); 1730 if(!t.isNull()) 1731 d->messageReceipt = ReceiptReceived; 1732 1733 // xencrypted 1734 t = childElementsByTagNameNS(root, "jabber:x:encrypted", "x").item(0).toElement(); 1735 if(!t.isNull()) 1736 d->xencrypted = t.text(); 1737 else 1738 d->xencrypted = QString(); 1739 1740 // addresses 1741 d->addressList.clear(); 1742 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/address", "addresses"); 1743 if (!nl.isEmpty()) { 1744 QDomElement t = nl.item(0).toElement(); 1745 nl = t.elementsByTagName("address"); 1746 for(n = 0; n < nl.count(); ++n) { 1747 d->addressList += Address(nl.item(n).toElement()); 1748 } 1749 } 1750 1751 // roster item exchange 1752 d->rosterExchangeItems.clear(); 1753 nl = childElementsByTagNameNS(root, "http://jabber.org/protocol/rosterx", "x"); 1754 if (!nl.isEmpty()) { 1755 QDomElement t = nl.item(0).toElement(); 1756 nl = t.elementsByTagName("item"); 1757 for(n = 0; n < nl.count(); ++n) { 1758 RosterExchangeItem it = RosterExchangeItem(nl.item(n).toElement()); 1759 if (!it.isNull()) 1760 d->rosterExchangeItems += it; 1761 } 1762 } 1763 1764 // invite 1765 t = childElementsByTagNameNS(root, "jabber:x:conference", "x").item(0).toElement(); 1766 if(!t.isNull()) 1767 d->invite = t.attribute("jid"); 1768 else 1769 d->invite = QString(); 1770 1771 // nick 1772 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/nick", "nick").item(0).toElement(); 1773 if(!t.isNull()) 1774 d->nick = t.text(); 1775 else 1776 d->nick = QString(); 1777 1778 // sxe 1779 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/sxe", "sxe").item(0).toElement(); 1780 if(!t.isNull()) 1781 d->sxe = t; 1782 else 1783 d->sxe = QDomElement(); 1784 1785 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/muc#user", "x").item(0).toElement(); 1786 if(!t.isNull()) { 1787 for(QDomNode muc_n = t.firstChild(); !muc_n.isNull(); muc_n = muc_n.nextSibling()) { 1788 QDomElement muc_e = muc_n.toElement(); 1789 if(muc_e.isNull()) 1790 continue; 1791 if (muc_e.tagName() == "status") { 1792 addMUCStatus(muc_e.attribute("code").toInt()); 1793 } 1794 else if (muc_e.tagName() == "invite") { 1795 MUCInvite inv(muc_e); 1796 if (!inv.isNull()) 1797 addMUCInvite(inv); 1798 } 1799 else if (muc_e.tagName() == "decline") { 1800 setMUCDecline(MUCDecline(muc_e)); 1801 } 1802 else if (muc_e.tagName() == "password") { 1803 setMUCPassword(muc_e.text()); 1804 } 1805 } 1806 } 1807 1808 // http auth 1809 t = childElementsByTagNameNS(root, "http://jabber.org/protocol/http-auth", "confirm").item(0).toElement(); 1810 if(!t.isNull()){ 1811 d->httpAuthRequest = HttpAuthRequest(t); 1812 } 1813 else { 1814 d->httpAuthRequest = HttpAuthRequest(); 1815 } 1816 1817 // data form 1818 t = childElementsByTagNameNS(root, "jabber:x:data", "x").item(0).toElement(); 1819 if(!t.isNull()){ 1820 d->xdata.fromXml(t); 1821 } 1822 1823 return true; 1824 } 1825 1826 /*! 1827 Error object used to deny a request. 1828 */ 1829 Stanza::Error HttpAuthRequest::denyError(Stanza::Error::Auth, Stanza::Error::NotAuthorized); 1830 1831 /*! 1832 Constructs request of resource URL \a u, made by method \a m, with transaction id \a i. 1833 */ 1834 HttpAuthRequest::HttpAuthRequest(const QString &m, const QString &u, const QString &i) : method_(m), url_(u), id_(i), hasId_(true) 1835 { 1836 } 1837 1838 /*! 1839 Constructs request of resource URL \a u, made by method \a m, without transaction id. 1840 */ 1841 HttpAuthRequest::HttpAuthRequest(const QString &m, const QString &u) : method_(m), url_(u), hasId_(false) 1842 { 1843 } 1844 1845 /*! 1846 Constructs request object by reading XML <confirm/> element \a e. 1847 */ 1848 HttpAuthRequest::HttpAuthRequest(const QDomElement &e) 1849 { 1850 fromXml(e); 1851 } 1852 1853 /*! 1854 Returns true is object is empty (not valid). 1855 */ 1856 bool HttpAuthRequest::isEmpty() const 1857 { 1858 return method_.isEmpty() && url_.isEmpty(); 1859 } 1860 1861 /*! 1862 Sets request method. 1863 */ 1864 void HttpAuthRequest::setMethod(const QString& m) 1865 { 1866 method_ = m; 1867 } 1868 1869 /*! 1870 Sets requested URL. 1871 */ 1872 void HttpAuthRequest::setUrl(const QString& u) 1873 { 1874 url_ = u; 1875 } 1876 1877 /*! 1878 Sets transaction identifier. 1879 */ 1880 void HttpAuthRequest::setId(const QString& i) 1881 { 1882 id_ = i; 1883 hasId_ = true; 1884 } 1885 1886 /*! 1887 Returns request method. 1888 */ 1889 QString HttpAuthRequest::method() const 1890 { 1891 return method_; 1892 } 1893 1894 /*! 1895 Returns requested URL. 1896 */ 1897 QString HttpAuthRequest::url() const 1898 { 1899 return url_; 1900 } 1901 1902 /*! 1903 Returns transaction identifier. 1904 Empty QString may mean both empty id or no id. Use hasId() to tell the difference. 1905 */ 1906 QString HttpAuthRequest::id() const 1907 { 1908 return id_; 1909 } 1910 1911 /*! 1912 Returns true if the request contains transaction id. 1913 */ 1914 bool HttpAuthRequest::hasId() const 1915 { 1916 return hasId_; 1917 } 1918 1919 /*! 1920 Returns XML element representing the request. 1921 If object is empty, this function returns empty element. 1922 */ 1923 QDomElement HttpAuthRequest::toXml(QDomDocument &doc) const 1924 { 1925 QDomElement e; 1926 if(isEmpty()) 1927 return e; 1928 1929 e = doc.createElementNS("http://jabber.org/protocol/http-auth", "confirm"); 1930 e.setAttribute("xmlns", "http://jabber.org/protocol/http-auth"); 1931 1932 if(hasId_) 1933 e.setAttribute("id", id_); 1934 e.setAttribute("method", method_); 1935 e.setAttribute("url", url_); 1936 1937 return e; 1938 } 1939 1940 /*! 1941 Reads request data from XML element \a e. 1942 */ 1943 bool HttpAuthRequest::fromXml(const QDomElement &e) 1944 { 1945 if(e.tagName() != "confirm") 1946 return false; 1947 1948 hasId_ = e.hasAttribute("id"); 1949 if(hasId_) 1950 id_ = e.attribute("id"); 1951 1952 method_ = e.attribute("method"); 1953 url_ = e.attribute("url"); 1954 1955 return true; 1956 } 1957 1958 //--------------------------------------------------------------------------- 1959 // Subscription 1960 //--------------------------------------------------------------------------- 1961 Subscription::Subscription(SubType type) 1962 { 1963 value = type; 1964 } 1965 1966 int Subscription::type() const 1967 { 1968 return value; 1969 } 1970 1971 QString Subscription::toString() const 1972 { 1973 switch(value) { 1974 case Remove: 1975 return "remove"; 1976 case Both: 1977 return "both"; 1978 case From: 1979 return "from"; 1980 case To: 1981 return "to"; 1982 case None: 1983 default: 1984 return "none"; 1985 } 1986 } 1987 1988 bool Subscription::fromString(const QString &s) 1989 { 1990 if(s == "remove") 1991 value = Remove; 1992 else if(s == "both") 1993 value = Both; 1994 else if(s == "from") 1995 value = From; 1996 else if(s == "to") 1997 value = To; 1998 else if(s == "none") 1999 value = None; 2000 else 2001 return false; 2002 2003 return true; 2004 } 2005 2006 2007 //--------------------------------------------------------------------------- 2008 // Status 2009 //--------------------------------------------------------------------------- 2010 2011 Status::Status(const QString &show, const QString &status, int priority, bool available) 2012 { 2013 v_isAvailable = available; 2014 v_show = show; 2015 v_status = status; 2016 v_priority = priority; 2017 v_timeStamp = QDateTime::currentDateTime(); 2018 v_isInvisible = false; 2019 v_hasPhotoHash = false; 2020 v_isMUC = false; 2021 v_hasMUCItem = false; 2022 v_hasMUCDestroy = false; 2023 v_mucHistoryMaxChars = -1; 2024 v_mucHistoryMaxStanzas = -1; 2025 v_mucHistorySeconds = -1; 2026 ecode = -1; 2027 } 2028 2029 Status::Status(Type type, const QString& status, int priority) 2030 { 2031 v_status = status; 2032 v_priority = priority; 2033 v_timeStamp = QDateTime::currentDateTime(); 2034 v_hasPhotoHash = false; 2035 v_isMUC = false; 2036 v_hasMUCItem = false; 2037 v_hasMUCDestroy = false; 2038 v_mucHistoryMaxChars = -1; 2039 v_mucHistoryMaxStanzas = -1; 2040 v_mucHistorySeconds = -1; 2041 ecode = -1; 2042 setType(type); 2043 } 2044 2045 Status::~Status() 2046 { 2047 } 2048 2049 bool Status::hasError() const 2050 { 2051 return (ecode != -1); 2052 } 2053 2054 void Status::setError(int code, const QString &str) 2055 { 2056 ecode = code; 2057 estr = str; 2058 } 2059 2060 void Status::setIsAvailable(bool available) 2061 { 2062 v_isAvailable = available; 2063 } 2064 2065 void Status::setIsInvisible(bool invisible) 2066 { 2067 v_isInvisible = invisible; 2068 } 2069 2070 void Status::setPriority(int x) 2071 { 2072 v_priority = x; 2073 } 2074 2075 void Status::setType(Status::Type _type) 2076 { 2077 bool available = true; 2078 bool invisible = false; 2079 QString show; 2080 switch(_type) { 2081 case Away: show = "away"; break; 2082 case FFC: show = "chat"; break; 2083 case XA: show = "xa"; break; 2084 case DND: show = "dnd"; break; 2085 case Offline: available = false; break; 2086 case Invisible: invisible = true; break; 2087 default: break; 2088 } 2089 setShow(show); 2090 setIsAvailable(available); 2091 setIsInvisible(invisible); 2092 } 2093 2094 void Status::setType(QString stat) 2095 { 2096 if (stat == "offline") 2097 setType(XMPP::Status::Offline); 2098 else if (stat == "online") 2099 setType(XMPP::Status::Online); 2100 else if (stat == "away") 2101 setType(XMPP::Status::Away); 2102 else if (stat == "xa") 2103 setType(XMPP::Status::XA); 2104 else if (stat == "dnd") 2105 setType(XMPP::Status::DND); 2106 else if (stat == "invisible") 2107 setType(XMPP::Status::Invisible); 2108 else if (stat == "chat") 2109 setType(XMPP::Status::FFC); 2110 else 2111 setType(XMPP::Status::Away); 2112 } 2113 2114 void Status::setShow(const QString & _show) 2115 { 2116 v_show = _show; 2117 } 2118 2119 void Status::setStatus(const QString & _status) 2120 { 2121 v_status = _status; 2122 } 2123 2124 void Status::setTimeStamp(const QDateTime & _timestamp) 2125 { 2126 v_timeStamp = _timestamp; 2127 } 2128 2129 void Status::setKeyID(const QString &key) 2130 { 2131 v_key = key; 2132 } 2133 2134 void Status::setXSigned(const QString &s) 2135 { 2136 v_xsigned = s; 2137 } 2138 2139 void Status::setSongTitle(const QString & _songtitle) 2140 { 2141 v_songTitle = _songtitle; 2142 } 2143 2144 void Status::setCapsNode(const QString & _capsNode) 2145 { 2146 v_capsNode = _capsNode; 2147 } 2148 2149 void Status::setCapsVersion(const QString & _capsVersion) 2150 { 2151 v_capsVersion = _capsVersion; 2152 } 2153 2154 void Status::setCapsExt(const QString & _capsExt) 2155 { 2156 v_capsExt = _capsExt; 2157 } 2158 2159 void Status::setMUC() 2160 { 2161 v_isMUC = true; 2162 } 2163 2164 void Status::setMUCItem(const MUCItem& i) 2165 { 2166 v_hasMUCItem = true; 2167 v_mucItem = i; 2168 } 2169 2170 void Status::setMUCDestroy(const MUCDestroy& i) 2171 { 2172 v_hasMUCDestroy = true; 2173 v_mucDestroy = i; 2174 } 2175 2176 void Status::setMUCHistory(int maxchars, int maxstanzas, int seconds) 2177 { 2178 v_mucHistoryMaxChars = maxchars; 2179 v_mucHistoryMaxStanzas = maxstanzas; 2180 v_mucHistorySeconds = seconds; 2181 } 2182 2183 2184 const QString& Status::photoHash() const 2185 { 2186 return v_photoHash; 2187 } 2188 2189 void Status::setPhotoHash(const QString& h) 2190 { 2191 v_photoHash = h; 2192 v_hasPhotoHash = true; 2193 } 2194 2195 bool Status::hasPhotoHash() const 2196 { 2197 return v_hasPhotoHash; 2198 } 2199 2200 bool Status::isAvailable() const 2201 { 2202 return v_isAvailable; 2203 } 2204 2205 bool Status::isAway() const 2206 { 2207 return (v_show == "away" || v_show == "xa" || v_show == "dnd"); 2208 } 2209 2210 bool Status::isInvisible() const 2211 { 2212 return v_isInvisible; 2213 } 2214 2215 int Status::priority() const 2216 { 2217 return v_priority; 2218 } 2219 2220 Status::Type Status::type() const 2221 { 2222 Status::Type type = Status::Online; 2223 if (!isAvailable()) { 2224 type = Status::Offline; 2225 } 2226 else if (isInvisible()) { 2227 type = Status::Invisible; 2228 } 2229 else { 2230 QString s = show(); 2231 if (s == "away") 2232 type = Status::Away; 2233 else if (s == "xa") 2234 type = Status::XA; 2235 else if (s == "dnd") 2236 type = Status::DND; 2237 else if (s == "chat") 2238 type = Status::FFC; 2239 } 2240 return type; 2241 } 2242 2243 QString Status::typeString() const 2244 { 2245 QString stat; 2246 switch(type()) { 2247 case XMPP::Status::Offline: stat = "offline"; break; 2248 case XMPP::Status::Online: stat = "online"; break; 2249 case XMPP::Status::Away: stat = "away"; break; 2250 case XMPP::Status::XA: stat = "xa"; break; 2251 case XMPP::Status::DND: stat = "dnd"; break; 2252 case XMPP::Status::Invisible: stat = "invisible"; break; 2253 case XMPP::Status::FFC: stat = "chat"; break; 2254 default: stat = "away"; 2255 } 2256 return stat; 2257 } 2258 2259 const QString & Status::show() const 2260 { 2261 return v_show; 2262 } 2263 const QString & Status::status() const 2264 { 2265 return v_status; 2266 } 2267 2268 QDateTime Status::timeStamp() const 2269 { 2270 return v_timeStamp; 2271 } 2272 2273 const QString & Status::keyID() const 2274 { 2275 return v_key; 2276 } 2277 2278 const QString & Status::xsigned() const 2279 { 2280 return v_xsigned; 2281 } 2282 2283 const QString & Status::songTitle() const 2284 { 2285 return v_songTitle; 2286 } 2287 2288 const QString & Status::capsNode() const 2289 { 2290 return v_capsNode; 2291 } 2292 2293 const QString & Status::capsVersion() const 2294 { 2295 return v_capsVersion; 2296 } 2297 2298 const QString & Status::capsExt() const 2299 { 2300 return v_capsExt; 2301 } 2302 2303 bool Status::isMUC() const 2304 { 2305 return v_isMUC || !v_mucPassword.isEmpty() || hasMUCHistory(); 2306 } 2307 2308 bool Status::hasMUCItem() const 2309 { 2310 return v_hasMUCItem; 2311 } 2312 2313 const MUCItem& Status::mucItem() const 2314 { 2315 return v_mucItem; 2316 } 2317 2318 bool Status::hasMUCDestroy() const 2319 { 2320 return v_hasMUCDestroy; 2321 } 2322 2323 const MUCDestroy& Status::mucDestroy() const 2324 { 2325 return v_mucDestroy; 2326 } 2327 2328 const QList<int>& Status::getMUCStatuses() const 2329 { 2330 return v_mucStatuses; 2331 } 2332 2333 void Status::addMUCStatus(int i) 2334 { 2335 v_mucStatuses += i; 2336 } 2337 2338 const QString& Status::mucPassword() const 2339 { 2340 return v_mucPassword; 2341 } 2342 2343 bool Status::hasMUCHistory() const 2344 { 2345 return v_mucHistoryMaxChars >= 0 || v_mucHistoryMaxStanzas >= 0 || v_mucHistorySeconds >= 0; 2346 } 2347 2348 int Status::mucHistoryMaxChars() const 2349 { 2350 return v_mucHistoryMaxChars; 2351 } 2352 2353 int Status::mucHistoryMaxStanzas() const 2354 { 2355 return v_mucHistoryMaxStanzas; 2356 } 2357 2358 int Status::mucHistorySeconds() const 2359 { 2360 return v_mucHistorySeconds; 2361 } 2362 2363 void Status::setMUCPassword(const QString& i) 2364 { 2365 v_mucPassword = i; 2366 } 2367 2368 int Status::errorCode() const 2369 { 2370 return ecode; 2371 } 2372 2373 const QString & Status::errorString() const 2374 { 2375 return estr; 2376 } 2377 2378 2379 //--------------------------------------------------------------------------- 2380 // Resource 2381 //--------------------------------------------------------------------------- 2382 Resource::Resource(const QString &name, const Status &stat) 2383 { 2384 v_name = name; 2385 v_status = stat; 2386 } 2387 2388 Resource::~Resource() 2389 { 2390 } 2391 2392 const QString & Resource::name() const 2393 { 2394 return v_name; 2395 } 2396 2397 int Resource::priority() const 2398 { 2399 return v_status.priority(); 2400 } 2401 2402 const Status & Resource::status() const 2403 { 2404 return v_status; 2405 } 2406 2407 void Resource::setName(const QString & _name) 2408 { 2409 v_name = _name; 2410 } 2411 2412 void Resource::setStatus(const Status & _status) 2413 { 2414 v_status = _status; 2415 } 2416 2417 2418 //--------------------------------------------------------------------------- 2419 // ResourceList 2420 //--------------------------------------------------------------------------- 2421 ResourceList::ResourceList() 2422 :QList<Resource>() 2423 { 2424 } 2425 2426 ResourceList::~ResourceList() 2427 { 2428 } 2429 2430 ResourceList::Iterator ResourceList::find(const QString & _find) 2431 { 2432 for(ResourceList::Iterator it = begin(); it != end(); ++it) { 2433 if((*it).name() == _find) 2434 return it; 2435 } 2436 2437 return end(); 2438 } 2439 2440 ResourceList::Iterator ResourceList::priority() 2441 { 2442 ResourceList::Iterator highest = end(); 2443 2444 for(ResourceList::Iterator it = begin(); it != end(); ++it) { 2445 if(highest == end() || (*it).priority() > (*highest).priority()) 2446 highest = it; 2447 } 2448 2449 return highest; 2450 } 2451 2452 ResourceList::ConstIterator ResourceList::find(const QString & _find) const 2453 { 2454 for(ResourceList::ConstIterator it = constBegin(); it != constEnd(); ++it) { 2455 if((*it).name() == _find) 2456 return it; 2457 } 2458 2459 return end(); 2460 } 2461 2462 ResourceList::ConstIterator ResourceList::priority() const 2463 { 2464 ResourceList::ConstIterator highest = end(); 2465 2466 for(ResourceList::ConstIterator it = constBegin(); it != constEnd(); ++it) { 2467 if(highest == end() || (*it).priority() > (*highest).priority()) 2468 highest = it; 2469 } 2470 2471 return highest; 2472 } 2473 2474 2475 //--------------------------------------------------------------------------- 2476 // RosterItem 2477 //--------------------------------------------------------------------------- 2478 RosterItem::RosterItem(const Jid &_jid) 2479 { 2480 v_jid = _jid; 2481 v_push = false; 2482 } 2483 2484 RosterItem::~RosterItem() 2485 { 2486 } 2487 2488 const Jid & RosterItem::jid() const 2489 { 2490 return v_jid; 2491 } 2492 2493 const QString & RosterItem::name() const 2494 { 2495 return v_name; 2496 } 2497 2498 const QStringList & RosterItem::groups() const 2499 { 2500 return v_groups; 2501 } 2502 2503 const Subscription & RosterItem::subscription() const 2504 { 2505 return v_subscription; 2506 } 2507 2508 const QString & RosterItem::ask() const 2509 { 2510 return v_ask; 2511 } 2512 2513 bool RosterItem::isPush() const 2514 { 2515 return v_push; 2516 } 2517 2518 bool RosterItem::inGroup(const QString &g) const 2519 { 2520 for(QStringList::ConstIterator it = v_groups.constBegin(); it != v_groups.constEnd(); ++it) { 2521 if(*it == g) 2522 return true; 2523 } 2524 return false; 2525 } 2526 2527 void RosterItem::setJid(const Jid &_jid) 2528 { 2529 v_jid = _jid; 2530 } 2531 2532 void RosterItem::setName(const QString &_name) 2533 { 2534 v_name = _name; 2535 } 2536 2537 void RosterItem::setGroups(const QStringList &_groups) 2538 { 2539 v_groups = _groups; 2540 } 2541 2542 void RosterItem::setSubscription(const Subscription &type) 2543 { 2544 v_subscription = type; 2545 } 2546 2547 void RosterItem::setAsk(const QString &_ask) 2548 { 2549 v_ask = _ask; 2550 } 2551 2552 void RosterItem::setIsPush(bool b) 2553 { 2554 v_push = b; 2555 } 2556 2557 bool RosterItem::addGroup(const QString &g) 2558 { 2559 if(inGroup(g)) 2560 return false; 2561 2562 v_groups += g; 2563 return true; 2564 } 2565 2566 bool RosterItem::removeGroup(const QString &g) 2567 { 2568 for(QStringList::Iterator it = v_groups.begin(); it != v_groups.end(); ++it) { 2569 if(*it == g) { 2570 v_groups.erase(it); 2571 return true; 2572 } 2573 } 2574 2575 return false; 2576 } 2577 2578 QDomElement RosterItem::toXml(QDomDocument *doc) const 2579 { 2580 QDomElement item = doc->createElement("item"); 2581 item.setAttribute("jid", v_jid.full()); 2582 item.setAttribute("name", v_name); 2583 item.setAttribute("subscription", v_subscription.toString()); 2584 if(!v_ask.isEmpty()) 2585 item.setAttribute("ask", v_ask); 2586 for(QStringList::ConstIterator it = v_groups.constBegin(); it != v_groups.constEnd(); ++it) 2587 item.appendChild(textTag(doc, "group", *it)); 2588 2589 return item; 2590 } 2591 2592 bool RosterItem::fromXml(const QDomElement &item) 2593 { 2594 if(item.tagName() != "item") 2595 return false; 2596 Jid j(item.attribute("jid")); 2597 if(!j.isValid()) 2598 return false; 2599 QString na = item.attribute("name"); 2600 Subscription s; 2601 if(!s.fromString(item.attribute("subscription")) ) 2602 return false; 2603 QStringList g; 2604 for(QDomNode n = item.firstChild(); !n.isNull(); n = n.nextSibling()) { 2605 QDomElement i = n.toElement(); 2606 if(i.isNull()) 2607 continue; 2608 if(i.tagName() == "group") 2609 g += tagContent(i); 2610 } 2611 QString a = item.attribute("ask"); 2612 2613 v_jid = j; 2614 v_name = na; 2615 v_subscription = s; 2616 v_groups = g; 2617 v_ask = a; 2618 2619 return true; 2620 } 2621 2622 2623 //--------------------------------------------------------------------------- 2624 // Roster 2625 //--------------------------------------------------------------------------- 2626 Roster::Roster() 2627 :QList<RosterItem>() 2628 { 2629 } 2630 2631 Roster::~Roster() 2632 { 2633 } 2634 2635 Roster::Iterator Roster::find(const Jid &j) 2636 { 2637 for(Roster::Iterator it = begin(); it != end(); ++it) { 2638 if((*it).jid().compare(j)) 2639 return it; 2640 } 2641 2642 return end(); 2643 } 2644 2645 Roster::ConstIterator Roster::find(const Jid &j) const 2646 { 2647 for(Roster::ConstIterator it = begin(); it != end(); ++it) { 2648 if((*it).jid().compare(j)) 2649 return it; 2650 } 2651 2652 return end(); 2653 } 2654 2655 2656 //--------------------------------------------------------------------------- 2657 // FormField 2658 //--------------------------------------------------------------------------- 2659 FormField::FormField(const QString &type, const QString &value) 2660 { 2661 v_type = misc; 2662 if(!type.isEmpty()) { 2663 int x = tagNameToType(type); 2664 if(x != -1) 2665 v_type = x; 2666 } 2667 v_value = value; 2668 } 2669 2670 FormField::~FormField() 2671 { 2672 } 2673 2674 int FormField::type() const 2675 { 2676 return v_type; 2677 } 2678 2679 QString FormField::realName() const 2680 { 2681 return typeToTagName(v_type); 2682 } 2683 2684 QString FormField::fieldName() const 2685 { 2686 switch(v_type) { 2687 case username: return QObject::tr("Username"); 2688 case nick: return QObject::tr("Nickname"); 2689 case password: return QObject::tr("Password"); 2690 case name: return QObject::tr("Name"); 2691 case first: return QObject::tr("First Name"); 2692 case last: return QObject::tr("Last Name"); 2693 case email: return QObject::tr("E-mail"); 2694 case address: return QObject::tr("Address"); 2695 case city: return QObject::tr("City"); 2696 case state: return QObject::tr("State"); 2697 case zip: return QObject::tr("Zipcode"); 2698 case phone: return QObject::tr("Phone"); 2699 case url: return QObject::tr("URL"); 2700 case date: return QObject::tr("Date"); 2701 case misc: return QObject::tr("Misc"); 2702 default: return ""; 2703 }; 2704 } 2705 2706 bool FormField::isSecret() const 2707 { 2708 return (type() == password); 2709 } 2710 2711 const QString & FormField::value() const 2712 { 2713 return v_value; 2714 } 2715 2716 void FormField::setType(int x) 2717 { 2718 v_type = x; 2719 } 2720 2721 bool FormField::setType(const QString &in) 2722 { 2723 int x = tagNameToType(in); 2724 if(x == -1) 2725 return false; 2726 2727 v_type = x; 2728 return true; 2729 } 2730 2731 void FormField::setValue(const QString &in) 2732 { 2733 v_value = in; 2734 } 2735 2736 int FormField::tagNameToType(const QString &in) const 2737 { 2738 if(!in.compare("username")) return username; 2739 if(!in.compare("nick")) return nick; 2740 if(!in.compare("password")) return password; 2741 if(!in.compare("name")) return name; 2742 if(!in.compare("first")) return first; 2743 if(!in.compare("last")) return last; 2744 if(!in.compare("email")) return email; 2745 if(!in.compare("address")) return address; 2746 if(!in.compare("city")) return city; 2747 if(!in.compare("state")) return state; 2748 if(!in.compare("zip")) return zip; 2749 if(!in.compare("phone")) return phone; 2750 if(!in.compare("url")) return url; 2751 if(!in.compare("date")) return date; 2752 if(!in.compare("misc")) return misc; 2753 2754 return -1; 2755 } 2756 2757 QString FormField::typeToTagName(int type) const 2758 { 2759 switch(type) { 2760 case username: return "username"; 2761 case nick: return "nick"; 2762 case password: return "password"; 2763 case name: return "name"; 2764 case first: return "first"; 2765 case last: return "last"; 2766 case email: return "email"; 2767 case address: return "address"; 2768 case city: return "city"; 2769 case state: return "state"; 2770 case zip: return "zipcode"; 2771 case phone: return "phone"; 2772 case url: return "url"; 2773 case date: return "date"; 2774 case misc: return "misc"; 2775 default: return ""; 2776 }; 2777 } 2778 2779 2780 //--------------------------------------------------------------------------- 2781 // Form 2782 //--------------------------------------------------------------------------- 2783 Form::Form(const Jid &j) 2784 :QList<FormField>() 2785 { 2786 setJid(j); 2787 } 2788 2789 Form::~Form() 2790 { 2791 } 2792 2793 Jid Form::jid() const 2794 { 2795 return v_jid; 2796 } 2797 2798 QString Form::instructions() const 2799 { 2800 return v_instructions; 2801 } 2802 2803 QString Form::key() const 2804 { 2805 return v_key; 2806 } 2807 2808 void Form::setJid(const Jid &j) 2809 { 2810 v_jid = j; 2811 } 2812 2813 void Form::setInstructions(const QString &s) 2814 { 2815 v_instructions = s; 2816 } 2817 2818 void Form::setKey(const QString &s) 2819 { 2820 v_key = s; 2821 } 2822 2823 2824 //--------------------------------------------------------------------------- 2825 // SearchResult 2826 //--------------------------------------------------------------------------- 2827 SearchResult::SearchResult(const Jid &jid) 2828 { 2829 setJid(jid); 2830 } 2831 2832 SearchResult::~SearchResult() 2833 { 2834 } 2835 2836 const Jid & SearchResult::jid() const 2837 { 2838 return v_jid; 2839 } 2840 2841 const QString & SearchResult::nick() const 2842 { 2843 return v_nick; 2844 } 2845 2846 const QString & SearchResult::first() const 2847 { 2848 return v_first; 2849 } 2850 2851 const QString & SearchResult::last() const 2852 { 2853 return v_last; 2854 } 2855 2856 const QString & SearchResult::email() const 2857 { 2858 return v_email; 2859 } 2860 2861 void SearchResult::setJid(const Jid &jid) 2862 { 2863 v_jid = jid; 2864 } 2865 2866 void SearchResult::setNick(const QString &nick) 2867 { 2868 v_nick = nick; 2869 } 2870 2871 void SearchResult::setFirst(const QString &first) 2872 { 2873 v_first = first; 2874 } 2875 2876 void SearchResult::setLast(const QString &last) 2877 { 2878 v_last = last; 2879 } 2880 2881 void SearchResult::setEmail(const QString &email) 2882 { 2883 v_email = email; 2884 } 2885 2886 PubSubItem::PubSubItem() 2887 { 2888 } 2889 2890 PubSubItem::PubSubItem(const QString& id, const QDomElement& payload) : id_(id), payload_(payload) 2891 { 2892 } 2893 2894 const QString& PubSubItem::id() const 2895 { 2896 return id_; 2897 } 2898 2899 const QDomElement& PubSubItem::payload() const 2900 { 2901 return payload_; 2902 } 2903 2904 2905 PubSubRetraction::PubSubRetraction() 2906 { 2907 } 2908 2909 PubSubRetraction::PubSubRetraction(const QString& id) : id_(id) 2910 { 2911 } 2912 2913 const QString& PubSubRetraction::id() const 2914 { 2915 return id_; 2916 } 2917 2918 2919 }