Refactor overall status compution
* Allow configuring the information to consider for computing the overall status via SyncthingStatusComputionFlags * Add flag to allow considering the status of remote devices for https://github.com/Martchus/syncthingtray/issues/74 * Show only plain "idle" status when no flags are present for https://github.com/Martchus/syncthingtray/issues/76 * Set the default flags to keep the default behavior as-is
This commit is contained in:
parent
392eb70b12
commit
da911c6350
|
@ -579,20 +579,25 @@ void Application::printStatus(const ArgumentOccurrence &)
|
||||||
const auto &overallStats(m_connection.computeOverallDirStatistics());
|
const auto &overallStats(m_connection.computeOverallDirStatistics());
|
||||||
const auto *statusString = "idle";
|
const auto *statusString = "idle";
|
||||||
const auto *statusColor = "32";
|
const auto *statusColor = "32";
|
||||||
switch (m_connection.status()) {
|
if (m_connection.hasOutOfSyncDirs()) {
|
||||||
case SyncthingStatus::Synchronizing:
|
|
||||||
statusString = "synchronizing";
|
|
||||||
statusColor = "34";
|
|
||||||
break;
|
|
||||||
case SyncthingStatus::Scanning:
|
|
||||||
statusString = "scanning";
|
|
||||||
statusColor = "34";
|
|
||||||
break;
|
|
||||||
case SyncthingStatus::OutOfSync:
|
|
||||||
statusString = "out-of-sync";
|
statusString = "out-of-sync";
|
||||||
statusColor = "31";
|
statusColor = "31";
|
||||||
break;
|
} else {
|
||||||
default:;
|
switch (m_connection.status()) {
|
||||||
|
case SyncthingStatus::Synchronizing:
|
||||||
|
statusString = "synchronizing";
|
||||||
|
statusColor = "34";
|
||||||
|
break;
|
||||||
|
case SyncthingStatus::RemoteNotInSync:
|
||||||
|
statusString = "remote synchronizing";
|
||||||
|
statusColor = "34";
|
||||||
|
break;
|
||||||
|
case SyncthingStatus::Scanning:
|
||||||
|
statusString = "scanning";
|
||||||
|
statusColor = "34";
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!EscapeCodes::enabled) {
|
if (!EscapeCodes::enabled) {
|
||||||
printProperty("Status", statusString);
|
printProperty("Status", statusString);
|
||||||
|
|
|
@ -72,6 +72,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
|
||||||
, m_syncthingUrl(syncthingUrl)
|
, m_syncthingUrl(syncthingUrl)
|
||||||
, m_apiKey(apiKey)
|
, m_apiKey(apiKey)
|
||||||
, m_status(SyncthingStatus::Disconnected)
|
, m_status(SyncthingStatus::Disconnected)
|
||||||
|
, m_statusComputionFlags(SyncthingStatusComputionFlags::Default)
|
||||||
, m_keepPolling(false)
|
, m_keepPolling(false)
|
||||||
, m_abortingAllRequests(false)
|
, m_abortingAllRequests(false)
|
||||||
, m_abortingToReconnect(false)
|
, m_abortingToReconnect(false)
|
||||||
|
@ -169,6 +170,8 @@ QString SyncthingConnection::statusText(SyncthingStatus status)
|
||||||
return tr("connected, paused");
|
return tr("connected, paused");
|
||||||
case SyncthingStatus::Synchronizing:
|
case SyncthingStatus::Synchronizing:
|
||||||
return tr("connected, synchronizing");
|
return tr("connected, synchronizing");
|
||||||
|
case SyncthingStatus::RemoteNotInSync:
|
||||||
|
return tr("connected, remote not in sync");
|
||||||
default:
|
default:
|
||||||
return tr("unknown");
|
return tr("unknown");
|
||||||
}
|
}
|
||||||
|
@ -773,15 +776,29 @@ bool SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionS
|
||||||
setDevStatsPollInterval(connectionSettings.devStatsPollInterval);
|
setDevStatsPollInterval(connectionSettings.devStatsPollInterval);
|
||||||
setErrorsPollInterval(connectionSettings.errorsPollInterval);
|
setErrorsPollInterval(connectionSettings.errorsPollInterval);
|
||||||
setAutoReconnectInterval(connectionSettings.reconnectInterval);
|
setAutoReconnectInterval(connectionSettings.reconnectInterval);
|
||||||
|
setStatusComputionFlags(connectionSettings.statusComputionFlags);
|
||||||
|
|
||||||
return reconnectRequired;
|
return reconnectRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the connection status. Ensures statusChanged() is emitted.
|
* \brief Sets the connection status. Ensures statusChanged() is emitted if the status has actually changed.
|
||||||
* \param status Specifies the status; should be either SyncthingStatus::Disconnected, SyncthingStatus::Reconnecting, or
|
* \param status Specifies the status; should be either SyncthingStatus::Disconnected, SyncthingStatus::Reconnecting, or
|
||||||
* SyncthingStatus::Idle. There is no use in specifying other values such as SyncthingStatus::Synchronizing as
|
* SyncthingStatus::Idle. There is no use in specifying other values such as SyncthingStatus::Synchronizing as
|
||||||
* these are determined automatically within the method.
|
* these are determined automatically within the method according to SyncthingConnection::statusComputionFlags().
|
||||||
|
*
|
||||||
|
* The precedence of the "connected" states from highest to lowest is:
|
||||||
|
* 1. SyncthingStatus::Synchronizing
|
||||||
|
* 2. SyncthingStatus::RemoteSynchronizing
|
||||||
|
* 3. SyncthingStatus::Scanning
|
||||||
|
* 4. SyncthingStatus::Paused
|
||||||
|
* 5. SyncthingStatus::Idle
|
||||||
|
*
|
||||||
|
* \remarks
|
||||||
|
* - The "out-of-sync" status is (currently) *not* handled by this function. One needs to query this via
|
||||||
|
* the SyncthingConnection::hasOutOfSyncDirs() function.
|
||||||
|
* - Whether notifications are available is *not* handled by this function. One needs to query this via
|
||||||
|
* SyncthingConnection::hasUnreadNotifications().
|
||||||
*/
|
*/
|
||||||
void SyncthingConnection::setStatus(SyncthingStatus status)
|
void SyncthingConnection::setStatus(SyncthingStatus status)
|
||||||
{
|
{
|
||||||
|
@ -802,30 +819,51 @@ void SyncthingConnection::setStatus(SyncthingStatus status)
|
||||||
// reset reconnect tries
|
// reset reconnect tries
|
||||||
m_autoReconnectTries = 0;
|
m_autoReconnectTries = 0;
|
||||||
|
|
||||||
|
// skip if no further status information should be gathered
|
||||||
|
if (m_statusComputionFlags == SyncthingStatusComputionFlags::None) {
|
||||||
|
status = SyncthingStatus::Idle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// check whether at least one directory is scanning, preparing to synchronize or synchronizing
|
// check whether at least one directory is scanning, preparing to synchronize or synchronizing
|
||||||
// note: We don't distinguish between "preparing to sync" and "synchronizing" for computing the overall
|
// note: We don't distinguish between "preparing to sync" and "synchronizing" for computing the overall
|
||||||
// status at the moment.
|
// status at the moment.
|
||||||
bool scanning = false;
|
auto scanning = false, synchronizing = false, remoteSynchronizing = false;
|
||||||
bool synchronizing = false;
|
if (m_statusComputionFlags & SyncthingStatusComputionFlags::Synchronizing
|
||||||
for (const SyncthingDir &dir : m_dirs) {
|
|| m_statusComputionFlags & SyncthingStatusComputionFlags::Scanning) {
|
||||||
switch (dir.status) {
|
for (const SyncthingDir &dir : m_dirs) {
|
||||||
case SyncthingDirStatus::PreparingToSync:
|
switch (dir.status) {
|
||||||
case SyncthingDirStatus::Synchronizing:
|
case SyncthingDirStatus::WaitingToSync:
|
||||||
synchronizing = true;
|
case SyncthingDirStatus::PreparingToSync:
|
||||||
break;
|
case SyncthingDirStatus::Synchronizing:
|
||||||
case SyncthingDirStatus::WaitingToScan:
|
synchronizing = m_statusComputionFlags & SyncthingStatusComputionFlags::Synchronizing;
|
||||||
case SyncthingDirStatus::Scanning:
|
break;
|
||||||
scanning = true;
|
case SyncthingDirStatus::WaitingToScan:
|
||||||
break;
|
case SyncthingDirStatus::Scanning:
|
||||||
default:;
|
scanning = m_statusComputionFlags & SyncthingStatusComputionFlags::Scanning;
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
if (synchronizing) {
|
||||||
|
break; // skip remaining dirs, "synchronizing" overrides "scanning" anyways
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (synchronizing) {
|
}
|
||||||
break; // skip remaining dirs, "synchronizing" overrides "scanning" anyways
|
|
||||||
|
// set the status to "remote synchronizing" if at least one remote device is still in progress
|
||||||
|
if (!synchronizing && (m_statusComputionFlags & SyncthingStatusComputionFlags::RemoteSynchronizing)) {
|
||||||
|
for (const SyncthingDev &dev : m_devs) {
|
||||||
|
if (dev.status == SyncthingDevStatus::Synchronizing) {
|
||||||
|
remoteSynchronizing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (synchronizing) {
|
if (synchronizing) {
|
||||||
status = SyncthingStatus::Synchronizing;
|
status = SyncthingStatus::Synchronizing;
|
||||||
|
} else if (remoteSynchronizing) {
|
||||||
|
status = SyncthingStatus::RemoteNotInSync;
|
||||||
} else if (scanning) {
|
} else if (scanning) {
|
||||||
status = SyncthingStatus::Scanning;
|
status = SyncthingStatus::Scanning;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -30,6 +30,7 @@ class MiscTests;
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
struct SyncthingConnectionSettings;
|
struct SyncthingConnectionSettings;
|
||||||
|
enum class SyncthingStatusComputionFlags : quint64;
|
||||||
|
|
||||||
LIB_SYNCTHING_CONNECTOR_EXPORT QNetworkAccessManager &networkAccessManager();
|
LIB_SYNCTHING_CONNECTOR_EXPORT QNetworkAccessManager &networkAccessManager();
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject {
|
||||||
Q_PROPERTY(QString user READ user)
|
Q_PROPERTY(QString user READ user)
|
||||||
Q_PROPERTY(QString password READ password)
|
Q_PROPERTY(QString password READ password)
|
||||||
Q_PROPERTY(Data::SyncthingStatus status READ status NOTIFY statusChanged)
|
Q_PROPERTY(Data::SyncthingStatus status READ status NOTIFY statusChanged)
|
||||||
|
Q_PROPERTY(Data::SyncthingStatusComputionFlags statusComputionFlags READ statusComputionFlags WRITE setStatusComputionFlags)
|
||||||
Q_PROPERTY(QString statusText READ statusText NOTIFY statusChanged)
|
Q_PROPERTY(QString statusText READ statusText NOTIFY statusChanged)
|
||||||
Q_PROPERTY(bool connected READ isConnected NOTIFY statusChanged)
|
Q_PROPERTY(bool connected READ isConnected NOTIFY statusChanged)
|
||||||
Q_PROPERTY(bool hasUnreadNotifications READ hasUnreadNotifications)
|
Q_PROPERTY(bool hasUnreadNotifications READ hasUnreadNotifications)
|
||||||
|
@ -98,6 +100,8 @@ public:
|
||||||
SyncthingStatus status() const;
|
SyncthingStatus status() const;
|
||||||
QString statusText() const;
|
QString statusText() const;
|
||||||
static QString statusText(SyncthingStatus status);
|
static QString statusText(SyncthingStatus status);
|
||||||
|
SyncthingStatusComputionFlags statusComputionFlags() const;
|
||||||
|
void setStatusComputionFlags(SyncthingStatusComputionFlags flags);
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
bool hasPendingRequests() const;
|
bool hasPendingRequests() const;
|
||||||
bool hasPendingRequestsIncludingEvents() const;
|
bool hasPendingRequestsIncludingEvents() const;
|
||||||
|
@ -313,6 +317,8 @@ private:
|
||||||
QString m_user;
|
QString m_user;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
SyncthingStatus m_status;
|
SyncthingStatus m_status;
|
||||||
|
SyncthingStatusComputionFlags m_statusComputionFlags;
|
||||||
|
|
||||||
bool m_keepPolling;
|
bool m_keepPolling;
|
||||||
bool m_abortingAllRequests;
|
bool m_abortingAllRequests;
|
||||||
bool m_abortingToReconnect;
|
bool m_abortingToReconnect;
|
||||||
|
@ -618,6 +624,25 @@ inline void SyncthingConnection::setRecordFileChanges(bool recordFileChanges)
|
||||||
m_recordFileChanges = recordFileChanges;
|
m_recordFileChanges = recordFileChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns what information is considered to compute the overall status returned by status().
|
||||||
|
*/
|
||||||
|
inline SyncthingStatusComputionFlags SyncthingConnection::statusComputionFlags() const
|
||||||
|
{
|
||||||
|
return m_statusComputionFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets what information should be used to compute the overall status returned by status().
|
||||||
|
*/
|
||||||
|
inline void SyncthingConnection::setStatusComputionFlags(SyncthingStatusComputionFlags flags)
|
||||||
|
{
|
||||||
|
if (m_statusComputionFlags != flags) {
|
||||||
|
m_statusComputionFlags = flags;
|
||||||
|
recalculateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the Syncthing home/configuration directory.
|
* \brief Returns the Syncthing home/configuration directory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "./global.h"
|
#include "./global.h"
|
||||||
|
|
||||||
|
#include <c++utilities/misc/flagenumclass.h>
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QSslError>
|
#include <QSslError>
|
||||||
|
@ -10,6 +12,21 @@
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The SyncthingStatusComputionFlags enum specifies what information is considered to compute the overall state.
|
||||||
|
* \remarks The enum is supposed to be used as flag-enum.
|
||||||
|
*/
|
||||||
|
enum class SyncthingStatusComputionFlags : quint64 {
|
||||||
|
None = 0, /**< no further information is considered leaving SyncthingStatus::Disconnected, SyncthingStatus::Reconnecting,
|
||||||
|
SyncthingStatus::BeingDestroyed and SyncthingStatus::Idle the only possible states */
|
||||||
|
Scanning = (1 << 0), /**< the status SyncthingStatus::Scanning might be set (in addition) */
|
||||||
|
Synchronizing = (1 << 1), /**< the status SyncthingStatus::Synchronizing might be set (in addition) */
|
||||||
|
RemoteSynchronizing = (1 << 2), /**< the status SyncthingStatus::RemoteNotInSync might be set (in addition) */
|
||||||
|
DevicePaused = (1 << 3), /**< the status SyncthingStatus::Paused might be set if there's at least one paused device (in addition) */
|
||||||
|
Default = SyncthingStatusComputionFlags::Scanning | SyncthingStatusComputionFlags::Synchronizing | SyncthingStatusComputionFlags::DevicePaused,
|
||||||
|
/**< the default flags used all over the place */
|
||||||
|
};
|
||||||
|
|
||||||
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
||||||
QString label;
|
QString label;
|
||||||
QString syncthingUrl;
|
QString syncthingUrl;
|
||||||
|
@ -23,6 +40,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
||||||
int reconnectInterval = defaultReconnectInterval;
|
int reconnectInterval = defaultReconnectInterval;
|
||||||
QString httpsCertPath;
|
QString httpsCertPath;
|
||||||
QList<QSslError> expectedSslErrors;
|
QList<QSslError> expectedSslErrors;
|
||||||
|
SyncthingStatusComputionFlags statusComputionFlags = SyncthingStatusComputionFlags::Default;
|
||||||
bool autoConnect = false;
|
bool autoConnect = false;
|
||||||
bool loadHttpsCert();
|
bool loadHttpsCert();
|
||||||
|
|
||||||
|
@ -33,4 +51,6 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
||||||
};
|
};
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(Data, Data::SyncthingStatusComputionFlags)
|
||||||
|
|
||||||
#endif // SYNCTHINGCONNECTIONSETTINGS_H
|
#endif // SYNCTHINGCONNECTIONSETTINGS_H
|
||||||
|
|
|
@ -12,7 +12,25 @@ Q_NAMESPACE
|
||||||
extern LIB_SYNCTHING_CONNECTOR_EXPORT const QMetaObject staticMetaObject;
|
extern LIB_SYNCTHING_CONNECTOR_EXPORT const QMetaObject staticMetaObject;
|
||||||
QT_ANNOTATE_CLASS(qt_qnamespace, "") /*end*/
|
QT_ANNOTATE_CLASS(qt_qnamespace, "") /*end*/
|
||||||
|
|
||||||
enum class SyncthingStatus { Disconnected, Reconnecting, Idle, Scanning, Paused, Synchronizing, OutOfSync, BeingDestroyed };
|
/*!
|
||||||
|
* \brief The SyncthingStatus enum specifies the overall status of the connection to Syncthing via its REST-API.
|
||||||
|
*
|
||||||
|
* Scanning, paused and (remote) synchronizing are only computed if the SyncthingStatusComputionFlags are set for
|
||||||
|
* these.
|
||||||
|
*
|
||||||
|
* This is *not* a flag enum even though the "connected" states are not exclusive. That's because only one icon can be
|
||||||
|
* shown at the same time anyways. Checkout SyncthingConnection::setStatus() for the precedence.
|
||||||
|
*/
|
||||||
|
enum class SyncthingStatus {
|
||||||
|
Disconnected = 0, /**< disconnected, possibly currently connecting */
|
||||||
|
Reconnecting = 1, /**< disconnected, currently re-connnecting */
|
||||||
|
BeingDestroyed = 7, /**< status is unknown; the SyncthingConnnection object is being destroyed anyways */
|
||||||
|
Idle = 2, /**< connected, no special status information available/determined */
|
||||||
|
Scanning = 3, /**< connected, at least one directory is scanning */
|
||||||
|
Paused = 4, /**< connected, at least one device is paused */
|
||||||
|
Synchronizing = 5, /**< connected, at least one local directory is waiting to sync, preparing to sync or synchronizing */
|
||||||
|
RemoteNotInSync = 8, /**< connected, at least one directory of a connected remote device is not in sync (still synchronizing, error, …) */
|
||||||
|
};
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||||
Q_ENUM_NS(SyncthingStatus)
|
Q_ENUM_NS(SyncthingStatus)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@ SyncthingStatusSelectionModel::SyncthingStatusSelectionModel(QObject *parent)
|
||||||
itemFor(SyncthingStatus::Scanning),
|
itemFor(SyncthingStatus::Scanning),
|
||||||
itemFor(SyncthingStatus::Paused),
|
itemFor(SyncthingStatus::Paused),
|
||||||
itemFor(SyncthingStatus::Synchronizing),
|
itemFor(SyncthingStatus::Synchronizing),
|
||||||
|
itemFor(SyncthingStatus::RemoteNotInSync),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,7 @@ void TrayWidget::handleStatusChanged(SyncthingStatus status)
|
||||||
case SyncthingStatus::Idle:
|
case SyncthingStatus::Idle:
|
||||||
case SyncthingStatus::Scanning:
|
case SyncthingStatus::Scanning:
|
||||||
case SyncthingStatus::Synchronizing:
|
case SyncthingStatus::Synchronizing:
|
||||||
|
case SyncthingStatus::RemoteNotInSync:
|
||||||
m_ui->statusPushButton->setText(tr("Pause"));
|
m_ui->statusPushButton->setText(tr("Pause"));
|
||||||
m_ui->statusPushButton->setToolTip(tr("Syncthing is running, click to pause all devices"));
|
m_ui->statusPushButton->setToolTip(tr("Syncthing is running, click to pause all devices"));
|
||||||
m_ui->statusPushButton->setIcon(QIcon::fromTheme(
|
m_ui->statusPushButton->setIcon(QIcon::fromTheme(
|
||||||
|
@ -609,6 +610,7 @@ void TrayWidget::changeStatus()
|
||||||
case SyncthingStatus::Idle:
|
case SyncthingStatus::Idle:
|
||||||
case SyncthingStatus::Scanning:
|
case SyncthingStatus::Scanning:
|
||||||
case SyncthingStatus::Synchronizing:
|
case SyncthingStatus::Synchronizing:
|
||||||
|
case SyncthingStatus::RemoteNotInSync:
|
||||||
m_connection.pauseAllDevs();
|
m_connection.pauseAllDevs();
|
||||||
break;
|
break;
|
||||||
case SyncthingStatus::Paused:
|
case SyncthingStatus::Paused:
|
||||||
|
|
|
@ -85,6 +85,10 @@ void StatusInfo::updateConnectionStatus(const SyncthingConnection &connection, c
|
||||||
m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Synchronization is ongoing");
|
m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Synchronization is ongoing");
|
||||||
m_statusIcon = &icons.sync;
|
m_statusIcon = &icons.sync;
|
||||||
break;
|
break;
|
||||||
|
case SyncthingStatus::RemoteNotInSync:
|
||||||
|
m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "At least one remote directory is not in sync");
|
||||||
|
m_statusIcon = &icons.sync;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Status is unknown");
|
m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Status is unknown");
|
||||||
m_statusIcon = &icons.disconnected;
|
m_statusIcon = &icons.disconnected;
|
||||||
|
|
Loading…
Reference in New Issue