diff --git a/qmlUiKirigami/AlbumDelegate.qml b/qmlUiKirigami/AlbumDelegate.qml index 6c57e94..47f7162 100644 --- a/qmlUiKirigami/AlbumDelegate.qml +++ b/qmlUiKirigami/AlbumDelegate.qml @@ -1,112 +1,112 @@ /* * Copyright (C) 2017 Atul Sharma * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ import QtQuick 2.7 import QtQuick.Controls 2.1 as Controls import org.kde.kquickcontrolsaddons 2.0 as KQA import org.kde.kirigami 2.1 as Kirigami import org.kde.koko 0.1 as Koko Item { id: albumDelegate width: gridView.cellWidth height: gridView.cellHeight KQA.QImageItem { id: image anchors.centerIn: parent width: gridView.cellWidth - (Kirigami.Units.largeSpacing ) height: width smooth: true image: model.thumbnail fillMode: KQA.QImageItem.PreserveAspectCrop } Kirigami.BasicListItem { visible: model.itemType == Koko.Types.Folder || model.itemType == Koko.Types.Album label: model.fileCount ? i18np(" %2 \n 1 Image"," %2 \n %1 Images", model.fileCount, model.display) : model.display reserveSpaceForIcon: false width: image.width anchors.left: image.left anchors.top: image.top background: Rectangle { anchors.fill: parent opacity: 0.7 color: Kirigami.Theme.backgroundColor } } SelectionButton { id: selectionButton visible: ( albumThumbnailMouseArea.containsMouse || iconMouseArea.containsMouse ) && !(model.itemType == Koko.Types.Folder || model.itemType == Koko.Types.Album) } SelectionDelegateHighlight { id: selectionHighlight visible: model.selected } MouseArea { id: albumThumbnailMouseArea anchors.fill: parent hoverEnabled: true onClicked: activate(); } Keys.onPressed: { switch (event.key) { case Qt.Key_Enter: case Qt.Key_Return: case Qt.Key_Space: activate(); break; default: break; } } function activate( ) { gridView.model.clearSelections() switch( model.itemType) { case Koko.Types.Album: { - imageListModel.imageList = model.files + imageListModel.query = imageListModel.queryForIndex( model.sourceIndex) sortedListModel.sourceModel = imageListModel collectionSelected( sortedListModel, model.display) break; } case Koko.Types.Folder: { imageFolderModel.url = model.imageurl sortedListModel.sourceModel = imageFolderModel folderSelected( sortedListModel, model.display) break; } case Koko.Types.Image: { imageSelected(model.index) break; } default: { console.log("Unknown") break; } } } } diff --git a/qmlUiKirigami/AlbumView.qml b/qmlUiKirigami/AlbumView.qml index 2712f08..fcdf373 100644 --- a/qmlUiKirigami/AlbumView.qml +++ b/qmlUiKirigami/AlbumView.qml @@ -1,107 +1,104 @@ /* * Copyright (C) 2017 Atul Sharma * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ import QtQuick 2.7 import QtQuick.Controls 2.1 as Controls import org.kde.kirigami 2.1 as Kirigami import org.kde.koko 0.1 as Koko Kirigami.ScrollablePage { id: page property alias model: gridView.model signal collectionSelected(QtObject selectedModel, string cover) signal imageSelected(int currentIndex) signal folderSelected(QtObject selectedModel, string cover) keyboardNavigationEnabled: true focus: true contextualActions: [ Kirigami.Action { text: i18n("Select All") enabled: model.containImages onTriggered: model.selectAll() }, Kirigami.Action { text: i18n("Deselect All") enabled: model.containImages onTriggered: model.clearSelections() }, Kirigami.Action { text: i18n("Delete Selection") enabled: model.hasSelectedImages onTriggered: model.deleteSelection() } ] background: Rectangle { color: Kirigami.Theme.viewBackgroundColor } GridView { id: gridView property int iconSize: Kirigami.Units.iconSizes.enormous keyNavigationEnabled: true //leave a gridUnit for the scrollbar on desktop systems //TODO: automate this in kirigami somehow? readonly property int effectiveWidth: Kirigami.Settings.isMobile ? width : width - Kirigami.Units.gridUnit cellWidth: effectiveWidth / Math.floor(effectiveWidth / (iconSize + Kirigami.Units.largeSpacing*2)) cellHeight: cellWidth highlight: Rectangle { color: Kirigami.Theme.highlightColor} delegate: AlbumDelegate {} } Keys.onPressed: { switch (event.key) { case Qt.Key_Escape: gridView.model.clearSelections() break; default: break; } } Koko.SortModel { id: sortedListModel } - Koko.ImageListModel { - id: imageListModel - } Koko.ImageFolderModel { id: imageFolderModel } onCollectionSelected: pageStack.push( Qt.resolvedUrl("AlbumView.qml"), { "model": selectedModel, "title": i18n(cover)}) onFolderSelected: pageStack.push( Qt.resolvedUrl("AlbumView.qml"), { "model": selectedModel, "title": i18n(cover)}) onImageSelected: { currentImage.model = model currentImage.index = currentIndex imageViewer.state = "open"; } } diff --git a/qmlUiKirigami/main.qml b/qmlUiKirigami/main.qml index 15c12bd..0a87da6 100644 --- a/qmlUiKirigami/main.qml +++ b/qmlUiKirigami/main.qml @@ -1,168 +1,181 @@ /* * Copyright (C) 2017 Atul Sharma * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ import QtQuick 2.1 import QtQuick.Controls 2.0 as Controls import org.kde.kirigami 2.0 as Kirigami import org.kde.koko 0.1 as Koko Kirigami.ApplicationWindow { id: root header: Kirigami.ApplicationHeader {} QtObject { id: currentImage property int index property var model property GridView view : pageStack.currentItem.flickable onIndexChanged: { view.currentIndex = currentImage.index } } pageStack.initialPage: AlbumView { id: albumView } globalDrawer: Sidebar { id: sideBar onFilterBy: { pageStack.pop(albumView) albumView.title = i18n(value) previouslySelectedAction.checked = false switch( value){ case "Countries": { albumView.model = imageLocationModelCountry; + imageListModel.locationGroup = Koko.Types.Country; break; } case "States": { albumView.model = imageLocationModelState; + imageListModel.locationGroup = Koko.Types.State; break; } case "Cities": { albumView.model = imageLocationModelCity; + imageListModel.locationGroup = Koko.Types.City; break; } case "Years": { albumView.model = imageTimeModelYear; + imageListModel.timeGroup = Koko.Types.Year; break; } case "Months": { albumView.model = imageTimeModelMonth; + imageListModel.timeGroup = Koko.Types.Month; break; } case "Weeks": { - albumView.model = imageTimeModelWeek; + albumView.model = imageTimeModelWeek; + imageListModel.timeGroup = Koko.Types.Week; break; } case "Days": { albumView.model = imageTimeModelDay; + imageListModel.timeGroup = Koko.Types.Day; break; } case "Folders": { albumView.model = imageFolderModel; + imageListModel.locationGroup = -1; + imageListModel.timeGroup = -1; break; } } } } contextDrawer: Kirigami.ContextDrawer {} Koko.SortModel{ id: imageFolderModel sourceModel: Koko.ImageFolderModel {} } Koko.SortModel { id: imageTimeModelYear sourceModel: Koko.ImageTimeModel { group: Koko.Types.Year } sortRoleName: "date" } Koko.SortModel { id: imageTimeModelMonth sourceModel: Koko.ImageTimeModel { group: Koko.Types.Month } sortRoleName: "date" } Koko.SortModel { id: imageTimeModelWeek sourceModel: Koko.ImageTimeModel { group: Koko.Types.Week } sortRoleName: "date" } Koko.SortModel { id: imageTimeModelDay sourceModel: Koko.ImageTimeModel { group: Koko.Types.Day } sortRoleName: "date" } Koko.SortModel { id: imageLocationModelCountry sourceModel: Koko.ImageLocationModel { group: Koko.Types.Country } } Koko.SortModel { id: imageLocationModelState sourceModel: Koko.ImageLocationModel { group: Koko.Types.State } } Koko.SortModel { id: imageLocationModelCity sourceModel: Koko.ImageLocationModel { group: Koko.Types.City } } + Koko.ImageListModel { + id: imageListModel + } + ImageViewer { id: imageViewer //go on top of the overlay drawer //HACK on the parent and z to go on top of the handle as well z: 2000002 parent: root.overlay.parent width: overlay.width height: overlay.height currentIndex: currentImage.index model: currentImage.model imageWidth: root.width imageHeight: root.height } Component.onCompleted: { albumView.model = imageFolderModel albumView.title = i18n("Folders") } } diff --git a/src/imagelistmodel.cpp b/src/imagelistmodel.cpp index 80b44e8..baf82b7 100644 --- a/src/imagelistmodel.cpp +++ b/src/imagelistmodel.cpp @@ -1,92 +1,163 @@ /* * Copyright 2017 by Atul Sharma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "imagelistmodel.h" -#include "types.h" #include "roles.h" +#include "imagestorage.h" #include #include ImageListModel::ImageListModel(QObject* parent) : QAbstractListModel(parent) { + connect(this, &ImageListModel::locationGroupChanged, + this, &ImageListModel::slotLocationGroupChanged); + connect(this, &ImageListModel::timeGroupChanged, + this, &ImageListModel::slotTimeGroupChanged); + connect(this, &ImageListModel::queryChanged, + this, &ImageListModel::slotResetModel); + + connect(ImageStorage::instance(), &ImageStorage::storageModified, + this, &ImageListModel::slotResetModel); } ImageListModel::~ImageListModel() { } QHash ImageListModel::roleNames() const { QHash hash = QAbstractListModel::roleNames(); hash.insert( Roles::ImageUrlRole, "imageurl"); - hash.insert( Roles::MimeTypeRole, "mimeType"); hash.insert( Roles::ItemTypeRole, "itemType"); return hash; } QVariant ImageListModel::data(const QModelIndex& index, int role) const { if( !index.isValid()) { return QVariant(); } int indexValue = index.row(); - QMimeDatabase db; - QMimeType type = db.mimeTypeForFile(m_images.at(indexValue)); switch( role) { case Qt::DisplayRole: //TODO: return the filename component return m_images.at(indexValue); case Roles::ImageUrlRole: return m_images.at(indexValue); - case Roles::MimeTypeRole: - return type.name(); - case Roles::ItemTypeRole: return Types::Image; } return QVariant(); } int ImageListModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_images.size(); } -QStringList ImageListModel::imageList() const +void ImageListModel::slotLocationGroupChanged() +{ + if( m_locationGroup != -1) { + m_locations = ImageStorage::instance()->locations( static_cast(m_locationGroup)); + m_queryType = Types::LocationQuery; + } +} + +void ImageListModel::slotTimeGroupChanged() +{ + if( m_timeGroup != -1) { + m_times = ImageStorage::instance()->timeTypes( static_cast(m_timeGroup)); + m_queryType = Types::TimeQuery; + } +} + +void ImageListModel::slotResetModel() +{ + beginResetModel(); + if(m_queryType == Types::LocationQuery) { + m_images = ImageStorage::instance()->imagesForLocation( m_query, static_cast(m_locationGroup)); + } else if (m_queryType == Types::TimeQuery) { + m_images = ImageStorage::instance()->imagesForTime( m_query, static_cast(m_timeGroup)); + } + endResetModel(); +} + +Types::LocationGroup ImageListModel::locationGroup() const { - return m_images; + return m_locationGroup; } -void ImageListModel::setImageList(QStringList images) +void ImageListModel::setLocationGroup(const Types::LocationGroup &group) { - m_images = images; - emit imageListChanged(); + m_locationGroup = group; + emit locationGroupChanged(); +} + +Types::TimeGroup ImageListModel::timeGroup() const +{ + return m_timeGroup; +} + +void ImageListModel::setTimeGroup(const Types::TimeGroup &group) +{ + m_timeGroup = group; + emit timeGroupChanged(); +} + +Types::QueryType ImageListModel::queryType() const +{ + return m_queryType; +} + +void ImageListModel::setQueryType(const Types::QueryType& type) +{ + m_queryType = type; +} + +QByteArray ImageListModel::query() const +{ + return m_query; +} +void ImageListModel::setQuery(const QByteArray &statement) +{ + m_query = statement; + emit queryChanged(); +} + +QByteArray ImageListModel::queryForIndex(const QModelIndex &index) +{ + if(m_queryType == Types::LocationQuery) { + return m_locations.at( index.row()).first; + } else if( m_queryType == Types::TimeQuery) { + return m_times.at( index.row()).first; + } + return QByteArray(); } #include "moc_imagelistmodel.cpp" diff --git a/src/imagelistmodel.h b/src/imagelistmodel.h index b981316..0296c70 100644 --- a/src/imagelistmodel.h +++ b/src/imagelistmodel.h @@ -1,52 +1,79 @@ /* * Copyright 2017 by Atul Sharma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef IMAGELISTMODEL_H #define IMAGELISTMODEL_H #include +#include "types.h" + class ImageListModel : public QAbstractListModel { Q_OBJECT - /* - * imageList property is used to store the images of a particular collection - */ - Q_PROPERTY(QStringList imageList READ imageList WRITE setImageList NOTIFY imageListChanged) + Q_PROPERTY(Types::LocationGroup locationGroup READ locationGroup WRITE setLocationGroup NOTIFY locationGroupChanged) + Q_PROPERTY(Types::TimeGroup timeGroup READ timeGroup WRITE setTimeGroup NOTIFY timeGroupChanged) + Q_PROPERTY(Types::QueryType queryType READ queryType WRITE setQueryType) + Q_PROPERTY(QByteArray query READ query WRITE setQuery NOTIFY queryChanged) public: explicit ImageListModel(QObject* parent = 0); ~ImageListModel(); virtual QHash< int, QByteArray > roleNames() const; virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - QStringList imageList() const; - void setImageList(QStringList images); + Types::LocationGroup locationGroup() const; + void setLocationGroup(const Types::LocationGroup &group); + + Types::TimeGroup timeGroup() const; + void setTimeGroup(const Types::TimeGroup &group); + + Types::QueryType queryType() const; + void setQueryType( const Types::QueryType &type); + + QByteArray query() const; + void setQuery(const QByteArray &statement); + + Q_INVOKABLE QByteArray queryForIndex(const QModelIndex &index); + + void slotLocationGroupChanged(); + void slotTimeGroupChanged(); + void slotResetModel(); Q_SIGNALS: void imageListChanged(); + void locationGroupChanged(); + void timeGroupChanged(); + void queryChanged(); private: QStringList m_images; + Types::LocationGroup m_locationGroup; + Types::TimeGroup m_timeGroup; + Types::QueryType m_queryType; + QByteArray m_query; + + QList< QPair > m_times; + QList< QPair > m_locations; }; #endif diff --git a/src/roles.h b/src/roles.h index a0976d3..c56d854 100644 --- a/src/roles.h +++ b/src/roles.h @@ -1,43 +1,44 @@ /* * Copyright 2017 by Atul Sharma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ROLES_H #define ROLES_H #include class Roles : public QObject { Q_OBJECT public: Roles(QObject* parent); ~Roles(); enum RoleNames { ImageUrlRole = Qt::UserRole + 1, MimeTypeRole, Thumbnail, ItemTypeRole, FilesRole, FileCountRole, DateRole, - SelectedRole + SelectedRole, + SourceIndex }; }; #endif diff --git a/src/sortmodel.cpp b/src/sortmodel.cpp index ccfbb10..c198cd6 100644 --- a/src/sortmodel.cpp +++ b/src/sortmodel.cpp @@ -1,287 +1,291 @@ /* * Copyright (C) 2017 Atul Sharma * Copyright (C) 2014 Vishesh Handa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "sortmodel.h" #include "types.h" #include "roles.h" #include #include #include #include #include using namespace Jungle; SortModel::SortModel(QObject* parent) : QSortFilterProxyModel(parent), m_screenshotSize(256, 256), m_containImages(false) { setSortLocaleAware(true); sort(0); m_selectionModel = new QItemSelectionModel(this); m_previewTimer = new QTimer(this); m_previewTimer->setSingleShot(true); connect(m_previewTimer, &QTimer::timeout, this, &SortModel::delayedPreview); connect(this, &SortModel::rowsInserted, this, [this] (const QModelIndex &parent, int first, int last) { Q_UNUSED(parent) for (int i = first; i <= last; i++) { if (Types::Image == data(index(i, 0, QModelIndex()), Roles::ItemTypeRole).toInt() && m_containImages == false) { setContainImages(true); break; } } }); connect(this, &SortModel::sourceModelChanged, this, [this] () { if (!sourceModel()) { return; } for (int i = 0; i <= sourceModel()->rowCount(); i++) { if (Types::Image == sourceModel()->data(sourceModel()->index(i, 0, QModelIndex()), Roles::ItemTypeRole).toInt() && m_containImages == false) { setContainImages(true); break; } } }); //using the same cache of the engine, they index both by url m_imageCache = new KImageCache(QStringLiteral("org.kde.koko"), 10485760); } SortModel::~SortModel() { delete m_imageCache; } void SortModel::setContainImages(bool value) { m_containImages = value; emit containImagesChanged(); } QByteArray SortModel::sortRoleName() const { int role = sortRole(); return roleNames().value(role); } void SortModel::setSortRoleName(const QByteArray& name) { if (!sourceModel()) { m_sortRoleName = name; return; } const QHash roles = sourceModel()->roleNames(); for (auto it = roles.begin(); it != roles.end(); it++) { if (it.value() == name) { setSortRole(it.key()); return; } } qDebug() << "Sort role" << name << "not found"; } QHash SortModel::roleNames() const { QHash hash = sourceModel()->roleNames(); hash.insert( Roles::SelectedRole, "selected"); hash.insert( Roles::Thumbnail, "thumbnail"); + hash.insert( Roles::SourceIndex, "sourceIndex"); return hash; } QVariant SortModel::data(const QModelIndex& index, int role) const { if( !index.isValid()) { return QVariant(); } switch( role) { case Roles::SelectedRole: { return m_selectionModel->isSelected(index); } case Roles::Thumbnail: { QUrl thumbnailSource(QString( /*"file://" + */data( index, Roles::ImageUrlRole).toString())); KFileItem item( thumbnailSource, QString() ); QImage preview = QImage(m_screenshotSize, QImage::Format_ARGB32_Premultiplied); if (m_imageCache->findImage(item.url().toString(), &preview)) { return preview; } m_previewTimer->start(100); const_cast(this)->m_filesToPreview[item.url()] = QPersistentModelIndex(index); } + case Roles::SourceIndex: { + return mapToSource(index); + } } return QSortFilterProxyModel::data(index, role); } void SortModel::setSourceModel(QAbstractItemModel* sourceModel) { QSortFilterProxyModel::setSourceModel(sourceModel); if (!m_sortRoleName.isEmpty()) { setSortRoleName(m_sortRoleName); m_sortRoleName.clear(); } } bool SortModel::containImages() { return m_containImages; } bool SortModel::hasSelectedImages() { return m_selectionModel->hasSelection(); } void SortModel::setSelected(int indexValue) { if( indexValue < 0) return; QModelIndex index = QSortFilterProxyModel::index( indexValue, 0); m_selectionModel->select( index, QItemSelectionModel::Select ); emit dataChanged( index, index); emit selectedImagesChanged(); } void SortModel::toggleSelected(int indexValue ) { if( indexValue < 0) return; QModelIndex index = QSortFilterProxyModel::index( indexValue, 0); m_selectionModel->select( index, QItemSelectionModel::Toggle ); emit dataChanged( index, index); emit selectedImagesChanged(); } void SortModel::clearSelections() { if(m_selectionModel->hasSelection()) { QModelIndexList selectedIndex = m_selectionModel->selectedIndexes(); m_selectionModel->clear(); foreach(QModelIndex indexValue, selectedIndex) { emit dataChanged( indexValue, indexValue); } } emit selectedImagesChanged(); } void SortModel::selectAll() { QModelIndexList indexList; for( int row=0; rowhasSelection()) { m_selectionModel->clear(); } foreach(QModelIndex index, indexList) { if( Types::Image == data(index, Roles::ItemTypeRole)) m_selectionModel->select( index, QItemSelectionModel::Select); } emit dataChanged( index( 0, 0, QModelIndex()), index( rowCount()-1, 0, QModelIndex()) ); emit selectedImagesChanged(); } void SortModel::deleteSelection() { QList filesToDelete; foreach(QModelIndex index, m_selectionModel->selectedIndexes()) { filesToDelete << data( index, Roles::ImageUrlRole).toUrl(); } auto trashJob = KIO::trash(filesToDelete); trashJob->exec(); } void SortModel::delayedPreview() { QHash::const_iterator i = m_filesToPreview.constBegin(); KFileItemList list; while (i != m_filesToPreview.constEnd()) { QUrl file = i.key(); QPersistentModelIndex index = i.value(); if (!m_previewJobs.contains(file) && file.isValid()) { list.append(KFileItem(file, QString(), 0)); m_previewJobs.insert(file, QPersistentModelIndex(index)); } ++i; } if (list.size() > 0) { KIO::PreviewJob* job = KIO::filePreview(list, m_screenshotSize); job->setIgnoreMaximumSize(true); // qDebug() << "Created job" << job; connect(job, &KIO::PreviewJob::gotPreview, this, &SortModel::showPreview); connect(job, &KIO::PreviewJob::failed, this, &SortModel::previewFailed); } m_filesToPreview.clear(); } void SortModel::showPreview(const KFileItem &item, const QPixmap &preview) { QPersistentModelIndex index = m_previewJobs.value(item.url()); m_previewJobs.remove(item.url()); if (!index.isValid()) { return; } m_imageCache->insertImage(item.url().toString(), preview.toImage()); //qDebug() << "preview size:" << preview.size(); emit dataChanged(index, index); } void SortModel::previewFailed(const KFileItem &item) { m_previewJobs.remove(item.url()); } diff --git a/src/types.h b/src/types.h index d080ab6..07e8989 100644 --- a/src/types.h +++ b/src/types.h @@ -1,50 +1,56 @@ /* * Copyright 2017 by Atul Sharma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ITEMTYPES_H #define ITEMTYPES_H #include class Types : public QObject { Q_OBJECT Q_ENUMS(ItemTypes) Q_ENUMS(TimeGroup) Q_ENUMS(LocationGroup) + Q_ENUMS(QueryType) public: Types(QObject* parent); ~Types(); enum ItemTypes { Album = 0 , Folder, Image }; enum TimeGroup { Year = 3, Month, Week, Day }; enum LocationGroup { Country = 7, State, City }; + enum QueryType { + LocationQuery = 10, + TimeQuery + }; + }; #endif