diff options
-rw-r--r-- | qt-ui/divelogexportdialog.cpp | 5 | ||||
-rw-r--r-- | qt-ui/divelogexportdialog.ui | 10 | ||||
-rw-r--r-- | qt-ui/diveshareexportdialog.cpp | 142 | ||||
-rw-r--r-- | qt-ui/diveshareexportdialog.h | 34 | ||||
-rw-r--r-- | qt-ui/diveshareexportdialog.ui | 268 | ||||
-rw-r--r-- | save-html.c | 3 | ||||
-rw-r--r-- | save-html.h | 2 | ||||
-rw-r--r-- | subsurface.pro | 9 |
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><html><head/><body><p><span style=" font-size:20pt; font-weight:600; color:#ff8000;">⚠</span> Not using a UserID means that you will need to manually keep bookmarks to your dives, to find them again.</p></body></html></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 "related dives" 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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.google.com"><span style=" text-decoration: underline; color:#0000ff;">asd</span></a></p></body></html></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 |