From ed495ec6677bcc9bb1a863e43b70357a02152e8c Mon Sep 17 00:00:00 2001 From: Martchus Date: Fri, 1 Jan 2021 20:48:19 +0100 Subject: [PATCH] Add UI to configure what information should be considered to compute overall status * See https://github.com/Martchus/syncthingtray/issues/74 * See https://github.com/Martchus/syncthingtray/issues/76 --- connector/syncthingconnection.cpp | 12 +- connector/syncthingconnection.h | 7 +- model/CMakeLists.txt | 2 + model/syncthingstatuscomputionmodel.cpp | 67 +++++++++++ model/syncthingstatuscomputionmodel.h | 28 +++++ model/syncthingstatusselectionmodel.cpp | 2 +- widgets/settings/connectionoptionpage.ui | 147 +++++++++++++++-------- widgets/settings/settingsdialog.cpp | 5 + widgets/settings/settingsdialog.h | 2 + 9 files changed, 212 insertions(+), 60 deletions(-) create mode 100644 model/syncthingstatuscomputionmodel.cpp create mode 100644 model/syncthingstatuscomputionmodel.h diff --git a/connector/syncthingconnection.cpp b/connector/syncthingconnection.cpp index dff93c7..bebcaff 100644 --- a/connector/syncthingconnection.cpp +++ b/connector/syncthingconnection.cpp @@ -820,8 +820,8 @@ void SyncthingConnection::setStatus(SyncthingStatus status) m_autoReconnectTries = 0; // skip if no further status information should be gathered + status = SyncthingStatus::Idle; if (m_statusComputionFlags == SyncthingStatusComputionFlags::None) { - status = SyncthingStatus::Idle; break; } @@ -866,20 +866,14 @@ void SyncthingConnection::setStatus(SyncthingStatus status) status = SyncthingStatus::RemoteNotInSync; } else if (scanning) { status = SyncthingStatus::Scanning; - } else { + } else if (m_statusComputionFlags & SyncthingStatusComputionFlags::DevicePaused) { // check whether at least one device is paused - bool paused = false; for (const SyncthingDev &dev : m_devs) { if (dev.paused) { - paused = true; + status = SyncthingStatus::Paused; break; } } - if (paused) { - status = SyncthingStatus::Paused; - } else { - status = SyncthingStatus::Idle; - } } } if (m_status != status) { diff --git a/connector/syncthingconnection.h b/connector/syncthingconnection.h index f1e6f8c..e2f84ae 100644 --- a/connector/syncthingconnection.h +++ b/connector/syncthingconnection.h @@ -27,10 +27,15 @@ QT_FORWARD_DECLARE_CLASS(QJsonParseError) class ConnectionTests; class MiscTests; +#define SYNCTHING_CONNECTOR_ENUM_CLASS enum class +namespace Data { +SYNCTHING_CONNECTOR_ENUM_CLASS SyncthingStatusComputionFlags : quint64; +} +#undef SYNCTHING_CONNECTOR_ENUM_CLASS + namespace Data { struct SyncthingConnectionSettings; -enum class SyncthingStatusComputionFlags : quint64; LIB_SYNCTHING_CONNECTOR_EXPORT QNetworkAccessManager &networkAccessManager(); diff --git a/model/CMakeLists.txt b/model/CMakeLists.txt index bce785f..a7b2c2c 100644 --- a/model/CMakeLists.txt +++ b/model/CMakeLists.txt @@ -16,6 +16,7 @@ set(HEADER_FILES syncthingdownloadmodel.h syncthingrecentchangesmodel.h syncthingsortfiltermodel.h + syncthingstatuscomputionmodel.h syncthingstatusselectionmodel.h syncthingicons.h colors.h) @@ -26,6 +27,7 @@ set(SRC_FILES syncthingdownloadmodel.cpp syncthingrecentchangesmodel.cpp syncthingsortfiltermodel.cpp + syncthingstatuscomputionmodel.cpp syncthingstatusselectionmodel.cpp syncthingicons.cpp) set(RES_FILES resources/${META_PROJECT_NAME}icons.qrc) diff --git a/model/syncthingstatuscomputionmodel.cpp b/model/syncthingstatuscomputionmodel.cpp new file mode 100644 index 0000000..4dfb4a7 --- /dev/null +++ b/model/syncthingstatuscomputionmodel.cpp @@ -0,0 +1,67 @@ +#include "./syncthingstatuscomputionmodel.h" + +#include "../connector/syncthingconnectionsettings.h" + +#include + +using namespace QtUtilities; + +namespace Data { + +using FlagType = SyncthingStatusComputionFlags; +using UnderlyingFlagType = std::underlying_type_t; + +inline static ChecklistItem itemFor(SyncthingStatusComputionFlags oneFlag) +{ + return ChecklistItem( + static_cast(oneFlag), QString(), SyncthingStatusComputionFlags::Default & oneFlag ? Qt::Checked : Qt::Unchecked); +} + +SyncthingStatusComputionModel::SyncthingStatusComputionModel(QObject *parent) + : ChecklistModel(parent) +{ + setItems({ + itemFor(SyncthingStatusComputionFlags::Scanning), + itemFor(SyncthingStatusComputionFlags::Synchronizing), + itemFor(SyncthingStatusComputionFlags::RemoteSynchronizing), + itemFor(SyncthingStatusComputionFlags::DevicePaused), + }); +} + +QString SyncthingStatusComputionModel::labelForId(const QVariant &id) const +{ + switch (static_cast(id.toInt())) { + case SyncthingStatusComputionFlags::Scanning: + return tr("Local dir is scanning"); + case SyncthingStatusComputionFlags::Synchronizing: + return tr("Local dir is synchronizing"); + case SyncthingStatusComputionFlags::RemoteSynchronizing: + return tr("Remote dir has outstanding progress"); + case SyncthingStatusComputionFlags::DevicePaused: + return tr("A device is paused"); + default: + return id.toString(); + } +} + +SyncthingStatusComputionFlags SyncthingStatusComputionModel::statusComputionFlags() const +{ + auto flags = SyncthingStatusComputionFlags::None; + for (auto row = 0, rows = rowCount(); row != rows; ++row) { + const auto i = index(row); + if (i.data(Qt::CheckStateRole).toInt() == Qt::Checked) { + flags += static_cast(i.data(idRole()).value()); + } + } + return flags; +} + +void SyncthingStatusComputionModel::setStatusComputionFlags(SyncthingStatusComputionFlags flags) +{ + for (auto row = 0, rows = rowCount(); row != rows; ++row) { + const auto i = index(row); + setData(i, flags & static_cast(i.data(idRole()).value()) ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); + } +} + +} // namespace Data diff --git a/model/syncthingstatuscomputionmodel.h b/model/syncthingstatuscomputionmodel.h new file mode 100644 index 0000000..5ac4c6d --- /dev/null +++ b/model/syncthingstatuscomputionmodel.h @@ -0,0 +1,28 @@ +#ifndef DATA_SYNCTHINGSTATUSCOMPUTIONMODELL_H +#define DATA_SYNCTHINGSTATUSCOMPUTIONMODELL_H + +#include "./global.h" + +#include + +#define SYNCTHING_MODEL_ENUM_CLASS enum class +namespace Data { +SYNCTHING_MODEL_ENUM_CLASS SyncthingStatusComputionFlags : quint64; +} +#undef SYNCTHING_MODEL_ENUM_CLASS + +namespace Data { + +class LIB_SYNCTHING_MODEL_EXPORT SyncthingStatusComputionModel : public QtUtilities::ChecklistModel { + Q_OBJECT + +public: + explicit SyncthingStatusComputionModel(QObject *parent = nullptr); + QString labelForId(const QVariant &id) const override; + SyncthingStatusComputionFlags statusComputionFlags() const; + void setStatusComputionFlags(SyncthingStatusComputionFlags flags); +}; + +} // namespace Data + +#endif // DATA_SYNCTHINGSTATUSCOMPUTIONMODELL_H diff --git a/model/syncthingstatusselectionmodel.cpp b/model/syncthingstatusselectionmodel.cpp index 9c255dd..b252efd 100644 --- a/model/syncthingstatusselectionmodel.cpp +++ b/model/syncthingstatusselectionmodel.cpp @@ -6,7 +6,7 @@ using namespace QtUtilities; namespace Data { -inline ChecklistItem itemFor(SyncthingStatus status) +inline static ChecklistItem itemFor(SyncthingStatus status) { return ChecklistItem(static_cast(status), QString(), Qt::Unchecked); } diff --git a/widgets/settings/connectionoptionpage.ui b/widgets/settings/connectionoptionpage.ui index 73ebb7e..202f358 100644 --- a/widgets/settings/connectionoptionpage.ui +++ b/widgets/settings/connectionoptionpage.ui @@ -3,7 +3,7 @@ QtGui::ConnectionOptionPage - + 0 0 @@ -263,6 +263,51 @@ + + + + 0 + + + + + + 0 + 0 + + + + font-weight: bold; + + + Insert values from local Syncthing configuration + + + + :/icons/hicolor/scalable/actions/edit-paste.svg:/icons/hicolor/scalable/actions/edit-paste.svg + + + + + + + + 0 + 0 + + + + Select config file manually + + + + . + :/icons/hicolor/scalable/actions/document-open.svg. + + + + + @@ -437,20 +482,69 @@ - + - Status + Overall status + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + 2 + + + + + Select what information should be considered to compute the overall status: + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + QListView::LeftToRight + + + true + + + true + + + + + + + + + Current status + + + + disconnected - + @@ -467,51 +561,6 @@ - - - - 0 - - - - - - 0 - 0 - - - - font-weight: bold; - - - Insert values from local Syncthing configuration - - - - :/icons/hicolor/scalable/actions/edit-paste.svg:/icons/hicolor/scalable/actions/edit-paste.svg - - - - - - - - 0 - 0 - - - - Select config file manually - - - - . - :/icons/hicolor/scalable/actions/document-open.svg. - - - - - diff --git a/widgets/settings/settingsdialog.cpp b/widgets/settings/settingsdialog.cpp index 728a303..af81bd5 100644 --- a/widgets/settings/settingsdialog.cpp +++ b/widgets/settings/settingsdialog.cpp @@ -6,6 +6,7 @@ #include "../../connector/syncthingconnection.h" #include "../../connector/syncthingprocess.h" #include "../../connector/utils.h" +#include "../../model/syncthingstatuscomputionmodel.h" #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD #include "../../connector/syncthingservice.h" #include "../../model/colors.h" @@ -92,6 +93,7 @@ void ConnectionOptionPage::hideConnectionStatus() QWidget *ConnectionOptionPage::setupWidget() { auto *const widget = ConnectionOptionPageBase::setupWidget(); + m_statusComputionModel = new SyncthingStatusComputionModel(widget); ui()->certPathSelection->provideCustomFileMode(QFileDialog::ExistingFile); ui()->certPathSelection->lineEdit()->setPlaceholderText( QCoreApplication::translate("QtGui::ConnectionOptionPage", "Auto-detected for local instance")); @@ -105,6 +107,7 @@ QWidget *ConnectionOptionPage::setupWidget() } else { hideConnectionStatus(); } + ui()->statusComputionFlagsListView->setModel(m_statusComputionModel); QObject::connect(ui()->connectPushButton, &QPushButton::clicked, bind(&ConnectionOptionPage::applyAndReconnect, this)); QObject::connect(ui()->insertFromConfigFilePushButton, &QPushButton::clicked, bind(&ConnectionOptionPage::insertFromConfigFile, this, false)); QObject::connect( @@ -198,6 +201,7 @@ bool ConnectionOptionPage::showConnectionSettings(int index) ui()->pollErrorsSpinBox->setValue(connectionSettings.errorsPollInterval); ui()->reconnectSpinBox->setValue(connectionSettings.reconnectInterval); ui()->autoConnectCheckBox->setChecked(connectionSettings.autoConnect); + m_statusComputionModel->setStatusComputionFlags(connectionSettings.statusComputionFlags); setCurrentIndex(index); return true; } @@ -222,6 +226,7 @@ bool ConnectionOptionPage::cacheCurrentSettings(bool applying) connectionSettings.errorsPollInterval = ui()->pollErrorsSpinBox->value(); connectionSettings.reconnectInterval = ui()->reconnectSpinBox->value(); connectionSettings.autoConnect = ui()->autoConnectCheckBox->isChecked(); + connectionSettings.statusComputionFlags = m_statusComputionModel->statusComputionFlags(); if (!connectionSettings.loadHttpsCert()) { const QString errorMessage = QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to load specified certificate \"%1\".") .arg(connectionSettings.httpsCertPath); diff --git a/widgets/settings/settingsdialog.h b/widgets/settings/settingsdialog.h index b4f0ff3..520c3ab 100644 --- a/widgets/settings/settingsdialog.h +++ b/widgets/settings/settingsdialog.h @@ -31,6 +31,7 @@ class SyncthingConnection; class SyncthingService; class SyncthingProcess; class SyncthingLauncher; +class SyncthingStatusComputionModel; } // namespace Data namespace QtGui { @@ -67,6 +68,7 @@ void setCurrentIndex(int currentIndex); Data::SyncthingConnection *m_connection; Data::SyncthingConnectionSettings m_primarySettings; std::vector m_secondarySettings; +Data::SyncthingStatusComputionModel *m_statusComputionModel; int m_currentIndex; END_DECLARE_OPTION_PAGE