Improve Plasmoid to make it look more like official Plasmoids
* Use header (with integrated buttons when shown as part of the system tray Plasmoid) * Use less space so it fits into the system tray plasmoid (at least on a full HD screen with 96 dpi) * Show action for internal errors only if there are internal errors (like in the Qt Widgets based GUI) * Port away from deprecated tab bar (which is not used in official Plasmoids anymore as well) * Simplify code for ensuring the minimum size as configured (still does not work within the system tray Plasmoid)
This commit is contained in:
parent
463f1a0ac6
commit
cb1071b3ad
|
@ -20,8 +20,10 @@ set(PLASMOID_FILES
|
||||||
package/contents/ui/TopLevelItem.qml
|
package/contents/ui/TopLevelItem.qml
|
||||||
package/contents/ui/DetailView.qml
|
package/contents/ui/DetailView.qml
|
||||||
package/contents/ui/DetailItem.qml
|
package/contents/ui/DetailItem.qml
|
||||||
|
package/contents/ui/TabButton.qml
|
||||||
package/contents/ui/ToolTipTrigger.qml
|
package/contents/ui/ToolTipTrigger.qml
|
||||||
package/contents/ui/ToolTipView.qml
|
package/contents/ui/ToolTipView.qml
|
||||||
|
package/contents/ui/ToolBar.qml
|
||||||
package/contents/ui/ToolButton.qml
|
package/contents/ui/ToolButton.qml
|
||||||
package/contents/ui/TinyButton.qml
|
package/contents/ui/TinyButton.qml
|
||||||
package/contents/ui/IconLabel.qml
|
package/contents/ui/IconLabel.qml
|
||||||
|
|
|
@ -15,6 +15,8 @@ X-KDE-ServiceTypes=Plasma/Applet
|
||||||
X-Plasma-NotificationArea=true
|
X-Plasma-NotificationArea=true
|
||||||
X-Plasma-API=declarativeappletscript
|
X-Plasma-API=declarativeappletscript
|
||||||
X-Plasma-MainScript=ui/main.qml
|
X-Plasma-MainScript=ui/main.qml
|
||||||
|
X-Plasma-NotificationArea=true
|
||||||
|
X-Plasma-NotificationAreaCategory=SystemServices
|
||||||
X-Plasma-RemoteLocation=
|
X-Plasma-RemoteLocation=
|
||||||
X-KDE-PluginInfo-EnabledByDefault=true
|
X-KDE-PluginInfo-EnabledByDefault=true
|
||||||
X-KDE-PluginInfo-Category=System Information
|
X-KDE-PluginInfo-Category=System Information
|
||||||
|
|
|
@ -65,6 +65,7 @@ SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data)
|
||||||
, m_webViewDlg(nullptr)
|
, m_webViewDlg(nullptr)
|
||||||
#endif
|
#endif
|
||||||
, m_currentConnectionConfig(-1)
|
, m_currentConnectionConfig(-1)
|
||||||
|
, m_hasInternalErrors(false)
|
||||||
, m_initialized(false)
|
, m_initialized(false)
|
||||||
{
|
{
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
|
@ -248,6 +249,11 @@ bool SyncthingApplet::isStartStopEnabled() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SyncthingApplet::hasInternalErrors() const
|
||||||
|
{
|
||||||
|
return m_hasInternalErrors;
|
||||||
|
}
|
||||||
|
|
||||||
bool SyncthingApplet::areNotificationsAvailable() const
|
bool SyncthingApplet::areNotificationsAvailable() const
|
||||||
{
|
{
|
||||||
return !m_notifications.empty();
|
return !m_notifications.empty();
|
||||||
|
@ -471,6 +477,9 @@ void SyncthingApplet::handleInternalError(
|
||||||
InternalError error(errorMsg, request.url(), response);
|
InternalError error(errorMsg, request.url(), response);
|
||||||
m_dbusNotifier.showInternalError(error);
|
m_dbusNotifier.showInternalError(error);
|
||||||
InternalErrorsDialog::addError(move(error));
|
InternalErrorsDialog::addError(move(error));
|
||||||
|
if (!m_hasInternalErrors) {
|
||||||
|
emit hasInternalErrorsChanged(m_hasInternalErrors = true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncthingApplet::handleDirStatisticsChanged()
|
void SyncthingApplet::handleDirStatisticsChanged()
|
||||||
|
@ -481,6 +490,7 @@ void SyncthingApplet::handleDirStatisticsChanged()
|
||||||
|
|
||||||
void SyncthingApplet::handleErrorsCleared()
|
void SyncthingApplet::handleErrorsCleared()
|
||||||
{
|
{
|
||||||
|
emit hasInternalErrorsChanged(m_hasInternalErrors = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncthingApplet::handleAboutDialogDeleted()
|
void SyncthingApplet::handleAboutDialogDeleted()
|
||||||
|
|
|
@ -65,6 +65,7 @@ class SyncthingApplet : public Plasma::Applet {
|
||||||
Q_PROPERTY(int currentConnectionConfigIndex READ currentConnectionConfigIndex WRITE setCurrentConnectionConfigIndex NOTIFY
|
Q_PROPERTY(int currentConnectionConfigIndex READ currentConnectionConfigIndex WRITE setCurrentConnectionConfigIndex NOTIFY
|
||||||
currentConnectionConfigIndexChanged)
|
currentConnectionConfigIndexChanged)
|
||||||
Q_PROPERTY(bool startStopEnabled READ isStartStopEnabled NOTIFY settingsChanged)
|
Q_PROPERTY(bool startStopEnabled READ isStartStopEnabled NOTIFY settingsChanged)
|
||||||
|
Q_PROPERTY(bool hasInternalErrors READ hasInternalErrors NOTIFY hasInternalErrorsChanged)
|
||||||
Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
|
Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
|
||||||
Q_PROPERTY(bool notificationsAvailable READ areNotificationsAvailable NOTIFY notificationsAvailableChanged)
|
Q_PROPERTY(bool notificationsAvailable READ areNotificationsAvailable NOTIFY notificationsAvailableChanged)
|
||||||
Q_PROPERTY(bool passive READ isPassive NOTIFY passiveChanged)
|
Q_PROPERTY(bool passive READ isPassive NOTIFY passiveChanged)
|
||||||
|
@ -102,6 +103,7 @@ public:
|
||||||
Data::SyncthingConnectionSettings *connectionConfig(int index);
|
Data::SyncthingConnectionSettings *connectionConfig(int index);
|
||||||
void setCurrentConnectionConfigIndex(int index);
|
void setCurrentConnectionConfigIndex(int index);
|
||||||
bool isStartStopEnabled() const;
|
bool isStartStopEnabled() const;
|
||||||
|
bool hasInternalErrors() const;
|
||||||
QSize size() const;
|
QSize size() const;
|
||||||
void setSize(const QSize &size);
|
void setSize(const QSize &size);
|
||||||
bool areNotificationsAvailable() const;
|
bool areNotificationsAvailable() const;
|
||||||
|
@ -147,6 +149,7 @@ Q_SIGNALS:
|
||||||
void statisticsChanged();
|
void statisticsChanged();
|
||||||
void settingsChanged();
|
void settingsChanged();
|
||||||
void currentConnectionConfigIndexChanged(int index);
|
void currentConnectionConfigIndexChanged(int index);
|
||||||
|
void hasInternalErrorsChanged(bool hasInternalErrors);
|
||||||
void sizeChanged(const QSize &size);
|
void sizeChanged(const QSize &size);
|
||||||
void notificationsAvailableChanged(bool notificationsAvailable);
|
void notificationsAvailableChanged(bool notificationsAvailable);
|
||||||
void passiveChanged(bool passive);
|
void passiveChanged(bool passive);
|
||||||
|
@ -193,6 +196,7 @@ private:
|
||||||
QtGui::WebViewDialog *m_webViewDlg;
|
QtGui::WebViewDialog *m_webViewDlg;
|
||||||
#endif
|
#endif
|
||||||
int m_currentConnectionConfig;
|
int m_currentConnectionConfig;
|
||||||
|
bool m_hasInternalErrors;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,16 @@ ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
objectName: "DirectoriesPage"
|
objectName: "DirectoriesPage"
|
||||||
|
|
||||||
|
PlasmaComponents3.TextField {
|
||||||
|
property bool explicitelyShown: false
|
||||||
|
id: filter
|
||||||
|
clearButtonShown: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: explicitelyShown || text !== ""
|
||||||
|
placeholderText: qsTr("Filter directories")
|
||||||
|
onTextChanged: directoryView.model.filterRegularExpression = new RegExp(text)
|
||||||
|
}
|
||||||
|
|
||||||
PlasmaExtras.ScrollArea {
|
PlasmaExtras.ScrollArea {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
@ -170,13 +180,4 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaComponents3.TextField {
|
|
||||||
property bool explicitelyShown: false
|
|
||||||
id: filter
|
|
||||||
clearButtonShown: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: explicitelyShown || text !== ""
|
|
||||||
onTextChanged: directoryView.model.filterRegularExpression = new RegExp(text)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,36 @@
|
||||||
import QtQuick 2.8
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Controls 2.15 as QQ2 // for ComboBox (PlasmaComponents3 version clips the end of the text)
|
|
||||||
import QtQml 2.2
|
import QtQml 2.2
|
||||||
|
import QtQuick 2.8
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Controls 2.15 as QQ2
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents // for vertical TabBar
|
|
||||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||||
import martchus.syncthingplasmoid 0.6 as SyncthingPlasmoid
|
|
||||||
|
|
||||||
ColumnLayout {
|
PlasmaComponents3.Page {
|
||||||
id: root
|
header: PlasmaExtras.PlasmoidHeading {
|
||||||
|
ToolBar {
|
||||||
// ensure keyboard events can be received after initialization
|
id: toolbar
|
||||||
Component.onCompleted: forceActiveFocus()
|
width: parent.width
|
||||||
|
|
||||||
// update the size when settings changed
|
|
||||||
Connections {
|
|
||||||
target: plasmoid.nativeInterface
|
|
||||||
onSizeChanged: {
|
|
||||||
switch (plasmoid.location) {
|
|
||||||
case PlasmaCore.Types.Floating:
|
|
||||||
case PlasmaCore.Types.TopEdge:
|
|
||||||
case PlasmaCore.Types.BottomEdge:
|
|
||||||
case PlasmaCore.Types.LeftEdge:
|
|
||||||
case PlasmaCore.Types.RightEdge:
|
|
||||||
// set the parent's width and height so it will shrink again when decreasing the size
|
|
||||||
var size = plasmoid.nativeInterface.size
|
|
||||||
parent.width = units.gridUnit * size.width
|
|
||||||
parent.height = units.gridUnit * size.height
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// define functions to locate the current page and filter
|
||||||
|
function findCurrentPage() {
|
||||||
|
switch (tabBar.currentIndex) {
|
||||||
|
case 0: return directoriesPage
|
||||||
|
case 1: return devicesPage
|
||||||
|
case 2: return downloadsPage
|
||||||
|
case 3: return recentChangesPage
|
||||||
|
default: return directoriesPage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function findCurrentFilter() {
|
||||||
|
return findCurrentPage().filter
|
||||||
|
}
|
||||||
|
|
||||||
// define shortcuts to trigger actions for currently selected item
|
// define shortcuts to trigger actions for currently selected item
|
||||||
function clickCurrentItemButton(buttonName) {
|
function clickCurrentItemButton(buttonName) {
|
||||||
mainTabGroup.currentTab.item.view.clickCurrentItemButton(buttonName)
|
findCurrentPage().view.clickCurrentItemButton(buttonName)
|
||||||
}
|
}
|
||||||
Shortcut {
|
Shortcut {
|
||||||
sequence: "Ctrl+R"
|
sequence: "Ctrl+R"
|
||||||
|
@ -52,569 +45,248 @@ ColumnLayout {
|
||||||
onActivated: clickCurrentItemButton("openButton")
|
onActivated: clickCurrentItemButton("openButton")
|
||||||
}
|
}
|
||||||
|
|
||||||
// define custom key handling for switching tabs, selecting items and filtering
|
FocusScope {
|
||||||
Keys.onPressed: {
|
anchors.fill: parent
|
||||||
// note: event only received after clicking the tab buttons in plasmoidviewer
|
anchors.topMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
// but works as expected in plasmashell
|
|
||||||
switch (event.key) {
|
|
||||||
case Qt.Key_Up:
|
|
||||||
switch (event.modifiers) {
|
|
||||||
case Qt.NoModifier:
|
|
||||||
// select previous item in current tab
|
|
||||||
mainTabGroup.currentTab.item.view.decrementCurrentIndex()
|
|
||||||
break
|
|
||||||
case Qt.ShiftModifier:
|
|
||||||
// select previous connection
|
|
||||||
--plasmoid.nativeInterface.currentConnectionConfigIndex
|
|
||||||
break
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Down:
|
|
||||||
switch (event.modifiers) {
|
|
||||||
case Qt.NoModifier:
|
|
||||||
// select next item in current tab
|
|
||||||
mainTabGroup.currentTab.item.view.incrementCurrentIndex()
|
|
||||||
break
|
|
||||||
case Qt.ShiftModifier:
|
|
||||||
// select previous connection
|
|
||||||
++plasmoid.nativeInterface.currentConnectionConfigIndex
|
|
||||||
break
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Left:
|
|
||||||
// select previous tab
|
|
||||||
switch (mainTabGroup.currentTab) {
|
|
||||||
case dirsPage:
|
|
||||||
recentChangesPage.clicked()
|
|
||||||
break
|
|
||||||
case devicesPage:
|
|
||||||
dirsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case downloadsPage:
|
|
||||||
devsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case recentChangesPage:
|
|
||||||
downloadsTabButton.clicked()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Right:
|
|
||||||
// select next tab
|
|
||||||
switch (mainTabGroup.currentTab) {
|
|
||||||
case dirsPage:
|
|
||||||
devsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case devicesPage:
|
|
||||||
downloadsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case downloadsPage:
|
|
||||||
recentChangesTabButton.clicked()
|
|
||||||
break
|
|
||||||
case recentChangesPage:
|
|
||||||
dirsTabButton.clicked()
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Enter:
|
|
||||||
|
|
||||||
// fallthrough
|
|
||||||
case Qt.Key_Return:
|
|
||||||
// toggle expanded state of current item
|
|
||||||
var currentItem = mainTabGroup.currentTab.item.view.currentItem
|
|
||||||
if (currentItem) {
|
|
||||||
currentItem.expanded = !currentItem.expanded
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Escape:
|
|
||||||
var filter = findCurrentFilter()
|
|
||||||
if (filter && filter.text !== "") {
|
|
||||||
// reset filter
|
|
||||||
filter.explicitelyShown = false
|
|
||||||
filter.text = ""
|
|
||||||
event.accepted = true
|
|
||||||
} else {
|
|
||||||
// hide plasmoid
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_1:
|
|
||||||
dirsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case Qt.Key_2:
|
|
||||||
devsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case Qt.Key_3:
|
|
||||||
downloadsTabButton.clicked()
|
|
||||||
break
|
|
||||||
case Qt.Key_4:
|
|
||||||
recentChangesTabButton.clicked()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
sendKeyEventToFilter(event)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function findCurrentFilter() {
|
|
||||||
return mainTabGroup.currentTab.item.filter
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendKeyEventToFilter(event) {
|
|
||||||
var filter = findCurrentFilter()
|
|
||||||
if (!filter || event.text === "" || filter.activeFocus) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (event.key === Qt.Key_Backspace && filter.text === "") {
|
|
||||||
filter.explicitelyShown = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (event.matches(StandardKey.Paste)) {
|
|
||||||
filter.paste()
|
|
||||||
} else {
|
|
||||||
filter.text = ""
|
|
||||||
filter.text += event.text
|
|
||||||
}
|
|
||||||
filter.forceActiveFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// heading and right-corner buttons
|
|
||||||
RowLayout {
|
|
||||||
id: toolBar
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.minimumHeight: units.iconSizes.medium
|
|
||||||
Layout.maximumHeight: units.iconSizes.medium
|
|
||||||
|
|
||||||
ToolButton {
|
|
||||||
id: connectButton
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "disconnected"
|
|
||||||
PropertyChanges {
|
|
||||||
target: connectButton
|
|
||||||
text: qsTr("Connect")
|
|
||||||
icon.source: "image://fa/refresh"
|
|
||||||
visible: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "connecting"
|
|
||||||
PropertyChanges {
|
|
||||||
target: connectButton
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "paused"
|
|
||||||
PropertyChanges {
|
|
||||||
target: connectButton
|
|
||||||
text: qsTr("Resume")
|
|
||||||
icon.source: "image://fa/play"
|
|
||||||
visible: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "idle"
|
|
||||||
PropertyChanges {
|
|
||||||
target: connectButton
|
|
||||||
text: qsTr("Pause")
|
|
||||||
icon.source: "image://fa/pause"
|
|
||||||
visible: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
state: {
|
|
||||||
switch (plasmoid.nativeInterface.connection.status) {
|
|
||||||
case SyncthingPlasmoid.Data.Disconnected:
|
|
||||||
return "disconnected"
|
|
||||||
case SyncthingPlasmoid.Data.Reconnecting:
|
|
||||||
return "connecting";
|
|
||||||
case SyncthingPlasmoid.Data.Paused:
|
|
||||||
return "paused"
|
|
||||||
default:
|
|
||||||
return "idle"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: connectButton.text
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
switch (plasmoid.nativeInterface.connection.status) {
|
|
||||||
case SyncthingPlasmoid.Data.Disconnected:
|
|
||||||
plasmoid.nativeInterface.connection.connect()
|
|
||||||
break
|
|
||||||
case SyncthingPlasmoid.Data.Reconnecting:
|
|
||||||
break
|
|
||||||
case SyncthingPlasmoid.Data.Paused:
|
|
||||||
plasmoid.nativeInterface.connection.resumeAllDevs()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
plasmoid.nativeInterface.connection.pauseAllDevs()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+Shift+P"
|
|
||||||
onActivated: connectButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: startStopButton
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "running"
|
|
||||||
PropertyChanges {
|
|
||||||
target: startStopButton
|
|
||||||
visible: true
|
|
||||||
text: qsTr("Stop")
|
|
||||||
icon.source: "image://fa/stop"
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
|
||||||
target: startStopToolTip
|
|
||||||
text: (plasmoid.nativeInterface.service.userScope ? "systemctl --user stop " : "systemctl stop ")
|
|
||||||
+ plasmoid.nativeInterface.service.unitName
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "stopped"
|
|
||||||
PropertyChanges {
|
|
||||||
target: startStopButton
|
|
||||||
visible: true
|
|
||||||
text: qsTr("Start")
|
|
||||||
icon.source: "image://fa/play"
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
|
||||||
target: startStopToolTip
|
|
||||||
text: (plasmoid.nativeInterface.service.userScope ? "systemctl --user start " : "systemctl start ")
|
|
||||||
+ plasmoid.nativeInterface.service.unitName
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "irrelevant"
|
|
||||||
PropertyChanges {
|
|
||||||
target: startStopButton
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
state: {
|
|
||||||
var nativeInterface = plasmoid.nativeInterface
|
|
||||||
// the systemd unit status is only relevant when connected to the local instance
|
|
||||||
if (!nativeInterface.local
|
|
||||||
|| !nativeInterface.startStopEnabled) {
|
|
||||||
return "irrelevant"
|
|
||||||
}
|
|
||||||
// show start/stop button only when the configured unit is available
|
|
||||||
var service = nativeInterface.service
|
|
||||||
if (!service || !service.systemdAvailable) {
|
|
||||||
return "irrelevant"
|
|
||||||
}
|
|
||||||
return service.running ? "running" : "stopped"
|
|
||||||
}
|
|
||||||
onClicked: plasmoid.nativeInterface.service.toggleRunning()
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
id: startStopToolTip
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+Shift+S"
|
|
||||||
onActivated: {
|
|
||||||
if (startStopButton.visible) {
|
|
||||||
startStopButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolButton {
|
|
||||||
id: showNewNotifications
|
|
||||||
icon.name: "emblem-warning"
|
|
||||||
visible: plasmoid.nativeInterface.notificationsAvailable
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showNotificationsDialog()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Show new notifications")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+N"
|
|
||||||
onActivated: {
|
|
||||||
if (showNewNotifications.visible) {
|
|
||||||
showNewNotifications.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
icon.source: "image://fa/info"
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("About Syncthing Tray")
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showAboutDialog()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: showOwnIdButton
|
|
||||||
icon.source: "image://fa/qrcode"
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showOwnDeviceId()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Show own device ID")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+I"
|
|
||||||
onActivated: showOwnIdButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: showLogButton
|
|
||||||
icon.source: "image://fa/file-text"
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showLog()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Show Syncthing log")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+L"
|
|
||||||
onActivated: showLogButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: rescanAllDirsButton
|
|
||||||
icon.source: "image://fa/refresh"
|
|
||||||
onClicked: plasmoid.nativeInterface.connection.rescanAllDirs()
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Rescan all directories")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+Shift+R"
|
|
||||||
onActivated: rescanAllDirsButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: settingsButton
|
|
||||||
icon.source: "image://fa/cog"
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showSettingsDlg()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Settings")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+S"
|
|
||||||
onActivated: settingsButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToolButton {
|
|
||||||
id: webUIButton
|
|
||||||
icon.source: "image://fa/syncthing"
|
|
||||||
onClicked: {
|
|
||||||
plasmoid.nativeInterface.showWebUI()
|
|
||||||
plasmoid.expanded = false
|
|
||||||
}
|
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Open Syncthing")
|
|
||||||
}
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+W"
|
|
||||||
onActivated: webUIButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QQ2.ComboBox {
|
|
||||||
id: connectionConfigsMenu
|
|
||||||
model: plasmoid.nativeInterface.connectionConfigNames
|
|
||||||
visible: plasmoid.nativeInterface.connectionConfigNames.length > 1
|
|
||||||
currentIndex: plasmoid.nativeInterface.currentConnectionConfigIndex
|
|
||||||
onCurrentIndexChanged: plasmoid.nativeInterface.currentConnectionConfigIndex = currentIndex
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: implicitWidth
|
|
||||||
Shortcut {
|
|
||||||
sequence: "Ctrl+Shift+C"
|
|
||||||
onActivated: connectionConfigsMenu.popup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.SvgItem {
|
|
||||||
Layout.preferredWidth: parent.width
|
|
||||||
Layout.preferredHeight: 2
|
|
||||||
elementId: "horizontal-line"
|
|
||||||
svg: PlasmaCore.Svg {
|
|
||||||
imagePath: "widgets/line"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// global statistics and traffic
|
|
||||||
GridLayout {
|
|
||||||
Layout.leftMargin: 5
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: false
|
|
||||||
columns: 3
|
|
||||||
rowSpacing: 1
|
|
||||||
columnSpacing: 4
|
|
||||||
|
|
||||||
Image {
|
|
||||||
Layout.preferredWidth: 16
|
|
||||||
Layout.preferredHeight: 16
|
|
||||||
height: 16
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: "image://fa/globe"
|
|
||||||
}
|
|
||||||
StatisticsView {
|
|
||||||
Layout.leftMargin: 4
|
|
||||||
statistics: plasmoid.nativeInterface.globalStatistics
|
|
||||||
context: qsTr("Global")
|
|
||||||
}
|
|
||||||
|
|
||||||
IconLabel {
|
|
||||||
Layout.leftMargin: 10
|
|
||||||
iconSource: "image://fa/cloud-download"
|
|
||||||
iconOpacity: plasmoid.nativeInterface.hasIncomingTraffic ? 1.0 : 0.5
|
|
||||||
text: plasmoid.nativeInterface.incomingTraffic
|
|
||||||
tooltip: qsTr("Global incoming traffic")
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
Layout.preferredWidth: 16
|
|
||||||
Layout.preferredHeight: 16
|
|
||||||
height: 16
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: "image://fa/home"
|
|
||||||
}
|
|
||||||
StatisticsView {
|
|
||||||
Layout.leftMargin: 4
|
|
||||||
statistics: plasmoid.nativeInterface.localStatistics
|
|
||||||
context: qsTr("Local")
|
|
||||||
}
|
|
||||||
|
|
||||||
IconLabel {
|
|
||||||
Layout.leftMargin: 10
|
|
||||||
iconSource: "image://fa/cloud-upload"
|
|
||||||
iconOpacity: plasmoid.nativeInterface.hasOutgoingTraffic ? 1.0 : 0.5
|
|
||||||
text: plasmoid.nativeInterface.outgoingTraffic
|
|
||||||
tooltip: qsTr("Global outgoing traffic")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.SvgItem {
|
|
||||||
Layout.preferredWidth: parent.width
|
|
||||||
Layout.preferredHeight: 2
|
|
||||||
elementId: "horizontal-line"
|
|
||||||
svg: PlasmaCore.Svg {
|
|
||||||
imagePath: "widgets/line"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tab "widget"
|
|
||||||
RowLayout {
|
|
||||||
id: tabWidget
|
|
||||||
spacing: 0
|
|
||||||
Layout.minimumWidth: units.gridUnit * plasmoid.nativeInterface.size.width
|
|
||||||
Layout.minimumHeight: units.gridUnit * plasmoid.nativeInterface.size.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 0
|
anchors.fill: parent
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
|
||||||
|
|
||||||
PlasmaComponents.TabBar {
|
// ensure keyboard events can be received after initialization
|
||||||
id: tabBar
|
Component.onCompleted: forceActiveFocus()
|
||||||
tabPosition: Qt.LeftEdge
|
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
|
||||||
|
|
||||||
PlasmaComponents.TabButton {
|
// define custom key handling for switching tabs, selecting items and filtering
|
||||||
id: dirsTabButton
|
function sendKeyEventToFilter(event) {
|
||||||
iconSource: plasmoid.nativeInterface.loadForkAwesomeIcon("folder")
|
var filter = findCurrentFilter()
|
||||||
tab: dirsPage
|
if (!filter || event.text === "" || filter.activeFocus) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
PlasmaComponents.TabButton {
|
if (event.key === Qt.Key_Backspace && filter.text === "") {
|
||||||
id: devsTabButton
|
filter.explicitelyShown = false
|
||||||
iconSource: plasmoid.nativeInterface.loadForkAwesomeIcon("sitemap")
|
return
|
||||||
tab: devicesPage
|
|
||||||
}
|
}
|
||||||
PlasmaComponents.TabButton {
|
if (event.matches(StandardKey.Paste)) {
|
||||||
id: downloadsTabButton
|
filter.paste()
|
||||||
iconSource: plasmoid.nativeInterface.loadForkAwesomeIcon("download")
|
} else {
|
||||||
tab: downloadsPage
|
filter.text = ""
|
||||||
}
|
filter.text += event.text
|
||||||
PlasmaComponents.TabButton {
|
|
||||||
id: recentChangesTabButton
|
|
||||||
iconSource: plasmoid.nativeInterface.loadForkAwesomeIcon("history")
|
|
||||||
tab: recentChangesPage
|
|
||||||
}
|
}
|
||||||
|
filter.forceActiveFocus()
|
||||||
}
|
}
|
||||||
Item {
|
Keys.onPressed: {
|
||||||
Layout.fillHeight: true
|
// note: event only received after clicking the tab buttons in plasmoidviewer
|
||||||
}
|
// but works as expected in plasmashell
|
||||||
ToolButton {
|
switch (event.key) {
|
||||||
id: searchButton
|
case Qt.Key_Up:
|
||||||
Layout.fillWidth: false
|
switch (event.modifiers) {
|
||||||
Layout.fillHeight: false
|
case Qt.NoModifier:
|
||||||
Layout.minimumWidth: units.iconSizes.smallMedium
|
// select previous item in current tab
|
||||||
Layout.minimumHeight: units.iconSizes.smallMedium
|
findCurrentPage().view.decrementCurrentIndex()
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
|
break
|
||||||
icon.source: "image://fa/search"
|
case Qt.ShiftModifier:
|
||||||
enabled: mainTabGroup.currentTab === dirsPage
|
// select previous connection
|
||||||
onClicked: {
|
--plasmoid.nativeInterface.currentConnectionConfigIndex
|
||||||
var filter = findCurrentFilter()
|
break
|
||||||
if (!filter) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if (!filter.explicitelyShown) {
|
break
|
||||||
filter.explicitelyShown = true
|
case Qt.Key_Down:
|
||||||
filter.forceActiveFocus()
|
switch (event.modifiers) {
|
||||||
} else {
|
case Qt.NoModifier:
|
||||||
|
// select next item in current tab
|
||||||
|
findCurrentPage().view.incrementCurrentIndex()
|
||||||
|
break
|
||||||
|
case Qt.ShiftModifier:
|
||||||
|
// select previous connection
|
||||||
|
++plasmoid.nativeInterface.currentConnectionConfigIndex
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case Qt.Key_Left:
|
||||||
|
// select previous tab
|
||||||
|
tabBar.currentIndex = tabBar.currentIndex > 0 ? tabBar.currentIndex - 1 : 3
|
||||||
|
break
|
||||||
|
case Qt.Key_Right:
|
||||||
|
// select next tab
|
||||||
|
tabBar.currentIndex = tabBar.currentIndex < 3 ? tabBar.currentIndex + 1 : 0
|
||||||
|
break
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
|
||||||
|
// fallthrough
|
||||||
|
case Qt.Key_Return:
|
||||||
|
// toggle expanded state of current item
|
||||||
|
var currentItem = findCurrentPage().view.currentItem
|
||||||
|
if (currentItem) {
|
||||||
|
currentItem.expanded = !currentItem.expanded
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case Qt.Key_Escape:
|
||||||
|
var filter = findCurrentFilter()
|
||||||
|
if (filter && filter.text !== "") {
|
||||||
|
// reset filter
|
||||||
filter.explicitelyShown = false
|
filter.explicitelyShown = false
|
||||||
filter.text = ""
|
filter.text = ""
|
||||||
|
event.accepted = true
|
||||||
|
} else {
|
||||||
|
// hide plasmoid
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case Qt.Key_1:
|
||||||
|
tabBar.currentIndex = 0
|
||||||
|
break
|
||||||
|
case Qt.Key_2:
|
||||||
|
tabBar.currentIndex = 1
|
||||||
|
break
|
||||||
|
case Qt.Key_3:
|
||||||
|
tabBar.currentIndex = 2
|
||||||
|
break
|
||||||
|
case Qt.Key_4:
|
||||||
|
tabBar.currentIndex = 3
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
sendKeyEventToFilter(event)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// global statistics and traffic
|
||||||
|
GridLayout {
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
columns: 5
|
||||||
|
rowSpacing: 1
|
||||||
|
columnSpacing: 4
|
||||||
|
|
||||||
|
Image {
|
||||||
|
Layout.preferredWidth: 16
|
||||||
|
Layout.preferredHeight: 16
|
||||||
|
height: 16
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "image://fa/globe"
|
||||||
|
}
|
||||||
|
StatisticsView {
|
||||||
|
Layout.leftMargin: 4
|
||||||
|
statistics: plasmoid.nativeInterface.globalStatistics
|
||||||
|
context: qsTr("Global")
|
||||||
|
}
|
||||||
|
IconLabel {
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
iconSource: "image://fa/cloud-download"
|
||||||
|
iconOpacity: plasmoid.nativeInterface.hasIncomingTraffic ? 1.0 : 0.5
|
||||||
|
text: plasmoid.nativeInterface.incomingTraffic
|
||||||
|
tooltip: qsTr("Global incoming traffic")
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.rowSpan: 2
|
||||||
|
}
|
||||||
|
TinyButton {
|
||||||
|
id: searchButton
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.fillHeight: false
|
||||||
|
Layout.rowSpan: 2
|
||||||
|
icon.source: "image://fa/search"
|
||||||
|
enabled: tabBar.currentIndex === 0
|
||||||
|
opacity: enabled ? 1.0 : 0.25
|
||||||
|
tooltip: qsTr("Toggle filter")
|
||||||
|
onClicked: {
|
||||||
|
var filter = findCurrentFilter()
|
||||||
|
if (!filter) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!filter.explicitelyShown) {
|
||||||
|
filter.explicitelyShown = true
|
||||||
|
filter.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
filter.explicitelyShown = false
|
||||||
|
filter.text = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PlasmaComponents3.ToolTip {
|
|
||||||
text: qsTr("Toggle filter")
|
Image {
|
||||||
|
Layout.preferredWidth: 16
|
||||||
|
Layout.preferredHeight: 16
|
||||||
|
height: 16
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "image://fa/home"
|
||||||
|
}
|
||||||
|
StatisticsView {
|
||||||
|
Layout.leftMargin: 4
|
||||||
|
statistics: plasmoid.nativeInterface.localStatistics
|
||||||
|
context: qsTr("Local")
|
||||||
|
}
|
||||||
|
IconLabel {
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
iconSource: "image://fa/cloud-upload"
|
||||||
|
iconOpacity: plasmoid.nativeInterface.hasOutgoingTraffic ? 1.0 : 0.5
|
||||||
|
text: plasmoid.nativeInterface.outgoingTraffic
|
||||||
|
tooltip: qsTr("Global outgoing traffic")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.SvgItem {
|
// tab "widget"
|
||||||
Layout.preferredWidth: 2
|
ColumnLayout {
|
||||||
Layout.fillHeight: true
|
id: tabWidget
|
||||||
elementId: "vertical-line"
|
spacing: 0
|
||||||
svg: PlasmaCore.Svg {
|
Layout.fillWidth: true
|
||||||
imagePath: "widgets/line"
|
Layout.fillHeight: true
|
||||||
}
|
|
||||||
}
|
|
||||||
PlasmaComponents.TabGroup {
|
|
||||||
id: mainTabGroup
|
|
||||||
currentTab: dirsPage
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
PlasmaExtras.ConditionalLoader {
|
StackLayout {
|
||||||
id: dirsPage
|
id: tabLayout
|
||||||
when: mainTabGroup.currentTab === dirsPage
|
currentIndex: tabBar.currentIndex
|
||||||
source: Qt.resolvedUrl("DirectoriesPage.qml")
|
Layout.fillWidth: true
|
||||||
}
|
Layout.fillHeight: true
|
||||||
PlasmaExtras.ConditionalLoader {
|
DirectoriesPage {
|
||||||
id: devicesPage
|
id: directoriesPage
|
||||||
when: mainTabGroup.currentTab === devicesPage
|
}
|
||||||
source: Qt.resolvedUrl("DevicesPage.qml")
|
DevicesPage {
|
||||||
}
|
id: devicesPage
|
||||||
PlasmaExtras.ConditionalLoader {
|
}
|
||||||
id: downloadsPage
|
DownloadsPage {
|
||||||
when: mainTabGroup.currentTab === downloadsPage
|
id: downloadsPage
|
||||||
source: Qt.resolvedUrl("DownloadsPage.qml")
|
}
|
||||||
}
|
RecentChangesPage {
|
||||||
PlasmaExtras.ConditionalLoader {
|
id: recentChangesPage
|
||||||
id: recentChangesPage
|
}
|
||||||
when: mainTabGroup.currentTab === recentChangesPage
|
}
|
||||||
source: Qt.resolvedUrl("RecentChangesPage.qml")
|
PlasmaCore.SvgItem {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elementId: "horizontal-line"
|
||||||
|
svg: PlasmaCore.Svg {
|
||||||
|
imagePath: "widgets/line"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaComponents3.TabBar {
|
||||||
|
id: tabBar
|
||||||
|
position: PlasmaComponents3.TabBar.Footer
|
||||||
|
spacing: units.smallSpacing
|
||||||
|
Layout.alignment: Qt.AlignBottom
|
||||||
|
TabButton {
|
||||||
|
id: dirsTabButton
|
||||||
|
text: qsTr("Directories")
|
||||||
|
icon.source: "image://fa/folder"
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
id: devsTabButton
|
||||||
|
text: qsTr("Devices")
|
||||||
|
icon.source: "image://fa/sitemap"
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
id: downloadsTabButton
|
||||||
|
text: qsTr("Downloads")
|
||||||
|
icon.source: "image://fa/download"
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
id: recentChangesTabButton
|
||||||
|
text: qsTr("History")
|
||||||
|
icon.source: "image://fa/history"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import QtQuick 2.8
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||||
|
|
||||||
|
PlasmaComponents3.TabButton {
|
||||||
|
id: root
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: label.visible ? units.smallSpacing : 0
|
||||||
|
PlasmaCore.ColorScope.inherit: true
|
||||||
|
Image {
|
||||||
|
id: image
|
||||||
|
Layout.preferredHeight: height
|
||||||
|
source: root.icon.source
|
||||||
|
height: units.iconSizes.small
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
PlasmaComponents3.Label {
|
||||||
|
id: label
|
||||||
|
visible: text.length > 0
|
||||||
|
text: root.text
|
||||||
|
font: root.parent.font
|
||||||
|
color: PlasmaCore.ColorScope.textColor
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,279 @@
|
||||||
|
import QtQml 2.3
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.kquickcontrolsaddons 2.0
|
||||||
|
import martchus.syncthingplasmoid 0.6 as SyncthingPlasmoid
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: toolBar
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.minimumHeight: units.iconSizes.medium
|
||||||
|
Layout.maximumHeight: units.iconSizes.medium
|
||||||
|
|
||||||
|
readonly property bool showExtraButtons: !(plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentDrawsPlasmoidHeading)
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
id: connectButton
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "disconnected"
|
||||||
|
PropertyChanges {
|
||||||
|
target: connectButton
|
||||||
|
text: qsTr("Connect")
|
||||||
|
icon.source: "image://fa/refresh"
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "connecting"
|
||||||
|
PropertyChanges {
|
||||||
|
target: connectButton
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "paused"
|
||||||
|
PropertyChanges {
|
||||||
|
target: connectButton
|
||||||
|
text: qsTr("Resume")
|
||||||
|
icon.source: "image://fa/play"
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "idle"
|
||||||
|
PropertyChanges {
|
||||||
|
target: connectButton
|
||||||
|
text: qsTr("Pause")
|
||||||
|
icon.source: "image://fa/pause"
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
state: {
|
||||||
|
switch (plasmoid.nativeInterface.connection.status) {
|
||||||
|
case SyncthingPlasmoid.Data.Disconnected:
|
||||||
|
return "disconnected"
|
||||||
|
case SyncthingPlasmoid.Data.Reconnecting:
|
||||||
|
return "connecting";
|
||||||
|
case SyncthingPlasmoid.Data.Paused:
|
||||||
|
return "paused"
|
||||||
|
default:
|
||||||
|
return "idle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
switch (plasmoid.nativeInterface.connection.status) {
|
||||||
|
case SyncthingPlasmoid.Data.Disconnected:
|
||||||
|
plasmoid.nativeInterface.connection.connect()
|
||||||
|
break
|
||||||
|
case SyncthingPlasmoid.Data.Reconnecting:
|
||||||
|
break
|
||||||
|
case SyncthingPlasmoid.Data.Paused:
|
||||||
|
plasmoid.nativeInterface.connection.resumeAllDevs()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
plasmoid.nativeInterface.connection.pauseAllDevs()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: connectButton.text
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+Shift+P"
|
||||||
|
onActivated: connectButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: startStopButton
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "running"
|
||||||
|
PropertyChanges {
|
||||||
|
target: startStopButton
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Stop")
|
||||||
|
icon.source: "image://fa/stop"
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: startStopToolTip
|
||||||
|
text: (plasmoid.nativeInterface.service.userScope ? "systemctl --user stop " : "systemctl stop ")
|
||||||
|
+ plasmoid.nativeInterface.service.unitName
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "stopped"
|
||||||
|
PropertyChanges {
|
||||||
|
target: startStopButton
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Start")
|
||||||
|
icon.source: "image://fa/play"
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: startStopToolTip
|
||||||
|
text: (plasmoid.nativeInterface.service.userScope ? "systemctl --user start " : "systemctl start ")
|
||||||
|
+ plasmoid.nativeInterface.service.unitName
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "irrelevant"
|
||||||
|
PropertyChanges {
|
||||||
|
target: startStopButton
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
state: {
|
||||||
|
var nativeInterface = plasmoid.nativeInterface
|
||||||
|
// the systemd unit status is only relevant when connected to the local instance
|
||||||
|
if (!nativeInterface.local
|
||||||
|
|| !nativeInterface.startStopEnabled) {
|
||||||
|
return "irrelevant"
|
||||||
|
}
|
||||||
|
// show start/stop button only when the configured unit is available
|
||||||
|
var service = nativeInterface.service
|
||||||
|
if (!service || !service.systemdAvailable) {
|
||||||
|
return "irrelevant"
|
||||||
|
}
|
||||||
|
return service.running ? "running" : "stopped"
|
||||||
|
}
|
||||||
|
onClicked: plasmoid.nativeInterface.service.toggleRunning()
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
id: startStopToolTip
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+Shift+S"
|
||||||
|
onActivated: {
|
||||||
|
if (startStopButton.visible) {
|
||||||
|
startStopButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolButton {
|
||||||
|
id: showNewNotifications
|
||||||
|
icon.name: "emblem-warning"
|
||||||
|
visible: plasmoid.nativeInterface.notificationsAvailable
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showNotificationsDialog()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Show new notifications")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+N"
|
||||||
|
onActivated: {
|
||||||
|
if (showNewNotifications.visible) {
|
||||||
|
showNewNotifications.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
icon.source: "image://fa/info"
|
||||||
|
visible: showExtraButtons
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showAboutDialog()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("About Syncthing Tray")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: showOwnIdButton
|
||||||
|
icon.source: "image://fa/qrcode"
|
||||||
|
visible: showExtraButtons
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showOwnDeviceId()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Show own device ID")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+I"
|
||||||
|
onActivated: showOwnIdButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: showLogButton
|
||||||
|
icon.source: "image://fa/file-text"
|
||||||
|
visible: showExtraButtons
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showLog()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Show Syncthing log")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+L"
|
||||||
|
onActivated: showLogButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: rescanAllDirsButton
|
||||||
|
icon.source: "image://fa/refresh"
|
||||||
|
onClicked: plasmoid.nativeInterface.connection.rescanAllDirs()
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Rescan all directories")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+Shift+R"
|
||||||
|
onActivated: rescanAllDirsButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: settingsButton
|
||||||
|
icon.source: "image://fa/cog"
|
||||||
|
visible: showExtraButtons
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showSettingsDlg()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Settings")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+S"
|
||||||
|
onActivated: settingsButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
id: webUIButton
|
||||||
|
icon.source: "image://fa/syncthing"
|
||||||
|
onClicked: {
|
||||||
|
plasmoid.nativeInterface.showWebUI()
|
||||||
|
plasmoid.expanded = false
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ToolTip {
|
||||||
|
text: qsTr("Open Syncthing")
|
||||||
|
}
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+W"
|
||||||
|
onActivated: webUIButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaComponents3.ComboBox {
|
||||||
|
id: connectionConfigsMenu
|
||||||
|
model: plasmoid.nativeInterface.connectionConfigNames
|
||||||
|
visible: plasmoid.nativeInterface.connectionConfigNames.length > 1
|
||||||
|
currentIndex: plasmoid.nativeInterface.currentConnectionConfigIndex
|
||||||
|
onCurrentIndexChanged: plasmoid.nativeInterface.currentConnectionConfigIndex = currentIndex
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: implicitWidth
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Ctrl+Shift+C"
|
||||||
|
onActivated: connectionConfigsMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.2
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import org.kde.plasma.plasmoid 2.0
|
import org.kde.plasma.plasmoid 2.0
|
||||||
import org.kde.kquickcontrolsaddons 2.0
|
import org.kde.kquickcontrolsaddons 2.0
|
||||||
|
@ -6,29 +6,22 @@ import org.kde.kquickcontrolsaddons 2.0
|
||||||
Item {
|
Item {
|
||||||
id: syncthingApplet
|
id: syncthingApplet
|
||||||
|
|
||||||
Plasmoid.switchWidth: units.gridUnit * 25
|
Plasmoid.switchWidth: units.gridUnit * (plasmoid.nativeInterface.size.width + 1)
|
||||||
Plasmoid.switchHeight: units.gridUnit * 20
|
Plasmoid.switchHeight: units.gridUnit * (plasmoid.nativeInterface.size.height + 1)
|
||||||
|
|
||||||
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
|
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
|
||||||
Plasmoid.compactRepresentation: CompactRepresentation {}
|
Plasmoid.compactRepresentation: CompactRepresentation {}
|
||||||
Plasmoid.fullRepresentation: Loader {
|
Plasmoid.fullRepresentation: FullRepresentation {
|
||||||
source: "FullRepresentation.qml"
|
Layout.minimumWidth: units.gridUnit * plasmoid.nativeInterface.size.width
|
||||||
onLoaded: {
|
Layout.minimumHeight: units.gridUnit * plasmoid.nativeInterface.size.height
|
||||||
if (typeof (item.updateSize) === 'function') {
|
|
||||||
item.updateSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Plasmoid.icon: "syncthingtray"
|
Plasmoid.icon: "syncthingtray"
|
||||||
Plasmoid.toolTipMainText: plasmoid.nativeInterface.statusText
|
Plasmoid.toolTipMainText: plasmoid.nativeInterface.statusText
|
||||||
Plasmoid.toolTipSubText: plasmoid.nativeInterface.additionalStatusText
|
Plasmoid.toolTipSubText: plasmoid.nativeInterface.additionalStatusText
|
||||||
Plasmoid.toolTipItem: Loader {
|
Plasmoid.toolTipItem: ToolTipView {
|
||||||
Layout.minimumWidth: item ? item.width : 0
|
Layout.minimumWidth: item ? item.width : 0
|
||||||
Layout.maximumWidth: item ? item.width : 0
|
Layout.maximumWidth: item ? item.width : 0
|
||||||
Layout.minimumHeight: item ? item.height : 0
|
Layout.minimumHeight: item ? item.height : 0
|
||||||
Layout.maximumHeight: item ? item.height : 0
|
Layout.maximumHeight: item ? item.height : 0
|
||||||
source: "ToolTipView.qml"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Plasmoid.hideOnWindowDeactivate: true
|
Plasmoid.hideOnWindowDeactivate: true
|
||||||
|
@ -37,10 +30,14 @@ Item {
|
||||||
plasmoid.nativeInterface.showWebUI()
|
plasmoid.nativeInterface.showWebUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
function action_showSettings() {
|
function action_configure() {
|
||||||
plasmoid.nativeInterface.showSettingsDlg()
|
plasmoid.nativeInterface.showSettingsDlg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function action_showOwnId() {
|
||||||
|
plasmoid.nativeInterface.showOwnDeviceId()
|
||||||
|
}
|
||||||
|
|
||||||
function action_rescanAllDirs() {
|
function action_rescanAllDirs() {
|
||||||
plasmoid.nativeInterface.connection.rescanAllDirs()
|
plasmoid.nativeInterface.connection.rescanAllDirs()
|
||||||
}
|
}
|
||||||
|
@ -67,13 +64,16 @@ Item {
|
||||||
plasmoid.setAction(
|
plasmoid.setAction(
|
||||||
"showWebUI", qsTr("Open Syncthing"),
|
"showWebUI", qsTr("Open Syncthing"),
|
||||||
":/icons/hicolor/scalable/status/syncthing-default.svg")
|
":/icons/hicolor/scalable/status/syncthing-default.svg")
|
||||||
plasmoid.setAction("showSettings", qsTr("Settings"), "configure")
|
plasmoid.setAction("configure", qsTr("Settings"), "configure")
|
||||||
plasmoid.setAction("showLog", qsTr("Log"), "text-x-generic")
|
|
||||||
plasmoid.setAction("showErrors", qsTr("Internal errors"), "data-error")
|
|
||||||
plasmoid.setAction("rescanAllDirs", qsTr("Rescan all directories"),
|
plasmoid.setAction("rescanAllDirs", qsTr("Rescan all directories"),
|
||||||
"folder-sync")
|
"folder-sync")
|
||||||
|
plasmoid.setAction("showOwnId", qsTr("Show own device ID"),
|
||||||
|
"view-barcode-qr")
|
||||||
plasmoid.setAction("restartSyncthing", qsTr("Restart Syncthing"),
|
plasmoid.setAction("restartSyncthing", qsTr("Restart Syncthing"),
|
||||||
"system-reboot")
|
"system-reboot")
|
||||||
|
plasmoid.setAction("showLog", qsTr("Log"), "text-x-generic")
|
||||||
|
plasmoid.setAction("showErrors", qsTr("Internal errors"), "data-error")
|
||||||
|
plasmoid.action("showErrors").visible = Qt.binding(() => { return plasmoid.nativeInterface.hasInternalErrors })
|
||||||
plasmoid.setAction("showAboutDialog", qsTr("About"), "help-about")
|
plasmoid.setAction("showAboutDialog", qsTr("About"), "help-about")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ rather than the regular home to separate testing from production.
|
||||||
4. Set `%{sourceDir}/../../syncthingtray/plasmoid/scripts/starttesting.sh plasmoidviewer --applet martchus.syncthingplasmoid`
|
4. Set `%{sourceDir}/../../syncthingtray/plasmoid/scripts/starttesting.sh plasmoidviewer --applet martchus.syncthingplasmoid`
|
||||||
as CLI argument
|
as CLI argument
|
||||||
* It is also possible to use `plasmawindowed` or `plasmashell`, see sections below.
|
* It is also possible to use `plasmawindowed` or `plasmashell`, see sections below.
|
||||||
|
* It is also possible to specify `org.kde.plasma.systemtray` as applet to test how the Plasmoid
|
||||||
|
looks like within the system tray plasmoid.
|
||||||
* This usage of `%{sourceDir}` assumes one used the "Building this straight" instructions
|
* This usage of `%{sourceDir}` assumes one used the "Building this straight" instructions
|
||||||
from the main README.md.
|
from the main README.md.
|
||||||
5. Keep `%{buildDir}` as working directory.
|
5. Keep `%{buildDir}` as working directory.
|
||||||
|
|
Loading…
Reference in New Issue