diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | qt-models/divepicturemodel.cpp | 129 | ||||
-rw-r--r-- | qt-models/divepicturemodel.h | 41 | ||||
-rw-r--r-- | qt-ui/divelistview.cpp | 3 | ||||
-rw-r--r-- | qt-ui/divepicturewidget.cpp | 125 | ||||
-rw-r--r-- | qt-ui/divepicturewidget.h | 32 | ||||
-rw-r--r-- | qt-ui/maintab.cpp | 1 | ||||
-rw-r--r-- | qt-ui/maintab.h | 1 | ||||
-rw-r--r-- | qt-ui/mainwindow.cpp | 1 | ||||
-rw-r--r-- | qt-ui/profile/divepixmapitem.cpp | 2 | ||||
-rw-r--r-- | qt-ui/profile/profilewidget2.cpp | 1 |
11 files changed, 181 insertions, 156 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index cfa156d17..fbbee2576 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -263,6 +263,7 @@ set(SUBSURFACE_MODELS_LIB_SRCS qt-models/divecomputerextradatamodel.cpp qt-models/completionmodels.cpp qt-models/profileprintmodel.cpp + qt-models/divepicturemodel.cpp ) source_group("Subsurface Models" FILES ${SUBSURFACE_MODELS}) 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 diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index 7f755fc16..c25bb17cb 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -20,7 +20,8 @@ #include "qthelper.h" #include "undocommands.h" #include "divelistview.h" -#include "models.h" +#include "divepicturemodel.h" +#include "metrics.h" // # Date Rtg Dpth Dur Tmp Wght Suit Cyl Gas SAC OTU CNS Loc static int defaultWidth[] = { 70, 140, 90, 50, 50, 50, 50, 70, 50, 50, 70, 50, 50, 500}; diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index 8c1cb3571..bed3d3bd1 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -1,4 +1,5 @@ #include "divepicturewidget.h" +#include "divepicturemodel.h" #include "metrics.h" #include "dive.h" #include "divelist.h" @@ -14,7 +15,7 @@ #include <qthelper.h> #include <QStandardPaths> -void loadPicuture(struct picture *picture) +void loadPicture(struct picture *picture) { ImageDownloader download(picture); download.load(); @@ -31,7 +32,7 @@ SHashedImage::SHashedImage(struct picture *picture) : QImage() if (!isNull()) { QtConcurrent::run(updateHash, picture); } else { - QtConcurrent::run(loadPicuture, picture); + QtConcurrent::run(loadPicture, picture); } } else { QByteArray hash = hashFile(url.toLocalFile()); @@ -87,126 +88,6 @@ void ImageDownloader::saveImage(QNetworkReply *reply) reply->deleteLater(); } -DivePictureModel *DivePictureModel::instance() -{ - static DivePictureModel *self = new DivePictureModel(); - return self; -} - -DivePictureModel::DivePictureModel() : numberOfPictures(0) -{ -} - -typedef struct picture *picturepointer; -typedef QPair<picturepointer, QImage> SPixmap; -typedef QList<struct picture *> SPictureList; - -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; -} - -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; -} - DivePictureWidget::DivePictureWidget(QWidget *parent) : QListView(parent) { connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(doubleClicked(const QModelIndex &))); diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index 2ce228daf..54f5bb826 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -7,18 +7,6 @@ #include <QFuture> #include <QNetworkReply> -typedef QPair<QString, QByteArray> SHashedFilename; - -struct PhotoHelper { - QImage image; - int offsetSeconds; -}; - -class SHashedImage : public QImage { -public: - SHashedImage(struct picture *picture); -}; - class ImageDownloader : public QObject { Q_OBJECT; public: @@ -31,26 +19,6 @@ private slots: void saveImage(QNetworkReply *reply); }; -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; -}; - class DivePictureWidget : public QListView { Q_OBJECT public: diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index 02d6d66f0..5dc0f434b 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -18,6 +18,7 @@ #include "divesitehelpers.h" #include "cylindermodel.h" #include "weightmodel.h" +#include "divepicturemodel.h" #include "divecomputerextradatamodel.h" #if defined(FBSUPPORT) diff --git a/qt-ui/maintab.h b/qt-ui/maintab.h index d8880f584..23be96efa 100644 --- a/qt-ui/maintab.h +++ b/qt-ui/maintab.h @@ -19,6 +19,7 @@ class WeightModel; class CylindersModel; class ExtraDataModel; +class DivePictureModel; class QCompleter; struct Completers { diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 60f6941d8..2848e26b7 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -42,6 +42,7 @@ #ifndef NO_USERMANUAL #include "usermanual.h" #endif +#include "divepicturemodel.h" #include <QNetworkProxy> #include <QUndoStack> #include <qthelper.h> diff --git a/qt-ui/profile/divepixmapitem.cpp b/qt-ui/profile/divepixmapitem.cpp index c9129761e..581f6f9b4 100644 --- a/qt-ui/profile/divepixmapitem.cpp +++ b/qt-ui/profile/divepixmapitem.cpp @@ -1,6 +1,6 @@ #include "divepixmapitem.h" #include "animationfunctions.h" -#include <divepicturewidget.h> +#include "divepicturemodel.h" #include <preferences.h> #include <QDesktopServices> diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp index d70d88763..fb75b08cf 100644 --- a/qt-ui/profile/profilewidget2.cpp +++ b/qt-ui/profile/profilewidget2.cpp @@ -13,6 +13,7 @@ #include "divepicturewidget.h" #include "diveplannermodel.h" #include "models.h" +#include "divepicturemodel.h" #include "maintab.h" #include "diveplanner.h" |