diff options
author | Tomaz Canabrava <tomaz.canabrava@intel.com> | 2015-05-29 14:42:57 -0300 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-05-29 14:14:27 -0700 |
commit | ffc0c8ee993ce6301b8f6c0992b6e1652d2b08d7 (patch) | |
tree | 46b2584896a04437ec8d61d4ecc8dc41b3d6259a /qt-models | |
parent | 37bd82f623ae2fc89a53d8193e7a308b7a2910c3 (diff) | |
download | subsurface-ffc0c8ee993ce6301b8f6c0992b6e1652d2b08d7.tar.gz |
Move DivePictureModel to qt-models
This class will surely be used on the mobile version, and it was very
tangled inside divepicturewidget.
Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'qt-models')
-rw-r--r-- | qt-models/divepicturemodel.cpp | 129 | ||||
-rw-r--r-- | qt-models/divepicturemodel.h | 41 |
2 files changed, 170 insertions, 0 deletions
diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp new file mode 100644 index 000000000..9e60404ed --- /dev/null +++ b/qt-models/divepicturemodel.cpp @@ -0,0 +1,129 @@ +#include "divepicturemodel.h" +#include "dive.h" +#include "metrics.h" +#include "divelist.h" + +#include <QtConcurrent> + +typedef QList<struct picture *> SPictureList; +typedef struct picture *picturepointer; +typedef QPair<picturepointer, QImage> SPixmap; + + +static SPixmap scaleImages(picturepointer picture) +{ + static QHash <QString, QImage > cache; + SPixmap ret; + ret.first = picture; + if (cache.contains(picture->filename) && !cache.value(picture->filename).isNull()) { + ret.second = cache.value(picture->filename); + } else { + int dim = defaultIconMetrics().sz_pic; + QImage p = SHashedImage(picture); + if(!p.isNull()) + p = p.scaled(dim, dim, Qt::KeepAspectRatio); + cache.insert(picture->filename, p); + ret.second = p; + } + return ret; +} + + +DivePictureModel *DivePictureModel::instance() +{ + static DivePictureModel *self = new DivePictureModel(); + return self; +} + +DivePictureModel::DivePictureModel() : numberOfPictures(0) +{ +} + + +void DivePictureModel::updateDivePicturesWhenDone(QList<QFuture<void> > futures) +{ + Q_FOREACH (QFuture<void> f, futures) { + f.waitForFinished(); + } + updateDivePictures(); +} + +void DivePictureModel::updateDivePictures() +{ + if (numberOfPictures != 0) { + beginRemoveRows(QModelIndex(), 0, numberOfPictures - 1); + numberOfPictures = 0; + endRemoveRows(); + } + + // if the dive_table is empty, ignore the displayed_dive + numberOfPictures = dive_table.nr == 0 ? 0 : dive_get_picture_count(&displayed_dive); + if (numberOfPictures == 0) { + return; + } + + stringPixmapCache.clear(); + SPictureList pictures; + FOR_EACH_PICTURE_NON_PTR(displayed_dive) { + stringPixmapCache[QString(picture->filename)].offsetSeconds = picture->offset.seconds; + pictures.push_back(picture); + } + + QList<SPixmap> list = QtConcurrent::blockingMapped(pictures, scaleImages); + Q_FOREACH (const SPixmap &pixmap, list) + stringPixmapCache[pixmap.first->filename].image = pixmap.second; + + beginInsertRows(QModelIndex(), 0, numberOfPictures - 1); + endInsertRows(); +} + +int DivePictureModel::columnCount(const QModelIndex &parent) const +{ + return 2; +} + +QVariant DivePictureModel::data(const QModelIndex &index, int role) const +{ + QVariant ret; + if (!index.isValid()) + return ret; + + QString key = stringPixmapCache.keys().at(index.row()); + if (index.column() == 0) { + switch (role) { + case Qt::ToolTipRole: + ret = key; + break; + case Qt::DecorationRole: + ret = stringPixmapCache[key].image; + break; + case Qt::DisplayRole: + ret = QFileInfo(key).fileName(); + break; + case Qt::DisplayPropertyRole: + ret = QFileInfo(key).filePath(); + } + } else if (index.column() == 1) { + switch (role) { + case Qt::UserRole: + ret = QVariant::fromValue((int)stringPixmapCache[key].offsetSeconds); + break; + case Qt::DisplayRole: + ret = key; + } + } + return ret; +} + +void DivePictureModel::removePicture(const QString &fileUrl) +{ + dive_remove_picture(fileUrl.toUtf8().data()); + copy_dive(current_dive, &displayed_dive); + updateDivePictures(); + mark_divelist_changed(true); +} + +int DivePictureModel::rowCount(const QModelIndex &parent) const +{ + return numberOfPictures; +}
\ No newline at end of file diff --git a/qt-models/divepicturemodel.h b/qt-models/divepicturemodel.h new file mode 100644 index 000000000..edcddd7a2 --- /dev/null +++ b/qt-models/divepicturemodel.h @@ -0,0 +1,41 @@ +#ifndef DIVEPICTUREMODEL_H +#define DIVEPICTUREMODEL_H + +#include <QAbstractTableModel> +#include <QImage> +#include <QFuture> + +typedef QPair<QString, QByteArray> SHashedFilename; + +class SHashedImage : public QImage { +public: + SHashedImage(struct picture *picture); +}; + + +struct PhotoHelper { + QImage image; + int offsetSeconds; +}; + +class DivePictureModel : public QAbstractTableModel { + Q_OBJECT +public: + static DivePictureModel *instance(); + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + void updateDivePictures(); + void updateDivePicturesWhenDone(QList<QFuture<void> >); + void removePicture(const QString& fileUrl); + +private: + DivePictureModel(); + int numberOfPictures; + // Currently, load the images on the fly + // Later, use a thread to load the images + // Later, save the thumbnails so we don't need to reopen every time. + QHash<QString, PhotoHelper> stringPixmapCache; +}; + +#endif
\ No newline at end of file |