/* * vcardfactory.cpp - class for caching vCards * Copyright (C) 2003 Michail Pishchagin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "vcardfactory.h" #include #include #include #include #include #include #include #include "common.h" // jidEncode #include "profiles.h" //---------------------------------------------------------------------------- // VCardFactory //---------------------------------------------------------------------------- class VCardFactoryPrivate : public QObject { Q_OBJECT private: static const uint dictSize; static QStringList vcardList; static QDict *vcardDict; public slots: void taskFinished(); signals: void vcardChanged(const Jid&); public: VCardFactoryPrivate(); ~VCardFactoryPrivate(); static QDict *vcards(); static void checkLimit(QString jid, VCard *vcard); }; const uint VCardFactoryPrivate::dictSize = 5; // don't cache too many vCards at a time QDict *VCardFactoryPrivate::vcardDict = 0; QStringList VCardFactoryPrivate::vcardList; VCardFactoryPrivate::VCardFactoryPrivate() : QObject(qApp, "VCardFactoryPrivate") { vcardDict = new QDict; vcardDict->setAutoDelete(true); } VCardFactoryPrivate::~VCardFactoryPrivate() { delete vcardDict; } QDict *VCardFactoryPrivate::vcards() { return vcardDict; } void VCardFactoryPrivate::checkLimit(QString jid, VCard *vcard) { if ( vcardList.find(jid) != vcardList.end() ) { vcardDict->remove(jid); vcardList.remove(jid); } else if ( vcardList.size() > dictSize ) { vcardDict->remove( vcardList.back() ); vcardList.pop_back(); } vcardDict->insert(jid, vcard); vcardList.push_front(jid); } void VCardFactoryPrivate::taskFinished() { JT_VCard *task = (JT_VCard *)sender(); if ( task->success() ) { Jid j = task->jid(); VCard *vcard = new VCard; *vcard = task->vcard(); checkLimit(j.userHost(), vcard); // save vCard to disk // ensure that there's a vcard directory to save into QDir p(pathToProfile(activeProfile)); QDir v(pathToProfile(activeProfile) + "/vcard"); if(!v.exists()) p.mkdir("vcard"); QFile file ( getVCardDir() + "/" + jidEncode(j.userHost()).lower() + ".xml" ); file.open ( IO_WriteOnly ); QTextStream out ( &file ); out.setEncoding ( QTextStream::UnicodeUTF8 ); QDomDocument doc; doc.appendChild( vcard->toXml ( &doc ) ); out << doc.toString(4); emit vcardChanged(j); } } static VCardFactoryPrivate *vcardFactoryPrivate = 0; const VCard *VCardFactory::vcard(const Jid &j) { if ( !vcardFactoryPrivate ) vcardFactoryPrivate = new VCardFactoryPrivate; // first, try to get vCard from runtime cache QDict *vcards = VCardFactoryPrivate::vcards(); if ( vcards->find( j.userHost() ) ) return vcards->find( j.userHost() ); // then try to load from cache on disk QFile file ( getVCardDir() + "/" + jidEncode(j.userHost()).lower() + ".xml" ); file.open (IO_ReadOnly); QDomDocument doc; VCard *vcard = new VCard; if ( doc.setContent(&file, false) ) { vcard->fromXml( doc.documentElement() ); VCardFactoryPrivate::checkLimit(j.userHost(), vcard); return vcard; } delete vcard; return 0; } void VCardFactory::setVCard(const Jid &j, const VCard &v) { if ( !vcardFactoryPrivate ) vcardFactoryPrivate = new VCardFactoryPrivate; VCard *vcard = new VCard; *vcard = v; VCardFactoryPrivate::checkLimit(j.userHost(), vcard); } JT_VCard *VCardFactory::getVCard(const Jid &jid, Task *rootTask, const QObject *obj, const char *slot, bool cacheVCard) { if ( !vcardFactoryPrivate ) vcardFactoryPrivate = new VCardFactoryPrivate; JT_VCard *task = new JT_VCard( rootTask ); if ( cacheVCard ) task->connect(task, SIGNAL(finished()), vcardFactoryPrivate, SLOT(taskFinished())); task->connect(task, SIGNAL(finished()), obj, slot); task->get(jid); task->go(true); return task; } void VCardFactory::registerVCardChanged(const QObject* obj, const char* slot) { if ( !vcardFactoryPrivate ) vcardFactoryPrivate = new VCardFactoryPrivate; QObject::connect(vcardFactoryPrivate,SIGNAL(vcardChanged(const Jid&)),obj,slot); } #include"vcardfactory.moc"