X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/ffe179ad51d1f88f98e03fc130ec85b306a018d8..e6ea3ab4c41dcc115143a237aafd3a1152849433:/src/kitemviews/kfileitemmodelrolesupdater.h diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h index 68559d8dd..e21cd30df 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/src/kitemviews/kfileitemmodelrolesupdater.h @@ -20,37 +20,33 @@ #ifndef KFILEITEMMODELROLESUPDATER_H #define KFILEITEMMODELROLESUPDATER_H -#include +#include "dolphin_export.h" +#include "kitemviews/kitemmodelbase.h" #include -#include - -#include +#include #include #include #include #include -class KDirWatch; +class KDirectoryContentsCounter; class KFileItemModel; -class KJob; class QPixmap; class QTimer; +class KOverlayIconPlugin; -#ifdef HAVE_NEPOMUK - namespace Nepomuk2 - { - class ResourceWatcher; - class Resource; - } -#else - // Required for the slot applyChangedNepomukRoles() that - // cannot be ifdefined due to moc. - namespace Nepomuk2 +namespace KIO { + class PreviewJob; +} + +#ifdef HAVE_BALOO + namespace Baloo { - class Resource; + class FileMonitor; } + #include #endif /** @@ -59,14 +55,46 @@ class QTimer; * KFileItemModel only resolves roles that are inexpensive like e.g. the file name or * the permissions. Creating previews or determining the MIME-type can be quite expensive * and KFileItemModelRolesUpdater takes care to update such roles asynchronously. + * + * To prevent a huge CPU and I/O load, these roles are not updated for all + * items, but only for the visible items, some items around the visible area, + * and the items on the first and last pages of the view. This is a compromise + * that aims to minimize the risk that the user sees items with unknown icons + * in the view when scrolling or pressing Home or End. + * + * Determining the roles is done in several phases: + * + * 1. If the sort role is "slow", it is determined for all items. If this + * cannot be finished synchronously in 200 ms, the remaining items are + * handled asynchronously by \a resolveNextSortRole(). + * + * 2. The function startUpdating(), which is called if either the sort role + * has been successfully determined for all items, or items are inserted + * in the view, or the visible items might have changed because items + * were removed or moved, tries to determine the icons for all visible + * items synchronously for 200 ms. Then: + * + * (a) If previews are disabled, icons and all other roles are determined + * asynchronously for the interesting items. This is done by the + * function \a resolveNextPendingRoles(). + * + * (b) If previews are enabled, a \a KIO::PreviewJob is started that loads + * the previews for the interesting items. At the same time, the icons + * for these items are determined asynchronously as fast as possible + * by \a resolveNextPendingRoles(). This minimizes the risk that the + * user sees "unknown" icons when scrolling before the previews have + * arrived. + * + * 3. Finally, the entire process is repeated for any items that might have + * changed in the mean time. */ -class LIBDOLPHINPRIVATE_EXPORT KFileItemModelRolesUpdater : public QObject +class DOLPHIN_EXPORT KFileItemModelRolesUpdater : public QObject { Q_OBJECT public: - explicit KFileItemModelRolesUpdater(KFileItemModel* model, QObject* parent = 0); - virtual ~KFileItemModelRolesUpdater(); + explicit KFileItemModelRolesUpdater(KFileItemModel* model, QObject* parent = nullptr); + ~KFileItemModelRolesUpdater() override; void setIconSize(const QSize& size); QSize iconSize() const; @@ -77,6 +105,8 @@ public: */ void setVisibleIndexRange(int index, int count); + void setMaximumVisibleItems(int count); + /** * If \a show is set to true, the "iconPixmap" role will be filled with a preview * of the file. If \a show is false the MIME type icon will be used for the "iconPixmap" @@ -127,6 +157,7 @@ public: private slots: void slotItemsInserted(const KItemRangeList& itemRanges); void slotItemsRemoved(const KItemRangeList& itemRanges); + void slotItemsMoved(const KItemRange& itemRange, const QList &movedToIndexes); void slotItemsChanged(const KItemRangeList& itemRanges, const QSet& roles); void slotSortRoleChanged(const QByteArray& current, @@ -145,76 +176,87 @@ private slots: void slotPreviewFailed(const KFileItem& item); /** - * Is invoked when the preview job has been finished and - * removes the job from the m_previewJobs list. + * Is invoked when the preview job has been finished. Starts a new preview + * job if there are any interesting items without previews left, or updates + * the changed items otherwise. * * @see startPreviewJob() */ - void slotPreviewJobFinished(KJob* job); + void slotPreviewJobFinished(); + + /** + * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed + */ + void slotOverlaysChanged(const QUrl& url, const QStringList&); + /** + * Resolves the sort role of the next item in m_pendingSortRole, applies it + * to the model, and invokes itself if there are any pending items left. If + * that is not the case, \a startUpdating() is called. + */ + void resolveNextSortRole(); + + /** + * Resolves the icon name and (if previews are disabled) all other roles + * for the next interesting item. If there are no pending items left, any + * changed items are updated. + */ void resolveNextPendingRoles(); /** * Resolves items that have not been resolved yet after the change has been * notified by slotItemsChanged(). Is invoked if the m_changedItemsTimer - * exceeds. + * expires. */ - void resolveChangedItems(); + void resolveRecentlyChangedItems(); + + void applyChangedBalooRoles(const QString& file); + void applyChangedBalooRolesForItem(const KFileItem& file); - void applyChangedNepomukRoles(const Nepomuk2::Resource& resource); + void slotDirectoryContentsCountReceived(const QString& path, int count, long size); +private: /** - * Is invoked if a directory watched by KDirWatch got dirty. Updates - * the "isExpandable"- and "size"-roles of the item that matches to - * the given path. + * Starts the updating of all roles. The visible items are handled first. */ - void slotDirWatchDirty(const QString& path); + void startUpdating(); -private: /** - * Updates the roles for the given item ranges. The roles for the currently - * visible items will get updated first. + * Loads the icons for the visible items. After 200 ms, the function + * stops determining mime types and only loads preliminary icons. + * This is a compromise that prevents that + * (a) the GUI is blocked for more than 200 ms, and + * (b) "unknown" icons could be shown in the view. */ - void startUpdating(const KItemRangeList& itemRanges); + void updateVisibleIcons(); /** - * Creates previews for the items starting from the first item of the - * given list. + * Creates previews for the items starting from the first item in + * m_pendingPreviewItems. * @see slotGotPreview() * @see slotPreviewFailed() * @see slotPreviewJobFinished() */ - void startPreviewJob(const KFileItemList& items); - - bool hasPendingRoles() const; - void resolvePendingRoles(); - void resetPendingRoles(); - void sortAndResolveAllRoles(); - void sortAndResolvePendingRoles(); - void applySortProgressToModel(); + void startPreviewJob(); /** - * Updates m_sortProgress to be 0 if the sort-role - * needs to get resolved asynchronously and hence a - * progress is required. Otherwise m_sortProgress - * will be set to -1 which means that no progress - * will be provided. + * Ensures that icons, previews, and other roles are determined for any + * items that have been changed. */ - void updateSortProgress(); + void updateChangedItems(); /** - * @return True, if at least one item from the model - * has an unknown MIME-type. + * Resolves the sort role of the item and applies it to the model. */ - bool hasUnknownMimeTypes() const; + void applySortRole(int index); + + void applySortProgressToModel(); enum ResolveHint { ResolveFast, ResolveAll }; - bool applyResolvedRoles(const KFileItem& item, ResolveHint hint); - QHash rolesData(const KFileItem& item) const; - - KFileItemList sortedItems(const QSet& items) const; + bool applyResolvedRoles(int index, ResolveHint hint); + QHash rolesData(const KFileItem& item); /** * @return The number of items of the path \a path. @@ -227,9 +269,20 @@ private: */ void updateAllPreviews(); + void killPreviewJob(); + + QList indexesToResolve() const; + private: - // Property for setPaused()/isPaused(). - bool m_paused; + enum State { + Idle, + Paused, + ResolvingSortRole, + ResolvingAllRoles, + PreviewJobRunning + }; + + State m_state; // Property changes during pausing must be remembered to be able // to react when unpausing again: @@ -248,34 +301,50 @@ private: // during the roles-updater has been paused by setPaused(). bool m_clearPreviews; - int m_sortingProgress; + // Remembers which items have been handled already, to prevent that + // previews and other expensive roles are determined again. + QSet m_finishedItems; KFileItemModel* m_model; QSize m_iconSize; int m_firstVisibleIndex; int m_lastVisibleIndex; + int m_maximumVisibleItems; QSet m_roles; QSet m_resolvableRoles; QStringList m_enabledPlugins; - QSet m_pendingVisibleItems; - QSet m_pendingInvisibleItems; - QList m_previewJobs; + // Items for which the sort role still has to be determined. + QSet m_pendingSortRoleItems; + + // Indexes of items which still have to be handled by + // resolveNextPendingRoles(). + QList m_pendingIndexes; + + // Items which have been left over from the last call of startPreviewJob(). + // A new preview job will be started from them once the first one finishes. + KFileItemList m_pendingPreviewItems; + + KIO::PreviewJob* m_previewJob; // When downloading or copying large files, the slot slotItemsChanged() // will be called periodically within a quite short delay. To prevent // a high CPU-load by generating e.g. previews for each notification, the update // will be postponed until no file change has been done within a longer period // of time. - QTimer* m_changedItemsTimer; + QTimer* m_recentlyChangedItemsTimer; + QSet m_recentlyChangedItems; + + // Items which have not been changed repeatedly recently. QSet m_changedItems; - KDirWatch* m_dirWatcher; - mutable QSet m_watchedDirs; // Required as sadly KDirWatch does not offer a getter method - // to get all watched directories. -#ifdef HAVE_NEPOMUK - Nepomuk2::ResourceWatcher* m_nepomukResourceWatcher; - mutable QHash m_nepomukUriItems; + KDirectoryContentsCounter* m_directoryContentsCounter; + + QList m_overlayIconsPlugin; + +#ifdef HAVE_BALOO + Baloo::FileMonitor* m_balooFileMonitor; + Baloo::IndexerConfig m_balooConfig; #endif };