2 SPDX-FileCopyrightText: 2008 Stephen Kelly <[email protected]>
19 namespace Akonadi
22 class Item;
25 class Session;
93 * to a different mimetype. KContacts::Addressee::mimeType() is an alias for "text/directory". If changed to KMime::Message::mimeType()
94 * (an alias for "message/rfc822") the model would instead contain emails. The model can be configured to contain items of any mimetype
97 * @note The EntityTreeModel does some extra configuration on the Monitor, such as setting itemFetchScope() and collectionFetchScope()
104 * The EntityTreeModel can be further configured for certain behaviours such as fetching of collections and items.
106 * The model can be configured to not fetch items into the model (ie, fetch collections only) by setting
112 * The items may be fetched lazily, i.e. not inserted into the model until request by the user for performance reasons.
120 * This will typically be used with a EntityMimeTypeFilterModel in a configuration such as KMail or AkonadiConsole.
122 * The CollectionFetchStrategy determines how the model will be populated with Collections. That is, if FetchNoCollections is set,
123 * no collections beyond the root of the model will be fetched. This can be used in combination with setting a particular Collection to monitor.
133 * This has the effect of creating a model of only a list of Items, and not collections. This is similar in behaviour and aims to the ItemModel.
136 * @note It is important that you set only one Collection to be monitored in the monitor object. This one collection will be the root of the tree.
137 * If you need a model with a more complex structure, consider monitoring a common ancestor and using a SelectionProxyModel.
148 * By default the displayed name of the root collection is '[*]', because it doesn't require i18n, and is generic. It can be changed too.
152 * entityTree->setRootCollectionDisplayName(i18nc("Name of top level for all addressbooks in the application", "[All AddressBooks]"))
168 * An Akonadi::SelectionProxyModel can be used to simplify managing selection in one view through multiple proxy models to a representation in another view.
169 * The selectionModel of the initial view is used to create a proxied model which filters out anything not related to the current selection.
202 * See the KSelectionProxyModel documentation for the valid configurations of a Akonadi::SelectionProxyModel.
204 * Obviously, the SelectionProxyModel may be used in a view, or further processed with other proxy models. Typically, the result
205 * from this model will be further filtered to remove collections from the item list as in the above example.
207 * There are several advantages of using EntityTreeModel with the SelectionProxyModel, namely the items can be fetched and cached
208 * instead of being fetched many times, and the chain of proxies from the core model to the view is automatically handled. There is
241 * Note that it is important in this case to use the KDescendantsProxyModel before the EntityMimeTypeFilterModel.
242 * Otherwise, by filtering out the collections first, you would also be filtering out their child items.
250 * Usually an application will create a subclass of an EntityTreeModel and use that in several views via proxy models.
252 * The subclassing is necessary in order for the data in the model to have type-specific representation in applications
254 * For example, the headerData for an EntityTreeModel will be different depending on whether it is in a view showing only Collections
255 * in which case the header data should be "AddressBooks" for example, or only Items, in which case the headerData would be
256 * for example "Family Name", "Given Name" and "Email address" for contacts or "Subject", "Sender", "Date" in the case of emails.
260 * In summary, it must be possible to have different numbers of columns, different data in the rows of those columns, and different
263 * The way this is accomplished is by using the EntityMimeTypeFilterModel for splitting the model into a "CollectionTree" and an "Item List"
264 * as in the above example, and using a type-specific EntityTreeModel subclass to return the type-specific data, typically for only one type (for example,
269 * -- Implement to return the number of columns for a HeaderGroup. If the HeaderGroup is CollectionTreeHeaders, return the number of columns to display for the
270 * Collection tree, and if it is ItemListHeaders, return the number of columns to display for the item. In the case of addressee, this could be for example,
271 * two (for given name and family name) or for emails it could be three (for subject, sender, date). This is a decision of the subclass implementor.
272 * - `QVariant entityHeaderData( int section, Qt::Orientation orientation, int role, HeaderGroup headerGroup ) const;`
273 * -- Implement to return the data for each section for a HeaderGroup. For example, if the header group is CollectionTreeHeaders in a contacts model,
274 * the string "Address books" might be returned for column 0, whereas if the headerGroup is ItemListHeaders, the strings "Given Name", "Family Name",
276 * - `QVariant entityData( const Collection &collection, int column, int role = Qt::DisplayRole ) const;`
277 * -- Implement to return data for a particular Collection. Typically this will be the name of the collection or the EntityDisplayAttribute.
279 * -- Implement to return the data for a particular item and column. In the case of email for example, this would be the actual subject, sender and date of the
282 * @note The entityData methods are just for convenience. the QAbstractItemModel::data method can be overridden if required.
284 * The application writer must then properly configure proxy models for the views, so that the correct data is shown in the correct view.
295 * For example, a job is run to fetch the contents of collections (that is, list the items in it).
298 * To indicate that such a job is underway, the EntityTreeModel makes the FetchState available. The
299 * FetchState returned from a QModelIndex representing a Akonadi::Collection will be FetchingState if a
302 * @author Stephen Kelly <[email protected]>
314 // sebsauer, 2009-05-07; to be able here to keep the akonadi_next EntityTreeModel compatible with
328 ColumnCountRole, ///< @internal Used by proxies to determine the number of columns for a header group.
335 EntityUrlRole, ///< The akonadi:/ Url of the entity as a string. Item urls will contain the mimetype.
338 IsPopulatedRole, ///< Returns whether a Collection has been populated, i.e. whether its items have been fetched. @since 4.10
342 TerminalUserRole = 2000, ///< Last role for user extensions. Don't use a role beyond this or headerData will break.
362 FetchingState ///< There is a fetch of items in this collection in progress.
374 UserHeaders = 10, ///< Last header information for submodel extensions
375 EndHeaderGroup = 32 ///< Last headergroup role. Don't use a role beyond this or headerData will break.
376 // Note that we're splitting up available roles for the header data hack and int(EndRole / TerminalUserRole) == 32
390 ~EntityTreeModel() override;
397 ImmediatePopulation, ///< Retrieve items immediately when their parent is in the model. This is the default.
398 LazyPopulation ///< Fetch items only when requested (using canFetchMore/fetchMore)
402 * Some Entities are hidden in the model, but exist for internal purposes, for example, custom object
420 [[nodiscard]] Akonadi::CollectionFetchScope::ListFilter listFilter() const;
427 void setListFilter(Akonadi::CollectionFetchScope::ListFilter filter);
434 void setCollectionsMonitored(const Akonadi::Collection::List &collections);
443 void setCollectionMonitored(const Akonadi::Collection &col, bool monitored = true);
474 void setRootCollectionDisplayName(const QString &name);
479 [[nodiscard]] QString rootCollectionDisplayName() const;
487 FetchCollectionsRecursive, ///< Fetches collections in the root collection recursively. This is the default.
488 InvisibleCollectionFetch ///< Fetches collections, but does not put them in the model. This can be used to create a list of items in all collections.
489 ///< The ParentCollectionRole can still be used to retrieve the parent collection of an Item. @since 4.5
502 [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
507 [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
508 [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
511 [[nodiscard]] QStringList mimeTypes() const override;
513 [[nodiscard]] Qt::DropActions supportedDropActions() const override;
514 [[nodiscard]] QMimeData *mimeData(const QModelIndexList &indexes) const override;
515 bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
516 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
518 [[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
522 [[nodiscard]] bool canFetchMore(const QModelIndex &parent) const override;
523 void fetchMore(const QModelIndex &parent) override;
540 [[nodiscard]] bool isCollectionPopulated(Akonadi::Collection::Id) const;
545 * Returns true once the collection tree has been fetched and all collections have been populated.
558 const QVariant &value,
577 * // Maybe it is filtered out if proxy 2 is only showing items? Make sure you use the correct proxy.
581 * // collection has the id colId, and all other attributes already fetched by the model such as name, remoteId, Akonadi::Attributes etc.
585 * This can be useful for example if an id is stored in a config file and needs to be used in the application.
587 * Note however, that to restore view state such as scrolling, selection and expansion of items in trees, the ETMViewStateSaver can be used for convenience.
592 static QModelIndex modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection);
621 void collectionTreeFetched(const Akonadi::Collection::List &collections);
630 void collectionPopulated(Akonadi::Collection::Id collectionId);
656 virtual QVariant entityData(const Collection &collection, int column, int role = Qt::DisplayRole) const;
662 virtual QVariant entityHeaderData(int section, Qt::Orientation orientation, int role, HeaderGroup headerGroup) const;
681 Q_PRIVATE_SLOT(d_func(), void monitoredCollectionStatisticsChanged(Akonadi::Collection::Id, const Akonadi::CollectionStatistics &))
686 Q_PRIVATE_SLOT(d_func(), void collectionFetchJobDone(KJob *job))
687 Q_PRIVATE_SLOT(d_func(), void rootFetchJobDone(KJob *job))
688 Q_PRIVATE_SLOT(d_func(), void pasteJobDone(KJob *job))
689 Q_PRIVATE_SLOT(d_func(), void updateJobDone(KJob *job))
696 Q_PRIVATE_SLOT(d_func(), void monitoredMimeTypeChanged(const QString &, bool))
699 Q_PRIVATE_SLOT(d_func(), void monitoredResourcesChanged(const QByteArray &, bool))
701 Q_PRIVATE_SLOT(d_func(), void monitoredCollectionAdded(const Akonadi::Collection &, const Akonadi::Collection &))
704 Q_PRIVATE_SLOT(d_func(), void monitoredCollectionMoved(const Akonadi::Collection &, const Akonadi::Collection &, const Akonadi::Collection &))
706 Q_PRIVATE_SLOT(d_func(), void monitoredItemAdded(const Akonadi::Item &, const Akonadi::Collection &))
708 Q_PRIVATE_SLOT(d_func(), void monitoredItemChanged(const Akonadi::Item &, const QSet<QByteArray> &))
709 Q_PRIVATE_SLOT(d_func(), void monitoredItemMoved(const Akonadi::Item &, const Akonadi::Collection &, const Akonadi::Collection &))
711 Q_PRIVATE_SLOT(d_func(), void monitoredItemLinked(const Akonadi::Item &, const Akonadi::Collection &))
712 Q_PRIVATE_SLOT(d_func(), void monitoredItemUnlinked(const Akonadi::Item &, const Akonadi::Collection &))
716 Q_PRIVATE_SLOT(d_func(), void monitoredItemsRetrieved(KJob *job))
Header information for a list of items.
There is no fetch of items in this collection in progress.
Provides statistics information of a Collection.
A model for collections and items together.
Fetches first level collections in the root collection.
Do not include items in the model.
Parts available in the model for the item.
The akonadi:/ Url of the entity as a string. Item urls will contain the mimetype.
Returns the same as Qt::DisplayRole.
Q_SCRIPTABLE Q_NOREPLY void start()
Describes the state of fetch jobs related to particular collections.
The remoteId of the entity.
Returns original name for collection.
Header information for a collection-only tree.
Returns the number of unread items in a collection.
Header information for a tree with collections and items.
Fetches collections in the root collection recursively. This is the default.
Describes the list filter.
Fetches nothing. This creates an empty model.
Ordered list of child items if available.
Describes how the model should populated its items.
Parts available in the Akonadi server for the item.
Used to indicate items which are to be cut.
Returns whether a Collection has been populated, i.e. whether its items have been fetched.
Retrieve items immediately when their parent is in the model. This is the default.
Returns the FetchState of a particular item.
Describes what header information the model shall return.
The parent collection of the entity.
Describes what collections shall be fetched by and represent in the model.
Helper integration between Akonadi and Qt.