|
|
/*
|
|
|
* types.cpp - IM data types
|
|
|
* Copyright (C) 2003 Justin Karneges
|
|
|
*
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
*
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
* Lesser General Public License for more details.
|
|
|
*
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
#include"im.h"
|
|
|
#include "protocol.h"
|
|
|
#include<tqmap.h>
|
|
|
#include<tqapplication.h>
|
|
|
|
|
|
#define NS_XML "http://www.w3.org/XML/1998/namespace"
|
|
|
|
|
|
static TQDomElement textTag(TQDomDocument *doc, const TQString &name, const TQString &content)
|
|
|
{
|
|
|
TQDomElement tag = doc->createElement(name);
|
|
|
TQDomText text = doc->createTextNode(content);
|
|
|
tag.appendChild(text);
|
|
|
|
|
|
return tag;
|
|
|
}
|
|
|
|
|
|
static TQString tagContent(const TQDomElement &e)
|
|
|
{
|
|
|
// look for some tag content
|
|
|
for(TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
|
|
|
TQDomText i = n.toText();
|
|
|
if(i.isNull())
|
|
|
continue;
|
|
|
return i.data();
|
|
|
}
|
|
|
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
static TQDateTime stamp2TS(const TQString &ts)
|
|
|
{
|
|
|
if(ts.length() != 17)
|
|
|
return TQDateTime();
|
|
|
|
|
|
int year = ts.mid(0,4).toInt();
|
|
|
int month = ts.mid(4,2).toInt();
|
|
|
int day = ts.mid(6,2).toInt();
|
|
|
|
|
|
int hour = ts.mid(9,2).toInt();
|
|
|
int min = ts.mid(12,2).toInt();
|
|
|
int sec = ts.mid(15,2).toInt();
|
|
|
|
|
|
TQDate xd;
|
|
|
xd.setYMD(year, month, day);
|
|
|
if(!xd.isValid())
|
|
|
return TQDateTime();
|
|
|
|
|
|
TQTime xt;
|
|
|
xt.setHMS(hour, min, sec);
|
|
|
if(!xt.isValid())
|
|
|
return TQDateTime();
|
|
|
|
|
|
return TQDateTime(xd, xt);
|
|
|
}
|
|
|
|
|
|
/*static TQString TS2stamp(const TQDateTime &d)
|
|
|
{
|
|
|
TQString str;
|
|
|
|
|
|
str.sprintf("%04d%02d%02dT%02d:%02d:%02d",
|
|
|
d.date().year(),
|
|
|
d.date().month(),
|
|
|
d.date().day(),
|
|
|
d.time().hour(),
|
|
|
d.time().minute(),
|
|
|
d.time().second());
|
|
|
|
|
|
return str;
|
|
|
}*/
|
|
|
|
|
|
namespace XMPP
|
|
|
{
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
// Url
|
|
|
//----------------------------------------------------------------------------
|
|
|
class Url::Private
|
|
|
{
|
|
|
public:
|
|
|
TQString url;
|
|
|
TQString desc;
|
|
|
};
|
|
|
|
|
|
//! \brief Construct Url object with a given URL and Description.
|
|
|
//!
|
|
|
//! This function will construct a Url object.
|
|
|
//! \param TQString - url (default: empty string)
|
|
|
//! \param TQString - description of url (default: empty string)
|
|
|
//! \sa setUrl() setDesc()
|
|
|
Url::Url(const TQString &url, const TQString &desc)
|
|
|
{
|
|
|
d = new Private;
|
|
|
d->url = url;
|
|
|
d->desc = desc;
|
|
|
}
|
|
|
|
|
|
//! \brief Construct Url object.
|
|
|
//!
|
|
|
//! Overloaded constructor which will constructs a exact copy of the Url object that was passed to the constructor.
|
|
|
//! \param Url - Url Object
|
|
|
Url::Url(const Url &from)
|
|
|
{
|
|
|
d = new Private;
|
|
|
*this = from;
|
|
|
}
|
|
|
|
|
|
//! \brief operator overloader needed for d pointer (Internel).
|
|
|
Url & Url::operator=(const Url &from)
|
|
|
{
|
|
|
*d = *from.d;
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
//! \brief destroy Url object.
|
|
|
Url::~Url()
|
|
|
{
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
//! \brief Get url information.
|
|
|
//!
|
|
|
//! Returns url information.
|
|
|
TQString Url::url() const
|
|
|
{
|
|
|
return d->url;
|
|
|
}
|
|
|
|
|
|
//! \brief Get Description information.
|
|
|
//!
|
|
|
//! Returns desction of the URL.
|
|
|
TQString Url::desc() const
|
|
|
{
|
|
|
return d->desc;
|
|
|
}
|
|
|
|
|
|
//! \brief Set Url information.
|
|
|
//!
|
|
|
//! Set url information.
|
|
|
//! \param url - url string (eg: http://psi.affinix.com/)
|
|
|
void Url::setUrl(const TQString &url)
|
|
|
{
|
|
|
d->url = url;
|
|
|
}
|
|
|
|
|
|
//! \brief Set Description information.
|
|
|
//!
|
|
|
//! Set description of the url.
|
|
|
//! \param desc - description of url
|
|
|
void Url::setDesc(const TQString &desc)
|
|
|
{
|
|
|
d->desc = desc;
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
// Message
|
|
|
//----------------------------------------------------------------------------
|
|
|
class Message::Private
|
|
|
{
|
|
|
public:
|
|
|
Jid to, from;
|
|
|
TQString id, type, lang;
|
|
|
|
|
|
StringMap subject, body, xHTMLBody;
|
|
|
|
|
|
TQString thread;
|
|
|
Stanza::Error error;
|
|
|
|
|
|
// extensions
|
|
|
TQDateTime timeStamp;
|
|
|
UrlList urlList;
|
|
|
TQValueList<MsgEvent> eventList;
|
|
|
TQString eventId;
|
|
|
TQString xencrypted, invite;
|
|
|
|
|
|
bool spooled, wasEncrypted;
|
|
|
};
|
|
|
|
|
|
//! \brief Constructs Message with given Jid information.
|
|
|
//!
|
|
|
//! This function will construct a Message container.
|
|
|
//! \param to - specify reciver (default: empty string)
|
|
|
Message::Message(const Jid &to)
|
|
|
{
|
|
|
d = new Private;
|
|
|
d->to = to;
|
|
|
d->spooled = false;
|
|
|
d->wasEncrypted = false;
|
|
|
/*d->flag = false;
|
|
|
d->spooled = false;
|
|
|
d->wasEncrypted = false;
|
|
|
d->errorCode = -1;*/
|
|
|
}
|
|
|
|
|
|
//! \brief Constructs a copy of Message object
|
|
|
//!
|
|
|
//! Overloaded constructor which will constructs a exact copy of the Message
|
|
|
//! object that was passed to the constructor.
|
|
|
//! \param from - Message object you want to copy
|
|
|
Message::Message(const Message &from)
|
|
|
{
|
|
|
d = new Private;
|
|
|
*this = from;
|
|
|
}
|
|
|
|
|
|
//! \brief Required for internel use.
|
|
|
Message & Message::operator=(const Message &from)
|
|
|
{
|
|
|
*d = *from.d;
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
//! \brief Destroy Message object.
|
|
|
Message::~Message()
|
|
|
{
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
//! \brief Return receiver's Jid information.
|
|
|
Jid Message::to() const
|
|
|
{
|
|
|
return d->to;
|
|
|
}
|
|
|
|
|
|
//! \brief Return sender's Jid information.
|
|
|
Jid Message::from() const
|
|
|
{
|
|
|
return d->from;
|
|
|
}
|
|
|
|
|
|
TQString Message::id() const
|
|
|
{
|
|
|
return d->id;
|
|
|
}
|
|
|
|
|
|
//! \brief Return type information
|
|
|
TQString Message::type() const
|
|
|
{
|
|
|
return d->type;
|
|
|
}
|
|
|
|
|
|
TQString Message::lang() const
|
|
|
{
|
|
|
return d->lang;
|
|
|
}
|
|
|
|
|
|
//! \brief Return subject information.
|
|
|
TQString Message::subject(const TQString &lang) const
|
|
|
{
|
|
|
return d->subject[lang];
|
|
|
}
|
|
|
|
|
|
//! \brief Return body information.
|
|
|
//!
|
|
|
//! This function will return a plain text or the Richtext version if it
|
|
|
//! it exists.
|
|
|
//! \param rich - Returns richtext if true and plain text if false. (default: false)
|
|
|
//! \note Richtext is in TQt's richtext format and not in xhtml.
|
|
|
TQString Message::body(const TQString &lang) const
|
|
|
{
|
|
|
return d->body[lang];
|
|
|
}
|
|
|
|
|
|
TQString Message::xHTMLBody(const TQString &lang) const
|
|
|
{
|
|
|
return d->xHTMLBody[lang];
|
|
|
}
|
|
|
|
|
|
TQString Message::thread() const
|
|
|
{
|
|
|
return d->thread;
|
|
|
}
|
|
|
|
|
|
Stanza::Error Message::error() const
|
|
|
{
|
|
|
return d->error;
|
|
|
}
|
|
|
|
|
|
//! \brief Set receivers information
|
|
|
//!
|
|
|
//! \param to - Receivers Jabber id
|
|
|
void Message::setTo(const Jid &j)
|
|
|
{
|
|
|
d->to = j;
|
|
|
//d->flag = false;
|
|
|
}
|
|
|
|
|
|
void Message::setFrom(const Jid &j)
|
|
|
{
|
|
|
d->from = j;
|
|
|
//d->flag = false;
|
|
|
}
|
|
|
|
|
|
void Message::setId(const TQString &s)
|
|
|
{
|
|
|
d->id = s;
|
|
|
}
|
|
|
|
|
|
//! \brief Set Type of message
|
|
|
//!
|
|
|
//! \param type - type of message your going to send
|
|
|
void Message::setType(const TQString &s)
|
|
|
{
|
|
|
d->type = s;
|
|
|
//d->flag = false;
|
|
|
}
|
|
|
|
|
|
void Message::setLang(const TQString &s)
|
|
|
{
|
|
|
d->lang = s;
|
|
|
}
|
|
|
|
|
|
//! \brief Set subject
|
|
|
//!
|
|
|
//! \param subject - Subject information
|
|
|
void Message::setSubject(const TQString &s, const TQString &lang)
|
|
|
{
|
|
|
d->subject[lang] = s;
|
|
|
//d->flag = false;
|
|
|
}
|
|
|
|
|
|
//! \brief Set body
|
|
|
//!
|
|
|
//! \param body - body information
|
|
|
//! \param rich - set richtext if true and set plaintext if false.
|
|
|
//! \note Richtext support will be implemented in the future... Sorry.
|
|
|
void Message::setBody(const TQString &s, const TQString &lang)
|
|
|
{
|
|
|
d->body[lang] = s;
|
|
|
}
|
|
|
|
|
|
void Message::setXHTMLBody(const TQString &s, const TQString &lang, const TQString &attr)
|
|
|
{
|
|
|
//ugly but needed if s is not a node but a list of leaf
|
|
|
|
|
|
TQString content = "<body xmlns='" + TQString(NS_XHTML) + "' "+attr+" >\n" + s +"\n</body>";
|
|
|
d->xHTMLBody[lang] = content;
|
|
|
}
|
|
|
|
|
|
void Message::setThread(const TQString &s)
|
|
|
{
|
|
|
d->thread = s;
|
|
|
}
|
|
|
|
|
|
void Message::setError(const Stanza::Error &err)
|
|
|
{
|
|
|
d->error = err;
|
|
|
}
|
|
|
|
|
|
TQDateTime Message::timeStamp() const
|
|
|
{
|
|
|
return d->timeStamp;
|
|
|
}
|
|
|
|
|
|
void Message::setTimeStamp(const TQDateTime &ts)
|
|
|
{
|
|
|
d->timeStamp = ts;
|
|
|
}
|
|
|
|
|
|
//! \brief Return list of urls attached to message.
|
|
|
UrlList Message::urlList() const
|
|
|
{
|
|
|
return d->urlList;
|
|
|
}
|
|
|
|
|
|
//! \brief Add Url to the url list.
|
|
|
//!
|
|
|
//! \param url - url to append
|
|
|
void Message::urlAdd(const Url &u)
|
|
|
{
|
|
|
d->urlList += u;
|
|
|
}
|
|
|
|
|
|
//! \brief clear out the url list.
|
|
|
void Message::urlsClear()
|
|
|
{
|
|
|
d->urlList.clear();
|
|
|
}
|
|
|
|
|
|
//! \brief Set urls to send
|
|
|
//!
|
|
|
//! \param urlList - list of urls to send
|
|
|
void Message::setUrlList(const UrlList &list)
|
|
|
{
|
|
|
d->urlList = list;
|
|
|
}
|
|
|
|
|
|
TQString Message::eventId() const
|
|
|
{
|
|
|
return d->eventId;
|
|
|
}
|
|
|
|
|
|
void Message::setEventId(const TQString& id)
|
|
|
{
|
|
|
d->eventId = id;
|
|
|
}
|
|
|
|
|
|
bool Message::containsEvents() const
|
|
|
{
|
|
|
return !d->eventList.isEmpty();
|
|
|
}
|
|
|
|
|
|
bool Message::containsEvent(MsgEvent e) const
|
|
|
{
|
|
|
return d->eventList.contains(e);
|
|
|
}
|
|
|
|
|
|
void Message::addEvent(MsgEvent e)
|
|
|
{
|
|
|
if (!d->eventList.contains(e)) {
|
|
|
if (e == CancelEvent || containsEvent(CancelEvent))
|
|
|
d->eventList.clear(); // Reset list
|
|
|
d->eventList += e;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
TQString Message::xencrypted() const
|
|
|
{
|
|
|
return d->xencrypted;
|
|
|
}
|
|
|
|
|
|
void Message::setXEncrypted(const TQString &s)
|
|
|
{
|
|
|
d->xencrypted = s;
|
|
|
}
|
|
|
|
|
|
TQString Message::invite() const
|
|
|
{
|
|
|
return d->invite;
|
|
|
}
|
|
|
|
|
|
void Message::setInvite(const TQString &s)
|
|
|
{
|
|
|
d->invite = s;
|
|
|
}
|
|
|
|
|
|
bool Message::spooled() const
|
|
|
{
|
|
|
return d->spooled;
|
|
|
}
|
|
|
|
|
|
void Message::setSpooled(bool b)
|
|
|
{
|
|
|
d->spooled = b;
|
|
|
}
|
|
|
|
|
|
bool Message::wasEncrypted() const
|
|
|
{
|
|
|
return d->wasEncrypted;
|
|
|
}
|
|
|
|
|
|
void Message::setWasEncrypted(bool b)
|
|
|
{
|
|
|
d->wasEncrypted = b;
|
|
|
}
|
|
|
|
|
|
Stanza Message::toStanza(Stream *stream) const
|
|
|
{
|
|
|
Stanza s = stream->createStanza(Stanza::Message, d->to, d->type);
|
|
|
if(!d->from.isEmpty())
|
|
|
s.setFrom(d->from);
|
|
|
if(!d->id.isEmpty())
|
|
|
s.setId(d->id);
|
|
|
if(!d->lang.isEmpty())
|
|
|
s.setLang(d->lang);
|
|
|
|
|
|
StringMap::ConstIterator it;
|
|
|
for(it = d->subject.begin(); it != d->subject.end(); ++it) {
|
|
|
const TQString &str = it.data();
|
|
|
if(!str.isEmpty()) {
|
|
|
TQDomElement e = s.createTextElement(s.baseNS(), "subject", str);
|
|
|
if(!it.key().isEmpty())
|
|
|
e.setAttributeNS(NS_XML, "xml:lang", it.key());
|
|
|
s.appendChild(e);
|
|
|
}
|
|
|
}
|
|
|
for(it = d->body.begin(); it != d->body.end(); ++it) {
|
|
|
const TQString &str = it.data();
|
|
|
if(!str.isEmpty()) {
|
|
|
TQDomElement e = s.createTextElement(s.baseNS(), "body", str);
|
|
|
if(!it.key().isEmpty())
|
|
|
e.setAttributeNS(NS_XML, "xml:lang", it.key());
|
|
|
s.appendChild(e);
|
|
|
}
|
|
|
}
|
|
|
if ( !d->xHTMLBody.isEmpty()) {
|
|
|
TQDomElement parent = s.createElement(s.xhtmlImNS(), "html");
|
|
|
for(it = d->xHTMLBody.begin(); it != d->xHTMLBody.end(); ++it) {
|
|
|
const TQString &str = it.data();
|
|
|
if(!str.isEmpty()) {
|
|
|
TQDomElement child = s.createXHTMLElement(str);
|
|
|
if(!it.key().isEmpty())
|
|
|
child.setAttributeNS(NS_XML, "xml:lang", it.key());
|
|
|
parent.appendChild(child);
|
|
|
}
|
|
|
}
|
|
|
s.appendChild(parent);
|
|
|
}
|
|
|
if(d->type == "error")
|
|
|
s.setError(d->error);
|
|
|
|
|
|
// timestamp
|
|
|
/*if(!d->timeStamp.isNull()) {
|
|
|
TQDomElement e = s.createElement("jabber:x:delay", "x");
|
|
|
e.setAttribute("stamp", TS2stamp(d->timeStamp));
|
|
|
s.appendChild(e);
|
|
|
}*/
|
|
|
|
|
|
// urls
|
|
|
for(TQValueList<Url>::ConstIterator uit = d->urlList.begin(); uit != d->urlList.end(); ++uit) {
|
|
|
TQDomElement x = s.createElement("jabber:x:oob", "x");
|
|
|
x.appendChild(s.createTextElement("jabber:x:oob", "url", (*uit).url()));
|
|
|
if(!(*uit).desc().isEmpty())
|
|
|
x.appendChild(s.createTextElement("jabber:x:oob", "desc", (*uit).desc()));
|
|
|
s.appendChild(x);
|
|
|
}
|
|
|
|
|
|
// events
|
|
|
if (!d->eventList.isEmpty()) {
|
|
|
TQDomElement x = s.createElement("jabber:x:event", "x");
|
|
|
|
|
|
if (d->body.isEmpty()) {
|
|
|
if (d->eventId.isEmpty())
|
|
|
x.appendChild(s.createElement("jabber:x:event","id"));
|
|
|
else
|
|
|
x.appendChild(s.createTextElement("jabber:x:event","id",d->eventId));
|
|
|
}
|
|
|
else if (d->type=="chat" || d->type=="groupchat")
|
|
|
s.appendChild( s.createElement(NS_CHATSTATES , "active" ) );
|
|
|
|
|
|
bool need_x_event=false;
|
|
|
for(TQValueList<MsgEvent>::ConstIterator ev = d->eventList.begin(); ev != d->eventList.end(); ++ev) {
|
|
|
switch (*ev) {
|
|
|
case OfflineEvent:
|
|
|
x.appendChild(s.createElement("jabber:x:event", "offline"));
|
|
|
need_x_event=true;
|
|
|
break;
|
|
|
case DeliveredEvent:
|
|
|
x.appendChild(s.createElement("jabber:x:event", "delivered"));
|
|
|
need_x_event=true;
|
|
|
break;
|
|
|
case DisplayedEvent:
|
|
|
x.appendChild(s.createElement("jabber:x:event", "displayed"));
|
|
|
need_x_event=true;
|
|
|
break;
|
|
|
case ComposingEvent:
|
|
|
x.appendChild(s.createElement("jabber:x:event", "composing"));
|
|
|
need_x_event=true;
|
|
|
if (d->body.isEmpty() && (d->type=="chat" || d->type=="groupchat") )
|
|
|
s.appendChild( s.createElement(NS_CHATSTATES , "composing" ) );
|
|
|
break;
|
|
|
case CancelEvent:
|
|
|
need_x_event=true;
|
|
|
if (d->body.isEmpty() && (d->type=="chat" || d->type=="groupchat") )
|
|
|
s.appendChild( s.createElement(NS_CHATSTATES , "paused" ) );
|
|
|
break;
|
|
|
case InactiveEvent:
|
|
|
if (d->body.isEmpty() && (d->type=="chat" || d->type=="groupchat") )
|
|
|
s.appendChild( s.createElement(NS_CHATSTATES , "inactive" ) );
|
|
|
break;
|
|
|
case GoneEvent:
|
|
|
if (d->body.isEmpty() && (d->type=="chat" || d->type=="groupchat") )
|
|
|
s.appendChild( s.createElement(NS_CHATSTATES , "gone" ) );
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if(need_x_event) //we don't need to have the (empty) x:event element if this is only <gone> or <inactive>
|
|
|
s.appendChild(x);
|
|
|
}
|
|
|
|
|
|
|
|
|
// xencrypted
|
|
|
if(!d->xencrypted.isEmpty())
|
|
|
s.appendChild(s.createTextElement("jabber:x:encrypted", "x", d->xencrypted));
|
|
|
|
|
|
// invite
|
|
|
if(!d->invite.isEmpty()) {
|
|
|
TQDomElement e = s.createElement("jabber:x:conference", "x");
|
|
|
e.setAttribute("jid", d->invite);
|
|
|
s.appendChild(e);
|
|
|
}
|
|
|
|
|
|
return s;
|
|
|
}
|
|
|
|
|
|
bool Message::fromStanza(const Stanza &s, int timeZoneOffset)
|
|
|
{
|
|
|
if(s.kind() != Stanza::Message)
|
|
|
return false;
|
|
|
|
|
|
setTo(s.to());
|
|
|
setFrom(s.from());
|
|
|
setId(s.id());
|
|
|
setType(s.type());
|
|
|
setLang(s.lang());
|
|
|
|
|
|
d->subject.clear();
|
|
|
d->body.clear();
|
|
|
d->thread = TQString();
|
|
|
d->eventList.clear();
|
|
|
|
|
|
TQDomElement root = s.element();
|
|
|
|
|
|
TQDomNodeList nl = root.childNodes();
|
|
|
uint n;
|
|
|
for(n = 0; n < nl.count(); ++n) {
|
|
|
TQDomNode i = nl.item(n);
|
|
|
if(i.isElement()) {
|
|
|
TQDomElement e = i.toElement();
|
|
|
if(e.namespaceURI() == s.baseNS()) {
|
|
|
if(e.tagName() == "subject") {
|
|
|
TQString lang = e.attributeNS(NS_XML, "lang", "");
|
|
|
d->subject[lang] = e.text();
|
|
|
}
|
|
|
else if(e.tagName() == "body") {
|
|
|
TQString lang = e.attributeNS(NS_XML, "lang", "");
|
|
|
d->body[lang] = e.text();
|
|
|
}
|
|
|
else if(e.tagName() == "thread")
|
|
|
d->thread = e.text();
|
|
|
}
|
|
|
else if (e.namespaceURI() == s.xhtmlImNS()) {
|
|
|
if (e.tagName() == "html") {
|
|
|
TQDomNodeList htmlNL= e.childNodes();
|
|
|
for (unsigned int x = 0; x < htmlNL.count(); x++) {
|
|
|
TQDomElement i = htmlNL.item(x).toElement();
|
|
|
|
|
|
if (i.tagName() == "body") {
|
|
|
TQDomDocument RichText;
|
|
|
TQString lang = i.attributeNS(NS_XML, "lang", "");
|
|
|
RichText.appendChild(i);
|
|
|
d-> xHTMLBody[lang] = RichText.toString();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (e.namespaceURI() == NS_CHATSTATES)
|
|
|
{
|
|
|
if(e.tagName() == "active")
|
|
|
{
|
|
|
//like in JEP-0022 we let the client know that we can receive ComposingEvent
|
|
|
// (we can do that according to <20>4.6 of the JEP-0085)
|
|
|
d->eventList += ComposingEvent;
|
|
|
d->eventList += InactiveEvent;
|
|
|
d->eventList += GoneEvent;
|
|
|
}
|
|
|
else if (e.tagName() == "composing")
|
|
|
{
|
|
|
d->eventList += ComposingEvent;
|
|
|
}
|
|
|
else if (e.tagName() == "paused")
|
|
|
{
|
|
|
d->eventList += CancelEvent;
|
|
|
}
|
|
|
else if (e.tagName() == "inactive")
|
|
|
{
|
|
|
d->eventList += InactiveEvent;
|
|
|
}
|
|
|
else if (e.tagName() == "gone")
|
|
|
{
|
|
|
d->eventList += GoneEvent;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
//printf("extension element: [%s]\n", e.tagName().latin1());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(s.type() == "error")
|
|
|
d->error = s.error();
|
|
|
|
|
|
// timestamp
|
|
|
TQDomElement t = root.elementsByTagNameNS("jabber:x:delay", "x").item(0).toElement();
|
|
|
if(!t.isNull()) {
|
|
|
d->timeStamp = stamp2TS(t.attribute("stamp"));
|
|
|
d->timeStamp = d->timeStamp.addSecs(timeZoneOffset * 3600);
|
|
|
d->spooled = true;
|
|
|
}
|
|
|
else {
|
|
|
d->timeStamp = TQDateTime::currentDateTime();
|
|
|
d->spooled = false;
|
|
|
}
|
|
|
|
|
|
// urls
|
|
|
d->urlList.clear();
|
|
|
nl = root.elementsByTagNameNS("jabber:x:oob", "x");
|
|
|
for(n = 0; n < nl.count(); ++n) {
|
|
|
TQDomElement t = nl.item(n).toElement();
|
|
|
Url u;
|
|
|
u.setUrl(t.elementsByTagName("url").item(0).toElement().text());
|
|
|
u.setDesc(t.elementsByTagName("desc").item(0).toElement().text());
|
|
|
d->urlList += u;
|
|
|
}
|
|
|
|
|
|
// events
|
|
|
nl = root.elementsByTagNameNS("jabber:x:event", "x");
|
|
|
if (nl.count()) {
|
|
|
nl = nl.item(0).childNodes();
|
|
|
for(n = 0; n < nl.count(); ++n) {
|
|
|
TQString evtag = nl.item(n).toElement().tagName();
|
|
|
if (evtag == "id") {
|
|
|
d->eventId = nl.item(n).toElement().text();
|
|
|
}
|
|
|
else if (evtag == "displayed")
|
|
|
d->eventList += DisplayedEvent;
|
|
|
else if (evtag == "composing")
|
|
|
d->eventList += ComposingEvent;
|
|
|
else if (evtag == "delivered")
|
|
|
d->eventList += DeliveredEvent;
|
|
|
else if (evtag == "offline")
|
|
|
d->eventList += OfflineEvent;
|
|
|
}
|
|
|
if (d->eventList.isEmpty())
|
|
|
d->eventList += CancelEvent;
|
|
|
}
|
|
|
|
|
|
// xencrypted
|
|
|
t = root.elementsByTagNameNS("jabber:x:encrypted", "x").item(0).toElement();
|
|
|
if(!t.isNull())
|
|
|
d->xencrypted = t.text();
|
|
|
else
|
|
|
d->xencrypted = TQString();
|
|
|
|
|
|
// invite
|
|
|
t = root.elementsByTagNameNS("jabber:x:conference", "x").item(0).toElement();
|
|
|
if(!t.isNull())
|
|
|
d->invite = t.attribute("jid");
|
|
|
else
|
|
|
d->invite = TQString();
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Subscription
|
|
|
//---------------------------------------------------------------------------
|
|
|
Subscription::Subscription(SubType type)
|
|
|
{
|
|
|
value = type;
|
|
|
}
|
|
|
|
|
|
int Subscription::type() const
|
|
|
{
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
TQString Subscription::toString() const
|
|
|
{
|
|
|
switch(value) {
|
|
|
case Remove:
|
|
|
return "remove";
|
|
|
case Both:
|
|
|
return "both";
|
|
|
case From:
|
|
|
return "from";
|
|
|
case To:
|
|
|
return "to";
|
|
|
case None:
|
|
|
default:
|
|
|
return "none";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool Subscription::fromString(const TQString &s)
|
|
|
{
|
|
|
if(s == "remove")
|
|
|
value = Remove;
|
|
|
else if(s == "both")
|
|
|
value = Both;
|
|
|
else if(s == "from")
|
|
|
value = From;
|
|
|
else if(s == "to")
|
|
|
value = To;
|
|
|
else if(s == "none")
|
|
|
value = None;
|
|
|
else
|
|
|
return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Status
|
|
|
//---------------------------------------------------------------------------
|
|
|
Status::Status(const TQString &show, const TQString &status, int priority, bool available)
|
|
|
{
|
|
|
v_isAvailable = available;
|
|
|
v_show = show;
|
|
|
v_status = status;
|
|
|
v_priority = priority;
|
|
|
v_timeStamp = TQDateTime::currentDateTime();
|
|
|
v_isInvisible = false;
|
|
|
ecode = -1;
|
|
|
}
|
|
|
|
|
|
Status::~Status()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
bool Status::hasError() const
|
|
|
{
|
|
|
return (ecode != -1);
|
|
|
}
|
|
|
|
|
|
void Status::setError(int code, const TQString &str)
|
|
|
{
|
|
|
ecode = code;
|
|
|
estr = str;
|
|
|
}
|
|
|
|
|
|
void Status::setIsAvailable(bool available)
|
|
|
{
|
|
|
v_isAvailable = available;
|
|
|
}
|
|
|
|
|
|
void Status::setIsInvisible(bool invisible)
|
|
|
{
|
|
|
v_isInvisible = invisible;
|
|
|
}
|
|
|
|
|
|
void Status::setPriority(int x)
|
|
|
{
|
|
|
v_priority = x;
|
|
|
}
|
|
|
|
|
|
void Status::setShow(const TQString & _show)
|
|
|
{
|
|
|
v_show = _show;
|
|
|
}
|
|
|
|
|
|
void Status::setStatus(const TQString & _status)
|
|
|
{
|
|
|
v_status = _status;
|
|
|
}
|
|
|
|
|
|
void Status::setTimeStamp(const TQDateTime & _timestamp)
|
|
|
{
|
|
|
v_timeStamp = _timestamp;
|
|
|
}
|
|
|
|
|
|
void Status::setKeyID(const TQString &key)
|
|
|
{
|
|
|
v_key = key;
|
|
|
}
|
|
|
|
|
|
void Status::setXSigned(const TQString &s)
|
|
|
{
|
|
|
v_xsigned = s;
|
|
|
}
|
|
|
|
|
|
void Status::setSongTitle(const TQString & _songtitle)
|
|
|
{
|
|
|
v_songTitle = _songtitle;
|
|
|
}
|
|
|
|
|
|
void Status::setCapsNode(const TQString & _capsNode)
|
|
|
{
|
|
|
v_capsNode = _capsNode;
|
|
|
}
|
|
|
|
|
|
void Status::setCapsVersion(const TQString & _capsVersion)
|
|
|
{
|
|
|
v_capsVersion = _capsVersion;
|
|
|
}
|
|
|
|
|
|
void Status::setCapsExt(const TQString & _capsExt)
|
|
|
{
|
|
|
v_capsExt = _capsExt;
|
|
|
}
|
|
|
|
|
|
bool Status::isAvailable() const
|
|
|
{
|
|
|
return v_isAvailable;
|
|
|
}
|
|
|
|
|
|
bool Status::isAway() const
|
|
|
{
|
|
|
if(v_show == "away" || v_show == "xa" || v_show == "dnd")
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool Status::isInvisible() const
|
|
|
{
|
|
|
return v_isInvisible;
|
|
|
}
|
|
|
|
|
|
int Status::priority() const
|
|
|
{
|
|
|
return v_priority;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::show() const
|
|
|
{
|
|
|
return v_show;
|
|
|
}
|
|
|
const TQString & Status::status() const
|
|
|
{
|
|
|
return v_status;
|
|
|
}
|
|
|
|
|
|
TQDateTime Status::timeStamp() const
|
|
|
{
|
|
|
return v_timeStamp;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::keyID() const
|
|
|
{
|
|
|
return v_key;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::xsigned() const
|
|
|
{
|
|
|
return v_xsigned;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::songTitle() const
|
|
|
{
|
|
|
return v_songTitle;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::capsNode() const
|
|
|
{
|
|
|
return v_capsNode;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::capsVersion() const
|
|
|
{
|
|
|
return v_capsVersion;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::capsExt() const
|
|
|
{
|
|
|
return v_capsExt;
|
|
|
}
|
|
|
|
|
|
int Status::errorCode() const
|
|
|
{
|
|
|
return ecode;
|
|
|
}
|
|
|
|
|
|
const TQString & Status::errorString() const
|
|
|
{
|
|
|
return estr;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Resource
|
|
|
//---------------------------------------------------------------------------
|
|
|
Resource::Resource(const TQString &name, const Status &stat)
|
|
|
{
|
|
|
v_name = name;
|
|
|
v_status = stat;
|
|
|
}
|
|
|
|
|
|
Resource::~Resource()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
const TQString & Resource::name() const
|
|
|
{
|
|
|
return v_name;
|
|
|
}
|
|
|
|
|
|
int Resource::priority() const
|
|
|
{
|
|
|
return v_status.priority();
|
|
|
}
|
|
|
|
|
|
const Status & Resource::status() const
|
|
|
{
|
|
|
return v_status;
|
|
|
}
|
|
|
|
|
|
void Resource::setName(const TQString & _name)
|
|
|
{
|
|
|
v_name = _name;
|
|
|
}
|
|
|
|
|
|
void Resource::setStatus(const Status & _status)
|
|
|
{
|
|
|
v_status = _status;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// ResourceList
|
|
|
//---------------------------------------------------------------------------
|
|
|
ResourceList::ResourceList()
|
|
|
:TQValueList<Resource>()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
ResourceList::~ResourceList()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
ResourceList::Iterator ResourceList::find(const TQString & _find)
|
|
|
{
|
|
|
for(ResourceList::Iterator it = begin(); it != end(); ++it) {
|
|
|
if((*it).name() == _find)
|
|
|
return it;
|
|
|
}
|
|
|
|
|
|
return end();
|
|
|
}
|
|
|
|
|
|
ResourceList::Iterator ResourceList::priority()
|
|
|
{
|
|
|
ResourceList::Iterator highest = end();
|
|
|
|
|
|
for(ResourceList::Iterator it = begin(); it != end(); ++it) {
|
|
|
if(highest == end() || (*it).priority() > (*highest).priority())
|
|
|
highest = it;
|
|
|
}
|
|
|
|
|
|
return highest;
|
|
|
}
|
|
|
|
|
|
ResourceList::ConstIterator ResourceList::find(const TQString & _find) const
|
|
|
{
|
|
|
for(ResourceList::ConstIterator it = begin(); it != end(); ++it) {
|
|
|
if((*it).name() == _find)
|
|
|
return it;
|
|
|
}
|
|
|
|
|
|
return end();
|
|
|
}
|
|
|
|
|
|
ResourceList::ConstIterator ResourceList::priority() const
|
|
|
{
|
|
|
ResourceList::ConstIterator highest = end();
|
|
|
|
|
|
for(ResourceList::ConstIterator it = begin(); it != end(); ++it) {
|
|
|
if(highest == end() || (*it).priority() > (*highest).priority())
|
|
|
highest = it;
|
|
|
}
|
|
|
|
|
|
return highest;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// RosterItem
|
|
|
//---------------------------------------------------------------------------
|
|
|
RosterItem::RosterItem(const Jid &_jid)
|
|
|
{
|
|
|
v_jid = _jid;
|
|
|
}
|
|
|
|
|
|
RosterItem::~RosterItem()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
const Jid & RosterItem::jid() const
|
|
|
{
|
|
|
return v_jid;
|
|
|
}
|
|
|
|
|
|
const TQString & RosterItem::name() const
|
|
|
{
|
|
|
return v_name;
|
|
|
}
|
|
|
|
|
|
const TQStringList & RosterItem::groups() const
|
|
|
{
|
|
|
return v_groups;
|
|
|
}
|
|
|
|
|
|
const Subscription & RosterItem::subscription() const
|
|
|
{
|
|
|
return v_subscription;
|
|
|
}
|
|
|
|
|
|
const TQString & RosterItem::ask() const
|
|
|
{
|
|
|
return v_ask;
|
|
|
}
|
|
|
|
|
|
bool RosterItem::isPush() const
|
|
|
{
|
|
|
return v_push;
|
|
|
}
|
|
|
|
|
|
bool RosterItem::inGroup(const TQString &g) const
|
|
|
{
|
|
|
for(TQStringList::ConstIterator it = v_groups.begin(); it != v_groups.end(); ++it) {
|
|
|
if(*it == g)
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setJid(const Jid &_jid)
|
|
|
{
|
|
|
v_jid = _jid;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setName(const TQString &_name)
|
|
|
{
|
|
|
v_name = _name;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setGroups(const TQStringList &_groups)
|
|
|
{
|
|
|
v_groups = _groups;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setSubscription(const Subscription &type)
|
|
|
{
|
|
|
v_subscription = type;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setAsk(const TQString &_ask)
|
|
|
{
|
|
|
v_ask = _ask;
|
|
|
}
|
|
|
|
|
|
void RosterItem::setIsPush(bool b)
|
|
|
{
|
|
|
v_push = b;
|
|
|
}
|
|
|
|
|
|
bool RosterItem::addGroup(const TQString &g)
|
|
|
{
|
|
|
if(inGroup(g))
|
|
|
return false;
|
|
|
|
|
|
v_groups += g;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool RosterItem::removeGroup(const TQString &g)
|
|
|
{
|
|
|
for(TQStringList::Iterator it = v_groups.begin(); it != v_groups.end(); ++it) {
|
|
|
if(*it == g) {
|
|
|
v_groups.remove(it);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
TQDomElement RosterItem::toXml(TQDomDocument *doc) const
|
|
|
{
|
|
|
TQDomElement item = doc->createElement("item");
|
|
|
item.setAttribute("jid", v_jid.full());
|
|
|
item.setAttribute("name", v_name);
|
|
|
item.setAttribute("subscription", v_subscription.toString());
|
|
|
if(!v_ask.isEmpty())
|
|
|
item.setAttribute("ask", v_ask);
|
|
|
for(TQStringList::ConstIterator it = v_groups.begin(); it != v_groups.end(); ++it)
|
|
|
item.appendChild(textTag(doc, "group", *it));
|
|
|
|
|
|
return item;
|
|
|
}
|
|
|
|
|
|
bool RosterItem::fromXml(const TQDomElement &item)
|
|
|
{
|
|
|
if(item.tagName() != "item")
|
|
|
return false;
|
|
|
Jid j(item.attribute("jid"));
|
|
|
if(!j.isValid())
|
|
|
return false;
|
|
|
TQString na = item.attribute("name");
|
|
|
Subscription s;
|
|
|
if(!s.fromString(item.attribute("subscription")) )
|
|
|
return false;
|
|
|
TQStringList g;
|
|
|
for(TQDomNode n = item.firstChild(); !n.isNull(); n = n.nextSibling()) {
|
|
|
TQDomElement i = n.toElement();
|
|
|
if(i.isNull())
|
|
|
continue;
|
|
|
if(i.tagName() == "group")
|
|
|
g += tagContent(i);
|
|
|
}
|
|
|
TQString a = item.attribute("ask");
|
|
|
|
|
|
v_jid = j;
|
|
|
v_name = na;
|
|
|
v_subscription = s;
|
|
|
v_groups = g;
|
|
|
v_ask = a;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Roster
|
|
|
//---------------------------------------------------------------------------
|
|
|
Roster::Roster()
|
|
|
:TQValueList<RosterItem>()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
Roster::~Roster()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
Roster::Iterator Roster::find(const Jid &j)
|
|
|
{
|
|
|
for(Roster::Iterator it = begin(); it != end(); ++it) {
|
|
|
if((*it).jid().compare(j))
|
|
|
return it;
|
|
|
}
|
|
|
|
|
|
return end();
|
|
|
}
|
|
|
|
|
|
Roster::ConstIterator Roster::find(const Jid &j) const
|
|
|
{
|
|
|
for(Roster::ConstIterator it = begin(); it != end(); ++it) {
|
|
|
if((*it).jid().compare(j))
|
|
|
return it;
|
|
|
}
|
|
|
|
|
|
return end();
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// FormField
|
|
|
//---------------------------------------------------------------------------
|
|
|
FormField::FormField(const TQString &type, const TQString &value)
|
|
|
{
|
|
|
v_type = misc;
|
|
|
if(!type.isEmpty()) {
|
|
|
int x = tagNameToType(type);
|
|
|
if(x != -1)
|
|
|
v_type = x;
|
|
|
}
|
|
|
v_value = value;
|
|
|
}
|
|
|
|
|
|
FormField::~FormField()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
int FormField::type() const
|
|
|
{
|
|
|
return v_type;
|
|
|
}
|
|
|
|
|
|
TQString FormField::realName() const
|
|
|
{
|
|
|
return typeToTagName(v_type);
|
|
|
}
|
|
|
|
|
|
TQString FormField::fieldName() const
|
|
|
{
|
|
|
switch(v_type) {
|
|
|
case username: return TQObject::tr("Username");
|
|
|
case nick: return TQObject::tr("Nickname");
|
|
|
case password: return TQObject::tr("Password");
|
|
|
case name: return TQObject::tr("Name");
|
|
|
case first: return TQObject::tr("First Name");
|
|
|
case last: return TQObject::tr("Last Name");
|
|
|
case email: return TQObject::tr("E-mail");
|
|
|
case address: return TQObject::tr("Address");
|
|
|
case city: return TQObject::tr("City");
|
|
|
case state: return TQObject::tr("State");
|
|
|
case zip: return TQObject::tr("Zipcode");
|
|
|
case phone: return TQObject::tr("Phone");
|
|
|
case url: return TQObject::tr("URL");
|
|
|
case date: return TQObject::tr("Date");
|
|
|
case misc: return TQObject::tr("Misc");
|
|
|
default: return "";
|
|
|
};
|
|
|
}
|
|
|
|
|
|
bool FormField::isSecret() const
|
|
|
{
|
|
|
return (type() == password);
|
|
|
}
|
|
|
|
|
|
const TQString & FormField::value() const
|
|
|
{
|
|
|
return v_value;
|
|
|
}
|
|
|
|
|
|
void FormField::setType(int x)
|
|
|
{
|
|
|
v_type = x;
|
|
|
}
|
|
|
|
|
|
bool FormField::setType(const TQString &in)
|
|
|
{
|
|
|
int x = tagNameToType(in);
|
|
|
if(x == -1)
|
|
|
return false;
|
|
|
|
|
|
v_type = x;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
void FormField::setValue(const TQString &in)
|
|
|
{
|
|
|
v_value = in;
|
|
|
}
|
|
|
|
|
|
int FormField::tagNameToType(const TQString &in) const
|
|
|
{
|
|
|
if(!in.compare("username")) return username;
|
|
|
if(!in.compare("nick")) return nick;
|
|
|
if(!in.compare("password")) return password;
|
|
|
if(!in.compare("name")) return name;
|
|
|
if(!in.compare("first")) return first;
|
|
|
if(!in.compare("last")) return last;
|
|
|
if(!in.compare("email")) return email;
|
|
|
if(!in.compare("address")) return address;
|
|
|
if(!in.compare("city")) return city;
|
|
|
if(!in.compare("state")) return state;
|
|
|
if(!in.compare("zip")) return zip;
|
|
|
if(!in.compare("phone")) return phone;
|
|
|
if(!in.compare("url")) return url;
|
|
|
if(!in.compare("date")) return date;
|
|
|
if(!in.compare("misc")) return misc;
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
TQString FormField::typeToTagName(int type) const
|
|
|
{
|
|
|
switch(type) {
|
|
|
case username: return "username";
|
|
|
case nick: return "nick";
|
|
|
case password: return "password";
|
|
|
case name: return "name";
|
|
|
case first: return "first";
|
|
|
case last: return "last";
|
|
|
case email: return "email";
|
|
|
case address: return "address";
|
|
|
case city: return "city";
|
|
|
case state: return "state";
|
|
|
case zip: return "zipcode";
|
|
|
case phone: return "phone";
|
|
|
case url: return "url";
|
|
|
case date: return "date";
|
|
|
case misc: return "misc";
|
|
|
default: return "";
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Form
|
|
|
//---------------------------------------------------------------------------
|
|
|
Form::Form(const Jid &j)
|
|
|
:TQValueList<FormField>()
|
|
|
{
|
|
|
setJid(j);
|
|
|
}
|
|
|
|
|
|
Form::~Form()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
Jid Form::jid() const
|
|
|
{
|
|
|
return v_jid;
|
|
|
}
|
|
|
|
|
|
TQString Form::instructions() const
|
|
|
{
|
|
|
return v_instructions;
|
|
|
}
|
|
|
|
|
|
TQString Form::key() const
|
|
|
{
|
|
|
return v_key;
|
|
|
}
|
|
|
|
|
|
void Form::setJid(const Jid &j)
|
|
|
{
|
|
|
v_jid = j;
|
|
|
}
|
|
|
|
|
|
void Form::setInstructions(const TQString &s)
|
|
|
{
|
|
|
v_instructions = s;
|
|
|
}
|
|
|
|
|
|
void Form::setKey(const TQString &s)
|
|
|
{
|
|
|
v_key = s;
|
|
|
}
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// SearchResult
|
|
|
//---------------------------------------------------------------------------
|
|
|
SearchResult::SearchResult(const Jid &jid)
|
|
|
{
|
|
|
setJid(jid);
|
|
|
}
|
|
|
|
|
|
SearchResult::~SearchResult()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
const Jid & SearchResult::jid() const
|
|
|
{
|
|
|
return v_jid;
|
|
|
}
|
|
|
|
|
|
const TQString & SearchResult::nick() const
|
|
|
{
|
|
|
return v_nick;
|
|
|
}
|
|
|
|
|
|
const TQString & SearchResult::first() const
|
|
|
{
|
|
|
return v_first;
|
|
|
}
|
|
|
|
|
|
const TQString & SearchResult::last() const
|
|
|
{
|
|
|
return v_last;
|
|
|
}
|
|
|
|
|
|
const TQString & SearchResult::email() const
|
|
|
{
|
|
|
return v_email;
|
|
|
}
|
|
|
|
|
|
void SearchResult::setJid(const Jid &jid)
|
|
|
{
|
|
|
v_jid = jid;
|
|
|
}
|
|
|
|
|
|
void SearchResult::setNick(const TQString &nick)
|
|
|
{
|
|
|
v_nick = nick;
|
|
|
}
|
|
|
|
|
|
void SearchResult::setFirst(const TQString &first)
|
|
|
{
|
|
|
v_first = first;
|
|
|
}
|
|
|
|
|
|
void SearchResult::setLast(const TQString &last)
|
|
|
{
|
|
|
v_last = last;
|
|
|
}
|
|
|
|
|
|
void SearchResult::setEmail(const TQString &email)
|
|
|
{
|
|
|
v_email = email;
|
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// Features
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
Features::Features()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
Features::Features(const TQStringList &l)
|
|
|
{
|
|
|
setList(l);
|
|
|
}
|
|
|
|
|
|
Features::Features(const TQString &str)
|
|
|
{
|
|
|
TQStringList l;
|
|
|
l << str;
|
|
|
|
|
|
setList(l);
|
|
|
}
|
|
|
|
|
|
Features::~Features()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
TQStringList Features::list() const
|
|
|
{
|
|
|
return _list;
|
|
|
}
|
|
|
|
|
|
void Features::setList(const TQStringList &l)
|
|
|
{
|
|
|
_list = l;
|
|
|
}
|
|
|
|
|
|
bool Features::test(const TQStringList &ns) const
|
|
|
{
|
|
|
TQStringList::ConstIterator it = ns.begin();
|
|
|
for ( ; it != ns.end(); ++it)
|
|
|
if ( _list.find( *it ) != _list.end() )
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
#define FID_REGISTER "jabber:iq:register"
|
|
|
bool Features::canRegister() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_REGISTER;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_SEARCH "jabber:iq:search"
|
|
|
bool Features::canSearch() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_SEARCH;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_XHTML "http://jabber.org/protocol/xhtml-im"
|
|
|
bool Features::canXHTML() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
|
|
|
ns << FID_XHTML;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_GROUPCHAT "jabber:iq:conference"
|
|
|
bool Features::canGroupchat() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << "http://jabber.org/protocol/muc";
|
|
|
ns << FID_GROUPCHAT;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_VOICE "http://www.google.com/xmpp/protocol/voice/v1"
|
|
|
bool Features::canVoice() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_VOICE;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_GATEWAY "jabber:iq:gateway"
|
|
|
bool Features::isGateway() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_GATEWAY;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_DISCO "http://jabber.org/protocol/disco"
|
|
|
bool Features::canDisco() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_DISCO;
|
|
|
ns << "http://jabber.org/protocol/disco#info";
|
|
|
ns << "http://jabber.org/protocol/disco#items";
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
#define FID_VCARD "vcard-temp"
|
|
|
bool Features::haveVCard() const
|
|
|
{
|
|
|
TQStringList ns;
|
|
|
ns << FID_VCARD;
|
|
|
|
|
|
return test(ns);
|
|
|
}
|
|
|
|
|
|
// custom Psi acitons
|
|
|
#define FID_ADD "psi:add"
|
|
|
|
|
|
class Features::FeatureName : public TQObject
|
|
|
{
|
|
|
Q_OBJECT
|
|
|
|
|
|
public:
|
|
|
FeatureName()
|
|
|
: TQObject(tqApp)
|
|
|
{
|
|
|
id2s[FID_Invalid] = tr("ERROR: Incorrect usage of Features class");
|
|
|
id2s[FID_None] = tr("None");
|
|
|
id2s[FID_Register] = tr("Register");
|
|
|
id2s[FID_Search] = tr("Search");
|
|
|
id2s[FID_Groupchat] = tr("Groupchat");
|
|
|
id2s[FID_Gateway] = tr("Gateway");
|
|
|
id2s[FID_Disco] = tr("Service Discovery");
|
|
|
id2s[FID_VCard] = tr("VCard");
|
|
|
|
|
|
// custom Psi actions
|
|
|
id2s[FID_Add] = tr("Add to roster");
|
|
|
|
|
|
// compute reverse map
|
|
|
//TQMap<TQString, long>::Iterator it = id2s.begin();
|
|
|
//for ( ; it != id2s.end(); ++it)
|
|
|
// s2id[it.data()] = it.key();
|
|
|
|
|
|
id2f[FID_Register] = FID_REGISTER;
|
|
|
id2f[FID_Search] = FID_SEARCH;
|
|
|
id2f[FID_Groupchat] = FID_GROUPCHAT;
|
|
|
id2f[FID_Gateway] = FID_GATEWAY;
|
|
|
id2f[FID_Disco] = FID_DISCO;
|
|
|
id2f[FID_VCard] = FID_VCARD;
|
|
|
|
|
|
// custom Psi actions
|
|
|
id2f[FID_Add] = FID_ADD;
|
|
|
}
|
|
|
|
|
|
//TQMap<TQString, long> s2id;
|
|
|
TQMap<long, TQString> id2s;
|
|
|
TQMap<long, TQString> id2f;
|
|
|
};
|
|
|
|
|
|
static Features::FeatureName *featureName = 0;
|
|
|
|
|
|
long Features::id() const
|
|
|
{
|
|
|
if ( _list.count() > 1 )
|
|
|
return FID_Invalid;
|
|
|
else if ( canRegister() )
|
|
|
return FID_Register;
|
|
|
else if ( canSearch() )
|
|
|
return FID_Search;
|
|
|
else if ( canGroupchat() )
|
|
|
return FID_Groupchat;
|
|
|
else if ( isGateway() )
|
|
|
return FID_Gateway;
|
|
|
else if ( canDisco() )
|
|
|
return FID_Disco;
|
|
|
else if ( haveVCard() )
|
|
|
return FID_VCard;
|
|
|
else if ( test(FID_ADD) )
|
|
|
return FID_Add;
|
|
|
|
|
|
return FID_None;
|
|
|
}
|
|
|
|
|
|
long Features::id(const TQString &feature)
|
|
|
{
|
|
|
Features f(feature);
|
|
|
return f.id();
|
|
|
}
|
|
|
|
|
|
TQString Features::feature(long id)
|
|
|
{
|
|
|
if ( !featureName )
|
|
|
featureName = new FeatureName();
|
|
|
|
|
|
return featureName->id2f[id];
|
|
|
}
|
|
|
|
|
|
TQString Features::name(long id)
|
|
|
{
|
|
|
if ( !featureName )
|
|
|
featureName = new FeatureName();
|
|
|
|
|
|
return featureName->id2s[id];
|
|
|
}
|
|
|
|
|
|
TQString Features::name() const
|
|
|
{
|
|
|
return name(id());
|
|
|
}
|
|
|
|
|
|
TQString Features::name(const TQString &feature)
|
|
|
{
|
|
|
Features f(feature);
|
|
|
return f.name(f.id());
|
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
// DiscoItem
|
|
|
//---------------------------------------------------------------------------
|
|
|
class DiscoItem::Private
|
|
|
{
|
|
|
public:
|
|
|
Private()
|
|
|
{
|
|
|
action = None;
|
|
|
}
|
|
|
|
|
|
Jid jid;
|
|
|
TQString name;
|
|
|
TQString node;
|
|
|
Action action;
|
|
|
|
|
|
Features features;
|
|
|
Identities identities;
|
|
|
};
|
|
|
|
|
|
DiscoItem::DiscoItem()
|
|
|
{
|
|
|
d = new Private;
|
|
|
}
|
|
|
|
|
|
DiscoItem::DiscoItem(const DiscoItem &from)
|
|
|
{
|
|
|
d = new Private;
|
|
|
*this = from;
|
|
|
}
|
|
|
|
|
|
DiscoItem & DiscoItem::operator= (const DiscoItem &from)
|
|
|
{
|
|
|
d->jid = from.d->jid;
|
|
|
d->name = from.d->name;
|
|
|
d->node = from.d->node;
|
|
|
d->action = from.d->action;
|
|
|
d->features = from.d->features;
|
|
|
d->identities = from.d->identities;
|
|
|
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
DiscoItem::~DiscoItem()
|
|
|
{
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
AgentItem DiscoItem::toAgentItem() const
|
|
|
{
|
|
|
AgentItem ai;
|
|
|
|
|
|
ai.setJid( jid() );
|
|
|
ai.setName( name() );
|
|
|
|
|
|
Identity id;
|
|
|
if ( !identities().isEmpty() )
|
|
|
id = identities().first();
|
|
|
|
|
|
ai.setCategory( id.category );
|
|
|
ai.setType( id.type );
|
|
|
|
|
|
ai.setFeatures( d->features );
|
|
|
|
|
|
return ai;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::fromAgentItem(const AgentItem &ai)
|
|
|
{
|
|
|
setJid( ai.jid() );
|
|
|
setName( ai.name() );
|
|
|
|
|
|
Identity id;
|
|
|
id.category = ai.category();
|
|
|
id.type = ai.type();
|
|
|
id.name = ai.name();
|
|
|
|
|
|
Identities idList;
|
|
|
idList << id;
|
|
|
|
|
|
setIdentities( idList );
|
|
|
|
|
|
setFeatures( ai.features() );
|
|
|
}
|
|
|
|
|
|
const Jid &DiscoItem::jid() const
|
|
|
{
|
|
|
return d->jid;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setJid(const Jid &j)
|
|
|
{
|
|
|
d->jid = j;
|
|
|
}
|
|
|
|
|
|
const TQString &DiscoItem::name() const
|
|
|
{
|
|
|
return d->name;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setName(const TQString &n)
|
|
|
{
|
|
|
d->name = n;
|
|
|
}
|
|
|
|
|
|
const TQString &DiscoItem::node() const
|
|
|
{
|
|
|
return d->node;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setNode(const TQString &n)
|
|
|
{
|
|
|
d->node = n;
|
|
|
}
|
|
|
|
|
|
DiscoItem::Action DiscoItem::action() const
|
|
|
{
|
|
|
return d->action;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setAction(Action a)
|
|
|
{
|
|
|
d->action = a;
|
|
|
}
|
|
|
|
|
|
const Features &DiscoItem::features() const
|
|
|
{
|
|
|
return d->features;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setFeatures(const Features &f)
|
|
|
{
|
|
|
d->features = f;
|
|
|
}
|
|
|
|
|
|
const DiscoItem::Identities &DiscoItem::identities() const
|
|
|
{
|
|
|
return d->identities;
|
|
|
}
|
|
|
|
|
|
void DiscoItem::setIdentities(const Identities &i)
|
|
|
{
|
|
|
d->identities = i;
|
|
|
|
|
|
if ( name().isEmpty() && i.count() )
|
|
|
setName( i.first().name );
|
|
|
}
|
|
|
|
|
|
|
|
|
DiscoItem::Action DiscoItem::string2action(TQString s)
|
|
|
{
|
|
|
Action a;
|
|
|
|
|
|
if ( s == "update" )
|
|
|
a = Update;
|
|
|
else if ( s == "remove" )
|
|
|
a = Remove;
|
|
|
else
|
|
|
a = None;
|
|
|
|
|
|
return a;
|
|
|
}
|
|
|
|
|
|
TQString DiscoItem::action2string(Action a)
|
|
|
{
|
|
|
TQString s;
|
|
|
|
|
|
if ( a == Update )
|
|
|
s = "update";
|
|
|
else if ( a == Remove )
|
|
|
s = "remove";
|
|
|
else
|
|
|
s = TQString();
|
|
|
|
|
|
return s;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#include"types.moc"
|