First attempt at getting rid of tracker for post capture
authorMohammed Sameer <msameer@foolab.org>
Sat, 24 Aug 2013 22:32:24 +0000 (01:32 +0300)
committerMohammed Sameer <msameer@foolab.org>
Sat, 24 Aug 2013 22:32:24 +0000 (01:32 +0300)
icons/cameraplus-icon-m-toolbar-favorite-mark-white.png [deleted file]
icons/cameraplus-icon-m-toolbar-favorite-unmark-white.png [deleted file]
icons/icon-m-toolbar-favorite-mark.svg [deleted file]
icons/icon-m-toolbar-favorite-unmark.svg [deleted file]
qml/PostCaptureItem.qml
qml/PostCaptureView.qml
src/fileinfomodel.cpp [new file with mode: 0644]
src/fileinfomodel.h [new file with mode: 0644]
src/postcapturemodel.cpp
src/postcapturemodel.h
src/src.pro

diff --git a/icons/cameraplus-icon-m-toolbar-favorite-mark-white.png b/icons/cameraplus-icon-m-toolbar-favorite-mark-white.png
deleted file mode 100644 (file)
index 1a0be97..0000000
Binary files a/icons/cameraplus-icon-m-toolbar-favorite-mark-white.png and /dev/null differ
diff --git a/icons/cameraplus-icon-m-toolbar-favorite-unmark-white.png b/icons/cameraplus-icon-m-toolbar-favorite-unmark-white.png
deleted file mode 100644 (file)
index 7c43907..0000000
Binary files a/icons/cameraplus-icon-m-toolbar-favorite-unmark-white.png and /dev/null differ
diff --git a/icons/icon-m-toolbar-favorite-mark.svg b/icons/icon-m-toolbar-favorite-mark.svg
deleted file mode 100644 (file)
index 0ec1dc3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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
diff --git a/icons/icon-m-toolbar-favorite-unmark.svg b/icons/icon-m-toolbar-favorite-unmark.svg
deleted file mode 100644 (file)
index 2bf46ab..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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
index 760ae26..f648a5f 100644 (file)
@@ -26,16 +26,21 @@ import CameraPlus 1.0
 Item {
     id: postCaptureItem
 
 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 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")
     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 = ""
         if (!loader.item.play()) {
             showError(qsTr("Error playing video. Please try again."))
             loader.source = ""
@@ -60,8 +65,8 @@ Item {
 
     FullScreenThumbnail {
         id: image
 
     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
         rotation: calculateRotation(orientation.orientation)
         width: isPortrait ? parent.height : parent.width - 10
         height: isPortrait ? parent.width - 10 : parent.height
index a90b30c..1e01688 100644 (file)
@@ -25,7 +25,6 @@ import CameraPlus 1.0
 import QtCamera 1.0
 
 // TODO: qrc:/qml/PostCaptureView.qml:104:5: QML CameraToolBar: Binding loop detected for property "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
 
 Item {
     id: postCaptureView
@@ -35,7 +34,6 @@ Item {
     property int policyMode: view.currentItem && view.currentItem.playing ?
         CameraResources.Player : settings.mode == Camera.VideoMode ? CameraResources.Video :
         CameraResources.Image
     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
 
     Connections {
         target: view.currentItem
@@ -96,13 +94,10 @@ Item {
 
             PostCaptureModel {
                 id: postCaptureModel
 
             PostCaptureModel {
                 id: postCaptureModel
-                manufacturer: deviceInfo.manufacturer
-                model: deviceInfo.model
+                imagePath: platformSettings.imagePath
+                videoPath: platformSettings.videoPath
+
                 Component.onCompleted: reload()
                 Component.onCompleted: reload()
-                onError: {
-                    console.log("Error populating model " + msg)
-                    showError(qsTr("Failed to load captures"))
-                }
             }
         }
     }
             }
         }
     }
@@ -127,25 +122,15 @@ Item {
 
         property bool show: deleteDialog.isOpen || deleteDialog.isOpening ||
             hideTimer.running ||
 
         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 {
 
         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
             CameraToolIcon {
                 iconSource: cameraTheme.shareIconId
-                opacity: available ? 1.0 : 0.4
                 onClicked: {
                     shareCurrentItem()
                     restartTimer()
                 onClicked: {
                     shareCurrentItem()
                     restartTimer()
@@ -154,7 +139,6 @@ Item {
 
             CameraToolIcon {
                 iconSource: cameraTheme.deleteIconId
 
             CameraToolIcon {
                 iconSource: cameraTheme.deleteIconId
-                opacity: available ? 1.0 : 0.4
                 onClicked: {
                     deleteCurrentItem()
                     restartTimer()
                 onClicked: {
                     deleteCurrentItem()
                     restartTimer()
@@ -180,10 +164,10 @@ Item {
         onStatusChanged: restartTimer()
 
         onAccepted: {
         onStatusChanged: restartTimer()
 
         onAccepted: {
-            if (!remove.remove(view.currentItem.itemData.url)) {
+            if (!remove.remove(view.currentItem.itemUrl)) {
                 showError(qsTr("Failed to delete item"))
             } else {
                 showError(qsTr("Failed to delete item"))
             } else {
-                postCaptureModel.remove(view.currentItem.itemData);
+                view.model.remove(view.currentItem.itemUrl)
             }
         }
 
             }
         }
 
@@ -216,7 +200,7 @@ Item {
             height: parent.height
 
             CameraLabel {
             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
                 width: parent.width / 2
                 height: parent.height
                 font.bold: true
@@ -225,7 +209,7 @@ Item {
             }
 
             CameraLabel {
             }
 
             CameraLabel {
-                text: view.currentItem ? view.currentItem.itemData.created : ""
+                text: view.currentItem ? view.currentItem.itemCreated : ""
                 width: parent.width / 2
                 height: parent.height
                 font.bold: true
                 width: parent.width / 2
                 height: parent.height
                 font.bold: true
@@ -242,44 +226,20 @@ Item {
     }
 
     function deleteCurrentItem() {
     }
 
     function deleteCurrentItem() {
-        if (!available) {
+        if (view.currentItem == null) {
             return
         }
 
             return
         }
 
-        deleteDialog.message = view.currentItem.itemData.fileName
+        deleteDialog.message = view.currentItem.itemFileName
         deleteDialog.open()
     }
 
     function shareCurrentItem() {
         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"))
         }
     }
 
             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()
     }
     function restartTimer() {
         hideTimer.restart()
     }
diff --git a/src/fileinfomodel.cpp b/src/fileinfomodel.cpp
new file mode 100644 (file)
index 0000000..725e347
--- /dev/null
@@ -0,0 +1,88 @@
+/*!
+ * 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();
+}
diff --git a/src/fileinfomodel.h b/src/fileinfomodel.h
new file mode 100644 (file)
index 0000000..6649aa0
--- /dev/null
@@ -0,0 +1,52 @@
+// -*- 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 */
index fc639c9..1f71a58 100644 (file)
  */
 
 #include "postcapturemodel.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 <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) :
 
 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;
 
   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);
 
   setRoleNames(roles);
+
+  if (m_mime.isEmpty()) {
+    m_mime.insert("jpg", "image/jpeg");
+    m_mime.insert("mp4", "video/mp4");
+  }
 }
 
 PostCaptureModel::~PostCaptureModel() {
 }
 
 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)
 }
 
 #if defined(QT5)
@@ -289,93 +173,3 @@ void PostCaptureModel::setRoleNames(const QHash<int, QByteArray>& roles) {
   m_roles = roles;
 }
 #endif
   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;
-}
index c5e0ce1..411a9a9 100644 (file)
 #ifndef POST_CAPTURE_MODEL_H
 #define POST_CAPTURE_MODEL_H
 
 #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_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 {
 
   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();
 
   } 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;
 
   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();
 
 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:
 
 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;
 
 #if defined(QT5)
   QHash<int, QByteArray> roleNames() const;
@@ -91,58 +86,4 @@ private:
 #endif
 };
 
 #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 */
 #endif /* POST_CAPTURE_MODEL_H */
index 9238f70..3ff8d8c 100644 (file)
@@ -22,13 +22,15 @@ SOURCES += main.cpp \
            trackerstore.cpp focusrectangle.cpp sharehelper.cpp \
            deletehelper.cpp galleryhelper.cpp postcapturemodel.cpp \
            gridlines.cpp platformsettings.cpp dbusservice.cpp \
            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 \
 
 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
 
 
 RESOURCES += ../qml/qml.qrc