diff --git a/connector/syncthingconnection.cpp b/connector/syncthingconnection.cpp index 3cb073e..1af462d 100644 --- a/connector/syncthingconnection.cpp +++ b/connector/syncthingconnection.cpp @@ -54,6 +54,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt m_lastEventId(0), m_trafficPollInterval(2000), m_devStatsPollInterval(60000), + m_reconnectTimer(), m_totalIncomingTraffic(0), m_totalOutgoingTraffic(0), m_totalIncomingRate(0), @@ -67,7 +68,10 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt m_hasConfig(false), m_hasStatus(false), m_lastFileDeleted(false) -{} +{ + m_reconnectTimer.setTimerType(Qt::VeryCoarseTimer); + QObject::connect(&m_reconnectTimer, &QTimer::timeout, this, static_cast(&SyncthingConnection::connect)); +} /*! * \brief Destroys the instance. Ongoing requests are aborted. @@ -117,6 +121,7 @@ bool SyncthingConnection::hasOutOfSyncDirs() const */ void SyncthingConnection::connect() { + m_reconnectTimer.stop(); if(!isConnected()) { m_reconnecting = m_hasConfig = m_hasStatus = false; if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) { @@ -144,6 +149,7 @@ void SyncthingConnection::disconnect() */ void SyncthingConnection::reconnect() { + m_reconnectTimer.stop(); if(isConnected()) { m_reconnecting = true; m_hasConfig = m_hasStatus = false; @@ -622,6 +628,7 @@ void SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionS } setTrafficPollInterval(connectionSettings.trafficPollInterval); setDevStatsPollInterval(connectionSettings.devStatsPollInterval); + setReconnectInterval(connectionSettings.reconnectInterval); if(connectionSettings.expectedSslErrors.isEmpty()) { loadSelfSignedCertificate(); connectionSettings.expectedSslErrors = expectedSslErrors(); @@ -661,6 +668,9 @@ void SyncthingConnection::readConfig() default: emit error(tr("Unable to request Syncthing config: ") + reply->errorString()); setStatus(SyncthingStatus::Disconnected); + if(m_reconnectTimer.interval()) { + m_reconnectTimer.start(); + } } } @@ -1046,6 +1056,9 @@ void SyncthingConnection::readEvents() } else { emit error(tr("Unable to parse Syncthing events: ") + jsonError.errorString()); setStatus(SyncthingStatus::Disconnected); + if(m_reconnectTimer.interval()) { + m_reconnectTimer.start(); + } return; } break; @@ -1065,6 +1078,9 @@ void SyncthingConnection::readEvents() default: emit error(tr("Unable to request Syncthing events: ") + reply->errorString()); setStatus(SyncthingStatus::Disconnected); + if(m_reconnectTimer.interval()) { + m_reconnectTimer.start(); + } return; } diff --git a/connector/syncthingconnection.h b/connector/syncthingconnection.h index 63bff60..a53ce37 100644 --- a/connector/syncthingconnection.h +++ b/connector/syncthingconnection.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,8 @@ public: void setTrafficPollInterval(int trafficPollInterval); int devStatsPollInterval() const; void setDevStatsPollInterval(int devStatsPollInterval); + int reconnectInterval() const; + void setReconnectInterval(int reconnectInterval); const QString &configDir() const; const QString &myId() const; int totalIncomingTraffic() const; @@ -186,6 +189,7 @@ private: int m_lastEventId; int m_trafficPollInterval; int m_devStatsPollInterval; + QTimer m_reconnectTimer; QString m_configDir; QString m_myId; int m_totalIncomingTraffic; @@ -327,6 +331,27 @@ inline void SyncthingConnection::setDevStatsPollInterval(int devStatsPollInterva m_devStatsPollInterval = devStatsPollInterval; } +/*! + * \brief Returns the reconnect interval in milliseconds. + * \remarks Default value is 0 which indicates disabled auto-reconnect. + */ +inline int SyncthingConnection::reconnectInterval() const +{ + return m_reconnectTimer.interval(); +} + +/*! + * \brief Sets the reconnect interval in milliseconds. + * \remarks Default value is 0 which indicates disabled auto-reconnect. + */ +inline void SyncthingConnection::setReconnectInterval(int reconnectInterval) +{ + if(!reconnectInterval) { + m_reconnectTimer.stop(); + } + m_reconnectTimer.setInterval(reconnectInterval); +} + /*! * \brief Returns the Syncthing home/configuration directory. */ diff --git a/connector/syncthingconnectionsettings.h b/connector/syncthingconnectionsettings.h index 2c1dbff7..23a1827 100644 --- a/connector/syncthingconnectionsettings.h +++ b/connector/syncthingconnectionsettings.h @@ -18,6 +18,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings { QByteArray apiKey; int trafficPollInterval = 2000; int devStatsPollInterval = 60000; + int reconnectInterval = 0; QString httpsCertPath; QList expectedSslErrors; bool loadHttpsCert(); diff --git a/tray/application/settings.cpp b/tray/application/settings.cpp index 9af0896..eb248c7 100644 --- a/tray/application/settings.cpp +++ b/tray/application/settings.cpp @@ -167,6 +167,7 @@ void restore() connectionSettings->apiKey = settings.value(QStringLiteral("apiKey")).toByteArray(); connectionSettings->trafficPollInterval = settings.value(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval).toInt(); connectionSettings->devStatsPollInterval = settings.value(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval).toInt(); + connectionSettings->reconnectInterval = settings.value(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval).toInt(); connectionSettings->httpsCertPath = settings.value(QStringLiteral("httpsCertPath")).toString(); if(!connectionSettings->loadHttpsCert()) { QMessageBox::critical(nullptr, QCoreApplication::applicationName(), QCoreApplication::translate("Settings::restore", "Unable to load certificate \"%1\" when restoring settings.").arg(connectionSettings->httpsCertPath)); @@ -224,6 +225,7 @@ void save() settings.setValue(QStringLiteral("apiKey"), connectionSettings->apiKey); settings.setValue(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval); settings.setValue(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval); + settings.setValue(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval); settings.setValue(QStringLiteral("httpsCertPath"), connectionSettings->httpsCertPath); } settings.endArray(); diff --git a/tray/gui/connectionoptionpage.ui b/tray/gui/connectionoptionpage.ui index f608cf1..464b5c1 100644 --- a/tray/gui/connectionoptionpage.ui +++ b/tray/gui/connectionoptionpage.ui @@ -295,6 +295,12 @@ + + + 0 + 0 + + ms @@ -322,6 +328,12 @@ + + + 0 + 0 + + ms @@ -333,6 +345,39 @@ + + + + Qt::Vertical + + + + + + + Reconnect + + + + + + + + 0 + 0 + + + + no + + + ms + + + 999999999 + + + diff --git a/tray/gui/settingsdialog.cpp b/tray/gui/settingsdialog.cpp index b74f81e..26745f1 100644 --- a/tray/gui/settingsdialog.cpp +++ b/tray/gui/settingsdialog.cpp @@ -118,6 +118,7 @@ bool ConnectionOptionPage::showConnectionSettings(int index) ui()->certPathSelection->lineEdit()->setText(connectionSettings.httpsCertPath); ui()->pollTrafficSpinBox->setValue(connectionSettings.trafficPollInterval); ui()->pollDevStatsSpinBox->setValue(connectionSettings.devStatsPollInterval); + ui()->reconnectSpinBox->setValue(connectionSettings.reconnectInterval); m_currentIndex = index; } else { ui()->selectionComboBox->setCurrentIndex(m_currentIndex); @@ -142,6 +143,7 @@ bool ConnectionOptionPage::cacheCurrentSettings(bool applying) connectionSettings.httpsCertPath = ui()->certPathSelection->lineEdit()->text(); connectionSettings.trafficPollInterval = ui()->pollTrafficSpinBox->value(); connectionSettings.devStatsPollInterval = ui()->pollDevStatsSpinBox->value(); + connectionSettings.reconnectInterval = ui()->reconnectSpinBox->value(); if(!connectionSettings.loadHttpsCert()) { const QString errorMessage = QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to load specified certificate \"%1\".").arg(connectionSettings.httpsCertPath); if(!applying) { diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp index 4887bad..cfa9e22 100644 --- a/tray/gui/traywidget.cpp +++ b/tray/gui/traywidget.cpp @@ -294,6 +294,8 @@ void TrayWidget::handleStatusChanged(SyncthingStatus status) m_ui->statusPushButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/media-playback-resume.svg")))); m_ui->statusPushButton->setHidden(false); break; + default: + ; } } @@ -404,6 +406,8 @@ void TrayWidget::changeStatus() case SyncthingStatus::Paused: m_connection.resumeAllDevs(); break; + default: + ; } }