summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qt-ui/divelogexportdialog.cpp5
-rw-r--r--qt-ui/divelogexportdialog.ui10
-rw-r--r--qt-ui/diveshareexportdialog.cpp142
-rw-r--r--qt-ui/diveshareexportdialog.h34
-rw-r--r--qt-ui/diveshareexportdialog.ui268
-rw-r--r--save-html.c3
-rw-r--r--save-html.h2
-rw-r--r--subsurface.pro9
8 files changed, 469 insertions, 4 deletions
diff --git a/qt-ui/divelogexportdialog.cpp b/qt-ui/divelogexportdialog.cpp
index 3f9373a4f..6b847a425 100644
--- a/qt-ui/divelogexportdialog.cpp
+++ b/qt-ui/divelogexportdialog.cpp
@@ -9,6 +9,7 @@
#include "mainwindow.h"
#include "divelogexportdialog.h"
+#include "diveshareexportdialog.h"
#include "ui_divelogexportdialog.h"
#include "subsurfacewebservices.h"
#include "worldmap-save.h"
@@ -70,6 +71,8 @@ void DiveLogExportDialog::showExplanation()
ui->description->setText(tr("Comma separated values that include the most relevant information of the dive profile."));
} else if (ui->exportDivelogs->isChecked()) {
ui->description->setText(tr("Send the dive data to divelogs.de website."));
+ } else if (ui->exportDiveshare->isChecked()) {
+ ui->description->setText(tr("Send the dive data to dive-share.appspot.com website"));
} else if (ui->exportWorldMap->isChecked()) {
ui->description->setText(tr("HTML export of the dive locations, visualized on a world map."));
} else if (ui->exportSubsurfaceXML->isChecked()) {
@@ -245,6 +248,8 @@ void DiveLogExportDialog::on_buttonBox_accepted()
tr("CSV files (*.csv *.CSV)"));
} else if (ui->exportDivelogs->isChecked()) {
DivelogsDeWebServices::instance()->prepareDivesForUpload(ui->exportSelected->isChecked());
+ } else if (ui->exportDiveshare->isChecked()) {
+ DiveShareExportDialog::instance()->prepareDivesForUpload(ui->exportSelected->isChecked());
} else if (ui->exportWorldMap->isChecked()) {
filename = QFileDialog::getSaveFileName(this, tr("Export world map"), lastDir,
tr("HTML files (*.html)"));
diff --git a/qt-ui/divelogexportdialog.ui b/qt-ui/divelogexportdialog.ui
index b54d2eac6..aaa485eb3 100644
--- a/qt-ui/divelogexportdialog.ui
+++ b/qt-ui/divelogexportdialog.ui
@@ -154,6 +154,16 @@
</widget>
</item>
<item>
+ <widget class="QRadioButton" name="exportDiveshare">
+ <property name="text">
+ <string>DiveShare</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
<widget class="QRadioButton" name="exportCSV">
<property name="text">
<string>CSV</string>
diff --git a/qt-ui/diveshareexportdialog.cpp b/qt-ui/diveshareexportdialog.cpp
new file mode 100644
index 000000000..8f817ae63
--- /dev/null
+++ b/qt-ui/diveshareexportdialog.cpp
@@ -0,0 +1,142 @@
+#include "diveshareexportdialog.h"
+#include "ui_diveshareexportdialog.h"
+#include "mainwindow.h"
+#include "save-html.h"
+#include "qt-ui/usersurvey.h"
+#include "qt-ui/subsurfacewebservices.h"
+
+#include <QDesktopServices>
+#include <QUrl>
+#include <QSettings>
+
+DiveShareExportDialog::DiveShareExportDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::DiveShareExportDialog),
+ reply(NULL)
+{
+ ui->setupUi(this);
+}
+
+DiveShareExportDialog::~DiveShareExportDialog()
+{
+ delete ui;
+ delete reply;
+}
+
+void DiveShareExportDialog::UIDFromBrowser()
+{
+ QDesktopServices::openUrl(QUrl(DIVESHARE_BASE_URI "/secret"));
+}
+
+DiveShareExportDialog *DiveShareExportDialog::instance()
+{
+ static DiveShareExportDialog *self = new DiveShareExportDialog(MainWindow::instance());
+ self->setAttribute(Qt::WA_QuitOnClose, false);
+ self->ui->txtResult->setHtml("");
+ self->ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
+ return self;
+}
+
+void DiveShareExportDialog::prepareDivesForUpload(bool selected)
+{
+ exportSelected = selected;
+ ui->frameConfigure->setVisible(true);
+ ui->frameResults->setVisible(false);
+
+ QSettings settings;
+ if (settings.contains("diveshareExport/uid"))
+ ui->txtUID->setText(settings.value("diveshareExport/uid").toString());
+
+ if (settings.contains("diveshareExport/private"))
+ ui->chkPrivate->setChecked(settings.value("diveshareExport/private").toBool());
+
+ show();
+}
+
+static QByteArray generate_html_list(const QByteArray &data)
+{
+ QList<QByteArray> dives = data.split('\n');
+ QByteArray html;
+ html.append("<html><body><table>");
+ for (int i = 0; i < dives.length(); i++ ) {
+ html.append("<tr>");
+ QList<QByteArray> dive_details = dives[i].split(',');
+ if (dive_details.length() < 3)
+ continue;
+
+ QByteArray dive_id = dive_details[0];
+ QByteArray dive_delete = dive_details[1];
+
+ html.append("<td>");
+ html.append("<a href=\"" DIVESHARE_BASE_URI "/dive/" + dive_id + "\">");
+
+ //Title gets separated too, this puts it back together
+ const char *sep = "";
+ for (int t = 2; t < dive_details.length(); t++) {
+ html.append(sep);
+ html.append(dive_details[t]);
+ sep = ",";
+ }
+
+ html.append("</a>");
+ html.append("</td>");
+ html.append("<td>");
+ html.append("<a href=\"" DIVESHARE_BASE_URI "/delete/dive/" + dive_delete + "\">Delete dive</a>");
+ html.append("</td>" );
+
+ html.append("</tr>");
+ }
+
+ html.append("</table></body></html>");
+ return html;
+}
+
+void DiveShareExportDialog::finishedSlot()
+{
+ ui->progressBar->setVisible(false);
+ if (reply->error() != 0) {
+ ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
+ ui->txtResult->setText(reply->errorString());
+ } else {
+ ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok);
+ ui->txtResult->setHtml(generate_html_list(reply->readAll()));
+ }
+
+ reply->deleteLater();
+}
+
+void DiveShareExportDialog::doUpload()
+{
+ //Store current settings
+ QSettings settings;
+ settings.setValue("diveshareExport/uid", ui->txtUID->text());
+ settings.setValue("diveshareExport/private", ui->chkPrivate->isChecked());
+
+ //Change UI into results mode
+ ui->frameConfigure->setVisible(false);
+ ui->frameResults->setVisible(true);
+ ui->progressBar->setVisible(true);
+ ui->progressBar->setRange(0, 0);
+
+ //generate json
+ struct membuffer buf = { 0 };
+ export_list(&buf, NULL, exportSelected, false);
+ QByteArray json_data(buf.buffer, buf.len);
+ free_buffer(&buf);
+
+ //Request to server
+ QNetworkRequest request;
+
+ if (ui->chkPrivate->isChecked())
+ request.setUrl(QUrl(DIVESHARE_BASE_URI "/upload?private=true"));
+ else
+ request.setUrl(QUrl(DIVESHARE_BASE_URI "/upload"));
+
+ request.setRawHeader("User-Agent", UserSurvey::getUserAgent().toUtf8());
+ if (ui->txtUID->text().length() != 0)
+ request.setRawHeader("X-UID", ui->txtUID->text().toUtf8());
+
+ reply = WebServices::manager()->put(request, json_data);
+
+ QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot()));
+}
diff --git a/qt-ui/diveshareexportdialog.h b/qt-ui/diveshareexportdialog.h
new file mode 100644
index 000000000..85dadf5f1
--- /dev/null
+++ b/qt-ui/diveshareexportdialog.h
@@ -0,0 +1,34 @@
+#ifndef DIVESHAREEXPORTDIALOG_H
+#define DIVESHAREEXPORTDIALOG_H
+
+#include <QDialog>
+#include <QNetworkReply>
+#include <QNetworkAccessManager>
+
+#define DIVESHARE_WEBSITE "dive-share.appspot.com"
+#define DIVESHARE_BASE_URI "http://" DIVESHARE_WEBSITE
+
+namespace Ui {
+class DiveShareExportDialog;
+}
+
+class DiveShareExportDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit DiveShareExportDialog(QWidget *parent = 0);
+ ~DiveShareExportDialog();
+ static DiveShareExportDialog *instance();
+ void prepareDivesForUpload(bool);
+private:
+ Ui::DiveShareExportDialog *ui;
+ bool exportSelected;
+ QNetworkReply *reply;
+private
+slots:
+ void UIDFromBrowser();
+ void doUpload();
+ void finishedSlot();
+};
+
+#endif // DIVESHAREEXPORTDIALOG_H
diff --git a/qt-ui/diveshareexportdialog.ui b/qt-ui/diveshareexportdialog.ui
new file mode 100644
index 000000000..051f4f3e2
--- /dev/null
+++ b/qt-ui/diveshareexportdialog.ui
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DiveShareExportDialog</class>
+ <widget class="QDialog" name="DiveShareExportDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>309</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QFrame" name="frameConfigure">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>User ID</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtUID">
+ <property name="toolTip">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cmdClear">
+ <property name="text">
+ <string>⌫</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="getUIDbutton">
+ <property name="text">
+ <string>Get UserID</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:20pt; font-weight:600; color:#ff8000;&quot;&gt;⚠&lt;/span&gt; Not using a UserID means that you will need to manually keep bookmarks to your dives, to find them again.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="chkPrivate">
+ <property name="toolTip">
+ <string>Private dives will not appear in &quot;related dives&quot; lists, and will only be accessible if their URL is known.</string>
+ </property>
+ <property name="text">
+ <string>Keep dives private</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="doUploadButton">
+ <property name="text">
+ <string>Upload dive data</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frameResults">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QTextBrowser" name="txtResult">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;asd&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>24</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>68</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>DiveShareExportDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>97</x>
+ <y>299</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>252</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>getUIDbutton</sender>
+ <signal>clicked()</signal>
+ <receiver>DiveShareExportDialog</receiver>
+ <slot>UIDFromBrowser()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>223</x>
+ <y>29</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>159</x>
+ <y>215</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>doUploadButton</sender>
+ <signal>clicked()</signal>
+ <receiver>DiveShareExportDialog</receiver>
+ <slot>doUpload()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>223</x>
+ <y>120</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>159</x>
+ <y>215</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cmdClear</sender>
+ <signal>clicked()</signal>
+ <receiver>txtUID</receiver>
+ <slot>clear()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>148</x>
+ <y>36</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>105</x>
+ <y>27</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>DiveShareExportDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>159</x>
+ <y>288</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>159</x>
+ <y>154</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>getUID()</slot>
+ <slot>doUpload()</slot>
+ </slots>
+</ui>
diff --git a/save-html.c b/save-html.c
index b517b199e..2befb418e 100644
--- a/save-html.c
+++ b/save-html.c
@@ -290,7 +290,8 @@ void write_one_dive(struct membuffer *b, struct dive *dive, const char *photos_d
put_HTML_samples(b, dive);
put_HTML_bookmarks(b, dive);
write_dive_status(b, dive);
- save_photos(b, photos_dir, dive);
+ if (photos_dir)
+ save_photos(b, photos_dir, dive);
write_divecomputers(b, dive);
}
put_HTML_notes(b, dive, "\"notes\":\"", "\"");
diff --git a/save-html.h b/save-html.h
index f47ae3ba6..fddbf2681 100644
--- a/save-html.h
+++ b/save-html.h
@@ -16,6 +16,8 @@ void put_HTML_notes(struct membuffer *b, struct dive *dive, const char *pre, con
void put_HTML_quoted(struct membuffer *b, const char *text);
void export_HTML(const char *file_name, const char *photos_dir, const bool selected_only, const bool list_only);
+void export_list(struct membuffer *b, const char *photos_dir, bool selected_only, const bool list_only);
+
void export_translation(const char *file_name);
extern void copy_image_and_overwrite(const char *cfileName, const char *cnewName);
diff --git a/subsurface.pro b/subsurface.pro
index 176e23ffe..d4b71c303 100644
--- a/subsurface.pro
+++ b/subsurface.pro
@@ -99,7 +99,8 @@ HEADERS = \
qt-ui/statistics/monthstatistics.h \
qt-ui/statistics/statisticswidget.h \
qt-ui/statistics/statisticsbar.h \
- qt-ui/statistics/yearstatistics.h
+ qt-ui/statistics/yearstatistics.h \
+ qt-ui/diveshareexportdialog.h
android: HEADERS -= \
qt-ui/usermanual.h \
@@ -188,7 +189,8 @@ SOURCES = \
qt-ui/statistics/statisticswidget.cpp \
qt-ui/statistics/yearstatistics.cpp \
qt-ui/statistics/statisticsbar.cpp \
- qt-ui/statistics/monthstatistics.cpp
+ qt-ui/statistics/monthstatistics.cpp \
+ qt-ui/diveshareexportdialog.cpp
android: SOURCES += android.cpp
else: win32: SOURCES += windows.c
@@ -222,7 +224,8 @@ FORMS = \
qt-ui/usersurvey.ui \
qt-ui/divecomponentselection.ui \
qt-ui/configuredivecomputerdialog.ui \
- qt-ui/tagfilter.ui
+ qt-ui/tagfilter.ui \
+ qt-ui/diveshareexportdialog.ui
# Nether usermanual or printing is supported on android right now
android: FORMS -= qt-ui/printoptions.ui