• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

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( const Akonadi::Collection& ) ),
00054                     q, SLOT( collectionRemoved( const Akonadi::Collection& ) ) );
00055   QObject::connect( mMonitor, SIGNAL( collectionStatisticsChanged( Akonadi::Collection::Id, const Akonadi::CollectionStatistics& ) ),
00056                     q, SLOT( collectionStatisticsChanged( Akonadi::Collection::Id, const Akonadi::CollectionStatistics& ) ) );
00057 }
00058 
00059 SpecialCollectionsPrivate::~SpecialCollectionsPrivate()
00060 {
00061 }
00062 
00063 QString SpecialCollectionsPrivate::defaultResourceId() const
00064 {
00065   mSettings->readConfig();
00066   const KConfigSkeletonItem *item = mSettings->findItem( QLatin1String( "DefaultResourceId" ) );
00067   Q_ASSERT( item );
00068 
00069   mDefaultResourceId = item->property().toString();
00070   return mDefaultResourceId;
00071 }
00072 
00073 void SpecialCollectionsPrivate::emitChanged( const QString &resourceId )
00074 {
00075   if ( mBatchMode ) {
00076     mToEmitChangedFor.insert( resourceId );
00077   } else {
00078     kDebug() << "Emitting changed for" << resourceId;
00079     const AgentInstance agentInstance = AgentManager::self()->instance( resourceId );
00080     emit q->collectionsChanged( agentInstance );
00081     // first compare with local value then with config value (which also updates the local value)
00082     if ( resourceId == mDefaultResourceId || resourceId == defaultResourceId() ) {
00083       kDebug() << "Emitting defaultFoldersChanged.";
00084       emit q->defaultCollectionsChanged();
00085     }
00086   }
00087 }
00088 
00089 void SpecialCollectionsPrivate::collectionRemoved( const Collection &collection )
00090 {
00091   kDebug() << "Collection" << collection.id() << "resource" << collection.resource();
00092   if ( mFoldersForResource.contains( collection.resource() ) ) {
00093 
00094     // Retrieve the list of special folders for the resource the collection belongs to
00095     QHash<QByteArray, Collection> &folders = mFoldersForResource[ collection.resource() ];
00096     {
00097       QMutableHashIterator<QByteArray, Collection> it( folders );
00098       while ( it.hasNext() ) {
00099         it.next();
00100         if ( it.value() == collection ) {
00101           // The collection to be removed is a special folder
00102           it.remove();
00103           emitChanged( collection.resource() );
00104         }
00105       }
00106     }
00107 
00108     if ( folders.isEmpty() ) {
00109       // This resource has no more folders, so remove it completely.
00110       mFoldersForResource.remove( collection.resource() );
00111     }
00112   }
00113 }
00114 
00115 void SpecialCollectionsPrivate::collectionStatisticsChanged( Akonadi::Collection::Id collectionId, const Akonadi::CollectionStatistics &statistics )
00116 {
00117   // need to get the name of the collection in order to be able to check if we are storing it,
00118   // but we have the id from the monitor, so fetch the name.
00119   Akonadi::CollectionFetchJob* fetchJob = new Akonadi::CollectionFetchJob( Collection( collectionId ), Akonadi::CollectionFetchJob::Base );
00120   fetchJob->fetchScope().setAncestorRetrieval( Akonadi::CollectionFetchScope::None );
00121   fetchJob->setProperty( "statistics", QVariant::fromValue( statistics ) );
00122 
00123   q->connect( fetchJob, SIGNAL( result( KJob* ) ), q, SLOT( collectionFetchJobFinished( KJob* ) ) );
00124 }
00125 
00126 
00127 void SpecialCollectionsPrivate::collectionFetchJobFinished( KJob* job )
00128 {
00129   if ( job->error() ) {
00130     kWarning() << "Error fetching collection to get name from id for statistics updating in specialcollections!";
00131     return;
00132   }
00133 
00134   const Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job );
00135 
00136   Q_ASSERT( fetchJob->collections().size() > 0 );
00137   const Akonadi::Collection collection = fetchJob->collections().first();
00138   const Akonadi::CollectionStatistics statistics = fetchJob->property( "statistics" ).value<Akonadi::CollectionStatistics>();
00139 
00140   mFoldersForResource[ collection.resource() ][ collection.name().toUtf8() ].setStatistics( statistics );
00141 }
00142 
00143 void SpecialCollectionsPrivate::beginBatchRegister()
00144 {
00145   Q_ASSERT( !mBatchMode );
00146   mBatchMode = true;
00147   Q_ASSERT( mToEmitChangedFor.isEmpty() );
00148 }
00149 
00150 void SpecialCollectionsPrivate::endBatchRegister()
00151 {
00152   Q_ASSERT( mBatchMode );
00153   mBatchMode = false;
00154 
00155   foreach ( const QString &resourceId, mToEmitChangedFor ) {
00156     emitChanged( resourceId );
00157   }
00158 
00159   mToEmitChangedFor.clear();
00160 }
00161 
00162 void SpecialCollectionsPrivate::forgetFoldersForResource( const QString &resourceId )
00163 {
00164   if ( mFoldersForResource.contains( resourceId ) ) {
00165     const Collection::List folders = mFoldersForResource[ resourceId ].values();
00166 
00167     foreach ( const Collection &collection, folders ) {
00168       mMonitor->setCollectionMonitored( collection, false );
00169     }
00170 
00171     mFoldersForResource.remove( resourceId );
00172     emitChanged( resourceId );
00173   }
00174 }
00175 
00176 AgentInstance SpecialCollectionsPrivate::defaultResource() const
00177 {
00178   const QString identifier = defaultResourceId();
00179   return AgentManager::self()->instance( identifier );
00180 }
00181 
00182 
00183 SpecialCollections::SpecialCollections( KCoreConfigSkeleton *settings, QObject *parent )
00184   : QObject( parent ),
00185     d( new SpecialCollectionsPrivate( settings, this ) )
00186 {
00187 }
00188 
00189 SpecialCollections::~SpecialCollections()
00190 {
00191   delete d;
00192 }
00193 
00194 bool SpecialCollections::hasCollection( const QByteArray &type, const AgentInstance &instance ) const
00195 {
00196   kDebug() << "Type" << type << "resourceId" << instance.identifier();
00197 
00198   if ( !d->mFoldersForResource.contains( instance.identifier() ) ) {
00199     // We do not know any folders in this resource.
00200     return false;
00201   }
00202 
00203   return d->mFoldersForResource[ instance.identifier() ].contains( type );
00204 }
00205 
00206 Akonadi::Collection SpecialCollections::collection( const QByteArray &type, const AgentInstance &instance ) const
00207 {
00208   if ( !d->mFoldersForResource.contains( instance.identifier() ) ) {
00209     // We do not know any folders in this resource.
00210     return Collection( -1 );
00211   }
00212   return d->mFoldersForResource[ instance.identifier() ][ type ];
00213 }
00214 
00215 bool SpecialCollections::registerCollection( const QByteArray &type, const Collection &collection )
00216 {
00217   if ( !collection.isValid() ) {
00218     kWarning() << "Invalid collection.";
00219     return false;
00220   }
00221 
00222   const QString &resourceId = collection.resource();
00223   if ( resourceId.isEmpty() ) {
00224     kWarning() << "Collection has empty resourceId.";
00225     return false;
00226   }
00227 
00228   if ( !collection.hasAttribute<SpecialCollectionAttribute>() || collection.attribute<SpecialCollectionAttribute>()->collectionType() != type ) {
00229     Collection attributeCollection( collection );
00230     SpecialCollectionAttribute *attribute = attributeCollection.attribute<SpecialCollectionAttribute>( Collection::AddIfMissing );
00231     attribute->setCollectionType( type );
00232 
00233     new CollectionModifyJob( attributeCollection );
00234   }
00235 
00236   if ( !d->mFoldersForResource.contains( resourceId ) ) {
00237     // We do not know any folders in this resource yet.
00238     d->mFoldersForResource.insert( resourceId, QHash<QByteArray, Collection>() );
00239   }
00240 
00241   if ( !d->mFoldersForResource[ resourceId ].contains( type ) )
00242     d->mFoldersForResource[ resourceId ].insert( type, Collection() );
00243 
00244   if ( d->mFoldersForResource[ resourceId ][ type ] != collection ) {
00245     d->mMonitor->setCollectionMonitored( d->mFoldersForResource[ resourceId ][ type ], false );
00246     d->mMonitor->setCollectionMonitored( collection, true );
00247     d->mFoldersForResource[ resourceId ].insert( type, collection );
00248     d->emitChanged( resourceId );
00249   }
00250 
00251   kDebug() << "Registered collection" << collection.id() << "as folder of type" << type
00252     << "in resource" << resourceId;
00253   return true;
00254 }
00255 
00256 bool SpecialCollections::hasDefaultCollection( const QByteArray &type ) const
00257 {
00258   return hasCollection( type, d->defaultResource() );
00259 }
00260 
00261 Akonadi::Collection SpecialCollections::defaultCollection( const QByteArray &type ) const
00262 {
00263   return collection( type, d->defaultResource() );
00264 }
00265 
00266 #include "specialcollections.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal