+++ /dev/null
-<?xml version="1.0" encoding="iso-8859-1"?>\r
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->\r
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
-<svg version="1.1" id="icon-m-toolbar-favorite-mark-layer"\r
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"\r
- viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">\r
-<g id="icon-m-toolbar-favorite-mark_1_">\r
- <rect style="fill:none;" width="32" height="32"/>\r
- <path style="fill:#FFFFFF;" d="M31.396,12.717c0.445-0.334,0.357-0.605-0.201-0.605H20.922c-0.556,0-1.158-0.433-1.334-0.959\r
- l-3.266-9.734c-0.177-0.527-0.467-0.527-0.644,0l-3.269,9.734c-0.176,0.526-0.777,0.959-1.334,0.959H0.804\r
- c-0.558,0-0.647,0.271-0.199,0.605l8.215,6.105c0.448,0.332,0.668,1.036,0.491,1.564L5.94,30.428\r
- c-0.178,0.527,0.055,0.708,0.52,0.399l8.697-5.794c0.464-0.309,1.223-0.309,1.687,0l8.694,5.794\r
- c0.465,0.309,0.699,0.128,0.521-0.399l-3.371-10.041c-0.176-0.528,0.045-1.232,0.492-1.564L31.396,12.717z"/>\r
-</g>\r
-</svg>\r
+++ /dev/null
-<?xml version="1.0" encoding="iso-8859-1"?>\r
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->\r
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
-<svg version="1.1" id="icon-m-toolbar-favorite-unmark-layer"\r
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"\r
- viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">\r
-<g id="icon-m-toolbar-favorite-unmark_1_">\r
- <rect style="fill:none;" width="32" height="32"/>\r
- <path style="fill:#FFFFFF;" d="M25.333,31.02L25.333,31.02c-0.277,0-0.572-0.101-0.867-0.296l-8.183-5.455\r
- c-0.037-0.022-0.135-0.062-0.282-0.062c-0.149,0-0.248,0.04-0.284,0.062l-8.184,5.455c-0.681,0.451-1.399,0.354-1.766-0.157\r
- c-0.168-0.234-0.324-0.647-0.111-1.281l3.174-9.45c0.038-0.116-0.038-0.364-0.138-0.439l-7.733-5.747\r
- c-0.769-0.57-0.666-1.19-0.587-1.432c0.08-0.24,0.369-0.799,1.325-0.799h9.666c0.127,0,0.342-0.154,0.382-0.274l3.077-9.16\r
- c0.301-0.904,0.923-1.001,1.177-1.001c0.252,0,0.873,0.097,1.177,1l3.073,9.16c0.042,0.121,0.256,0.275,0.383,0.275h9.669\r
- c0.956,0,1.245,0.559,1.323,0.799c0.08,0.241,0.183,0.861-0.586,1.432l-7.733,5.747c-0.099,0.075-0.177,0.323-0.137,0.44\r
- l3.173,9.449c0.212,0.635,0.057,1.047-0.113,1.283C26.023,30.854,25.696,31.02,25.333,31.02L25.333,31.02z M16.001,23.361\r
- c0.479,0,0.942,0.132,1.305,0.373l6.73,4.485l-2.615-7.797c-0.293-0.878,0.043-1.956,0.787-2.507l6.259-4.652l-7.833-0.001\r
- c-0.922,0-1.838-0.659-2.131-1.534l-2.502-7.454l-2.505,7.454c-0.293,0.875-1.209,1.534-2.131,1.534h-7.83l6.258,4.653\r
- c0.743,0.553,1.083,1.629,0.788,2.507l-2.618,7.796l6.734-4.484C15.057,23.493,15.52,23.361,16.001,23.361L16.001,23.361z"/>\r
-</g>\r
-</svg>\r
Item {
id: postCaptureItem
- property bool isVideo: itemData.type.search("nmm#Video") > 0
+ property url itemUrl: url
+ property string itemTitle: title
+ property string itemMimeType: mimeType
+ property string itemCreated: created
+ property string itemFileName: fileName
+
+ property bool isVideo: itemMimeType.search("video/") >= 0
property alias error: image.error
- property variant itemData: item
property bool playing: loader.source != ""
signal clicked
clip: true
function startPlayback() {
loader.source = Qt.resolvedUrl("VideoPlayerPage.qml")
- loader.item.source = itemData.url
+ loader.item.source = itemUrl
if (!loader.item.play()) {
showError(qsTr("Error playing video. Please try again."))
loader.source = ""
FullScreenThumbnail {
id: image
- source: itemData.url
- mimeType: itemData.mimeType
+ source: itemUrl
+ mimeType: itemMimeType
rotation: calculateRotation(orientation.orientation)
width: isPortrait ? parent.height : parent.width - 10
height: isPortrait ? parent.width - 10 : parent.height
import QtCamera 1.0
// TODO: qrc:/qml/PostCaptureView.qml:104:5: QML CameraToolBar: Binding loop detected for property "height"
-// TODO: try to reload the preview thumbnail when the picture becomes available
Item {
id: postCaptureView
property int policyMode: view.currentItem && view.currentItem.playing ?
CameraResources.Player : settings.mode == Camera.VideoMode ? CameraResources.Video :
CameraResources.Image
- property bool available: view.currentItem ? view.currentItem.itemData.available : false
Connections {
target: view.currentItem
PostCaptureModel {
id: postCaptureModel
- manufacturer: deviceInfo.manufacturer
- model: deviceInfo.model
+ imagePath: platformSettings.imagePath
+ videoPath: platformSettings.videoPath
+
Component.onCompleted: reload()
- onError: {
- console.log("Error populating model " + msg)
- showError(qsTr("Failed to load captures"))
- }
}
}
}
property bool show: deleteDialog.isOpen || deleteDialog.isOpening ||
hideTimer.running ||
- (view.currentItem && view.currentItem.error) && !view.currentItem.playing
+ (view.currentItem != null && view.currentItem.error) && !view.currentItem.playing
Behavior on anchors.bottomMargin {
PropertyAnimation { duration: view.currentItem && view.currentItem.playing ? 0 : 200 }
}
tools: CameraToolBarTools {
- CameraToolIcon {
- iconSource: available && view.currentItem.itemData.favorite ? cameraTheme.favoriteMarkIconId : cameraTheme.favoriteUnmarkIconId
- opacity: available ? 1.0 : 0.4
- onClicked: {
- addOrRemoveFavorite()
- restartTimer()
- }
- }
-
CameraToolIcon {
iconSource: cameraTheme.shareIconId
- opacity: available ? 1.0 : 0.4
onClicked: {
shareCurrentItem()
restartTimer()
CameraToolIcon {
iconSource: cameraTheme.deleteIconId
- opacity: available ? 1.0 : 0.4
onClicked: {
deleteCurrentItem()
restartTimer()
onStatusChanged: restartTimer()
onAccepted: {
- if (!remove.remove(view.currentItem.itemData.url)) {
+ if (!remove.remove(view.currentItem.itemUrl)) {
showError(qsTr("Failed to delete item"))
} else {
- postCaptureModel.remove(view.currentItem.itemData);
+ view.model.remove(view.currentItem.itemUrl)
}
}
height: parent.height
CameraLabel {
- text: view.currentItem ? view.currentItem.itemData.title : ""
+ text: view.currentItem ? view.currentItem.itemTitle : ""
width: parent.width / 2
height: parent.height
font.bold: true
}
CameraLabel {
- text: view.currentItem ? view.currentItem.itemData.created : ""
+ text: view.currentItem ? view.currentItem.itemCreated : ""
width: parent.width / 2
height: parent.height
font.bold: true
}
function deleteCurrentItem() {
- if (!available) {
+ if (view.currentItem == null) {
return
}
- deleteDialog.message = view.currentItem.itemData.fileName
+ deleteDialog.message = view.currentItem.itemFileName
deleteDialog.open()
}
function shareCurrentItem() {
- if (!available) {
- return
- }
-
- if (!share.share(view.currentItem.itemData.url)) {
+ if (view.currentItem != null && !share.share(view.currentItem.itemUrl)) {
showError(qsTr("Failed to launch share service"))
}
}
- function addOrRemoveFavorite() {
- if (!available) {
- return
- }
-
- if (view.currentItem.itemData.favorite) {
- if (!trackerStore.removeFromFavorites(view.currentItem.itemData.url)) {
- showError(qsTr("Failed to remove favorite"))
- } else {
- view.currentItem.itemData.favorite = false
- }
- } else {
- if (!trackerStore.addToFavorites(view.currentItem.itemData.url)) {
- showError(qsTr("Failed to add favorite"))
- } else {
- view.currentItem.itemData.favorite = true
- }
- }
- }
-
function restartTimer() {
hideTimer.restart()
}
--- /dev/null
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
+ *
+ * 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 "fileinfomodel.h"
+
+FileInfoModel::FileInfoModel(QObject *parent) :
+ QAbstractListModel(parent) {
+
+}
+
+FileInfoModel::~FileInfoModel() {
+
+}
+
+int FileInfoModel::rowCount(const QModelIndex& parent) const {
+ if (parent.isValid()) {
+ return 0;
+ }
+
+ return m_info.size();
+}
+
+QVariant FileInfoModel::data(const QModelIndex& index, int role) const {
+ if (index.isValid() && index.row() < m_info.count() && role == Qt::DisplayRole) {
+ return m_info[index.row()];
+ }
+
+ return QVariant();
+}
+
+void FileInfoModel::setFiles(const QStringList& files) {
+ clear();
+
+ appendFiles(files);
+}
+
+void FileInfoModel::appendFile(const QString& file) {
+ appendFiles(QStringList() << file);
+}
+
+void FileInfoModel::appendFiles(const QStringList& files) {
+ if (files.isEmpty()) {
+ return;
+ }
+
+ beginInsertRows(QModelIndex(), m_info.size(), files.size() - 1);
+ m_info << files;
+ endInsertRows();
+}
+
+void FileInfoModel::removeFile(const QString& file) {
+ int index = m_info.indexOf(file);
+
+ if (index == -1) {
+ return;
+ }
+
+ beginRemoveRows(QModelIndex(), index, index);
+ m_info.removeAt(index);
+ endRemoveRows();
+}
+
+void FileInfoModel::clear() {
+ if (m_info.isEmpty()) {
+ return;
+ }
+
+ beginRemoveRows(QModelIndex(), 0, m_info.size());
+ m_info.clear();
+ endRemoveRows();
+}
--- /dev/null
+// -*- c++ -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
+ *
+ * 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
+ */
+
+#ifndef FILE_INFO_MODEL_H
+#define FILE_INFO_MODEL_H
+
+#include <QAbstractListModel>
+#include <QStringList>
+
+class FileInfoModel : public QAbstractListModel {
+ Q_OBJECT
+
+public:
+ FileInfoModel(QObject *parent = 0);
+ ~FileInfoModel();
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+
+ void setFiles(const QStringList& files);
+
+ void appendFile(const QString& file);
+ void appendFiles(const QStringList& files);
+
+ void removeFile(const QString& file);
+
+private:
+ void clear();
+
+ QStringList m_info;
+};
+
+#endif /* FILE_INFO_MODEL_H */
*/
#include "postcapturemodel.h"
-#include <QSparqlConnection>
-#include <QSparqlQuery>
-#include <QSparqlResult>
-#include <QSparqlError>
-#if defined(QT4)
-#include <QDeclarativeInfo>
-#elif defined(QT5)
-#include <QQmlInfo>
-#endif
+#include "fileinfomodel.h"
+#include <QDir>
#include <QDateTime>
-#include <QDBusConnection>
-#include <QStringList>
-#include <QDBusMetaType>
-#include <QDBusArgument>
-
-#define DRIVER "QTRACKER_DIRECT"
-#define QUERY "SELECT rdf:type(?urn) AS ?type nie:url(?urn) AS ?url nie:contentCreated(?urn) AS ?created nie:title(?urn) AS ?title nfo:fileName(?urn) AS ?filename nie:mimeType(?urn) AS ?mimetype tracker:available(?urn) AS ?available nfo:fileLastModified(?urn) as ?lastmod tracker:id(?urn) AS ?trackerid (EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite }) AS ?favorite WHERE { ?urn nfo:equipment ?:equipment . {?urn a nfo:Video} UNION {?urn a nfo:Image}} ORDER BY DESC(?created)"
-
-#define UPDATE_QUERY "SELECT rdf:type(?urn) AS ?type nie:url(?urn) AS ?url nie:contentCreated(?urn) AS ?created nie:title(?urn) AS ?title nfo:fileName(?urn) AS ?filename nie:mimeType(?urn) AS ?mimetype tracker:available(?urn) AS ?available nfo:fileLastModified(?urn) as ?lastmod tracker:id(?urn) AS ?trackerid (EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite }) AS ?favorite WHERE {?urn a nfo:Visual . FILTER (tracker:id(?urn) IN (%1)) }"
-
-#define TRACKER_SERVICE "org.freedesktop.Tracker1"
-#define TRACKER_RESOURCE_PATH "/org/freedesktop/Tracker1/Resources"
-#define TRACKER_RESOURCE_INTERFACE "org.freedesktop.Tracker1.Resources"
-#define TRACKER_RESOURCE_SIGNAL "GraphUpdated"
-#define PHOTO_CLASS "http://www.tracker-project.org/temp/nmm#Photo"
-#define VIDEO_CLASS "http://www.tracker-project.org/temp/nmm#Video"
-#define TRACKER_RESOURCE_SIGNAL_SIGNATURE "sa(iiii)a(iiii)"
-
-class Quad {
-public:
- int graph;
- int subject;
- int predicate;
- int object;
-};
-
-Q_DECLARE_METATYPE(Quad);
-Q_DECLARE_METATYPE(QList<Quad>);
-
-QDBusArgument& operator<<(QDBusArgument& argument, const Quad& t) {
- argument.beginStructure();
- argument << t.graph << t.subject << t.predicate << t.object;
- argument.endStructure();
- return argument;
-}
+#include <QUrl>
-const QDBusArgument& operator>>(const QDBusArgument& argument, Quad& t) {
- argument.beginStructure();
- argument >> t.graph >> t.subject >> t.predicate >> t.object;
- argument.endStructure();
- return argument;
-}
+static QHash<QString, QString> m_mime;
PostCaptureModel::PostCaptureModel(QObject *parent) :
- QAbstractListModel(parent),
- m_connection(0),
- m_connected(false) {
-
- qDBusRegisterMetaType<Quad>();
- qDBusRegisterMetaType<QList<Quad> >();
+ QSortFilterProxyModel(parent),
+ m_model(new FileInfoModel(this)) {
QHash<int, QByteArray> roles;
- roles.insert(Item, "item");
+ roles.insert(UrlRole, "url");
+ roles.insert(TitleRole, "title");
+ roles.insert(MimeTypeRole, "mimeType");
+ roles.insert(CreatedRole, "created");
+ roles.insert(FileNameRole, "fileName");
+
+ setSourceModel(m_model);
+
+ setDynamicSortFilter(true);
+ setSortRole(CreatedRole);
setRoleNames(roles);
+
+ if (m_mime.isEmpty()) {
+ m_mime.insert("jpg", "image/jpeg");
+ m_mime.insert("mp4", "video/mp4");
+ }
}
PostCaptureModel::~PostCaptureModel() {
- qDeleteAll(m_items);
- m_items.clear();
- delete m_connection; m_connection = 0;
}
-void PostCaptureModel::reload() {
- delete m_connection; m_connection = 0;
-
- if (!m_items.isEmpty()) {
- beginRemoveRows(QModelIndex(), 0, m_items.size() - 1);
- qDeleteAll(m_items);
- m_items.clear();
- endRemoveRows();
- }
-
- m_connection = new QSparqlConnection(DRIVER, QSparqlConnectionOptions(), this);
- if (!m_connection->isValid()) {
- emit error(tr("Failed to create SPARQL connection"));
- return;
- }
+QString PostCaptureModel::imagePath() const {
+ return m_imagePath;
+}
- QString equipment = QString("urn:equipment:%1:%2:").arg(m_manufacturer).arg(m_model);
-
- QSparqlQuery q(QUERY, QSparqlQuery::SelectStatement);
- q.bindValue("equipment", equipment);
- exec(q);
-
- if (!m_connected) {
- const char *slot = SLOT(graphUpdated(const QString&,
- const QList<Quad>&,
- const QList<Quad>&));
- m_connected = QDBusConnection::sessionBus().connect(TRACKER_SERVICE, TRACKER_RESOURCE_PATH,
- TRACKER_RESOURCE_INTERFACE,
- TRACKER_RESOURCE_SIGNAL,
- TRACKER_RESOURCE_SIGNAL_SIGNATURE,
- this, slot);
+void PostCaptureModel::setImagePath(const QString& path) {
+ if (m_imagePath != path) {
+ m_imagePath = path;
+ emit imagePathChanged();
}
+}
- if (!m_connected) {
- qmlInfo(this) << "Failed to connect to tracker " << TRACKER_RESOURCE_SIGNAL;
- }
+QString PostCaptureModel::videoPath() const {
+ return m_videoPath;
}
-void PostCaptureModel::exec(QSparqlQuery& query) {
- if (!m_connection) {
- qWarning() << "No connection to query";
- return;
+void PostCaptureModel::setVideoPath(const QString& path) {
+ if (m_videoPath != path) {
+ m_videoPath = path;
+ emit videoPathChanged();
}
+}
- QSparqlResult *result = m_connection->exec(query);
-
- if (result->hasError()) {
- QSparqlError error = result->lastError();
- qmlInfo(this) << "Error executing SPARQL query" << error.message();
-
- delete result;
+QStringList PostCaptureModel::loadDir(QDir& dir) {
+ QStringList files;
+ QStringList entries(dir.entryList(QDir::Files | QDir::NoDotAndDotDot));
- emit PostCaptureModel::error(tr("Failed to query tracker"));
+ foreach (const QString& entry, entries) {
+ files << dir.absoluteFilePath(entry);
}
- if (result) {
- QObject::connect(result, SIGNAL(dataReady(int)), this, SLOT(dataReady(int)));
- QObject::connect(result, SIGNAL(finished()), result, SLOT(deleteLater()));
- }
+ return files;
}
-int PostCaptureModel::rowCount(const QModelIndex& parent) const {
- if (parent.isValid()) {
- return 0;
- }
+void PostCaptureModel::reload() {
+ QStringList files;
- return m_items.size();
-}
+ QDir images(m_imagePath);
+ QDir videos(m_videoPath);
-QVariant PostCaptureModel::data(const QModelIndex& index, int role) const {
- if (!index.isValid() || index.row() < 0 || index.row() >= m_items.size()) {
- return QVariant();
+ if (images.canonicalPath() == videos.canonicalPath()) {
+ files += loadDir(images);
}
-
- if (role == Item) {
- return QVariant::fromValue(dynamic_cast<QObject *>(m_items[index.row()]));
+ else {
+ files += loadDir(images);
+ files += loadDir(videos);
}
- return QVariant();
-}
+ m_data.clear();
-QString PostCaptureModel::manufacturer() const {
- return m_manufacturer;
-}
+ m_model->setFiles(files);
-void PostCaptureModel::setManufacturer(const QString& manufacturer) {
- if (m_manufacturer != manufacturer) {
- m_manufacturer = manufacturer;
- emit manufacturerChanged();
- }
+ sort(0, Qt::DescendingOrder);
}
-QString PostCaptureModel::model() const {
- return m_model;
+bool PostCaptureModel::lessThan(const QModelIndex& left, const QModelIndex& right) const {
+ return info(sourceModel()->data(left, Qt::DisplayRole).toString()).created() <
+ info(sourceModel()->data(right, Qt::DisplayRole).toString()).created();
}
-void PostCaptureModel::setModel(const QString& model) {
- if (m_model != model) {
- m_model = model;
- emit modelChanged();
+QVariant PostCaptureModel::data(const QModelIndex& index, int role) const {
+ if (!index.isValid() || index.row() < 0) {
+ return QVariant();
}
-}
-void PostCaptureModel::dataReady(int totalCount) {
- Q_UNUSED(totalCount);
+ QFileInfo inf = info(QSortFilterProxyModel::data(index, Qt::DisplayRole).toString());
+ switch (role) {
+ case UrlRole:
+ return QUrl::fromLocalFile(inf.absoluteFilePath());
- QSparqlResult *result = dynamic_cast<QSparqlResult *>(sender());
- if (!result) {
- return;
- }
-
- while (result->next()) {
- addRow(new PostCaptureModelItem(result->current(), this));
- }
+ case TitleRole:
+ return inf.baseName();
- result->previous();
-}
-
-void PostCaptureModel::addRow(PostCaptureModelItem *item) {
- if (m_hash.contains(item->trackerId())) {
- m_hash[item->trackerId()]->update(item);
- delete item;
- return;
- }
+ case MimeTypeRole:
+ if (m_mime.contains(inf.completeSuffix())) {
+ return m_mime[inf.completeSuffix()];
+ }
- beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
- m_items << item;
- m_hash.insert(item->trackerId(), item);
+ return QString();
- endInsertRows();
-}
+ case CreatedRole:
+ return inf.created().toString();
-void PostCaptureModel::remove(QObject *item) {
- PostCaptureModelItem *i = dynamic_cast<PostCaptureModelItem *>(item);
- if (!i) {
- qmlInfo(this) << "Invalid item to remove";
- return;
- }
+ case FileNameRole:
+ return inf.fileName();
- int index = m_items.indexOf(i);
- if (index == -1) {
- qmlInfo(this) << "Item" << i->trackerId() << "not found in model";
- return;
+ default:
+ break;
}
- beginRemoveRows(QModelIndex(), index, index);
- m_items.takeAt(index);
- m_hash.remove(i->trackerId());
- endRemoveRows();
-
- i->deleteLater();
+ return QVariant();
}
-void PostCaptureModel::graphUpdated(const QString& className, const QList<Quad>& deleted,
- const QList<Quad>& inserted) {
-
- // We will just assume tracker:available has changed and that's it.
- // We are not really interested in the rest of properties.
-
- if (!(className == QLatin1String(PHOTO_CLASS) || className == QLatin1String(VIDEO_CLASS))) {
- return;
+QFileInfo PostCaptureModel::info(const QString& path) const {
+ if (m_data.contains(path)) {
+ return m_data[path];
}
- QList<int> items;
-
- for (int x = 0; x < deleted.size(); x++) {
- Quad q = deleted[x];
- if (m_hash.contains(q.subject) && items.indexOf(q.subject) == -1) {
- items << q.subject;
- }
- }
+ QFileInfo inf(path);
+ m_data.insert(path, inf);
- for (int x = 0; x < inserted.size(); x++) {
- Quad q = inserted[x];
- if (m_hash.contains(q.subject) && items.indexOf(q.subject) == -1) {
- items << q.subject;
- }
- }
+ return inf;
+}
- for (int x = 0; x < items.size(); x++) {
- QString query = QString(UPDATE_QUERY).arg(items[x]);
- QSparqlQuery q(query, QSparqlQuery::SelectStatement);
+void PostCaptureModel::remove(const QUrl& file) {
+ QString path(file.toLocalFile());
- exec(q);
- }
+ m_data.remove(path);
+ m_model->removeFile(path);
}
#if defined(QT5)
m_roles = roles;
}
#endif
-
-PostCaptureModelItem::PostCaptureModelItem(const QSparqlResultRow& row, QObject *parent) :
- QObject(parent) {
-
- for (int x = 0; x < row.count(); x++) {
- QSparqlBinding b = row.binding(x);
- m_data.insert(b.name(), b.value());
- }
-}
-
-QString PostCaptureModelItem::type() const {
- return value("type").toString();
-}
-
-QUrl PostCaptureModelItem::url() const {
- return value("url").toUrl();
-}
-
-QString PostCaptureModelItem::created() const {
- return formatDateTime(value("created").toDateTime());
-}
-
-QString PostCaptureModelItem::title() const {
- return value("title").toString();
-}
-
-QString PostCaptureModelItem::fileName() const {
- return value("filename").toString();
-}
-
-QString PostCaptureModelItem::mimeType() const {
- return value("mimetype").toString();
-}
-
-bool PostCaptureModelItem::available() const {
- return value("available", false).toBool();
-}
-
-QString PostCaptureModelItem::lastModified() const {
- return formatDateTime(value("lastmod").toDateTime());
-}
-
-unsigned PostCaptureModelItem::trackerId() const {
- return value("trackerid").toUInt();
-}
-
-bool PostCaptureModelItem::favorite() const {
- return value("favorite", false).toBool();
-}
-
-void PostCaptureModelItem::setFavorite(bool add) {
- if (favorite() != add) {
- m_data["favorite"] = add;
-
- emit favoriteChanged();
- }
-}
-
-QString PostCaptureModelItem::formatDateTime(const QDateTime& dt) const {
- return dt.toString();
-}
-
-void PostCaptureModelItem::update(PostCaptureModelItem *other) {
- // We will only update available, favorite and title:
-#if 0
- qDebug() << "i" << trackerId() << other->trackerId() << "\n"
- << "a" << available() << other->available() << "\n"
- << "t" << title() << other->title() << "\n"
- << "f" << favorite() << other->favorite();
-#endif
-
- if (available() != other->available()) {
- m_data["available"] = other->available();
- emit availableChanged();
- }
-
- if (title() != other->title()) {
- m_data["title"] = other->title();
- emit titleChanged();
- }
-
- if (favorite() != other->favorite()) {
- m_data["favorite"] = other->favorite();
- emit favoriteChanged();
- }
-}
-
-QVariant PostCaptureModelItem::value(const QString& id, const QVariant& def) const {
- return m_data.contains(id) ? m_data[id] : def;
-}
#ifndef POST_CAPTURE_MODEL_H
#define POST_CAPTURE_MODEL_H
-#include <QAbstractListModel>
-#include <QUrl>
+#include <QSortFilterProxyModel>
+#include <QStringList>
+#include <QFileInfo>
-class QSparqlConnection;
-class PostCaptureModelItem;
-class QDateTime;
-class Quad;
-class QSparqlQuery;
-class QSparqlResultRow;
+class FileInfoModel;
+class QDir;
-class PostCaptureModel : public QAbstractListModel {
+class PostCaptureModel : public QSortFilterProxyModel {
Q_OBJECT
- Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer NOTIFY manufacturerChanged);
- Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged);
+ Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged);
+ Q_PROPERTY(QString videoPath READ videoPath WRITE setVideoPath NOTIFY videoPathChanged);
typedef enum {
- Item = Qt::UserRole + 1
+ UrlRole = Qt::UserRole + 1,
+ TitleRole = Qt::UserRole + 2,
+ MimeTypeRole = Qt::UserRole + 3,
+ CreatedRole = Qt::UserRole + 4,
+ FileNameRole = Qt::UserRole + 5,
} Roles;
public:
PostCaptureModel(QObject *parent = 0);
~PostCaptureModel();
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QString manufacturer() const;
- void setManufacturer(const QString& manufacturer);
+ QString imagePath() const;
+ void setImagePath(const QString& path);
- QString model() const;
- void setModel(const QString& model);
-
-signals:
- void error(const QString& msg);
-
- void manufacturerChanged();
- void modelChanged();
+ QString videoPath() const;
+ void setVideoPath(const QString& path);
public slots:
void reload();
- void remove(QObject *item);
+ void remove(const QUrl& file);
-private slots:
- void dataReady(int totalCount);
- void graphUpdated(const QString& className, const QList<Quad>& deleted,
- const QList<Quad>& inserted);
+signals:
+ void imagePathChanged();
+ void videoPathChanged();
+
+protected:
+ bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
private:
- void addRow(PostCaptureModelItem *item);
- void exec(QSparqlQuery& query);
+ QFileInfo info(const QString& path) const;
+
+ QString m_imagePath;
+ QString m_videoPath;
- QSparqlConnection *m_connection;
- QString m_manufacturer;
- QString m_model;
+ FileInfoModel *m_model;
- QList<PostCaptureModelItem *> m_items;
- QHash<int, PostCaptureModelItem *> m_hash;
+ QStringList loadDir(QDir& dir);
- bool m_connected;
+ mutable QHash<QString, QFileInfo> m_data;
#if defined(QT5)
QHash<int, QByteArray> roleNames() const;
#endif
};
-class PostCaptureModelItem : public QObject {
- Q_OBJECT
-
- Q_PROPERTY(QString type READ type NOTIFY typeChanged);
- Q_PROPERTY(QUrl url READ url NOTIFY urlChanged);
- Q_PROPERTY(QString created READ created NOTIFY createdChanged);
- Q_PROPERTY(QString title READ title NOTIFY titleChanged);
- Q_PROPERTY(QString fileName READ fileName NOTIFY fileNameChanged);
- Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged);
- Q_PROPERTY(bool available READ available NOTIFY availableChanged);
- Q_PROPERTY(QString lastModified READ lastModified NOTIFY lastModifiedChanged);
- Q_PROPERTY(unsigned trackerId READ trackerId CONSTANT);
- Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged);
-
-public:
- PostCaptureModelItem(const QSparqlResultRow& row, QObject *parent = 0);
-
- ~PostCaptureModelItem() {
-
- }
-
- void update(PostCaptureModelItem *other);
-
- QString type() const;
- QUrl url() const;
- QString created() const;
- QString title() const;
- QString fileName() const;
- QString mimeType() const;
- bool available() const;
- QString lastModified() const;
- unsigned trackerId() const;
-
- void setFavorite(bool add);
- bool favorite() const;
-
-signals:
- void typeChanged();
- void urlChanged();
- void createdChanged();
- void titleChanged();
- void fileNameChanged();
- void mimeTypeChanged();
- void availableChanged();
- void lastModifiedChanged();
- void favoriteChanged();
-
-private:
- QString formatDateTime(const QDateTime& dt) const;
- QVariant value(const QString& id, const QVariant& def = QVariant()) const;
-
- QVariantMap m_data;
-};
-
#endif /* POST_CAPTURE_MODEL_H */
trackerstore.cpp focusrectangle.cpp sharehelper.cpp \
deletehelper.cpp galleryhelper.cpp postcapturemodel.cpp \
gridlines.cpp platformsettings.cpp dbusservice.cpp \
- mountprotector.cpp devicesettings.cpp
+ mountprotector.cpp devicesettings.cpp dirmodel.cpp \
+ fileinfomodel.cpp
HEADERS += settings.h filenaming.h cameraresources.h \
trackerstore.h focusrectangle.h sharehelper.h \
deletehelper.h galleryhelper.h postcapturemodel.h \
gridlines.h platformsettings.h dbusservice.h \
- mountprotector.h devicesettings.h
+ mountprotector.h devicesettings.h dirmodel.h \
+ fileinfomodel.h
RESOURCES += ../qml/qml.qrc