6.6 KiB
qwfassoc (suite)
A Qt Widgets based GUI for the wfassoc library, split into a reusable shared library and a small standalone executable that exercises it.
The project is organized as two CMake subprojects:
qwfassoc/ Parent directory (this README)
├── CMakeLists.txt Top-level CMake; add_subdirectory's both
│ subprojects and finds Qt, wfassoc, toml11
├── cmake/
│ ├── Findwfassoc.cmake Verbatim copy of wfassoc's Find module
│ └── README.md Provenance notes for the copy
├── qwfassoc/ Shared library subproject
│ ├── CMakeLists.txt
│ ├── i18n/
│ │ └── qwfassoc_zh_CN.ts Empty placeholder translation file
│ └── src/
│ ├── qwfassoc_global.h QWFASSOC_EXPORT macro
│ ├── scope.h Shared TargetScope enum
│ ├── manifest.h Manifest data struct (no TOML dependency)
│ ├── icon_utils.h/.cpp wfassocpp::HICON -> QPixmap conversion
│ ├── application_widget.h/.cpp/.ui
│ │ Install / uninstall widget
│ └── association_widget.h/.cpp/.ui
│ File associations widget
└── qwfassoc-standalone/ Executable subproject
├── CMakeLists.txt
├── i18n/
│ └── qwfassoc-standalone_zh_CN.ts
│ Empty placeholder translation file
└── src/
├── main.cpp Entry point, CLI parsing, translator loading
├── main_window.h/.cpp/.ui
│ QDialog hosting the two widgets in a tab widget
└── manifest_parser.h/.cpp
TOML -> Manifest, Manifest -> Schema
Subprojects at a glance
qwfassoc (shared library)
Exports two reusable widgets that wrap wfassoc:
qwfassoc::ApplicationWidget— install / uninstall the program in the configured scope.qwfassoc::AssociationWidget— stage and apply per-extension link / unlink operations.
Both widgets follow the two-phase initialization pattern expected by Qt
Designer promoted widgets: the constructor only takes a QWidget* parent and
leaves the widget disabled. A setConfig(Config) method injects the
wfassocpp::Program pointer and TargetScope (and, for the association
widget, whether the OK/Cancel buttons are visible). Each widget also exposes:
- a
refresh()slot that re-queries the live wfassoc state, intended to be called by the host when another component has mutated the registry; - a
changed()signal emitted whenever the widget itself mutates the registry (install / uninstall / apply); - (
AssociationWidgetonly) afinished(bool accepted)signal emitted when the user clicks OK (afterchanged()) or Cancel, so the host can close the dialog.
The library also exposes the plain qwfassoc::Manifest data struct and a
qwfassoc::icon_utils::fromHicon() helper, but the TOML parsing logic (which
depends on toml11) lives in the standalone executable.
qwfassoc-standalone (executable)
Reproduces the original tabbed wfassoc configurator by:
- parsing
-c/--manifest <path>and-f/--for <user|system>from the command line; - building a
wfassocpp::ProgramviaparseManifestFile+buildSchema; - hosting
ApplicationWidgetandAssociationWidgetinside aQTabWidgetin aMainWindowdialog; - wiring the widgets'
changed()andfinished()signals so that any registry mutation refreshes both pages and OK/Cancel drive the dialog's acceptance.
Requirements
- CMake 3.20 or newer (3.21+ recommended for
qt6_add_translations). - A C++17 compiler.
- Qt 6 with the
WidgetsandLinguistToolscomponents. - wfassoc, with
wfassoc_ROOTpointing at an installed tree (seecmake/Findwfassoc.cmakefor the expected directory layout). - toml11 — only required when building the standalone executable.
Building
cmake -S . -B build ^
-DCMAKE_PREFIX_PATH=C:\Qt\6.x.x\msvc2022_64 ^
-Dwfassoc_ROOT=C:\path\to\wfassoc\install ^
-Dtoml11_DIR=C:\path\to\toml11\share\toml11\cmake
cmake --build build --config Release
To skip the standalone executable (and the toml11 dependency):
cmake -S . -B build -DQWFASSOC_BUILD_STANDALONE=OFF ...
The standalone executable is build/qwfassoc-standalone/Release/qwfassoc-standalone.exe
(or similar, depending on the generator); the library is
build/qwfassoc/Release/qwfassoc.dll.
Running the standalone executable
| Short | Long | Meaning |
|---|---|---|
-c |
--manifest |
Path to the application manifest TOML file (see example/manifest/ppic.toml). |
-f |
--for |
Target scope: user or system. |
qwfassoc-standalone -c C:\path\to\ppic.toml -f user
Internationalization
Source strings are English and every user-facing string is wrapped in tr()
(in code) or is a plain <string> element in the .ui file (which uic
wraps in QCoreApplication::translate).
Each subproject ships its own empty placeholder .ts file under its
i18n/ directory and registers it with qt6_add_translations():
qwfassoc/i18n/qwfassoc_zh_CN.ts— covers the library widgets.qwfassoc-standalone/i18n/qwfassoc-standalone_zh_CN.ts— covers the executable-specific messages (CLI errors, tab titles, dialog window title, etc.).
At runtime, installTranslators() in qwfassoc-standalone/src/main.cpp
loads both .qm files for the user's preferred UI language from the
:/i18n/ resource prefix. Translators are expected to fill in the .ts
files; no actual translation work is performed by the build on its own.
Notes and Limitations
- "Self" detection in the file-association table is based on comparing the display name returned by wfassoc with the display name this program would use. Two programs sharing the exact same display name could therefore be confused.
- The system column in
AssociationWidgetis rendered disabled (usingQt::ItemIsSelectablewithoutQt::ItemIsEnabled) whenTargetScopeisUser; the cells stay visible but cannot be clicked. - All errors originating from wfassoc are surfaced through
QMessageBoxdialogs; fatal errors during startup cause the process to exit with a non-zero status code.