4
Copyright (c) 2003-2004 by Olivier Goffart <ogoffart@kde.org>
6
Kopete (c) 2003-2004 by the Kopete developers <kopete-devel@kde.org>
8
*************************************************************************
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
*************************************************************************
18
#include "historylogger.h"
20
#include <QtCore/QRegExp>
21
#include <QtCore/QFile>
22
#include <QtCore/QDir>
23
#include <QtCore/QDateTime>
24
#include <QtCore/QTimer>
25
#include <QtCore/QTextStream>
26
#include <QtCore/QList>
27
#include <QtCore/QDate>
28
#include <QtGui/QTextDocument>
31
#include <kstandarddirs.h>
32
#include <ksavefile.h>
34
#include "kopeteglobal.h"
35
#include "kopetecontact.h"
36
#include "kopeteprotocol.h"
37
#include "kopeteaccount.h"
38
#include "kopetemetacontact.h"
39
#include "kopetechatsession.h"
41
#include "historyconfig.h"
43
bool messageTimestampLessThan(const Kopete::Message &m1, const Kopete::Message &m2)
45
const Kopete::Contact* c1 = (m1.direction() == Kopete::Message::Outbound) ? m1.to().value(0) : m1.from();
46
const Kopete::Contact* c2 = (m2.direction() == Kopete::Message::Outbound) ? m2.to().value(0) : m2.from();
48
if (c1 == c2) // Messages from the same account, keep order as it was saved.
51
return m1.timestamp() < m2.timestamp();
54
// -----------------------------------------------------------------------------
55
HistoryLogger::HistoryLogger( Kopete::MetaContact *m, QObject *parent )
63
m_realMonth=QDate::currentDate().month();
65
m_filterCaseSensitive=Qt::CaseSensitive;
68
//the contact may be destroyed, for example, if the contact changes its metacontact
69
connect(m_metaContact , SIGNAL(destroyed(QObject*)) , this , SLOT(slotMCDeleted()));
75
HistoryLogger::HistoryLogger( Kopete::Contact *c, QObject *parent )
81
m_metaContact=c->metaContact();
83
m_realMonth=QDate::currentDate().month();
85
m_filterCaseSensitive=Qt::CaseSensitive;
88
//the contact may be destroyed, for example, if the contact changes its metacontact
89
connect(m_metaContact , SIGNAL(destroyed(QObject*)) , this , SLOT(slotMCDeleted()));
95
HistoryLogger::~HistoryLogger()
97
if(m_saveTimer && m_saveTimer->isActive())
102
void HistoryLogger::setPositionToLast()
105
m_oldSens = AntiChronological;
107
m_oldElements.clear();
111
void HistoryLogger::setPositionToFirst()
113
setCurrentMonth( getFirstMonth() );
114
m_oldSens = Chronological;
115
m_oldMonth=m_currentMonth;
116
m_oldElements.clear();
120
void HistoryLogger::setCurrentMonth(int month)
122
m_currentMonth = month;
123
m_currentElements.clear();
127
QDomDocument HistoryLogger::getDocument(const Kopete::Contact *c, unsigned int month , bool canLoad , bool* contain)
129
if(m_realMonth!=QDate::currentDate().month())
130
{ //We changed month, our index is not correct anymore, clean memory.
131
// or we will see what i called "the 31 midnight bug"(TM) :-) -Olivier
134
m_currentMonth++; //Not usre it's ok, but should work;
135
m_oldMonth++; // idem
136
m_realMonth=QDate::currentDate().month();
140
{ //this may happen if the contact has been moved, and the MC deleted
141
if(c && c->metaContact())
142
m_metaContact=c->metaContact();
144
return QDomDocument();
147
if(!m_metaContact->contacts().contains(const_cast<Kopete::Contact*>(c)))
151
return QDomDocument();
154
QMap<unsigned int , QDomDocument> documents = m_documents[c];
155
if (documents.contains(month))
156
return documents[month];
159
QDomDocument doc = getDocument(c, QDate::currentDate().addMonths(0-month), canLoad, contain);
161
documents.insert(month, doc);
162
m_documents[c]=documents;
168
QDomDocument HistoryLogger::getDocument(const Kopete::Contact *contact, const QDate date , bool canLoad , bool* contain)
170
Kopete::Contact *c = const_cast<Kopete::Contact*>(contact);
172
{ //this may happen if the contact has been moved, and the MC deleted
173
if(c && c->metaContact())
174
m_metaContact=c->metaContact();
176
return QDomDocument();
179
if(!m_metaContact->contacts().contains(c))
183
return QDomDocument();
190
return QDomDocument();
193
QString FileName = getFileName(c, date);
195
QDomDocument doc( "Kopete-History" );
197
QFile file( FileName );
198
if ( !file.open( QIODevice::ReadOnly ) )
204
if ( !doc.setContent( &file ) )
220
void HistoryLogger::appendMessage( const Kopete::Message &msg , const Kopete::Contact *ct )
225
// If no contact are given: If the manager is availiable, use the manager's
226
// first contact (the channel on irc, or the other contact for others protocols
227
const Kopete::Contact *c = ct;
228
if(!c && msg.manager() )
230
QList<Kopete::Contact*> mb=msg.manager()->members() ;
233
if(!c) //If the contact is still not initialized, use the message author.
234
c = msg.direction()==Kopete::Message::Outbound ? msg.to().first() : msg.from() ;
238
{ //this may happen if the contact has been moved, and the MC deleted
239
if(c && c->metaContact())
240
m_metaContact=c->metaContact();
246
if(!c || !m_metaContact->contacts().contains(const_cast<Kopete::Contact*>(c)) )
248
/*QPtrList<Kopete::Contact> contacts= m_metaContact->contacts();
249
QPtrListIterator<Kopete::Contact> it( contacts );
250
for( ; it.current(); ++it )
252
if( (*it)->protocol()->pluginId() == msg.from()->protocol()->pluginId() )
260
kWarning(14310) << "No contact found in this metacontact to" <<
261
" append in the history" << endl;
265
QDate date = msg.timestamp().date();
267
QDomDocument doc=getDocument(c, QDate::currentDate().month() - date.month() - (QDate::currentDate().year() - date.year()) * 12);
268
QDomElement docElem = doc.documentElement();
272
docElem= doc.createElement( "kopete-history" );
273
docElem.setAttribute ( "version" , "0.9" );
274
doc.appendChild( docElem );
275
QDomElement headElem = doc.createElement( "head" );
276
docElem.appendChild( headElem );
277
QDomElement dateElem = doc.createElement( "date" );
278
dateElem.setAttribute( "year", QString::number(date.year()) );
279
dateElem.setAttribute( "month", QString::number(date.month()) );
280
headElem.appendChild(dateElem);
281
QDomElement myselfElem = doc.createElement( "contact" );
282
myselfElem.setAttribute( "type", "myself" );
283
myselfElem.setAttribute( "contactId", c->account()->myself()->contactId() );
284
headElem.appendChild(myselfElem);
285
QDomElement contactElem = doc.createElement( "contact" );
286
contactElem.setAttribute( "contactId", c->contactId() );
287
headElem.appendChild(contactElem);
290
QDomElement msgElem = doc.createElement( "msg" );
291
msgElem.setAttribute( "in", msg.direction()==Kopete::Message::Outbound ? "0" : "1" );
292
msgElem.setAttribute( "from", msg.from()->contactId() );
293
msgElem.setAttribute( "nick", msg.from()->property( Kopete::Global::Properties::self()->nickName() ).value().toString() ); //do we have to set this?
294
msgElem.setAttribute( "time", msg.timestamp().toString("d h:m:s") );
298
if ( msg.format() != Qt::PlainText )
299
msgNode = doc.createTextNode( msg.escapedBody() );
301
msgNode = doc.createTextNode( Qt::escape(msg.plainBody()).replace('\n', "<br />") );
303
docElem.appendChild( msgElem );
304
msgElem.appendChild( msgNode );
307
// I'm temporizing the save.
308
// On hight-traffic channel, saving can take lots of CPU. (because the file is big)
309
// So i wait a time proportional to the time needed to save..
311
const QString filename=getFileName(c, date);
312
if(!m_toSaveFileName.isEmpty() && m_toSaveFileName != filename)
313
{ //that mean the contact or the month has changed, save it now.
317
m_toSaveFileName=filename;
318
m_toSaveDocument=doc;
322
m_saveTimer=new QTimer(this);
323
connect( m_saveTimer, SIGNAL(timeout()) , this, SLOT(saveToDisk()) );
325
if(!m_saveTimer->isActive())
327
m_saveTimer->setSingleShot( true );
328
m_saveTimer->start( m_saveTimerTime );
332
void HistoryLogger::saveToDisk()
336
if(m_toSaveFileName.isEmpty() || m_toSaveDocument.isNull())
340
t.start(); //mesure the time needed to save.
342
KSaveFile file( m_toSaveFileName );
345
QTextStream stream ( &file );
346
//stream.setEncoding( QTextStream::UnicodeUTF8 ); //???? oui ou non?
347
m_toSaveDocument.save( stream, 1 );
350
m_saveTimerTime=qMin(t.elapsed()*1000, 300000);
351
//a time 1000 times supperior to the time needed to save. but with a upper limit of 5 minutes
352
//on a my machine, (2.4Ghz, but old HD) it should take about 10 ms to save the file.
353
// So that would mean save every 10 seconds, which seems to be ok.
354
// But it may take 500 ms if the file to save becomes too big (1Mb).
355
kDebug(14310) << m_toSaveFileName << " saved in " << t.elapsed() << " ms ";
357
m_toSaveFileName.clear();
358
m_toSaveDocument=QDomDocument();
361
kError(14310) << "impossible to save the history file " << m_toSaveFileName << endl;
365
QList<Kopete::Message> HistoryLogger::readMessages(QDate date)
367
QRegExp rxTime("(\\d+) (\\d+):(\\d+)($|:)(\\d*)"); //(with a 0.7.x compatibility)
368
QList<Kopete::Message> messages;
369
QList<Kopete::Contact*> ct=m_metaContact->contacts();
371
foreach(Kopete::Contact* contact, ct)
373
QDomDocument doc=getDocument(contact,date, true, 0L);
374
QDomElement docElem = doc.documentElement();
375
QDomNode n = docElem.firstChild();
379
QDomElement msgElem2 = n.toElement();
380
if( !msgElem2.isNull() && msgElem2.tagName()=="msg")
382
rxTime.indexIn(msgElem2.attribute("time"));
383
QDateTime dt( QDate(date.year() , date.month() , rxTime.cap(1).toUInt()), QTime( rxTime.cap(2).toUInt() , rxTime.cap(3).toUInt(), rxTime.cap(5).toUInt() ) );
385
if (dt.date() != date)
391
Kopete::Message::MessageDirection dir = (msgElem2.attribute("in") == "1") ?
392
Kopete::Message::Inbound : Kopete::Message::Outbound;
394
if(!m_hideOutgoing || dir != Kopete::Message::Outbound)
395
{ //parse only if we don't hide it
397
QString f=msgElem2.attribute("from" );
398
const Kopete::Contact *from=f.isNull()? 0L : contact->account()->contacts().value( f );
401
from = (dir == Kopete::Message::Inbound) ? contact : contact->account()->myself();
403
Kopete::ContactPtrList to;
404
to.append( dir==Kopete::Message::Inbound ? contact->account()->myself() : contact );
406
Kopete::Message msg(from, to);
408
msg.setHtmlBody( QString::fromLatin1("<span title=\"%1\">%2</span>")
409
.arg( dt.toString(Qt::LocalDate), msgElem2.text() ));
410
msg.setTimestamp( dt );
411
msg.setDirection( dir );
413
messages.append(msg);
418
} // end while on messages
422
//Bubble Sort, can't use qStableSort because we have to compare surrounding items only, mostly
423
//it will be only O(n) sort, because we will only have one contact in metacontact for a day.
424
const int size = messages.size();
425
for (int i = 0; i < size; i++)
428
for (int j = 0; j < size - 1; j++)
430
if (messageTimestampLessThan(messages.at(j + 1), messages.at(j))) {
431
messages.swap(j, j + 1);
442
QList<Kopete::Message> HistoryLogger::readMessages(int lines,
443
const Kopete::Contact *c, Sens sens, bool reverseOrder, bool colorize)
445
//QDate dd = QDate::currentDate().addMonths(0-m_currentMonth);
447
QList<Kopete::Message> messages;
449
// A regexp useful for this function
450
QRegExp rxTime("(\\d+) (\\d+):(\\d+)($|:)(\\d*)"); //(with a 0.7.x compatibility)
453
{ //this may happen if the contact has been moved, and the MC deleted
454
if(c && c->metaContact())
455
m_metaContact=c->metaContact();
460
if(c && !m_metaContact->contacts().contains(const_cast<Kopete::Contact*>(c)) )
463
if(sens == Default ) //if no sens are selected, just continue in the previous sens
465
if( m_oldSens != Default && sens != m_oldSens )
466
{ //we changed our sens! so retrieve the old position to fly in the other way
467
m_currentElements= m_oldElements;
468
m_currentMonth=m_oldMonth;
472
m_oldElements=m_currentElements;
473
m_oldMonth=m_currentMonth;
477
//getting the color for messages:
478
QColor fgColor = HistoryConfig::history_color();
482
//there are two algoritms:
483
// - if a contact is given, or the metacontact contain only one contact, just read the history.
484
// - else, merge the history
486
//the merging algoritm is the following:
487
// we see what contact we have to read first, and we look at the firt date before another contact
488
// has a message with a bigger date.
491
const Kopete::Contact *currentContact=c;
492
if(!c && m_metaContact->contacts().count()==1)
493
currentContact=m_metaContact->contacts().first();
494
else if(!c && m_metaContact->contacts().count()== 0)
499
while(messages.count() < lines)
501
timeLimit=QDateTime();
502
QDomElement msgElem; //here is the message element
503
QDateTime timestamp; //and the timestamp of this message
505
if(!c && m_metaContact->contacts().count()>1)
506
{ //we have to merge the differents subcontact history
507
QList<Kopete::Contact*> ct=m_metaContact->contacts();
509
foreach(Kopete::Contact *contact, ct)
510
{ //we loop over each contact. we are searching the contact with the next message with the smallest date,
511
// it will becomes our current contact, and the contact with the mext message with the second smallest
512
// date, this date will bocomes the limit.
515
if(m_currentElements.contains(contact))
516
n=m_currentElements[contact];
517
else //there is not yet "next message" register, so we will take the first (for the current month)
519
QDomDocument doc=getDocument(contact,m_currentMonth);
520
QDomElement docElem = doc.documentElement();
521
n= (sens==Chronological)?docElem.firstChild() : docElem.lastChild();
523
//i can't drop the root element
524
workaround.append(docElem);
528
QDomElement msgElem2 = n.toElement();
529
if( !msgElem2.isNull() && msgElem2.tagName()=="msg")
531
rxTime.indexIn(msgElem2.attribute("time"));
532
QDate d=QDate::currentDate().addMonths(0-m_currentMonth);
533
QDateTime dt( QDate(d.year() , d.month() , rxTime.cap(1).toUInt()), QTime( rxTime.cap(2).toUInt() , rxTime.cap(3).toUInt(), rxTime.cap(5).toUInt() ) );
534
if(!timestamp.isValid() || ((sens==Chronological )? dt < timestamp : dt > timestamp) )
539
currentContact=contact;
542
else if(!timeLimit.isValid() || ((sens==Chronological) ? timeLimit > dt : timeLimit < dt) )
548
n=(sens==Chronological)? n.nextSibling() : n.previousSibling();
552
else //we don't have to merge the history. just take the next item in the contact
554
if(m_currentElements.contains(currentContact))
555
msgElem=m_currentElements[currentContact];
558
QDomDocument doc=getDocument(currentContact,m_currentMonth);
559
QDomElement docElem = doc.documentElement();
560
QDomNode n= (sens==Chronological)?docElem.firstChild() : docElem.lastChild();
561
msgElem=QDomElement();
562
while(!n.isNull()) //continue until we get a msg
564
msgElem=n.toElement();
565
if( !msgElem.isNull() && msgElem.tagName()=="msg")
567
m_currentElements[currentContact]=msgElem;
570
n=(sens==Chronological)? n.nextSibling() : n.previousSibling();
573
//i can't drop the root element
574
workaround.append(docElem);
579
if(msgElem.isNull()) //we don't find ANY messages in any contact for this month. so we change the month
581
if(sens==Chronological)
583
if(m_currentMonth <= 0)
584
break; //there are no other messages to show. break even if we don't have nb messages
585
setCurrentMonth(m_currentMonth-1);
589
if(m_currentMonth >= getFirstMonth(c))
590
break; //we don't have any other messages to show
591
setCurrentMonth(m_currentMonth+1);
593
continue; //begin the loop from the bottom, and find currentContact and timeLimit again
597
(messages.count() < lines) &&
599
(!timestamp.isValid() || !timeLimit.isValid() ||
600
((sens==Chronological) ? timestamp <= timeLimit : timestamp >= timeLimit)
603
// break this loop, if we have reached the correct number of messages,
604
// if there are no more messages for this contact, or if we reached
605
// the timeLimit msgElem is the next message, still not parsed, so
608
Kopete::Message::MessageDirection dir = (msgElem.attribute("in") == "1") ?
609
Kopete::Message::Inbound : Kopete::Message::Outbound;
611
if(!m_hideOutgoing || dir != Kopete::Message::Outbound)
612
{ //parse only if we don't hide it
614
if( m_filter.isNull() || ( m_filterRegExp? msgElem.text().contains(QRegExp(m_filter,m_filterCaseSensitive)) : msgElem.text().contains(m_filter,m_filterCaseSensitive) ))
616
Q_ASSERT(currentContact);
617
QString f=msgElem.attribute("from" );
618
const Kopete::Contact *from=f.isNull() ? 0L : currentContact->account()->contacts().value(f);
621
from = (dir == Kopete::Message::Inbound) ? currentContact : currentContact->account()->myself();
623
Kopete::ContactPtrList to;
624
to.append( dir==Kopete::Message::Inbound ? currentContact->account()->myself() : const_cast<Kopete::Contact*>(currentContact) );
626
if(!timestamp.isValid())
628
//parse timestamp only if it was not already parsed
629
rxTime.indexIn(msgElem.attribute("time"));
630
QDate d=QDate::currentDate().addMonths(0-m_currentMonth);
631
timestamp=QDateTime( QDate(d.year() , d.month() , rxTime.cap(1).toUInt()), QTime( rxTime.cap(2).toUInt() , rxTime.cap(3).toUInt() , rxTime.cap(5).toUInt() ) );
634
Kopete::Message msg(from, to);
635
msg.setTimestamp( timestamp );
636
msg.setDirection( dir );
640
msg.setHtmlBody( QString::fromLatin1("<span style=\"color:%1\" title=\"%2\">%3</span>")
641
.arg( fgColor.name(), timestamp.toString(Qt::LocalDate), msgElem.text() ));
642
msg.setForegroundColor( fgColor );
643
msg.addClass( "history" );
647
msg.setHtmlBody( QString::fromLatin1("<span title=\"%1\">%2</span>")
648
.arg( timestamp.toString(Qt::LocalDate), msgElem.text() ));
652
messages.prepend(msg);
654
messages.append(msg);
658
//here is the point of workaround. If i drop the root element, this crashes
659
//get the next message
660
QDomNode node = ( (sens==Chronological) ? msgElem.nextSibling() :
661
msgElem.previousSibling() );
663
msgElem = QDomElement(); //n.toElement();
664
while (!node.isNull() && msgElem.isNull())
666
msgElem = node.toElement();
667
if (!msgElem.isNull())
669
if (msgElem.tagName() == "msg")
671
if (!c && (m_metaContact->contacts().count() > 1))
673
// In case of hideoutgoing messages, it is faster to do
674
// this, so we don't parse the date if it is not needed
675
QRegExp rx("(\\d+) (\\d+):(\\d+):(\\d+)");
676
rx.indexIn(msgElem.attribute("time"));
678
QDate d = QDate::currentDate().addMonths(0-m_currentMonth);
679
timestamp = QDateTime(
680
QDate(d.year(), d.month(), rx.cap(1).toUInt()),
681
QTime( rx.cap(2).toUInt(), rx.cap(3).toUInt() ) );
684
timestamp = QDateTime(); //invalid
687
msgElem = QDomElement();
690
node = (sens == Chronological) ? node.nextSibling() :
691
node.previousSibling();
693
m_currentElements[currentContact]=msgElem; //this is the next message
697
if(messages.count() < lines)
698
m_currentElements.clear(); //current elements are null this can't be allowed
703
QString HistoryLogger::getFileName(const Kopete::Contact* c, QDate date)
706
QString name = c->protocol()->pluginId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) ) +
707
QString::fromLatin1( "/" ) +
708
c->account()->accountId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) ) +
709
QString::fromLatin1( "/" ) +
710
c->contactId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) ) +
711
date.toString(".yyyyMM");
713
QString filename=KStandardDirs::locateLocal( "data", QString::fromLatin1( "kopete/logs/" ) + name+ QString::fromLatin1( ".xml" ) ) ;
715
//Check if there is a kopete 0.7.x file
716
QFileInfo fi(filename);
719
name = c->protocol()->pluginId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) ) +
720
QString::fromLatin1( "/" ) +
721
c->contactId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) ) +
722
date.toString(".yyyyMM");
724
QString filename2=KStandardDirs::locateLocal( "data", QString::fromLatin1( "kopete/logs/" ) + name+ QString::fromLatin1( ".xml" ) ) ;
726
QFileInfo fi2(filename2);
735
unsigned int HistoryLogger::getFirstMonth(const Kopete::Contact *c)
738
return getFirstMonth();
740
QRegExp rx( "\\.(\\d\\d\\d\\d)(\\d\\d)" );
742
// BEGIN check if there are Kopete 0.7.x
743
QDir d1(KStandardDirs::locateLocal("data",QString("kopete/logs/")+
744
c->protocol()->pluginId().replace( QRegExp(QString::fromLatin1("[./~?*]")),QString::fromLatin1("-"))
746
d1.setFilter( QDir::Files | QDir::NoSymLinks );
747
d1.setSorting( QDir::Name );
749
const QFileInfoList list1 = d1.entryInfoList();
751
foreach(const QFileInfo &fi, list1)
753
if(fi.fileName().contains(c->contactId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) )))
755
rx.indexIn(fi.fileName());
756
int result = 12*(QDate::currentDate().year() - rx.cap(1).toUInt()) +QDate::currentDate().month() - rx.cap(2).toUInt();
760
kWarning(14310) << "Kopete only found log file from Kopete 0.7.x made in the future. Check your date!";
766
// END of kopete 0.7.x check
769
QDir d(KStandardDirs::locateLocal("data",QString("kopete/logs/")+
770
c->protocol()->pluginId().replace( QRegExp(QString::fromLatin1("[./~?*]")),QString::fromLatin1("-")) +
771
QString::fromLatin1( "/" ) +
772
c->account()->accountId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) )
775
d.setFilter( QDir::Files | QDir::NoSymLinks );
776
d.setSorting( QDir::Name );
778
const QFileInfoList list = d.entryInfoList();
780
foreach(const QFileInfo &fi, list)
782
if(fi.fileName().contains(c->contactId().replace( QRegExp( QString::fromLatin1( "[./~?*]" ) ), QString::fromLatin1( "-" ) )))
784
rx.indexIn(fi.fileName());
785
int result = 12*(QDate::currentDate().year() - rx.cap(1).toUInt()) +QDate::currentDate().month() - rx.cap(2).toUInt();
788
kWarning(14310) << "Kopete only found log file made in the future. Check your date!";
797
unsigned int HistoryLogger::getFirstMonth()
799
if(m_cachedMonth!=-1)
800
return m_cachedMonth;
806
QList<Kopete::Contact*> contacts=m_metaContact->contacts();
808
foreach(Kopete::Contact* contact, contacts)
810
int m2=getFirstMonth(contact);
817
void HistoryLogger::setHideOutgoing(bool b)
822
void HistoryLogger::slotMCDeleted()
827
void HistoryLogger::setFilter(const QString& filter, bool caseSensitive , bool isRegExp)
830
m_filterCaseSensitive=caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
831
m_filterRegExp=isRegExp;
834
QString HistoryLogger::filter() const
839
bool HistoryLogger::filterCaseSensitive() const
841
return (m_filterCaseSensitive == Qt::CaseSensitive);
844
bool HistoryLogger::filterRegExp() const
846
return m_filterRegExp;
849
QList<int> HistoryLogger::getDaysForMonth(QDate date)
851
QRegExp rxTime("time=\"(\\d+) \\d+:\\d+(:\\d+)?\""); //(with a 0.7.x compatibility)
855
QList<Kopete::Contact*> contacts = m_metaContact->contacts();
858
foreach(Kopete::Contact *contact, contacts)
860
// kDebug() << getFileName(*it, date);
861
QFile file(getFileName(contact, date));
862
if(!file.open(QIODevice::ReadOnly))
866
QTextStream stream(&file);
867
QString fullText = stream.readAll();
871
while( (pos = rxTime.indexIn(fullText, pos)) != -1)
873
pos += rxTime.matchedLength();
874
int day=rxTime.capturedTexts()[1].toInt();
876
if ( day !=lastDay && dayList.indexOf(day) == -1) // avoid duplicates
878
dayList.append(rxTime.capturedTexts()[1].toInt());
886
#include "historylogger.moc"