• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • 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(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 May 14 2012 04:53:00 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

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

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • 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
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal