2
Copyright (c) 2008 Stephen Kelly <steveire@gmail.com>
4
This library is free software; you can redistribute it and/or modify it
5
under the terms of the GNU Library General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or (at your
7
option) any later version.
9
This library is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12
License for more details.
14
You should have received a copy of the GNU Library General Public License
15
along with this library; see the file COPYING.LIB. If not, write to the
16
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
#ifndef AKONADI_ENTITYTREEMODEL_H
21
#define AKONADI_ENTITYTREEMODEL_H
23
#include "abstractitemmodel.h"
25
// #include <QtCore/QAbstractItemModel>
26
#include <QtCore/QStringList>
28
#include <akonadi/collection.h>
29
#include <akonadi/item.h>
30
#include "akonadi_next_export.h"
32
// TODO (Applies to all these 'new' models, not just EntityTreeModel):
33
// * Figure out how LazyPopulation and signals from monitor containing items should
34
// fit together. Possibly store a list of collections whose items have already
35
// been lazily fetched.
36
// * Fgure out whether DescendantEntitiesProxyModel needs to use fetchMore.
37
// * Profile this and DescendantEntitiesProxyModel. Make sure it's faster than
38
// FlatCollectionProxyModel. See if the cache in that class can be cleared less often.
39
// * Unit tests. Much of the stuff here is not covered by modeltest, and some of
40
// it is akonadi specific, such as setting root collection etc.
41
// * Implement support for includeUnsubscribed.
42
// * Use CollectionStatistics for item count stuff. Find out if I can get stats by mimetype.
43
// * Make sure there are applications using it before committing to it until KDE5.
44
// Some API/ virtual methods might need to be added when real applications are made.
45
// * Implement ordering support.
46
// * Implement some proxy models for time-table like uses, eg KOrganizer events.
52
class CollectionStatistics;
57
class EntityTreeModelPrivate;
60
* @short A model for collections and items together.
62
* This class is a wrapper around a Akonadi::Monitor object. The model represents a
63
* part of the collection and item tree configured in the Monitor.
67
* Monitor *monitor = new Monitor(this);
68
* monitor->setCollectionMonitored(Collection::root());
69
* monitor->setMimeTypeMonitored(KABC::addresseeMimeType());
71
* EntityTreeModel *model = new EntityTreeModel( session, monitor, this );
73
* EntityTreeView *view = new EntityTreeView( this );
74
* view->setModel( model );
78
* @author Stephen Kelly <steveire@gmail.com>
81
class AKONADI_NEXT_EXPORT EntityTreeModel : public AbstractItemModel
87
* Describes the roles for items. Roles for collections are defined by the superclass.
90
//sebsauer, 2009-05-07; to be able here to keep the akonadi_next EntityTreeModel compatible with
91
//the akonadi_old ItemModel and CollectionModel, we need to use the same int-values for
92
//ItemRole, ItemIdRole and MimeTypeRole like the Akonadi::ItemModel is using and the same
93
//CollectionIdRole and CollectionRole like the Akonadi::CollectionModel is using.
94
ItemIdRole = Qt::UserRole + 1, ///< The item id
95
ItemRole = Qt::UserRole + 2, ///< The Item
96
MimeTypeRole = Qt::UserRole + 3, ///< The mimetype of the entity
98
CollectionIdRole = Qt::UserRole + 10, ///< The collection id.
99
CollectionRole = Qt::UserRole + 11, ///< The collection.
101
RemoteIdRole, ///< The remoteId of the entity
102
CollectionChildOrderRole, ///< Ordered list of child items if available
103
UserRole = Qt::UserRole + 1000, ///< Role for user extensions.
104
TerminalUserRole = 10000 ///< Last role for user extensions. Don't use a role beyond this or headerData will break.
108
* Describes what header information the model shall return.
111
EntityTreeHeaders, ///< Header information for a tree with collections and items
112
CollectionTreeHeaders, ///< Header information for a collection-only tree
113
ItemListHeaders, ///< Header information for a list of items
114
UserHeaders = 1000 ///< Last header information for submodel extensions
118
* Creates a new entity tree model.
120
* @param session The Session to use to communicate with Akonadi.
121
* @param monitor The Monitor whose entities should be represented in the model.
122
* @param parent The parent object.
124
EntityTreeModel( Session *session, Monitor *monitor, QObject *parent = 0 );
127
* Destroys the entity tree model.
129
virtual ~EntityTreeModel();
132
* Describes how the model should populated its items.
134
enum ItemPopulationStrategy {
135
NoItemPopulation, ///< Do not include items in the model.
136
ImmediatePopulation, ///< Retrieve items immediately when their parent is in the model. This is the default.
137
LazyPopulation ///< Fetch items only when requested (using canFetchMore/fetchMore)
141
* Sets the item population @p strategy of the model.
143
void setItemPopulationStrategy( ItemPopulationStrategy strategy );
146
* Returns the item population strategy of the model.
148
ItemPopulationStrategy itemPopulationStrategy() const;
151
* Sets the root collection to create an entity tree for.
152
* The @p collection must be a valid Collection object.
154
* By default the Collection::root() is used.
156
void setRootCollection( const Collection &collection );
159
* Returns the root collection of the entity tree.
161
Collection rootCollection() const;
164
* Sets whether the root collection shall be provided by the model.
166
* @see setRootCollectionDisplayName()
168
void setIncludeRootCollection( bool include );
171
* Returns whether the root collection is provided by the model.
173
bool includeRootCollection() const;
176
* Sets the display @p name of the root collection of the model.
177
* The default display name is "[*]".
179
* @note The display name for the root collection is only used if
180
* the root collection has been included with setIncludeRootCollection().
182
void setRootCollectionDisplayName( const QString &name );
185
* Returns the display name of the root collection.
187
QString rootCollectionDisplayName() const;
190
* Describes what collections shall be fetched by and represent in the model.
192
enum CollectionFetchStrategy {
193
FetchNoCollections, ///< Fetches nothing. This creates an empty model.
194
FetchFirstLevelChildCollections, ///< Fetches first level collections in the root collection.
195
FetchCollectionsRecursive ///< Fetches collections in the root collection recursively. This is the default.
199
* Sets the collection fetch @p strategy of the model.
201
void setCollectionFetchStrategy( CollectionFetchStrategy strategy );
204
* Returns the collection fetch strategy of the model.
206
CollectionFetchStrategy collectionFetchStrategy() const;
209
* Returns the model index for the given @p collection.
211
QModelIndex indexForCollection( const Collection &collection ) const;
214
* Returns the model indexes for the given @p item.
216
QModelIndexList indexesForItem( const Item &item ) const;
219
* Returns the collection for the given collection @p id.
221
Collection collectionForId( Collection::Id id ) const;
224
* Returns the item for the given item @p id.
226
Item itemForId( Item::Id id ) const;
228
// TODO: Remove these and use the Monitor instead. Need to add api to Monitor for this.
229
void setIncludeUnsubscribed( bool include );
230
bool includeUnsubscribed() const;
232
virtual int columnCount( const QModelIndex & parent = QModelIndex() ) const;
233
virtual int rowCount( const QModelIndex & parent = QModelIndex() ) const;
235
virtual QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const;
236
virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
238
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
239
virtual QStringList mimeTypes() const;
241
virtual Qt::DropActions supportedDropActions() const;
242
virtual QMimeData *mimeData( const QModelIndexList &indexes ) const;
243
virtual bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent );
244
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
246
virtual QModelIndex index( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
247
virtual QModelIndex parent( const QModelIndex & index ) const;
249
// TODO: Review the implementations of these. I think they could be better.
250
virtual bool canFetchMore( const QModelIndex & parent ) const;
251
virtual void fetchMore( const QModelIndex & parent );
252
virtual bool hasChildren( const QModelIndex &parent = QModelIndex() ) const;
256
* Clears and resets the model. Always call this instead of the reset method in the superclass.
257
* Using the reset method will not reliably clear or refill the model.
259
void clearAndReset();
262
* Provided for convenience of subclasses.
264
virtual QVariant getData( const Item &item, int column, int role = Qt::DisplayRole ) const;
267
* Provided for convenience of subclasses.
269
virtual QVariant getData( const Collection &collection, int column, int role = Qt::DisplayRole ) const;
272
* Reimplement this to provide different header data. This is needed when using one model
273
* with multiple proxies and views, and each should show different header data.
275
virtual QVariant getHeaderData( int section, Qt::Orientation orientation, int role, int headerSet ) const;
278
* Removes the rows from @p start to @p end from @parent
280
virtual bool removeRows( int start, int end, const QModelIndex &parent = QModelIndex() );
284
Q_DECLARE_PRIVATE( EntityTreeModel )
285
EntityTreeModelPrivate *d_ptr;
287
// Make these private, they shouldn't be called by applications
288
virtual bool insertRows( int , int, const QModelIndex& = QModelIndex() );
289
virtual bool insertColumns( int, int, const QModelIndex& = QModelIndex() );
290
virtual bool removeColumns( int, int, const QModelIndex& = QModelIndex() );
292
Q_PRIVATE_SLOT( d_func(), void monitoredCollectionStatisticsChanged( Akonadi::Collection::Id,
293
const Akonadi::CollectionStatistics& ) )
295
Q_PRIVATE_SLOT( d_func(), void startFirstListJob() )
296
// Q_PRIVATE_SLOT( d_func(), void slotModelReset() )
298
// TODO: Can I merge these into one jobResult slot?
299
Q_PRIVATE_SLOT( d_func(), void fetchJobDone( KJob *job ) )
300
Q_PRIVATE_SLOT( d_func(), void copyJobDone( KJob *job ) )
301
Q_PRIVATE_SLOT( d_func(), void moveJobDone( KJob *job ) )
302
Q_PRIVATE_SLOT( d_func(), void updateJobDone( KJob *job ) )
304
Q_PRIVATE_SLOT( d_func(), void itemsFetched( Akonadi::Item::List ) )
305
Q_PRIVATE_SLOT( d_func(), void collectionsFetched( Akonadi::Collection::List ) )
307
Q_PRIVATE_SLOT( d_func(), void monitoredMimeTypeChanged( const QString&, bool ) )
309
Q_PRIVATE_SLOT( d_func(), void monitoredCollectionAdded( const Akonadi::Collection&, const Akonadi::Collection& ) )
310
Q_PRIVATE_SLOT( d_func(), void monitoredCollectionRemoved( const Akonadi::Collection& ) )
311
Q_PRIVATE_SLOT( d_func(), void monitoredCollectionChanged( const Akonadi::Collection& ) )
312
Q_PRIVATE_SLOT( d_func(), void monitoredCollectionMoved( const Akonadi::Collection&, const Akonadi::Collection&,
313
const Akonadi::Collection&) )
315
Q_PRIVATE_SLOT( d_func(), void monitoredItemAdded( const Akonadi::Item&, const Akonadi::Collection& ) )
316
Q_PRIVATE_SLOT( d_func(), void monitoredItemRemoved( const Akonadi::Item& ) )
317
Q_PRIVATE_SLOT( d_func(), void monitoredItemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) )
318
Q_PRIVATE_SLOT( d_func(), void monitoredItemMoved( const Akonadi::Item&, const Akonadi::Collection&,
319
const Akonadi::Collection& ) )
321
Q_PRIVATE_SLOT( d_func(), void monitoredItemLinked( const Akonadi::Item&, const Akonadi::Collection& ) )
322
Q_PRIVATE_SLOT( d_func(), void monitoredItemUnlinked( const Akonadi::Item&, const Akonadi::Collection& ) )