People, I'm very sleepy - and this doesn't seems to work - I got nothing, but I'm relying on the currently implemented method on dive list to load images. Anyone knows why I don't get a single image when I load *random* pictures ( I had to test with what I had on my computer... so... got my "mom pictures" and tested loading on a dive.
From ba702774ef10a87e259564011c5f2ea81c62496f Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Fri, 30 May 2014 13:36:00 -0300 Subject: [PATCH 1/6] Fix layout on the Shift-Image-Time import dialog
The dialogs where hard-coded and some variations of themes could broke the placement of the text on it. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/shiftimagetimes.ui | 92 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/qt-ui/shiftimagetimes.ui b/qt-ui/shiftimagetimes.ui index ee05c63..5b6bb41 100644 --- a/qt-ui/shiftimagetimes.ui +++ b/qt-ui/shiftimagetimes.ui @@ -167,54 +167,50 @@ <property name="title"> <string/> </property> - <widget class="QDateTimeEdit" name="dcTime"> - <property name="geometry"> - <rect> - <x>0</x> - <y>70</y> - <width>161</width> - <height>24</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="label_2"> - <property name="geometry"> - <rect> - <x>0</x> - <y>10</y> - <width>234</width> - <height>60</height> - </rect> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>60</height> - </size> - </property> - <property name="text"> - <string>Which date and time are displayed on the image?</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - <widget class="QGraphicsView" name="DCImage"> - <property name="geometry"> - <rect> - <x>260</x> - <y>10</y> - <width>361</width> - <height>281</height> - </rect> - </property> - <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - </widget> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>60</height> + </size> + </property> + <property name="text"> + <string>Which date and time are displayed on the image?</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1" rowspan="3"> + <widget class="QGraphicsView" name="DCImage"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QDateTimeEdit" name="dcTime"/> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>193</height> + </size> + </property> + </spacer> + </item> + </layout> </widget> </item> </layout> -- 1.9.3
From 9b8ebe1564d7b325da5a3df611e6ef2dd0bc4081 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Fri, 30 May 2014 13:46:26 -0300 Subject: [PATCH 2/6] Do not replot for each picture added on dive. Do not replot for each picture added on dive, but wait for all pictures have been set and plot that. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/divelistview.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index 8f54448..8378861 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -817,13 +817,13 @@ void DiveListView::loadImages() dive->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude); dive->longitude.udeg = lrint(1000000.0 * exif.GeoLocation.Longitude); } - mark_divelist_changed(true); - MainWindow::instance()->refreshDisplay(); - MainWindow::instance()->graphics()->replot(); } } } } + mark_divelist_changed(true); + MainWindow::instance()->refreshDisplay(); + MainWindow::instance()->graphics()->replot(); } QString DiveListView::lastUsedImageDir() -- 1.9.3
From 92ac260a2bd7fee13768c0c30e20fb68c90ef644 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Fri, 30 May 2014 14:38:27 -0300 Subject: [PATCH 3/6] Added stub for a widget to show the dive pictures. Added a stub for a widget to show the dive pictures. it has a few classes: the model is the list of pictures for the current dive, the delegate is how this pictures will be displayed on screen, the widget is the collection of delegates, and the DivePictureThumbnailThread is a worker-thread to generate the thumbnails so the UI will not freeze. Signed-off-by: Tomaz Canabrava <[email protected]> --- CMakeLists.txt | 1 + qt-ui/divepicturewidget.cpp | 26 ++++++++++++++++++++++++++ qt-ui/divepicturewidget.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 qt-ui/divepicturewidget.cpp create mode 100644 qt-ui/divepicturewidget.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e19032c..ab46d37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,7 @@ SET(SUBSURFACE_INTERFACE qt-ui/groupedlineedit.cpp qt-ui/usermanual.cpp qt-ui/divelogexportdialog.cpp + qt-ui/divepicturewidget.cpp ) #the profile widget diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp new file mode 100644 index 0000000..aea4157 --- /dev/null +++ b/qt-ui/divepicturewidget.cpp @@ -0,0 +1,26 @@ +#include "divepicturewidget.h" + +void DivePictureDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); +} + +int DivePictureModel::columnCount(const QModelIndex &parent) const +{ + +} + +QVariant DivePictureModel::data(const QModelIndex &index, int role) const +{ + +} + +int DivePictureModel::rowCount(const QModelIndex &parent) const +{ + +} + +DivePictureView::DivePictureView(QWidget *parent): QListView(parent) +{ + +} diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h new file mode 100644 index 0000000..260d3ca --- /dev/null +++ b/qt-ui/divepicturewidget.h @@ -0,0 +1,29 @@ +#ifndef DIVEPICTUREWIDGET_H +#define DIVEPICTUREWIDGET_H + +#include <QAbstractTableModel> +#include <QStyledItemDelegate> +#include <QListView> +#include <QThread> + +class DivePictureModel : QAbstractTableModel { + 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; +}; + +class DivePictureDelegate : QStyledItemDelegate { + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +class DivePictureView : public QListView{ + Q_OBJECT +public: + DivePictureView(QWidget *parent); +}; + +class DivePictureThumbnailThread : public QThread { + +}; + +#endif \ No newline at end of file -- 1.9.3
From e68bbdb8980bb24b078f21a869d88fe1dd22df09 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Fri, 30 May 2014 14:50:49 -0300 Subject: [PATCH 4/6] Added a new widget on the main tab: Pictures. Currently this does nothing, but since "dive photos" can also mean photos that were taking during the trip to the dive, some of them will not be visible on the profile. this currently shows nothing, because I didn't worked out the Model bits yet. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/divepicturewidget.cpp | 2 +- qt-ui/divepicturewidget.h | 4 ++-- qt-ui/maintab.ui | 25 ++++++++++++++++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index aea4157..a74bba0 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -20,7 +20,7 @@ int DivePictureModel::rowCount(const QModelIndex &parent) const } -DivePictureView::DivePictureView(QWidget *parent): QListView(parent) +DivePictureWidget::DivePictureWidget(QWidget *parent): QListView(parent) { } diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index 260d3ca..7761db3 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -16,10 +16,10 @@ class DivePictureDelegate : QStyledItemDelegate { virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; }; -class DivePictureView : public QListView{ +class DivePictureWidget : public QListView{ Q_OBJECT public: - DivePictureView(QWidget *parent); + DivePictureWidget(QWidget *parent); }; class DivePictureThumbnailThread : public QThread { diff --git a/qt-ui/maintab.ui b/qt-ui/maintab.ui index 276c792..31ed130 100644 --- a/qt-ui/maintab.ui +++ b/qt-ui/maintab.ui @@ -38,7 +38,7 @@ <x>0</x> <y>0</y> <width>662</width> - <height>644</height> + <height>649</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_2"> @@ -157,7 +157,7 @@ </widget> </item> <item row="8" column="1"> - <widget class="TagWidget" name="buddy"> + <widget class="TagWidget" name="buddy"> <property name="readOnly"> <bool>false</bool> </property> @@ -290,7 +290,7 @@ <x>0</x> <y>0</y> <width>662</width> - <height>644</height> + <height>649</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_5"> @@ -370,7 +370,7 @@ <x>0</x> <y>0</y> <width>662</width> - <height>644</height> + <height>649</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_6"> @@ -680,7 +680,7 @@ <x>0</x> <y>0</y> <width>662</width> - <height>644</height> + <height>649</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_7"> @@ -813,6 +813,16 @@ </item> </layout> </widget> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Photos</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="DivePictureWidget" name="listView"/> + </item> + </layout> + </widget> </widget> <customwidgets> <customwidget> @@ -844,6 +854,11 @@ <extends>QPlainTextEdit</extends> <header>qt-ui/tagwidget.h</header> </customwidget> + <customwidget> + <class>DivePictureWidget</class> + <extends>QListView</extends> + <header>divepicturewidget.h</header> + </customwidget> </customwidgets> <tabstops> <tabstop>scrollArea</tabstop> -- 1.9.3
From eda3cebcc1ef0aad39a318eecec1a2a265bdc3e5 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Fri, 30 May 2014 15:16:00 -0300 Subject: [PATCH 5/6] Added a method to update the dive pictures on the model. And called that method from the mainWindow when the dive changes. The updateDivePictures walks around the events of the first dc ( since all pictures are distributed allong all dive computers ) to get the events of type '123' ( I wonder if there's not a better way to save pictures on the dive, line an linked list of char* named pictures. ) Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/divepicturewidget.cpp | 33 ++++++++++++++++++++++++++++++++- qt-ui/divepicturewidget.h | 6 ++++++ qt-ui/mainwindow.cpp | 4 +++- qt-ui/mainwindow.h | 1 + 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index a74bba0..11849af 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -1,10 +1,41 @@ #include "divepicturewidget.h" +#include <dive.h> void DivePictureDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyledItemDelegate::paint(painter, option, index); } +DivePictureModel::DivePictureModel(QObject *parent): QAbstractTableModel(parent) +{ + +} + +void DivePictureModel::updateDivePictures(int divenr) +{ + beginRemoveRows(QModelIndex(), 0, numberOfPictures-1); + numberOfPictures = 0; + endRemoveRows(); + + struct dive *d = get_dive(divenr); + if (!d) + return; + // All pictures are set in *all* divecomputers. ( waste of memory if > 100 pictures? ) + // so just get from the first one. + struct event *ev = d->dc.events; + while(ev){ + if(ev->type == 123){ // 123 means PICTURE. + numberOfPictures++; + } + ev = ev->next; + } + + if (numberOfPictures == 0) + return; + beginInsertRows(QModelIndex(), 0, numberOfPictures-1); + endInsertRows(); +} + int DivePictureModel::columnCount(const QModelIndex &parent) const { @@ -17,7 +48,7 @@ QVariant DivePictureModel::data(const QModelIndex &index, int role) const int DivePictureModel::rowCount(const QModelIndex &parent) const { - + return numberOfPictures; } DivePictureWidget::DivePictureWidget(QWidget *parent): QListView(parent) diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index 7761db3..062e225 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -7,9 +7,15 @@ #include <QThread> class DivePictureModel : QAbstractTableModel { +Q_OBJECT +public: + DivePictureModel(QObject *parent); 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(int divenr); +private: + int numberOfPictures; }; class DivePictureDelegate : QStyledItemDelegate { diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 9a325ce..4182ff1 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -59,7 +59,8 @@ MainWindow::MainWindow() : QMainWindow(), yearlyStatsModel(0), state(VIEWALL), updateManager(0), - fakeDiveId(0) + fakeDiveId(0), + divePictureModel(new DivePictureModel(this)) { Q_ASSERT_X(m_Instance == NULL, "MainWindow", "MainWindow recreated!"); m_Instance = this; @@ -164,6 +165,7 @@ void MainWindow::current_dive_changed(int divenr) */ ui.newProfile->plotDives(QList<dive *>() << (current_dive)); ui.InfoWidget->updateDiveInfo(divenr); + divePictureModel->updateDivePictures(divenr); } void MainWindow::on_actionNew_triggered() diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h index 9501e97..39d643a 100644 --- a/qt-ui/mainwindow.h +++ b/qt-ui/mainwindow.h @@ -179,6 +179,7 @@ private: bool plannerStateClean(); void createFakeDiveForAddAndPlan(); int fakeDiveId; + DivePictureModel *divePictureModel; }; #endif // MAINWINDOW_H -- 1.9.3
From 4a12b0bde49e1802ba3c3d07074f58217bc2ebb5 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Sat, 31 May 2014 00:42:54 -0300 Subject: [PATCH 6/6] Add Threaded processing of Image's pixmap. This code adds threaded processing of a batch of images. it uses the QtConcurrent implementations to call a function repeteadly using MAX_THREADS ( Qt gets that for us ) and returns a list of it. This call is blocking, so while the pixmaps are being scaled in threads, it will wait for all scalling to be done. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/divepicturewidget.cpp | 28 ++++++++++++++++++++++++++-- qt-ui/divepicturewidget.h | 4 ++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index 11849af..eda4ff6 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -1,5 +1,6 @@ #include "divepicturewidget.h" #include <dive.h> +#include <qtconcurrentmap.h> void DivePictureDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -11,29 +12,52 @@ DivePictureModel::DivePictureModel(QObject *parent): QAbstractTableModel(parent) } +typedef QPair<QString, QPixmap> SPixmap; +typedef QList<SPixmap> SPixmapList; + +SPixmap scaleImages(const QString& s){ + QPixmap p = QPixmap(s).scaled(128,128, Qt::KeepAspectRatio); + SPixmap ret; + ret.first = s; + ret.second = p; + return ret; +} + void DivePictureModel::updateDivePictures(int divenr) { + qDebug() << "Updating dive pictures."; beginRemoveRows(QModelIndex(), 0, numberOfPictures-1); numberOfPictures = 0; endRemoveRows(); + QStringList pictures; struct dive *d = get_dive(divenr); - if (!d) + if (!d){ + qDebug() << "Got no dive, exiting."; return; + } // All pictures are set in *all* divecomputers. ( waste of memory if > 100 pictures? ) // so just get from the first one. struct event *ev = d->dc.events; while(ev){ if(ev->type == 123){ // 123 means PICTURE. numberOfPictures++; + pictures.push_back(QString(ev->name)); } ev = ev->next; } - if (numberOfPictures == 0) + SPixmapList retList = QtConcurrent::blockingMapped<SPixmapList>( pictures, scaleImages); + Q_FOREACH(const SPixmap & pixmap, retList) + stringPixmapCache[pixmap.first] = pixmap.second; + + if (numberOfPictures == 0){ + qDebug() << "Got no pictures, exiting."; return; + } beginInsertRows(QModelIndex(), 0, numberOfPictures-1); endInsertRows(); + qDebug() << "Everything Ok."; } int DivePictureModel::columnCount(const QModelIndex &parent) const diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index 062e225..ff8d1aa 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -16,6 +16,10 @@ public: void updateDivePictures(int divenr); private: 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, QPixmap> stringPixmapCache; }; class DivePictureDelegate : QStyledItemDelegate { -- 1.9.3
_______________________________________________ subsurface mailing list [email protected] http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface
