From a3e87361dcd25c06f30998540ee605c56420e9df Mon Sep 17 00:00:00 2001 From: "Peter P. Lupo" Date: Tue, 12 May 2026 10:08:26 -0400 Subject: [PATCH 01/16] feat(wlx): Add KPart host "Universal Wrapper" plugin This commit introduces the kpart WLX plugin. It acts as a host for KDE KParts, effectively allowing Double Commander to leverage any installed KDE viewer (like Okular for PDFs or LibreOffice for docs) directly within the Quick View panel natively on Wayland/Qt6. Committed files: - Source code (src/) for KPart hosting logic - SDK headers (sdk/) - CMakeLists.txt for build configuration - README.md with screenshots - test.svg and screenshot assets (kpart_md.png, kpart_svg.png) - Integration into root build.sh for automated release packaging --- build.sh | 9 ++ wlx/kpart/CMakeLists.txt | 43 ++++++ wlx/kpart/README.md | 26 ++++ wlx/kpart/kpart_md.png | Bin 0 -> 128960 bytes wlx/kpart/kpart_svg.png | Bin 0 -> 187991 bytes wlx/kpart/sdk/common.h | 81 ++++++++++ wlx/kpart/sdk/wlxplugin.h | 75 +++++++++ wlx/kpart/src/kpartwidget.cpp | 281 ++++++++++++++++++++++++++++++++++ wlx/kpart/src/kpartwidget.h | 37 +++++ wlx/kpart/src/main.cpp | 130 ++++++++++++++++ 10 files changed, 682 insertions(+) create mode 100644 wlx/kpart/CMakeLists.txt create mode 100644 wlx/kpart/README.md create mode 100644 wlx/kpart/kpart_md.png create mode 100644 wlx/kpart/kpart_svg.png create mode 100644 wlx/kpart/sdk/common.h create mode 100644 wlx/kpart/sdk/wlxplugin.h create mode 100644 wlx/kpart/src/kpartwidget.cpp create mode 100644 wlx/kpart/src/kpartwidget.h create mode 100644 wlx/kpart/src/main.cpp diff --git a/build.sh b/build.sh index 55f0030..ee191da 100755 --- a/build.sh +++ b/build.sh @@ -66,6 +66,15 @@ install -m 644 wdx/mediainfo/luajit/*.lua release/wdx/mediainfo/ install -m 644 wdx/translitwdx/translitwdx.lua release/wdx/translitwdx/ install -m 644 wdx/translitwdx/readme.txt release/wdx/translitwdx/ + +# kpart +mkdir -p release/wlx/kpart +mkdir -p wlx/kpart/build +(cd wlx/kpart/build && cmake .. && make) +install -m 644 wlx/kpart/build/kpart_host.wlx release/wlx/kpart/ +install -m 644 wlx/kpart/*.md release/wlx/kpart/ +install -m 644 wlx/kpart/*.png release/wlx/kpart/ + pushd release tar -czpf ../plugins-$(date +%y.%m.%d)-$ARCH.tar.gz * popd diff --git a/wlx/kpart/CMakeLists.txt b/wlx/kpart/CMakeLists.txt new file mode 100644 index 0000000..2cc2d79 --- /dev/null +++ b/wlx/kpart/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.16) +project(kpart_host LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) + +# Double Commander plugin settings +set(CMAKE_SHARED_LIBRARY_PREFIX "") +if(UNIX) + set(CMAKE_SHARED_LIBRARY_SUFFIX ".wlx") +endif() + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) +find_package(KF6Parts REQUIRED) +find_package(KF6KIO REQUIRED) +find_package(KF6CoreAddons REQUIRED) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/sdk +) + +add_library(kpart_host SHARED + src/main.cpp + src/kpartwidget.cpp +) + +target_link_libraries(kpart_host + PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets + KF6::Parts + KF6::KIOFileWidgets + KF6::CoreAddons +) + +# Use ECM for standard installation paths and KDE integration +find_package(ECM 5.80.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) diff --git a/wlx/kpart/README.md b/wlx/kpart/README.md new file mode 100644 index 0000000..d87dc37 --- /dev/null +++ b/wlx/kpart/README.md @@ -0,0 +1,26 @@ +# KPart Host Double Commander Plugin + +A "Universal KDE Wrapper" WLX (Lister) plugin for Double Commander. This plugin acts as a host for KDE KParts, allowing Double Commander to view any file type supported by a KDE application (like Okular for PDFs or LibreOffice for documents) directly in the Quick View panel. + +![Markdown Screenshot](kpart_md.png) +![SVG Screenshot](kpart_svg.png) + +## Features +- Dynamic MIME-type detection using `QMimeDatabase`. +- Automatic loading of the best available KDE KPart for the file type. +- Native Wayland/Qt6 embedding via in-process KPart hosting. + +## Dependencies +- **Qt6**: Core, Gui, Widgets +- **KDE Frameworks 6 (KF6)**: Parts, KIO, CoreAddons +- **CMake**: `cmake` and `extra-cmake-modules` + +## Compilation +```bash +mkdir build +cd build +cmake .. +make +``` + +The build will produce `kpart_host.wlx`. diff --git a/wlx/kpart/kpart_md.png b/wlx/kpart/kpart_md.png new file mode 100644 index 0000000000000000000000000000000000000000..14a14af88bd8106dc637b2bedd962890e610f01e GIT binary patch literal 128960 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