[graphics/koko/release/26.08] src: Disallow selection and file actions when presenting collections
Oliver Beard <[email protected]> Tue, 4 Aug 2026 13:30:43 +0000 (UTC)
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit d5cf4d6dc7fe07c6eeaa61162ac489881cfe8b9c by Oliver Beard.
Committed on 04/08/2026 at 13:25.
Pushed by olib into branch 'release/26.08'.
Disallow selection and file actions when presenting collections
Collections are virtual folders. Their URL is reported so as to show a preview, but corresponds to an actual file. That file shouldn't be acted upon for file actions nor is selection relevant.
M +5 -0 src/models/abstractgallerymodel.cpp
M +4 -0 src/models/abstractgallerymodel.h
M +6 -0 src/models/gallerylocationmodel.cpp
M +2 -0 src/models/gallerylocationmodel.h
M +6 -0 src/models/gallerytagsmodel.cpp
M +2 -0 src/models/gallerytagsmodel.h
M +6 -0 src/models/gallerytimemodel.cpp
M +2 -0 src/models/gallerytimemodel.h
M +28 -12 src/qml/gallery/GalleryPage.qml
https://invent.kde.org/graphics/koko/-/commit/d5cf4d6dc7fe07c6eeaa61162ac489881cfe8b9c
diff --git a/src/models/abstractgallerymodel.cpp b/src/models/abstractgallerymodel.cpp
index afa74806..72dc7f8b 100644
--- a/src/models/abstractgallerymodel.cpp
+++ b/src/models/abstractgallerymodel.cpp
@@ -17,6 +17,11 @@ AbstractGalleryModel::Status AbstractGalleryModel::status() const
return Loaded;
}
+bool AbstractGalleryModel::showingCollections() const
+{
+ return false;
+}
+
QHash<int, QByteArray> AbstractGalleryModel::roleNames() const
{
QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
diff --git a/src/models/abstractgallerymodel.h b/src/models/abstractgallerymodel.h
index edc16f46..dd96ff2a 100644
--- a/src/models/abstractgallerymodel.h
+++ b/src/models/abstractgallerymodel.h
@@ -23,6 +23,7 @@ class AbstractGalleryModel : public QAbstractListModel
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(bool showingCollections READ showingCollections NOTIFY showingCollectionsChanged)
public:
~AbstractGalleryModel() = default;
@@ -60,11 +61,14 @@ public:
// For models which are not immediately populated
virtual Status status() const;
+ virtual bool showingCollections() const;
+
QHash<int, QByteArray> roleNames() const override;
Q_SIGNALS:
void titleChanged();
void statusChanged();
+ void showingCollectionsChanged();
protected:
explicit AbstractGalleryModel(QObject *parent = nullptr);
diff --git a/src/models/gallerylocationmodel.cpp b/src/models/gallerylocationmodel.cpp
index bae8dc88..462e9e0e 100644
--- a/src/models/gallerylocationmodel.cpp
+++ b/src/models/gallerylocationmodel.cpp
@@ -35,6 +35,7 @@ GalleryLocationModel::GalleryLocationModel(QObject *parent)
, m_mode(None)
{
connect(this, &GalleryLocationModel::pathChanged, this, &GalleryLocationModel::titleChanged);
+ connect(this, &GalleryLocationModel::pathChanged, this, &GalleryLocationModel::showingCollectionsChanged);
connect(ImageStorage::instance(), &ImageStorage::storageModified, this, [this]() {
populate(m_path);
});
@@ -104,6 +105,11 @@ QVariant GalleryLocationModel::pathForIndex(const QModelIndex &index) const
}
}
+bool GalleryLocationModel::showingCollections() const
+{
+ return m_mode != FileItemMode;
+}
+
QVariant GalleryLocationModel::data(const QModelIndex &index, int role) const
{
Q_ASSERT(checkIndex(index, CheckIndexOption::ParentIsInvalid | CheckIndexOption::IndexIsValid));
diff --git a/src/models/gallerylocationmodel.h b/src/models/gallerylocationmodel.h
index 438c9cfb..2cf007e6 100644
--- a/src/models/gallerylocationmodel.h
+++ b/src/models/gallerylocationmodel.h
@@ -32,6 +32,8 @@ public:
Q_INVOKABLE QVariant pathForIndex(const QModelIndex &index) const override;
+ bool showingCollections() const override;
+
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = {}) const override;
diff --git a/src/models/gallerytagsmodel.cpp b/src/models/gallerytagsmodel.cpp
index 07e6ed5f..2f4686eb 100644
--- a/src/models/gallerytagsmodel.cpp
+++ b/src/models/gallerytagsmodel.cpp
@@ -15,6 +15,7 @@ GalleryTagsModel::GalleryTagsModel(QObject *parent)
, m_mode(None)
{
connect(this, &GalleryTagsModel::pathChanged, this, &GalleryTagsModel::titleChanged);
+ connect(this, &GalleryTagsModel::pathChanged, this, &GalleryTagsModel::showingCollectionsChanged);
connect(ImageStorage::instance(), &ImageStorage::storageModified, this, [this]() {
populate(m_path);
});
@@ -67,6 +68,11 @@ QVariant GalleryTagsModel::pathForIndex(const QModelIndex &index) const
}
}
+bool GalleryTagsModel::showingCollections() const
+{
+ return m_mode != FileItemMode;
+}
+
QVariant GalleryTagsModel::data(const QModelIndex &index, int role) const
{
Q_ASSERT(checkIndex(index, CheckIndexOption::ParentIsInvalid | CheckIndexOption::IndexIsValid));
diff --git a/src/models/gallerytagsmodel.h b/src/models/gallerytagsmodel.h
index baa05d39..3469830a 100644
--- a/src/models/gallerytagsmodel.h
+++ b/src/models/gallerytagsmodel.h
@@ -30,6 +30,8 @@ public:
Q_INVOKABLE QVariant pathForIndex(const QModelIndex &index) const override;
+ bool showingCollections() const override;
+
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = {}) const override;
diff --git a/src/models/gallerytimemodel.cpp b/src/models/gallerytimemodel.cpp
index 26fe3cfc..45c14f70 100644
--- a/src/models/gallerytimemodel.cpp
+++ b/src/models/gallerytimemodel.cpp
@@ -37,6 +37,7 @@ GalleryTimeModel::GalleryTimeModel(QObject *parent)
, m_mode(None)
{
connect(this, &GalleryTimeModel::pathChanged, this, &GalleryTimeModel::titleChanged);
+ connect(this, &GalleryTimeModel::pathChanged, this, &GalleryTimeModel::showingCollectionsChanged);
connect(ImageStorage::instance(), &ImageStorage::storageModified, this, [this]() {
populate(m_path);
});
@@ -108,6 +109,11 @@ QVariant GalleryTimeModel::pathForIndex(const QModelIndex &index) const
}
}
+bool GalleryTimeModel::showingCollections() const
+{
+ return m_mode != FileItemMode;
+}
+
QVariant GalleryTimeModel::data(const QModelIndex &index, int role) const
{
Q_ASSERT(checkIndex(index, CheckIndexOption::ParentIsInvalid | CheckIndexOption::IndexIsValid));
diff --git a/src/models/gallerytimemodel.h b/src/models/gallerytimemodel.h
index 3f7d22bc..5358d3ea 100644
--- a/src/models/gallerytimemodel.h
+++ b/src/models/gallerytimemodel.h
@@ -32,6 +32,8 @@ public:
Q_INVOKABLE QVariant pathForIndex(const QModelIndex &index) const override;
+ bool showingCollections() const override;
+
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = {}) const override;
diff --git a/src/qml/gallery/GalleryPage.qml b/src/qml/gallery/GalleryPage.qml
index 28c8e659..815c8079 100644
--- a/src/qml/gallery/GalleryPage.qml
+++ b/src/qml/gallery/GalleryPage.qml
@@ -39,6 +39,7 @@ Kirigami.ScrollablePage {
property list<var> navigationHistory: []
property int navigationIndex: -1
+ property bool showingCollections: galleryModel.showingCollections
property bool selectionMode: selectionModel.hasSelection
Component.onCompleted: {
@@ -365,56 +366,56 @@ Kirigami.ScrollablePage {
readonly property list<Kirigami.Action> fileMenuActions: [
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canSaveAs
+ enabled: fileMenuManager.enabled && fileMenuManager.canSaveAs && !page.showingCollections
visible: enabled
AC.ActionCollection.action: AC.StandardActionData.SaveAs
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canOpenFolder
+ enabled: fileMenuManager.enabled && fileMenuManager.canOpenFolder && !page.showingCollections
visible: enabled
AC.ActionCollection.action: "OpenFolder"
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canOpenWith
+ enabled: fileMenuManager.enabled && fileMenuManager.canOpenWith && !page.showingCollections
visible: enabled
AC.ActionCollection.action: "OpenWith"
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canCopy
+ enabled: fileMenuManager.enabled && fileMenuManager.canCopy && !page.showingCollections
visible: enabled
AC.ActionCollection.action: AC.StandardActionData.Copy
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canCopyPath
+ enabled: fileMenuManager.enabled && fileMenuManager.canCopyPath && !page.showingCollections
visible: enabled
AC.ActionCollection.action: "CopyPath"
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canMoveToTrash
+ enabled: fileMenuManager.enabled && fileMenuManager.canMoveToTrash && !page.showingCollections
visible: enabled
AC.ActionCollection.action: AC.StandardActionData.MoveToTrash
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canDeleteFile
+ enabled: fileMenuManager.enabled && fileMenuManager.canDeleteFile && !page.showingCollections
visible: enabled
AC.ActionCollection.action: AC.StandardActionData.DeleteFile
AC.ActionCollection.collection: "org.kde.koko.mediaview"
},
Kirigami.Action {
displayHint: Kirigami.DisplayHint.AlwaysHide
- enabled: fileMenuManager.enabled && fileMenuManager.canPrint
+ enabled: fileMenuManager.enabled && fileMenuManager.canPrint && !page.showingCollections
visible: enabled
AC.ActionCollection.action: AC.StandardActionData.Print
AC.ActionCollection.collection: "org.kde.koko.mediaview"
@@ -430,16 +431,15 @@ Kirigami.ScrollablePage {
id: selectAllAction
AC.ActionCollection.action: AC.StandardActionData.SelectAll
AC.ActionCollection.collection: "org.kde.koko.gallery"
- enabled: page.visible && !page.isEmpty && !page.disallowMassSelection
+ enabled: page.visible && !page.isEmpty && !page.showingCollections && !page.disallowMassSelection
displayHint: Kirigami.DisplayHint.AlwaysHide
onTriggered: selectionModel.select(gridView.model.index(0, 0), ItemSelectionModel.Select | ItemSelectionModel.Columns)
-
},
Kirigami.Action {
id: deselectAllAction
AC.ActionCollection.action: AC.StandardActionData.Deselect
AC.ActionCollection.collection: "org.kde.koko.gallery"
- enabled: page.visible && !page.isEmpty && !page.disallowMassSelection
+ enabled: page.visible && !page.isEmpty && !page.showingCollections && !page.disallowMassSelection
displayHint: Kirigami.DisplayHint.AlwaysHide
onTriggered: selectionModel.clearSelection()
},
@@ -447,7 +447,7 @@ Kirigami.ScrollablePage {
id: invertSelectionAction
AC.ActionCollection.action: "InvertSelection"
AC.ActionCollection.collection: "org.kde.koko.gallery"
- enabled: page.visible && !page.isEmpty && !page.disallowMassSelection
+ enabled: page.visible && !page.isEmpty && !page.showingCollections && !page.disallowMassSelection
displayHint: Kirigami.DisplayHint.AlwaysHide
onTriggered: selectionModel.select(gridView.model.index(0, 0), ItemSelectionModel.Toggle | ItemSelectionModel.Columns)
}
@@ -712,11 +712,19 @@ Kirigami.ScrollablePage {
}
function select() {
+ if (page.showingCollections) {
+ return;
+ }
+
gridView.currentIndex = delegate.index;
selectionModel.select(gridView.model.index(index, 0), ItemSelectionModel.ClearAndSelect);
}
function shiftSelect() {
+ if (page.showingCollections) {
+ return;
+ }
+
let fromIndex = Math.min(gridView.currentIndex, delegate.index);
let toIndex = Math.max(gridView.currentIndex, delegate.index);
@@ -727,11 +735,19 @@ Kirigami.ScrollablePage {
}
function ctrlSelect() {
+ if (page.showingCollections) {
+ return;
+ }
+
gridView.currentIndex = delegate.index;
selectionModel.select(gridView.model.index(index, 0), ItemSelectionModel.Toggle);
}
function showMenu() {
+ if (page.showingCollections) {
+ return;
+ }
+
gridView.currentIndex = delegate.index;
if (!selectionModel.selectedIndexes.includes(gridView.model.index(index, 0))) {
selectionModel.select(gridView.model.index(index, 0), ItemSelectionModel.ClearAndSelect);