diff --git a/fileitemactionplugin/testing.md b/fileitemactionplugin/testing.md index 20142e3..a7d38be 100644 --- a/fileitemactionplugin/testing.md +++ b/fileitemactionplugin/testing.md @@ -1,12 +1,28 @@ # Testing and debugging Dolphin/KIO plugin with Qt Creator - -1. Build as usual, ensure `NO_FILE_ITEM_ACTION_PLUGIN` is turned off -2. Copy `*.desktop` file to `~/.local/share/kservices5` and enable it in Dolphin - if packaged version is not already installed -3. Add new config for run in Qt Creator and set `dolphin` as executable +1. Build as usual, ensure `NO_FILE_ITEM_ACTION_PLUGIN` is turned off. +2. Copy `*.desktop` file to `~/.local/share/kservices5` and enable it in Dolphin if a packaged version + with the same configuration name is not already installed. Replace `5` with the current major version + of KDE. +3. Add new config for run in Qt Creator and set `dolphin` as executable. 4. In execution environment, set - * `QT_PLUGIN_PATH` to directory containing plugin `\*.so`-file - * `QT_DEBUG_PLUGINS` to 1 for verbose plugin detection - * `QT_XCB_NO_GRAB_SERVER` to 1 to prevent grabbing so the debugger is usable -5. Ignore warning that executable is no debug build, it is sufficiant when - plugin is debug build + * `QT_PLUGIN_PATH` to directory containing plugin `\*.so`-file. + * `QT_DEBUG_PLUGINS` to 1 for verbose plugin detection. + * `QT_XCB_NO_GRAB_SERVER` to 1 to prevent grabbing so the debugger is usable. +5. Ignore warning that executable is no debug build, it is sufficiant when plugin is debug build. + +## Testing against a development build of Dolphin +NOTE: This does not actually work with a KF6 build. Maybe the `*.desktop` file needs to be changed. + +1. Build the whole dependency chain up to `dolphin` installing it under some custom prefix. +2. Then follow the usual steps but make sure you build Syncthing Tray against the custom KDE builds. + This is achieved the easiest by using the `debug-kde` CMake preset. This preset uses the environment + variable `KDE_INSTALL_DIR` which must point to the custom prefix used in step 1. +3. Copy the `*.desktop` file into the custom prefix used in step 1 under `share/kservices6`. Replace `6` + with the current major version of KDE. The directory likely needs to be created first. +4. Source the `prefix.sh` script that should be present in the build directory of any KDE library + you built in step 1, e.g. `source kde/plasma-sdk/prefix.sh`. +5. When setting the environment one needs to be more careful to not override variables set in step 4. + It is the easiest to just start e.g. `plasmawindowed` from the shell: + ``` + QT_PLUGIN_PATH=$BUILD_DIR/syncthingtray/debug-kde/syncthingtray/fileitemactionplugin:$QT_PLUGIN_PATH dolphin + ``` diff --git a/plasmoid/.gitignore b/plasmoid/.gitignore index 078e450..a0df595 100644 --- a/plasmoid/.gitignore +++ b/plasmoid/.gitignore @@ -1,2 +1,3 @@ -# the generated desktop file is required by inittesting.sh +# the generated desktop/JSON file is required by inittesting.sh metadata.desktop +metadata.json diff --git a/plasmoid/CMakeLists.txt b/plasmoid/CMakeLists.txt index 8f40bcf..bacbe30 100644 --- a/plasmoid/CMakeLists.txt +++ b/plasmoid/CMakeLists.txt @@ -11,38 +11,37 @@ set(META_QT5_VERSION 5.8) # use testfiles directory from syncthingconnector set(META_SRCDIR_REFS "${CMAKE_CURRENT_SOURCE_DIR}\n${CMAKE_CURRENT_SOURCE_DIR}/../syncthingconnector") +# find Plasma +find_package(${KF_PACKAGE_PREFIX}Plasma REQUIRED) + # source files +set(PLASMOID_FILES_BASE "package${KF_MAJOR_VERSION}") +set(PLASMOID_FILES_UI "${PLASMOID_FILES_BASE}/contents/ui") set(PLASMOID_FILES - package/contents/ui/CompactRepresentation.qml - package/contents/ui/FullRepresentation.qml - package/contents/ui/DirectoriesPage.qml - package/contents/ui/DevicesPage.qml - package/contents/ui/DownloadsPage.qml - package/contents/ui/RecentChangesPage.qml - package/contents/ui/TopLevelView.qml - package/contents/ui/TopLevelItem.qml - package/contents/ui/DetailView.qml - package/contents/ui/DetailItem.qml - package/contents/ui/TabButton.qml - package/contents/ui/ToolTipTrigger.qml - package/contents/ui/ToolTipView.qml - package/contents/ui/ToolBar.qml - package/contents/ui/ToolButton.qml - package/contents/ui/TinyButton.qml - package/contents/ui/IconLabel.qml - package/contents/ui/StatisticsView.qml - package/contents/ui/main.qml) + ${PLASMOID_FILES_UI}/CompactRepresentation.qml + ${PLASMOID_FILES_UI}/FullRepresentation.qml + ${PLASMOID_FILES_UI}/DirectoriesPage.qml + ${PLASMOID_FILES_UI}/DevicesPage.qml + ${PLASMOID_FILES_UI}/DownloadsPage.qml + ${PLASMOID_FILES_UI}/RecentChangesPage.qml + ${PLASMOID_FILES_UI}/TopLevelView.qml + ${PLASMOID_FILES_UI}/TopLevelItem.qml + ${PLASMOID_FILES_UI}/DetailView.qml + ${PLASMOID_FILES_UI}/DetailItem.qml + ${PLASMOID_FILES_UI}/TabButton.qml + ${PLASMOID_FILES_UI}/ToolTipTrigger.qml + ${PLASMOID_FILES_UI}/ToolTipView.qml + ${PLASMOID_FILES_UI}/ToolBar.qml + ${PLASMOID_FILES_UI}/ToolButton.qml + ${PLASMOID_FILES_UI}/TinyButton.qml + ${PLASMOID_FILES_UI}/IconLabel.qml + ${PLASMOID_FILES_UI}/StatisticsView.qml + ${PLASMOID_FILES_UI}/main.qml) # find ECM (required by Plasma) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_MODULE_PATH}) -# find Plasma -set(KF_PACKAGE_PREFIX - "KF5" - CACHE STRING "specifies the prefix for KDE Frameworks packages") -find_package(${KF_PACKAGE_PREFIX}Plasma REQUIRED) - # find c++utilities find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.20.0 REQUIRED) list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS}) @@ -50,14 +49,22 @@ list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS}) # prepare plasmoid package/configuration set(PLASMOID_PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/package") file(MAKE_DIRECTORY "${PLASMOID_PACKAGE_DIR}") -set(PLASMOID_CONFIG_TARGET_FILE "${PLASMOID_PACKAGE_DIR}/metadata.desktop") +if (KF_MAJOR_VERSION LESS 6) + set(PLASMOID_CONFIG_TARGET_FILE "${PLASMOID_PACKAGE_DIR}/metadata.desktop") +else () + set(PLASMOID_CONFIG_TARGET_FILE "${PLASMOID_PACKAGE_DIR}/metadata.json") +endif () # make plugin library add_subdirectory(lib) # make plasmoid configuration include(TemplateFinder) -find_template_file("metadata.desktop" "${META_PROJECT_NAME}" PLASMOID_CONFIG_TEMPLATE_FILE) +if (KF_MAJOR_VERSION LESS 6) + find_template_file("metadata.desktop" "${META_PROJECT_NAME}" PLASMOID_CONFIG_TEMPLATE_FILE) +else () + find_template_file("metadata.json" "${META_PROJECT_NAME}" PLASMOID_CONFIG_TEMPLATE_FILE) +endif () get_filename_component(PLASMOID_CONFIG_TARGET_FILE_ABSOLUTE_PATH "${PLASMOID_CONFIG_TARGET_FILE}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") configure_file("${PLASMOID_CONFIG_TEMPLATE_FILE}" "${PLASMOID_CONFIG_TARGET_FILE}") @@ -75,6 +82,6 @@ plasma_install_package("${PLASMOID_PACKAGE_DIR}" "${META_ID}") set(PLASMOID_TESTDIR "${CMAKE_BINARY_DIR}" CACHE STRING "specifies the Plasmoid test directory") file(MAKE_DIRECTORY "${PLASMOID_TESTDIR}") add_custom_target(init_plasmoid_testing - COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/inittesting.sh" "${PLASMOID_CONFIG_TARGET_FILE_ABSOLUTE_PATH}" + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/inittesting.sh" "${PLASMOID_CONFIG_TARGET_FILE_ABSOLUTE_PATH}" "${PLASMOID_FILES_BASE}" WORKING_DIRECTORY "${PLASMOID_TESTDIR}" ) diff --git a/plasmoid/cmake/templates/metadata.json.in b/plasmoid/cmake/templates/metadata.json.in new file mode 100644 index 0000000..b247948 --- /dev/null +++ b/plasmoid/cmake/templates/metadata.json.in @@ -0,0 +1,19 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [{"Name": "@META_APP_AUTHOR@"}], + "BugReportUrl": "@META_APP_BUGTRACKER_URL@", + "Category": "SystemServices", + "Description": "@META_APP_DESCRIPTION@", + "EnabledByDefault": false, + "Icon": "syncthingtray", + "Id": "@META_ID@", + "License": "@META_PROJECT_LICENSE@", + "Name": "Syncthing", + "Version": "@META_APP_VERSION@", + "Website": "@META_APP_URL@" + }, + "Keywords": "syncthing;sync;", + "X-Plasma-API": "declarativeappletscript", + "X-Plasma-MainScript": "ui/main.qml" +} diff --git a/plasmoid/lib/CMakeLists.txt b/plasmoid/lib/CMakeLists.txt index 849109d..1b48f84 100644 --- a/plasmoid/lib/CMakeLists.txt +++ b/plasmoid/lib/CMakeLists.txt @@ -34,6 +34,10 @@ use_syncthingwidgets() # link also explicitly against the following Qt modules list(APPEND ADDITIONAL_QT_MODULES Network Qml) +if (KF_MAJOR_VERSION GREATER_EQUAL 6) + set(Config_MODULE_TARGETS ${KF_PACKAGE_PREFIX}::ConfigCore) + list(APPEND ADDITIONAL_KF_MODULES Config) +endif () list(APPEND ADDITIONAL_KF_MODULES Plasma) include(BasicConfig) @@ -55,9 +59,16 @@ set(META_PROJECT_LICENSE "${META_PROJECT_LICENSE}" PARENT_SCOPE) -# what ever this does, it is done -kcoreaddons_desktop_to_json("${META_TARGET_NAME}" "${PLASMOID_CONFIG_TARGET_FILE}" DESKTOP_TO_JSON_OUTPUT_DIR - "${PLASMOID_PACKAGE_DIR}") +# convert meta-data file to JSON +if (KF_MAJOR_VERSION LESS 6) + kcoreaddons_desktop_to_json("${META_TARGET_NAME}" "${PLASMOID_CONFIG_TARGET_FILE}" DESKTOP_TO_JSON_OUTPUT_DIR + "${PLASMOID_PACKAGE_DIR}") +endif () + +# set the library prefix so it doesn't start with "lib" and is rather prefixed with "martchus." +if (KF_MAJOR_VERSION GREATER_EQUAL 6) + set_target_properties(${META_TARGET_NAME} PROPERTIES PREFIX "martchus.") +endif () # install appstream file add_appstream_file() diff --git a/plasmoid/lib/syncthingapplet.cpp b/plasmoid/lib/syncthingapplet.cpp index 955a2c6..0120b88 100644 --- a/plasmoid/lib/syncthingapplet.cpp +++ b/plasmoid/lib/syncthingapplet.cpp @@ -69,7 +69,11 @@ static inline QPalette paletteFromTheme(const Plasma::Theme &theme) } SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data) +#if PLASMA_VERSION >= QT_VERSION_CHECK(5, 240, 0) + : Applet(parent, KPluginMetaData(), data) +#else : Applet(parent, data) +#endif , m_faUrl(QStringLiteral("image://fa/")) , m_iconManager(IconManager::instance(&m_palette)) , m_aboutDlg(nullptr) @@ -678,6 +682,12 @@ void SyncthingApplet::handleSystemdStatusChanged() } // namespace Plasmoid +#if PLASMA_VERSION >= QT_VERSION_CHECK(5, 240, 0) +namespace Plasmoid { +K_PLUGIN_CLASS(SyncthingApplet) +} +#else K_EXPORT_PLASMA_APPLET_WITH_JSON(syncthing, Plasmoid::SyncthingApplet, "metadata.json") +#endif #include "syncthingapplet.moc" diff --git a/plasmoid/package/contents/ui/CompactRepresentation.qml b/plasmoid/package5/contents/ui/CompactRepresentation.qml similarity index 100% rename from plasmoid/package/contents/ui/CompactRepresentation.qml rename to plasmoid/package5/contents/ui/CompactRepresentation.qml diff --git a/plasmoid/package/contents/ui/DetailItem.qml b/plasmoid/package5/contents/ui/DetailItem.qml similarity index 100% rename from plasmoid/package/contents/ui/DetailItem.qml rename to plasmoid/package5/contents/ui/DetailItem.qml diff --git a/plasmoid/package/contents/ui/DetailView.qml b/plasmoid/package5/contents/ui/DetailView.qml similarity index 100% rename from plasmoid/package/contents/ui/DetailView.qml rename to plasmoid/package5/contents/ui/DetailView.qml diff --git a/plasmoid/package/contents/ui/DevicesPage.qml b/plasmoid/package5/contents/ui/DevicesPage.qml similarity index 100% rename from plasmoid/package/contents/ui/DevicesPage.qml rename to plasmoid/package5/contents/ui/DevicesPage.qml diff --git a/plasmoid/package/contents/ui/DirectoriesPage.qml b/plasmoid/package5/contents/ui/DirectoriesPage.qml similarity index 100% rename from plasmoid/package/contents/ui/DirectoriesPage.qml rename to plasmoid/package5/contents/ui/DirectoriesPage.qml diff --git a/plasmoid/package/contents/ui/DownloadsPage.qml b/plasmoid/package5/contents/ui/DownloadsPage.qml similarity index 100% rename from plasmoid/package/contents/ui/DownloadsPage.qml rename to plasmoid/package5/contents/ui/DownloadsPage.qml diff --git a/plasmoid/package/contents/ui/FullRepresentation.qml b/plasmoid/package5/contents/ui/FullRepresentation.qml similarity index 99% rename from plasmoid/package/contents/ui/FullRepresentation.qml rename to plasmoid/package5/contents/ui/FullRepresentation.qml index 27dc12f..c1b8846 100644 --- a/plasmoid/package/contents/ui/FullRepresentation.qml +++ b/plasmoid/package5/contents/ui/FullRepresentation.qml @@ -95,7 +95,6 @@ PlasmaExtras.Representation { id: searchButton anchors.right: mainLayout.right anchors.rightMargin: PlasmaCore.Units.smallSpacing * 2 - anchors.verticalCenter: infoLayout.verticalCenter icon.source: plasmoid.nativeInterface.faUrl + "search" width: PlasmaCore.Units.iconSizes.smallMedium height: width diff --git a/plasmoid/package/contents/ui/IconLabel.qml b/plasmoid/package5/contents/ui/IconLabel.qml similarity index 100% rename from plasmoid/package/contents/ui/IconLabel.qml rename to plasmoid/package5/contents/ui/IconLabel.qml diff --git a/plasmoid/package/contents/ui/RecentChangesPage.qml b/plasmoid/package5/contents/ui/RecentChangesPage.qml similarity index 100% rename from plasmoid/package/contents/ui/RecentChangesPage.qml rename to plasmoid/package5/contents/ui/RecentChangesPage.qml diff --git a/plasmoid/package/contents/ui/StatisticsView.qml b/plasmoid/package5/contents/ui/StatisticsView.qml similarity index 100% rename from plasmoid/package/contents/ui/StatisticsView.qml rename to plasmoid/package5/contents/ui/StatisticsView.qml diff --git a/plasmoid/package/contents/ui/TabButton.qml b/plasmoid/package5/contents/ui/TabButton.qml similarity index 100% rename from plasmoid/package/contents/ui/TabButton.qml rename to plasmoid/package5/contents/ui/TabButton.qml diff --git a/plasmoid/package/contents/ui/TinyButton.qml b/plasmoid/package5/contents/ui/TinyButton.qml similarity index 100% rename from plasmoid/package/contents/ui/TinyButton.qml rename to plasmoid/package5/contents/ui/TinyButton.qml diff --git a/plasmoid/package/contents/ui/ToolBar.qml b/plasmoid/package5/contents/ui/ToolBar.qml similarity index 100% rename from plasmoid/package/contents/ui/ToolBar.qml rename to plasmoid/package5/contents/ui/ToolBar.qml diff --git a/plasmoid/package/contents/ui/ToolButton.qml b/plasmoid/package5/contents/ui/ToolButton.qml similarity index 100% rename from plasmoid/package/contents/ui/ToolButton.qml rename to plasmoid/package5/contents/ui/ToolButton.qml diff --git a/plasmoid/package/contents/ui/ToolTipTrigger.qml b/plasmoid/package5/contents/ui/ToolTipTrigger.qml similarity index 100% rename from plasmoid/package/contents/ui/ToolTipTrigger.qml rename to plasmoid/package5/contents/ui/ToolTipTrigger.qml diff --git a/plasmoid/package/contents/ui/ToolTipView.qml b/plasmoid/package5/contents/ui/ToolTipView.qml similarity index 100% rename from plasmoid/package/contents/ui/ToolTipView.qml rename to plasmoid/package5/contents/ui/ToolTipView.qml diff --git a/plasmoid/package/contents/ui/TopLevelItem.qml b/plasmoid/package5/contents/ui/TopLevelItem.qml similarity index 100% rename from plasmoid/package/contents/ui/TopLevelItem.qml rename to plasmoid/package5/contents/ui/TopLevelItem.qml diff --git a/plasmoid/package/contents/ui/TopLevelView.qml b/plasmoid/package5/contents/ui/TopLevelView.qml similarity index 100% rename from plasmoid/package/contents/ui/TopLevelView.qml rename to plasmoid/package5/contents/ui/TopLevelView.qml diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package5/contents/ui/main.qml similarity index 100% rename from plasmoid/package/contents/ui/main.qml rename to plasmoid/package5/contents/ui/main.qml diff --git a/plasmoid/package6/contents/ui/CompactRepresentation.qml b/plasmoid/package6/contents/ui/CompactRepresentation.qml new file mode 100644 index 0000000..6c9b0f2 --- /dev/null +++ b/plasmoid/package6/contents/ui/CompactRepresentation.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 +import org.kde.plasma.plasmoid 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore + +MouseArea { + Layout.fillWidth: false + hoverEnabled: true + onClicked: plasmoid.expanded = !plasmoid.expanded + + PlasmaCore.IconItem { + id: icon + anchors.fill: parent + source: plasmoid.statusIcon + active: parent.containsMouse + } +} diff --git a/plasmoid/package6/contents/ui/DetailItem.qml b/plasmoid/package6/contents/ui/DetailItem.qml new file mode 100644 index 0000000..4f388fc --- /dev/null +++ b/plasmoid/package6/contents/ui/DetailItem.qml @@ -0,0 +1,50 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.1 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.kirigami 2.20 as Kirigami + +Item { + id: detailItem + + property string detailName: name ? name : "" + property string detailValue: detail ? detail : "" + + width: detailRow.implicitWidth + height: detailRow.implicitHeight + + RowLayout { + id: detailRow + width: parent.width + + PlasmaCore.IconItem { + source: detailIcon + Layout.leftMargin: Kirigami.Units.iconSizes.small * 1.1 + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + opacity: 0.8 + } + PlasmaComponents3.Label { + Layout.preferredWidth: 100 + text: detailName + font.weight: Font.DemiBold + } + PlasmaComponents3.Label { + Layout.leftMargin: theme.defaultFont.pointSize * 0.9 + Layout.fillWidth: true + text: detailValue + elide: Text.ElideRight + horizontalAlignment: Qt.AlignRight + } + } + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: { + var view = detailItem.ListView.view + var coordinates = mapToItem(view, mouseX, mouseY) + view.showContextMenu(detailItem, coordinates.x, coordinates.y) + } + } +} diff --git a/plasmoid/package6/contents/ui/DetailView.qml b/plasmoid/package6/contents/ui/DetailView.qml new file mode 100644 index 0000000..c183def --- /dev/null +++ b/plasmoid/package6/contents/ui/DetailView.qml @@ -0,0 +1,29 @@ +import QtQuick 2.7 +import org.kde.plasma.extras 2.0 as PlasmaExtras + +ListView { + id: detailView + property DetailItem contextMenuItem: null + currentIndex: -1 + interactive: false + height: contentHeight + + PlasmaExtras.Menu { + id: contextMenu + PlasmaExtras.MenuItem { + text: qsTr('Copy value') + icon: "edit-copy" + onClicked: { + var item = detailView.contextMenuItem + if (item) { + plasmoid.copyToClipboard(item.detailValue) + } + } + } + } + + function showContextMenu(item, x, y) { + contextMenuItem = item + contextMenu.open(x, y) + } +} diff --git a/plasmoid/package6/contents/ui/DevicesPage.qml b/plasmoid/package6/contents/ui/DevicesPage.qml new file mode 100644 index 0000000..4f6f2a1 --- /dev/null +++ b/plasmoid/package6/contents/ui/DevicesPage.qml @@ -0,0 +1,125 @@ +import QtQuick 2.3 +import QtQuick.Layouts 1.1 +import QtQml.Models 2.2 +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.kirigami 2.20 as Kirigami + +Item { + property alias view: deviceView + objectName: "DevicesPage" + + PlasmaComponents3.ScrollView { + anchors.fill: parent + + // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 + PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff + + contentItem: TopLevelView { + id: deviceView + model: plasmoid.sortFilterDevModel + + delegate: TopLevelItem { + id: item + width: deviceView.effectiveWidth() + readonly property string devName: name + readonly property string devID: devId + property alias resumePauseButton: resumePauseButton + + ColumnLayout { + width: parent.width + spacing: 0 + + RowLayout { + Layout.fillWidth: true + + PlasmaCore.IconItem { + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + source: statusIcon + } + PlasmaComponents3.Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + elide: Text.ElideRight + text: name + } + RowLayout { + id: toolButtonsLayout + spacing: 0 + PlasmaComponents3.Label { + height: implicitHeight + text: statusString + color: statusColor ? statusColor : PlasmaCore.ColorScope.textColor + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + } + Item { + width: 3 + } + TinyButton { + id: resumePauseButton + icon.source: plasmoid.faUrl + (paused ? "play" : "pause") + icon.cache: false + tooltip: paused ? qsTr("Resume") : qsTr("Pause") + enabled: !isOwnDevice + onClicked: { + paused ? plasmoid.connection.resumeDevice( + [devId]) : plasmoid.connection.pauseDevice( + [devId]) + } + } + } + } + + DetailView { + id: detailsView + visible: item.expanded + Layout.fillWidth: true + Layout.topMargin: 3 + + model: DelegateModel { + model: plasmoid.devModel + rootIndex: deviceView.model.mapToSource(deviceView.model.index(index, 0)) + delegate: DetailItem { + width: detailsView.width + } + } + } + } + } + + PlasmaExtras.Menu { + id: contextMenu + + function init(item) { + // use value for properties depending on paused state from buttons + resumePauseItem.text = item.resumePauseButton.tooltip + resumePauseItem.icon = item.resumePauseButton.icon + } + + PlasmaExtras.MenuItem { + text: qsTr("Copy name") + icon: "edit-copy" + onClicked: deviceView.copyCurrentItemData("devName") + } + PlasmaExtras.MenuItem { + text: qsTr("Copy ID") + icon: "edit-copy" + onClicked: deviceView.copyCurrentItemData("devID") + } + PlasmaExtras.MenuItem { + separator: true + } + PlasmaExtras.MenuItem { + id: resumePauseItem + text: qsTr("Pause") + icon: "media-playback-pause" + onClicked: deviceView.clickCurrentItemButton( + "resumePauseButton") + } + } + } + } +} diff --git a/plasmoid/package6/contents/ui/DirectoriesPage.qml b/plasmoid/package6/contents/ui/DirectoriesPage.qml new file mode 100644 index 0000000..40b9391 --- /dev/null +++ b/plasmoid/package6/contents/ui/DirectoriesPage.qml @@ -0,0 +1,186 @@ +import QtQuick 2.3 +import QtQuick.Layouts 1.1 +import QtQml.Models 2.2 +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.kirigami 2.20 as Kirigami + +ColumnLayout { + property alias view: directoryView + property alias filter: filter + objectName: "DirectoriesPage" + + PlasmaComponents3.TextField { + Layout.topMargin: Kirigami.Units.smallSpacing * 2 + Layout.leftMargin: Kirigami.Units.smallSpacing * 2 + Layout.rightMargin: Kirigami.Units.smallSpacing * 2 + 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) + } + + PlasmaComponents3.ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + + // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 + PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff + + contentItem: TopLevelView { + id: directoryView + model: plasmoid.sortFilterDirModel + + delegate: TopLevelItem { + id: item + width: directoryView.effectiveWidth() + readonly property string dirName: name + readonly property string dirPath: path + property alias errorsButton: errorsButton + property alias rescanButton: rescanButton + property alias resumePauseButton: resumePauseButton + property alias openButton: openButton + + ColumnLayout { + width: parent.width + spacing: 0 + + RowLayout { + id: itemSummary + Layout.fillWidth: true + + PlasmaCore.IconItem { + Layout.preferredWidth: units.iconSizes.small + Layout.preferredHeight: units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + source: statusIcon + } + PlasmaComponents3.Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + elide: Text.ElideRight + text: name + } + RowLayout { + id: toolButtonsLayout + spacing: 0 + + PlasmaComponents3.Label { + height: implicitHeight + text: statusString + color: statusColor ? statusColor : PlasmaCore.ColorScope.textColor + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + } + Item { + width: units.smallSpacing + } + TinyButton { + id: errorsButton + icon.source: plasmoid.faUrl + "exclamation-triangle" + tooltip: qsTr("Show errors") + visible: pullErrorCount > 0 + onClicked: { + plasmoid.showDirectoryErrors( + dirId) + plasmoid.expanded = false + } + } + TinyButton { + id: rescanButton + icon.source: plasmoid.faUrl + "refresh" + tooltip: qsTr("Rescan") + enabled: !paused + onClicked: plasmoid.connection.rescan( + dirId) + } + TinyButton { + id: resumePauseButton + icon.source: plasmoid.faUrl + (paused ? "play" : "pause") + tooltip: paused ? qsTr("Resume") : qsTr("Pause") + onClicked: { + paused ? plasmoid.connection.resumeDirectories( + [dirId]) : plasmoid.connection.pauseDirectories( + [dirId]) + } + } + TinyButton { + id: openButton + icon.source: plasmoid.faUrl + "folder" + tooltip: qsTr("Open in file browser") + onClicked: { + Qt.openUrlExternally(plasmoid.substituteTilde(path)) + plasmoid.expanded = false + } + } + } + } + + DetailView { + id: detailsView + visible: item.expanded + Layout.fillWidth: true + Layout.topMargin: 3 + + model: DelegateModel { + model: plasmoid.dirModel + rootIndex: directoryView.model.mapToSource(directoryView.model.index(index, 0)) + delegate: DetailItem { + width: detailsView.width + } + } + } + } + } + + PlasmaExtras.Menu { + id: contextMenu + + function init(item) { + // use value for properties depending on paused state from buttons + rescanItem.enabled = item.rescanButton.enabled + resumePauseItem.text = item.resumePauseButton.tooltip + resumePauseItem.icon = item.resumePauseButton.icon + } + + PlasmaExtras.MenuItem { + text: qsTr("Copy label/ID") + icon: "edit-copy" + onClicked: directoryView.copyCurrentItemData("dirName") + } + PlasmaExtras.MenuItem { + text: qsTr("Copy path") + icon: "edit-copy" + onClicked: directoryView.copyCurrentItemData("dirPath") + } + PlasmaExtras.MenuItem { + separator: true + } + PlasmaExtras.MenuItem { + id: rescanItem + text: qsTr("Rescan") + icon: "view-refresh" + onClicked: directoryView.clickCurrentItemButton( + "rescanButton") + } + PlasmaExtras.MenuItem { + id: resumePauseItem + text: qsTr("Pause") + icon: "media-playback-pause" + onClicked: directoryView.clickCurrentItemButton( + "resumePauseButton") + } + PlasmaExtras.MenuItem { + id: openItem + text: qsTr("Open in file browser") + icon: "folder" + onClicked: directoryView.clickCurrentItemButton( + "openButton") + } + } + } + } +} diff --git a/plasmoid/package6/contents/ui/DownloadsPage.qml b/plasmoid/package6/contents/ui/DownloadsPage.qml new file mode 100644 index 0000000..c12c624 --- /dev/null +++ b/plasmoid/package6/contents/ui/DownloadsPage.qml @@ -0,0 +1,155 @@ +import QtQuick 2.3 +import QtQuick.Layouts 1.1 +import QtQml.Models 2.2 +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.kirigami 2.20 as Kirigami + +Item { + property alias view: downloadView + objectName: "DownloadsPage" + + PlasmaComponents3.ScrollView { + anchors.fill: parent + + // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 + PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff + + contentItem: TopLevelView { + id: downloadView + model: plasmoid.downloadModel + + delegate: TopLevelItem { + id: item + width: downloadView.effectiveWidth() + readonly property string downloadName: name + property alias openButton: openButton + + ColumnLayout { + width: parent.width + spacing: 0 + + RowLayout { + id: itemSummary + Layout.fillWidth: true + + RowLayout { + spacing: units.smallSpacing + PlasmaComponents3.Label { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + elide: Text.ElideRight + text: name ? name : "?" + } + } + PlasmaComponents3.ProgressBar { + Layout.fillWidth: true + Layout.fillHeight: true + from: 0.0 + to: 100.0 + value: percentage ? percentage : 0.0 + } + RowLayout { + id: toolButtonsLayout + spacing: 0 + + PlasmaComponents3.Label { + height: implicitHeight + text: progressLabel ? progressLabel : "" + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + } + Item { + width: 3 + } + TinyButton { + id: openButton + icon.source: plasmoid.faUrl + "folder" + tooltip: qsTr("Open in file browser") + enabled: path !== undefined + onClicked: { + Qt.openUrlExternally(path) + plasmoid.expanded = false + } + } + } + } + + DetailView { + id: detailsView + visible: item.expanded + Layout.fillWidth: true + + model: DelegateModel { + model: plasmoid.downloadModel + rootIndex: detailsView.model.modelIndex(index) + delegate: RowLayout { + width: detailsView.width + + PlasmaCore.IconItem { + Layout.preferredWidth: Kirigami.Units.iconSizes.medium + Layout.preferredHeight: Kirigami.Units.iconSizes.medium + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + source: fileIcon + } + ColumnLayout { + spacing: 0 + Layout.fillWidth: true + RowLayout { + spacing: Kirigami.Units.smallSpacing + Layout.fillWidth: true + PlasmaComponents3.Label { + Layout.fillWidth: true + text: name + font.pointSize: theme.defaultFont.pointSize * 0.8 + elide: Text.ElideRight + } + PlasmaComponents3.Label { + text: progressLabel + font.pointSize: theme.defaultFont.pointSize * 0.8 + elide: Text.ElideRight + } + } + PlasmaComponents3.ProgressBar { + Layout.fillWidth: true + Layout.preferredHeight: 8 + Layout.topMargin: 0 + from: 0.0 + to: 100.0 + value: percentage + } + } + TinyButton { + icon.source: plasmoid.faUrl + "folder" + tooltip: qsTr("Open in file browser") + onClicked: { + Qt.openUrlExternally(path + "/..") + plasmoid.expanded = false + } + } + } + } + } + } + } + + PlasmaExtras.Menu { + id: contextMenu + + PlasmaExtras.MenuItem { + text: qsTr("Copy label/ID") + icon: "edit-copy" + onClicked: downloadView.copyCurrentItemData("downloadName") + } + PlasmaExtras.MenuItem { + separator: true + } + PlasmaExtras.MenuItem { + id: openItem + text: qsTr("Open in file browser") + icon: "folder" + onClicked: downloadView.clickCurrentItemButton("openButton") + } + } + } + } +} diff --git a/plasmoid/package6/contents/ui/FullRepresentation.qml b/plasmoid/package6/contents/ui/FullRepresentation.qml new file mode 100644 index 0000000..900074d --- /dev/null +++ b/plasmoid/package6/contents/ui/FullRepresentation.qml @@ -0,0 +1,303 @@ +import QtQml 2.2 +import QtQuick 2.8 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.15 as QQ2 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.kirigami 2.20 as Kirigami + +PlasmaExtras.Representation { + // disable margins as they don't look good together with the scroll view + // note: Would be collapsed automatically if the scroll view was the immediate content item. + collapseMarginsHint: true + + // header ("toolbar" with buttons and combo box) and footer ("tabbar") + header: PlasmaExtras.PlasmoidHeading { + ToolBar { + id: toolbar + width: parent.width + } + } + footer: PlasmaExtras.PlasmoidHeading { + spacing: 0 + topPadding: 0 + height: Kirigami.Units.iconSizes.medium + PlasmaComponents3.TabBar { + id: tabBar + readonly property double buttonWidth: parent.width / count + position: PlasmaComponents3.TabBar.Footer + Layout.fillWidth: true + Layout.fillHeight: true + TabButton { + id: dirsTabButton + text: qsTr("Directories") + icon.source: plasmoid.faUrl + "folder" + width: tabBar.buttonWidth + } + TabButton { + id: devsTabButton + text: qsTr("Devices") + icon.source: plasmoid.faUrl + "sitemap" + width: tabBar.buttonWidth + } + TabButton { + id: downloadsTabButton + text: qsTr("Downloads") + icon.source: plasmoid.faUrl + "download" + width: tabBar.buttonWidth + } + TabButton { + id: recentChangesTabButton + text: qsTr("History") + icon.source: plasmoid.faUrl + "history" + width: tabBar.buttonWidth + } + } + } + + // 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 + function clickCurrentItemButton(buttonName) { + findCurrentPage().view.clickCurrentItemButton(buttonName) + } + Shortcut { + sequence: "Ctrl+R" + onActivated: clickCurrentItemButton("rescanButton") + } + Shortcut { + sequence: "Ctrl+P" + onActivated: clickCurrentItemButton("resumePauseButton") + } + Shortcut { + sequence: "Ctrl+O" + onActivated: clickCurrentItemButton("openButton") + } + + // main contents + FocusScope { + anchors.fill: parent + anchors.topMargin: Kirigami.Units.smallSpacing * 2 + + TinyButton { + id: searchButton + anchors.right: mainLayout.right + anchors.rightMargin: Kirigami.Units.smallSpacing * 2 + icon.source: plasmoid.faUrl + "search" + width: Kirigami.Units.iconSizes.smallMedium + height: width + 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 = "" + } + } + } + + ColumnLayout { + id: mainLayout + anchors.fill: parent + spacing: 0 + + // ensure keyboard events can be received after initialization + Component.onCompleted: forceActiveFocus() + + // define custom key handling for switching tabs, selecting items and filtering + 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() + } + Keys.onPressed: function(event) { + // note: event only received after clicking the tab buttons in plasmoidviewer + // 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 + findCurrentPage().view.decrementCurrentIndex() + break + case Qt.ShiftModifier: + // select previous connection + --plasmoid.currentConnectionConfigIndex + break + } + break + case Qt.Key_Down: + switch (event.modifiers) { + case Qt.NoModifier: + // select next item in current tab + findCurrentPage().view.incrementCurrentIndex() + break + case Qt.ShiftModifier: + // select previous connection + ++plasmoid.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.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 { + id: infoLayout + Layout.leftMargin: Kirigami.Units.smallSpacing * 2 + Layout.rightMargin: Kirigami.Units.smallSpacing * 2 + Layout.fillWidth: true + Layout.fillHeight: false + Layout.maximumWidth: parent.width + columns: 4 + rowSpacing: 1 + columnSpacing: 4 + + Image { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + height: 16 + fillMode: Image.PreserveAspectFit + source: plasmoid.faUrl + "globe" + cache: false + } + StatisticsView { + Layout.leftMargin: 4 + statistics: plasmoid.globalStatistics + context: qsTr("Global") + } + IconLabel { + Layout.leftMargin: 5 + iconSource: plasmoid.faUrl + "cloud-download" + iconOpacity: plasmoid.hasIncomingTraffic ? 1.0 : 0.5 + text: plasmoid.incomingTraffic + tooltip: qsTr("Global incoming traffic") + } + + Item { + Layout.fillWidth: true + Layout.rowSpan: 2 + } + Image { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + height: 16 + fillMode: Image.PreserveAspectFit + source: plasmoid.faUrl + "home" + cache: false + } + StatisticsView { + Layout.leftMargin: 4 + statistics: plasmoid.localStatistics + context: qsTr("Local") + } + IconLabel { + Layout.leftMargin: 5 + iconSource: plasmoid.faUrl + "cloud-upload" + iconOpacity: plasmoid.hasOutgoingTraffic ? 1.0 : 0.5 + text: plasmoid.outgoingTraffic + tooltip: qsTr("Global outgoing traffic") + } + } + + // tab content + StackLayout { + id: tabLayout + currentIndex: tabBar.currentIndex + Layout.fillWidth: true + Layout.fillHeight: true + DirectoriesPage { + id: directoriesPage + } + DevicesPage { + id: devicesPage + } + DownloadsPage { + id: downloadsPage + } + RecentChangesPage { + id: recentChangesPage + } + } + } + } +} diff --git a/plasmoid/package6/contents/ui/IconLabel.qml b/plasmoid/package6/contents/ui/IconLabel.qml new file mode 100644 index 0000000..66d6891 --- /dev/null +++ b/plasmoid/package6/contents/ui/IconLabel.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 3.0 as PlasmaComponents3 + +Item { + property alias iconSource: iconItem.source + property alias iconOpacity: iconItem.opacity + property alias text: label.text + property alias tooltip: tooltipTrigger.tooltip + + implicitWidth: layout.implicitWidth + implicitHeight: layout.implicitHeight + + RowLayout { + id: layout + + Image { + id: iconItem + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + height: 16 + cache: false + fillMode: Image.PreserveAspectFit + } + PlasmaComponents3.Label { + id: label + } + } + ToolTipTrigger { + id: tooltipTrigger + anchors.fill: layout + } +} diff --git a/plasmoid/package6/contents/ui/RecentChangesPage.qml b/plasmoid/package6/contents/ui/RecentChangesPage.qml new file mode 100644 index 0000000..b421d85 --- /dev/null +++ b/plasmoid/package6/contents/ui/RecentChangesPage.qml @@ -0,0 +1,127 @@ +import QtQuick 2.3 +import QtQuick.Layouts 1.1 +import QtQml.Models 2.2 +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.kirigami 2.20 as Kirigami + +Item { + property alias view: recentChangesView + objectName: "RecentChangesPage" + + PlasmaComponents3.ScrollView { + anchors.fill: parent + + // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 + PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff + + contentItem: TopLevelView { + id: recentChangesView + model: plasmoid.recentChangesModel + delegate: TopLevelItem { + width: recentChangesView.effectiveWidth() + ColumnLayout { + width: parent.width + spacing: 0 + RowLayout { + Layout.fillWidth: true + PlasmaCore.IconItem { + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + source: actionIcon + } + PlasmaComponents3.Label { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.fillWidth: true + elide: Text.ElideRight + text: extendedAction + } + Item { + width: Kirigami.Units.smallSpacing + } + Image { + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + height: parent.height + fillMode: Image.PreserveAspectFit + source: plasmoid.faUrl + "calendar" + } + PlasmaComponents3.Label { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + elide: Text.ElideRight + text: eventTime + } + Item { + width: Kirigami.Units.smallSpacing + } + Image { + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + height: parent.height + fillMode: Image.PreserveAspectFit + source: plasmoid.faUrl + "qrcode" + } + PlasmaComponents3.Label { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + elide: Text.ElideRight + text: modifiedBy + } + } + RowLayout { + Layout.fillWidth: true + Image { + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + height: parent.height + fillMode: Image.PreserveAspectFit + source: plasmoid.faUrl + (itemType === "file" ? "file-o" : "folder-o") + } + PlasmaComponents3.Label { + text: directoryId + ": " + font.weight: Font.DemiBold + } + PlasmaComponents3.Label { + Layout.fillWidth: true + text: path + elide: Text.ElideRight + } + } + } + + function copyPath() { + plasmoid.copyToClipboard(path) + } + function copyDeviceId() { + plasmoid.copyToClipboard(modifiedBy) + } + function copyFolderId() { + plasmoid.copyToClipboard(folderId) + } + } + + PlasmaExtras.Menu { + id: contextMenu + PlasmaExtras.MenuItem { + text: qsTr("Copy path") + icon: "edit-copy" + onClicked: recentChangesView.currentItem.copyPath() + } + PlasmaExtras.MenuItem { + text: qsTr("Copy device ID") + icon: "network-server-symbolic" + onClicked: recentChangesView.currentItem.copyDeviceId() + } + PlasmaExtras.MenuItem { + text: qsTr("Copy directory ID") + icon: "folder" + onClicked: recentChangesView.currentItem.copyFolderId() + } + } + } + } +} diff --git a/plasmoid/package6/contents/ui/StatisticsView.qml b/plasmoid/package6/contents/ui/StatisticsView.qml new file mode 100644 index 0000000..f80cfad --- /dev/null +++ b/plasmoid/package6/contents/ui/StatisticsView.qml @@ -0,0 +1,25 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.1 + +RowLayout { + id: rowLayout + property var statistics + property string context: "?" + + IconLabel { + iconSource: plasmoid.faUrl + "file-o" + text: statistics.files !== undefined ? statistics.files : "?" + tooltip: context + qsTr(" files") + } + IconLabel { + iconSource: plasmoid.faUrl + "folder-o" + text: statistics.dirs !== undefined ? statistics.dirs : "?" + tooltip: context + qsTr(" directories") + } + IconLabel { + iconSource: plasmoid.faUrl + "hdd-o" + text: statistics.bytes !== undefined ? plasmoid.formatFileSize( + statistics.bytes) : "?" + tooltip: context + qsTr(" size") + } +} diff --git a/plasmoid/package6/contents/ui/TabButton.qml b/plasmoid/package6/contents/ui/TabButton.qml new file mode 100644 index 0000000..2c28298 --- /dev/null +++ b/plasmoid/package6/contents/ui/TabButton.qml @@ -0,0 +1,48 @@ +import QtQuick 2.8 +import QtQuick.Templates 2.15 as T +import QtQuick.Layouts 1.1 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.kirigami 2.5 as Kirigami + +PlasmaComponents3.TabButton { + id: root + spacing: 0 + + property bool showTabText: plasmoid.showTabTexts + property string tooltip: "" + + PlasmaComponents3.ToolTip { + id: tooltip + text: root.tooltip !== "" ? root.tooltip : (root.showTabText ? "" : root.text) + visible: text !== "" && parent instanceof T.AbstractButton && (Kirigami.Settings.tabletMode ? parent.pressed : parent.hovered) + } + + contentItem: RowLayout { + spacing: label.visible ? Kirigami.Units.smallSpacing : 0 + PlasmaCore.ColorScope.inherit: true + width: parent.width + Item { + Layout.fillWidth: true + } + Image { + id: image + Layout.preferredHeight: height + source: root.icon.source + cache: false + height: Kirigami.Units.iconSizes.small + fillMode: Image.PreserveAspectFit + } + PlasmaComponents3.Label { + id: label + visible: text.length > 0 + text: root.showTabText ? root.text : "" + color: PlasmaCore.ColorScope.textColor + elide: Text.ElideRight + Layout.fillHeight: true + } + Item { + Layout.fillWidth: true + } + } +} diff --git a/plasmoid/package6/contents/ui/TinyButton.qml b/plasmoid/package6/contents/ui/TinyButton.qml new file mode 100644 index 0000000..73fae37 --- /dev/null +++ b/plasmoid/package6/contents/ui/TinyButton.qml @@ -0,0 +1,24 @@ +import QtQuick 2.8 +import QtQuick.Layouts 1.1 +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.kirigami 2.20 as Kirigami + +PlasmaComponents3.ToolButton { + id: root + + property alias tooltip: tooltip.text + + Layout.fillHeight: true + Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium + Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium + + PlasmaComponents3.ToolTip { + id: tooltip + } + contentItem: Image { + source: root.icon.source + cache: false + height: parent.height + fillMode: Image.PreserveAspectFit + } +} diff --git a/plasmoid/package6/contents/ui/ToolBar.qml b/plasmoid/package6/contents/ui/ToolBar.qml new file mode 100644 index 0000000..384ac70 --- /dev/null +++ b/plasmoid/package6/contents/ui/ToolBar.qml @@ -0,0 +1,280 @@ +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.kirigami 2.20 as Kirigami +import org.kde.kquickcontrolsaddons 2.0 +import martchus.syncthingplasmoid 0.6 as SyncthingPlasmoid + +RowLayout { + id: toolBar + Layout.fillWidth: true + spacing: Kirigami.Units.smallSpacing + Layout.minimumHeight: Kirigami.Units.iconSizes.medium + Layout.maximumHeight: Kirigami.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: plasmoid.faUrl + "refresh" + enabled: true + } + }, + State { + name: "connecting" + PropertyChanges { + target: connectButton + text: qsTr("Connecting …") + icon.source: plasmoid.faUrl + "refresh" + enabled: false + } + }, + State { + name: "paused" + PropertyChanges { + target: connectButton + text: qsTr("Resume") + icon.source: plasmoid.faUrl + "play" + enabled: true + } + }, + State { + name: "idle" + PropertyChanges { + target: connectButton + text: qsTr("Pause") + icon.source: plasmoid.faUrl + "pause" + enabled: true + } + } + ] + state: { + switch (plasmoid.connection.status) { + case SyncthingPlasmoid.Data.Disconnected: + return plasmoid.connection.connecting ? "connecting" : "disconnected" + case SyncthingPlasmoid.Data.Reconnecting: + return "connecting"; + case SyncthingPlasmoid.Data.Paused: + return "paused" + default: + return "idle" + } + } + onClicked: { + switch (plasmoid.connection.status) { + case SyncthingPlasmoid.Data.Disconnected: + plasmoid.connection.connect() + break + case SyncthingPlasmoid.Data.Reconnecting: + break + case SyncthingPlasmoid.Data.Paused: + plasmoid.connection.resumeAllDevs() + break + default: + plasmoid.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: plasmoid.faUrl + "stop" + } + PropertyChanges { + target: startStopToolTip + text: (plasmoid.service.userScope ? "systemctl --user stop " : "systemctl stop ") + + plasmoid.service.unitName + } + }, + State { + name: "stopped" + PropertyChanges { + target: startStopButton + visible: true + text: qsTr("Start") + icon.source: plasmoid.faUrl + "play" + } + PropertyChanges { + target: startStopToolTip + text: (plasmoid.service.userScope ? "systemctl --user start " : "systemctl start ") + + plasmoid.service.unitName + } + }, + State { + name: "irrelevant" + PropertyChanges { + target: startStopButton + visible: false + } + } + ] + state: { + // the systemd unit status is only relevant when connected to the local instance + if (!plasmoid.local || !plasmoid.startStopEnabled) { + return "irrelevant" + } + // show start/stop button only when the configured unit is available + var service = plasmoid.service + if (!service || !service.systemdAvailable) { + return "irrelevant" + } + return service.running ? "running" : "stopped" + } + onClicked: plasmoid.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.notificationsAvailable + onClicked: { + plasmoid.showNotificationsDialog() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("Show new notifications") + } + Shortcut { + sequence: "Ctrl+N" + onActivated: { + if (showNewNotifications.visible) { + showNewNotifications.clicked() + } + } + } + } + ToolButton { + icon.source: plasmoid.faUrl + "info" + visible: showExtraButtons + onClicked: { + plasmoid.showAboutDialog() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("About Syncthing Tray") + } + } + ToolButton { + id: showOwnIdButton + icon.source: plasmoid.faUrl + "qrcode" + visible: showExtraButtons + onClicked: { + plasmoid.showOwnDeviceId() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("Show own device ID") + } + Shortcut { + sequence: "Ctrl+I" + onActivated: showOwnIdButton.clicked() + } + } + ToolButton { + id: showLogButton + icon.source: plasmoid.faUrl + "file-text" + visible: showExtraButtons + onClicked: { + plasmoid.showLog() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("Show Syncthing log") + } + Shortcut { + sequence: "Ctrl+L" + onActivated: showLogButton.clicked() + } + } + ToolButton { + id: rescanAllDirsButton + icon.source: plasmoid.faUrl + "refresh" + onClicked: plasmoid.connection.rescanAllDirs() + PlasmaComponents3.ToolTip { + text: qsTr("Rescan all directories") + } + Shortcut { + sequence: "Ctrl+Shift+R" + onActivated: rescanAllDirsButton.clicked() + } + } + ToolButton { + id: settingsButton + icon.source: plasmoid.faUrl + "cog" + visible: showExtraButtons + onClicked: { + plasmoid.showSettingsDlg() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("Settings") + } + Shortcut { + sequence: "Ctrl+S" + onActivated: settingsButton.clicked() + } + } + ToolButton { + id: webUIButton + icon.source: plasmoid.faUrl + "syncthing" + onClicked: { + plasmoid.showWebUI() + plasmoid.expanded = false + } + PlasmaComponents3.ToolTip { + text: qsTr("Open Syncthing") + } + Shortcut { + sequence: "Ctrl+W" + onActivated: webUIButton.clicked() + } + } + PlasmaComponents3.ComboBox { + id: connectionConfigsMenu + model: plasmoid.connectionConfigNames + visible: plasmoid.connectionConfigNames.length > 1 + currentIndex: plasmoid.currentConnectionConfigIndex + onCurrentIndexChanged: plasmoid.currentConnectionConfigIndex = currentIndex + Layout.fillWidth: true + Layout.maximumWidth: implicitWidth + Shortcut { + sequence: "Ctrl+Shift+C" + onActivated: connectionConfigsMenu.popup() + } + } +} diff --git a/plasmoid/package6/contents/ui/ToolButton.qml b/plasmoid/package6/contents/ui/ToolButton.qml new file mode 100644 index 0000000..7578d9f --- /dev/null +++ b/plasmoid/package6/contents/ui/ToolButton.qml @@ -0,0 +1,32 @@ +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 +import org.kde.kirigami 2.20 as Kirigami + +PlasmaComponents3.ToolButton { + id: root + Layout.fillHeight: true + contentItem: Grid { + columns: 2 + columnSpacing: label.visible ? Kirigami.Units.smallSpacing : 0 + verticalItemAlignment: Grid.AlignVCenter + PlasmaCore.ColorScope.inherit: true + Image { + source: root.icon.source + cache: false + height: parent.height + fillMode: Image.PreserveAspectFit + } + PlasmaComponents3.Label { + id: label + visible: text.length > 0 + text: root.text + color: PlasmaCore.ColorScope.textColor + elide: Text.ElideRight + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} + diff --git a/plasmoid/package6/contents/ui/ToolTipTrigger.qml b/plasmoid/package6/contents/ui/ToolTipTrigger.qml new file mode 100644 index 0000000..6141503 --- /dev/null +++ b/plasmoid/package6/contents/ui/ToolTipTrigger.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 +import org.kde.plasma.components 3.0 as PlasmaComponents3 + +MouseArea { + property alias interval: timer.interval + property alias tooltip: tooltip.text + hoverEnabled: true + Timer { + id: timer + interval: 1000 + running: parent.containsMouse && parent.tooltip.length !== 0 + onTriggered: tooltip.open() + } + PlasmaComponents3.ToolTip { + id: tooltip + } +} diff --git a/plasmoid/package6/contents/ui/ToolTipView.qml b/plasmoid/package6/contents/ui/ToolTipView.qml new file mode 100644 index 0000000..4a72422 --- /dev/null +++ b/plasmoid/package6/contents/ui/ToolTipView.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 3.0 as PlasmaComponents3 +import org.kde.kirigami 2.20 as Kirigami + +RowLayout { + spacing: Kirigami.Units.smallSpacing + + PlasmaCore.IconItem { + id: tooltipIcon + source: plasmoid.statusIcon + Layout.alignment: Qt.AlignCenter + visible: true + implicitWidth: Kirigami.Units.iconSizes.large + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.leftMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + Layout.rightMargin: Kirigami.Units.smallSpacing + Layout.preferredWidth: implicitWidth + Layout.preferredHeight: implicitWidth + } + + ColumnLayout { + Kirigami.Heading { + id: tooltipMaintext + level: 3 + elide: Text.ElideRight + text: plasmoid.statusText + } + PlasmaComponents3.Label { + id: tooltipSubtext + text: plasmoid.additionalStatusText + opacity: 0.6 + } + } +} diff --git a/plasmoid/package6/contents/ui/TopLevelItem.qml b/plasmoid/package6/contents/ui/TopLevelItem.qml new file mode 100644 index 0000000..f63c02c --- /dev/null +++ b/plasmoid/package6/contents/ui/TopLevelItem.qml @@ -0,0 +1,116 @@ +// Based on PlasmaComponents.ListItem from Plasma 5.44.0 +// (Can't use PlasmaComponents.ListItem itself because creating a MouseArea filling +// the entire entire item for detecting right-mouse-click is not possible due to binding +// loop of width and height properties.) +import QtQuick 2.7 +import QtQuick.Layouts 1.1 +import org.kde.ksvg 1.0 as KSvg +import org.kde.kirigami 2.20 as Kirigami + +Item { + id: listItem + property bool expanded: false + default property alias content: paddingItem.data + + /** + * If true makes the list item look as checked or pressed. It has to be set + * from the code, it won't change by itself. + */ + //plasma extension + //always look pressed? + property bool checked: false + + /** + * If true the item will be a delegate for a section, so will look like a + * "title" for the otems under it. + */ + //is this to be used as section delegate? + property bool sectionDelegate: false + + /** + * type: bool + * True if the separator between items is visible + * default: true + */ + property bool separatorVisible: true + + width: parent ? parent.width : childrenRect.width + height: paddingItem.childrenRect.height + background.margins.top + background.margins.bottom + + implicitHeight: paddingItem.childrenRect.height + background.margins.top + + background.margins.bottom + + function activate(containsMouse) { + view.activate(containsMouse ? index : -1) + } + + KSvg.FrameSvgItem { + id: background + imagePath: "widgets/listitem" + prefix: (listItem.sectionDelegate ? "section" : (itemMouse.pressed + || listItem.checked) ? "pressed" : "normal") + + anchors.fill: parent + visible: listItem.ListView.view ? listItem.ListView.view.highlight === null : true + Behavior on opacity { + NumberAnimation { + duration: Kirigami.Units.longDuration + } + } + } + KSvg.SvgItem { + svg: KSvg.Svg { + imagePath: "widgets/listitem" + } + elementId: "separator" + anchors { + left: parent.left + right: parent.right + top: parent.top + } + height: naturalSize.height + visible: separatorVisible && (listItem.sectionDelegate + || (typeof (index) != "undefined" + && index > 0 && !listItem.checked + && !itemMouse.pressed)) + } + + MouseArea { + id: itemMouse + property bool changeBackgroundOnPress: !listItem.checked + && !listItem.sectionDelegate + anchors.fill: background + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: function(mouse) { + switch (mouse.button) { + case Qt.LeftButton: + expanded = !expanded + break + case Qt.RightButton: + var view = listItem.ListView.view + var coordinates = mapToItem(view, mouseX, mouseY) + view.showContextMenu(listItem, coordinates.x, coordinates.y) + break + } + } + + onContainsMouseChanged: { + listItem.activate(containsMouse) + } + + Item { + id: paddingItem + anchors { + fill: parent + leftMargin: background.margins.left + topMargin: background.margins.top + rightMargin: background.margins.right + bottomMargin: background.margins.bottom + } + } + } + + Accessible.role: Accessible.ListItem +} diff --git a/plasmoid/package6/contents/ui/TopLevelView.qml b/plasmoid/package6/contents/ui/TopLevelView.qml new file mode 100644 index 0000000..92996b3 --- /dev/null +++ b/plasmoid/package6/contents/ui/TopLevelView.qml @@ -0,0 +1,64 @@ +import QtQuick 2.7 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.kirigami 2.20 as Kirigami + +ListView { + boundsBehavior: Flickable.StopAtBounds + interactive: contentHeight > height + keyNavigationEnabled: true + keyNavigationWraps: true + currentIndex: -1 + + highlightMoveDuration: 0 + highlightResizeDuration: 0 + highlight: PlasmaExtras.Highlight { + } + + topMargin: Kirigami.Units.smallSpacing * 2 + bottomMargin: Kirigami.Units.smallSpacing * 2 + leftMargin: Kirigami.Units.smallSpacing * 2 + rightMargin: Kirigami.Units.smallSpacing * 2 + + function effectiveWidth() { + return width - leftMargin - rightMargin + } + + function activate(index) { + if (typeof contextMenu !== "undefined" + && contextMenu.status !== PlasmaExtras.DialogStatus.Closed) { + return + } + currentIndex = index + } + + function clickCurrentItemButton(buttonName) { + if (!currentItem) { + return + } + var button = currentItem[buttonName] + if (button && button.enabled) { + button.clicked() + } + } + + function copyCurrentItemData(fieldName) { + if (!currentItem) { + return + } + var data = currentItem[fieldName] + if (data) { + plasmoid.copyToClipboard(data) + } + } + + function showContextMenu(item, x, y) { + if (typeof contextMenu === "undefined") { + return + } + if (typeof contextMenu.init !== "undefined") { + contextMenu.init(item) + } + contextMenu.open(x, y) + } +} diff --git a/plasmoid/package6/contents/ui/main.qml b/plasmoid/package6/contents/ui/main.qml new file mode 100644 index 0000000..2b77427 --- /dev/null +++ b/plasmoid/package6/contents/ui/main.qml @@ -0,0 +1,77 @@ +import QtQuick 2.2 +import QtQuick.Layouts 1.1 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.plasmoid 2.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.kirigami 2.20 as Kirigami + +PlasmoidItem { + id: syncthingApplet + + // FIXME: adding title causes plasmawindowed to segfault + //Plasmoid.title: "Syncthing" + Plasmoid.icon: "syncthing" + // FIXME: not sure whether assigning switchWidth/switchHeight like this works + switchWidth: fullRepresentationItem ? fullRepresentationItem.Layout.minimumWidth : -1 + switchHeight: fullRepresentationItem ? fullRepresentationItem.Layout.minimumHeight : -1 + preferredRepresentation: fullRepresentation + compactRepresentation: CompactRepresentation {} + fullRepresentation: FullRepresentation { + Layout.minimumWidth: Kirigami.Units.gridUnit * Plasmoid.size.width + Layout.minimumHeight: Kirigami.Units.gridUnit * Plasmoid.size.height + } + toolTipMainText: Plasmoid.statusText + toolTipSubText: Plasmoid.additionalStatusText + toolTipItem: ToolTipView {} + + Plasmoid.contextualActions: [ + PlasmaCore.Action { + text: qsTr("Open Syncthing") + icon.name: "syncthing" + onTriggered: Plasmoid.showWebUI() + }, + PlasmaCore.Action { + text: qsTr("Rescan all directories") + icon.name: "folder-sync" + onTriggered: Plasmoid.connection.rescanAllDirs() + }, + PlasmaCore.Action { + text: qsTr("Show own device ID") + icon.name: "view-barcode-qr" + onTriggered: Plasmoid.showOwnDeviceId() + }, + PlasmaCore.Action { + text: qsTr("Restart Syncthing") + icon.name: "system-reboot" + onTriggered: Plasmoid.connection.restart() + }, + PlasmaCore.Action { + text: qsTr("Log") + icon.name: "text-x-generic" + onTriggered: Plasmoid.showLog() + }, + PlasmaCore.Action { + text: qsTr("Internal errors") + icon.name: "data-error" + onTriggered: Plasmoid.showInternalErrorsDialog() + visible: Plasmoid.hasInternalErrors + }, + PlasmaCore.Action { + text: qsTr("About") + icon.name: "help-about" + onTriggered: Plasmoid.showAboutDialog() + } + ] + + PlasmaCore.Action { + id: configureAction + text: qsTr("Settings") + icon.name: "configure" + onTriggered: Plasmoid.showSettingsDlg() + } + + Component.onCompleted: { + Plasmoid.initEngine(this) + Plasmoid.setInternalAction("configure", configureAction) + } +} diff --git a/plasmoid/scripts/inittesting.sh b/plasmoid/scripts/inittesting.sh index 4c58561..b59bd1c 100755 --- a/plasmoid/scripts/inittesting.sh +++ b/plasmoid/scripts/inittesting.sh @@ -5,7 +5,7 @@ source "$script_dir/settestenv.sh" # use the package dir within the source-tree so one does not need to run CMake again for updating # build-tree copy all the time -package_dir=$script_dir/../package +package_dir=$script_dir/../$2 # copy the generated desktop file back into the source-tree package dir so it can actually be used meta_data_file=$1 diff --git a/plasmoid/testing.md b/plasmoid/testing.md index 2e34ba7..ba3fcb3 100644 --- a/plasmoid/testing.md +++ b/plasmoid/testing.md @@ -1,16 +1,15 @@ -# Testing and debugging Plasma 5 plasmoid with Qt Creator - +# Testing and debugging Plasmoid for Plasma with Qt Creator The following instructions allow to test the Plasmoid by installing it in a test directory rather than the regular home to separate testing from production. -1. Build as usual, ensure `NO_PLASMOID` is turned off +1. Build as usual, ensure `NO_PLASMOID` is turned off. 2. Add build step to execute the custom target `init_plasmoid_testing` which will install the Plasmoid in a test directory which is `$CMAKE_BUILD_DIR/plasmoid-testing` by default (configurable via cache variable `PLASMOID_TESTDIR`, the sub directory - `plasmoid-testing` is not part of the variable) -3. Add new config for run in Qt Creator and set `bash` as executable + `plasmoid-testing` is not part of the variable). +3. Add new config for run in Qt Creator and set `bash` as executable. 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 specify `org.kde.plasma.systemtray` as applet to test how the Plasmoid looks like within the system tray plasmoid. @@ -21,12 +20,12 @@ rather than the regular home to separate testing from production. already take care of setting the environment. * The home directory is set in accordance with the directory used in step 2. but can be overridden by setting `TEST_HOME`; make sure that `TEST_HOME` and the CMake variable `PLASMOID_TESTDIR` are - set in accordance + set in accordance. * If not already set, `QT_PLUGIN_PATH` is set to `$CMAKE_CURRENT_BINARY_DIR/plasmoid/lib` which - should contain the plugin for the Plasmoid under `plasma/applets/libsyncthingplasmoid.so` - * Set `QT_DEBUG_PLUGINS` to 1 for verbose plugin detection -7. Ignore warning that executable is no debug build, it is sufficiant when - the plugin is a debug build (see next section for QML debugging) + should contain the plugin for the Plasmoid under `plasma/applets/libsyncthingplasmoid.so`. + * Set `QT_DEBUG_PLUGINS` to 1 for verbose plugin detection. +7. Ignore warning that executable is no debug build, it is sufficient when + the plugin is a debug build (see next section for QML debugging). ## Saving/restoring settings @@ -64,3 +63,18 @@ To create a debug build of `plasmoidviewer` manually: 3. Prepend the build directory containing the `plasmoidviewer` binary to the path variable in the build environment of Syncthing Tray. 4. Enable QML debugging in the *Run* section. + +# Testing against a development build of Plasma +1. Build the whole dependency chain up to `plasma-desktop` installing it under some custom prefix. + Note that `plasma-sdk` alone is not sufficient. +2. Then follow the usual steps but make sure you build Syncthing Tray against the custom KDE builds. + This is achieved the easiest by using the `debug-kde` CMake preset. This preset uses the environment + variable `KDE_INSTALL_DIR` which must point to the custom prefix used in step 1. +3. Source the `prefix.sh` script that should be present in the build directory of any KDE library + you built in step 1, e.g. `source kde/plasma-sdk/prefix.sh`. +4. When setting the environment one needs to be more careful to not override variables set in step 3. + It is the easiest to just start e.g. `plasmawindowed` from the shell: + ``` + QT_PLUGIN_PATH=$BUILD_DIR/syncthingtray/debug-kde/syncthingtray/plasmoid/lib:$QT_PLUGIN_PATH HOME=$BUILD_DIR/syncthingtray/debug-kde/plasmoid-testing kdeinstall/bin/plasmawindowed martchus.syncthingplasmoid-devel + ``` + * It would make sense to tweak `starttesting.sh` to be able to do the sourcing automatically.