diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a399b0..7e658a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,8 @@ set(META_APP_DESCRIPTION "Tray application for Syncthing") set(META_APP_CATEGORIES "Network;FileTransfer") set(META_GUI_OPTIONAL false) set(META_VERSION_MAJOR 0) -set(META_VERSION_MINOR 8) -set(META_VERSION_PATCH 4) +set(META_VERSION_MINOR 9) +set(META_VERSION_PATCH 0) set(META_VERSION_EXACT_SONAME ON) set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON) diff --git a/README.md b/README.md index f4f4767..ee6efac 100644 --- a/README.md +++ b/README.md @@ -251,3 +251,7 @@ on GitHub. * The tray disconnects from the local instance when the network connection goes down. The network connection must be restored or the tray restarted to be able to connect to local Syncthing again. This is caused by Qt bug https://bugreports.qt.io/browse/QTBUG-60949. + +## Attribution for 3rd party content +* This project uses icons from the Syncthing project. +* This project uses some icons from [Font Awesome](https://fontawesome.com) (see [their license](https://fontawesome.com/license)). diff --git a/connector/syncthingconnection.cpp b/connector/syncthingconnection.cpp index cb312e5..e6efedf 100644 --- a/connector/syncthingconnection.cpp +++ b/connector/syncthingconnection.cpp @@ -92,6 +92,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt , m_hasEvents(false) , m_hasDiskEvents(false) , m_lastFileDeleted(false) + , m_dirStatsAltered(false) { m_trafficPollTimer.setInterval(SyncthingConnectionSettings::defaultTrafficPollInterval); m_trafficPollTimer.setTimerType(Qt::VeryCoarseTimer); @@ -380,6 +381,8 @@ void SyncthingConnection::continueReconnecting() m_lastFileName.clear(); m_lastFileDeleted = false; m_syncthingVersion.clear(); + m_dirStatsAltered = false; + emit dirStatisticsChanged(); // notify that the configuration has been invalidated if (!isConfigInvalidated) { @@ -427,6 +430,7 @@ void SyncthingConnection::concludeConnection() return; } setStatus(SyncthingStatus::Idle); + emitDirStatisticsChanged(); } /*! @@ -868,6 +872,17 @@ void SyncthingConnection::emitMyIdChanged(const QString &newId) emit myIdChanged(m_myId = newId); } +/*! + * \brief Internally called to emit dirStatisticsChanged() event. + */ +void SyncthingConnection::emitDirStatisticsChanged() +{ + if (m_dirStatsAltered) { + m_dirStatsAltered = false; + emit dirStatisticsChanged(); + } +} + /*! * \brief Internally called to handle a fatal error when reading config (dirs/devs), status and events. */ diff --git a/connector/syncthingconnection.h b/connector/syncthingconnection.h index f76cbae..5a76243 100644 --- a/connector/syncthingconnection.h +++ b/connector/syncthingconnection.h @@ -219,6 +219,7 @@ Q_SIGNALS: void dirStatusChanged(const SyncthingDir &dir, int index); void devStatusChanged(const SyncthingDev &dev, int index); void downloadProgressChanged(); + void dirStatisticsChanged(); void dirCompleted(ChronoUtilities::DateTime when, const SyncthingDir &dir, int index, const SyncthingDev *remoteDev = nullptr); void newNotification(ChronoUtilities::DateTime when, const QString &message); void newDevAvailable(ChronoUtilities::DateTime when, const QString &devId, const QString &address); @@ -298,6 +299,7 @@ private Q_SLOTS: void emitError(const QString &message, const QJsonParseError &jsonError, QNetworkReply *reply, const QByteArray &response = QByteArray()); void emitError(const QString &message, SyncthingErrorCategory category, QNetworkReply *reply); void emitMyIdChanged(const QString &newId); + void emitDirStatisticsChanged(); void handleFatalConnectionError(); void handleAdditionalRequestCanceled(); void recalculateStatus(); @@ -364,6 +366,7 @@ private: bool m_lastFileDeleted; QList m_expectedSslErrors; QJsonObject m_rawConfig; + bool m_dirStatsAltered; }; /*! diff --git a/connector/syncthingconnection_requests.cpp b/connector/syncthingconnection_requests.cpp index 9813513..9008c64 100644 --- a/connector/syncthingconnection_requests.cpp +++ b/connector/syncthingconnection_requests.cpp @@ -1411,6 +1411,7 @@ void SyncthingConnection::readDirSummary(DateTime eventTime, const QJsonObject & neededStats.dirs = jsonValueToInt(summary.value(QLatin1String("needDirectories"))); neededStats.symlinks = jsonValueToInt(summary.value(QLatin1String("needSymlinks"))); dir.pullErrorCount = jsonValueToInt(summary.value(QLatin1String("pullErrors"))); + m_dirStatsAltered = true; dir.ignorePatterns = summary.value(QLatin1String("ignorePatterns")).toBool(); dir.lastStatisticsUpdate = eventTime; @@ -1608,6 +1609,7 @@ void SyncthingConnection::readEventsFromJsonArray(const QJsonArray &events, int readChangeEvent(eventTime, eventType, eventData); } } + emitDirStatisticsChanged(); } /*! diff --git a/plasmoid/lib/CMakeLists.txt b/plasmoid/lib/CMakeLists.txt index 5ea0c5c..48dc21a 100644 --- a/plasmoid/lib/CMakeLists.txt +++ b/plasmoid/lib/CMakeLists.txt @@ -27,7 +27,7 @@ find_package(c++utilities 4.10.0 REQUIRED) list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS}) # find qtutilities -find_package(qtutilities 5.12.0 REQUIRED) +find_package(qtutilities 5.13.0 REQUIRED) use_qt_utilities() # check whether qtutilities supports DBus notifications diff --git a/plasmoid/lib/syncthingapplet.cpp b/plasmoid/lib/syncthingapplet.cpp index 10117a9..cc85e0e 100644 --- a/plasmoid/lib/syncthingapplet.cpp +++ b/plasmoid/lib/syncthingapplet.cpp @@ -88,6 +88,7 @@ void SyncthingApplet::init() connect(&m_connection, &SyncthingConnection::devStatusChanged, this, &SyncthingApplet::handleDevicesChanged); connect(&m_connection, &SyncthingConnection::error, this, &SyncthingApplet::handleInternalError); connect(&m_connection, &SyncthingConnection::trafficChanged, this, &SyncthingApplet::trafficChanged); + connect(&m_connection, &SyncthingConnection::dirStatisticsChanged, this, &SyncthingApplet::handleDirStatisticsChanged); connect(&m_connection, &SyncthingConnection::newNotification, this, &SyncthingApplet::handleNewNotification); connect(&m_notifier, &SyncthingNotifier::newDevice, &m_dbusNotifier, &DBusStatusNotifier::showNewDev); connect(&m_notifier, &SyncthingNotifier::newDir, &m_dbusNotifier, &DBusStatusNotifier::showNewDir); @@ -129,11 +130,31 @@ QString SyncthingApplet::incomingTraffic() const return trafficString(m_connection.totalIncomingTraffic(), m_connection.totalIncomingRate()); } +bool SyncthingApplet::hasIncomingTraffic() const +{ + return m_connection.totalIncomingRate() > 0.0; +} + QString SyncthingApplet::outgoingTraffic() const { return trafficString(m_connection.totalOutgoingTraffic(), m_connection.totalOutgoingRate()); } +bool SyncthingApplet::hasOutgoingTraffic() const +{ + return m_connection.totalOutgoingRate() > 0.0; +} + +QString SyncthingApplet::globalStatistics() const +{ + return directoryStatusString(m_overallStats.global); +} + +QString SyncthingApplet::localStatistics() const +{ + return directoryStatusString(m_overallStats.local); +} + QStringList SyncthingApplet::connectionConfigNames() const { const auto &settings = Settings::values().connection; @@ -273,7 +294,10 @@ void SyncthingApplet::showOwnDeviceId() void SyncthingApplet::showAboutDialog() { if (!m_aboutDlg) { - m_aboutDlg = new AboutDialog(nullptr, QStringLiteral(APP_NAME), QStringLiteral(APP_AUTHOR "\nSyncthing icons from Syncthing project"), + m_aboutDlg = new AboutDialog(nullptr, QStringLiteral(APP_NAME), + QStringLiteral("

Developed by " APP_AUTHOR "
Syncthing icons from Syncthing project
Using " + "icons from Font " + "Awesome (see their license)

"), QStringLiteral(APP_VERSION), ApplicationUtilities::dependencyVersions2, QStringLiteral(APP_URL), QStringLiteral(APP_DESCRIPTION), QImage(statusIcons().scanninig.pixmap(128).toImage())); m_aboutDlg->setWindowTitle(tr("About") + QStringLiteral(" - " APP_NAME)); @@ -405,6 +429,12 @@ void SyncthingApplet::handleInternalError( InternalErrorsDialog::addError(move(error)); } +void SyncthingApplet::handleDirStatisticsChanged() +{ + m_overallStats = m_connection.computeOverallDirStatistics(); + emit statisticsChanged(); +} + void SyncthingApplet::handleErrorsCleared() { } diff --git a/plasmoid/lib/syncthingapplet.h b/plasmoid/lib/syncthingapplet.h index 9755d69..61d5df4 100644 --- a/plasmoid/lib/syncthingapplet.h +++ b/plasmoid/lib/syncthingapplet.h @@ -52,7 +52,11 @@ class SyncthingApplet : public Plasma::Applet { Q_PROPERTY(QString additionalStatusText READ additionalStatusText NOTIFY connectionStatusChanged) Q_PROPERTY(QIcon statusIcon READ statusIcon NOTIFY connectionStatusChanged) Q_PROPERTY(QString incomingTraffic READ incomingTraffic NOTIFY trafficChanged) + Q_PROPERTY(bool hasIncomingTraffic READ hasIncomingTraffic NOTIFY trafficChanged) Q_PROPERTY(QString outgoingTraffic READ outgoingTraffic NOTIFY trafficChanged) + Q_PROPERTY(bool hasOutgoingTraffic READ hasOutgoingTraffic NOTIFY trafficChanged) + Q_PROPERTY(QString globalStatistics READ globalStatistics NOTIFY statisticsChanged) + Q_PROPERTY(QString localStatistics READ localStatistics NOTIFY statisticsChanged) Q_PROPERTY(QStringList connectionConfigNames READ connectionConfigNames NOTIFY settingsChanged) Q_PROPERTY(QString currentConnectionConfigName READ currentConnectionConfigName NOTIFY currentConnectionConfigIndexChanged) Q_PROPERTY(int currentConnectionConfigIndex READ currentConnectionConfigIndex WRITE setCurrentConnectionConfigIndex NOTIFY @@ -79,7 +83,11 @@ public: QString additionalStatusText() const; QIcon statusIcon() const; QString incomingTraffic() const; + bool hasIncomingTraffic() const; QString outgoingTraffic() const; + bool hasOutgoingTraffic() const; + QString globalStatistics() const; + QString localStatistics() const; QStringList connectionConfigNames() const; QString currentConnectionConfigName() const; int currentConnectionConfigIndex() const; @@ -124,6 +132,7 @@ Q_SIGNALS: void localChanged(); void connectionStatusChanged(); void trafficChanged(); + void statisticsChanged(); void settingsChanged(); void currentConnectionConfigIndexChanged(int index); void sizeChanged(const QSize &size); @@ -136,6 +145,7 @@ private Q_SLOTS: void handleDevicesChanged(); void handleInternalError( const QString &errorMsg, Data::SyncthingErrorCategory category, int networkError, const QNetworkRequest &request, const QByteArray &response); + void handleDirStatisticsChanged(); void handleErrorsCleared(); void handleAboutDialogDeleted(); #ifndef SYNCTHINGWIDGETS_NO_WEBVIEW @@ -151,6 +161,7 @@ private Q_SLOTS: private: Dialogs::AboutDialog *m_aboutDlg; Data::SyncthingConnection m_connection; + Data::SyncthingOverallDirStatistics m_overallStats; Data::SyncthingNotifier m_notifier; #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD Data::SyncthingService m_service; diff --git a/plasmoid/package/contents/ui/FullRepresentation.qml b/plasmoid/package/contents/ui/FullRepresentation.qml index 380cef9..a1e0e6d 100644 --- a/plasmoid/package/contents/ui/FullRepresentation.qml +++ b/plasmoid/package/contents/ui/FullRepresentation.qml @@ -378,53 +378,6 @@ ColumnLayout { onActivated: webUIButton.clicked() } } - } - - PlasmaCore.SvgItem { - Layout.preferredWidth: parent.width - Layout.preferredHeight: 2 - elementId: "horizontal-line" - svg: PlasmaCore.Svg { - imagePath: "widgets/line" - } - } - - // traffic and connection selection - RowLayout { - Layout.fillWidth: true - Layout.fillHeight: false - - PlasmaCore.IconItem { - source: "network-card" - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - } - ColumnLayout { - Layout.fillHeight: true - spacing: 1 - - PlasmaComponents.Label { - text: qsTr("In") - } - PlasmaComponents.Label { - text: qsTr("Out") - } - } - ColumnLayout { - Layout.fillHeight: true - spacing: 1 - - PlasmaComponents.Label { - text: plasmoid.nativeInterface.incomingTraffic - } - PlasmaComponents.Label { - text: plasmoid.nativeInterface.outgoingTraffic - } - } - Item { - Layout.fillWidth: true - Layout.fillHeight: true - } TinyButton { text: plasmoid.nativeInterface.currentConnectionConfigName iconSource: "network-connect" @@ -467,6 +420,64 @@ ColumnLayout { } } + // global statistics and traffic + GridLayout { + Layout.fillWidth: true + Layout.fillHeight: false + columns: 4 + rowSpacing: 1 + columnSpacing: 4 + + PlasmaCore.IconItem { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + source: "globe" + } + PlasmaComponents.Label { + text: plasmoid.nativeInterface.globalStatistics + } + + PlasmaCore.IconItem { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + Layout.leftMargin: 10 + source: "://icons/hicolor/scalable/fa/cloud-download-alt-solid.svg" + opacity: plasmoid.nativeInterface.hasIncomingTraffic ? 1.0 : 0.5 + } + PlasmaComponents.Label { + text: plasmoid.nativeInterface.incomingTraffic + } + + PlasmaCore.IconItem { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + source: "user-home-symbolic" + } + PlasmaComponents.Label { + text: plasmoid.nativeInterface.localStatistics + } + + PlasmaCore.IconItem { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + Layout.leftMargin: 10 + source: "://icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg" + opacity: plasmoid.nativeInterface.hasOutgoingTraffic ? 1.0 : 0.5 + } + PlasmaComponents.Label { + text: plasmoid.nativeInterface.outgoingTraffic + } + } + + PlasmaCore.SvgItem { + Layout.preferredWidth: parent.width + Layout.preferredHeight: 2 + elementId: "horizontal-line" + svg: PlasmaCore.Svg { + imagePath: "widgets/line" + } + } + // tab "widget" RowLayout { spacing: 0 diff --git a/widgets/resources/icons/hicolor/scalable/fa/cloud-download-alt-solid.svg b/widgets/resources/icons/hicolor/scalable/fa/cloud-download-alt-solid.svg new file mode 100644 index 0000000..5e47b45 --- /dev/null +++ b/widgets/resources/icons/hicolor/scalable/fa/cloud-download-alt-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/widgets/resources/icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg b/widgets/resources/icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg new file mode 100644 index 0000000..bbc5969 --- /dev/null +++ b/widgets/resources/icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/widgets/resources/syncthingwidgetsicons.qrc b/widgets/resources/syncthingwidgetsicons.qrc index ba1fe84..4b2e299 100644 --- a/widgets/resources/syncthingwidgetsicons.qrc +++ b/widgets/resources/syncthingwidgetsicons.qrc @@ -9,5 +9,7 @@ icons/hicolor/scalable/actions/list-remove.svg icons/hicolor/scalable/actions/edit-paste.svg icons/hicolor/scalable/app/syncthingtray.svg + icons/hicolor/scalable/fa/cloud-download-alt-solid.svg + icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg