mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-02 17:57:45 +03:00
feat(form-decompile,form-compile): CommandInterface — командный интерфейс формы из ring-3
Снят fast-fail на CommandInterface (4388 форм, 13.5% корпуса — крупнейший
оставшийся триггер ring-3).
Форменный ключ commandInterface = панели commandBar + navigationPanel, списки
переопределений авто-расстановки (платформа эмитит только отклонения). Элемент:
command (verbatim; "0"=пустой), type (Auto опускаем/Added), defaultVisible,
visible (тот же xr-flag, что userVisible/use — bool или {common,roles}),
group (CommandGroup verbatim), index, attribute. Порядок тегов Item:
Command,Type,Attribute,CommandGroup,Index,DefaultVisible,Visible.
Две формы записи панели: плоский массив (декомпилятор эмитит её) + древовидная
{группа:[команды]} как входной сахар (алиасы important/goTo/seeAlso→
FormNavigationPanel*, important/createBasedOn→FormCommandBar*; иной ключ verbatim;
group из ключа, элементы не дублируют). Голый элемент → строка-shorthand.
Переиспользует Decompile-XrFlag/Emit-XrFlag.
Выборка 2.17: ring3 37→7, match 181→197; сам CommandInterface роундтрипится
бит-в-бит (0 CI-diff, остаток TOTAL — несвязанный хвост раскрытых форм). Зеркало
py байт-в-байт, кейс commands (+commandInterface tree-форма) сертифицирован
загрузкой в 1С. Регресс 40/40 (ps1+py).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ef036c7cf1
commit
d7dedd4843
@@ -1,4 +1,4 @@
|
|||||||
# form-compile v1.97 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.98 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[string]$JsonPath,
|
[string]$JsonPath,
|
||||||
@@ -4962,6 +4962,94 @@ function Emit-Commands {
|
|||||||
X "$indent</Commands>"
|
X "$indent</Commands>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Резолв ключа-группы древовидной формы → CommandGroup (зависит от панели). Дружелюбные
|
||||||
|
# алиасы стандартных form-групп; любой иной ключ (CommandGroup.X / GUID / "") — verbatim.
|
||||||
|
function Resolve-CommandGroupKey {
|
||||||
|
param([string]$key, [string]$panelTag)
|
||||||
|
$k = ($key -replace '\s','').ToLower()
|
||||||
|
if ($panelTag -eq 'NavigationPanel') {
|
||||||
|
switch ($k) {
|
||||||
|
'important' { return 'FormNavigationPanelImportant' }
|
||||||
|
'важное' { return 'FormNavigationPanelImportant' }
|
||||||
|
'goto' { return 'FormNavigationPanelGoTo' }
|
||||||
|
'перейти' { return 'FormNavigationPanelGoTo' }
|
||||||
|
'seealso' { return 'FormNavigationPanelSeeAlso' }
|
||||||
|
'смтакже' { return 'FormNavigationPanelSeeAlso' }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch ($k) {
|
||||||
|
'important' { return 'FormCommandBarImportant' }
|
||||||
|
'важное' { return 'FormCommandBarImportant' }
|
||||||
|
'createbasedon' { return 'FormCommandBarCreateBasedOn' }
|
||||||
|
'создатьнаосновании' { return 'FormCommandBarCreateBasedOn' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $key # verbatim
|
||||||
|
}
|
||||||
|
|
||||||
|
# Командный интерфейс формы (<CommandInterface>): панели CommandBar + NavigationPanel.
|
||||||
|
# Значение панели: МАССИВ (плоская форма; элемент может нести group) ИЛИ ОБЪЕКТ
|
||||||
|
# (древовидная форма: {группа: [команды]}, group берётся из ключа, элементы его не дублируют).
|
||||||
|
# Элемент: строка (голый command, Type=Auto) или объект. Порядок тегов:
|
||||||
|
# Command, Type(деф. Auto), Attribute, CommandGroup, Index, DefaultVisible, Visible(xr-flag).
|
||||||
|
function Emit-CommandInterface {
|
||||||
|
param($ci, [string]$indent)
|
||||||
|
if (-not $ci) { return }
|
||||||
|
$inner = "$indent`t"
|
||||||
|
$panels = @(
|
||||||
|
@{ Tag='CommandBar'; Syns=@('commandBar','команднаяПанель','КоманднаяПанель') },
|
||||||
|
@{ Tag='NavigationPanel'; Syns=@('navigationPanel','панельНавигации','ПанельНавигации') }
|
||||||
|
)
|
||||||
|
$present = @()
|
||||||
|
foreach ($p in $panels) {
|
||||||
|
$items = $null
|
||||||
|
foreach ($syn in $p.Syns) { if ($null -ne $ci.PSObject.Properties[$syn]) { $items = $ci.($syn); break } }
|
||||||
|
if ($null -ne $items) { $present += ,@{ Tag=$p.Tag; Items=$items } }
|
||||||
|
}
|
||||||
|
if ($present.Count -eq 0) { return }
|
||||||
|
X "$indent<CommandInterface>"
|
||||||
|
foreach ($p in $present) {
|
||||||
|
X "$inner<$($p.Tag)>"
|
||||||
|
# Нормализация: плоский список пар (элемент, group-из-дерева). Объект → дерево.
|
||||||
|
$flat = New-Object System.Collections.ArrayList
|
||||||
|
if ($p.Items -is [System.Management.Automation.PSCustomObject]) {
|
||||||
|
foreach ($prop in $p.Items.PSObject.Properties) {
|
||||||
|
$grpFromTree = Resolve-CommandGroupKey -key $prop.Name -panelTag $p.Tag
|
||||||
|
foreach ($it in @($prop.Value)) { [void]$flat.Add(@{ item=$it; treeGroup=$grpFromTree }) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($it in @($p.Items)) { [void]$flat.Add(@{ item=$it; treeGroup=$null }) }
|
||||||
|
}
|
||||||
|
foreach ($fi in $flat) {
|
||||||
|
$item = $fi.item; $treeGroup = $fi.treeGroup
|
||||||
|
if ($item -is [string]) {
|
||||||
|
$cmd = $item; $type = 'Auto'; $attr = $null; $grp = $null; $idx = $null; $dv = $null; $vis = $null
|
||||||
|
} else {
|
||||||
|
$cmd = Get-ElProp $item @('command','команда')
|
||||||
|
$type = Get-ElProp $item @('type','тип'); if (-not $type) { $type = 'Auto' }
|
||||||
|
$attr = Get-ElProp $item @('attribute','реквизит')
|
||||||
|
$grp = Get-ElProp $item @('group','группа','группаКоманд')
|
||||||
|
$idx = Get-ElProp $item @('index','индекс')
|
||||||
|
$dv = Get-ElProp $item @('defaultVisible','видимость','видимостьПоУмолчанию')
|
||||||
|
$vis = Get-ElProp $item @('visible','видимостьПоРолям','настройкаВидимости')
|
||||||
|
}
|
||||||
|
# group из дерева побеждает (если задан и непустой); явный group элемента — фолбэк
|
||||||
|
if ($treeGroup) { $grp = $treeGroup }
|
||||||
|
X "$inner`t<Item>"
|
||||||
|
X "$inner`t`t<Command>$(Esc-Xml "$cmd")</Command>"
|
||||||
|
X "$inner`t`t<Type>$type</Type>"
|
||||||
|
if ($attr) { X "$inner`t`t<Attribute>$(Esc-Xml "$attr")</Attribute>" }
|
||||||
|
if ($grp) { X "$inner`t`t<CommandGroup>$(Esc-Xml "$grp")</CommandGroup>" }
|
||||||
|
if ($null -ne $idx) { X "$inner`t`t<Index>$idx</Index>" }
|
||||||
|
if ($null -ne $dv) { X "$inner`t`t<DefaultVisible>$(if ($dv){'true'}else{'false'})</DefaultVisible>" }
|
||||||
|
if ($null -ne $vis) { Emit-XrFlag -tag 'Visible' -val $vis -indent "$inner`t`t" }
|
||||||
|
X "$inner`t</Item>"
|
||||||
|
}
|
||||||
|
X "$inner</$($p.Tag)>"
|
||||||
|
}
|
||||||
|
X "$indent</CommandInterface>"
|
||||||
|
}
|
||||||
|
|
||||||
# --- 11. Properties emitter ---
|
# --- 11. Properties emitter ---
|
||||||
|
|
||||||
function Emit-Properties {
|
function Emit-Properties {
|
||||||
@@ -5366,6 +5454,9 @@ Emit-Parameters -params $def.parameters -indent "`t"
|
|||||||
# 12i. Commands
|
# 12i. Commands
|
||||||
Emit-Commands -cmds $def.commands -indent "`t"
|
Emit-Commands -cmds $def.commands -indent "`t"
|
||||||
|
|
||||||
|
# 12i2. CommandInterface (командный интерфейс формы — последний дочерний Form)
|
||||||
|
Emit-CommandInterface -ci $def.commandInterface -indent "`t"
|
||||||
|
|
||||||
# 12j. Close
|
# 12j. Close
|
||||||
X '</Form>'
|
X '</Form>'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# form-compile v1.97 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.98 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
@@ -4655,6 +4655,86 @@ def emit_commands(lines, cmds, indent):
|
|||||||
lines.append(f'{indent}</Commands>')
|
lines.append(f'{indent}</Commands>')
|
||||||
|
|
||||||
|
|
||||||
|
# Командный интерфейс формы (<CommandInterface>): панели CommandBar + NavigationPanel.
|
||||||
|
# Элемент: строка (голый command, Type=Auto) или dict. Порядок тегов:
|
||||||
|
# Command, Type(деф. Auto), Attribute, CommandGroup, Index, DefaultVisible, Visible(xr-flag).
|
||||||
|
def _resolve_command_group_key(key, panel_tag):
|
||||||
|
"""Ключ-группа древовидной формы → CommandGroup (зависит от панели); иначе verbatim."""
|
||||||
|
k = re.sub(r'\s', '', str(key)).lower()
|
||||||
|
if panel_tag == 'NavigationPanel':
|
||||||
|
m = {'important': 'FormNavigationPanelImportant', 'важное': 'FormNavigationPanelImportant',
|
||||||
|
'goto': 'FormNavigationPanelGoTo', 'перейти': 'FormNavigationPanelGoTo',
|
||||||
|
'seealso': 'FormNavigationPanelSeeAlso', 'смтакже': 'FormNavigationPanelSeeAlso'}
|
||||||
|
else:
|
||||||
|
m = {'important': 'FormCommandBarImportant', 'важное': 'FormCommandBarImportant',
|
||||||
|
'createbasedon': 'FormCommandBarCreateBasedOn', 'создатьнаосновании': 'FormCommandBarCreateBasedOn'}
|
||||||
|
return m.get(k, key)
|
||||||
|
|
||||||
|
|
||||||
|
def emit_command_interface(lines, ci, indent):
|
||||||
|
if not ci:
|
||||||
|
return
|
||||||
|
inner = f'{indent}\t'
|
||||||
|
panels = [
|
||||||
|
('CommandBar', ('commandBar', 'команднаяПанель', 'КоманднаяПанель')),
|
||||||
|
('NavigationPanel', ('navigationPanel', 'панельНавигации', 'ПанельНавигации')),
|
||||||
|
]
|
||||||
|
present = []
|
||||||
|
for tag, syns in panels:
|
||||||
|
items = None
|
||||||
|
for syn in syns:
|
||||||
|
if isinstance(ci, dict) and syn in ci:
|
||||||
|
items = ci[syn]
|
||||||
|
break
|
||||||
|
if items is not None:
|
||||||
|
present.append((tag, items))
|
||||||
|
if not present:
|
||||||
|
return
|
||||||
|
lines.append(f'{indent}<CommandInterface>')
|
||||||
|
for tag, items in present:
|
||||||
|
lines.append(f'{inner}<{tag}>')
|
||||||
|
# Нормализация: плоский список пар (элемент, group-из-дерева). dict → древовидная форма.
|
||||||
|
flat = []
|
||||||
|
if isinstance(items, dict):
|
||||||
|
for gkey, gitems in items.items():
|
||||||
|
grp_tree = _resolve_command_group_key(gkey, tag)
|
||||||
|
for it in gitems:
|
||||||
|
flat.append((it, grp_tree))
|
||||||
|
else:
|
||||||
|
for it in items:
|
||||||
|
flat.append((it, None))
|
||||||
|
for item, tree_group in flat:
|
||||||
|
if isinstance(item, str):
|
||||||
|
cmd, typ, attr, grp, idx, dv, vis = item, 'Auto', None, None, None, None, None
|
||||||
|
else:
|
||||||
|
cmd = get_el_prop(item, ('command', 'команда'))
|
||||||
|
typ = get_el_prop(item, ('type', 'тип')) or 'Auto'
|
||||||
|
attr = get_el_prop(item, ('attribute', 'реквизит'))
|
||||||
|
grp = get_el_prop(item, ('group', 'группа', 'группаКоманд'))
|
||||||
|
idx = get_el_prop(item, ('index', 'индекс'))
|
||||||
|
dv = get_el_prop(item, ('defaultVisible', 'видимость', 'видимостьПоУмолчанию'))
|
||||||
|
vis = get_el_prop(item, ('visible', 'видимостьПоРолям', 'настройкаВидимости'))
|
||||||
|
# group из дерева побеждает (если задан и непустой); явный group элемента — фолбэк
|
||||||
|
if tree_group:
|
||||||
|
grp = tree_group
|
||||||
|
lines.append(f'{inner}\t<Item>')
|
||||||
|
lines.append(f'{inner}\t\t<Command>{esc_xml(str(cmd))}</Command>')
|
||||||
|
lines.append(f'{inner}\t\t<Type>{typ}</Type>')
|
||||||
|
if attr:
|
||||||
|
lines.append(f'{inner}\t\t<Attribute>{esc_xml(str(attr))}</Attribute>')
|
||||||
|
if grp:
|
||||||
|
lines.append(f'{inner}\t\t<CommandGroup>{esc_xml(str(grp))}</CommandGroup>')
|
||||||
|
if idx is not None:
|
||||||
|
lines.append(f'{inner}\t\t<Index>{idx}</Index>')
|
||||||
|
if dv is not None:
|
||||||
|
lines.append(f'{inner}\t\t<DefaultVisible>{"true" if dv else "false"}</DefaultVisible>')
|
||||||
|
if vis is not None:
|
||||||
|
emit_xr_flag(lines, 'Visible', vis, f'{inner}\t\t')
|
||||||
|
lines.append(f'{inner}\t</Item>')
|
||||||
|
lines.append(f'{inner}</{tag}>')
|
||||||
|
lines.append(f'{indent}</CommandInterface>')
|
||||||
|
|
||||||
|
|
||||||
# --- Properties emitter ---
|
# --- Properties emitter ---
|
||||||
|
|
||||||
PROP_MAP = {
|
PROP_MAP = {
|
||||||
@@ -5204,6 +5284,9 @@ def main():
|
|||||||
# Commands
|
# Commands
|
||||||
emit_commands(lines, defn.get('commands'), '\t')
|
emit_commands(lines, defn.get('commands'), '\t')
|
||||||
|
|
||||||
|
# CommandInterface (командный интерфейс формы — последний дочерний Form)
|
||||||
|
emit_command_interface(lines, defn.get('commandInterface'), '\t')
|
||||||
|
|
||||||
# Close
|
# Close
|
||||||
lines.append('</Form>')
|
lines.append('</Form>')
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-decompile v0.73 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
# form-decompile v0.74 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||||
param(
|
param(
|
||||||
@@ -145,7 +145,6 @@ function Fail-Ring3 {
|
|||||||
[Console]::Error.WriteLine("Для точечной работы с этой формой используй /form-edit.")
|
[Console]::Error.WriteLine("Для точечной работы с этой формой используй /form-edit.")
|
||||||
exit 3
|
exit 3
|
||||||
}
|
}
|
||||||
foreach ($el in $xmlDoc.SelectNodes("//*[local-name()='CommandInterface']")) { Fail-Ring3 -kind "CommandInterface" -loc "form/CommandInterface" }
|
|
||||||
foreach ($el in $xmlDoc.SelectNodes("//*[local-name()='ConditionalAppearance']")) { Fail-Ring3 -kind "ConditionalAppearance" -loc "form/ConditionalAppearance" }
|
foreach ($el in $xmlDoc.SelectNodes("//*[local-name()='ConditionalAppearance']")) { Fail-Ring3 -kind "ConditionalAppearance" -loc "form/ConditionalAppearance" }
|
||||||
|
|
||||||
# --- 1c. Compact JSON serializer (созвучно skd-decompile: 2-проб. indent, inline в пределах lineLimit) ---
|
# --- 1c. Compact JSON serializer (созвучно skd-decompile: 2-проб. indent, inline в пределах lineLimit) ---
|
||||||
@@ -864,6 +863,38 @@ function Decompile-XrFlag {
|
|||||||
return $o
|
return $o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Командный интерфейс формы (<CommandInterface>): панели CommandBar + NavigationPanel,
|
||||||
|
# каждая — список переопределений команд (платформа эмитит ТОЛЬКО отклонения от авто-расстановки).
|
||||||
|
# Элемент: command (verbatim, "0"=пустой) + type (Auto опускаем) + attribute/group(CommandGroup)/index +
|
||||||
|
# defaultVisible(bool) + visible(xr-flag bool/{common,roles} — тот же механизм, что userVisible).
|
||||||
|
# Голый элемент (только команда, Type=Auto) → строковый shorthand.
|
||||||
|
function Decompile-CommandInterface {
|
||||||
|
$ciNode = $root.SelectSingleNode("lf:CommandInterface", $ns)
|
||||||
|
if (-not $ciNode) { return $null }
|
||||||
|
$ci = [ordered]@{}
|
||||||
|
foreach ($panel in @(@('CommandBar','commandBar'), @('NavigationPanel','navigationPanel'))) {
|
||||||
|
$pn = $ciNode.SelectSingleNode("lf:$($panel[0])", $ns)
|
||||||
|
if (-not $pn) { continue }
|
||||||
|
$items = New-Object System.Collections.ArrayList
|
||||||
|
foreach ($it in @($pn.SelectNodes("lf:Item", $ns))) {
|
||||||
|
$o = [ordered]@{}
|
||||||
|
$cmd = Get-Child $it 'Command'
|
||||||
|
$o['command'] = "$cmd"
|
||||||
|
$ty = Get-Child $it 'Type'; if ($ty -and $ty -ne 'Auto') { $o['type'] = $ty }
|
||||||
|
$at = Get-Child $it 'Attribute'; if ($at) { $o['attribute'] = $at }
|
||||||
|
$cg = Get-Child $it 'CommandGroup'; if ($cg) { $o['group'] = $cg }
|
||||||
|
$idx = Get-Child $it 'Index'; if ($null -ne $idx) { $o['index'] = [int]$idx }
|
||||||
|
$dv = Get-Child $it 'DefaultVisible'; if ($null -ne $dv) { $o['defaultVisible'] = ($dv -eq 'true') }
|
||||||
|
$vis = Decompile-XrFlag $it 'Visible'; if ($null -ne $vis) { $o['visible'] = $vis }
|
||||||
|
# Голый элемент (только command) → строка-shorthand; иначе объект
|
||||||
|
if ($o.Count -eq 1) { [void]$items.Add("$cmd") } else { [void]$items.Add($o) }
|
||||||
|
}
|
||||||
|
if ($items.Count -gt 0) { $ci[$panel[1]] = @($items) }
|
||||||
|
}
|
||||||
|
if ($ci.Count -gt 0) { return $ci }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
# <FunctionalOptions><Item>FunctionalOption.X</Item>…> → массив строк (префикс FunctionalOption. снят; GUID — как есть).
|
# <FunctionalOptions><Item>FunctionalOption.X</Item>…> → массив строк (префикс FunctionalOption. снят; GUID — как есть).
|
||||||
function Decompile-FunctionalOptions {
|
function Decompile-FunctionalOptions {
|
||||||
param($node)
|
param($node)
|
||||||
@@ -2092,6 +2123,10 @@ if ($cmdsNode) {
|
|||||||
if ($cmds.Count -gt 0) { $dsl['commands'] = @($cmds) }
|
if ($cmds.Count -gt 0) { $dsl['commands'] = @($cmds) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# commandInterface (форменный <CommandInterface> — последний дочерний Form)
|
||||||
|
$ci = Decompile-CommandInterface
|
||||||
|
if ($null -ne $ci) { $dsl['commandInterface'] = $ci }
|
||||||
|
|
||||||
# --- 6. Output ---
|
# --- 6. Output ---
|
||||||
$json = ConvertTo-CompactJson -obj $dsl
|
$json = ConvertTo-CompactJson -obj $dsl
|
||||||
if ($OutputPath) {
|
if ($OutputPath) {
|
||||||
|
|||||||
@@ -940,6 +940,46 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 7b. CommandInterface — командный интерфейс формы
|
||||||
|
|
||||||
|
Форменный ключ `commandInterface` (XML `<CommandInterface>`, последний дочерний `<Form>`). Две панели:
|
||||||
|
`commandBar` (командная панель) и `navigationPanel` (панель навигации). Платформа эмитит **только
|
||||||
|
переопределения** авто-расстановки (видимость/положение), поэтому в списке лишь изменённые команды.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"commandInterface": {
|
||||||
|
"commandBar": [
|
||||||
|
{ "command": "Form.Command.Печать", "defaultVisible": false, "group": "FormCommandBarImportant",
|
||||||
|
"visible": { "common": false, "roles": { "Бухгалтер": true } } },
|
||||||
|
"CommonCommand.История"
|
||||||
|
],
|
||||||
|
"navigationPanel": {
|
||||||
|
"important": [ { "command": "CommonCommand.СвязанныеДокументы", "defaultVisible": false, "visible": false } ],
|
||||||
|
"seeAlso": [ { "command": "CommonCommand.Заметки", "defaultVisible": false, "visible": false } ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Элемент** (объект или строка-shorthand = голый `command` со всеми умолчаниями):
|
||||||
|
|
||||||
|
| Свойство | Тип | Описание |
|
||||||
|
|----------|-----|----------|
|
||||||
|
| `command` | string | Ссылка на команду verbatim: `CommonCommand.X`, `Document.X.StandardCommand.Y`, `Form.Command.X`, `Form.StandardCommand.OK`, `"0"` (пустой/разделитель) |
|
||||||
|
| `type` | string | `Auto` (дефолт, опускаем) / `Added` |
|
||||||
|
| `defaultVisible` | bool | Видимость по умолчанию (`<DefaultVisible>`; на практике всегда `false` — скрыть видимую команду) |
|
||||||
|
| `visible` | bool/object | Видимость с исключениями по ролям — **тот же xr-flag, что `userVisible`/`use`** (§4.1c): `bool` или `{common, roles:{Имя:bool}}` |
|
||||||
|
| `group` | string | `<CommandGroup>` verbatim: `FormCommandBarImportant`/`FormNavigationPanelGoTo`/…, `CommandGroup.X` (именованная), GUID (расширение) |
|
||||||
|
| `index` | int | Порядок в группе (`<Index>`) |
|
||||||
|
| `attribute` | string | Путь реквизита для элемента панели навигации (`<Attribute>`) |
|
||||||
|
|
||||||
|
**Две формы записи панели:**
|
||||||
|
- **Плоский массив** — каждый элемент опц. несёт `group` (полная общность; декомпилятор эмитит ЭТУ форму).
|
||||||
|
- **Дерево** (входной сахар) — объект `{группа: [команды]}`; `group` берётся из ключа, элементы его не дублируют. Дружелюбные алиасы (зависят от панели): navigation — `important`/`goTo`/`seeAlso` (рус. `важное`/`перейти`/`смТакже`), commandBar — `important`/`createBasedOn`; иной ключ (`CommandGroup.X`/GUID) — verbatim.
|
||||||
|
|
||||||
|
Синонимы ключей: `команда`/`тип`/`видимость`/`видимостьПоРолям`/`группа`/`индекс`/`реквизит`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 8. Система типов (shorthand)
|
## 8. Система типов (shorthand)
|
||||||
|
|
||||||
### Примитивные типы
|
### Примитивные типы
|
||||||
|
|||||||
@@ -29,6 +29,13 @@
|
|||||||
],
|
],
|
||||||
"commands": [
|
"commands": [
|
||||||
{ "name": "Выполнить", "action": "ВыполнитьОбработка", "shortcut": "Ctrl+Enter", "use": false, "modifiesSavedData": true }
|
{ "name": "Выполнить", "action": "ВыполнитьОбработка", "shortcut": "Ctrl+Enter", "use": false, "modifiesSavedData": true }
|
||||||
]
|
],
|
||||||
|
"commandInterface": {
|
||||||
|
"commandBar": {
|
||||||
|
"important": [
|
||||||
|
{ "command": "Form.Command.Выполнить", "defaultVisible": false, "index": 0, "visible": false }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -90,4 +90,18 @@
|
|||||||
<Shortcut>Ctrl+Enter</Shortcut>
|
<Shortcut>Ctrl+Enter</Shortcut>
|
||||||
</Command>
|
</Command>
|
||||||
</Commands>
|
</Commands>
|
||||||
|
<CommandInterface>
|
||||||
|
<CommandBar>
|
||||||
|
<Item>
|
||||||
|
<Command>Form.Command.Выполнить</Command>
|
||||||
|
<Type>Auto</Type>
|
||||||
|
<CommandGroup>FormCommandBarImportant</CommandGroup>
|
||||||
|
<Index>0</Index>
|
||||||
|
<DefaultVisible>false</DefaultVisible>
|
||||||
|
<Visible>
|
||||||
|
<xr:Common>false</xr:Common>
|
||||||
|
</Visible>
|
||||||
|
</Item>
|
||||||
|
</CommandBar>
|
||||||
|
</CommandInterface>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
Reference in New Issue
Block a user