diff --git a/src/filewidgets/kfileplacesview.cpp b/src/filewidgets/kfileplacesview.cpp --- a/src/filewidgets/kfileplacesview.cpp +++ b/src/filewidgets/kfileplacesview.cpp @@ -29,22 +29,22 @@ #include #include #include +#include #include - #include #include #include #include #include #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -57,6 +57,14 @@ #define LATERAL_MARGIN 4 #define CAPACITYBAR_HEIGHT 6 +struct PlaceFreeSpaceInfo +{ + QDateTime lastUpdated; + KIO::filesize_t used = 0; + KIO::filesize_t size = 0; + QPointer job; +}; + class KFilePlacesViewDelegate : public QAbstractItemDelegate { Q_OBJECT @@ -93,6 +101,8 @@ int sectionHeaderHeight() const; + void clearFreeSpaceInfo(); + private: QString groupNameFromIndex(const QModelIndex &index) const; QModelIndex previousVisibleIndex(const QModelIndex &index) const; @@ -121,6 +131,8 @@ QMap m_timeLineMap; QMap m_timeLineInverseMap; + + mutable QMap m_freeSpaceInfo; }; KFilePlacesViewDelegate::KFilePlacesViewDelegate(KFilePlacesView *parent) : @@ -217,11 +229,11 @@ bool drawCapacityBar = false; if (placesModel->data(index, KFilePlacesModel::CapacityBarRecommendedRole).toBool()) { const QUrl url = placesModel->url(index); - if (url.isLocalFile() && contentsOpacity(index) > 0) { - const QString mountPointPath = url.toLocalFile(); + if (contentsOpacity(index) > 0) { + QPersistentModelIndex persistentIndex(index); + PlaceFreeSpaceInfo &info = m_freeSpaceInfo[persistentIndex]; - const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(mountPointPath); - drawCapacityBar = info.size() != 0; + drawCapacityBar = info.size > 0; if (drawCapacityBar) { painter->save(); painter->setOpacity(painter->opacity() * contentsOpacity(index)); @@ -232,14 +244,34 @@ painter->drawText(rectText, Qt::AlignLeft | Qt::AlignTop, opt.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width())); QRect capacityRect(isLTR ? rectText.x() : LATERAL_MARGIN, rectText.bottom() - 1, rectText.width() - LATERAL_MARGIN, CAPACITYBAR_HEIGHT); KCapacityBar capacityBar(KCapacityBar::DrawTextInline); - capacityBar.setValue((info.used() * 100) / info.size()); + capacityBar.setValue((info.used * 100) / info.size); capacityBar.drawCapacityBar(painter, capacityRect); painter->restore(); painter->save(); painter->setOpacity(painter->opacity() * (1 - contentsOpacity(index))); } + + if (!info.job && + (!info.lastUpdated.isValid() || info.lastUpdated.secsTo(QDateTime::currentDateTimeUtc()) > 60)) { + info.job = KIO::fileSystemFreeSpace(url); + connect(info.job, &KIO::FileSystemFreeSpaceJob::result, this, [this, persistentIndex](KIO::Job *job, KIO::filesize_t size, KIO::filesize_t available) { + PlaceFreeSpaceInfo &info = m_freeSpaceInfo[persistentIndex]; + + // even if we receive an error we want to refresh lastUpdated to avoid repeatedly querying in this case + info.lastUpdated = QDateTime::currentDateTimeUtc(); + + if (job->error()) { + return; + } + + info.size = size; + info.used = size - available; + + // FIXME scheduleDelayedItemsLayout but we're in the delegate here, not the view + }); + } } } @@ -384,6 +416,11 @@ m_dragStarted = true; } +void KFilePlacesViewDelegate::clearFreeSpaceInfo() +{ + m_freeSpaceInfo.clear(); +} + QString KFilePlacesViewDelegate::groupNameFromIndex(const QModelIndex &index) const { if (index.isValid()) { @@ -511,6 +548,7 @@ void setCurrentIndex(const QModelIndex &index); void adaptItemSize(); void updateHiddenRows(); + void clearFreeSpaceInfos(); bool insertAbove(const QRect &itemRect, const QPoint &pos) const; bool insertBelow(const QRect &itemRect, const QPoint &pos) const; int insertIndicatorHeight(int itemHeight) const; @@ -1074,6 +1112,8 @@ this, SLOT(adaptItemSize()), Qt::QueuedConnection); connect(selectionModel(), &QItemSelectionModel::currentChanged, d->watcher, &KFilePlacesEventWatcher::currentIndexChanged); + + static_cast(itemDelegate())->clearFreeSpaceInfo(); } void KFilePlacesView::rowsInserted(const QModelIndex &parent, int start, int end)