📄 contactxmlio.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info\@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <qtopia/global.h>#include <qtopia/qpeapplication.h>#include "contact.h"#include "contactxmlio_p.h"#include <qtopia/config.h>#include <qtopia/stringutil.h>#ifdef Q_WS_QWS#include <qtopia/qcopenvelope_qws.h>#endif#include <qapplication.h>#include <qfileinfo.h>#include <qfile.h>#include <qasciidict.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#ifdef Q_OS_WIN32#include <process.h>#else#include <unistd.h>#endifvoid removeBusinessCard();void updateBusinessCard(const PimContact &);SortedContacts::SortedContacts() : SortedRecords<PimContact>(){}SortedContacts::SortedContacts(uint s) : SortedRecords<PimContact>(s){}SortedContacts::~SortedContacts() {}int SortedContacts::compareItems(QCollection::Item d1, QCollection::Item d2){ PrContact *pc1 = (PrContact *)d1; PrContact *pc2 = (PrContact *)d2; if ( mKey == -1 ) return 0; QString key1, key2; if ( mKey >= PimContact::ContactFieldsEnd ) { key1 = pc1->bestLabel().lower(); key2 = pc2->bestLabel().lower(); } else { key1 = pc1->field( mKey ).lower(); key2 = pc2->field( mKey ).lower(); } if ( mAscending ) return -( Qtopia::compare(key1, key2) ); return Qtopia::compare(key1, key2);}ContactXmlIO::ContactXmlIO(AccessMode m, const QString &file, const QString &journal ) : ContactIO(m), PimXmlIO(PimContact::keyToIdentifierMap(), PimContact::identifierToKeyMap() ), cFilter(-2), needsSave(FALSE){ if ( file != QString::null ) setDataFilename( file ); else setDataFilename( Global::applicationFileName( "addressbook", "addressbook.xml" ) ); if ( journal != QString::null ) setJournalFilename( journal ); else setJournalFilename( Global::journalFileName( ".abjournal" ) ); m_Contacts.setAutoDelete(TRUE); loadData();#ifndef QT_NO_COP if (m == ReadOnly) { QCopChannel *channel = new QCopChannel( "QPE/PIM", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(pimMessage(const QCString&, const QByteArray&)) ); }#endif}void ContactXmlIO::pimMessage(const QCString &message, const QByteArray &data){ QDataStream ds(data, IO_ReadOnly); if (message == "addedContact(int,PimContact)") { int pid; PimContact contact; ds >> pid; ds >> contact; if (pid != getpid()) { internalAddRecord(new PimContact(contact)); emit contactsUpdated(); } } else if (message == "removedContact(int,PimContact)") { int pid; PimContact contact; ds >> pid; ds >> contact; if (pid != getpid()) { internalRemoveRecord(new PimContact(contact)); emit contactsUpdated(); } } else if (message == "updatedContact(int,PimContact)") { int pid; PimContact contact; ds >> pid; ds >> contact; if (pid != getpid()) { internalUpdateRecord(new PimContact(contact)); emit contactsUpdated(); } } else if (message == "reloadContacts()") { ensureDataCurrent(); } else if (message == "reload(int)") { int force; ds >> force; ensureDataCurrent(force); }}ContactXmlIO::~ContactXmlIO(){ saveData();}bool ContactXmlIO::loadData(){ if (PimXmlIO::loadData()) { m_Filtered.sort(); emit contactsUpdated(); return TRUE; } return FALSE;}bool ContactXmlIO::internalAddRecord(PimRecord *r){ PrContact *cnt = (PrContact *)r; m_Contacts.append( cnt ); if (select(*cnt)) m_Filtered.append( cnt ); return TRUE;}bool ContactXmlIO::internalRemoveRecord(PimRecord *r){ PrContact *cnt = (PrContact *)r; for (m_Contacts.first(); m_Contacts.current(); m_Contacts.next()) { if (m_Contacts.current()->uid() == cnt->uid()) { if ( select( *(m_Contacts.current()) ) ) { m_Filtered.remove(m_Contacts.current()); } m_Contacts.remove(); delete cnt; return TRUE; } } delete cnt; return FALSE;}bool ContactXmlIO::internalUpdateRecord(PimRecord *r){ PrContact *cnt = (PrContact *)r; for (m_Contacts.first(); m_Contacts.current(); m_Contacts.next()) { PrContact *current = m_Contacts.current(); if (current->uid() == cnt->uid()) { if ( select(*current) ) { m_Filtered.remove(current); } if ( current != cnt ) { *current = *cnt; delete cnt; } if (select(*current)) { m_Filtered.append(current); } return TRUE; } } delete cnt; return FALSE;}/** * Returns the full contact list. This is guaranteed * to be current against what is stored by other apps. */const QList<PrContact>& ContactXmlIO::contacts() { ensureDataCurrent(); return m_Contacts;}const SortedContacts& ContactXmlIO::sortedContacts() { ensureDataCurrent(); return m_Filtered;}PrContact ContactXmlIO::contactForId( const QUuid &u, bool *ok ) const{ QListIterator<PrContact> it(m_Contacts); PrContact *p; for (; it.current(); ++it ) { p = *it; if (u == p->uid()) { if (ok) *ok = TRUE; return *p; } } if (ok) *ok = FALSE; return PrContact();}/** * Saves the current contact data. Returns true if * successful. */bool ContactXmlIO::saveData(){ if ( !QFile::exists( dataFilename() ) || QFile::exists( journalFilename() ) ) needsSave = TRUE; if (!needsSave) return TRUE; if (accessMode() != ReadOnly ) { if (PimXmlIO::saveData((QList<PimRecord> &)m_Contacts)) { needsSave = FALSE; return TRUE; } } return FALSE;}void ContactXmlIO::clear(){ cFilter = -2; m_Filtered.clear(); m_Contacts.clear(); needsSave = TRUE;}void ContactXmlIO::setContacts( const QValueList<PimContact> &l ){ clear(); for ( QValueList<PimContact>::ConstIterator it = l.begin(); it != l.end(); ++it ) { PrContact *cnt = new PrContact(*it); m_Contacts.append( cnt ); m_Filtered.append( cnt ); } m_Filtered.sort();}QUuid ContactXmlIO::addContact(const PimContact &contact, bool newUid ){ QUuid u; if (accessMode() == ReadOnly) return u; PrContact *cnt = new PrContact((const PrContact &)contact); if (cnt->customField("BusinessCard") == "TRUE") { // set the config. updateBusinessCard(*cnt); } if ( newUid || cnt->uid().isNull() ) assignNewUid(cnt); u = cnt->uid(); if (internalAddRecord(cnt )) { needsSave = TRUE; m_Filtered.sort(); updateJournal(*cnt, ACTION_ADD);#ifndef QT_NO_COP { QCopEnvelope e("QPE/PIM", "addedContact(int,PimContact)"); e << getpid(); e << *cnt; }#endif } return u;}bool ContactXmlIO::removeContact(const PimContact &contact){ if (accessMode() == ReadOnly) return FALSE; PrContact *cnt = new PrContact((const PrContact &)contact); if (cnt->customField("BusinessCard") == "TRUE") { // set the config. removeBusinessCard(); } if ( !internalRemoveRecord(cnt) ) return FALSE; needsSave = TRUE; m_Filtered.sort(); updateJournal(contact, ACTION_REMOVE);#ifndef QT_NO_COP { QCopEnvelope e("QPE/PIM", "removedContact(int,PimContact)"); e << getpid(); e << contact; }#endif return TRUE;}void ContactXmlIO::updateContact(const PimContact &contact){ if (accessMode() == ReadOnly) return; PrContact *cnt = new PrContact((const PrContact &)contact); if (cnt->customField("BusinessCard") == "TRUE") { // set the config. updateBusinessCard(*cnt); } if (internalUpdateRecord(cnt)) { needsSave = TRUE; m_Filtered.sort(); updateJournal(contact, ACTION_REPLACE);#ifndef QT_NO_COP { QCopEnvelope e("QPE/PIM", "updatedContact(int,PimContact)"); e << getpid(); e << contact; }#endif }}// conservative on the yes vote.bool ContactXmlIO::contains( const PimContact &c ) const{ //### FIXME: this should use the Qtopia Desktop match algorithm; // this probably will require some code reorganization QString regExp(c.fileAs()); QListIterator<PrContact> it(m_Contacts); for (; it.current(); ++it) { if ( !c.uid().isNull() && it.current()->uid() == c.uid() ) return TRUE; //expensive compare; but rich text is only done if match passes else if ( it.current()->match(regExp) && (c.toRichText() == (*it)->toRichText() ) ) return TRUE; } return FALSE;}void ContactXmlIO::ensureDataCurrent(bool forceReload){ if (accessMode() == WriteOnly || ( isDataCurrent() && !forceReload) ) return; qDebug("ContactXmlIO: Reloading data..."); m_Contacts.clear(); m_Filtered.clear(); loadData();}bool ContactXmlIO::select(const PrContact &c) const{ // -1 is unfiled // -2 is all QArray<int> cats = c.categories(); if ( cFilter == -1 ) { if ( cats.count() > 0 ) return FALSE; } else if ( cFilter != -2 ) { if (cats.find(cFilter) == -1) return FALSE; } return TRUE;}int ContactXmlIO::filter() const{ return cFilter;}void ContactXmlIO::setFilter(int f) { if (f != cFilter) { cFilter = f; m_Filtered.clear(); for (m_Contacts.first(); m_Contacts.current(); m_Contacts.next()) { PrContact *cnt = m_Contacts.current(); if (select(*cnt)) { m_Filtered.append(cnt); } } m_Filtered.sort(); }}int ContactXmlIO::sortKey() const{ return m_Filtered.sortKey();}bool ContactXmlIO::sortAcending() const{ return m_Filtered.ascending();}void ContactXmlIO::setSorting(int key, bool ascending){ if (key != m_Filtered.sortKey() || ascending != m_Filtered.ascending() ) { m_Filtered.setSorting( key, ascending ); m_Filtered.sort(); }}PrContact ContactXmlIO::personal() const{ QListIterator<PrContact> it(m_Contacts); for (; it.current(); ++it) { if (it.current()->customField("BusinessCard") == "TRUE") return PrContact(*(it.current())); } return PrContact();}// ### slow, but safe for nowbool ContactXmlIO::hasPersonal() const{ return !personal().uid().isNull();}void ContactXmlIO::setAsPersonal(const QUuid &u){ if (u.isNull()) return; PrContact oldBC; PrContact newBC; bool foundOld = FALSE; bool foundNew = FALSE; QListIterator<PrContact> it(m_Contacts); for (; it.current(); ++it) { if (it.current()->customField("BusinessCard") == "TRUE") { oldBC = *(it.current()); foundOld = TRUE; } if (it.current()->uid() == u) { newBC = *(it.current()); foundNew = TRUE; } } if (newBC.uid() != oldBC.uid()) { if (foundNew) { newBC.setCustomField("BusinessCard", "TRUE"); updateContact(newBC); } if (foundOld) { oldBC.removeCustomField("BusinessCard"); updateContact(oldBC); } }}QString businessCardName() { return Global::applicationFileName("addressbook", "businesscard.vcf");}void updateBusinessCard(const PimContact &cnt){ Config cfg( QPEApplication::qpeDir()+"/etc/Security.conf", Config::File ); cfg.setGroup("Sync"); cfg.writeEntry("ownername", cnt.fullName()); PimContact::writeVCard( businessCardName(), cnt);}void removeBusinessCard(){ Config cfg( QPEApplication::qpeDir()+"/etc/Security.conf", Config::File ); cfg.setGroup("Sync"); cfg.writeEntry("ownername", ""); QFile::remove( businessCardName() );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -