akonadi
specialcollections.cpp
00001 /* 00002 Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "specialcollections.h" 00021 00022 #include "specialcollections_p.h" 00023 #include "specialcollectionattribute_p.h" 00024 00025 #include "akonadi/agentinstance.h" 00026 #include "akonadi/agentmanager.h" 00027 #include "akonadi/collectionmodifyjob.h" 00028 #include "akonadi/collectionfetchjob.h" 00029 #include "akonadi/monitor.h" 00030 00031 #include <KDebug> 00032 #include <kcoreconfigskeleton.h> 00033 00034 #include <QtCore/QHash> 00035 #include <QtCore/QObject> 00036 #include <QtCore/QSet> 00037 #include <akonadi/collectionfetchscope.h> 00038 00039 using namespace Akonadi; 00040 00041 SpecialCollectionsPrivate::SpecialCollectionsPrivate( KCoreConfigSkeleton *settings, SpecialCollections *qq ) 00042 : q( qq ), 00043 mSettings( settings ), 00044 mBatchMode( false ) 00045 { 00046 mMonitor = new Monitor( q ); 00047 mMonitor->fetchCollectionStatistics( true ); 00048 00053 QObject::connect( mMonitor, SIGNAL(collectionRemoved(Akonadi::Collection)), 00054 q, SLOT(collectionRemoved(Akonadi::Collection)) ); 00055 QObject::connect( mMonitor, SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)), 00056 q, SLOT(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) ); 00057 } 00058 00059 SpecialCollectionsPrivate::~SpecialCollectionsPrivate() 00060 { 00061 } 00062 00063 QString SpecialCollectionsPrivate::defaultResourceId() const 00064 { 00065 if ( mDefaultResourceId.isEmpty() ) { 00066 mSettings->readConfig(); 00067 const KConfigSkeletonItem *item = mSettings->findItem( QLatin1String( "DefaultResourceId" ) ); 00068 Q_ASSERT( item ); 00069 00070 mDefaultResourceId = item->property().toString(); 00071 } 00072 return mDefaultResourceId; 00073 } 00074 00075 void SpecialCollectionsPrivate::emitChanged( const QString &resourceId ) 00076 { 00077 if ( mBatchMode ) { 00078 mToEmitChangedFor.insert( resourceId ); 00079 } else { 00080 kDebug() << "Emitting changed for" << resourceId; 00081 const AgentInstance agentInstance = AgentManager::self()->instance( resourceId ); 00082 emit q->collectionsChanged( agentInstance ); 00083 // first compare with local value then with config value (which also updates the local value) 00084 if ( resourceId == mDefaultResourceId || resourceId == defaultResourceId() ) { 00085 kDebug() << "Emitting defaultFoldersChanged."; 00086 emit q->defaultCollectionsChanged(); 00087 } 00088 } 00089 } 00090 00091 void SpecialCollectionsPrivate::collectionRemoved( const Collection &collection ) 00092 { 00093 kDebug() << "Collection" << collection.id() << "resource" << collection.resource(); 00094 if ( mFoldersForResource.contains( collection.resource() ) ) { 00095 00096 // Retrieve the list of special folders for the resource the collection belongs to 00097 QHash<QByteArray, Collection> &folders = mFoldersForResource[ collection.resource() ]; 00098 { 00099 QMutableHashIterator<QByteArray, Collection> it( folders ); 00100 while ( it.hasNext() ) { 00101 it.next(); 00102 if ( it.value() == collection ) { 00103 // The collection to be removed is a special folder 00104 it.remove(); 00105 emitChanged( collection.resource() ); 00106 } 00107 } 00108 } 00109 00110 if ( folders.isEmpty() ) { 00111 // This resource has no more folders, so remove it completely. 00112 mFoldersForResource.remove( collection.resource() ); 00113 } 00114 } 00115 } 00116 00117 void SpecialCollectionsPrivate::collectionStatisticsChanged( Akonadi::Collection::Id collectionId, const Akonadi::CollectionStatistics &statistics ) 00118 { 00119 // need to get the name of the collection in order to be able to check if we are storing it, 00120 // but we have the id from the monitor, so fetch the name. 00121 Akonadi::CollectionFetchJob* fetchJob = new Akonadi::CollectionFetchJob( Collection( collectionId ), Akonadi::CollectionFetchJob::Base ); 00122 fetchJob->fetchScope().setAncestorRetrieval( Akonadi::CollectionFetchScope::None ); 00123 fetchJob->setProperty( "statistics", QVariant::fromValue( statistics ) ); 00124 00125 q->connect( fetchJob, SIGNAL(result(KJob*)), q, SLOT(collectionFetchJobFinished(KJob*)) ); 00126 } 00127 00128 00129 void SpecialCollectionsPrivate::collectionFetchJobFinished( KJob* job ) 00130 { 00131 if ( job->error() ) { 00132 kWarning() << "Error fetching collection to get name from id for statistics updating in specialcollections!"; 00133 return; 00134 } 00135 00136 const Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job ); 00137 00138 Q_ASSERT( fetchJob->collections().size() > 0 ); 00139 const Akonadi::Collection collection = fetchJob->collections().first(); 00140 const Akonadi::CollectionStatistics statistics = fetchJob->property( "statistics" ).value<Akonadi::CollectionStatistics>(); 00141 00142 mFoldersForResource[ collection.resource() ][ collection.name().toUtf8() ].setStatistics( statistics ); 00143 } 00144 00145 void SpecialCollectionsPrivate::beginBatchRegister() 00146 { 00147 Q_ASSERT( !mBatchMode ); 00148 mBatchMode = true; 00149 Q_ASSERT( mToEmitChangedFor.isEmpty() ); 00150 } 00151 00152 void SpecialCollectionsPrivate::endBatchRegister() 00153 { 00154 Q_ASSERT( mBatchMode ); 00155 mBatchMode = false; 00156 00157 foreach ( const QString &resourceId, mToEmitChangedFor ) { 00158 emitChanged( resourceId ); 00159 } 00160 00161 mToEmitChangedFor.clear(); 00162 } 00163 00164 void SpecialCollectionsPrivate::forgetFoldersForResource( const QString &resourceId ) 00165 { 00166 if ( mFoldersForResource.contains( resourceId ) ) { 00167 const Collection::List folders = mFoldersForResource[ resourceId ].values(); 00168 00169 foreach ( const Collection &collection, folders ) { 00170 mMonitor->setCollectionMonitored( collection, false ); 00171 } 00172 00173 mFoldersForResource.remove( resourceId ); 00174 emitChanged( resourceId ); 00175 } 00176 } 00177 00178 AgentInstance SpecialCollectionsPrivate::defaultResource() const 00179 { 00180 const QString identifier = defaultResourceId(); 00181 return AgentManager::self()->instance( identifier ); 00182 } 00183 00184 00185 SpecialCollections::SpecialCollections( KCoreConfigSkeleton *settings, QObject *parent ) 00186 : QObject( parent ), 00187 d( new SpecialCollectionsPrivate( settings, this ) ) 00188 { 00189 } 00190 00191 SpecialCollections::~SpecialCollections() 00192 { 00193 delete d; 00194 } 00195 00196 bool SpecialCollections::hasCollection( const QByteArray &type, const AgentInstance &instance ) const 00197 { 00198 00199 if ( !d->mFoldersForResource.contains( instance.identifier() ) ) { 00200 // We do not know any folders in this resource. 00201 return false; 00202 } 00203 00204 return d->mFoldersForResource[ instance.identifier() ].contains( type ); 00205 } 00206 00207 Akonadi::Collection SpecialCollections::collection( const QByteArray &type, const AgentInstance &instance ) const 00208 { 00209 if ( !d->mFoldersForResource.contains( instance.identifier() ) ) { 00210 // We do not know any folders in this resource. 00211 return Collection( -1 ); 00212 } 00213 return d->mFoldersForResource[ instance.identifier() ][ type ]; 00214 } 00215 00216 bool SpecialCollections::registerCollection( const QByteArray &type, const Collection &collection ) 00217 { 00218 if ( !collection.isValid() ) { 00219 kWarning() << "Invalid collection."; 00220 return false; 00221 } 00222 00223 const QString &resourceId = collection.resource(); 00224 if ( resourceId.isEmpty() ) { 00225 kWarning() << "Collection has empty resourceId."; 00226 return false; 00227 } 00228 00229 if ( !collection.hasAttribute<SpecialCollectionAttribute>() || collection.attribute<SpecialCollectionAttribute>()->collectionType() != type ) { 00230 Collection attributeCollection( collection ); 00231 SpecialCollectionAttribute *attribute = attributeCollection.attribute<SpecialCollectionAttribute>( Collection::AddIfMissing ); 00232 attribute->setCollectionType( type ); 00233 00234 new CollectionModifyJob( attributeCollection ); 00235 } 00236 00237 if ( !d->mFoldersForResource.contains( resourceId ) ) { 00238 // We do not know any folders in this resource yet. 00239 d->mFoldersForResource.insert( resourceId, QHash<QByteArray, Collection>() ); 00240 } 00241 00242 if ( !d->mFoldersForResource[ resourceId ].contains( type ) ) 00243 d->mFoldersForResource[ resourceId ].insert( type, Collection() ); 00244 00245 if ( d->mFoldersForResource[ resourceId ][ type ] != collection ) { 00246 d->mMonitor->setCollectionMonitored( d->mFoldersForResource[ resourceId ][ type ], false ); 00247 d->mMonitor->setCollectionMonitored( collection, true ); 00248 d->mFoldersForResource[ resourceId ].insert( type, collection ); 00249 d->emitChanged( resourceId ); 00250 } 00251 00252 return true; 00253 } 00254 00255 bool SpecialCollections::hasDefaultCollection( const QByteArray &type ) const 00256 { 00257 return hasCollection( type, d->defaultResource() ); 00258 } 00259 00260 Akonadi::Collection SpecialCollections::defaultCollection( const QByteArray &type ) const 00261 { 00262 return collection( type, d->defaultResource() ); 00263 } 00264 00265 #include "specialcollections.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:16 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:16 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.