Plan clipboard text actions in app core
This commit is contained in:
@@ -440,6 +440,10 @@ Known local toolchain state:
|
|||||||
- `pano_cli plan-cursor-visibility` exposes `pp_app_core` cursor visibility
|
- `pano_cli plan-cursor-visibility` exposes `pp_app_core` cursor visibility
|
||||||
planning as JSON for hidden and visible states; live canvas cursor requests
|
planning as JSON for hidden and visible states; live canvas cursor requests
|
||||||
consume the same contract before retained desktop platform cursor bridges.
|
consume the same contract before retained desktop platform cursor bridges.
|
||||||
|
- `pano_cli plan-clipboard-read` and `pano_cli plan-clipboard-write` expose
|
||||||
|
`pp_app_core` clipboard text planning as JSON, including empty text writes;
|
||||||
|
live clipboard get/set requests consume the same contracts before retained
|
||||||
|
platform clipboard bridges.
|
||||||
- `pano_cli plan-cloud-upload` exposes `pp_app_core` cloud upload availability,
|
- `pano_cli plan-cloud-upload` exposes `pp_app_core` cloud upload availability,
|
||||||
new-document warning, publish prompt, and save-before-upload planning as JSON;
|
new-document warning, publish prompt, and save-before-upload planning as JSON;
|
||||||
the live cloud upload command consumes the same start contract before
|
the live cloud upload command consumes the same start contract before
|
||||||
@@ -474,7 +478,8 @@ Known local toolchain state:
|
|||||||
and non-empty picked-path callback planning, plus empty/non-empty display-file
|
and non-empty picked-path callback planning, plus empty/non-empty display-file
|
||||||
planning before platform picker/display callbacks, plus virtual keyboard
|
planning before platform picker/display callbacks, plus virtual keyboard
|
||||||
show/hide planning before platform keyboard callbacks, plus cursor visibility
|
show/hide planning before platform keyboard callbacks, plus cursor visibility
|
||||||
planning before platform cursor callbacks.
|
planning before platform cursor callbacks, plus clipboard read/write
|
||||||
|
planning before platform clipboard callbacks.
|
||||||
- `pp_app_core_document_cloud_tests` covers cloud upload no-canvas,
|
- `pp_app_core_document_cloud_tests` covers cloud upload no-canvas,
|
||||||
new-document warning, clean publish prompt, and dirty save-before-upload
|
new-document warning, clean publish prompt, and dirty save-before-upload
|
||||||
decisions, plus cloud browse no-canvas/show-browser and selected-download
|
decisions, plus cloud browse no-canvas/show-browser and selected-download
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ and validation command.
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Mouse/keyboard/touch/gestures/cursor | `App`, platform entrypoints | `pp_app_core`, `pp_platform_*`, app | Cursor visibility decision tests, synthetic event playback |
|
| Mouse/keyboard/touch/gestures/cursor | `App`, platform entrypoints | `pp_app_core`, `pp_platform_*`, app | Cursor visibility decision tests, synthetic event playback |
|
||||||
| Wacom pressure | `WacomTablet` | `pp_platform_windows` | Adapter smoke with fallback |
|
| Wacom pressure | `WacomTablet` | `pp_platform_windows` | Adapter smoke with fallback |
|
||||||
| Clipboard/file picker/share/display | `App` platform methods | `pp_app_core`, `pp_platform_*` | Share saved-path, picked-path, and display-file decision tests, platform smoke or mocked service |
|
| Clipboard/file picker/share/display | `App` platform methods | `pp_app_core`, `pp_platform_*` | Clipboard read/write, share saved-path, picked-path, and display-file decision tests, platform smoke or mocked service |
|
||||||
| Virtual keyboard | `App`, platform entrypoints | `pp_app_core`, `pp_platform_*` | Keyboard visibility decision tests, platform smoke |
|
| Virtual keyboard | `App`, platform entrypoints | `pp_app_core`, `pp_platform_*` | Keyboard visibility decision tests, platform smoke |
|
||||||
| OpenVR desktop | `HMD`, `Vive`, `app_vr` | `pp_platform_vr`, app | Compile gate and mocked pose tests |
|
| OpenVR desktop | `HMD`, `Vive`, `app_vr` | `pp_platform_vr`, app | Compile gate and mocked pose tests |
|
||||||
| Quest/OVR | Android Quest files | `pp_platform_android_quest` | Compile/package gate |
|
| Quest/OVR | Android Quest files | `pp_platform_android_quest` | Compile/package gate |
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
| DEBT-0013 | Open | Modernization | `pp_assets`, `pp_document`, `pano_cli inspect-project`, `pano_cli load-project`, and `pano_cli save-project` validate the fixed PPI header, thumbnail/body byte layout, generated multi-layer/multi-frame PPI writing with explicit layer opacity/blend/alpha-lock/visibility metadata, per-layer frame durations, metadata-only and targeted dirty-face-payload save/load round-trips, layer/frame index, dirty-face descriptors, dirty-face PNG payload metadata, asset-level RGBA PNG payload decoding, pure document-to-PPI export, CLI document export automation, file-writing document export automation, stroke-script-generated document payload export, and decoded pixel attachment to `pp_document`, but full legacy PPI round-trip parity is not yet extracted | Full PPI save parity requires staged extraction of legacy `Canvas` serialization and image/layer payload handling | `ctest --preset desktop-fast --build-config Debug`; `pp_assets_image_pixels_tests`; `pp_assets_ppi_header_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_inspect_project_layout_smoke`; `pano_cli_load_project_metadata_smoke`; `pano_cli_save_project_roundtrip_smoke`; `pano_cli_save_project_payload_roundtrip_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Full PPI load/save fixtures cover thumbnails, decoded layer face payloads attached to documents, frames, corrupt payloads, dirty-face payload saving, arbitrary legacy canvas payload/layout combinations, and legacy app round-trip compatibility |
|
| DEBT-0013 | Open | Modernization | `pp_assets`, `pp_document`, `pano_cli inspect-project`, `pano_cli load-project`, and `pano_cli save-project` validate the fixed PPI header, thumbnail/body byte layout, generated multi-layer/multi-frame PPI writing with explicit layer opacity/blend/alpha-lock/visibility metadata, per-layer frame durations, metadata-only and targeted dirty-face-payload save/load round-trips, layer/frame index, dirty-face descriptors, dirty-face PNG payload metadata, asset-level RGBA PNG payload decoding, pure document-to-PPI export, CLI document export automation, file-writing document export automation, stroke-script-generated document payload export, and decoded pixel attachment to `pp_document`, but full legacy PPI round-trip parity is not yet extracted | Full PPI save parity requires staged extraction of legacy `Canvas` serialization and image/layer payload handling | `ctest --preset desktop-fast --build-config Debug`; `pp_assets_image_pixels_tests`; `pp_assets_ppi_header_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_inspect_project_layout_smoke`; `pano_cli_load_project_metadata_smoke`; `pano_cli_save_project_roundtrip_smoke`; `pano_cli_save_project_payload_roundtrip_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Full PPI load/save fixtures cover thumbnails, decoded layer face payloads attached to documents, frames, corrupt payloads, dirty-face payload saving, arbitrary legacy canvas payload/layout combinations, and legacy app round-trip compatibility |
|
||||||
| DEBT-0014 | Open | Modernization | `windows-clangcl-asan` now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer | Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible | `cmake --fresh --preset windows-clangcl-asan`; `cmake --build --preset windows-clangcl-asan --target pp_foundation` | Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make `platform-build.ps1 -Presets windows-clangcl-asan` pass for the headless matrix |
|
| DEBT-0014 | Open | Modernization | `windows-clangcl-asan` now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer | Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible | `cmake --fresh --preset windows-clangcl-asan`; `cmake --build --preset windows-clangcl-asan --target pp_foundation` | Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make `platform-build.ps1 -Presets windows-clangcl-asan` pass for the headless matrix |
|
||||||
| DEBT-0015 | Open | Modernization | Cursor visibility requests now consume pure `pp_app_core` planning through `pano_cli plan-cursor-visibility`, but live cursor execution still reaches retained Win32/macOS platform bridges from `App::show_cursor` and `App::hide_cursor` | Keep canvas cursor behavior stable while platform shells are extracted incrementally | `pp_app_core_document_platform_io_tests`; `pano_cli plan-cursor-visibility --visible`; `ctest --preset desktop-fast --build-config Debug` | Cursor visibility execution is owned by `pp_platform_*` services and live app code depends on an injected platform interface instead of direct singleton/platform calls |
|
| DEBT-0015 | Open | Modernization | Cursor visibility requests now consume pure `pp_app_core` planning through `pano_cli plan-cursor-visibility`, but live cursor execution still reaches retained Win32/macOS platform bridges from `App::show_cursor` and `App::hide_cursor` | Keep canvas cursor behavior stable while platform shells are extracted incrementally | `pp_app_core_document_platform_io_tests`; `pano_cli plan-cursor-visibility --visible`; `ctest --preset desktop-fast --build-config Debug` | Cursor visibility execution is owned by `pp_platform_*` services and live app code depends on an injected platform interface instead of direct singleton/platform calls |
|
||||||
|
| DEBT-0016 | Open | Modernization | Clipboard get/set requests now consume pure `pp_app_core` planning through `pano_cli plan-clipboard-read` and `pano_cli plan-clipboard-write`, but live clipboard execution still reaches retained Win32/Apple/Android platform bridges from `App::clipboard_get_text` and `App::clipboard_set_text` | Keep picker/color text clipboard behavior stable while platform shells are extracted incrementally | `pp_app_core_document_platform_io_tests`; `pano_cli plan-clipboard-write --text #ff00aa`; `ctest --preset desktop-fast --build-config Debug` | Clipboard execution is owned by `pp_platform_*` services and live app code depends on an injected platform interface instead of direct singleton/platform calls |
|
||||||
|
|
||||||
## Closed Debt
|
## Closed Debt
|
||||||
|
|
||||||
|
|||||||
@@ -463,6 +463,9 @@ mobile platform keyboard bridges continue.
|
|||||||
`pano_cli plan-cursor-visibility` exposes the app-core cursor visibility
|
`pano_cli plan-cursor-visibility` exposes the app-core cursor visibility
|
||||||
decision used by live canvas cursor requests before retained desktop platform
|
decision used by live canvas cursor requests before retained desktop platform
|
||||||
cursor bridges continue.
|
cursor bridges continue.
|
||||||
|
`pano_cli plan-clipboard-read` and `pano_cli plan-clipboard-write` expose the
|
||||||
|
app-core clipboard text decisions used by live clipboard get/set requests
|
||||||
|
before retained platform clipboard bridges continue.
|
||||||
`pano_cli plan-cloud-upload` exposes the app-core cloud upload decision used by
|
`pano_cli plan-cloud-upload` exposes the app-core cloud upload decision used by
|
||||||
the live cloud upload command for missing-canvas, new-document warning, publish
|
the live cloud upload command for missing-canvas, new-document warning, publish
|
||||||
prompt, and dirty-document save-before-upload states before legacy UI, canvas,
|
prompt, and dirty-document save-before-upload states before legacy UI, canvas,
|
||||||
@@ -954,6 +957,7 @@ Results:
|
|||||||
callbacks, plus empty/non-empty display-file planning before platform
|
callbacks, plus empty/non-empty display-file planning before platform
|
||||||
display callbacks, plus virtual keyboard show/hide planning before platform
|
display callbacks, plus virtual keyboard show/hide planning before platform
|
||||||
keyboard callbacks, plus cursor visibility planning before platform cursor
|
keyboard callbacks, plus cursor visibility planning before platform cursor
|
||||||
|
callbacks, plus clipboard read/write planning before platform clipboard
|
||||||
callbacks.
|
callbacks.
|
||||||
- `pano_cli_plan_picked_path_empty_smoke` and
|
- `pano_cli_plan_picked_path_empty_smoke` and
|
||||||
`pano_cli_plan_picked_path_selected_smoke` passed and expose app-core picker
|
`pano_cli_plan_picked_path_selected_smoke` passed and expose app-core picker
|
||||||
@@ -967,6 +971,10 @@ Results:
|
|||||||
- `pano_cli_plan_cursor_visibility_hidden_smoke` and
|
- `pano_cli_plan_cursor_visibility_hidden_smoke` and
|
||||||
`pano_cli_plan_cursor_visibility_visible_smoke` passed and expose app-core
|
`pano_cli_plan_cursor_visibility_visible_smoke` passed and expose app-core
|
||||||
cursor visibility decisions as JSON.
|
cursor visibility decisions as JSON.
|
||||||
|
- `pano_cli_plan_clipboard_read_smoke`,
|
||||||
|
`pano_cli_plan_clipboard_write_smoke`, and
|
||||||
|
`pano_cli_plan_clipboard_write_empty_smoke` passed and expose app-core
|
||||||
|
clipboard decisions as JSON, including empty write text.
|
||||||
- `panopainter_validate_shaders` passed, validating 25 shader programs and 7
|
- `panopainter_validate_shaders` passed, validating 25 shader programs and 7
|
||||||
shader includes for stage markers and include graph integrity.
|
shader includes for stage markers and include graph integrity.
|
||||||
- `pp_renderer_gl_capabilities_tests` passed on default MSVC, vcpkg-headless,
|
- `pp_renderer_gl_capabilities_tests` passed on default MSVC, vcpkg-headless,
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ enum class CursorVisibilityAction {
|
|||||||
hide_cursor,
|
hide_cursor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ClipboardReadAction {
|
||||||
|
read_text,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ClipboardWriteAction {
|
||||||
|
write_text,
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] constexpr PickedPathAction plan_picked_path(std::string_view path) noexcept
|
[[nodiscard]] constexpr PickedPathAction plan_picked_path(std::string_view path) noexcept
|
||||||
{
|
{
|
||||||
return path.empty()
|
return path.empty()
|
||||||
@@ -52,4 +60,14 @@ enum class CursorVisibilityAction {
|
|||||||
: CursorVisibilityAction::hide_cursor;
|
: CursorVisibilityAction::hide_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr ClipboardReadAction plan_clipboard_read() noexcept
|
||||||
|
{
|
||||||
|
return ClipboardReadAction::read_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr ClipboardWriteAction plan_clipboard_write(std::string_view) noexcept
|
||||||
|
{
|
||||||
|
return ClipboardWriteAction::write_text;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ void webgl_sync();
|
|||||||
|
|
||||||
std::string App::clipboard_get_text()
|
std::string App::clipboard_get_text()
|
||||||
{
|
{
|
||||||
|
if (pp::app::plan_clipboard_read() != pp::app::ClipboardReadAction::read_text)
|
||||||
|
return {};
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
return win32_clipboard_get_text();
|
return win32_clipboard_get_text();
|
||||||
#elif __IOS__
|
#elif __IOS__
|
||||||
@@ -76,6 +79,9 @@ std::string App::clipboard_get_text()
|
|||||||
|
|
||||||
bool App::clipboard_set_text(const std::string& s)
|
bool App::clipboard_set_text(const std::string& s)
|
||||||
{
|
{
|
||||||
|
if (pp::app::plan_clipboard_write(s) != pp::app::ClipboardWriteAction::write_text)
|
||||||
|
return false;
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
return win32_clipboard_set_text(s);
|
return win32_clipboard_set_text(s);
|
||||||
#elif __IOS__
|
#elif __IOS__
|
||||||
|
|||||||
@@ -651,6 +651,24 @@ if(TARGET pano_cli)
|
|||||||
LABELS "app;integration;desktop-fast"
|
LABELS "app;integration;desktop-fast"
|
||||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-cursor-visibility\".*\"visible\":true.*\"decision\":\"show-cursor\"")
|
PASS_REGULAR_EXPRESSION "\"command\":\"plan-cursor-visibility\".*\"visible\":true.*\"decision\":\"show-cursor\"")
|
||||||
|
|
||||||
|
add_test(NAME pano_cli_plan_clipboard_read_smoke
|
||||||
|
COMMAND pano_cli plan-clipboard-read)
|
||||||
|
set_tests_properties(pano_cli_plan_clipboard_read_smoke PROPERTIES
|
||||||
|
LABELS "app;integration;desktop-fast"
|
||||||
|
PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-read\".*\"decision\":\"read-text\"")
|
||||||
|
|
||||||
|
add_test(NAME pano_cli_plan_clipboard_write_smoke
|
||||||
|
COMMAND pano_cli plan-clipboard-write --text "#ff00aa")
|
||||||
|
set_tests_properties(pano_cli_plan_clipboard_write_smoke PROPERTIES
|
||||||
|
LABELS "app;integration;desktop-fast"
|
||||||
|
PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-write\".*\"text\":\"#ff00aa\".*\"decision\":\"write-text\"")
|
||||||
|
|
||||||
|
add_test(NAME pano_cli_plan_clipboard_write_empty_smoke
|
||||||
|
COMMAND pano_cli plan-clipboard-write)
|
||||||
|
set_tests_properties(pano_cli_plan_clipboard_write_empty_smoke PROPERTIES
|
||||||
|
LABELS "app;integration;desktop-fast;fuzz"
|
||||||
|
PASS_REGULAR_EXPRESSION "\"command\":\"plan-clipboard-write\".*\"text\":\"\".*\"decision\":\"write-text\"")
|
||||||
|
|
||||||
add_test(NAME pano_cli_simulate_app_session_clean_smoke
|
add_test(NAME pano_cli_simulate_app_session_clean_smoke
|
||||||
COMMAND pano_cli simulate-app-session)
|
COMMAND pano_cli simulate-app-session)
|
||||||
set_tests_properties(pano_cli_simulate_app_session_clean_smoke PROPERTIES
|
set_tests_properties(pano_cli_simulate_app_session_clean_smoke PROPERTIES
|
||||||
|
|||||||
@@ -59,6 +59,27 @@ void cursor_visibility_plans_hide_action(pp::tests::Harness& harness)
|
|||||||
pp::app::plan_cursor_visibility(false) == pp::app::CursorVisibilityAction::hide_cursor);
|
pp::app::plan_cursor_visibility(false) == pp::app::CursorVisibilityAction::hide_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clipboard_read_plans_text_read(pp::tests::Harness& harness)
|
||||||
|
{
|
||||||
|
PP_EXPECT(
|
||||||
|
harness,
|
||||||
|
pp::app::plan_clipboard_read() == pp::app::ClipboardReadAction::read_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clipboard_write_plans_text_write(pp::tests::Harness& harness)
|
||||||
|
{
|
||||||
|
PP_EXPECT(
|
||||||
|
harness,
|
||||||
|
pp::app::plan_clipboard_write("#ff00aa") == pp::app::ClipboardWriteAction::write_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clipboard_write_keeps_empty_text_writable(pp::tests::Harness& harness)
|
||||||
|
{
|
||||||
|
PP_EXPECT(
|
||||||
|
harness,
|
||||||
|
pp::app::plan_clipboard_write("") == pp::app::ClipboardWriteAction::write_text);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -72,5 +93,8 @@ int main()
|
|||||||
harness.run("virtual keyboard plans hide action", virtual_keyboard_plans_hide_action);
|
harness.run("virtual keyboard plans hide action", virtual_keyboard_plans_hide_action);
|
||||||
harness.run("cursor visibility plans show action", cursor_visibility_plans_show_action);
|
harness.run("cursor visibility plans show action", cursor_visibility_plans_show_action);
|
||||||
harness.run("cursor visibility plans hide action", cursor_visibility_plans_hide_action);
|
harness.run("cursor visibility plans hide action", cursor_visibility_plans_hide_action);
|
||||||
|
harness.run("clipboard read plans text read", clipboard_read_plans_text_read);
|
||||||
|
harness.run("clipboard write plans text write", clipboard_write_plans_text_write);
|
||||||
|
harness.run("clipboard write keeps empty text writable", clipboard_write_keeps_empty_text_writable);
|
||||||
return harness.finish();
|
return harness.finish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,10 @@ struct PlanCursorVisibilityArgs {
|
|||||||
bool visible = false;
|
bool visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlanClipboardWriteArgs {
|
||||||
|
std::string text;
|
||||||
|
};
|
||||||
|
|
||||||
struct SimulateAppSessionArgs {
|
struct SimulateAppSessionArgs {
|
||||||
bool has_canvas = true;
|
bool has_canvas = true;
|
||||||
bool new_document = false;
|
bool new_document = false;
|
||||||
@@ -563,6 +567,26 @@ const char* cursor_visibility_action_name(pp::app::CursorVisibilityAction action
|
|||||||
return "hide-cursor";
|
return "hide-cursor";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* clipboard_read_action_name(pp::app::ClipboardReadAction action) noexcept
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case pp::app::ClipboardReadAction::read_text:
|
||||||
|
return "read-text";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "read-text";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* clipboard_write_action_name(pp::app::ClipboardWriteAction action) noexcept
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case pp::app::ClipboardWriteAction::write_text:
|
||||||
|
return "write-text";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "write-text";
|
||||||
|
}
|
||||||
|
|
||||||
pp::foundation::Result<float> parse_float_arg(std::string_view text)
|
pp::foundation::Result<float> parse_float_arg(std::string_view text)
|
||||||
{
|
{
|
||||||
float value = 0.0F;
|
float value = 0.0F;
|
||||||
@@ -608,6 +632,8 @@ void print_help()
|
|||||||
<< " plan-display-file [--path FILE]\n"
|
<< " plan-display-file [--path FILE]\n"
|
||||||
<< " plan-keyboard-visibility [--visible]\n"
|
<< " plan-keyboard-visibility [--visible]\n"
|
||||||
<< " plan-cursor-visibility [--visible]\n"
|
<< " plan-cursor-visibility [--visible]\n"
|
||||||
|
<< " plan-clipboard-read\n"
|
||||||
|
<< " plan-clipboard-write [--text TEXT]\n"
|
||||||
<< " load-project --path FILE\n"
|
<< " load-project --path FILE\n"
|
||||||
<< " parse-layout --path FILE\n"
|
<< " parse-layout --path FILE\n"
|
||||||
<< " record-render [--width N] [--height N] [--exercise-clear]\n"
|
<< " record-render [--width N] [--height N] [--exercise-clear]\n"
|
||||||
@@ -2120,6 +2146,52 @@ int plan_cursor_visibility(int argc, char** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int plan_clipboard_read(int, char**)
|
||||||
|
{
|
||||||
|
const auto decision = pp::app::plan_clipboard_read();
|
||||||
|
std::cout << "{\"ok\":true,\"command\":\"plan-clipboard-read\""
|
||||||
|
<< ",\"decision\":\"" << clipboard_read_action_name(decision)
|
||||||
|
<< "\"}\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::foundation::Status parse_plan_clipboard_write_args(
|
||||||
|
int argc,
|
||||||
|
char** argv,
|
||||||
|
PlanClipboardWriteArgs& args)
|
||||||
|
{
|
||||||
|
for (int i = 2; i < argc; ++i) {
|
||||||
|
const std::string_view key(argv[i]);
|
||||||
|
if (key == "--text") {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||||
|
}
|
||||||
|
args.text = argv[++i];
|
||||||
|
} else {
|
||||||
|
return pp::foundation::Status::invalid_argument("unknown option");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp::foundation::Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
int plan_clipboard_write(int argc, char** argv)
|
||||||
|
{
|
||||||
|
PlanClipboardWriteArgs args;
|
||||||
|
const auto status = parse_plan_clipboard_write_args(argc, argv, args);
|
||||||
|
if (!status.ok()) {
|
||||||
|
print_error("plan-clipboard-write", status.message);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto decision = pp::app::plan_clipboard_write(args.text);
|
||||||
|
std::cout << "{\"ok\":true,\"command\":\"plan-clipboard-write\""
|
||||||
|
<< ",\"state\":{\"text\":\"" << json_escape(args.text)
|
||||||
|
<< "\"},\"decision\":\"" << clipboard_write_action_name(decision)
|
||||||
|
<< "\"}\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
pp::foundation::Status parse_plan_export_target_args(
|
pp::foundation::Status parse_plan_export_target_args(
|
||||||
int argc,
|
int argc,
|
||||||
char** argv,
|
char** argv,
|
||||||
@@ -4307,6 +4379,14 @@ int main(int argc, char** argv)
|
|||||||
return plan_cursor_visibility(argc, argv);
|
return plan_cursor_visibility(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command == "plan-clipboard-read") {
|
||||||
|
return plan_clipboard_read(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == "plan-clipboard-write") {
|
||||||
|
return plan_clipboard_write(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
if (command == "load-project") {
|
if (command == "load-project") {
|
||||||
return load_project(argc, argv);
|
return load_project(argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user