Reworked preview animation
[harmattan/cameraplus] / src / postcapturemodel.cpp
index 037d67c..f6d6a8b 100644 (file)
  */
 
 #include "postcapturemodel.h"
-#include "fileinfomodel.h"
 #include <QDir>
 #include <QDateTime>
 #include <QUrl>
+#include <QStandardItem>
+#include <dirent.h>
+#include <sys/types.h>
+#if defined(QT4)
+#include <QDeclarativeInfo>
+#elif defined(QT5)
+#include <QQmlInfo>
+#endif
 
 static QHash<QString, QString> m_mime;
 
+class PostCaptureModelItem : public QStandardItem {
+public:
+  PostCaptureModelItem(const QString& path, const char *file) :
+    m_dir(path),
+    m_name(QString::fromLocal8Bit(file)),
+    m_info(0) {
+
+  }
+
+  ~PostCaptureModelItem() {
+    if (m_info) {
+      delete m_info;
+      m_info = 0;
+    }
+  }
+
+  int type() const {
+    return UserType;
+  }
+
+  const QFileInfo *info() const {
+    if (!m_info) {
+      m_info = new QFileInfo(path());
+    }
+
+    return m_info;
+  }
+
+  QString path() const {
+    return QString("%1%2%3").arg(m_dir).arg(QDir::separator()).arg(m_name);
+  }
+
+  QVariant data (int role = Qt::UserRole + 1) const {
+    switch (role) {
+    case PostCaptureModel::UrlRole:
+      return QUrl::fromLocalFile(path());
+
+    case PostCaptureModel::TitleRole:
+      return info()->baseName();
+
+    case PostCaptureModel::MimeTypeRole:
+      if (m_mime.contains(info()->completeSuffix())) {
+       return m_mime[info()->completeSuffix()];
+      }
+
+      return QString();
+
+    case PostCaptureModel::CreatedRole:
+      return info()->created().toString();
+
+    case PostCaptureModel::FileNameRole:
+      return info()->fileName();
+
+    default:
+      return QVariant();
+    }
+  }
+
+private:
+  QString m_dir;
+  QString m_name;
+  mutable QFileInfo *m_info;
+};
+
+static bool lessThan(const QStandardItem *a1, const QStandardItem *a2) {
+  // we sort descending
+  return dynamic_cast<const PostCaptureModelItem *>(a1)->info()->created() >
+    dynamic_cast<const PostCaptureModelItem *>(a2)->info()->created();
+}
+
 PostCaptureModel::PostCaptureModel(QObject *parent) :
-  QSortFilterProxyModel(parent),
-  m_model(new FileInfoModel(this)) {
+  QStandardItemModel(parent) {
 
   QHash<int, QByteArray> roles;
   roles.insert(UrlRole, "url");
@@ -37,16 +113,13 @@ PostCaptureModel::PostCaptureModel(QObject *parent) :
   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("png", "image/png");
     m_mime.insert("mp4", "video/mp4");
+    m_mime.insert("avi", "video/x-msvideo");
   }
 }
 
@@ -76,102 +149,67 @@ void PostCaptureModel::setVideoPath(const QString& path) {
   }
 }
 
-QStringList PostCaptureModel::loadDir(QDir& dir) {
-  QStringList files;
-  QStringList entries(dir.entryList(QDir::Files | QDir::NoDotAndDotDot));
+void PostCaptureModel::loadDir(const QDir& dir, QList<QStandardItem *>& out) {
+  QString path = dir.canonicalPath();
 
-  foreach (const QString& entry, entries) {
-    files << dir.absoluteFilePath(entry);
+  DIR *d = opendir(path.toLocal8Bit().constData());
+  if (!d) {
+    qmlInfo(this) << "Failed to open dir" << path;
+    return;
   }
 
-  return files;
-}
+  while (true) {
+    struct dirent *entry = readdir(d);
+    if (!entry) {
+      break;
+    }
 
-void PostCaptureModel::reload() {
-  QStringList files;
+    if (QLatin1String(".") == entry->d_name || QLatin1String("..") == entry->d_name) {
+      continue;
+    }
 
-  QDir images(m_imagePath);
-  QDir videos(m_videoPath);
+    if (!(entry->d_type == DT_LNK || entry->d_type == DT_REG)) {
+      continue;
+    }
 
-  if (images.canonicalPath() == videos.canonicalPath()) {
-    files += loadDir(images);
-  }
-  else {
-    files += loadDir(images);
-    files += loadDir(videos);
+    out << new PostCaptureModelItem(path, entry->d_name);
   }
 
-  m_data.clear();
-
-  m_model->setFiles(files);
-
-  sort(0, Qt::DescendingOrder);
+  closedir(d);
 }
 
-void PostCaptureModel::clear() {
-  if (m_model->rowCount(QModelIndex()) == 0) {
-    return;
-  }
-
-  m_data.clear();
+void PostCaptureModel::reload() {
+  QList<QStandardItem *> files;
 
-  m_model->setFiles(QStringList());
-}
+  QDir images(m_imagePath);
+  QDir videos(m_videoPath);
 
-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();
-}
+  loadDir(images, files);
 
-QVariant PostCaptureModel::data(const QModelIndex& index, int role) const {
-  if (!index.isValid() || index.row() < 0) {
-    return QVariant();
+  if (images.canonicalPath() != videos.canonicalPath()) {
+    loadDir(videos, files);
   }
 
-  QFileInfo inf = info(QSortFilterProxyModel::data(index, Qt::DisplayRole).toString());
-  switch (role) {
-  case UrlRole:
-    return QUrl::fromLocalFile(inf.absoluteFilePath());
-
-  case TitleRole:
-    return inf.baseName();
-
-  case MimeTypeRole:
-    if (m_mime.contains(inf.completeSuffix())) {
-      return m_mime[inf.completeSuffix()];
-    }
-
-    return QString();
-
-  case CreatedRole:
-    return inf.created().toString();
-
-  case FileNameRole:
-    return inf.fileName();
-
-  default:
-    break;
-  }
+  qSort(files.begin(), files.end(), lessThan);
 
-  return QVariant();
+  invisibleRootItem()->appendRows(files);
 }
 
-QFileInfo PostCaptureModel::info(const QString& path) const {
-  if (m_data.contains(path)) {
-    return m_data[path];
-  }
-
-  QFileInfo inf(path);
-  m_data.insert(path, inf);
-
-  return inf;
+void PostCaptureModel::clear() {
+  QStandardItemModel::clear();
 }
 
 void PostCaptureModel::remove(const QUrl& file) {
   QString path(file.toLocalFile());
 
-  m_data.remove(path);
-  m_model->removeFile(path);
+  int count = invisibleRootItem()->rowCount();
+
+  for (int x = 0; x < count; x++) {
+    if (dynamic_cast<PostCaptureModelItem *>(invisibleRootItem()->child(x))->path() == path) {
+      invisibleRootItem()->removeRow(x);
+      return;
+    }
+  }
 }
 
 #if defined(QT5)