diff --git a/qml/DirImageGrid.qml b/qml/DirImageGrid.qml new file mode 100644 --- /dev/null +++ b/qml/DirImageGrid.qml @@ -0,0 +1,73 @@ +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.0 + +import org.kde.koko 0.1 as Koko + +ScrollView { + id: root + property alias model: dirModel + property alias index: view.currentIndex + signal imageSelected(string filePath, int index) + + // Without this the GridView will not get focus + // See QTBUG-31976 + flickableItem.interactive: true + + AutomaticSpacingGrid { + id: view + anchors.fill: parent + + focus: true + minRowSpacing: 5 + minColumnSpacing: 5 + cacheBuffer: 10000 + + delegate: Item { + width: view.cellWidth + height: view.cellHeight + + Image { + source: model.url //dirModel.checkType( model.mimeType, model.url) + asynchronous: true + fillMode: Image.PreserveAspectCrop + + width: 300 + height: 300 + sourceSize: Qt.size(300, 300) + anchors.centerIn: parent + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onClicked: root.imageSelected(model.url, model.index) + onEntered: view.currentIndex = model.index + } + + SystemPalette { id: sysPal; } + Rectangle { + id: borderRect + anchors.fill: parent + color: "#00000000" + radius: 2 + + antialiasing: true + border.color: view.currentIndex == index ? sysPal.highlight : "grey" + border.width: view.currentIndex == index ? 5 : 1 + } + } + + Keys.onEnterPressed: root.imageSelected(model.url, model.index) + Keys.onReturnPressed: root.imageSelected(model.url, model.index) + } + + model: Koko.DirModel{ + id: dirModel + } + } + + function positionViewAtIndex(index, mode) { + view.positionViewAtIndex(index, mode) + } +} diff --git a/qml/DirImageViewer.qml b/qml/DirImageViewer.qml new file mode 100644 --- /dev/null +++ b/qml/DirImageViewer.qml @@ -0,0 +1,15 @@ +import QtQuick 2.3 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.0 as QtControls + +import org.kde.plasma.components 2.0 as PlasmaComponents + +ListView { + + orientation: ListView.Horizontal + + delegate: Image { + source: model.url + } + model: model +} diff --git a/qml/main.qml b/qml/main.qml --- a/qml/main.qml +++ b/qml/main.qml @@ -222,7 +222,6 @@ } checkable: true exclusiveGroup: group - checked: true } } } @@ -310,6 +309,28 @@ } } } + + Component { + id: dirImageViewer + DirImageViewer { + objectName: "dirImageViewer" + } + } + + Component { + id: dirImageGrid + DirImageGrid { + onImageSelected: { + view.push({ + item: dirImageViewer, + properties: { focus: true, + model: model, + filePath: filePath, + currentIndex: index } + }) + } + } + } Component { id: firstRun @@ -379,7 +400,7 @@ toolBar.enabled = true push({ - item: folderImages, + item: dirImageGrid, replace: true, properties: { focus: true } }) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,6 +76,7 @@ imagefoldermodel.cpp sortmodel.cpp allimagesmodel.cpp + dirmodel.cpp ) add_library (kokoqmlplugin SHARED ${qml_plugin_SRCS}) @@ -85,6 +86,7 @@ KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets + KF5::KIONTLM kokocommon ) diff --git a/src/dirmodel.h b/src/dirmodel.h new file mode 100644 --- /dev/null +++ b/src/dirmodel.h @@ -0,0 +1,43 @@ +#ifndef DIRMODEL_H +#define DIRMODEL_H + +#include +#include +#include + +class DirModel : public KDirModel +{ + Q_OBJECT + Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) + +public: + enum Roles { + UrlRole = Qt::UserRole + 1, + MimeTypeRole = Qt::UserRole + 2, + }; + + DirModel(QObject* parent=0); + virtual ~DirModel(); + + QHash roleNames() const override; + + void setUrl(const QString& url); + QString url() const; + + QVariant data(const QModelIndex &index, int role) const; + int count() const {return rowCount();} + + Q_INVOKABLE int indexForUrl(const QString &url) const; + Q_INVOKABLE QVariantMap get(int index) const; + Q_INVOKABLE QUrl checkType(const QString& type, const QString& url); + +Q_SIGNALS: + void countChanged(); + void urlChanged(); + +private: + QStringList m_mimeTypes; +}; + +#endif // DIRMODEL_H diff --git a/src/dirmodel.cpp b/src/dirmodel.cpp new file mode 100644 --- /dev/null +++ b/src/dirmodel.cpp @@ -0,0 +1,124 @@ +#include "dirmodel.h" + +#include +#include +#include +#include + +DirModel::DirModel(QObject *parent) +: KDirModel(parent) +{ + dirLister()->openUrl(QUrl::fromLocalFile(KShell::tildeExpand("~/Pictures")), KCoreDirLister::Keep); + + QMimeDatabase db; + QList mimeList = db.allMimeTypes(); + + //m_mimeTypes << "inode/directory"; + foreach (const QMimeType &mime, mimeList) { + if (mime.name().startsWith(QStringLiteral("image/"))) { + m_mimeTypes << mime.name(); + } + } + + dirLister()->setMimeFilter(m_mimeTypes); + + //m_imageCache = new KImageCache(QStringLiteral("org.kde.dirmodel-qml"), 10485760); + + connect(this, &QAbstractItemModel::rowsInserted, + this, &DirModel::countChanged); + connect(this, &QAbstractItemModel::rowsRemoved, + this, &DirModel::countChanged); + connect(this, &QAbstractItemModel::modelReset, + this, &DirModel::countChanged); +} + +DirModel::~DirModel() +{ +} + +QHash DirModel::roleNames() const +{ + return { + { Qt::DisplayRole, "display" }, + { Qt::DecorationRole, "decoration" }, + { UrlRole, "url" }, + { MimeTypeRole, "mimeType" } + }; +} + +QString DirModel::url() const +{ + return dirLister()->url().toString(); +} + +void DirModel::setUrl(const QString& url) +{ + if (url.isEmpty()) { + return; + } + if (dirLister()->url().path() == url) { + dirLister()->updateDirectory(QUrl(url)); + return; + } + + beginResetModel(); + dirLister()->openUrl(QUrl(url)); + endResetModel(); + emit urlChanged(); +} + +int DirModel::indexForUrl(const QString &url) const +{ + QModelIndex index = KDirModel::indexForUrl(QUrl(url)); + return index.row(); +} + +QVariantMap DirModel::get(int i) const +{ + QModelIndex modelIndex = index(i, 0); + + KFileItem item = itemForIndex(modelIndex); + QString url = item.url().toString(); + QString mimeType = item.mimetype(); + + QVariantMap ret; + ret.insert(QStringLiteral("url"), QVariant(url)); + ret.insert(QStringLiteral("mimeType"), QVariant(mimeType)); + + return ret; +} + +QVariant DirModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + switch (role) { + case UrlRole: { + KFileItem item = itemForIndex(index); + return item.url().toString(); + } + case MimeTypeRole: { + KFileItem item = itemForIndex(index); + return item.mimetype(); + } + default: + return KDirModel::data(index, role); + } +} + +// to check the mimetype, if it is a directory then list images under that directory too +QUrl DirModel::checkType( const QString& type, const QString& url) +{ + if (type == "inode/directory") { + dirLister()->openUrl(QUrl::fromUserInput( url ), KCoreDirLister::Keep); + qDebug() << "here"; + return QUrl(); + } else { + return QUrl::fromUserInput( url ); + } +} + + +#include "moc_dirmodel.cpp" diff --git a/src/qmlplugins.cpp b/src/qmlplugins.cpp --- a/src/qmlplugins.cpp +++ b/src/qmlplugins.cpp @@ -27,6 +27,7 @@ #include "imagefoldermodel.h" #include "sortmodel.h" #include "allimagesmodel.h" +#include "dirmodel.h" #include @@ -43,4 +44,5 @@ qmlRegisterType (uri, 0, 1, "ImageFolderModel"); qmlRegisterType (uri, 0, 1, "AllImagesModel"); qmlRegisterType (uri, 0, 1, "SortModel"); + qmlRegisterType (uri, 0, 1, "DirModel"); }