mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-14 18:04:58 +03:00
feat(form-decompile,form-compile): картинки заголовка/подвала колонок + объектная модель картинки-ссылки (кластер column-pictures)
Декомпилятор терял картинки колонок таблиц формы:
- HeaderPicture/FooterPicture (общие для любого поля-колонки: input/check/labelField/picField)
- ValuesPicture: захват флага LoadTransparent (раньше брался только Ref)
- EditMode у PictureField
Единый формат "картинка-ссылка" (headerPicture/footerPicture/valuesPicture):
скаляр (Ref, loadTransparent=false — частый случай по корпусу ~64%) ИЛИ
объект {src, loadTransparent:true} для отклонения. Платформа всегда эмитит
<xr:LoadTransparent>, дефолт DSL=false. Флаг на каждой картинке (на одном
поле их бывает несколько).
Компилятор: HeaderPicture эмитится сразу после <EditMode> (порядок XDTO
строгий — иначе LoadConfigFromFiles падает с XDTO-исключением).
Forgiving-объект для <Picture> кнопки/попапа/команды: общий хелпер
Emit-CommandPicture принимает скаляр ИЛИ {src, loadTransparent}, чтобы
модель могла описать картинку объектно по аналогии с headerPicture.
Полярность кнопки сохранена (дефолт true). Декомпилятор не трогали —
объект только на вход, раундтрип без изменений.
Раундтрип sample-2.17: TOTAL 1582→1457, dec-fail/compile-fail 0.
Снапшот picture-field пересертифицирован в 1С. Регресс 34/34 ps+python.
Декомпилятор v0.45, компилятор v1.63.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.62 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.63 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2464,7 +2464,7 @@ function Emit-Element {
|
||||
# button-specific
|
||||
"type"=1;"command"=1;"commandName"=1;"stdCommand"=1;"defaultButton"=1;"locationInCommandBar"=1
|
||||
# picture/decoration
|
||||
"src"=1;"valuesPicture"=1;"loadTransparent"=1
|
||||
"src"=1;"valuesPicture"=1;"loadTransparent"=1;"headerPicture"=1;"footerPicture"=1
|
||||
# cmdBar-specific
|
||||
"autofill"=1
|
||||
}
|
||||
@@ -2558,6 +2558,49 @@ function Emit-CommonElementProps {
|
||||
if ($el.headerHorizontalAlign) { X "$indent<HeaderHorizontalAlign>$($el.headerHorizontalAlign)</HeaderHorizontalAlign>" }
|
||||
}
|
||||
|
||||
# Картинка-ссылка с прозрачностью (HeaderPicture/FooterPicture/ValuesPicture).
|
||||
# Платформа ВСЕГДА эмитит <xr:LoadTransparent> → пишем всегда (false по умолчанию).
|
||||
# Значение: скаляр (Ref) ИЛИ объект {src, loadTransparent}.
|
||||
function Emit-PictureRef {
|
||||
param($val, [string]$picTag, [string]$indent)
|
||||
if (-not $val) { return }
|
||||
$src = $null; $lt = $false
|
||||
if ($val -is [string]) { $src = $val }
|
||||
else { $src = $val.src; if ($val.loadTransparent -eq $true) { $lt = $true } }
|
||||
if (-not $src) { return }
|
||||
X "$indent<$picTag>"
|
||||
X "$indent`t<xr:Ref>$src</xr:Ref>"
|
||||
X "$indent`t<xr:LoadTransparent>$(if ($lt) { 'true' } else { 'false' })</xr:LoadTransparent>"
|
||||
X "$indent</$picTag>"
|
||||
}
|
||||
|
||||
# Картинки заголовка/подвала колонки поля — по схеме сразу после <EditMode>,
|
||||
# перед тип-специфичными элементами и layout (порядок XDTO строгий именно здесь).
|
||||
function Emit-ColumnPics {
|
||||
param($el, [string]$indent)
|
||||
Emit-PictureRef -val $el.headerPicture -picTag 'HeaderPicture' -indent $indent
|
||||
Emit-PictureRef -val $el.footerPicture -picTag 'FooterPicture' -indent $indent
|
||||
}
|
||||
|
||||
# <Picture> кнопки/попапа/команды. Дефолт LoadTransparent=true, отклонение false
|
||||
# (обратная конвенция относительно header/values-картинок). Прощающий ввод:
|
||||
# принимает скаляр (Ref) ИЛИ объект {src, loadTransparent} — на случай если модель
|
||||
# опишет картинку объектно по аналогии с headerPicture. $elemLt — legacy
|
||||
# элемент-уровневый ключ loadTransparent (используется, если в объекте флаг не задан).
|
||||
function Emit-CommandPicture {
|
||||
param($pic, $elemLt, [string]$indent)
|
||||
if (-not $pic) { return }
|
||||
$src = $null; $lt = $null
|
||||
if ($pic -is [string]) { $src = $pic }
|
||||
else { $src = $pic.src; if ($null -ne $pic.loadTransparent) { $lt = [bool]$pic.loadTransparent } }
|
||||
if (-not $src) { return }
|
||||
if ($null -eq $lt -and $null -ne $elemLt) { $lt = [bool]$elemLt }
|
||||
X "$indent<Picture>"
|
||||
X "$indent`t<xr:Ref>$src</xr:Ref>"
|
||||
X "$indent`t<xr:LoadTransparent>$(if ($lt -eq $false) { 'false' } else { 'true' })</xr:LoadTransparent>"
|
||||
X "$indent</Picture>"
|
||||
}
|
||||
|
||||
function Emit-Layout {
|
||||
param($el, [string]$indent, [switch]$skipHeight, [bool]$multiLineDefault = $false)
|
||||
Emit-CommonElementProps -el $el -indent $indent
|
||||
@@ -2777,6 +2820,7 @@ function Emit-Input {
|
||||
if ($el.dropListButton -eq $true) { X "$inner<DropListButton>true</DropListButton>" }
|
||||
if ($el.markIncomplete -eq $true) { X "$inner<AutoMarkIncomplete>true</AutoMarkIncomplete>" }
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
Emit-ColumnPics -el $el -indent $inner
|
||||
if ($el.textEdit -eq $false) { X "$inner<TextEdit>false</TextEdit>" }
|
||||
# InputField-специфичные скаляры (захват «как есть»: платформа эмитит явное не-дефолтное значение)
|
||||
foreach ($p in @(
|
||||
@@ -2815,6 +2859,7 @@ function Emit-Check {
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
Emit-ColumnPics -el $el -indent $inner
|
||||
# CheckBoxType: нет ключа → умный дефолт Auto; "" → подавить; значение → маппинг
|
||||
if ($null -ne $el.PSObject.Properties['checkBoxType']) {
|
||||
if ($el.checkBoxType) {
|
||||
@@ -3117,6 +3162,7 @@ function Emit-LabelField {
|
||||
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
Emit-ColumnPics -el $el -indent $inner
|
||||
# ВНИМАНИЕ: у LabelField платформенный тег именно <Hiperlink> (опечатка 1С), не <Hyperlink>.
|
||||
if ($el.hyperlink -eq $true) { X "$inner<Hiperlink>true</Hiperlink>" }
|
||||
Emit-Layout -el $el -indent $inner
|
||||
@@ -3398,12 +3444,7 @@ function Emit-Button {
|
||||
if ($el.defaultButton -eq $true) { X "$inner<DefaultButton>true</DefaultButton>" }
|
||||
|
||||
# Picture
|
||||
if ($el.picture) {
|
||||
X "$inner<Picture>"
|
||||
X "$inner`t<xr:Ref>$($el.picture)</xr:Ref>"
|
||||
X "$inner`t<xr:LoadTransparent>$(if ($el.loadTransparent -eq $false){'false'}else{'true'})</xr:LoadTransparent>"
|
||||
X "$inner</Picture>"
|
||||
}
|
||||
Emit-CommandPicture -pic $el.picture -elemLt $el.loadTransparent -indent $inner
|
||||
|
||||
if ($el.representation) {
|
||||
X "$inner<Representation>$($el.representation)</Representation>"
|
||||
@@ -3463,19 +3504,16 @@ function Emit-PictureField {
|
||||
Emit-Title -el $el -name $name -indent $inner
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
Emit-ColumnPics -el $el -indent $inner
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
|
||||
Emit-Layout -el $el -indent $inner
|
||||
|
||||
# ValuesPicture — picture (collection) used to render the field's value.
|
||||
# Required for a Boolean-bound PictureField to actually show an icon.
|
||||
# loadTransparent emitted only when true (1С default is false).
|
||||
if ($el.valuesPicture) {
|
||||
X "$inner<ValuesPicture>"
|
||||
X "$inner`t<xr:Ref>$($el.valuesPicture)</xr:Ref>"
|
||||
if ($el.loadTransparent) { X "$inner`t<xr:LoadTransparent>true</xr:LoadTransparent>" }
|
||||
X "$inner</ValuesPicture>"
|
||||
}
|
||||
|
||||
Emit-Layout -el $el -indent $inner
|
||||
# Скаляр (Ref) или объект {src, loadTransparent}; LoadTransparent эмитится всегда.
|
||||
Emit-PictureRef -val $el.valuesPicture -picTag 'ValuesPicture' -indent $inner
|
||||
|
||||
# Companions
|
||||
Emit-CompanionPanel -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner -panel $el.contextMenu
|
||||
@@ -3597,12 +3635,7 @@ function Emit-Popup {
|
||||
Emit-Title -el $el -name $name -indent $inner -auto
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.picture) {
|
||||
X "$inner<Picture>"
|
||||
X "$inner`t<xr:Ref>$($el.picture)</xr:Ref>"
|
||||
X "$inner`t<xr:LoadTransparent>$(if ($el.loadTransparent -eq $false){'false'}else{'true'})</xr:LoadTransparent>"
|
||||
X "$inner</Picture>"
|
||||
}
|
||||
Emit-CommandPicture -pic $el.picture -elemLt $el.loadTransparent -indent $inner
|
||||
|
||||
if ($el.representation) {
|
||||
X "$inner<Representation>$($el.representation)</Representation>"
|
||||
@@ -3855,12 +3888,7 @@ function Emit-Commands {
|
||||
X "$inner<Shortcut>$($cmd.shortcut)</Shortcut>"
|
||||
}
|
||||
|
||||
if ($cmd.picture) {
|
||||
X "$inner<Picture>"
|
||||
X "$inner`t<xr:Ref>$($cmd.picture)</xr:Ref>"
|
||||
X "$inner`t<xr:LoadTransparent>$(if ($cmd.loadTransparent -eq $false){'false'}else{'true'})</xr:LoadTransparent>"
|
||||
X "$inner</Picture>"
|
||||
}
|
||||
Emit-CommandPicture -pic $cmd.picture -elemLt $cmd.loadTransparent -indent $inner
|
||||
|
||||
if ($cmd.representation) {
|
||||
X "$inner<Representation>$($cmd.representation)</Representation>"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.62 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.63 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -1784,7 +1784,7 @@ KNOWN_KEYS = {
|
||||
"pagesRepresentation",
|
||||
"type", "command", "commandName", "stdCommand", "defaultButton", "locationInCommandBar",
|
||||
"commandBar", "contextMenu", "commandSource",
|
||||
"src", "valuesPicture", "loadTransparent",
|
||||
"src", "valuesPicture", "loadTransparent", "headerPicture", "footerPicture",
|
||||
"autofill",
|
||||
"choiceMode", "initialTreeView", "enableDrag", "enableStartDrag",
|
||||
"rowSelectionMode", "verticalLines", "horizontalLines",
|
||||
@@ -2215,6 +2215,57 @@ def emit_common_element_props(lines, el, indent):
|
||||
lines.append(f"{indent}<HeaderHorizontalAlign>{el['headerHorizontalAlign']}</HeaderHorizontalAlign>")
|
||||
|
||||
|
||||
def emit_picture_ref(lines, val, pic_tag, indent):
|
||||
"""Картинка-ссылка с прозрачностью (HeaderPicture/FooterPicture/ValuesPicture).
|
||||
Платформа ВСЕГДА эмитит <xr:LoadTransparent> → пишем всегда (false по умолчанию).
|
||||
Значение: скаляр (Ref) ИЛИ объект {src, loadTransparent}."""
|
||||
if not val:
|
||||
return
|
||||
if isinstance(val, str):
|
||||
src, lt = val, False
|
||||
else:
|
||||
src = val.get('src')
|
||||
lt = val.get('loadTransparent') is True
|
||||
if not src:
|
||||
return
|
||||
lines.append(f"{indent}<{pic_tag}>")
|
||||
lines.append(f"{indent}\t<xr:Ref>{src}</xr:Ref>")
|
||||
lines.append(f'{indent}\t<xr:LoadTransparent>{"true" if lt else "false"}</xr:LoadTransparent>')
|
||||
lines.append(f"{indent}</{pic_tag}>")
|
||||
|
||||
|
||||
def emit_column_pics(lines, el, indent):
|
||||
"""Картинки заголовка/подвала колонки поля — по схеме сразу после <EditMode>,
|
||||
перед тип-специфичными элементами и layout (порядок XDTO строгий именно здесь)."""
|
||||
emit_picture_ref(lines, el.get('headerPicture'), 'HeaderPicture', indent)
|
||||
emit_picture_ref(lines, el.get('footerPicture'), 'FooterPicture', indent)
|
||||
|
||||
|
||||
def emit_command_picture(lines, pic, elem_lt, indent):
|
||||
"""<Picture> кнопки/попапа/команды. Дефолт LoadTransparent=true, отклонение false
|
||||
(обратная конвенция относительно header/values-картинок). Прощающий ввод:
|
||||
принимает скаляр (Ref) ИЛИ объект {src, loadTransparent} — на случай если модель
|
||||
опишет картинку объектно по аналогии с headerPicture. elem_lt — legacy
|
||||
элемент-уровневый ключ loadTransparent (если в объекте флаг не задан)."""
|
||||
if not pic:
|
||||
return
|
||||
lt = None
|
||||
if isinstance(pic, str):
|
||||
src = pic
|
||||
else:
|
||||
src = pic.get('src')
|
||||
if pic.get('loadTransparent') is not None:
|
||||
lt = bool(pic.get('loadTransparent'))
|
||||
if not src:
|
||||
return
|
||||
if lt is None and elem_lt is not None:
|
||||
lt = bool(elem_lt)
|
||||
lines.append(f'{indent}<Picture>')
|
||||
lines.append(f'{indent}\t<xr:Ref>{src}</xr:Ref>')
|
||||
lines.append(f'{indent}\t<xr:LoadTransparent>{"false" if lt is False else "true"}</xr:LoadTransparent>')
|
||||
lines.append(f'{indent}</Picture>')
|
||||
|
||||
|
||||
def emit_layout(lines, el, indent, skip_height=False, multi_line_default=False):
|
||||
# Общие layout-свойства — применимы ко всем элементам. Порядок согласован
|
||||
# с историческим выводом input/label, чтобы не сдвигать существующие снапшоты.
|
||||
@@ -2684,6 +2735,7 @@ def emit_input(lines, el, name, eid, indent):
|
||||
lines.append(f'{inner}<AutoMarkIncomplete>true</AutoMarkIncomplete>')
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
emit_column_pics(lines, el, inner)
|
||||
if el.get('textEdit') is False:
|
||||
lines.append(f'{inner}<TextEdit>false</TextEdit>')
|
||||
# InputField-специфичные скаляры (захват «как есть»: платформа эмитит явное не-дефолтное значение)
|
||||
@@ -2721,6 +2773,7 @@ def emit_check(lines, el, name, eid, indent):
|
||||
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
emit_column_pics(lines, el, inner)
|
||||
# CheckBoxType: нет ключа → умный дефолт Auto; "" → подавить; значение → маппинг
|
||||
_cbt_map = {'auto': 'Auto', 'checkbox': 'CheckBox', 'switcher': 'Switcher', 'tumbler': 'Tumbler'}
|
||||
if 'checkBoxType' in el:
|
||||
@@ -2825,6 +2878,7 @@ def emit_label_field(lines, el, name, eid, indent):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
emit_column_pics(lines, el, inner)
|
||||
# ВНИМАНИЕ: у LabelField платформенный тег <Hiperlink> (опечатка 1С), не <Hyperlink>.
|
||||
if el.get('hyperlink') is True:
|
||||
lines.append(f'{inner}<Hiperlink>true</Hiperlink>')
|
||||
@@ -3096,11 +3150,7 @@ def emit_button(lines, el, name, eid, indent, in_cmd_bar=False):
|
||||
lines.append(f'{inner}<DefaultButton>true</DefaultButton>')
|
||||
|
||||
# Picture
|
||||
if el.get('picture'):
|
||||
lines.append(f'{inner}<Picture>')
|
||||
lines.append(f'{inner}\t<xr:Ref>{el["picture"]}</xr:Ref>')
|
||||
lines.append(f'{inner}\t<xr:LoadTransparent>{"false" if el.get("loadTransparent") is False else "true"}</xr:LoadTransparent>')
|
||||
lines.append(f'{inner}</Picture>')
|
||||
emit_command_picture(lines, el.get('picture'), el.get('loadTransparent'), inner)
|
||||
|
||||
if el.get('representation'):
|
||||
lines.append(f'{inner}<Representation>{el["representation"]}</Representation>')
|
||||
@@ -3155,20 +3205,18 @@ def emit_picture_field(lines, el, name, eid, indent):
|
||||
emit_title(lines, el, name, inner)
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
emit_column_pics(lines, el, inner)
|
||||
if el.get('titleLocation'):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
|
||||
emit_layout(lines, el, inner)
|
||||
|
||||
# ValuesPicture \u2014 picture (collection) used to render the field's value.
|
||||
# Required for a Boolean-bound PictureField to actually show an icon.
|
||||
# loadTransparent emitted only when true (1\u0421 default is false).
|
||||
if el.get('valuesPicture'):
|
||||
lines.append(f'{inner}<ValuesPicture>')
|
||||
lines.append(f'{inner}\t<xr:Ref>{el["valuesPicture"]}</xr:Ref>')
|
||||
if el.get('loadTransparent'):
|
||||
lines.append(f'{inner}\t<xr:LoadTransparent>true</xr:LoadTransparent>')
|
||||
lines.append(f'{inner}</ValuesPicture>')
|
||||
|
||||
emit_layout(lines, el, inner)
|
||||
# \u0421\u043a\u0430\u043b\u044f\u0440 (Ref) \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 {src, loadTransparent}; LoadTransparent \u044d\u043c\u0438\u0442\u0438\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430.
|
||||
emit_picture_ref(lines, el.get('valuesPicture'), 'ValuesPicture', inner)
|
||||
|
||||
# Companions
|
||||
emit_companion_panel(lines, 'ContextMenu', f'{name}\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435\u041c\u0435\u043d\u044e', inner, el.get('contextMenu'))
|
||||
@@ -3250,11 +3298,7 @@ def emit_popup(lines, el, name, eid, indent):
|
||||
emit_title(lines, el, name, inner, auto=True)
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('picture'):
|
||||
lines.append(f'{inner}<Picture>')
|
||||
lines.append(f'{inner}\t<xr:Ref>{el["picture"]}</xr:Ref>')
|
||||
lines.append(f'{inner}\t<xr:LoadTransparent>{"false" if el.get("loadTransparent") is False else "true"}</xr:LoadTransparent>')
|
||||
lines.append(f'{inner}</Picture>')
|
||||
emit_command_picture(lines, el.get('picture'), el.get('loadTransparent'), inner)
|
||||
|
||||
if el.get('representation'):
|
||||
lines.append(f'{inner}<Representation>{el["representation"]}</Representation>')
|
||||
@@ -3510,11 +3554,7 @@ def emit_commands(lines, cmds, indent):
|
||||
if cmd.get('shortcut'):
|
||||
lines.append(f'{inner}<Shortcut>{cmd["shortcut"]}</Shortcut>')
|
||||
|
||||
if cmd.get('picture'):
|
||||
lines.append(f'{inner}<Picture>')
|
||||
lines.append(f'{inner}\t<xr:Ref>{cmd["picture"]}</xr:Ref>')
|
||||
lines.append(f'{inner}\t<xr:LoadTransparent>{"false" if cmd.get("loadTransparent") is False else "true"}</xr:LoadTransparent>')
|
||||
lines.append(f'{inner}</Picture>')
|
||||
emit_command_picture(lines, cmd.get('picture'), cmd.get('loadTransparent'), inner)
|
||||
|
||||
if cmd.get('representation'):
|
||||
lines.append(f'{inner}<Representation>{cmd["representation"]}</Representation>')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.44 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.45 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -853,6 +853,20 @@ function Decompile-AttrColumn {
|
||||
}
|
||||
|
||||
# Общие свойства элемента (visible/enabled/readonly/title/events) → в hash
|
||||
# Картинка-ссылка с прозрачностью (HeaderPicture/FooterPicture/ValuesPicture).
|
||||
# Платформа ВСЕГДА эмитит <xr:LoadTransparent> (и true, и false) → дефолт DSL = false.
|
||||
# Скаляр (Ref) при loadTransparent=false; объект {src,loadTransparent:true} при true.
|
||||
function Get-PictureRef {
|
||||
param($node, [string]$picTag)
|
||||
$ref = $node.SelectSingleNode("lf:$picTag/xr:Ref", $ns)
|
||||
if (-not $ref) { return $null }
|
||||
$lt = $node.SelectSingleNode("lf:$picTag/xr:LoadTransparent", $ns)
|
||||
if ($lt -and $lt.InnerText -eq 'true') {
|
||||
return [ordered]@{ src = $ref.InnerText; loadTransparent = $true }
|
||||
}
|
||||
return $ref.InnerText
|
||||
}
|
||||
|
||||
function Add-CommonProps {
|
||||
param($obj, $node, [string]$elName)
|
||||
if ((Get-Child $node 'Visible') -eq 'false') { $obj['hidden'] = $true }
|
||||
@@ -868,6 +882,9 @@ function Add-CommonProps {
|
||||
$ttNode = $node.SelectSingleNode("lf:ToolTip", $ns)
|
||||
if ($ttNode) { $tt = Get-LangText $ttNode; if ($null -ne $tt) { $obj['tooltip'] = $tt } }
|
||||
$ttr = Get-Child $node 'ToolTipRepresentation'; if ($ttr) { $obj['tooltipRepresentation'] = $ttr }
|
||||
# Картинки заголовка/подвала колонки (любой field-тип, эмитятся платформой как column header/footer icon)
|
||||
$hp = Get-PictureRef $node 'HeaderPicture'; if ($null -ne $hp) { $obj['headerPicture'] = $hp }
|
||||
$fp = Get-PictureRef $node 'FooterPicture'; if ($null -ne $fp) { $obj['footerPicture'] = $fp }
|
||||
$ev = Get-Events $node $elName
|
||||
if ($ev) { $obj['events'] = $ev }
|
||||
}
|
||||
@@ -1121,8 +1138,9 @@ function Decompile-Element {
|
||||
$obj[$key] = $name
|
||||
$dp = Get-Child $node 'DataPath'; if ($dp) { $obj['path'] = $dp }
|
||||
Add-CommonProps $obj $node $name
|
||||
$em = Get-Child $node 'EditMode'; if ($em) { $obj['editMode'] = $em }
|
||||
$tl = Get-Child $node 'TitleLocation'; if ($tl) { $obj['titleLocation'] = $tl.ToLower() }
|
||||
$ref = $node.SelectSingleNode("lf:ValuesPicture/xr:Ref", $ns); if ($ref) { $obj['valuesPicture'] = $ref.InnerText }
|
||||
$vp = Get-PictureRef $node 'ValuesPicture'; if ($null -ne $vp) { $obj['valuesPicture'] = $vp }
|
||||
}
|
||||
'CalendarField' {
|
||||
$obj[$key] = $name
|
||||
|
||||
+22
-6
@@ -221,8 +221,24 @@ companion-панели с собственным контентом. Оба не
|
||||
| `autoCellHeight` | `<AutoCellHeight>` | bool — авто-высота ячейки |
|
||||
| `footerHorizontalAlign` | `<FooterHorizontalAlign>` | `Left`/`Right`/`Center` |
|
||||
| `headerHorizontalAlign` | `<HeaderHorizontalAlign>` | `Left`/`Right`/`Center`/`Auto` |
|
||||
| `headerPicture` | `<HeaderPicture>` | Картинка в шапке колонки. Формат — см. «Картинка-ссылка» ниже |
|
||||
| `footerPicture` | `<FooterPicture>` | Картинка в подвале колонки. Формат — см. «Картинка-ссылка» ниже |
|
||||
|
||||
> `defaultItem`/`enableStartDrag`/`fileDragMode`/`skipOnInput` + cell-свойства (`showInHeader`/`showInFooter`/`autoCellHeight`/`footerHorizontalAlign`/`headerHorizontalAlign`) — общие для любого поля-колонки (input, label, picField, check).
|
||||
> `defaultItem`/`enableStartDrag`/`fileDragMode`/`skipOnInput` + cell-свойства (`showInHeader`/`showInFooter`/`autoCellHeight`/`footerHorizontalAlign`/`headerHorizontalAlign`/`headerPicture`/`footerPicture`) — общие для любого поля-колонки (input, label, picField, check).
|
||||
|
||||
#### Картинка-ссылка (`headerPicture`/`footerPicture`/`valuesPicture`)
|
||||
|
||||
Картинка с флагом прозрачности. Два формата:
|
||||
|
||||
```json
|
||||
"headerPicture": "CommonPicture.Важность" // loadTransparent = false (частый случай)
|
||||
"headerPicture": { "src": "StdPicture.ExecuteTask", "loadTransparent": true } // отклонение
|
||||
```
|
||||
|
||||
- скаляр-строка — ссылка `StdPicture.*`/`CommonPicture.*`, `loadTransparent=false` (дефолт по корпусу: ~64% картинок);
|
||||
- объект `{ src, loadTransparent: true }` — только когда нужен `true` (объектная форма существует ровно ради этого отклонения; флаг привязан к конкретной картинке, т.к. на одном поле их бывает несколько).
|
||||
|
||||
> Не путать с `loadTransparent` у `<Picture>` кнопки/команды/попапа (§«button»/§7) — там обратная конвенция (дефолт `true`, отдельный скаляр-ключ на элементе).
|
||||
|
||||
### 4.2. События элемента и автоименование обработчиков
|
||||
|
||||
@@ -499,8 +515,8 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs
|
||||
| `stdCommand` | string | Стандартная команда (→ `Form.StandardCommand.<name>`; `X.Y` → `Form.Item.X.StandardCommand.Y`) |
|
||||
| `type` | string | `usual`, `hyperlink`, `commandBar` |
|
||||
| `defaultButton` | bool | Кнопка по умолчанию |
|
||||
| `picture` | string | Ссылка на картинку (`StdPicture.Name`) |
|
||||
| `loadTransparent` | bool | Загружать картинку прозрачной (у `<Picture>` кнопки/команды/попапа). **Дефолт `true`** (эмитится всегда; `false` — явно). Также у `command` (§7) и `popup` |
|
||||
| `picture` | string \| object | Ссылка на картинку (`StdPicture.Name`). Скаляр-строка ИЛИ объект `{src, loadTransparent}` (прощающий ввод — флаг можно задать прямо в объекте) |
|
||||
| `loadTransparent` | bool | Загружать картинку прозрачной (у `<Picture>` кнопки/команды/попапа). **Дефолт `true`** (эмитится всегда; `false` — явно). Элемент-уровневый ключ ИЛИ поле объекта `picture`. Также у `command` (§7) и `popup`. ⚠️ Полярность обратна `headerPicture`/`valuesPicture` (там дефолт `false`, см. §4.1) |
|
||||
| `path` | string | DataPath кнопки общей команды (`Объект.Ref`, `Items.X.CurrentData.Поле`) — привязка к контексту |
|
||||
| `representation` | string | `Auto`, `Picture`, `Text`, `PictureAndText` |
|
||||
| `locationInCommandBar` | string | `InCommandBar`, `InAdditionalSubmenu` |
|
||||
@@ -529,13 +545,13 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs
|
||||
|
||||
```json
|
||||
{ "picField": "Картинка", "path": "Таблица.Картинка",
|
||||
"valuesPicture": "StdPicture.Favorites", "loadTransparent": true }
|
||||
"valuesPicture": "StdPicture.FilterCriterion" }
|
||||
```
|
||||
|
||||
| Свойство | Тип | Описание |
|
||||
|----------|-----|----------|
|
||||
| `valuesPicture` | string | Ссылка на картинку значения (`StdPicture.*`, `CommonPicture.*`) |
|
||||
| `loadTransparent` | bool | Скрыть кадр «нет значения». Выводится только при `true` |
|
||||
| `valuesPicture` | string \| object | Картинка значения. Формат картинки-ссылки — см. §4.1 «Картинка-ссылка» |
|
||||
| `editMode` | string | Режим редактирования колонки (`EnterOnInput` и т.п.) |
|
||||
|
||||
#### calendar — CalendarField
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
"on": ["Selection"], "handlers": { "Selection": "ТаблицаДанныхВыбор" },
|
||||
"columns": [
|
||||
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
|
||||
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "valuesPicture": "StdPicture.Favorites", "loadTransparent": true },
|
||||
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг" }
|
||||
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "editMode": "EnterOnInput", "headerPicture": "StdPicture.ExecuteTask", "valuesPicture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true } },
|
||||
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } }
|
||||
]}
|
||||
],
|
||||
"attributes": [
|
||||
|
||||
+10
-1
@@ -46,9 +46,14 @@
|
||||
</InputField>
|
||||
<PictureField name="ТаблицаДанныхКартинка" id="17">
|
||||
<DataPath>ТаблицаДанных.Картинка</DataPath>
|
||||
<EditMode>EnterOnInput</EditMode>
|
||||
<HeaderPicture>
|
||||
<xr:Ref>StdPicture.ExecuteTask</xr:Ref>
|
||||
<xr:LoadTransparent>false</xr:LoadTransparent>
|
||||
</HeaderPicture>
|
||||
<TitleLocation>None</TitleLocation>
|
||||
<ValuesPicture>
|
||||
<xr:Ref>StdPicture.Favorites</xr:Ref>
|
||||
<xr:Ref>StdPicture.FilterCriterion</xr:Ref>
|
||||
<xr:LoadTransparent>true</xr:LoadTransparent>
|
||||
</ValuesPicture>
|
||||
<ContextMenu name="ТаблицаДанныхКартинкаКонтекстноеМеню" id="18"/>
|
||||
@@ -62,6 +67,10 @@
|
||||
<v8:content>Флаг</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
<HeaderPicture>
|
||||
<xr:Ref>StdPicture.ClearFilter</xr:Ref>
|
||||
<xr:LoadTransparent>true</xr:LoadTransparent>
|
||||
</HeaderPicture>
|
||||
<CheckBoxType>Auto</CheckBoxType>
|
||||
<TitleLocation>Right</TitleLocation>
|
||||
<ContextMenu name="ТаблицаДанныхКартинкаФлагКонтекстноеМеню" id="21"/>
|
||||
|
||||
Reference in New Issue
Block a user