mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 14:25:27 +00:00
Export to DiveShare
Adds the possibility of exporting dives to DiveShare. Signed-off-by: Salvo 'LtWorf' Tomaselli <tiposchi@tiscali.it> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
64d1ccc550
commit
4cdb80c4cd
8 changed files with 469 additions and 4 deletions
|
@ -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)"));
|
||||
|
|
|
@ -153,6 +153,16 @@
|
|||
</attribute>
|
||||
</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">
|
||||
|
|
142
qt-ui/diveshareexportdialog.cpp
Normal file
142
qt-ui/diveshareexportdialog.cpp
Normal file
|
@ -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()));
|
||||
}
|
34
qt-ui/diveshareexportdialog.h
Normal file
34
qt-ui/diveshareexportdialog.h
Normal file
|
@ -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
|
268
qt-ui/diveshareexportdialog.ui
Normal file
268
qt-ui/diveshareexportdialog.ui
Normal file
|
@ -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>
|
|
@ -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\":\"", "\"");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue