~ubuntu-branches/ubuntu/karmic/kdepim/karmic-backports

« back to all changes in this revision

Viewing changes to akonadi/kresources/shared/abstractsubresourcemodel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Harald Sitter
  • Date: 2009-06-27 04:40:05 UTC
  • mfrom: (1.1.39 upstream)
  • Revision ID: james.westby@ubuntu.com-20090627044005-4y2vm9xz7rvmzi4p
Tags: 4:4.2.95svn20090701-0ubuntu1
[ Alessandro Ghersi ]
* New upstream release
  - Bump build-deps
* Remove akonadi-kde and libmaildir4 packages
  - remove akonadi-kde.install and libmaildir4.install
  - remove libmaildir4 from debian/rules
  - remove akonadi-kde and libmaildir4 from depends
  - remove akonadi-kde and libmaildir4 from installgen
* Update kdepim-dev.install
* Update kpilot.install
* Add akonadi-kde and libmaildir4 transitional packages

[ Harald Sitter ]
* KAddressbook replaces Kontact << 4.2.85 (LP: #378373)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of kdepim.
 
3
    Copyright (c) 2009 Kevin Krammer <kevin.krammer@gmx.at>
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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.
 
19
*/
 
20
 
 
21
#include "abstractsubresourcemodel.h"
 
22
 
 
23
#include "concurrentjobs.h"
 
24
#include "itemfetchadapter.h"
 
25
 
 
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>
 
31
 
 
32
#include <KDebug>
 
33
#include <KLocale>
 
34
 
 
35
#include <QtCore/QHash>
 
36
#include <QtCore/QStringList>
 
37
 
 
38
using namespace Akonadi;
 
39
 
 
40
class AbstractSubResourceModel::AsyncLoadContext
 
41
{
 
42
  public:
 
43
    explicit AsyncLoadContext( AbstractSubResourceModel *parent )
 
44
      : mColFetchJob( 0 ), mResult( true )
 
45
    {
 
46
      mColFetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive );
 
47
 
 
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* ) ) );
 
52
    }
 
53
 
 
54
    ~AsyncLoadContext()
 
55
    {
 
56
      delete mColFetchJob;
 
57
 
 
58
      qDeleteAll( mItemFetchJobs );
 
59
    }
 
60
 
 
61
  public:
 
62
    CollectionFetchJob *mColFetchJob;
 
63
 
 
64
    QSet<ItemFetchAdapter*> mItemFetchJobs;
 
65
 
 
66
    bool mResult;
 
67
    QString mErrorString;
 
68
};
 
69
 
 
70
AbstractSubResourceModel::AbstractSubResourceModel( const QStringList &supportedMimeTypes, QObject *parent )
 
71
  : QObject( parent ),
 
72
    mMonitor( new Monitor( this ) ),
 
73
    mMimeChecker( new MimeTypeChecker() ),
 
74
    mAsyncLoadContext( 0 )
 
75
{
 
76
  mMimeChecker->setWantedMimeTypes( supportedMimeTypes );
 
77
 
 
78
  mMonitor->blockSignals( true );
 
79
 
 
80
  foreach ( const QString &mimeType, supportedMimeTypes ) {
 
81
    mMonitor->setMimeTypeMonitored( mimeType );
 
82
  }
 
83
 
 
84
  mMonitor->setCollectionMonitored( Akonadi::Collection::root() );
 
85
  mMonitor->fetchCollection( true );
 
86
  mMonitor->itemFetchScope().fetchFullPayload();
 
87
 
 
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 ) ) );
 
94
 
 
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 ) ) );
 
101
}
 
102
 
 
103
AbstractSubResourceModel::~AbstractSubResourceModel()
 
104
{
 
105
  delete mAsyncLoadContext;
 
106
  delete mMimeChecker;
 
107
}
 
108
 
 
109
QStringList AbstractSubResourceModel::subResourceIdentifiers() const
 
110
{
 
111
  return mSubResourceIdentifiers.toList();
 
112
}
 
113
 
 
114
void AbstractSubResourceModel::startMonitoring()
 
115
{
 
116
  mMonitor->blockSignals( false );
 
117
}
 
118
 
 
119
void AbstractSubResourceModel::stopMonitoring()
 
120
{
 
121
  mMonitor->blockSignals( true );
 
122
}
 
123
 
 
124
void AbstractSubResourceModel::clear()
 
125
{
 
126
  clearModel();
 
127
 
 
128
  mSubResourceIdentifiers.clear();
 
129
}
 
130
 
 
131
bool AbstractSubResourceModel::load()
 
132
{
 
133
  ConcurrentCollectionFetchJob colFetchJob;
 
134
 
 
135
  if ( !colFetchJob.exec() ) {
 
136
    kError( 5650 ) << "Loading collections failed:" << colFetchJob->errorString();
 
137
    emit loadingResult( false, colFetchJob->errorString() );
 
138
    return false;
 
139
  }
 
140
 
 
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() );
 
152
        return false;
 
153
      }
 
154
 
 
155
      const Item::List items = itemFetchJob->items();
 
156
      foreach ( const Item &item, items ) {
 
157
        if ( mMimeChecker->isWantedItem( item ) ) {
 
158
          itemAdded( item, collection );
 
159
        }
 
160
      }
 
161
    }
 
162
  }
 
163
 
 
164
  emit loadingResult( true, QString() );
 
165
  return true;
 
166
}
 
167
 
 
168
bool AbstractSubResourceModel::asyncLoad()
 
169
{
 
170
  if ( mAsyncLoadContext != 0 ) {
 
171
    const QString message = i18nc( "@info:status", "Loading already in progress" );
 
172
    emit loadingResult( false, message );
 
173
    return false;
 
174
  }
 
175
 
 
176
  mAsyncLoadContext = new AsyncLoadContext( this );
 
177
 
 
178
  return true;
 
179
}
 
180
 
 
181
void AbstractSubResourceModel::monitorCollectionAdded( const Akonadi::Collection &collection )
 
182
{
 
183
  // TODO check whether we need to do something while an async load is in progress
 
184
  if ( mMimeChecker->isWantedCollection( collection ) ) {
 
185
    collectionAdded( collection );
 
186
  }
 
187
}
 
188
 
 
189
void AbstractSubResourceModel::monitorCollectionChanged( const Akonadi::Collection &collection )
 
190
{
 
191
  // TODO check whether we need to do something while an async load is in progress
 
192
  if ( mMimeChecker->isWantedCollection( collection ) ) {
 
193
    collectionChanged( collection );
 
194
  }
 
195
}
 
196
 
 
197
void AbstractSubResourceModel::monitorCollectionRemoved( const Akonadi::Collection &collection )
 
198
{
 
199
  // TODO check whether we need to do something while an async load is in progress
 
200
  mMonitor->setCollectionMonitored( collection, false );
 
201
  collectionRemoved( collection );
 
202
}
 
203
 
 
204
void AbstractSubResourceModel::monitorItemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
 
205
{
 
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 );
 
209
  }
 
210
}
 
211
 
 
212
void AbstractSubResourceModel::monitorItemChanged( const Akonadi::Item &item )
 
213
{
 
214
  // TODO check whether we need to do something while an async load is in progress
 
215
  if ( mMimeChecker->isWantedItem( item ) ) {
 
216
    itemChanged( item );
 
217
  }
 
218
}
 
219
 
 
220
void AbstractSubResourceModel::monitorItemRemoved( const Akonadi::Item &item )
 
221
{
 
222
  // TODO check whether we need to do something while an async load is in progress
 
223
  if ( mMimeChecker->isWantedItem( item ) ) {
 
224
    itemRemoved( item );
 
225
  }
 
226
}
 
227
 
 
228
void AbstractSubResourceModel::asyncCollectionsReceived( const Akonadi::Collection::List &collections )
 
229
{
 
230
  AsyncLoadContext *context = mAsyncLoadContext;
 
231
  if ( context == 0 ) {
 
232
    return;
 
233
  }
 
234
 
 
235
  foreach ( const Collection &collection, collections ) {
 
236
    if ( mMimeChecker->isWantedCollection( collection ) ) {
 
237
      collectionAdded( collection );
 
238
      mMonitor->setCollectionMonitored( collection );
 
239
 
 
240
      context->mItemFetchJobs.insert( new ItemFetchAdapter( collection, this ) );
 
241
    }
 
242
  }
 
243
}
 
244
 
 
245
void AbstractSubResourceModel::asyncCollectionsResult( KJob *job )
 
246
{
 
247
  AsyncLoadContext *context = mAsyncLoadContext;
 
248
  if ( context == 0 ) {
 
249
    return;
 
250
  }
 
251
 
 
252
  Q_ASSERT( job == context->mColFetchJob );
 
253
 
 
254
  context->mColFetchJob = 0;
 
255
 
 
256
  if ( job->error() != 0 ) {
 
257
    mAsyncLoadContext = 0;
 
258
 
 
259
    kError( 5650 ) << "Loading collections failed:" << job->errorString();
 
260
    emit loadingResult( false, job->errorString() );
 
261
 
 
262
    delete context;
 
263
    return;
 
264
  }
 
265
 
 
266
  if ( context->mItemFetchJobs.isEmpty() ) {
 
267
    mAsyncLoadContext = 0;
 
268
 
 
269
    emit loadingResult( true, QString() );
 
270
 
 
271
    delete context;
 
272
  }
 
273
}
 
274
 
 
275
void AbstractSubResourceModel::asyncItemsReceived( const Akonadi::Collection &collection, const Akonadi::Item::List &items )
 
276
{
 
277
  foreach ( const Item &item, items ) {
 
278
    if ( mMimeChecker->isWantedItem( item ) ) {
 
279
      itemAdded( item, collection );
 
280
    }
 
281
  }
 
282
}
 
283
 
 
284
void AbstractSubResourceModel::asyncItemsResult( ItemFetchAdapter *fetcher, KJob *job )
 
285
{
 
286
  AsyncLoadContext *context = mAsyncLoadContext;
 
287
  if ( context == 0 ) {
 
288
    return;
 
289
  }
 
290
 
 
291
  context->mItemFetchJobs.remove( fetcher );
 
292
 
 
293
  if ( job->error() != 0 ) {
 
294
    mAsyncLoadContext = 0;
 
295
 
 
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() );
 
301
 
 
302
    delete context;
 
303
    return;
 
304
  }
 
305
 
 
306
  if ( context->mColFetchJob == 0 && mAsyncLoadContext->mItemFetchJobs.isEmpty() ) {
 
307
    mAsyncLoadContext = 0;
 
308
 
 
309
    emit loadingResult( true, QString() );
 
310
 
 
311
    delete context;
 
312
  }
 
313
}
 
314
 
 
315
#include "abstractsubresourcemodel.moc"
 
316
 
 
317
// kate: space-indent on; indent-width 2; replace-tabs on;