Summary
When a user copies a script Group from FileMaker (a folder of scripts in the Script Workspace) and pastes into SharpFM, the paste handler should decompose the Group into individual script clips and mirror the group's folder structure in the clip repository.
This is incoming-only. Outgoing (SharpFM → FileMaker) stays one clip at a time.
Behavior
- A pasted snippet whose root contains
<Group> elements is recognized as a folder paste.
- Each
<Group> becomes a folder in the clip repository, named after the Group's name attribute.
- Each
<Script> inside a Group becomes its own clip inside that repository folder.
- Nested Groups produce nested folders.
- A Group contains one type of object — scripts or tables, never mixed (FileMaker's UI enforces this).
- The Group's metadata (
id, groupCollapsed, includeInMenu) is preserved on the folder so a future round-trip path can rebuild the structure.
Out of scope
- Outgoing copy (SharpFM → FileMaker) remains a single clip at a time. Group export is a separate concern.
- Pasting Group-of-tables (
Mac-XMTB with <Group>) is the same shape but the table paste path is its own ticket.
- The FileMaker "Group" script step (a folder of script steps inside a script) is unrelated and out of scope.
Sample input
A copy of one folder containing one script. After paste, the repository should contain:
Paste Targets/
FizzBuzz (Mac-XMSS clip)
Full sample XML (FizzBuzz inside a "Paste Targets" group)
<fmxmlsnippet type="FMObjectList">
<Group groupCollapsed="False" includeInMenu="False" id="16" name="Paste Targets">
<Script includeInMenu="False" runFullAccess="False" id="19" name="FizzBuzz">
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[1]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$i</Name>
</Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA["[]"]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$json</Name>
</Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[100]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$limit</Name>
</Step>
<Step enable="True" id="71" name="Loop"></Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[Case ( Mod ( $i ; 15 ) = 0 ; "FizzBuzz" ; Mod ( $i ; 3 ) = 0 ; "Fizz" ; Mod ( $i ; 5 ) = 0 ; "Buzz" ; $i )]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$label</Name>
</Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[JSONSetElement ( $json ; "[" & ( $i - 1 ) & "]" ; $label ; JSONString )]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$json</Name>
</Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[$i + 1]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$i</Name>
</Step>
<Step enable="True" id="72" name="Exit Loop If">
<Calculation><![CDATA[$i > $limit]]></Calculation>
</Step>
<Step enable="True" id="73" name="End Loop"></Step>
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[JSONFormatElements ( $json )]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$json</Name>
</Step>
<Step enable="True" id="87" name="Show Custom Dialog">
<Title>
<Calculation><![CDATA["FizzBuzz"]]></Calculation>
</Title>
<Message>
<Calculation><![CDATA[$json]]></Calculation>
</Message>
<Buttons>
<Button CommitState="True">
<Calculation><![CDATA["OK"]]></Calculation>
</Button>
<Button CommitState="False"></Button>
<Button CommitState="False"></Button>
</Buttons>
</Step>
</Script>
</Group>
</fmxmlsnippet>
Implementation notes
- Clipboard format detection is unchanged —
Mac-XMSS already wraps both single-script and Group-of-scripts payloads. The wrapper sits inside the existing <fmxmlsnippet> root.
FileMakerClip represents one clip today. Two reasonable shapes:
- Decompose at the paste-handler layer: walk the snippet, emit one
FileMakerClip per <Script>, and create the matching folder rows in ClipRepository before any clip is added.
- Extend the model to hold a tree of clips and have
ClipRepository accept the tree wholesale.
- A flat repository today still works as a fallback — flatten the group into prefixed clip names if folder support isn't yet there.
Open questions
- Folder-name collisions: merge into the existing folder, error, or rename with a suffix? Default suggestion: merge (treat the folder name as a namespace).
- Preserve
id on the Group itself, or only on its children?
- Should pasted Groups pre-expand in the tree, or honor
groupCollapsed?
- If a paste contains a Group at the top level and loose scripts as siblings of the Group, where do the loose scripts land — repository root, or a default folder?
Acceptance criteria
- Pasting the sample XML produces a
Paste Targets folder in the tree browser containing one clip named FizzBuzz.
- Pasting a Group with multiple scripts produces all of them inside the matching folder.
- Pasting a nested Group structure produces nested folders.
- Existing single-clip paste behavior is unchanged.
- Copying a script back out to FileMaker still works (the Group is a tree-organization concern; it does not change the outgoing format).
- New tests cover: Group + one script, Group + many scripts, nested Groups, name-collision with an existing folder.
Summary
When a user copies a script Group from FileMaker (a folder of scripts in the Script Workspace) and pastes into SharpFM, the paste handler should decompose the Group into individual script clips and mirror the group's folder structure in the clip repository.
This is incoming-only. Outgoing (SharpFM → FileMaker) stays one clip at a time.
Behavior
<Group>elements is recognized as a folder paste.<Group>becomes a folder in the clip repository, named after the Group'snameattribute.<Script>inside a Group becomes its own clip inside that repository folder.id,groupCollapsed,includeInMenu) is preserved on the folder so a future round-trip path can rebuild the structure.Out of scope
Mac-XMTBwith<Group>) is the same shape but the table paste path is its own ticket.Sample input
A copy of one folder containing one script. After paste, the repository should contain:
Full sample XML (FizzBuzz inside a "Paste Targets" group)
Implementation notes
Mac-XMSSalready wraps both single-script and Group-of-scripts payloads. The wrapper sits inside the existing<fmxmlsnippet>root.FileMakerCliprepresents one clip today. Two reasonable shapes:FileMakerClipper<Script>, and create the matching folder rows inClipRepositorybefore any clip is added.ClipRepositoryaccept the tree wholesale.Open questions
idon the Group itself, or only on its children?groupCollapsed?Acceptance criteria
Paste Targetsfolder in the tree browser containing one clip namedFizzBuzz.