summaryrefslogtreecommitdiffstats
path: root/qt-ui
diff options
context:
space:
mode:
authorGravatar Robert C. Helling <helling@atdotde.de>2015-04-24 17:10:55 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-04-24 09:36:21 -0700
commit757c4aab20cee9cd3699276a9b4f7a7aee4719c2 (patch)
treecc4e06502e06183a8267e6708dbb9870ad183816 /qt-ui
parent98ae7b1f8657d153dd3b431638ff0110429b9d5f (diff)
downloadsubsurface-757c4aab20cee9cd3699276a9b4f7a7aee4719c2.tar.gz
Allow images to be added via the web
This adds a new divelist context menu entry which asks for a URL. The file is retrieved and if it is an image it is added to the cache and the url is associated to dives as with local files. NB this currently only works with URLs pointing directly to images. But it should not be too hard to add the possibility to add a direction via an html file and its image tags. To test: open dives/test43.xml and delete the image and then add the URL http://euve10195.vserver.de/~robert/wreck.jpg Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'qt-ui')
-rw-r--r--qt-ui/divelistview.cpp67
-rw-r--r--qt-ui/divelistview.h5
-rw-r--r--qt-ui/divepicturewidget.cpp4
-rw-r--r--qt-ui/simplewidgets.cpp14
-rw-r--r--qt-ui/simplewidgets.h10
-rw-r--r--qt-ui/urldialog.ui91
6 files changed, 189 insertions, 2 deletions
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index 92ae60b5d..fda170c56 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -4,17 +4,21 @@
* classes for the divelist of Subsurface
*
*/
-#include "divelistview.h"
#include "filtermodels.h"
#include "modeldelegates.h"
#include "mainwindow.h"
#include "divepicturewidget.h"
#include "display.h"
+#include <unistd.h>
#include <QSettings>
#include <QKeyEvent>
#include <QFileDialog>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QStandardPaths>
#include "qthelper.h"
#include "undocommands.h"
+#include "divelistview.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};
@@ -834,6 +838,7 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
popup.addAction(tr("Renumber dive(s)"), this, SLOT(renumberDives()));
popup.addAction(tr("Shift times"), this, SLOT(shiftTimes()));
popup.addAction(tr("Load images"), this, SLOT(loadImages()));
+ popup.addAction(tr("Load image(s) from web"), this, SLOT(loadWebImages()));
}
// "collapse all" really closes all trips,
@@ -859,8 +864,12 @@ void DiveListView::loadImages()
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open image files"), lastUsedImageDir(), tr("Image files (*.jpg *.jpeg *.pnm *.tif *.tiff)"));
if (fileNames.isEmpty())
return;
-
updateLastUsedImageDir(QFileInfo(fileNames[0]).dir().path());
+ matchImagesToDives(fileNames);
+}
+
+void DiveListView::matchImagesToDives(QStringList fileNames)
+{
ShiftImageTimesDialog shiftDialog(this, fileNames);
shiftDialog.setOffset(lastImageTimeOffset());
if (!shiftDialog.exec())
@@ -882,6 +891,60 @@ void DiveListView::loadImages()
DivePictureModel::instance()->updateDivePictures();
}
+void DiveListView::loadWebImages()
+{
+ URLDialog urlDialog(this);
+ if (!urlDialog.exec())
+ return;
+ loadImageFromURL(QUrl::fromUserInput(urlDialog.url()));
+
+}
+
+void DiveListView::loadImageFromURL(QUrl url)
+{
+ if (url.isValid()) {
+ QEventLoop loop;
+ QNetworkRequest request(url);
+ QNetworkReply *reply = manager.get(request);
+ while (reply->isRunning()) {
+ loop.processEvents();
+ sleep(1);
+ }
+ QByteArray imageData = reply->readAll();
+
+ QImage image = QImage();
+ image.loadFromData(imageData);
+ if (image.isNull())
+ // If this is not an image, maybe it's an html file and Miika can provide some xslr magic to extract images.
+ // In this case we would call the function recursively on the list of image source urls;
+ return;
+
+ // Since we already downloaded the image we can cache it as well.
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+ hash.addData(imageData);
+ QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
+ QDir dir(path);
+ if (!dir.exists())
+ dir.mkpath(path);
+ QFile imageFile(path.append("/").append(hash.result().toHex()));
+ if (imageFile.open(QIODevice::WriteOnly)) {
+ QDataStream stream(&imageFile);
+ stream.writeRawData(imageData.data(), imageData.length());
+ imageFile.waitForBytesWritten(-1);
+ imageFile.close();
+ add_hash(imageFile.fileName(), hash.result());
+ struct picture picture;
+ picture.hash = NULL;
+ picture.filename = strdup(url.toString().toUtf8().data());
+ learnHash(&picture, hash.result());
+ matchImagesToDives(QStringList(url.toString()));
+ }
+ }
+
+
+}
+
+
QString DiveListView::lastUsedImageDir()
{
QSettings settings;
diff --git a/qt-ui/divelistview.h b/qt-ui/divelistview.h
index a6522fa9a..6e9a18215 100644
--- a/qt-ui/divelistview.h
+++ b/qt-ui/divelistview.h
@@ -13,6 +13,7 @@
#include <QTreeView>
#include <QLineEdit>
+#include <QNetworkAccessManager>
#include "models.h"
class DiveListView : public QTreeView {
@@ -51,6 +52,7 @@ slots:
void renumberDives();
void shiftTimes();
void loadImages();
+ void loadWebImages();
static QString lastUsedImageDir();
signals:
@@ -78,6 +80,9 @@ private:
void updateLastImageTimeOffset(int offset);
int lastImageTimeOffset();
void addToTrip(int delta);
+ void matchImagesToDives(QStringList fileNames);
+ void loadImageFromURL(QUrl url);
+ QNetworkAccessManager manager;
};
#endif // DIVELISTVIEW_H
diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp
index ce997fea1..8c1cb3571 100644
--- a/qt-ui/divepicturewidget.cpp
+++ b/qt-ui/divepicturewidget.cpp
@@ -63,6 +63,10 @@ void ImageDownloader::load(){
void ImageDownloader::saveImage(QNetworkReply *reply)
{
QByteArray imageData = reply->readAll();
+ QImage image = QImage();
+ image.loadFromData(imageData);
+ if (image.isNull())
+ return;
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(imageData);
QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 2b8605a69..a074ad18c 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -361,6 +361,20 @@ void ShiftImageTimesDialog::timeEditChanged(const QTime &time)
updateInvalid();
}
+URLDialog::URLDialog(QWidget *parent) : QDialog(parent)
+{
+ ui.setupUi(this);
+ QShortcut *close = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
+ connect(close, SIGNAL(activated()), this, SLOT(close()));
+ QShortcut *quit = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this);
+ connect(quit, SIGNAL(activated()), parent, SLOT(close()));
+}
+
+QString URLDialog::url() const
+{
+ return ui.urlField->toPlainText();
+}
+
bool isGnome3Session()
{
#if defined(QT_OS_WIW) || defined(QT_OS_MAC)
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index 5f2402a86..dde30335f 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -14,6 +14,7 @@ class QNetworkReply;
#include "ui_setpoint.h"
#include "ui_shifttimes.h"
#include "ui_shiftimagetimes.h"
+#include "ui_urldialog.h"
#include "ui_divecomponentselection.h"
#include "ui_listfilter.h"
#include "ui_filterwidget.h"
@@ -115,6 +116,15 @@ private:
time_t dcImageEpoch;
};
+class URLDialog : public QDialog {
+ Q_OBJECT
+public:
+ explicit URLDialog(QWidget *parent);
+ QString url() const;
+private:
+ Ui::URLDialog ui;
+};
+
class QCalendarWidget;
class DateWidget : public QWidget {
diff --git a/qt-ui/urldialog.ui b/qt-ui/urldialog.ui
new file mode 100644
index 000000000..397f90a64
--- /dev/null
+++ b/qt-ui/urldialog.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>URLDialog</class>
+ <widget class="QDialog" name="URLDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>397</width>
+ <height>103</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>40</x>
+ <y>60</y>
+ <width>341</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ <widget class="QPlainTextEdit" name="urlField">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>371</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>151</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Enter URL for images</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>URLDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>URLDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>