2015-06-04 10:29:50 +00:00
# include "qmlmanager.h"
2015-06-04 10:36:36 +00:00
# include <QUrl>
2015-07-10 07:47:26 +00:00
# include <QSettings>
2015-07-13 00:39:13 +00:00
# include <QDebug>
2015-12-05 03:34:59 +00:00
# include <QNetworkAccessManager>
# include <QAuthenticator>
2015-12-26 21:22:50 +00:00
# include <QDesktopServices>
2016-01-08 06:30:58 +00:00
# include <QTextDocument>
2015-06-04 10:29:50 +00:00
2015-06-11 06:56:18 +00:00
# include "qt-models/divelistmodel.h"
2016-01-08 15:11:49 +00:00
# include <gpslistmodel.h>
2015-06-11 06:56:18 +00:00
# include "divelist.h"
2016-01-29 06:04:13 +00:00
# include "device.h"
2015-07-10 07:47:26 +00:00
# include "pref.h"
2015-07-10 08:31:24 +00:00
# include "qthelper.h"
2015-07-13 00:39:13 +00:00
# include "qt-gui.h"
2015-12-15 07:00:19 +00:00
# include "git-access.h"
2016-01-26 14:45:03 +00:00
# include "subsurface-core/cloudstorage.h"
2015-07-13 00:39:13 +00:00
2015-12-03 23:59:40 +00:00
QMLManager * QMLManager : : m_instance = NULL ;
static void appendTextToLogStandalone ( const char * text )
2015-07-13 00:39:13 +00:00
{
2016-01-26 14:45:03 +00:00
QMLManager * self = QMLManager : : instance ( ) ;
if ( self )
self - > appendTextToLog ( QString ( text ) ) ;
2015-07-13 00:39:13 +00:00
}
2015-06-09 19:20:44 +00:00
2015-12-15 07:00:19 +00:00
extern " C " int gitProgressCB ( int percent )
{
static int lastPercent = - 10 ;
if ( percent - lastPercent > = 10 ) {
lastPercent + = 10 ;
2016-01-26 14:45:03 +00:00
QMLManager * self = QMLManager : : instance ( ) ;
if ( self )
self - > loadDiveProgress ( percent ) ;
2015-12-15 07:00:19 +00:00
}
// return 0 so that we don't end the download
return 0 ;
}
2016-01-11 14:14:45 +00:00
QMLManager : : QMLManager ( ) : m_locationServiceEnabled ( false ) ,
2016-01-07 00:56:08 +00:00
m_verboseEnabled ( false ) ,
m_loadFromCloud ( false ) ,
2016-01-26 14:45:03 +00:00
reply ( 0 )
2015-06-04 10:29:50 +00:00
{
2015-12-03 23:59:40 +00:00
m_instance = this ;
2015-12-20 16:02:05 +00:00
appendTextToLog ( getUserAgent ( ) ) ;
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " build with Qt Version %1, runtime from Qt Version %2 " ) . arg ( QT_VERSION_STR ) . arg ( qVersion ( ) ) ) ;
2015-12-20 16:02:05 +00:00
qDebug ( ) < < " Starting " < < getUserAgent ( ) ;
2016-01-26 15:02:42 +00:00
qDebug ( ) < < QStringLiteral ( " build with Qt Version %1, runtime from Qt Version %2 " ) . arg ( QT_VERSION_STR ) . arg ( qVersion ( ) ) ;
2015-12-15 07:00:19 +00:00
m_startPageText = tr ( " Searching for dive data " ) ;
2015-11-11 20:32:54 +00:00
// create location manager service
2015-12-03 23:59:40 +00:00
locationProvider = new GpsLocation ( & appendTextToLogStandalone , this ) ;
2015-12-15 07:00:19 +00:00
set_git_update_cb ( & gitProgressCB ) ;
2016-01-11 05:38:44 +00:00
QSettings s ;
if ( s . contains ( " setLoadFromCloud " ) & & s . value ( " setLoadFromCloud " ) . toInt ( ) = = 1 )
setLoadFromCloud ( true ) ;
2015-12-05 03:34:59 +00:00
}
2015-11-11 20:32:54 +00:00
2015-12-05 03:34:59 +00:00
void QMLManager : : finishSetup ( )
{
2015-11-11 20:32:54 +00:00
// Initialize cloud credentials.
2015-07-10 07:47:26 +00:00
setCloudUserName ( prefs . cloud_storage_email ) ;
setCloudPassword ( prefs . cloud_storage_password ) ;
2015-07-21 08:57:10 +00:00
setSaveCloudPassword ( prefs . save_password_local ) ;
2015-11-18 21:14:19 +00:00
// if the cloud credentials are valid, we should get the GPS Webservice ID as well
2015-12-27 16:32:15 +00:00
QString url ;
2015-11-18 21:14:19 +00:00
if ( ! same_string ( prefs . cloud_storage_email , " " ) & &
2015-12-27 16:32:15 +00:00
! same_string ( prefs . cloud_storage_password , " " ) & &
getCloudURL ( url ) = = 0 ) {
clear_dive_file_data ( ) ;
2016-01-11 14:14:45 +00:00
QByteArray fileNamePrt = QFile : : encodeName ( url ) ;
2015-12-27 16:32:15 +00:00
prefs . git_local_only = true ;
int error = parse_file ( fileNamePrt . data ( ) ) ;
prefs . git_local_only = false ;
if ( error ) {
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " loading dives from cache failed %1 " ) . arg ( error ) ) ;
2015-12-27 16:32:15 +00:00
} else {
2016-01-07 05:58:02 +00:00
prefs . unit_system = informational_prefs . unit_system ;
2016-01-20 16:45:43 +00:00
if ( informational_prefs . unit_system = = IMPERIAL )
informational_prefs . units = IMPERIAL_units ;
2016-01-07 05:58:02 +00:00
prefs . units = informational_prefs . units ;
2015-12-27 16:32:15 +00:00
int i ;
struct dive * d ;
process_dives ( false , false ) ;
DiveListModel : : instance ( ) - > clear ( ) ;
2016-01-11 14:14:45 +00:00
for_each_dive ( i , d ) {
2015-12-27 16:32:15 +00:00
DiveListModel : : instance ( ) - > addDive ( d ) ;
}
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " %1 dives loaded from cache " ) . arg ( i ) ) ;
2015-12-27 16:32:15 +00:00
}
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " have cloud credentials, trying to connect " ) ) ;
2015-12-05 03:34:59 +00:00
tryRetrieveDataFromBackend ( ) ;
2015-12-20 00:08:10 +00:00
} else {
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " no cloud credentials, tell user no dives found " ) ) ;
2015-12-20 00:08:10 +00:00
setStartPageText ( tr ( " No recorded dives found. You can download your dives to this device from the Subsurface cloud storage service, from your dive computer, or add them manually. " ) ) ;
}
2015-11-14 17:10:06 +00:00
setDistanceThreshold ( prefs . distance_threshold ) ;
setTimeThreshold ( prefs . time_threshold / 60 ) ;
2015-06-04 10:29:50 +00:00
}
QMLManager : : ~ QMLManager ( )
{
2015-12-03 23:59:40 +00:00
m_instance = NULL ;
}
QMLManager * QMLManager : : instance ( )
{
return m_instance ;
2015-06-04 10:29:50 +00:00
}
2015-07-10 07:47:26 +00:00
void QMLManager : : savePreferences ( )
{
QSettings s ;
2015-11-14 17:10:06 +00:00
s . beginGroup ( " LocationService " ) ;
s . setValue ( " time_threshold " , timeThreshold ( ) * 60 ) ;
prefs . time_threshold = timeThreshold ( ) * 60 ;
s . setValue ( " distance_threshold " , distanceThreshold ( ) ) ;
prefs . distance_threshold = distanceThreshold ( ) ;
2015-12-05 03:34:59 +00:00
s . sync ( ) ;
2015-12-03 22:30:30 +00:00
}
2015-12-05 03:34:59 +00:00
# define CLOUDURL QString(prefs.cloud_base_url)
# define CLOUDREDIRECTURL CLOUDURL + " / cgi-bin / redirect.pl"
2015-12-03 22:30:30 +00:00
void QMLManager : : saveCloudCredentials ( )
{
QSettings s ;
bool cloudCredentialsChanged = false ;
2015-07-10 07:47:26 +00:00
s . beginGroup ( " CloudStorage " ) ;
s . setValue ( " email " , cloudUserName ( ) ) ;
2015-07-21 08:57:10 +00:00
s . setValue ( " save_password_local " , saveCloudPassword ( ) ) ;
if ( saveCloudPassword ( ) )
s . setValue ( " password " , cloudPassword ( ) ) ;
2015-07-10 07:47:26 +00:00
s . sync ( ) ;
2015-07-13 00:39:13 +00:00
if ( ! same_string ( prefs . cloud_storage_email , qPrintable ( cloudUserName ( ) ) ) ) {
free ( prefs . cloud_storage_email ) ;
prefs . cloud_storage_email = strdup ( qPrintable ( cloudUserName ( ) ) ) ;
2015-11-18 21:14:19 +00:00
cloudCredentialsChanged = true ;
2015-07-13 00:39:13 +00:00
}
2015-11-18 21:12:34 +00:00
if ( saveCloudPassword ( ) ! = prefs . save_password_local )
2015-07-21 08:57:10 +00:00
prefs . save_password_local = saveCloudPassword ( ) ;
2015-11-18 21:14:19 +00:00
cloudCredentialsChanged | = ! same_string ( prefs . cloud_storage_password , qPrintable ( cloudPassword ( ) ) ) ;
2015-07-21 08:57:10 +00:00
if ( saveCloudPassword ( ) ) {
if ( ! same_string ( prefs . cloud_storage_password , qPrintable ( cloudPassword ( ) ) ) ) {
free ( prefs . cloud_storage_password ) ;
prefs . cloud_storage_password = strdup ( qPrintable ( cloudPassword ( ) ) ) ;
}
2015-07-13 00:39:13 +00:00
}
2015-12-05 03:34:59 +00:00
if ( cloudCredentialsChanged ) {
free ( prefs . userid ) ;
prefs . userid = NULL ;
tryRetrieveDataFromBackend ( ) ;
}
}
void QMLManager : : checkCredentialsAndExecute ( execute_function_type execute )
{
// if the cloud credentials are present, we should try to get the GPS Webservice ID
// and (if we haven't done so) load the dive list
2015-11-18 21:14:19 +00:00
if ( ! same_string ( prefs . cloud_storage_email , " " ) & &
! same_string ( prefs . cloud_storage_password , " " ) ) {
2016-01-02 08:04:59 +00:00
setStartPageText ( tr ( " Testing cloud credentials " ) ) ;
2015-12-05 03:34:59 +00:00
appendTextToLog ( " Have credentials, let's see if they are valid " ) ;
2016-01-26 14:45:03 +00:00
connect ( manager ( ) , & QNetworkAccessManager : : authenticationRequired , this , & QMLManager : : provideAuth , Qt : : UniqueConnection ) ;
connect ( manager ( ) , & QNetworkAccessManager : : finished , this , execute , Qt : : UniqueConnection ) ;
2015-12-05 03:34:59 +00:00
QUrl url ( CLOUDREDIRECTURL ) ;
request = QNetworkRequest ( url ) ;
request . setRawHeader ( " User-Agent " , getUserAgent ( ) . toUtf8 ( ) ) ;
request . setRawHeader ( " Accept " , " text/html " ) ;
2016-01-26 14:45:03 +00:00
reply = manager ( ) - > get ( request ) ;
2015-12-05 03:34:59 +00:00
connect ( reply , SIGNAL ( error ( QNetworkReply : : NetworkError ) ) , this , SLOT ( handleError ( QNetworkReply : : NetworkError ) ) ) ;
connect ( reply , & QNetworkReply : : sslErrors , this , & QMLManager : : handleSslErrors ) ;
2015-11-18 21:14:19 +00:00
}
2015-12-05 03:34:59 +00:00
}
void QMLManager : : tryRetrieveDataFromBackend ( )
{
checkCredentialsAndExecute ( & QMLManager : : retrieveUserid ) ;
2015-07-10 07:47:26 +00:00
}
2015-07-10 08:31:24 +00:00
void QMLManager : : loadDives ( )
{
2015-12-05 03:34:59 +00:00
checkCredentialsAndExecute ( & QMLManager : : loadDivesWithValidCredentials ) ;
}
void QMLManager : : provideAuth ( QNetworkReply * reply , QAuthenticator * auth )
{
if ( auth - > user ( ) = = QString ( prefs . cloud_storage_email ) & &
auth - > password ( ) = = QString ( prefs . cloud_storage_password ) ) {
// OK, credentials have been tried and didn't work, so they are invalid
appendTextToLog ( " Cloud credentials are invalid " ) ;
2016-01-02 08:04:59 +00:00
setStartPageText ( tr ( " Cloud credentials are invalid " ) ) ;
2015-12-05 03:34:59 +00:00
reply - > disconnect ( ) ;
reply - > abort ( ) ;
reply - > deleteLater ( ) ;
2015-11-30 18:15:04 +00:00
return ;
}
2015-12-05 03:34:59 +00:00
auth - > setUser ( prefs . cloud_storage_email ) ;
auth - > setPassword ( prefs . cloud_storage_password ) ;
}
void QMLManager : : handleSslErrors ( const QList < QSslError > & errors )
{
2015-12-15 07:00:19 +00:00
setStartPageText ( tr ( " Cannot open cloud storage: Error creating https connection " ) ) ;
2016-01-11 14:14:45 +00:00
Q_FOREACH ( QSslError e , errors ) {
2015-12-05 03:34:59 +00:00
qDebug ( ) < < e . errorString ( ) ;
}
reply - > abort ( ) ;
reply - > deleteLater ( ) ;
}
2015-11-30 18:15:04 +00:00
2015-12-05 03:34:59 +00:00
void QMLManager : : handleError ( QNetworkReply : : NetworkError nError )
{
2015-12-15 07:00:19 +00:00
QString errorString = reply - > errorString ( ) ;
qDebug ( ) < < " handleError " < < nError < < errorString ;
setStartPageText ( tr ( " Cannot open cloud storage: %1 " ) . arg ( errorString ) ) ;
2015-12-05 03:34:59 +00:00
reply - > abort ( ) ;
reply - > deleteLater ( ) ;
}
void QMLManager : : retrieveUserid ( )
{
if ( reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) ! = 302 ) {
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " Cloud storage connection not working correctly: " ) + reply - > readAll ( ) ) ;
2015-12-05 03:34:59 +00:00
return ;
}
QString userid ( prefs . userid ) ;
2015-12-20 00:20:20 +00:00
if ( userid . isEmpty ( ) ) {
if ( same_string ( prefs . cloud_storage_email , " " ) | | same_string ( prefs . cloud_storage_password , " " ) ) {
appendTextToLog ( " cloud user name or password are empty, can't retrieve web user id " ) ;
return ;
}
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " calling getUserid with user %1 " ) . arg ( prefs . cloud_storage_email ) ) ;
2015-12-05 03:34:59 +00:00
userid = locationProvider - > getUserid ( prefs . cloud_storage_email , prefs . cloud_storage_password ) ;
2015-12-20 00:20:20 +00:00
}
2015-12-05 03:34:59 +00:00
if ( ! userid . isEmpty ( ) ) {
// overwrite the existing userid
free ( prefs . userid ) ;
prefs . userid = strdup ( qPrintable ( userid ) ) ;
QSettings s ;
s . setValue ( " subsurface_webservice_uid " , prefs . userid ) ;
s . sync ( ) ;
}
if ( ! loadFromCloud ( ) )
loadDivesWithValidCredentials ( ) ;
}
2015-12-15 07:00:19 +00:00
void QMLManager : : loadDiveProgress ( int percent )
{
QString text ( tr ( " Loading dive list from cloud storage. " ) ) ;
2016-01-11 14:14:45 +00:00
while ( percent > 0 ) {
2015-12-15 07:00:19 +00:00
text . append ( " . " ) ;
percent - = 10 ;
}
setStartPageText ( text ) ;
}
2015-12-05 03:34:59 +00:00
void QMLManager : : loadDivesWithValidCredentials ( )
{
if ( reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) ! = 302 ) {
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " Cloud storage connection not working correctly: " ) + reply - > readAll ( ) ) ;
2015-12-15 07:00:19 +00:00
setStartPageText ( tr ( " Cannot connect to cloud storage " ) ) ;
2015-12-05 03:34:59 +00:00
return ;
}
appendTextToLog ( " Cloud credentials valid, loading dives... " ) ;
2015-12-15 07:00:19 +00:00
loadDiveProgress ( 0 ) ;
2015-07-10 08:31:24 +00:00
QString url ;
if ( getCloudURL ( url ) ) {
2015-12-15 07:00:19 +00:00
QString errorString ( get_error_string ( ) ) ;
appendTextToLog ( errorString ) ;
setStartPageText ( tr ( " Cloud storage error: %1 " ) . arg ( errorString ) ) ;
2015-07-10 08:31:24 +00:00
return ;
}
2016-01-11 14:14:45 +00:00
QByteArray fileNamePrt = QFile : : encodeName ( url ) ;
2016-01-05 01:48:34 +00:00
if ( check_git_sha ( fileNamePrt . data ( ) ) = = 0 ) {
2015-12-27 18:05:19 +00:00
qDebug ( ) < < " local cache was current, no need to modify dive list " ;
appendTextToLog ( " Cloud sync shows local cache was current " ) ;
2016-01-07 19:49:29 +00:00
setLoadFromCloud ( true ) ;
2015-12-27 18:05:19 +00:00
return ;
}
2016-01-05 01:48:34 +00:00
clear_dive_file_data ( ) ;
DiveListModel : : instance ( ) - > clear ( ) ;
2015-12-27 18:05:19 +00:00
2016-01-05 01:48:34 +00:00
int error = parse_file ( fileNamePrt . data ( ) ) ;
2015-07-10 08:31:24 +00:00
if ( ! error ) {
2015-07-13 00:39:13 +00:00
report_error ( " filename is now %s " , fileNamePrt . data ( ) ) ;
2015-12-01 17:37:47 +00:00
const char * error_string = get_error_string ( ) ;
appendTextToLog ( error_string ) ;
2015-07-10 08:31:24 +00:00
set_filename ( fileNamePrt . data ( ) , true ) ;
2015-07-13 00:39:13 +00:00
} else {
2015-12-01 17:37:47 +00:00
report_error ( " failed to open file %s " , fileNamePrt . data ( ) ) ;
2015-12-15 07:00:19 +00:00
QString errorString ( get_error_string ( ) ) ;
appendTextToLog ( errorString ) ;
setStartPageText ( tr ( " Cloud storage error: %1 " ) . arg ( errorString ) ) ;
2015-12-03 01:50:47 +00:00
return ;
2015-07-10 08:31:24 +00:00
}
2016-01-07 05:58:02 +00:00
prefs . unit_system = informational_prefs . unit_system ;
2016-01-20 16:45:43 +00:00
if ( informational_prefs . unit_system = = IMPERIAL )
informational_prefs . units = IMPERIAL_units ;
2016-01-07 05:58:02 +00:00
prefs . units = informational_prefs . units ;
2015-07-10 08:31:24 +00:00
process_dives ( false , false ) ;
2015-07-24 20:18:30 +00:00
2015-07-10 08:31:24 +00:00
int i ;
struct dive * d ;
2016-01-11 14:14:45 +00:00
for_each_dive ( i , d ) {
2015-07-24 20:18:30 +00:00
DiveListModel : : instance ( ) - > addDive ( d ) ;
}
2016-01-26 15:02:42 +00:00
appendTextToLog ( QStringLiteral ( " %1 dives loaded " ) . arg ( i ) ) ;
2015-12-15 07:00:19 +00:00
if ( dive_table . nr = = 0 )
setStartPageText ( tr ( " Cloud storage open successfully. No dives in dive list. " ) ) ;
2015-12-03 02:49:02 +00:00
setLoadFromCloud ( true ) ;
2015-07-17 15:28:01 +00:00
}
2016-01-11 03:34:21 +00:00
void QMLManager : : refreshDiveList ( )
{
int i ;
struct dive * d ;
DiveListModel : : instance ( ) - > clear ( ) ;
2016-01-11 14:14:45 +00:00
for_each_dive ( i , d ) {
2016-01-11 03:34:21 +00:00
DiveListModel : : instance ( ) - > addDive ( d ) ;
}
}
2016-01-08 06:30:58 +00:00
// update the dive and return the notes field, stripped of the HTML junk
QString QMLManager : : commitChanges ( QString diveId , QString date , QString location , QString gps , QString duration , QString depth ,
2016-02-06 06:54:47 +00:00
QString airtemp , QString watertemp , QString suit , QString buddy , QString diveMaster , QString weight , QString notes )
2015-07-17 15:28:01 +00:00
{
2016-01-28 22:00:52 +00:00
# define DROP_EMPTY_PLACEHOLDER(_s) if ((_s) == QLatin1Literal("--")) (_s).clear()
DROP_EMPTY_PLACEHOLDER ( location ) ;
DROP_EMPTY_PLACEHOLDER ( duration ) ;
DROP_EMPTY_PLACEHOLDER ( depth ) ;
DROP_EMPTY_PLACEHOLDER ( airtemp ) ;
DROP_EMPTY_PLACEHOLDER ( watertemp ) ;
DROP_EMPTY_PLACEHOLDER ( suit ) ;
DROP_EMPTY_PLACEHOLDER ( buddy ) ;
DROP_EMPTY_PLACEHOLDER ( diveMaster ) ;
2016-02-06 06:54:47 +00:00
DROP_EMPTY_PLACEHOLDER ( weight ) ;
2016-01-28 22:00:52 +00:00
DROP_EMPTY_PLACEHOLDER ( notes ) ;
# undef DROP_EMPTY_PLACEHOLDER
2015-07-17 15:28:01 +00:00
struct dive * d = get_dive_by_uniq_id ( diveId . toInt ( ) ) ;
2016-01-08 06:30:58 +00:00
// notes comes back as rich text - let's convert this into plain text
QTextDocument doc ;
doc . setHtml ( notes ) ;
notes = doc . toPlainText ( ) ;
2015-12-27 05:24:29 +00:00
if ( ! d ) {
qDebug ( ) < < " don't touch this... no dive " ;
2016-01-08 06:30:58 +00:00
return notes ;
2015-12-27 05:24:29 +00:00
}
2015-07-17 15:28:01 +00:00
bool diveChanged = false ;
2016-01-06 06:57:40 +00:00
bool needResort = false ;
2015-07-17 15:28:01 +00:00
2016-01-06 06:53:32 +00:00
if ( date ! = get_dive_date_string ( d - > when ) ) {
2016-01-27 20:11:37 +00:00
diveChanged = needResort = true ;
2016-01-06 06:53:32 +00:00
QDateTime newDate ;
// what a pain - Qt will not parse dates if the day of the week is incorrect
// so if the user changed the date but didn't update the day of the week (most likely behavior, actually),
// we need to make sure we don't try to parse that
2016-01-26 15:02:42 +00:00
QString format ( QString ( prefs . date_format ) + QChar ( ' ' ) + prefs . time_format ) ;
if ( format . contains ( QLatin1String ( " ddd " ) ) | | format . contains ( QLatin1String ( " dddd " ) ) ) {
QString dateFormatToDrop = format . contains ( QLatin1String ( " ddd " ) ) ? QStringLiteral ( " ddd " ) : QStringLiteral ( " dddd " ) ;
2016-01-06 06:53:32 +00:00
QDateTime ts ;
QLocale loc = getLocale ( ) ;
ts . setMSecsSinceEpoch ( d - > when * 1000L ) ;
QString drop = loc . toString ( ts . toUTC ( ) , dateFormatToDrop ) ;
format . replace ( dateFormatToDrop , " " ) ;
date . replace ( drop , " " ) ;
}
newDate = QDateTime : : fromString ( date , format ) ;
2016-01-27 20:07:10 +00:00
if ( newDate . isValid ( ) ) {
// stupid Qt... two digit years are always 19xx - WTF???
// so if adding a hundred years gets you into something before a year from now...
// add a hundred years.
if ( newDate . addYears ( 100 ) < QDateTime : : currentDateTime ( ) . addYears ( 1 ) )
newDate = newDate . addYears ( 100 ) ;
2016-01-11 06:07:58 +00:00
d - > dc . when = d - > when = newDate . toMSecsSinceEpoch ( ) / 1000 + gettimezoneoffset ( newDate . toMSecsSinceEpoch ( ) / 1000 ) ;
2016-01-27 20:07:10 +00:00
}
2016-01-06 06:53:32 +00:00
}
2015-12-27 06:57:47 +00:00
struct dive_site * ds = get_dive_site_by_uuid ( d - > dive_site_uuid ) ;
char * locationtext = NULL ;
if ( ds )
locationtext = ds - > name ;
if ( ! same_string ( locationtext , qPrintable ( location ) ) ) {
diveChanged = true ;
// this is not ideal - and it's missing the gps information
// but for now let's just create a new dive site
ds = get_dive_site_by_uuid ( create_dive_site ( qPrintable ( location ) , d - > when ) ) ;
d - > dive_site_uuid = ds - > uuid ;
}
2016-01-27 14:29:14 +00:00
if ( ! gps . isEmpty ( ) ) {
QString gpsString = getCurrentPosition ( ) ;
if ( gpsString ! = QString ( " waiting for the next gps location " ) ) {
qDebug ( ) < < " from commitChanges call to getCurrentPosition returns " < < gpsString ;
double lat , lon ;
if ( parseGpsText ( qPrintable ( gpsString ) , & lat , & lon ) ) {
struct dive_site * ds = get_dive_site_by_uuid ( d - > dive_site_uuid ) ;
if ( ds ) {
ds - > latitude . udeg = lat * 1000000 ;
ds - > longitude . udeg = lon * 1000000 ;
} else {
degrees_t latData , lonData ;
latData . udeg = lat ;
lonData . udeg = lon ;
d - > dive_site_uuid = create_dive_site_with_gps ( " new site " , latData , lonData , d - > when ) ;
}
qDebug ( ) < < " set up dive site with new GPS data " ;
2016-01-02 01:23:29 +00:00
}
2016-01-27 14:29:14 +00:00
} else {
qDebug ( ) < < " still don't have a position - will need to implement some sort of callback " ;
2016-01-02 01:23:29 +00:00
}
}
2016-01-01 08:23:15 +00:00
if ( get_dive_duration_string ( d - > duration . seconds , tr ( " h: " ) , tr ( " min " ) ) ! = duration ) {
diveChanged = true ;
int h = 0 , m = 0 , s = 0 ;
2016-02-06 20:07:42 +00:00
QRegExp r1 ( QStringLiteral ( " ( \\ d*) \ \ s * % 1 [ \ \ s , : ] * ( \ \ d * ) \ \ s * % 2 [ \ \ s , : ] * ( \ \ d * ) \ \ s * % 3 " ).arg(tr( " h " )).arg(tr( " min " )).arg(tr( " sec " )), Qt::CaseInsensitive) ;
QRegExp r2 ( QStringLiteral ( " ( \\ d*) \ \ s * % 1 [ \ \ s , : ] * ( \ \ d * ) \ \ s * % 2 " ).arg(tr( " h " )).arg(tr( " min " )), Qt::CaseInsensitive) ;
QRegExp r3 ( QStringLiteral ( " ( \\ d*) \ \ s * % 1 " ).arg(tr( " min " )), Qt::CaseInsensitive) ;
2016-01-26 15:02:42 +00:00
QRegExp r4 ( QStringLiteral ( " ( \\ d*) : ( \ \ d * ) : ( \ \ d * ) " )) ;
QRegExp r5 ( QStringLiteral ( " ( \\ d*) : ( \ \ d * ) " )) ;
2016-01-01 08:23:15 +00:00
if ( r1 . indexIn ( duration ) > = 0 ) {
h = r1 . cap ( 1 ) . toInt ( ) ;
m = r1 . cap ( 2 ) . toInt ( ) ;
s = r1 . cap ( 3 ) . toInt ( ) ;
} else if ( r2 . indexIn ( duration ) > = 0 ) {
h = r2 . cap ( 1 ) . toInt ( ) ;
m = r2 . cap ( 2 ) . toInt ( ) ;
} else if ( r3 . indexIn ( duration ) > = 0 ) {
m = r3 . cap ( 1 ) . toInt ( ) ;
} else if ( r4 . indexIn ( duration ) > = 0 ) {
h = r4 . cap ( 1 ) . toInt ( ) ;
m = r4 . cap ( 2 ) . toInt ( ) ;
s = r4 . cap ( 3 ) . toInt ( ) ;
} else if ( r5 . indexIn ( duration ) > = 0 ) {
h = r5 . cap ( 1 ) . toInt ( ) ;
m = r5 . cap ( 2 ) . toInt ( ) ;
}
2016-01-11 06:08:42 +00:00
d - > dc . duration . seconds = d - > duration . seconds = h * 3600 + m * 60 + s ;
2016-01-01 08:23:15 +00:00
}
2016-01-01 08:32:30 +00:00
if ( get_depth_string ( d - > maxdepth . mm , true , true ) ! = depth ) {
diveChanged = true ;
if ( depth . contains ( tr ( " ft " ) ) )
prefs . units . length = units : : FEET ;
else if ( depth . contains ( tr ( " m " ) ) )
prefs . units . length = units : : METERS ;
d - > maxdepth . mm = parseLengthToMm ( depth ) ;
if ( same_string ( d - > dc . model , " manually added dive " ) )
d - > dc . maxdepth . mm = d - > maxdepth . mm ;
}
2016-01-20 21:56:28 +00:00
if ( get_temperature_string ( d - > airtemp , true ) ! = airtemp ) {
2016-01-01 01:34:20 +00:00
diveChanged = true ;
if ( airtemp . contains ( tr ( " C " ) ) )
prefs . units . temperature = units : : CELSIUS ;
else if ( airtemp . contains ( tr ( " F " ) ) )
prefs . units . temperature = units : : FAHRENHEIT ;
d - > airtemp . mkelvin = parseTemperatureToMkelvin ( airtemp ) ;
}
2016-01-20 21:56:28 +00:00
if ( get_temperature_string ( d - > watertemp , true ) ! = watertemp ) {
2016-01-01 01:34:20 +00:00
diveChanged = true ;
if ( watertemp . contains ( tr ( " C " ) ) )
prefs . units . temperature = units : : CELSIUS ;
else if ( watertemp . contains ( tr ( " F " ) ) )
prefs . units . temperature = units : : FAHRENHEIT ;
d - > watertemp . mkelvin = parseTemperatureToMkelvin ( watertemp ) ;
}
2016-02-06 06:54:47 +00:00
// not sure what we'd do if there was more than one weight system
// defined - for now just ignore that case
if ( weightsystem_none ( ( void * ) & d - > weightsystem [ 1 ] ) ) {
if ( get_weight_string ( d - > weightsystem [ 0 ] . weight , true ) ! = weight ) {
diveChanged = true ;
if ( weight . contains ( tr ( " kg " ) ) )
prefs . units . weight = units : : KG ;
else if ( weight . contains ( tr ( " lbs " ) ) )
prefs . units . weight = units : : LBS ;
d - > weightsystem [ 0 ] . weight . grams = parseWeightToGrams ( weight ) ;
}
}
2015-12-27 06:57:47 +00:00
if ( ! same_string ( d - > suit , qPrintable ( suit ) ) ) {
2015-07-17 15:28:01 +00:00
diveChanged = true ;
free ( d - > suit ) ;
2015-12-27 06:57:47 +00:00
d - > suit = strdup ( qPrintable ( suit ) ) ;
2015-07-17 15:28:01 +00:00
}
2015-12-27 06:57:47 +00:00
if ( ! same_string ( d - > buddy , qPrintable ( buddy ) ) ) {
2015-07-17 15:28:01 +00:00
diveChanged = true ;
free ( d - > buddy ) ;
2015-12-27 06:57:47 +00:00
d - > buddy = strdup ( qPrintable ( buddy ) ) ;
2015-07-17 15:28:01 +00:00
}
2015-12-27 06:57:47 +00:00
if ( ! same_string ( d - > divemaster , qPrintable ( diveMaster ) ) ) {
2015-07-17 15:28:01 +00:00
diveChanged = true ;
free ( d - > divemaster ) ;
2015-12-27 06:57:47 +00:00
d - > divemaster = strdup ( qPrintable ( diveMaster ) ) ;
2015-07-17 15:28:01 +00:00
}
2015-12-27 06:57:47 +00:00
if ( ! same_string ( d - > notes , qPrintable ( notes ) ) ) {
2015-07-17 15:28:01 +00:00
diveChanged = true ;
free ( d - > notes ) ;
2015-12-27 06:57:47 +00:00
d - > notes = strdup ( qPrintable ( notes ) ) ;
2015-07-17 15:28:01 +00:00
}
2016-01-27 20:11:37 +00:00
int oldIdx = get_idx_by_uniq_id ( d - > id ) ;
if ( needResort ) {
// we know that the only thing that might happen in a resort is that
// this one dive moves to a different spot in the dive list
2016-01-06 06:57:40 +00:00
sort_table ( & dive_table ) ;
2016-01-27 20:11:37 +00:00
int newIdx = get_idx_by_uniq_id ( d - > id ) ;
if ( newIdx ! = oldIdx ) {
DiveObjectHelper * newDive = new DiveObjectHelper ( d ) ;
DiveListModel : : instance ( ) - > removeDive ( oldIdx ) ;
DiveListModel : : instance ( ) - > insertDive ( newIdx , newDive ) ;
diveChanged = false ; // because we already modified things
}
}
2016-01-29 06:04:13 +00:00
if ( d - > maxdepth . mm = = d - > dc . maxdepth . mm & &
d - > maxdepth . mm > 0 & &
same_string ( d - > dc . model , " manually added dive " ) & &
d - > dc . samples = = 0 ) {
// so we have depth > 0, a manually added dive and no samples
// let's create an actual profile so the desktop version can work it
d - > dc = * fake_dc ( & d - > dc ) ;
}
2016-01-27 20:11:37 +00:00
if ( diveChanged )
DiveListModel : : instance ( ) - > updateDive ( oldIdx , d ) ;
2016-01-06 06:57:40 +00:00
if ( diveChanged | | needResort ) {
2015-11-19 03:26:07 +00:00
mark_divelist_changed ( true ) ;
2016-01-11 05:40:03 +00:00
// this is called "commit" for a reason - when the user saves an
// edit they have a reasonable expectation that their data is actually
// stored - so we need to store this to the local cache
qDebug ( ) < < " save dives to local cache " ;
prefs . cloud_background_sync = false ;
saveChanges ( ) ;
prefs . cloud_background_sync = true ;
2015-12-08 06:24:56 +00:00
}
2016-01-08 06:30:58 +00:00
return notes ;
2015-07-17 15:28:01 +00:00
}
void QMLManager : : saveChanges ( )
{
2015-12-03 02:49:02 +00:00
if ( ! loadFromCloud ( ) ) {
2015-12-03 23:59:40 +00:00
appendTextToLog ( " Don't save dives without loading from the cloud, first. " ) ;
2015-12-03 02:49:02 +00:00
return ;
}
2015-12-03 23:59:40 +00:00
appendTextToLog ( " Saving dives. " ) ;
2015-07-17 15:28:01 +00:00
QString fileName ;
if ( getCloudURL ( fileName ) ) {
2015-08-19 07:17:52 +00:00
appendTextToLog ( get_error_string ( ) ) ;
2015-07-17 15:28:01 +00:00
return ;
}
if ( save_dives ( fileName . toUtf8 ( ) . data ( ) ) ) {
2015-08-19 07:17:52 +00:00
appendTextToLog ( get_error_string ( ) ) ;
2015-07-17 15:28:01 +00:00
return ;
}
2015-08-19 07:17:52 +00:00
appendTextToLog ( " Dive saved. " ) ;
2015-07-17 15:28:01 +00:00
set_filename ( fileName . toUtf8 ( ) . data ( ) , true ) ;
mark_divelist_changed ( false ) ;
2015-07-10 08:31:24 +00:00
}
2015-08-10 05:35:47 +00:00
2015-12-27 05:37:18 +00:00
QString QMLManager : : addDive ( )
2015-08-10 05:35:47 +00:00
{
2015-08-19 07:17:52 +00:00
appendTextToLog ( " Adding new dive. " ) ;
2015-12-27 05:37:18 +00:00
return DiveListModel : : instance ( ) - > startAddDive ( ) ;
2015-08-10 05:35:47 +00:00
}
2016-01-29 14:25:13 +00:00
void QMLManager : : addDiveAborted ( int id )
{
DiveListModel : : instance ( ) - > removeDiveById ( id ) ;
}
2016-01-02 01:23:29 +00:00
QString QMLManager : : getCurrentPosition ( )
{
return locationProvider - > currentPosition ( ) ;
}
2015-11-13 04:23:00 +00:00
void QMLManager : : applyGpsData ( )
{
2016-01-11 03:34:21 +00:00
if ( locationProvider - > applyLocations ( ) )
refreshDiveList ( ) ;
2015-11-13 04:23:00 +00:00
}
2015-11-14 01:21:43 +00:00
void QMLManager : : sendGpsData ( )
{
locationProvider - > uploadToServer ( ) ;
}
2016-01-08 05:37:36 +00:00
void QMLManager : : downloadGpsData ( )
{
locationProvider - > downloadFromServer ( ) ;
2016-01-08 15:11:49 +00:00
populateGpsData ( ) ;
2016-01-08 05:37:36 +00:00
}
2016-01-08 05:40:15 +00:00
void QMLManager : : populateGpsData ( )
{
2016-01-08 15:11:49 +00:00
if ( GpsListModel : : instance ( ) )
GpsListModel : : instance ( ) - > update ( ) ;
2016-01-08 05:40:15 +00:00
}
2015-11-14 01:20:45 +00:00
void QMLManager : : clearGpsData ( )
{
locationProvider - > clearGpsData ( ) ;
2016-01-08 15:11:49 +00:00
populateGpsData ( ) ;
2015-11-14 01:20:45 +00:00
}
2016-01-09 07:18:41 +00:00
void QMLManager : : deleteGpsFix ( quint64 when )
{
locationProvider - > deleteGpsFix ( when ) ;
populateGpsData ( ) ;
}
2015-08-19 07:17:52 +00:00
QString QMLManager : : logText ( ) const
{
2015-11-13 17:17:13 +00:00
QString logText = m_logText + QString ( " \n Numer of GPS fixes: %1 " ) . arg ( locationProvider - > getGpsNum ( ) ) ;
return logText ;
2015-08-19 07:17:52 +00:00
}
void QMLManager : : setLogText ( const QString & logText )
{
m_logText = logText ;
2015-08-20 09:08:59 +00:00
emit logTextChanged ( ) ;
2015-08-19 07:17:52 +00:00
}
void QMLManager : : appendTextToLog ( const QString & newText )
{
m_logText + = " \n " + newText ;
2015-08-20 09:08:59 +00:00
emit logTextChanged ( ) ;
2015-08-19 07:17:52 +00:00
}
2015-07-21 08:57:10 +00:00
bool QMLManager : : saveCloudPassword ( ) const
{
return m_saveCloudPassword ;
}
void QMLManager : : setSaveCloudPassword ( bool saveCloudPassword )
{
m_saveCloudPassword = saveCloudPassword ;
}
2015-11-11 20:34:56 +00:00
bool QMLManager : : locationServiceEnabled ( ) const
{
return m_locationServiceEnabled ;
}
void QMLManager : : setLocationServiceEnabled ( bool locationServiceEnabled )
{
m_locationServiceEnabled = locationServiceEnabled ;
locationProvider - > serviceEnable ( m_locationServiceEnabled ) ;
}
2015-07-10 08:31:24 +00:00
2015-12-20 02:41:10 +00:00
bool QMLManager : : verboseEnabled ( ) const
{
return m_verboseEnabled ;
}
void QMLManager : : setVerboseEnabled ( bool verboseMode )
{
m_verboseEnabled = verboseMode ;
verbose = verboseMode ;
qDebug ( ) < < " verbose is " < < verbose ;
emit verboseEnabledChanged ( ) ;
}
2015-07-10 07:47:26 +00:00
QString QMLManager : : cloudPassword ( ) const
{
return m_cloudPassword ;
}
void QMLManager : : setCloudPassword ( const QString & cloudPassword )
{
m_cloudPassword = cloudPassword ;
emit cloudPasswordChanged ( ) ;
}
QString QMLManager : : cloudUserName ( ) const
{
return m_cloudUserName ;
}
void QMLManager : : setCloudUserName ( const QString & cloudUserName )
{
m_cloudUserName = cloudUserName ;
emit cloudUserNameChanged ( ) ;
}
2015-11-14 01:14:22 +00:00
2015-11-14 17:10:06 +00:00
int QMLManager : : distanceThreshold ( ) const
{
return m_distanceThreshold ;
}
void QMLManager : : setDistanceThreshold ( int distance )
{
m_distanceThreshold = distance ;
emit distanceThresholdChanged ( ) ;
}
int QMLManager : : timeThreshold ( ) const
{
return m_timeThreshold ;
}
void QMLManager : : setTimeThreshold ( int time )
{
m_timeThreshold = time ;
emit timeThresholdChanged ( ) ;
}
2015-12-03 02:49:02 +00:00
bool QMLManager : : loadFromCloud ( ) const
{
return m_loadFromCloud ;
}
void QMLManager : : setLoadFromCloud ( bool done )
{
2016-01-11 05:38:44 +00:00
QSettings s ;
s . setValue ( " loadFromCloud " , 1 ) ;
2015-12-03 02:49:02 +00:00
m_loadFromCloud = done ;
emit loadFromCloudChanged ( ) ;
}
2015-12-15 07:00:19 +00:00
QString QMLManager : : startPageText ( ) const
{
return m_startPageText ;
}
2016-01-26 15:02:42 +00:00
void QMLManager : : setStartPageText ( const QString & text )
2015-12-15 07:00:19 +00:00
{
m_startPageText = text ;
emit startPageTextChanged ( ) ;
}
2015-12-26 21:22:50 +00:00
2016-01-26 15:02:42 +00:00
void QMLManager : : showMap ( const QString & location )
2015-12-26 21:22:50 +00:00
{
if ( ! location . isEmpty ( ) ) {
2016-01-02 06:24:05 +00:00
QString link = QString ( " https://www.google.com/maps/place/%1/@%2,5000m/data=!3m1!1e3!4m2!3m1!1s0x0:0x0 " )
2016-01-11 14:14:45 +00:00
. arg ( location )
. arg ( location ) ;
2015-12-26 21:22:50 +00:00
QDesktopServices : : openUrl ( link ) ;
}
}
2015-12-27 04:02:23 +00:00
2016-01-26 15:02:42 +00:00
QString QMLManager : : getNumber ( const QString & diveId )
2015-12-27 04:02:23 +00:00
{
int dive_id = diveId . toInt ( ) ;
struct dive * d = get_dive_by_uniq_id ( dive_id ) ;
QString number ;
if ( d )
number = QString : : number ( d - > number ) ;
return number ;
}
2016-01-26 15:02:42 +00:00
QString QMLManager : : getDate ( const QString & diveId )
2015-12-27 04:02:23 +00:00
{
int dive_id = diveId . toInt ( ) ;
struct dive * d = get_dive_by_uniq_id ( dive_id ) ;
QString datestring ;
if ( d )
datestring = get_dive_date_string ( d - > when ) ;
return datestring ;
}