Improve plasmoid

Now implemented:
* Downloads
* Directory errors
* Systemd integrations
* Multiple connection configurations
This commit is contained in:
Martchus 2017-09-08 16:59:53 +02:00
parent 07a47f1b06
commit db1063d5a0
8 changed files with 425 additions and 169 deletions

View File

@ -28,6 +28,13 @@ list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS})
find_package(qtutilities 5.0.0 REQUIRED)
use_qt_utilities()
# check whether qtutilities supports DBus notifications
get_target_property(QT_UTILITIES_COMPILE_DEFINITIONS ${QT_UTILITIES_LIB} COMPILE_DEFINITIONS)
list(FIND QT_UTILITIES_COMPILE_DEFINITIONS QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS)
if(QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS LESS 0)
message(FATAL_ERROR "The provided build of Qt Utilities does not support D-Bus notifications which is required for the Plasmoid.")
endif()
# find backend libraries
find_package(syncthingconnector ${META_APP_VERSION} REQUIRED)
use_syncthingconnector()

View File

@ -1,5 +1,9 @@
#include "./syncthingapplet.h"
#include "../../connector/syncthingservice.h"
#include "../../connector/utils.h"
#include "../../widgets/misc/errorviewdialog.h"
#include "../../widgets/misc/otherdialogs.h"
#include "../../widgets/misc/textviewdialog.h"
#include "../../widgets/settings/settings.h"
@ -19,7 +23,9 @@
#include <qtutilities/settingsdialog/settingsdialog.h>
#include <QDesktopServices>
#include <QNetworkReply>
#include <QQmlEngine>
#include <QStringBuilder>
#include <iostream>
@ -28,6 +34,7 @@ using namespace Data;
using namespace Plasma;
using namespace Dialogs;
using namespace QtGui;
using namespace ChronoUtilities;
SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data)
: Applet(parent, data)
@ -36,18 +43,18 @@ SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data)
, m_dirModel(m_connection)
, m_devModel(m_connection)
, m_downloadModel(m_connection)
, m_connectionSettingsDlg(nullptr)
, m_settingsDlg(nullptr)
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
, m_webViewDlg(nullptr)
#endif
, m_currentConnectionConfig(-1)
{
qRegisterMetaType<Data::SyncthingStatus>("Data::SyncthingStatus");
qmlRegisterUncreatableMetaObject(Data::staticMetaObject, "martchus.syncthingplasmoid", 0, 6, "Data", QStringLiteral("only enums"));
}
SyncthingApplet::~SyncthingApplet()
{
delete m_connectionSettingsDlg;
delete m_settingsDlg;
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
delete m_webViewDlg;
#endif
@ -68,6 +75,45 @@ QString SyncthingApplet::outgoingTraffic() const
return trafficString(m_connection.totalOutgoingTraffic(), m_connection.totalOutgoingRate());
}
QStringList SyncthingApplet::connectionConfigNames() const
{
const auto &settings = Settings::values().connection;
QStringList names;
names.reserve(static_cast<int>(settings.secondary.size() + 1));
names << settings.primary.label;
for (const auto &setting : settings.secondary) {
names << setting.label;
}
return names;
}
QString SyncthingApplet::currentConnectionConfigName() const
{
const auto &settings = Settings::values().connection;
if (m_currentConnectionConfig == 0) {
return settings.primary.label;
} else if (m_currentConnectionConfig > 0 && static_cast<unsigned>(m_currentConnectionConfig) <= settings.secondary.size()) {
return settings.secondary[static_cast<unsigned>(m_currentConnectionConfig) - 1].label;
}
return QString();
}
inline void SyncthingApplet::setCurrentConnectionConfigIndex(int index)
{
auto &settings = Settings::values().connection;
if (index != m_currentConnectionConfig && index >= 0 && static_cast<unsigned>(index) <= settings.secondary.size()) {
auto &selectedConfig = index == 0 ? settings.primary : settings.secondary[static_cast<unsigned>(index) - 1];
m_connection.connect(selectedConfig);
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
if (m_webViewDlg) {
m_webViewDlg->applySettings(selectedConfig);
}
#endif
emit currentConnectionConfigIndexChanged(m_currentConnectionConfig = index);
emit localChanged();
}
}
QString SyncthingApplet::statusText() const
{
return m_statusInfo.statusText();
@ -84,33 +130,55 @@ void SyncthingApplet::init()
Applet::init();
// connect signals and slots
connect(&m_connection, &SyncthingConnection::statusChanged, this, &SyncthingApplet::handleConnectionStatusChanged);
connect(&m_connection, &SyncthingConnection::error, this, &SyncthingApplet::handleInternalError);
connect(&m_connection, &SyncthingConnection::trafficChanged, this, &SyncthingApplet::trafficChanged);
connect(&m_connection, &SyncthingConnection::newNotification, this, &SyncthingApplet::handleNewNotification);
connect(&m_dbusNotifier, &DBusStatusNotifier::connectRequested, &m_connection,
static_cast<void (SyncthingConnection::*)(void)>(&SyncthingConnection::connect));
connect(&m_dbusNotifier, &DBusStatusNotifier::dismissNotificationsRequested, this, &SyncthingApplet::dismissNotifications);
connect(&m_dbusNotifier, &DBusStatusNotifier::showNotificationsRequested, this, &SyncthingApplet::showNotificationsDialog);
connect(&m_dbusNotifier, &DBusStatusNotifier::errorDetailsRequested, this, &SyncthingApplet::showInternalErrorsDialog);
// restore settings
Settings::restore();
applyConnectionSettings();
// load primary connection config
setCurrentConnectionConfigIndex(0);
// initialize systemd service support
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
SyncthingService &service = syncthingService();
service.setUnitName(Settings::values().systemd.syncthingUnit);
connect(&service, &SyncthingService::errorOccurred, this, &SyncthingApplet::handleSystemdServiceError);
#endif
}
void SyncthingApplet::showConnectionSettingsDlg()
void SyncthingApplet::showSettingsDlg()
{
if (!m_connectionSettingsDlg) {
m_connectionSettingsDlg = new Dialogs::SettingsDialog;
m_connectionSettingsDlg->setTabBarAlwaysVisible(false);
if (!m_settingsDlg) {
m_settingsDlg = new Dialogs::SettingsDialog;
m_settingsDlg->setTabBarAlwaysVisible(false);
auto *const webViewPage = new QtGui::WebViewOptionPage;
auto *const webViewWidget = webViewPage->widget();
webViewWidget->setWindowTitle(tr("Web view"));
webViewWidget->setWindowIcon(QIcon::fromTheme(QStringLiteral("internet-web-browser")));
auto *const category = new Dialogs::OptionCategory(m_connectionSettingsDlg);
category->assignPages({ new QtGui::ConnectionOptionPage(&m_connection), webViewPage });
m_connectionSettingsDlg->setSingleCategory(category);
m_connectionSettingsDlg->resize(860, 620);
connect(m_connectionSettingsDlg, &Dialogs::SettingsDialog::applied, this, &SyncthingApplet::applyConnectionSettings);
connect(m_connectionSettingsDlg, &Dialogs::SettingsDialog::applied, &Settings::save);
auto *const category = new Dialogs::OptionCategory(m_settingsDlg);
category->assignPages({ new QtGui::ConnectionOptionPage(&m_connection), new QtGui::NotificationsOptionPage(true),
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
new QtGui::SystemdOptionPage,
#endif
webViewPage });
m_settingsDlg->setSingleCategory(category);
m_settingsDlg->resize(860, 620);
connect(m_settingsDlg, &Dialogs::SettingsDialog::applied, this, &SyncthingApplet::applyConnectionSettings);
connect(m_settingsDlg, &Dialogs::SettingsDialog::applied, &Settings::save);
}
Dialogs::centerWidget(m_connectionSettingsDlg);
m_connectionSettingsDlg->show();
m_connectionSettingsDlg->activateWindow();
Dialogs::centerWidget(m_settingsDlg);
m_settingsDlg->show();
m_settingsDlg->activateWindow();
}
void SyncthingApplet::showWebUI()
@ -153,10 +221,11 @@ void SyncthingApplet::showOwnDeviceId()
void SyncthingApplet::showAboutDialog()
{
if (!m_aboutDlg) {
m_aboutDlg = new AboutDialog(nullptr, QString(), QStringLiteral(APP_AUTHOR "\nSyncthing icons from Syncthing project"), QString(), QString(),
QStringLiteral(APP_DESCRIPTION), QImage(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
m_aboutDlg = new AboutDialog(nullptr, QStringLiteral(APP_NAME), QStringLiteral(APP_AUTHOR "\nSyncthing icons from Syncthing project"),
QStringLiteral(APP_VERSION), QStringLiteral(APP_URL), QStringLiteral(APP_DESCRIPTION),
QImage(statusIcons().scanninig.pixmap(128).toImage()));
m_aboutDlg->setWindowTitle(tr("About") + QStringLiteral(" - " APP_NAME));
m_aboutDlg->setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
m_aboutDlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("syncthingtray")));
m_aboutDlg->setAttribute(Qt::WA_DeleteOnClose);
connect(m_aboutDlg, &QObject::destroyed, this, &SyncthingApplet::handleAboutDialogDeleted);
}
@ -165,12 +234,46 @@ void SyncthingApplet::showAboutDialog()
m_aboutDlg->activateWindow();
}
void SyncthingApplet::showNotificationsDialog()
{
auto *const dlg = TextViewDialog::forLogEntries(m_notifications, tr("New notifications"));
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
centerWidget(dlg);
dlg->show();
m_notifications.clear();
dismissNotifications();
}
void SyncthingApplet::dismissNotifications()
{
m_connection.considerAllNotificationsRead();
}
void SyncthingApplet::showInternalErrorsDialog()
{
auto *const errorViewDlg = ErrorViewDialog::instance();
connect(errorViewDlg, &ErrorViewDialog::errorsCleared, this, &SyncthingApplet::handleErrorsCleared);
centerWidget(errorViewDlg);
errorViewDlg->show();
}
void SyncthingApplet::showDirectoryErrors(unsigned int directoryIndex) const
{
const auto &dirs = m_connection.dirInfo();
if (directoryIndex < dirs.size()) {
auto *const dlg = TextViewDialog::forDirectoryErrors(dirs[directoryIndex]);
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
centerWidget(dlg);
dlg->show();
}
}
void SyncthingApplet::applyConnectionSettings()
{
m_connection.connect(Settings::values().connection.primary);
if (m_webViewDlg) {
m_webViewDlg->applySettings(Settings::values().connection.primary);
}
const int currentConfig = m_currentConnectionConfig;
m_currentConnectionConfig = -1; // force update
setCurrentConnectionConfigIndex(currentConfig);
emit connectionConfigNamesChanged();
}
void SyncthingApplet::handleConnectionStatusChanged()
@ -179,6 +282,20 @@ void SyncthingApplet::handleConnectionStatusChanged()
emit connectionStatusChanged();
}
void SyncthingApplet::handleInternalError(
const QString &errorMsg, SyncthingErrorCategory category, int networkError, const QNetworkRequest &request, const QByteArray &response)
{
if (InternalError::isRelevant(m_connection, category, networkError)) {
InternalError error(errorMsg, request.url(), response);
m_dbusNotifier.showInternalError(error);
ErrorViewDialog::addError(move(error));
}
}
void SyncthingApplet::handleErrorsCleared()
{
}
void SyncthingApplet::handleAboutDialogDeleted()
{
m_aboutDlg = nullptr;
@ -189,6 +306,20 @@ void SyncthingApplet::handleWebViewDeleted()
m_webViewDlg = nullptr;
}
void SyncthingApplet::handleNewNotification(DateTime when, const QString &msg)
{
m_notifications.emplace_back(QString::fromLocal8Bit(when.toString(DateTimeOutputFormat::DateAndTime, true).data()), msg);
if (Settings::values().notifyOn.syncthingErrors) {
m_dbusNotifier.showSyncthingNotification(when, msg);
}
}
void SyncthingApplet::handleSystemdServiceError(const QString &context, const QString &name, const QString &message)
{
handleInternalError(tr("D-Bus error - unable to ") % context % QChar('\n') % name % QChar(':') % message, SyncthingErrorCategory::SpecificRequest,
QNetworkReply::NoError, QNetworkRequest(), QByteArray());
}
K_EXPORT_PLASMA_APPLET_WITH_JSON(syncthing, SyncthingApplet, "metadata.json")
#include "syncthingapplet.moc"

View File

@ -1,6 +1,7 @@
#ifndef SYNCTHINGAPPLET_H
#define SYNCTHINGAPPLET_H
#include "../../widgets/misc/dbusstatusnotifier.h"
#include "../../widgets/misc/statusinfo.h"
#include "../../model/syncthingdevicemodel.h"
@ -8,6 +9,7 @@
#include "../../model/syncthingdownloadmodel.h"
#include "../../connector/syncthingconnection.h"
#include "../../connector/syncthingservice.h"
#include <qtutilities/aboutdialog/aboutdialog.h>
@ -22,6 +24,8 @@ class SyncthingConnection;
class SyncthingDirectoryModel;
class SyncthingDeviceModel;
class SyncthingDownloadModel;
class SyncthingService;
enum class SyncthingErrorCategory;
}
namespace QtGui {
@ -34,11 +38,17 @@ class SyncthingApplet : public Plasma::Applet {
Q_PROPERTY(Data::SyncthingDirectoryModel *dirModel READ dirModel NOTIFY dirModelChanged)
Q_PROPERTY(Data::SyncthingDeviceModel *devModel READ devModel NOTIFY devModelChanged)
Q_PROPERTY(Data::SyncthingDownloadModel *downloadModel READ downloadModel NOTIFY downloadModelChanged)
Q_PROPERTY(Data::SyncthingService *service READ service NOTIFY serviceChanged)
Q_PROPERTY(bool local READ isLocal NOTIFY localChanged)
Q_PROPERTY(QString statusText READ statusText NOTIFY connectionStatusChanged)
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(QString outgoingTraffic READ outgoingTraffic NOTIFY trafficChanged)
Q_PROPERTY(QStringList connectionConfigNames READ connectionConfigNames NOTIFY connectionConfigNamesChanged)
Q_PROPERTY(QString currentConnectionConfigName READ currentConnectionConfigName NOTIFY currentConnectionConfigIndexChanged)
Q_PROPERTY(int currentConnectionConfigIndex READ currentConnectionConfigIndex WRITE setCurrentConnectionConfigIndex NOTIFY
currentConnectionConfigIndexChanged)
public:
SyncthingApplet(QObject *parent, const QVariantList &data);
@ -49,19 +59,29 @@ public:
Data::SyncthingDirectoryModel *dirModel() const;
Data::SyncthingDeviceModel *devModel() const;
Data::SyncthingDownloadModel *downloadModel() const;
Data::SyncthingService *service() const;
bool isLocal() const;
QString statusText() const;
QString additionalStatusText() const;
QIcon statusIcon() const;
QString incomingTraffic() const;
QString outgoingTraffic() const;
QStringList connectionConfigNames() const;
QString currentConnectionConfigName() const;
int currentConnectionConfigIndex() const;
void setCurrentConnectionConfigIndex(int index);
public Q_SLOTS:
void init() Q_DECL_OVERRIDE;
void showConnectionSettingsDlg();
void showSettingsDlg();
void showWebUI();
void showLog();
void showOwnDeviceId();
void showAboutDialog();
void showNotificationsDialog();
void dismissNotifications();
void showInternalErrorsDialog();
void showDirectoryErrors(unsigned int directoryIndex) const;
Q_SIGNALS:
/// \remarks Never emitted, just to silence "... depends on non-NOTIFYable ..."
@ -72,16 +92,26 @@ Q_SIGNALS:
void devModelChanged();
/// \remarks Never emitted, just to silence "... depends on non-NOTIFYable ..."
void downloadModelChanged();
/// \remarks Never emitted, just to silence "... depends on non-NOTIFYable ..."
void serviceChanged();
void localChanged();
void connectionStatusChanged();
void trafficChanged();
void connectionConfigNamesChanged();
void currentConnectionConfigIndexChanged(int index);
private Q_SLOTS:
void applyConnectionSettings();
void handleConnectionStatusChanged();
void handleInternalError(
const QString &errorMsg, Data::SyncthingErrorCategory category, int networkError, const QNetworkRequest &request, const QByteArray &response);
void handleErrorsCleared();
void handleAboutDialogDeleted();
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
void handleWebViewDeleted();
#endif
void handleNewNotification(ChronoUtilities::DateTime when, const QString &msg);
void handleSystemdServiceError(const QString &context, const QString &name, const QString &message);
private:
Dialogs::AboutDialog *m_aboutDlg;
@ -90,10 +120,13 @@ private:
Data::SyncthingDirectoryModel m_dirModel;
Data::SyncthingDeviceModel m_devModel;
Data::SyncthingDownloadModel m_downloadModel;
Dialogs::SettingsDialog *m_connectionSettingsDlg;
Dialogs::SettingsDialog *m_settingsDlg;
QtGui::DBusStatusNotifier m_dbusNotifier;
std::vector<Data::SyncthingLogEntry> m_notifications;
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
QtGui::WebViewDialog *m_webViewDlg;
#endif
int m_currentConnectionConfig;
};
inline Data::SyncthingConnection *SyncthingApplet::connection() const
@ -116,4 +149,23 @@ inline Data::SyncthingDownloadModel *SyncthingApplet::downloadModel() const
return const_cast<Data::SyncthingDownloadModel *>(&m_downloadModel);
}
inline Data::SyncthingService *SyncthingApplet::service() const
{
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
return &Data::syncthingService();
#else
return nullptr;
#endif
}
inline bool SyncthingApplet::isLocal() const
{
return m_connection.isLocal();
}
inline int SyncthingApplet::currentConnectionConfigIndex() const
{
return m_currentConnectionConfig;
}
#endif // SYNCTHINGAPPLET_H

View File

@ -26,24 +26,19 @@ Item {
spacing: 0
RowLayout {
RowLayout {
spacing: 5
PlasmaCore.IconItem {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
PlasmaComponents.Label {
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
text: name
}
PlasmaCore.IconItem {
Layout.preferredWidth: 24
Layout.preferredHeight: 24
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
Item {
PlasmaComponents.Label {
Layout.fillWidth: true
Layout.fillHeight: true
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
text: name
}
RowLayout {
id: toolButtonsLayout
spacing: 0
@ -51,7 +46,7 @@ Item {
PlasmaComponents.Label {
height: implicitHeight
text: statusString
color: statusColor
color: statusColor ? statusColor : PlasmaCore.ColorScope.textColor
anchors.verticalCenter: parent.verticalCenter
}
Item {

View File

@ -5,6 +5,7 @@ import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import martchus.syncthingplasmoid 0.6 as SyncthingPlasmoid
Item {
property alias view: directoryView
@ -28,24 +29,19 @@ Item {
RowLayout {
id: itemSummary
RowLayout {
spacing: 5
PlasmaCore.IconItem {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
PlasmaComponents.Label {
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
text: name
}
PlasmaCore.IconItem {
Layout.preferredWidth: 24
Layout.preferredHeight: 24
anchors.verticalCenter: parent.verticalCenter
source: statusIcon
}
Item {
PlasmaComponents.Label {
Layout.fillWidth: true
Layout.fillHeight: true
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
text: name
}
RowLayout {
id: toolButtonsLayout
spacing: 0
@ -53,12 +49,23 @@ Item {
PlasmaComponents.Label {
height: implicitHeight
text: statusString
color: statusColor
color: statusColor ? statusColor : PlasmaCore.ColorScope.textColor
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: 3
}
PlasmaComponents.ToolButton {
iconSource: "emblem-important"
tooltip: qsTr("Show errors")
// 5 stands for SyncthingDirStatus::OutOfSync, unfortunately there is currently
// no way to expose this to QML without conflicting SyncthingStatus
visible: status === 5
onClicked: {
plasmoid.nativeInterface.showDirectoryErrors(index)
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
iconSource: "view-refresh"
tooltip: qsTr("Rescan")

View File

@ -1,6 +1,7 @@
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQml 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.core 2.0 as PlasmaCore
@ -33,6 +34,15 @@ ColumnLayout {
break;
case Qt.Key_Escape:
break;
case Qt.Key_1:
mainTabGroup.currentTab = dirsPage;
break;
case Qt.Key_2:
mainTabGroup.currentTab = devicesPage;
break;
case Qt.Key_3:
mainTabGroup.currentTab = downloadsPage;
break;
default:
break;
}
@ -40,119 +50,151 @@ ColumnLayout {
// heading and right-corner buttons
RowLayout {
id: toolBar
Layout.fillWidth: true
Layout.fillHeight: false
PlasmaExtras.Heading {
id: headingLabel
level: 1
text: qsTr("Syncthing")
PlasmaComponents.ToolButton {
id: connectButton
states: [
State {
name: "disconnected"
PropertyChanges {
target: connectButton
text: qsTr("Connect")
iconSource: "view-refresh"
}
},
State {
name: "paused"
PropertyChanges {
target: connectButton
text: qsTr("Resume")
iconSource: "media-playback-start"
}
},
State {
name: "idle"
PropertyChanges {
target: connectButton
text: qsTr("Pause")
iconSource: "media-playback-pause"
}
}
]
state: {
switch(plasmoid.nativeInterface.connection.status) {
case SyncthingPlasmoid.Data.Disconnected:
case SyncthingPlasmoid.Data.Reconnecting:
return "disconnected";
case SyncthingPlasmoid.Data.Paused:
return "paused";
default:
return "idle";
}
}
tooltip: text
onClicked: {
switch(plasmoid.nativeInterface.connection.status) {
case SyncthingPlasmoid.Data.Disconnected:
case SyncthingPlasmoid.Data.Reconnecting:
plasmoid.nativeInterface.connection.connect();
break;
case SyncthingPlasmoid.Data.Paused:
plasmoid.nativeInterface.connection.resumeAllDevs();
break;
default:
plasmoid.nativeInterface.connection.pauseAllDevs();
break;
}
}
}
PlasmaComponents.ToolButton {
id: startStopButton
states: [
State {
name: "running"
PropertyChanges {
target: startStopButton
visible: true
text: qsTr("Stop")
tooltip: "systemctl --user stop " + plasmoid.nativeInterface.service.unitName
iconSource: "process-stop"
}
},
State {
name: "stopped"
PropertyChanges {
target: startStopButton
visible: true
text: qsTr("Start")
tooltip: "systemctl --user start " + plasmoid.nativeInterface.service.unitName
iconSource: "system-run"
}
},
State {
name: "irrelevant"
PropertyChanges {
target: startStopButton
visible: false
}
}
]
state: {
// the systemd unit status is only relevant when connected to the local instance
if(!plasmoid.nativeInterface.local) {
return "irrelevant";
}
// show start/stop button only when the configured unit is available
var service = plasmoid.nativeInterface.service;
if(!service || !service.unitAvailable) {
return "irrelevant";
}
return service.running ? "running" : "stopped";
}
onClicked: plasmoid.nativeInterface.service.toggleRunning()
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
RowLayout {
id: toolBar
anchors.verticalCenter: parent.verticalCenter
PlasmaComponents.ToolButton {
id: connectButton
states: [
State {
name: "disconnected"
PropertyChanges {
target: connectButton
text: qsTr("Connect")
iconSource: "view-refresh"
}
},
State {
name: "paused"
PropertyChanges {
target: connectButton
text: qsTr("Resume")
iconSource: "media-playback-start"
}
},
State {
name: "idle"
PropertyChanges {
target: connectButton
text: qsTr("Pause")
iconSource: "media-playback-pause"
}
}
]
state: {
switch(plasmoid.nativeInterface.connection.status) {
case SyncthingPlasmoid.Data.Disconnected:
case SyncthingPlasmoid.Data.Reconnecting:
return "disconnected";
case SyncthingPlasmoid.Data.Paused:
return "paused";
default:
return "idle";
}
}
tooltip: text
onClicked: function() {
switch(plasmoid.nativeInterface.connection.status) {
case SyncthingPlasmoid.Data.Disconnected:
case SyncthingPlasmoid.Data.Reconnecting:
plasmoid.nativeInterface.connection.connect();
break;
case SyncthingPlasmoid.Data.Paused:
plasmoid.nativeInterface.connection.resumeAllDevs();
break;
default:
plasmoid.nativeInterface.connection.pauseAllDevs();
break;
}
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Show own device ID")
iconSource: "view-barcode"
onClicked: {
plasmoid.nativeInterface.showOwnDeviceId()
plasmoid.expanded = false
}
PlasmaComponents.ToolButton {
id: startStopButton
text: qsTr("TODO: Start/stop")
tooltip: text
iconSource: "system-run"
onClicked: plasmoid.nativeInterface.toggleSyncthingRunning()
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Show Syncthing log")
iconSource: "text-x-generic"
onClicked: {
plasmoid.nativeInterface.showLog()
plasmoid.expanded = false
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Show own device ID")
iconSource: "view-barcode"
onClicked: {
plasmoid.nativeInterface.showOwnDeviceId()
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Rescan all directories")
iconSource: "view-refresh"
onClicked: plasmoid.nativeInterface.connection.rescanAllDirs()
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Settings")
iconSource: "preferences-other"
onClicked: {
plasmoid.nativeInterface.showSettingsDlg()
plasmoid.expanded = false
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Show Syncthing log")
iconSource: "text-x-generic"
onClicked: {
plasmoid.nativeInterface.showLog()
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Rescan all directories")
iconSource: "view-refresh"
onClicked: plasmoid.nativeInterface.connection.rescanAllDirs()
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Settings")
iconSource: "preferences-other"
onClicked: {
plasmoid.nativeInterface.showConnectionSettingsDlg()
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Web UI")
iconSource: "internet-web-browser"
onClicked: {
plasmoid.nativeInterface.showWebUI();
plasmoid.expanded = false
}
}
PlasmaComponents.ToolButton {
tooltip: qsTr("Web UI")
iconSource: "internet-web-browser"
onClicked: {
plasmoid.nativeInterface.showWebUI();
plasmoid.expanded = false
}
}
}
@ -203,15 +245,32 @@ ColumnLayout {
Layout.fillHeight: true
}
ToolButton {
text: qsTr("TODO: connection selection")
text: plasmoid.nativeInterface.currentConnectionConfigName
// FIXME: iconSource doesn't work
iconSource: "network-connect"
// FIXME: figure out why menu doesn't work in plasmoidviewer
// FIXME: figure out why menu doesn't work in plasmoidviewer using NVIDIA driver
// (works with plasmawindowed or Intel graphics)
menu: Menu {
MenuItem {
text: qsTr("foo")
id: connectionConfigsMenu
ExclusiveGroup {
id: connectionConfigsExclusiveGroup
}
MenuItem {
text: qsTr("bar")
Instantiator {
model: plasmoid.nativeInterface.connectionConfigNames
MenuItem {
text: model.modelData
checkable: true
checked: plasmoid.nativeInterface.currentConnectionConfigIndex === index
exclusiveGroup: connectionConfigsExclusiveGroup
onTriggered: {
plasmoid.nativeInterface.currentConnectionConfigIndex = index;
}
}
onObjectAdded: connectionConfigsMenu.insertItem(index, object)
onObjectRemoved: connectionConfigsMenu.removeItem(object)
}
}
}

View File

@ -26,7 +26,7 @@ Item {
}
function action_showSettings() {
plasmoid.nativeInterface.showConnectionSettingsDlg()
plasmoid.nativeInterface.showSettingsDlg()
}
function action_rescanAllDirs() {
@ -37,6 +37,10 @@ Item {
plasmoid.nativeInterface.showLog()
}
function action_showErrors() {
plasmoid.nativeInterface.showInternalErrorsDialog()
}
function action_showAboutDialog() {
plasmoid.nativeInterface.showAboutDialog()
}
@ -46,6 +50,7 @@ Item {
plasmoid.setAction("showWebUI", qsTr("Web UI"), "internet-web-browser");
plasmoid.setAction("showSettings", qsTr("Settings"), "configure");
plasmoid.setAction("showLog", qsTr("Log"), "text-x-generic");
plasmoid.setAction("showErrors", qsTr("Errors"), "emblem-error");
plasmoid.setAction("showAboutDialog", qsTr("About"), "help-about");
}
}

View File

@ -1,6 +1,6 @@
[Desktop Entry]
Encoding=UTF-8
Name=Syncthing Plasmoid
Name=Syncthing
Icon=syncthingtray
Type=Service
Keywords=syncthing;sync;