3
* Copyright (C) 2001, 2002 Justin Karneges
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
#include "psiaccount.h"
27
#include "xmpp_xmlcommon.h"
28
#include "filetransfer.h"
30
using namespace XMLHelper;
32
static PsiEvent *copyPsiEvent(PsiEvent *fe)
35
if ( fe->inherits("MessageEvent") )
36
e = new MessageEvent( *((MessageEvent *)fe) );
37
else if ( fe->inherits("AuthEvent") )
38
e = new AuthEvent( *((AuthEvent *)fe) );
39
else if ( fe->inherits("PGPEvent") )
40
e = new PGPEvent( *((PGPEvent *)fe) );
42
qWarning("copyPsiEvent(): Failed: unknown event type: %s", fe->className());
47
//----------------------------------------------------------------------------
49
//----------------------------------------------------------------------------
50
class DummyStream : public Stream
53
QDomDocument & doc() const { return v_doc; }
54
QString baseNS() const { return QString::null; }
55
bool old() const { return false; }
58
bool stanzaAvailable() const { return false; }
59
Stanza read() { return Stanza(); }
60
void write(const Stanza &) { }
62
int errorCondition() const { return 0; }
63
QString errorText() const { return QString::null; }
64
QDomElement errorAppSpec() const { return v_doc.documentElement(); }
67
static QDomDocument v_doc;
70
QDomDocument DummyStream::v_doc;
72
//----------------------------------------------------------------------------
74
//----------------------------------------------------------------------------
75
PsiEvent::PsiEvent(PsiAccount *acc)
77
v_originLocal = false;
82
PsiEvent::PsiEvent(const PsiEvent &from)
85
v_originLocal = from.v_originLocal;
89
v_account = from.v_account;
96
XMPP::Jid PsiEvent::jid() const
101
void PsiEvent::setJid(const XMPP::Jid &j)
106
PsiAccount *PsiEvent::account() const
111
bool PsiEvent::originLocal() const
113
return v_originLocal;
116
bool PsiEvent::late() const
121
QDateTime PsiEvent::timeStamp() const
126
void PsiEvent::setOriginLocal(bool b)
131
void PsiEvent::setLate(bool b)
136
void PsiEvent::setTimeStamp(const QDateTime &t)
141
QDomElement *PsiEvent::toXml(QDomDocument *doc) const
143
QDomElement e = doc->createElement("event");
144
e.setAttribute("type", className());
146
e.appendChild( textTag(*doc, "originLocal", v_originLocal) );
147
e.appendChild( textTag(*doc, "late", v_late) );
148
e.appendChild( textTag(*doc, "ts", v_ts.toString( ISODate )) );
149
if ( !v_jid.full().isEmpty() )
150
e.appendChild( textTag(*doc, "jid", v_jid.full()) );
153
e.appendChild( textTag(*doc, "account", v_account->name()) );
155
QDomElement *ret = new QDomElement(e);
159
bool PsiEvent::fromXml(PsiCon *psi, const QDomElement *e)
161
if ( e->tagName() != "event" )
163
if ( e->attribute("type") != className() )
166
readBoolEntry(*e, "originLocal", &v_originLocal);
167
readBoolEntry(*e, "late", &v_late);
168
v_ts = QDateTime::fromString(subTagText(*e, "ts"), ISODate);
169
v_jid = Jid( subTagText(*e, "jid") );
171
if ( hasSubTag(*e, "account") ) {
172
PsiAccountList list = psi->accountList();
173
PsiAccountListIt it(list);
174
QString accName = subTagText(*e, "account");
175
for ( ; it.current(); ++it) {
176
if ( it.current()->name() == accName ) {
177
v_account = it.current();
186
int PsiEvent::priority() const
188
return Options::EventPriorityDontCare;
191
//----------------------------------------------------------------------------
193
//----------------------------------------------------------------------------
195
MessageEvent::MessageEvent(PsiAccount *acc)
198
v_sentToChatWindow = false;
201
MessageEvent::MessageEvent(const XMPP::Message &m, PsiAccount *acc)
204
v_sentToChatWindow = false;
208
MessageEvent::MessageEvent(const MessageEvent &from)
209
: PsiEvent(from), v_m(from.v_m), v_sentToChatWindow(from.v_sentToChatWindow)
213
MessageEvent::~MessageEvent()
217
int MessageEvent::type() const
222
Jid MessageEvent::from() const
227
void MessageEvent::setFrom(const Jid &j)
232
bool MessageEvent::sentToChatWindow() const
234
return v_sentToChatWindow;
237
const XMPP::Message & MessageEvent::message() const
242
void MessageEvent::setSentToChatWindow(bool b)
244
v_sentToChatWindow = b;
247
void MessageEvent::setMessage(const XMPP::Message &m)
250
setTimeStamp ( v_m.timeStamp() );
251
setLate ( v_m.spooled() );
254
QDomElement *MessageEvent::toXml(QDomDocument *doc) const
256
QDomElement *e = PsiEvent::toXml(doc);
261
Stanza s = v_m.toStanza(&stream);
262
e->appendChild( s.element() );
267
bool MessageEvent::fromXml(PsiCon *psi, const QDomElement *e)
269
if ( !PsiEvent::fromXml(psi, e) )
273
QDomElement msg = findSubTag(*e, "message", &found);
276
Stanza s = stream.createStanza(msg);
277
v_m.fromStanza(s, 0); // FIXME: fix tzoffset?
284
int MessageEvent::priority() const
286
if ( v_m.type() == "headline" )
287
return option.eventPriorityHeadline;
288
else if ( v_m.type() == "chat" )
289
return option.eventPriorityChat;
291
return option.eventPriorityMessage;
294
//----------------------------------------------------------------------------
296
//----------------------------------------------------------------------------
298
AuthEvent::AuthEvent(const Jid &j, const QString &authType, PsiAccount *acc)
305
AuthEvent::AuthEvent(const AuthEvent &from)
306
: PsiEvent(from), v_from(from.v_from), v_at(from.v_at)
310
AuthEvent::~AuthEvent()
314
int AuthEvent::type() const
319
Jid AuthEvent::from() const
324
void AuthEvent::setFrom(const Jid &j)
329
QString AuthEvent::authType() const
334
QDomElement *AuthEvent::toXml(QDomDocument *doc) const
336
QDomElement *e = PsiEvent::toXml(doc);
340
e->appendChild( textTag(*doc, "from", v_from.full()) );
341
e->appendChild( textTag(*doc, "authType", v_at) );
346
bool AuthEvent::fromXml(PsiCon *psi, const QDomElement *e)
348
if ( !PsiEvent::fromXml(psi, e) )
351
v_from = Jid( subTagText(*e, "from") );
352
v_at = subTagText(*e, "authType");
357
int AuthEvent::priority() const
359
return option.eventPriorityAuth;
362
//----------------------------------------------------------------------------
364
//----------------------------------------------------------------------------
365
FileEvent::FileEvent(const Jid &j, FileTransfer *_ft, PsiAccount *acc)
372
FileEvent::~FileEvent()
377
int FileEvent::priority() const
379
return option.eventPriorityFile;
382
Jid FileEvent::from() const
387
void FileEvent::setFrom(const Jid &j)
392
FileTransfer *FileEvent::takeFileTransfer()
394
FileTransfer *_ft = ft;
399
//----------------------------------------------------------------------------
401
//----------------------------------------------------------------------------
406
EventItem(PsiEvent *_e, int i)
412
EventItem(const EventItem &from)
414
e = copyPsiEvent(from.e);
427
PsiEvent *event() const
437
class EventQueue::Private
441
list.setAutoDelete(true);
444
QPtrList<EventItem> list;
448
EventQueue::EventQueue(PsiCon *psi)
455
EventQueue::EventQueue(const EventQueue &from)
463
EventQueue::~EventQueue()
468
int EventQueue::nextId() const
470
QPtrListIterator<EventItem> it(d->list);
471
EventItem *i = it.current();
477
int EventQueue::count() const
479
return d->list.count();
482
int EventQueue::count(const Jid &j, bool compareRes) const
486
QPtrListIterator<EventItem> it(d->list);
487
for(EventItem *i; (i = it.current()); ++it) {
488
Jid j2(i->event()->jid());
489
if(j.compare(j2, compareRes))
496
void EventQueue::enqueue(PsiEvent *e)
498
EventItem *i = new EventItem(e, d->psi->getId());
500
int prior = e->priority();
503
// skip all with higher or equal priority
504
for ( EventItem *ei = d->list.first(); ei; ei = d->list.next() ) {
505
if ( ei && ei->event()->priority() < prior ) {
506
d->list.insert(d->list.find(ei), i);
519
void EventQueue::dequeue(PsiEvent *e)
524
QPtrListIterator<EventItem> it(d->list);
525
for(EventItem *i; (i = it.current()); ++it) {
526
if ( e == i->event() ) {
535
PsiEvent *EventQueue::dequeue(const Jid &j, bool compareRes)
537
QPtrListIterator<EventItem> it(d->list);
538
for(EventItem *i; (i = it.current()); ++it) {
539
PsiEvent *e = i->event();
541
if(j.compare(j2, compareRes)) {
542
d->list.removeRef(i);
551
PsiEvent *EventQueue::peek(const Jid &j, bool compareRes) const
553
QPtrListIterator<EventItem> it(d->list);
554
for(EventItem *i; (i = it.current()); ++it) {
555
PsiEvent *e = i->event();
557
if(j.compare(j2, compareRes)) {
565
PsiEvent *EventQueue::dequeueNext()
567
QPtrListIterator<EventItem> it(d->list);
568
EventItem *i = it.current();
571
PsiEvent *e = i->event();
577
PsiEvent *EventQueue::peekNext() const
579
QPtrListIterator<EventItem> it(d->list);
580
EventItem *i = it.current();
586
PsiEvent *EventQueue::peekFirstChat(const Jid &j, bool compareRes) const
588
QPtrListIterator<EventItem> it(d->list);
589
for(EventItem *i; (i = it.current()); ++it) {
590
PsiEvent *e = i->event();
591
if(e->type() == PsiEvent::Message) {
592
MessageEvent *me = (MessageEvent *)e;
593
if(j.compare(me->from(), compareRes) && me->message().type() == "chat")
601
bool EventQueue::hasChats(const Jid &j, bool compareRes) const
603
return (peekFirstChat(j, compareRes) ? true: false);
606
// this function extracts all chats from the queue, and returns a list of queue positions
607
void EventQueue::extractChats(QPtrList<PsiEvent> *el, const Jid &j, bool compareRes)
609
bool changed = false;
611
QPtrListIterator<EventItem> it(d->list);
612
for(EventItem *i; (i = it.current());) {
613
PsiEvent *e = i->event();
614
if(e->type() == PsiEvent::Message) {
615
MessageEvent *me = (MessageEvent *)e;
616
if(j.compare(me->from(), compareRes) && me->message().type() == "chat") {
630
void EventQueue::printContent() const
632
QPtrListIterator<EventItem> it(d->list);
633
for(EventItem *i; (i = it.current()); ++it) {
634
PsiEvent *e = i->event();
635
printf(" %d: (%d) from=[%s] jid=[%s]\n", i->id(), e->type(), e->from().full().latin1(), e->jid().full().latin1());
639
void EventQueue::clear()
646
// this function removes all events associated with the input jid
647
void EventQueue::clear(const Jid &j, bool compareRes)
649
bool changed = false;
651
QPtrListIterator<EventItem> it(d->list);
652
for(EventItem *i; (i = it.current());) {
653
PsiEvent *e = i->event();
655
if(j.compare(j2, compareRes)) {
656
d->list.removeRef(i);
667
EventQueue &EventQueue::operator= (const EventQueue &from)
670
d->psi = from.d->psi;
672
QPtrListIterator<EventItem> it(d->list);
673
for(EventItem *i; (i = it.current()); ++i) {
674
PsiEvent *e = i->event();
676
enqueue( copyPsiEvent(e) );
682
QDomElement *EventQueue::toXml(QDomDocument *doc) const
684
QDomElement e = doc->createElement("eventQueue");
685
e.setAttribute("version", "1.0");
686
e.appendChild(textTag(doc, "progver", PROG_VERSION));
688
QPtrListIterator<EventItem> it(d->list);
689
for(EventItem *i; (i = it.current()); ++it) {
690
QDomElement *event = (*it)->event()->toXml(doc);
693
e.appendChild( *event );
698
QDomElement *ret = new QDomElement(e);
702
bool EventQueue::fromXml(const QDomElement *q)
707
if ( q->tagName() != "eventQueue" )
710
if ( q->attribute("version") != "1.0" )
713
QString progver = subTagText(*q, "progver");
715
for(QDomNode n = q->firstChild(); !n.isNull(); n = n.nextSibling()) {
716
QDomElement e = n.toElement();
720
if ( e.tagName() != "event" )
724
QString eventType = e.attribute("type");
725
if ( eventType == "MessageEvent" ) {
726
event = new MessageEvent(0);
727
if ( !event->fromXml(d->psi, &e) ) {
732
else if ( eventType == "AuthEvent" ) {
733
event = new AuthEvent("", "", 0);
734
if ( !event->fromXml(d->psi, &e) ) {
741
emit handleEvent( event );
747
bool EventQueue::toFile(const QString &fname)
751
QDomElement *element = toXml(&doc);
754
doc.appendChild(*element);
757
if( !f.open(IO_WriteOnly) )
761
t.setEncoding( QTextStream::UnicodeUTF8 );
762
t << doc.toString(4);
769
bool EventQueue::fromFile(const QString &fname)
775
if(!f.open(IO_ReadOnly))
777
if(!doc.setContent(&f, true))
781
QDomElement base = doc.documentElement();
782
return fromXml(&base);