┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/kitemviews
diff options
context:
space:
mode:
Diffstat (limited to 'src/kitemviews')
-rw-r--r--src/kitemviews/kfileitemlistwidget.cpp43
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp4
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp8
-rw-r--r--src/kitemviews/kitemlistview.cpp54
-rw-r--r--src/kitemviews/kitemlistview.h3
-rw-r--r--src/kitemviews/private/kbaloorolesprovider.cpp135
-rw-r--r--src/kitemviews/private/kbaloorolesprovider.h10
-rw-r--r--src/kitemviews/private/kdirectorycontentscounterworker.cpp1
8 files changed, 169 insertions, 89 deletions
diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp
index 69a40ddf3..1b38176cc 100644
--- a/src/kitemviews/kfileitemlistwidget.cpp
+++ b/src/kitemviews/kfileitemlistwidget.cpp
@@ -47,41 +47,50 @@ QString KFileItemListWidgetInformant::roleText(const QByteArray& role,
{
QString text;
const QVariant roleValue = values.value(role);
+ QLocale local;
+ KFormat formatter(local);
// Implementation note: In case if more roles require a custom handling
// use a hash + switch for a linear runtime.
+ auto formatDate = [formatter, local](const QDateTime& time) {
+ if (DetailsModeSettings::useShortRelativeDates()) {
+ return formatter.formatRelativeDateTime(time, QLocale::ShortFormat);
+ } else {
+ return local.toString(time, QLocale::ShortFormat);
+ }
+ };
+
if (role == "size") {
if (values.value("isDir").toBool()) {
- // The item represents a directory.
- if (!roleValue.isNull()) {
- const int count = values.value("count").toInt();
- if (count > 0) {
- if (DetailsModeSettings::directorySizeCount()) {
- // Show the number of sub directories instead of the file size of the directory.
- text = i18ncp("@item:intable", "%1 item", "%1 items", count);
- } else {
- // if we have directory size available
- if (roleValue != -1) {
- const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
- text = KFormat().formatByteSize(size);
- }
- }
+ if (!roleValue.isNull() && roleValue != -1) {
+ // The item represents a directory.
+ if (DetailsModeSettings::directorySizeCount()) {
+ // Show the number of sub directories instead of the file size of the directory.
+ const int count = values.value("count").toInt();
+ text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+ } else {
+ // if we have directory size available
+ const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
+ text = formatter.formatByteSize(size);
}
}
} else {
const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
- text = KFormat().formatByteSize(size);
+ text = formatter.formatByteSize(size);
}
} else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") {
bool ok;
const long long time = roleValue.toLongLong(&ok);
if (ok && time != -1) {
- return QLocale().toString(QDateTime::fromSecsSinceEpoch(time), QLocale::ShortFormat);
+ const QDateTime dateTime = QDateTime::fromSecsSinceEpoch(time);
+ text = formatDate(dateTime);
}
} else if (role == "deletiontime" || role == "imageDateTime") {
const QDateTime dateTime = roleValue.toDateTime();
- text = QLocale().toString(dateTime, QLocale::ShortFormat);
+ if (dateTime.isValid()) {
+ text = formatDate(dateTime);
+ }
} else {
text = KStandardItemListWidgetInformant::roleText(role, values);
}
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 566f228f6..42788d2fe 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -776,9 +776,7 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin
if (getSizeRole) {
data.insert("count", count);
- if (size != -1) {
- data.insert("size", QVariant::fromValue(size));
- }
+ data.insert("size", QVariant::fromValue(size));
}
if (getIsExpandableRole) {
data.insert("isExpandable", count > 0);
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index 5c9a2bbdd..8687872ee 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -1550,8 +1550,9 @@ bool KItemListController::onRelease(const QPointF& pos, const Qt::KeyboardModifi
return true;
}
+ const bool controlPressed = modifiers & Qt::ControlModifier;
const bool shiftOrControlPressed = modifiers & Qt::ShiftModifier ||
- modifiers & Qt::ControlModifier;
+ controlPressed;
KItemListRubberBand* rubberBand = m_view->rubberBand();
if (rubberBand->isActive()) {
@@ -1585,6 +1586,11 @@ bool KItemListController::onRelease(const QPointF& pos, const Qt::KeyboardModifi
} else if (shiftOrControlPressed) {
// The mouse click should only update the selection, not trigger the item
emitItemActivated = false;
+ // When Ctrl-clicking an item when in single selection mode
+ // i.e. where Ctrl won't change the selection, pretend it was middle clicked
+ if (controlPressed && m_selectionBehavior == SingleSelection) {
+ Q_EMIT itemMiddleClicked(index);
+ }
} else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) {
if (touch) {
emitItemActivated = true;
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index f6e5e666b..96c337de3 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -27,6 +27,7 @@
#include <QPropertyAnimation>
#include <QStyleOptionRubberBand>
#include <QTimer>
+#include <QVariantAnimation>
namespace {
@@ -36,6 +37,11 @@ namespace {
// Delay in ms for triggering the next autoscroll
const int RepeatingAutoScrollDelay = 1000 / 60;
+
+ // Copied from the Kirigami.Units.shortDuration
+ const int RubberFadeSpeed = 150;
+
+ const char* RubberPropertyName = "_kitemviews_rubberBandPosition";
}
#ifndef QT_NO_ACCESSIBILITY
@@ -660,6 +666,30 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
{
QGraphicsWidget::paint(painter, option, widget);
+ for (auto animation : qAsConst(m_rubberBandAnimations)) {
+ QRectF rubberBandRect = animation->property(RubberPropertyName).toRectF();
+
+ const QPointF topLeft = rubberBandRect.topLeft();
+ if (scrollOrientation() == Qt::Vertical) {
+ rubberBandRect.moveTo(topLeft.x(), topLeft.y() - scrollOffset());
+ } else {
+ rubberBandRect.moveTo(topLeft.x() - scrollOffset(), topLeft.y());
+ }
+
+ QStyleOptionRubberBand opt;
+ initStyleOption(&opt);
+ opt.shape = QRubberBand::Rectangle;
+ opt.opaque = false;
+ opt.rect = rubberBandRect.toRect();
+
+ painter->save();
+
+ painter->setOpacity(animation->currentValue().toReal());
+ style()->drawControl(QStyle::CE_RubberBand, &opt, painter);
+
+ painter->restore();
+ }
+
if (m_rubberBand->isActive()) {
QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
m_rubberBand->endPosition()).normalized();
@@ -1455,6 +1485,30 @@ void KItemListView::slotRubberBandActivationChanged(bool active)
connect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = true;
} else {
+ QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
+ m_rubberBand->endPosition()).normalized();
+
+ auto animation = new QVariantAnimation(this);
+ animation->setStartValue(1.0);
+ animation->setEndValue(0.0);
+ animation->setDuration(RubberFadeSpeed);
+ animation->setProperty(RubberPropertyName, rubberBandRect);
+
+ QEasingCurve curve;
+ curve.setType(QEasingCurve::BezierSpline);
+ curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(1.0, 1.0), QPointF(1.0, 1.0));
+ animation->setEasingCurve(curve);
+
+ connect(animation, &QVariantAnimation::valueChanged, this, [=](const QVariant&) {
+ update();
+ });
+ connect(animation, &QVariantAnimation::finished, this, [=]() {
+ m_rubberBandAnimations.removeAll(animation);
+ delete animation;
+ });
+ animation->start();
+ m_rubberBandAnimations << animation;
+
disconnect(m_rubberBand, &KItemListRubberBand::startPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
disconnect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = false;
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index df582aad0..e6bf5ad90 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -32,6 +32,7 @@ class KItemListWidgetInformant;
class KItemListWidgetCreatorBase;
class QTimer;
class QPropertyAnimation;
+class QVariantAnimation;
/**
* @brief Represents the view of an item-list.
@@ -747,6 +748,8 @@ private:
// by KItemListView::showDropIndicator() and KItemListView::hideDropIndicator().
QRectF m_dropIndicator;
+ QList<QVariantAnimation*> m_rubberBandAnimations;
+
friend class KItemListContainer; // Accesses scrollBarRequired()
friend class KItemListHeader; // Accesses m_headerWidget
friend class KItemListController;
diff --git a/src/kitemviews/private/kbaloorolesprovider.cpp b/src/kitemviews/private/kbaloorolesprovider.cpp
index d45b06777..5c87de712 100644
--- a/src/kitemviews/private/kbaloorolesprovider.cpp
+++ b/src/kitemviews/private/kbaloorolesprovider.cpp
@@ -10,13 +10,52 @@
#include <Baloo/File>
#include <KFileMetaData/PropertyInfo>
#include <KFileMetaData/UserMetaData>
-#include <KFormat>
-#include <KLocalizedString>
#include <QCollator>
#include <QDebug>
#include <QTime>
+namespace {
+ QString tagsFromValues(const QStringList& values)
+ {
+ if (values.size() == 1) {
+ return values.at(0);
+ }
+
+ QStringList alphabeticalOrderTags = values;
+ QCollator coll;
+ coll.setNumericMode(true);
+ std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
+ return alphabeticalOrderTags.join(QLatin1String(", "));
+ }
+
+ using Property = KFileMetaData::Property::Property;
+ // Mapping from the KFM::Property to the KFileItemModel roles.
+ const QHash<Property, QByteArray> propertyRoleMap() {
+ static const auto map = QHash<Property, QByteArray> {
+ { Property::Rating, QByteArrayLiteral("rating") },
+ { Property::Comment, QByteArrayLiteral("comment") },
+ { Property::Title, QByteArrayLiteral("title") },
+ { Property::WordCount, QByteArrayLiteral("wordCount") },
+ { Property::LineCount, QByteArrayLiteral("lineCount") },
+ { Property::Width, QByteArrayLiteral("width") },
+ { Property::Height, QByteArrayLiteral("height") },
+ { Property::ImageDateTime, QByteArrayLiteral("imageDateTime") },
+ { Property::ImageOrientation, QByteArrayLiteral("orientation") },
+ { Property::Artist, QByteArrayLiteral("artist") },
+ { Property::Genre, QByteArrayLiteral("genre") },
+ { Property::Album, QByteArrayLiteral("album") },
+ { Property::Duration, QByteArrayLiteral("duration") },
+ { Property::BitRate, QByteArrayLiteral("bitrate") },
+ { Property::AspectRatio, QByteArrayLiteral("aspectRatio") },
+ { Property::FrameRate, QByteArrayLiteral("frameRate") },
+ { Property::ReleaseYear, QByteArrayLiteral("releaseYear") },
+ { Property::TrackNumber, QByteArrayLiteral("track") }
+ };
+ return map;
+ }
+}
+
struct KBalooRolesProviderSingleton
{
KBalooRolesProvider instance;
@@ -50,17 +89,17 @@ QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& f
while (rangeBegin != propMap.constKeyValueEnd()) {
auto key = (*rangeBegin).first;
- const KFileMetaData::PropertyInfo propertyInfo(key);
- const QByteArray role = roleForProperty(propertyInfo.name());
auto rangeEnd = std::find_if(rangeBegin, propMap.constKeyValueEnd(),
[key](const entry& e) { return e.first != key; });
+ const QByteArray role = propertyRoleMap().value(key);
if (role.isEmpty() || !roles.contains(role)) {
rangeBegin = rangeEnd;
continue;
}
+ const KFileMetaData::PropertyInfo propertyInfo(key);
auto distance = std::distance(rangeBegin, rangeEnd);
if (distance > 1) {
QVariantList list;
@@ -78,74 +117,54 @@ QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& f
rangeBegin = rangeEnd;
}
- KFileMetaData::UserMetaData md(file.path());
+ KFileMetaData::UserMetaData::Attributes attributes;
if (roles.contains("tags")) {
- values.insert("tags", tagsFromValues(md.tags()));
+ attributes |= KFileMetaData::UserMetaData::Tags;
}
if (roles.contains("rating")) {
- values.insert("rating", QString::number(md.rating()));
+ attributes |= KFileMetaData::UserMetaData::Rating;
}
if (roles.contains("comment")) {
- values.insert("comment", md.userComment());
+ attributes |= KFileMetaData::UserMetaData::Comment;
}
if (roles.contains("originUrl")) {
+ attributes |= KFileMetaData::UserMetaData::OriginUrl;
+ }
+
+ if (attributes == KFileMetaData::UserMetaData::None) {
+ return values;
+ }
+
+ KFileMetaData::UserMetaData md(file.path());
+ attributes = md.queryAttributes(attributes);
+
+ if (attributes & KFileMetaData::UserMetaData::Tags) {
+ values.insert("tags", tagsFromValues(md.tags()));
+ }
+ if (attributes & KFileMetaData::UserMetaData::Rating) {
+ values.insert("rating", QString::number(md.rating()));
+ }
+ if (attributes & KFileMetaData::UserMetaData::Comment) {
+ values.insert("comment", md.userComment());
+ }
+ if (attributes & KFileMetaData::UserMetaData::OriginUrl) {
values.insert("originUrl", md.originUrl());
}
return values;
}
-QByteArray KBalooRolesProvider::roleForProperty(const QString& property) const
+KBalooRolesProvider::KBalooRolesProvider()
{
- return m_roleForProperty.value(property);
-}
-
-KBalooRolesProvider::KBalooRolesProvider() :
- m_roles(),
- m_roleForProperty()
-{
- struct PropertyInfo
- {
- const char* const property;
- const char* const role;
- };
-
- // Mapping from the URIs to the KFileItemModel roles. Note that this must not be
- // a 1:1 mapping: One role may contain several URI-values
- static const PropertyInfo propertyInfoList[] = {
- { "rating", "rating" },
- { "tag", "tags" },
- { "comment", "comment" },
- { "title", "title" },
- { "wordCount", "wordCount" },
- { "lineCount", "lineCount" },
- { "width", "width" },
- { "height", "height" },
- { "imageDateTime", "imageDateTime"},
- { "imageOrientation", "orientation", },
- { "artist", "artist" },
- { "genre", "genre" },
- { "album", "album" },
- { "duration", "duration" },
- { "bitRate", "bitrate" },
- { "aspectRatio", "aspectRatio" },
- { "frameRate", "frameRate" },
- { "releaseYear", "releaseYear" },
- { "trackNumber", "track" },
- { "originUrl", "originUrl" }
- };
-
- for (unsigned int i = 0; i < sizeof(propertyInfoList) / sizeof(PropertyInfo); ++i) {
- m_roleForProperty.insert(propertyInfoList[i].property, propertyInfoList[i].role);
- m_roles.insert(propertyInfoList[i].role);
+ // Display roles filled from Baloo property cache
+ for (const auto& role : propertyRoleMap()) {
+ m_roles.insert(role);
}
-}
-QString KBalooRolesProvider::tagsFromValues(const QStringList& values) const
-{
- QStringList alphabeticalOrderTags = values;
- QCollator coll;
- coll.setNumericMode(true);
- std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
- return alphabeticalOrderTags.join(QLatin1String(", "));
+ // Display roles provided by UserMetaData
+ m_roles.insert(QByteArrayLiteral("tags"));
+ m_roles.insert(QByteArrayLiteral("rating"));
+ m_roles.insert(QByteArrayLiteral("comment"));
+ m_roles.insert(QByteArrayLiteral("originUrl"));
}
+
diff --git a/src/kitemviews/private/kbaloorolesprovider.h b/src/kitemviews/private/kbaloorolesprovider.h
index 99c601e16..97ed58f2b 100644
--- a/src/kitemviews/private/kbaloorolesprovider.h
+++ b/src/kitemviews/private/kbaloorolesprovider.h
@@ -42,21 +42,11 @@ public:
QHash<QByteArray, QVariant> roleValues(const Baloo::File& file,
const QSet<QByteArray>& roles) const;
- QByteArray roleForProperty(const QString& property) const;
-
protected:
KBalooRolesProvider();
private:
- /**
- * @return User visible string for the given tag-values.
- * The tag-values are sorted in alphabetical order.
- */
- QString tagsFromValues(const QStringList& values) const;
-
-private:
QSet<QByteArray> m_roles;
- QHash<QString, QByteArray> m_roleForProperty;
friend struct KBalooRolesProviderSingleton;
};
diff --git a/src/kitemviews/private/kdirectorycontentscounterworker.cpp b/src/kitemviews/private/kdirectorycontentscounterworker.cpp
index 1e3b7ff9f..73799e739 100644
--- a/src/kitemviews/private/kdirectorycontentscounterworker.cpp
+++ b/src/kitemviews/private/kdirectorycontentscounterworker.cpp
@@ -35,6 +35,7 @@ KDirectoryContentsCounterWorker::CountResult walkDir(const QString &dirPath,
auto dir = QT_OPENDIR(QFile::encodeName(dirPath));
if (dir) {
count = 0;
+ size = 0;
QT_STATBUF buf;
while ((dirEntry = QT_READDIR(dir))) {