2
This file is part of kdepim.
3
Copyright (c) 2009 Kevin Krammer <kevin.krammer@gmx.at>
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to
17
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
Boston, MA 02110-1301, USA.
21
#include "abstractsubresourcemodel.h"
23
#include "concurrentjobs.h"
24
#include "itemfetchadapter.h"
26
#include <akonadi/collectionfetchjob.h>
27
#include <akonadi/itemfetchjob.h>
28
#include <akonadi/itemfetchscope.h>
29
#include <akonadi/mimetypechecker.h>
30
#include <akonadi/monitor.h>
35
#include <QtCore/QHash>
36
#include <QtCore/QStringList>
38
using namespace Akonadi;
40
class AbstractSubResourceModel::AsyncLoadContext
43
explicit AsyncLoadContext( AbstractSubResourceModel *parent )
44
: mColFetchJob( 0 ), mResult( true )
46
mColFetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive );
48
connect( mColFetchJob, SIGNAL( collectionsReceived( Akonadi::Collection::List ) ),
49
parent, SLOT( asyncCollectionsReceived( Akonadi::Collection::List ) ) );
50
connect( mColFetchJob, SIGNAL( result( KJob* ) ),
51
parent, SLOT( asyncCollectionsResult( KJob* ) ) );
58
qDeleteAll( mItemFetchJobs );
62
CollectionFetchJob *mColFetchJob;
64
QSet<ItemFetchAdapter*> mItemFetchJobs;
70
AbstractSubResourceModel::AbstractSubResourceModel( const QStringList &supportedMimeTypes, QObject *parent )
72
mMonitor( new Monitor( this ) ),
73
mMimeChecker( new MimeTypeChecker() ),
74
mAsyncLoadContext( 0 )
76
mMimeChecker->setWantedMimeTypes( supportedMimeTypes );
78
mMonitor->blockSignals( true );
80
foreach ( const QString &mimeType, supportedMimeTypes ) {
81
mMonitor->setMimeTypeMonitored( mimeType );
84
mMonitor->setCollectionMonitored( Akonadi::Collection::root() );
85
mMonitor->fetchCollection( true );
86
mMonitor->itemFetchScope().fetchFullPayload();
88
connect( mMonitor, SIGNAL( collectionAdded( Akonadi::Collection, Akonadi::Collection ) ),
89
SLOT( monitorCollectionAdded( Akonadi::Collection ) ) );
90
connect( mMonitor, SIGNAL( collectionChanged( Akonadi::Collection ) ),
91
SLOT( monitorCollectionChanged( Akonadi::Collection ) ) );
92
connect( mMonitor, SIGNAL( collectionRemoved( Akonadi::Collection ) ),
93
SLOT( monitorCollectionRemoved( Akonadi::Collection ) ) );
95
connect( mMonitor, SIGNAL( itemAdded( Akonadi::Item, Akonadi::Collection ) ),
96
SLOT( monitorItemAdded( Akonadi::Item, Akonadi::Collection ) ) );
97
connect( mMonitor, SIGNAL( itemChanged( Akonadi::Item, QSet<QByteArray> ) ),
98
SLOT( monitorItemChanged( Akonadi::Item ) ) );
99
connect( mMonitor, SIGNAL( itemRemoved( Akonadi::Item ) ),
100
SLOT( monitorItemRemoved( Akonadi::Item ) ) );
103
AbstractSubResourceModel::~AbstractSubResourceModel()
105
delete mAsyncLoadContext;
109
QStringList AbstractSubResourceModel::subResourceIdentifiers() const
111
return mSubResourceIdentifiers.toList();
114
void AbstractSubResourceModel::startMonitoring()
116
mMonitor->blockSignals( false );
119
void AbstractSubResourceModel::stopMonitoring()
121
mMonitor->blockSignals( true );
124
void AbstractSubResourceModel::clear()
128
mSubResourceIdentifiers.clear();
131
bool AbstractSubResourceModel::load()
133
ConcurrentCollectionFetchJob colFetchJob;
135
if ( !colFetchJob.exec() ) {
136
kError( 5650 ) << "Loading collections failed:" << colFetchJob->errorString();
137
emit loadingResult( false, colFetchJob->errorString() );
141
const Collection::List collections = colFetchJob->collections();
142
foreach ( const Collection &collection, collections ) {
143
if ( mMimeChecker->isWantedCollection( collection ) ) {
144
collectionAdded( collection );
145
mMonitor->setCollectionMonitored( collection );
146
ConcurrentItemFetchJob itemFetchJob( collection );
147
if ( !itemFetchJob.exec() ) {
148
kError( 5650 ) << "Loading items for collection (id=" << collection.id()
149
<< ", remoteId=" << collection.remoteId()
150
<< "failed:" << itemFetchJob->errorString();
151
emit loadingResult( false, itemFetchJob->errorString() );
155
const Item::List items = itemFetchJob->items();
156
foreach ( const Item &item, items ) {
157
if ( mMimeChecker->isWantedItem( item ) ) {
158
itemAdded( item, collection );
164
emit loadingResult( true, QString() );
168
bool AbstractSubResourceModel::asyncLoad()
170
if ( mAsyncLoadContext != 0 ) {
171
const QString message = i18nc( "@info:status", "Loading already in progress" );
172
emit loadingResult( false, message );
176
mAsyncLoadContext = new AsyncLoadContext( this );
181
void AbstractSubResourceModel::monitorCollectionAdded( const Akonadi::Collection &collection )
183
// TODO check whether we need to do something while an async load is in progress
184
if ( mMimeChecker->isWantedCollection( collection ) ) {
185
collectionAdded( collection );
189
void AbstractSubResourceModel::monitorCollectionChanged( const Akonadi::Collection &collection )
191
// TODO check whether we need to do something while an async load is in progress
192
if ( mMimeChecker->isWantedCollection( collection ) ) {
193
collectionChanged( collection );
197
void AbstractSubResourceModel::monitorCollectionRemoved( const Akonadi::Collection &collection )
199
// TODO check whether we need to do something while an async load is in progress
200
mMonitor->setCollectionMonitored( collection, false );
201
collectionRemoved( collection );
204
void AbstractSubResourceModel::monitorItemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
206
// TODO check whether we need to do something while an async load is in progress
207
if ( mMimeChecker->isWantedItem( item ) ) {
208
itemAdded( item, collection );
212
void AbstractSubResourceModel::monitorItemChanged( const Akonadi::Item &item )
214
// TODO check whether we need to do something while an async load is in progress
215
if ( mMimeChecker->isWantedItem( item ) ) {
220
void AbstractSubResourceModel::monitorItemRemoved( const Akonadi::Item &item )
222
// TODO check whether we need to do something while an async load is in progress
223
if ( mMimeChecker->isWantedItem( item ) ) {
228
void AbstractSubResourceModel::asyncCollectionsReceived( const Akonadi::Collection::List &collections )
230
AsyncLoadContext *context = mAsyncLoadContext;
231
if ( context == 0 ) {
235
foreach ( const Collection &collection, collections ) {
236
if ( mMimeChecker->isWantedCollection( collection ) ) {
237
collectionAdded( collection );
238
mMonitor->setCollectionMonitored( collection );
240
context->mItemFetchJobs.insert( new ItemFetchAdapter( collection, this ) );
245
void AbstractSubResourceModel::asyncCollectionsResult( KJob *job )
247
AsyncLoadContext *context = mAsyncLoadContext;
248
if ( context == 0 ) {
252
Q_ASSERT( job == context->mColFetchJob );
254
context->mColFetchJob = 0;
256
if ( job->error() != 0 ) {
257
mAsyncLoadContext = 0;
259
kError( 5650 ) << "Loading collections failed:" << job->errorString();
260
emit loadingResult( false, job->errorString() );
266
if ( context->mItemFetchJobs.isEmpty() ) {
267
mAsyncLoadContext = 0;
269
emit loadingResult( true, QString() );
275
void AbstractSubResourceModel::asyncItemsReceived( const Akonadi::Collection &collection, const Akonadi::Item::List &items )
277
foreach ( const Item &item, items ) {
278
if ( mMimeChecker->isWantedItem( item ) ) {
279
itemAdded( item, collection );
284
void AbstractSubResourceModel::asyncItemsResult( ItemFetchAdapter *fetcher, KJob *job )
286
AsyncLoadContext *context = mAsyncLoadContext;
287
if ( context == 0 ) {
291
context->mItemFetchJobs.remove( fetcher );
293
if ( job->error() != 0 ) {
294
mAsyncLoadContext = 0;
296
const Collection collection = fetcher->collection();
297
kError( 5650 ) << "Loading items for collection (id=" << collection.id()
298
<< ", remoteId=" << collection.remoteId()
299
<< "failed:" << job->errorString();
300
emit loadingResult( false, job->errorString() );
306
if ( context->mColFetchJob == 0 && mAsyncLoadContext->mItemFetchJobs.isEmpty() ) {
307
mAsyncLoadContext = 0;
309
emit loadingResult( true, QString() );
315
#include "abstractsubresourcemodel.moc"
317
// kate: space-indent on; indent-width 2; replace-tabs on;