1
0
Files
wfassoc/example/qwfassoc/README.md

155 lines
6.6 KiB
Markdown
Raw Normal View History

2026-06-23 21:38:54 +08:00
# qwfassoc (suite)
2026-05-25 16:34:35 +08:00
2026-06-23 21:38:54 +08:00
A Qt Widgets based GUI for the [wfassoc](../../wfassoc) library, split into a
reusable shared library and a small standalone executable that exercises it.
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
The project is organized as two CMake subprojects:
2026-06-23 20:46:56 +08:00
```
2026-06-23 21:38:54 +08:00
qwfassoc/ Parent directory (this README)
├── CMakeLists.txt Top-level CMake; add_subdirectory's both
│ subprojects and finds Qt, wfassoc, toml11
2026-06-23 20:46:56 +08:00
├── cmake/
2026-06-23 21:38:54 +08:00
│ ├── 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
2026-06-23 20:46:56 +08:00
```
2026-06-23 21:38:54 +08:00
## 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);
* (`AssociationWidget` only) a `finished(bool accepted)` signal emitted when
the user clicks OK (after `changed()`) 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:
1. parsing `-c/--manifest <path>` and `-f/--for <user|system>` from the
command line;
2. building a `wfassocpp::Program` via `parseManifestFile` + `buildSchema`;
3. hosting `ApplicationWidget` and `AssociationWidget` inside a `QTabWidget`
in a `MainWindow` dialog;
4. wiring the widgets' `changed()` and `finished()` signals so that any
registry mutation refreshes both pages and OK/Cancel drive the dialog's
acceptance.
2026-06-23 20:46:56 +08:00
## Requirements
2026-06-23 21:38:54 +08:00
* **CMake** 3.20 or newer (3.21+ recommended for `qt6_add_translations`).
2026-06-23 20:46:56 +08:00
* A C++17 compiler.
2026-06-23 21:38:54 +08:00
* **Qt 6** with the `Widgets` and `LinguistTools` components.
* **wfassoc**, with `wfassoc_ROOT` pointing at an installed tree (see
2026-06-23 20:46:56 +08:00
[`cmake/Findwfassoc.cmake`](cmake/Findwfassoc.cmake) for the expected
directory layout).
2026-06-23 21:38:54 +08:00
* **toml11** — only required when building the standalone executable.
2026-06-23 20:46:56 +08:00
## Building
```bat
2026-06-23 21:38:54 +08:00
cmake -S . -B build ^
-DCMAKE_PREFIX_PATH=C:\Qt\6.x.x\msvc2022_64 ^
2026-06-23 20:46:56 +08:00
-Dwfassoc_ROOT=C:\path\to\wfassoc\install ^
-Dtoml11_DIR=C:\path\to\toml11\share\toml11\cmake
cmake --build build --config Release
```
2026-06-23 21:38:54 +08:00
To skip the standalone executable (and the toml11 dependency):
```bat
cmake -S . -B build -DQWFASSOC_BUILD_STANDALONE=OFF ...
```
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
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`.
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
## Running the standalone executable
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
| Short | Long | Meaning |
| ----- | ------------ | ------------------------------------------------------------------------ |
2026-06-23 20:46:56 +08:00
| `-c` | `--manifest` | Path to the application manifest TOML file (see [`example/manifest/ppic.toml`](../manifest/ppic.toml)). |
2026-06-23 21:38:54 +08:00
| `-f` | `--for` | Target scope: `user` or `system`. |
2026-06-23 20:46:56 +08:00
```bat
2026-06-23 21:38:54 +08:00
qwfassoc-standalone -c C:\path\to\ppic.toml -f user
2026-06-23 20:46:56 +08:00
```
## Internationalization
2026-06-23 21:38:54 +08:00
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`).
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
Each subproject ships its own empty placeholder `.ts` file under its
`i18n/` directory and registers it with `qt6_add_translations()`:
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
* `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.).
2026-06-23 20:46:56 +08:00
2026-06-23 21:38:54 +08:00
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.
2026-06-23 20:46:56 +08:00
## Notes and Limitations
2026-06-23 21:38:54 +08:00
* "Self" detection in the file-association table is based on comparing the
2026-06-23 20:46:56 +08:00
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.
2026-06-23 21:38:54 +08:00
* The system column in `AssociationWidget` is rendered disabled (using
`Qt::ItemIsSelectable` without `Qt::ItemIsEnabled`) when `TargetScope` is
`User`; the cells stay visible but cannot be clicked.
2026-06-23 20:46:56 +08:00
* All errors originating from wfassoc are surfaced through `QMessageBox`
dialogs; fatal errors during startup cause the process to exit with a
non-zero status code.