Changeset View
Changeset View
Standalone View
Standalone View
src/filewidgets/kfileplacesview.cpp
Show All 23 Lines | |||||
24 | #include <QDir> | 24 | #include <QDir> | ||
25 | #include <QTimeLine> | 25 | #include <QTimeLine> | ||
26 | #include <QTimer> | 26 | #include <QTimer> | ||
27 | #include <QPainter> | 27 | #include <QPainter> | ||
28 | #include <QAbstractItemDelegate> | 28 | #include <QAbstractItemDelegate> | ||
29 | #include <QKeyEvent> | 29 | #include <QKeyEvent> | ||
30 | #include <QApplication> | 30 | #include <QApplication> | ||
31 | #include <QMenu> | 31 | #include <QMenu> | ||
32 | #include <QPointer> | ||||
32 | #include <QScrollBar> | 33 | #include <QScrollBar> | ||
33 | 34 | | |||
34 | | ||||
35 | #include <kconfig.h> | 35 | #include <kconfig.h> | ||
36 | #include <kconfiggroup.h> | 36 | #include <kconfiggroup.h> | ||
37 | #include <kdirnotify.h> | 37 | #include <kdirnotify.h> | ||
38 | #include <klocalizedstring.h> | 38 | #include <klocalizedstring.h> | ||
39 | #include <kmessagebox.h> | 39 | #include <kmessagebox.h> | ||
40 | #include <kmountpoint.h> | 40 | #include <kmountpoint.h> | ||
41 | #include <kpropertiesdialog.h> | 41 | #include <kpropertiesdialog.h> | ||
42 | #include <kio/emptytrashjob.h> | 42 | #include <kio/emptytrashjob.h> | ||
43 | #include <kio/filesystemfreespacejob.h> | ||||
43 | #include <kio/jobuidelegate.h> | 44 | #include <kio/jobuidelegate.h> | ||
44 | #include <kjob.h> | 45 | #include <kjob.h> | ||
45 | #include <kjobwidgets.h> | 46 | #include <kjobwidgets.h> | ||
46 | #include <kcapacitybar.h> | 47 | #include <kcapacitybar.h> | ||
47 | #include <kdiskfreespaceinfo.h> | | |||
48 | #include <solid/storageaccess.h> | 48 | #include <solid/storageaccess.h> | ||
49 | #include <solid/storagedrive.h> | 49 | #include <solid/storagedrive.h> | ||
50 | #include <solid/storagevolume.h> | 50 | #include <solid/storagevolume.h> | ||
51 | #include <solid/opticaldrive.h> | 51 | #include <solid/opticaldrive.h> | ||
52 | #include <solid/opticaldisc.h> | 52 | #include <solid/opticaldisc.h> | ||
53 | 53 | | |||
54 | #include "kfileplaceeditdialog.h" | 54 | #include "kfileplaceeditdialog.h" | ||
55 | #include "kfileplacesmodel.h" | 55 | #include "kfileplacesmodel.h" | ||
56 | 56 | | |||
57 | #define LATERAL_MARGIN 4 | 57 | #define LATERAL_MARGIN 4 | ||
58 | #define CAPACITYBAR_HEIGHT 6 | 58 | #define CAPACITYBAR_HEIGHT 6 | ||
59 | 59 | | |||
60 | struct PlaceFreeSpaceInfo | ||||
61 | { | ||||
62 | QDateTime lastUpdated; | ||||
63 | KIO::filesize_t used = 0; | ||||
64 | KIO::filesize_t size = 0; | ||||
65 | QPointer<KIO::FileSystemFreeSpaceJob> job; | ||||
66 | }; | ||||
67 | | ||||
60 | class KFilePlacesViewDelegate : public QAbstractItemDelegate | 68 | class KFilePlacesViewDelegate : public QAbstractItemDelegate | ||
61 | { | 69 | { | ||
62 | Q_OBJECT | 70 | Q_OBJECT | ||
63 | public: | 71 | public: | ||
64 | explicit KFilePlacesViewDelegate(KFilePlacesView *parent); | 72 | explicit KFilePlacesViewDelegate(KFilePlacesView *parent); | ||
65 | ~KFilePlacesViewDelegate() override; | 73 | ~KFilePlacesViewDelegate() override; | ||
66 | QSize sizeHint(const QStyleOptionViewItem &option, | 74 | QSize sizeHint(const QStyleOptionViewItem &option, | ||
67 | const QModelIndex &index) const override; | 75 | const QModelIndex &index) const override; | ||
Show All 20 Lines | |||||
88 | qreal contentsOpacity(const QModelIndex &index) const; | 96 | qreal contentsOpacity(const QModelIndex &index) const; | ||
89 | 97 | | |||
90 | bool pointIsHeaderArea(const QPoint &pos); | 98 | bool pointIsHeaderArea(const QPoint &pos); | ||
91 | 99 | | |||
92 | void startDrag(); | 100 | void startDrag(); | ||
93 | 101 | | |||
94 | int sectionHeaderHeight() const; | 102 | int sectionHeaderHeight() const; | ||
95 | 103 | | |||
104 | void clearFreeSpaceInfo(); | ||||
105 | | ||||
96 | private: | 106 | private: | ||
97 | QString groupNameFromIndex(const QModelIndex &index) const; | 107 | QString groupNameFromIndex(const QModelIndex &index) const; | ||
98 | QModelIndex previousVisibleIndex(const QModelIndex &index) const; | 108 | QModelIndex previousVisibleIndex(const QModelIndex &index) const; | ||
99 | bool indexIsSectionHeader(const QModelIndex &index) const; | 109 | bool indexIsSectionHeader(const QModelIndex &index) const; | ||
100 | void drawSectionHeader(QPainter *painter, | 110 | void drawSectionHeader(QPainter *painter, | ||
101 | const QStyleOptionViewItem &option, | 111 | const QStyleOptionViewItem &option, | ||
102 | const QModelIndex &index) const; | 112 | const QModelIndex &index) const; | ||
103 | 113 | | |||
Show All 12 Lines | |||||
116 | int m_disappearingIconSize; | 126 | int m_disappearingIconSize; | ||
117 | qreal m_disappearingOpacity; | 127 | qreal m_disappearingOpacity; | ||
118 | 128 | | |||
119 | bool m_showHoverIndication; | 129 | bool m_showHoverIndication; | ||
120 | mutable bool m_dragStarted; | 130 | mutable bool m_dragStarted; | ||
121 | 131 | | |||
122 | QMap<QPersistentModelIndex, QTimeLine *> m_timeLineMap; | 132 | QMap<QPersistentModelIndex, QTimeLine *> m_timeLineMap; | ||
123 | QMap<QTimeLine *, QPersistentModelIndex> m_timeLineInverseMap; | 133 | QMap<QTimeLine *, QPersistentModelIndex> m_timeLineInverseMap; | ||
134 | | ||||
135 | mutable QMap<QPersistentModelIndex, PlaceFreeSpaceInfo> m_freeSpaceInfo; | ||||
124 | }; | 136 | }; | ||
125 | 137 | | |||
126 | KFilePlacesViewDelegate::KFilePlacesViewDelegate(KFilePlacesView *parent) : | 138 | KFilePlacesViewDelegate::KFilePlacesViewDelegate(KFilePlacesView *parent) : | ||
127 | QAbstractItemDelegate(parent), | 139 | QAbstractItemDelegate(parent), | ||
128 | m_view(parent), | 140 | m_view(parent), | ||
129 | m_iconSize(48), | 141 | m_iconSize(48), | ||
130 | m_appearingIconSize(0), | 142 | m_appearingIconSize(0), | ||
131 | m_appearingOpacity(0.0), | 143 | m_appearingOpacity(0.0), | ||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Line(s) | 217 | if (opt.state & QStyle::State_Selected) { | |||
212 | painter->setPen(opt.palette.color(cg, QPalette::HighlightedText)); | 224 | painter->setPen(opt.palette.color(cg, QPalette::HighlightedText)); | ||
213 | } | 225 | } | ||
214 | 226 | | |||
215 | QRect rectText; | 227 | QRect rectText; | ||
216 | 228 | | |||
217 | bool drawCapacityBar = false; | 229 | bool drawCapacityBar = false; | ||
218 | if (placesModel->data(index, KFilePlacesModel::CapacityBarRecommendedRole).toBool()) { | 230 | if (placesModel->data(index, KFilePlacesModel::CapacityBarRecommendedRole).toBool()) { | ||
219 | const QUrl url = placesModel->url(index); | 231 | const QUrl url = placesModel->url(index); | ||
220 | if (url.isLocalFile() && contentsOpacity(index) > 0) { | 232 | if (contentsOpacity(index) > 0) { | ||
221 | const QString mountPointPath = url.toLocalFile(); | 233 | QPersistentModelIndex persistentIndex(index); | ||
234 | PlaceFreeSpaceInfo &info = m_freeSpaceInfo[persistentIndex]; | ||||
222 | 235 | | |||
223 | const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(mountPointPath); | 236 | drawCapacityBar = info.size > 0; | ||
224 | drawCapacityBar = info.size() != 0; | | |||
225 | if (drawCapacityBar) { | 237 | if (drawCapacityBar) { | ||
226 | painter->save(); | 238 | painter->save(); | ||
227 | painter->setOpacity(painter->opacity() * contentsOpacity(index)); | 239 | painter->setOpacity(painter->opacity() * contentsOpacity(index)); | ||
228 | 240 | | |||
229 | int height = opt.fontMetrics.height() + CAPACITYBAR_HEIGHT; | 241 | int height = opt.fontMetrics.height() + CAPACITYBAR_HEIGHT; | ||
230 | rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + opt.rect.left() | 242 | rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + opt.rect.left() | ||
231 | : 0, opt.rect.top() + (opt.rect.height() / 2 - height / 2), opt.rect.width() - m_iconSize - LATERAL_MARGIN * 2, opt.fontMetrics.height()); | 243 | : 0, opt.rect.top() + (opt.rect.height() / 2 - height / 2), opt.rect.width() - m_iconSize - LATERAL_MARGIN * 2, opt.fontMetrics.height()); | ||
232 | painter->drawText(rectText, Qt::AlignLeft | Qt::AlignTop, opt.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width())); | 244 | painter->drawText(rectText, Qt::AlignLeft | Qt::AlignTop, opt.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width())); | ||
233 | QRect capacityRect(isLTR ? rectText.x() : LATERAL_MARGIN, rectText.bottom() - 1, rectText.width() - LATERAL_MARGIN, CAPACITYBAR_HEIGHT); | 245 | QRect capacityRect(isLTR ? rectText.x() : LATERAL_MARGIN, rectText.bottom() - 1, rectText.width() - LATERAL_MARGIN, CAPACITYBAR_HEIGHT); | ||
234 | KCapacityBar capacityBar(KCapacityBar::DrawTextInline); | 246 | KCapacityBar capacityBar(KCapacityBar::DrawTextInline); | ||
235 | capacityBar.setValue((info.used() * 100) / info.size()); | 247 | capacityBar.setValue((info.used * 100) / info.size); | ||
236 | capacityBar.drawCapacityBar(painter, capacityRect); | 248 | capacityBar.drawCapacityBar(painter, capacityRect); | ||
237 | 249 | | |||
238 | painter->restore(); | 250 | painter->restore(); | ||
239 | 251 | | |||
240 | painter->save(); | 252 | painter->save(); | ||
241 | painter->setOpacity(painter->opacity() * (1 - contentsOpacity(index))); | 253 | painter->setOpacity(painter->opacity() * (1 - contentsOpacity(index))); | ||
242 | } | 254 | } | ||
255 | | ||||
256 | if (!info.job && | ||||
257 | (!info.lastUpdated.isValid() || info.lastUpdated.secsTo(QDateTime::currentDateTimeUtc()) > 60)) { | ||||
258 | info.job = KIO::fileSystemFreeSpace(url); | ||||
anthonyfieroni: You will get the job as lambda parameter. | |||||
Yes but he needs it for !info.job 3 lines above, to avoid starting multiple jobs for the same thing at the same time. dfaure: Yes but he needs it for !info.job 3 lines above, to avoid starting multiple jobs for the same… | |||||
259 | connect(info.job, &KIO::FileSystemFreeSpaceJob::result, this, [this, persistentIndex](KIO::Job *job, KIO::filesize_t size, KIO::filesize_t available) { | ||||
You can make lambda mutable in there you can modify m_freeSpaceInfo without declare it mutable anthonyfieroni: You can make lambda mutable in there you can modify m_freeSpaceInfo without declare it mutable | |||||
anthonyfieroni: No ignore it, it does not work. | |||||
260 | PlaceFreeSpaceInfo &info = m_freeSpaceInfo[persistentIndex]; | ||||
261 | | ||||
262 | // even if we receive an error we want to refresh lastUpdated to avoid repeatedly querying in this case | ||||
263 | info.lastUpdated = QDateTime::currentDateTimeUtc(); | ||||
264 | | ||||
265 | if (job->error()) { | ||||
dfaure: Usually written as
if (job->error()) | |||||
266 | return; | ||||
267 | } | ||||
268 | | ||||
269 | info.size = size; | ||||
270 | info.used = size - available; | ||||
271 | | ||||
272 | // FIXME scheduleDelayedItemsLayout but we're in the delegate here, not the view | ||||
273 | }); | ||||
274 | } | ||||
243 | } | 275 | } | ||
244 | } | 276 | } | ||
245 | 277 | | |||
246 | rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + opt.rect.left() | 278 | rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + opt.rect.left() | ||
247 | : 0, opt.rect.top(), opt.rect.width() - m_iconSize - LATERAL_MARGIN * 2, opt.rect.height()); | 279 | : 0, opt.rect.top(), opt.rect.width() - m_iconSize - LATERAL_MARGIN * 2, opt.rect.height()); | ||
248 | painter->drawText(rectText, Qt::AlignLeft | Qt::AlignVCenter, opt.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width())); | 280 | painter->drawText(rectText, Qt::AlignLeft | Qt::AlignVCenter, opt.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width())); | ||
249 | 281 | | |||
250 | if (drawCapacityBar) { | 282 | if (drawCapacityBar) { | ||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Line(s) | 397 | { | |||
379 | return false; | 411 | return false; | ||
380 | } | 412 | } | ||
381 | 413 | | |||
382 | void KFilePlacesViewDelegate::startDrag() | 414 | void KFilePlacesViewDelegate::startDrag() | ||
383 | { | 415 | { | ||
384 | m_dragStarted = true; | 416 | m_dragStarted = true; | ||
385 | } | 417 | } | ||
386 | 418 | | |||
419 | void KFilePlacesViewDelegate::clearFreeSpaceInfo() | ||||
420 | { | ||||
421 | m_freeSpaceInfo.clear(); | ||||
422 | } | ||||
423 | | ||||
387 | QString KFilePlacesViewDelegate::groupNameFromIndex(const QModelIndex &index) const | 424 | QString KFilePlacesViewDelegate::groupNameFromIndex(const QModelIndex &index) const | ||
388 | { | 425 | { | ||
389 | if (index.isValid()) { | 426 | if (index.isValid()) { | ||
390 | return index.data(KFilePlacesModel::GroupRole).toString(); | 427 | return index.data(KFilePlacesModel::GroupRole).toString(); | ||
391 | } else { | 428 | } else { | ||
392 | return QString(); | 429 | return QString(); | ||
393 | } | 430 | } | ||
394 | } | 431 | } | ||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Line(s) | 524 | public: | |||
506 | Solid::StorageAccess *lastClickedStorage = nullptr; | 543 | Solid::StorageAccess *lastClickedStorage = nullptr; | ||
507 | QPersistentModelIndex lastClickedIndex; | 544 | QPersistentModelIndex lastClickedIndex; | ||
508 | 545 | | |||
509 | QRect dropRect; | 546 | QRect dropRect; | ||
510 | 547 | | |||
511 | void setCurrentIndex(const QModelIndex &index); | 548 | void setCurrentIndex(const QModelIndex &index); | ||
512 | void adaptItemSize(); | 549 | void adaptItemSize(); | ||
513 | void updateHiddenRows(); | 550 | void updateHiddenRows(); | ||
551 | void clearFreeSpaceInfos(); | ||||
514 | bool insertAbove(const QRect &itemRect, const QPoint &pos) const; | 552 | bool insertAbove(const QRect &itemRect, const QPoint &pos) const; | ||
515 | bool insertBelow(const QRect &itemRect, const QPoint &pos) const; | 553 | bool insertBelow(const QRect &itemRect, const QPoint &pos) const; | ||
516 | int insertIndicatorHeight(int itemHeight) const; | 554 | int insertIndicatorHeight(int itemHeight) const; | ||
517 | void fadeCapacityBar(const QModelIndex &index, FadeType fadeType); | 555 | void fadeCapacityBar(const QModelIndex &index, FadeType fadeType); | ||
518 | int sectionsCount() const; | 556 | int sectionsCount() const; | ||
519 | 557 | | |||
520 | void addDisappearingItem(KFilePlacesViewDelegate *delegate, const QModelIndex &index); | 558 | void addDisappearingItem(KFilePlacesViewDelegate *delegate, const QModelIndex &index); | ||
521 | 559 | | |||
▲ Show 20 Lines • Show All 543 Lines • ▼ Show 20 Line(s) | |||||
1065 | void KFilePlacesView::setModel(QAbstractItemModel *model) | 1103 | void KFilePlacesView::setModel(QAbstractItemModel *model) | ||
1066 | { | 1104 | { | ||
1067 | QListView::setModel(model); | 1105 | QListView::setModel(model); | ||
1068 | d->updateHiddenRows(); | 1106 | d->updateHiddenRows(); | ||
1069 | // Uses Qt::QueuedConnection to delay the time when the slot will be | 1107 | // Uses Qt::QueuedConnection to delay the time when the slot will be | ||
1070 | // called. In case of an item move the remove+add will be done before | 1108 | // called. In case of an item move the remove+add will be done before | ||
1071 | // we adapt the item size (otherwise we'd get it wrong as we'd execute | 1109 | // we adapt the item size (otherwise we'd get it wrong as we'd execute | ||
1072 | // it after the remove only). | 1110 | // it after the remove only). | ||
1073 | connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), | 1111 | connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), | ||
I think David F means you should connect here and expunge dead entries. davidedmundson: I think David F means you should connect here and expunge dead entries. | |||||
and clear the map in this method. But I see that calling setModel twice isn't really supported properly anyway (no disconnects). dfaure: and clear the map in this method.
But I see that calling setModel twice isn't really supported… | |||||
1074 | this, SLOT(adaptItemSize()), Qt::QueuedConnection); | 1112 | this, SLOT(adaptItemSize()), Qt::QueuedConnection); | ||
1075 | connect(selectionModel(), &QItemSelectionModel::currentChanged, | 1113 | connect(selectionModel(), &QItemSelectionModel::currentChanged, | ||
1076 | d->watcher, &KFilePlacesEventWatcher::currentIndexChanged); | 1114 | d->watcher, &KFilePlacesEventWatcher::currentIndexChanged); | ||
1115 | | ||||
1116 | static_cast<KFilePlacesViewDelegate *>(itemDelegate())->clearFreeSpaceInfo(); | ||||
1077 | } | 1117 | } | ||
1078 | 1118 | | |||
1079 | void KFilePlacesView::rowsInserted(const QModelIndex &parent, int start, int end) | 1119 | void KFilePlacesView::rowsInserted(const QModelIndex &parent, int start, int end) | ||
1080 | { | 1120 | { | ||
1081 | QListView::rowsInserted(parent, start, end); | 1121 | QListView::rowsInserted(parent, start, end); | ||
1082 | setUrl(d->currentUrl); | 1122 | setUrl(d->currentUrl); | ||
1083 | 1123 | | |||
1084 | KFilePlacesViewDelegate *delegate = static_cast<KFilePlacesViewDelegate *>(itemDelegate()); | 1124 | KFilePlacesViewDelegate *delegate = static_cast<KFilePlacesViewDelegate *>(itemDelegate()); | ||
▲ Show 20 Lines • Show All 394 Lines • Show Last 20 Lines |
You will get the job as lambda parameter.