Add 'Copy as SysML' context menu to all diagram tabs - #6
Merged
Conversation
Every rendered diagram tab (General, Interconnection, State Transition,
Action Flow, Sequence, Grid predefined views, and custom-view-builder
preview tabs) now exposes a single shared right-click context menu item,
"Copy as SysML", that copies the whole diagram's SysML `view { ... }`
definition (view kind, expose targets, and filter expression) to the OS
clipboard. All six diagram kinds and the custom preview funnel through the
one shared DiagramDocumentView/DiagramDocumentViewModel pair, so the
context menu, its enable/disable logic, and the click handler are added in
exactly one place rather than duplicated per diagram kind.
Predefined-view tabs previously had no concrete, reusable view definition
to export - only display metadata (ViewDescriptor). ViewCatalogPresenter
gains BuildViewDefinition(workspace, viewId), which reconstructs a real
ViewDefinitionModel (kind, every expose member with its own recursion kind
and optional bracket filter, filter expression, display name) from the
loaded workspace's SysmlViewNode, using ResolvedExposeMembers rather than
the raw ExposeMembers so qualified names are fully resolved against the
workspace rather than left as raw as-written text. It returns null for an
unknown view id, an unsupported render-target kind, or a view with zero
expose members (a valid but unscoped "expose everything" view with no
finite expose list to serialize). ViewDefinitionModel gains a matching
AddExposeTarget(ExposeTargetSelection) overload so an arbitrary real expose
member can be reconstructed in one call, deduplicated by the exact
(qualified name, recursion kind) pair, rather than needing the multi-call
add-then-retarget-then-filter sequence the existing string overload would
otherwise require.
WorkbenchTab now carries an optional SourceDefinition (the concrete
ViewDefinitionModel a tab was rendered from, populated by SelectPredefinedView
via BuildViewDefinition or carried through from PreviewCustomView).
MainWindowShell.CanExportTabAsSysml/ExportTabAsSysmlSnippet expose whether a
tab is exportable and generate its snippet text via the existing
SysmlSnippetGenerator - the same generator the custom view builder's own
export button already used - so there remains exactly one snippet-generation
code path. The no-derivable-definition edge case (unknown tab, or a
predefined view with no expose members) is handled gracefully: the context
menu item is disabled and the reason is logged at Info level via the
existing RollingFileLogger, never thrown.
The actual clipboard write goes through a new IClipboardService seam
(AvaloniaClipboardService wraps TopLevel.GetTopLevel(anchor)?.Clipboard,
resolved lazily per call rather than cached at construction), mirroring the
existing IUiDispatcher seam pattern, so DiagramDocumentViewModel.CopyAsSysmlAsync
can be unit tested with a fake clipboard instead of a live UI.
DiagramDocumentView's code-behind constructs the real clipboard service once
it has a view model and assigns it to the view model's ClipboardService
property.
Companion updates: reqstream requirements and test-name traceability for
MainWindowShell, ViewCatalogPresenter, ViewDefinitionModel, and the OTS
Avalonia unit; design docs for the same units plus the "Diagram Document
Tabs" section of docs/design/ots/dock.md, which documents the new context
menu, its enable/disable behavior, and the SourceDefinition data flow; and
matching verification-doc scenario narratives for every new test. New
tests: ViewDefinitionModelTests (AddExposeTarget selection overload, add and
null-argument cases), ViewCatalogPresenterTests (BuildViewDefinition kind/
expose/filter resolution, unknown view id, zero-expose-members cases),
MainWindowShellTests (CanExportTabAsSysml/ExportTabAsSysmlSnippet across
predefined, custom-preview, unknown, and unscoped-view cases),
DiagramDocumentViewModelTests (CopyAsSysmlAsync with a fake clipboard
service across exportable, non-exportable, and no-clipboard-assigned
cases), and one new OTS headless Avalonia end-to-end test,
DiagramContextMenu_CopyAsSysml_CopiesSnippetToClipboard, which drives the
real context menu and menu item through the actual visual tree and reads
the result back from the headless platform's real TopLevel.Clipboard.
Full dotnet build (0 warnings/errors), dotnet test (153 + 19 passing),
dotnet sysml2tools lint, dotnet reqstream --lint, and a local reproduction
of CI's dotnet reqstream --enforce (clean aside from the three pre-existing,
unrelated per-OS platform requirements that are only satisfiable on their
respective CI runner) all pass. fix.ps1 and lint.ps1 both run clean.
The right-click 'Copy as SysML' context menu (added in 62a94d5) applies to every open diagram tab - all predefined view kinds and custom-view previews - via the shared DiagramDocumentView, not just the Custom View Builder panel's own button. The user guide only documented the panel button, leaving the broader context-menu capability undiscoverable. Add a paragraph at the end of 'Browsing Predefined Views' describing the per-tab context menu and its disabled state when no concrete view definition can be derived, and a one-line cross-reference at the end of step 7 in 'Building a Custom View' pointing readers to it.
Border.ContextMenu consumes the right-button pointer release before the diagram's own PointerReleased handler runs, so panning (started for any button) was never stopped, leaving the diagram permanently dragging on subsequent mouse moves. Pan gestures now only start on the left button; right-click is reserved exclusively for the context menu. A PointerCaptureLost handler also resets the panning flag defensively. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a new "Copy as SysML" context menu action for all diagram tabs in the SysML2Workbench, allowing users to right-click any open diagram tab and copy its underlying SysML view definition to the OS clipboard. This feature is implemented with Avalonia's real
ContextMenuandTopLevel.ClipboardAPIs and is available for both predefined and custom view tabs. The implementation includes robust eligibility checks and error handling, ensures a single snippet-generation code path, and is fully covered by requirements and verification documentation. Additionally, new APIs and overloads are introduced to support the reconstruction and export of view definitions.The most important changes are:
User-Facing Feature: Diagram Tab "Copy as SysML" Context Menu
ContextMenuandTopLevel.ClipboardAPIs to copy the diagram's SysML view definition to the clipboard. The option is disabled if no concrete definition can be derived for the tab (e.g., unscoped predefined view or unrendered custom preview). [1]], [2]], [3]], [4]])App Shell & View Model Enhancements
WorkbenchTabnow carries a nullableSourceDefinition(ViewDefinitionModel?), backing the export action for each tab. ([docs/design/sysml2-workbench/app-shell-subsystem/main-window-shell.mdR40-R45])MainWindowShelladds two new methods:CanExportTabAsSysml(checks exportability of a tab) andExportTabAsSysmlSnippet(generates the snippet or returns null, with logging for expected null cases). ([docs/design/sysml2-workbench/app-shell-subsystem/main-window-shell.mdR138-R157])View Definition and Catalog Support
ViewDefinitionModelintroduces an overloadAddExposeTarget(ExposeTargetSelection)for direct, deduplicated addition of fully-specified expose targets, supporting arbitrary recursion kinds and bracket filters. ([docs/design/sysml2-workbench/view-builder-subsystem/view-definition-model.mdR58-R74])ViewCatalogPresenteraddsBuildViewDefinition, reconstructing a predefined view's concrete definition (view kind, expose members, filter, display name) from the workspace for snippet export. [1]], [2]])Requirements and Verification
Documentation Updates
These changes provide a unified, discoverable, and robust way for users to export SysML snippets from any diagram tab, while ensuring maintainability and testability of the new functionality.