From 8c522cac3456c10c5937c98bb6866323639aff51 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Sat, 17 Feb 2024 22:22:18 +0300 Subject: [PATCH] Load file metadata asynchronously Synchronous load of metadata resulted in big delays when opening a directory with substantial amount of files. Closes: https://mirror.git.trinitydesktop.org/gitea/TDE/gwenview/issues/17 Signed-off-by: Alexander Golubev --- src/gvcore/fileviewcontroller.cpp | 66 ++++++++++++++++++++++++++++--- src/gvcore/fileviewcontroller.h | 6 +++ src/gvcore/timeutils.cpp | 2 +- src/gvcore/timeutils.h | 2 +- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/gvcore/fileviewcontroller.cpp b/src/gvcore/fileviewcontroller.cpp index 4426658..ffcb971 100644 --- a/src/gvcore/fileviewcontroller.cpp +++ b/src/gvcore/fileviewcontroller.cpp @@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include // Local #include "archive.h" @@ -188,6 +189,9 @@ public: TQComboBox* mFilterComboBox; TQCheckBox* mShowFilterBarCheckBox; + TDEIO::MetaInfoJob* mMetaInfoJob; + KFileItemList mMetaInfoTodo; + void initFilterBar() { mFilterBar=new FilterBar(that); mFilterBar->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); @@ -266,6 +270,7 @@ FileViewController::FileViewController(TQWidget* parent,TDEActionCollection* act d->initFilterBar(); d->initFilterCombo(); d->mStack=new TQWidgetStack(this); + d->mMetaInfoJob=NULL; TQVBoxLayout *layout=new TQVBoxLayout(this); layout->addWidget(d->mToolBar); @@ -470,6 +475,7 @@ FileViewController::~FileViewController() { FileViewConfig::setToDateFilter(d->mFilterBar->mToDateEdit->date()); FileViewConfig::writeConfig(); + stopMetaInfoUpdate(); delete mDirLister; delete d; } @@ -1022,6 +1028,12 @@ void FileViewController::dirListerDeleteItem(KFileItem* item) { if (!newShownItem) newShownItem=findPreviousImage(); } + // Remove item from metadata todo list and job's pending update lists + d->mMetaInfoTodo.remove(item); + if (d->mMetaInfoJob) { + d->mMetaInfoJob->removeItem(item); + } + currentFileView()->removeItem(item); if (shownItem==item) { @@ -1040,21 +1052,24 @@ void FileViewController::dirListerNewItems(const KFileItemList& items) { LOG(""); mThumbnailsNeedUpdate=true; currentFileView()->addItemList(items); + loadMetaInfo(items); } void FileViewController::dirListerRefreshItems(const KFileItemList& list) { LOG(""); - const KFileItem* item=currentFileView()->shownFileItem(); KFileItemListIterator it(list); for (; *it!=0L; ++it) { - currentFileView()->updateView(*it); - if (*it==item) { - emit shownFileItemRefreshed(item); - } + updateViewItem(*it); } } +void FileViewController::updateViewItem(const KFileItem *item) { + currentFileView()->updateView(item); + if (item==currentFileView()->shownFileItem()) { + emit shownFileItemRefreshed(item); + } +} void FileViewController::refreshItems(const KURL::List& urls) { LOG(""); @@ -1145,6 +1160,7 @@ void FileViewController::dirListerCanceled() { if (mMode!=FILE_LIST) { mFileThumbnailView->stopThumbnailUpdate(); } + stopMetaInfoUpdate(); browseToFileNameToSelect(); } @@ -1316,5 +1332,45 @@ KFileItem* FileViewController::findItemByFileName(const TQString& fileName) cons return 0L; } +//----------------------------------------------------------------------------- +// +// MetaInfo loading +// +//----------------------------------------------------------------------------- + +void FileViewController::loadMetaInfo(const KFileItemList& items) { + if(d->mMetaInfoTodo.isEmpty()) { + d->mMetaInfoTodo = items; + } else { + for(const auto& item: items) { + d->mMetaInfoTodo.append(item); + } + } + + if(!d->mMetaInfoJob) { + nextMetaInfoJob(); + } +} + +void FileViewController::nextMetaInfoJob() { + if( !d->mMetaInfoTodo.isEmpty() ) { + d->mMetaInfoJob = new TDEIO::MetaInfoJob(d->mMetaInfoTodo); + connect( d->mMetaInfoJob, TQ_SIGNAL(result(TDEIO::Job *)), + this, TQ_SLOT(nextMetaInfoJob()) ); + connect( d->mMetaInfoJob, TQ_SIGNAL( gotMetaInfo(const KFileItem *)), + this, TQ_SLOT(updateViewItem(const KFileItem *)) ); + d->mMetaInfoTodo.clear(); + } else { + d->mMetaInfoJob = NULL; + } +} + +void FileViewController::stopMetaInfoUpdate() { + d->mMetaInfoTodo.clear(); + if(d->mMetaInfoJob) { + d->mMetaInfoJob->kill(); + d->mMetaInfoJob = 0; + } +} } // namespace diff --git a/src/gvcore/fileviewcontroller.h b/src/gvcore/fileviewcontroller.h index 6b2c49b..b863614 100644 --- a/src/gvcore/fileviewcontroller.h +++ b/src/gvcore/fileviewcontroller.h @@ -174,6 +174,7 @@ private slots: void toggleShowDotFiles(); void setSorting(); void updateSortMenu(TQDir::SortSpec); + void updateViewItem(const KFileItem *item); // Dir lister slots void dirListerDeleteItem(KFileItem* item); @@ -184,6 +185,11 @@ private slots: void dirListerCanceled(); void dirListerCompleted(); + // Metadata info loader jobs + void loadMetaInfo(const KFileItemList& items); + void nextMetaInfoJob(); + void stopMetaInfoUpdate(); + void openDropURLMenu(TQDropEvent*, KFileItem*); void prefetchDone(); diff --git a/src/gvcore/timeutils.cpp b/src/gvcore/timeutils.cpp index 3995833..c917232 100644 --- a/src/gvcore/timeutils.cpp +++ b/src/gvcore/timeutils.cpp @@ -30,7 +30,7 @@ namespace Gwenview { namespace TimeUtils { time_t getTime(const KFileItem* item) { - const KFileMetaInfo& info = item->metaInfo(); + const KFileMetaInfo& info = item->metaInfo(/*autogen=*/false); if (info.isValid()) { TQVariant value = info.value("Date/time"); TQDateTime dt = value.toDateTime(); diff --git a/src/gvcore/timeutils.h b/src/gvcore/timeutils.h index 8d9e9c1..8570b36 100644 --- a/src/gvcore/timeutils.h +++ b/src/gvcore/timeutils.h @@ -29,7 +29,7 @@ namespace Gwenview { namespace TimeUtils { /** - * Returns the time of an item, using EXIF info if available + * Returns the time of an item, using EXIF info if available and already loaded */ time_t getTime(const KFileItem*);