*/
#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;
-}