Files
ctbjrj/tools/migrate_ui.py
T

778 lines
32 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
把旧项目 主窗口.ui.cs 的 UI 迁移到 SharpDevelop 停靠面板项目。
映射:旧 tabControl2/tabControl3 的 9 个页签 → 9 个 DockWindow;
旧 tabControl1(顶部 项目/报价/设置)+ statusStrip1 → MainForm。
仅迁移 UI(控件、属性、布局),事件与逻辑下一阶段迁移。
"""
import io
import re
import os
import sys
SRC = r"F:\pycode\wpf\src\WinFormsDesigner.Fx48\bin\Debug\net48\Samples\COOO\scr\成套报价软件\主窗口.ui.cs"
DST_PROJECT = r"C:\Users\099978\Documents\SharpDevelop Projects\成套报价软件\成套报价软件"
DOCK_MAP = [
("DockWindow", "tabPage3", "项目"),
("DockWindow2", "tabPage4", "报价"),
("DockWindow3", "tabPage10", "选型"),
("DockWindow4", "tabPage5", "元件库"),
("DockWindow5", "tabPage6", "用户库"),
("DockWindow6", "tabPage11", "柜体库"),
("DockWindow7", "tabPage12", "母排"),
("DockWindow8", "tabPage13", "方案"),
("DockWindow9", "tabPage14", "箱体计算"),
]
NAME = r"[A-Za-z0-9_\u4e00-\u9fff]+"
# ---------------------------------------------------------------- 解析
def parse(text):
lines = text.split("\n")
decls = [] # [(name, fulltype)] 按旧文件声明顺序
decls_seen = set()
begin_inits = set()
top_statements = [] # 声明区/尾部区语句(无块头上下文)
blocks = [] # [(header_name, [statement strings])] 属性块
edges = [] # [(parent_key, [child])] Controls.AddRange
ts_edges = [] # [(toolstrip, [items])] ToolStrip Items.AddRange
cur_name = None
cur_stmt = []
cur_lines = []
prev_blank_comment = False
def flush_stmt():
nonlocal cur_stmt
if not cur_stmt:
return
stmt = "\n".join(cur_stmt).strip()
cur_stmt = []
if not stmt:
return
m = re.match(r"this\.(" + NAME + r"(?:\.Panel[12])?)\.Controls\.AddRange\(new System\.Windows\.Forms\.Control\[\] \{(.*?)\}\);", stmt, re.S)
if m:
kids = re.findall(r"this\.(" + NAME + r")(?=[,\s}])", m.group(2))
edges.append((m.group(1), kids))
return
m = re.match(r"this\.Controls\.AddRange\(new System\.Windows\.Forms\.Control\[\] \{(.*?)\}\);", stmt, re.S)
if m:
kids = re.findall(r"this\.(" + NAME + r")(?=[,\s}])", m.group(1))
edges.append(("", kids))
return
m = re.match(r"this\.(" + NAME + r")\.Items\.AddRange\(new System\.Windows\.Forms\.ToolStripItem\[\] \{(.*?)\}\);", stmt, re.S)
if m:
kids = re.findall(r"this\.(" + NAME + r")(?=[,\s}])", m.group(2))
ts_edges.append((m.group(1), kids))
return
m = re.match(r"this\.(" + NAME + r") = new ([\w.]+)\(\);$", stmt)
if m:
if m.group(1) == "components":
return
if m.group(1) not in decls_seen:
decls.append((m.group(1), m.group(2)))
decls_seen.add(m.group(1))
return
if re.match(r"\(\(System\.ComponentModel\.ISupportInitialize\)\(this\.(" + NAME + r")\)\)\.BeginInit\(\);", stmt):
begin_inits.add(re.match(r"\(\(System\.ComponentModel\.ISupportInitialize\)\(this\.(" + NAME + r")\)\)\.BeginInit\(\);", stmt).group(1))
return
if cur_name is not None:
cur_lines.append(stmt)
else:
top_statements.append(stmt)
field_re = re.compile(r"^private [\w.]+ " + NAME + r";$")
for raw in lines:
line = raw.rstrip("\r")
s = line.strip()
if field_re.match(s):
continue
m = re.match(r"^ {12}// (" + NAME + r")$", line)
if m and prev_blank_comment:
flush_stmt()
if cur_name is not None and cur_lines:
blocks.append((cur_name, cur_lines))
cur_name, cur_lines = m.group(1), []
prev_blank_comment = False
continue
prev_blank_comment = (s == "//")
if s.startswith("this.") or s.startswith("((System") or cur_stmt:
cur_stmt.append(s)
if s.endswith(";"):
flush_stmt()
flush_stmt()
if cur_name is not None and cur_lines:
blocks.append((cur_name, cur_lines))
return decls, begin_inits, blocks, top_statements, edges, ts_edges
def classify(blocks):
ctrl_blocks = {}
form_block = []
for name, stmts in blocks:
if name == "主窗口":
form_block = stmts
else:
ctrl_blocks[name] = stmts
return ctrl_blocks, form_block
# ---------------------------------------------------------------- 默认值过滤
DROP_GLOBAL = [
r"\.Enabled = true;$",
r"\.Visible = true;$",
r"\.TabStop = true;$",
r"\.Font = new System\.Drawing\.Font\(\"宋体\", 9F, System\.Drawing\.FontStyle\.Regular, System\.Drawing\.GraphicsUnit\.Point(, 1)?\);$",
r"\.ForeColor = System\.Drawing\.SystemColors\.ControlText;$",
r"\.Margin = new System\.Windows\.Forms\.Padding\((3, 3, 3, 3|0, 0, 0, 0)\);$",
r"\.MaximumSize = new System\.Drawing\.Size\(0, 0\);$",
r"\.MinimumSize = new System\.Drawing\.Size\(0, 0\);$",
r"\.Padding = new System\.Windows\.Forms\.Padding\(0, 0, 0, 0\);$",
r"\.AutoScroll = false;$",
r"\.AutoSize = false;$",
r"\.AutoSizeMode = System\.Windows\.Forms\.AutoSizeMode\.GrowOnly;$",
r"\.AutoValidate = System\.Windows\.Forms\.AutoValidate\.\w+;$",
r"\.AllowDrop = false;$",
r"\.UseWaitCursor = false;$",
r"\.BackgroundImageLayout = System\.Windows\.Forms\.ImageLayout\.Tile;$",
r"\.AutoEllipsis = false;$",
r"\.DialogResult = System\.Windows\.Forms\.DialogResult\.None;$",
r"\.FlatStyle = System\.Windows\.Forms\.FlatStyle\.Standard;$",
r"\.ImageAlign = System\.Drawing\.ContentAlignment\.MiddleCenter;$",
r"\.TextImageRelation = System\.Windows\.Forms\.TextImageRelation\.Overlay;$",
r"\.UseMnemonic = true;$",
r"\.UseCompatibleTextRendering = false;$",
r"\.Cursor = System\.Windows\.Forms\.Cursors\.Default;$",
r"\.ImeMode = System\.Windows\.Forms\.ImeMode\.\w+;$",
r"\.RightToLeft = System\.Windows\.Forms\.RightToLeft\.No;$",
r"\.CauseValidation = true;$",
r"\.Dock = System\.Windows\.Forms\.DockStyle\.None;$",
r"\.GridColor = System\.Drawing\.SystemColors\.ControlDark;$",
r"\.ColumnHeadersVisible = true;$",
r"\.RowHeadersVisible = true;$",
r"\.ShowCellErrors = true;$",
r"\.ShowCellToolTips = true;$",
r"\.ShowEditingIcon = true;$",
r"\.ShowRowErrors = true;$",
r"\.StandardTab = false;$",
r"\.VirtualMode = false;$",
r"\.MultiSelect = true;$",
r"\.ScrollBars = System\.Windows\.Forms\.ScrollBars\.Both;$",
r"\.AllowUserToResizeColumns = true;$",
r"\.AutoSizeColumnsMode = System\.Windows\.Forms\.DataGridViewAutoSizeColumnsMode\.None;$",
r"\.AutoSizeRowsMode = System\.Windows\.Forms\.DataGridViewAutoSizeRowsMode\.None;$",
r"\.ClipboardCopyMode = System\.Windows\.Forms\.DataGridViewClipboardCopyMode\.EnableWithAutoHeaderText;$",
r"\.ColumnHeadersBorderStyle = System\.Windows\.Forms\.DataGridViewHeaderBorderStyle\.Raised;$",
r"\.RowHeadersBorderStyle = System\.Windows\.Forms\.DataGridViewHeaderBorderStyle\.Raised;$",
r"\.RowHeadersWidthSizeMode = System\.Windows\.Forms\.DataGridViewRowHeadersWidthSizeMode\.EnableResizing;$",
r"\.ColumnHeadersHeightSizeMode = System\.Windows\.Forms.DataGridViewColumnHeadersHeightSizeMode\.EnableResizing;$",
r"\.EnableCellPaste = false;$",
r"\.DefaultCellStyle\.BackColor = System\.Drawing\.SystemColors\.Window;$",
r"\.DefaultCellStyle\.ForeColor = System\.Drawing\.SystemColors\.ControlText;$",
r"\.DefaultCellStyle\.SelectionBackColor = System\.Drawing\.SystemColors\.Highlight;$",
r"\.DefaultCellStyle\.SelectionForeColor = System\.Drawing\.SystemColors\.HighlightText;$",
r"\.DefaultCellStyle\.WrapMode = System\.Windows\.Forms\.DataGridViewTriState\.False;$",
r"\.DefaultCellStyle\.Alignment = System\.Windows\.Forms\.DataGridViewContentAlignment\.MiddleLeft;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle|DefaultCellStyle)\.Font = new System\.Drawing\.Font\(\"宋体\", 9F.*\);$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.BackColor = System\.Drawing\.SystemColors\.Control;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.ForeColor = System\.Drawing\.SystemColors\.WindowText;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.SelectionBackColor = System\.Drawing\.SystemColors\.Highlight;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.SelectionForeColor = System\.Drawing\.SystemColors\.HighlightText;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.WrapMode = System\.Windows\.Forms\.DataGridViewTriState\.True;$",
r"\.(ColumnHeadersDefaultCellStyle|RowHeadersDefaultCellStyle)\.Alignment = System\.Windows\.Forms\.DataGridViewContentAlignment\.MiddleLeft;$",
# TextBox / ComboBox 默认值
r"\.AcceptsReturn = false;$",
r"\.AutoCompleteMode = System\.Windows\.Forms\.AutoCompleteMode\.None;$",
r"\.AutoCompleteSource = System\.Windows\.Forms\.AutoCompleteSource\.None;$",
r"\.CharacterCasing = System\.Windows\.Forms\.CharacterCasing\.Normal;$",
r"\.Multiline = false;$",
r"\.UseSystemPasswordChar = false;$",
r"\.AcceptsTab = false;$",
r"\.ShortcutsEnabled = true;$",
r"\.HideSelection = true;$",
r"\.WordWrap = true;$",
r"\.MaxLength = 32767;$",
r"\.MaxLength = 0;$",
r"\.ReadOnly = false;$",
r"\.ScrollBars = System\.Windows\.Forms\.ScrollBars\.None;$",
r"\.TextAlign = System\.Windows\.Forms\.HorizontalAlignment\.Left;$",
r"\.BorderStyle = System\.Windows\.Forms\.BorderStyle\.Fixed3D;$",
r"\.DrawMode = System\.Windows\.Forms\.DrawMode\.Normal;$",
r"\.IntegralHeight = true;$",
r"\.MaxDropDownItems = 8;$",
r"\.Sorted = false;$",
r"\.DropDownStyle = System\.Windows\.Forms\.ComboBoxStyle\.DropDown;$",
r"\.CanOverflow = true;$",
r"\.AllowItemReorder = false;$",
r"\.AllowMerge = true;$",
r"\.GripMargin = new System\.Windows\.Forms\.Padding\(2, 2, 2, 2\);$",
r"\.ImageScalingSize = new System\.Drawing\.Size\(16, 16\);$",
r"\.LayoutStyle = System\.Windows\.Forms\.ToolStripLayoutStyle\.HorizontalStackWithOverflow;$",
r"\.Stretch = false;$",
r"\.RenderMode = System\.Windows\.Forms\.ToolStripRenderMode\.ManagerRenderMode;$",
r"\.ShowItemToolTips = true;$",
r"\.TextDirection = System\.Windows\.Forms\.ToolStripTextDirection\.Horizontal;$",
r"\.Padding = new System\.Windows\.Forms\.Padding\(0, 0, 1, 0\);$",
]
DROP_BY_TYPE = {
"Panel": [r"\.BorderStyle = System\.Windows\.Forms\.BorderStyle\.None;$",
r"\.BackColor = System\.Drawing\.SystemColors\.Control;$"],
"SplitContainer": [
r"\.BorderStyle = System\.Windows\.Forms\.BorderStyle\.None;$",
r"\.FixedPanel = System\.Windows\.Forms\.FixedPanel\.None;$",
r"\.IsSplitterFixed = false;$",
r"\.Orientation = System\.Windows\.Forms\.Orientation\.Vertical;$",
r"\.Panel1Collapsed = false;$",
r"\.Panel2Collapsed = false;$",
r"\.Panel1MinSize = 25;$",
r"\.Panel2MinSize = 25;$",
r"\.SplitterIncrement = 1;$",
r"\.SplitterWidth = 4;$",
r"\.BackColor = System\.Drawing\.SystemColors\.Control;$",
],
"TabControl": [
r"\.Alignment = System\.Windows\.Forms\.TabAlignment\.Top;$",
r"\.Appearance = System\.Windows\.Forms\.TabAppearance\.Normal;$",
r"\.DrawMode = System\.Windows\.Forms\.TabDrawMode\.Normal;$",
r"\.HotTrack = false;$",
r"\.Multiline = false;$",
r"\.RightToLeftLayout = false;$",
r"\.ShowToolTips = false;$",
r"\.BackColor = System\.Drawing\.SystemColors\.Control;$",
],
"TabPage": [
r"\.BorderStyle = System\.Windows\.Forms\.BorderStyle\.None;$",
r"\.AutoScrollMargin = new System\.Drawing\.Size\(0, 0\);$",
r"\.AutoScrollMinSize = new System\.Drawing\.Size\(0, 0\);$",
],
"Button": [
r"\.BackColor = System\.Drawing\.SystemColors\.Control;$",
r"\.TextAlign = System\.Drawing\.ContentAlignment\.MiddleCenter;$",
],
"Label": [
r"\.BackColor = System\.Drawing\.SystemColors\.Control;$",
],
}
DROP_GLOBAL_C = [re.compile(p) for p in DROP_GLOBAL]
DROP_BY_TYPE_C = {k: [re.compile(p) for p in v] for k, v in DROP_BY_TYPE.items()}
def short_type(t):
return t.split(".")[-1]
def should_drop(stmt, stype):
for c in DROP_GLOBAL_C:
if c.search(stmt):
return True
for c in DROP_BY_TYPE_C.get(stype, []):
if c.search(stmt):
return True
return False
# ---------------------------------------------------------------- 列转换
def extract_columns(stmts):
cols = []
rest = []
for st in stmts:
m = re.match(r"this\.(" + NAME + r")\.Columns\.Add\(new System\.Windows\.Forms\.(\w+)\(\)\);$", st, re.S)
if m:
cols.append({"type": m.group(2), "props": []})
continue
m = re.match(r"this\.(" + NAME + r")\.Columns\[(\d+)\]\.([\w.]+) = (.*);$", st, re.S)
if m:
idx = int(m.group(2))
while len(cols) <= idx:
cols.append({"type": "DataGridViewTextBoxColumn", "props": []})
cols[idx]["props"].append((m.group(3), m.group(4)))
continue
rest.append(st)
return rest, cols
COL_DROP_VALUE = {
"Visible": "true",
"Frozen": "false",
"AutoSizeMode": "System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet",
"Width": "100",
"Resizable": "System.Windows.Forms.DataGridViewTriState.True",
}
def column_lines(col):
out = []
for prop, val in col["props"]:
if prop in COL_DROP_VALUE and val == COL_DROP_VALUE[prop]:
continue
if prop == "Name" and val == '""':
continue
out.append((prop, val))
return out
# ---------------------------------------------------------------- 子树工具
def build_children(edges):
ch = {}
for parent, kids in edges:
ch.setdefault(parent, []).extend(kids)
return ch
def subtree(root, ch):
out = []
stack = [root]
while stack:
n = stack.pop(0)
out.append(n)
stack = ch.get(n, []) + ch.get(n + ".Panel1", []) + ch.get(n + ".Panel2", []) + stack
return out
# ---------------------------------------------------------------- 通用块生成
def plan_columns(ordered, ctrl_blocks):
"""预规划列字段:返回 {grid: [(fname, col)]},字段按 ordered 顺序编号"""
plan = {}
n = 0
for g in ordered:
_rest, cols = extract_columns(ctrl_blocks.get(g, []))
if cols:
flist = []
for col in cols:
n += 1
flist.append(("dataGridViewTextBoxColumn%d" % n, col))
plan[g] = flist
return plan
def emit_control_blocks(ordered, decl_types, ctrl_blocks, ts_edges, col_plan, a):
"""生成属性块"""
for n in ordered:
stype = short_type(decl_types[n])
stmts = ctrl_blocks.get(n, [])
rest, cols = extract_columns(stmts)
# 工具栏项
ts_items = None
for parent, kk in ts_edges:
if parent == n:
ts_items = kk
if not rest and not cols and ts_items is None:
continue
if n in col_plan:
for fname, col in col_plan[n]:
a("\t\t\t// ")
a("\t\t\t// %s" % fname)
a("\t\t\t// ")
for prop, val in column_lines(col):
a("\t\t\tthis.%s.%s = %s;" % (fname, prop, val))
a("\t\t\t// ")
a("\t\t\t// %s" % n)
a("\t\t\t// ")
for st in rest:
if should_drop(st, stype):
continue
a("\t\t\t" + st.replace("\n", "\n\t\t\t"))
if cols:
inner = ",\n\t\t\t\t".join("this.%s" % fname for fname, _c in col_plan[n])
a("\t\t\tthis.%s.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {" % n)
a("\t\t\t\t" + inner + "});")
if ts_items is not None:
inner = ",\n\t\t\t\t".join("this.%s" % k for k in ts_items)
a("\t\t\tthis.%s.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {" % n)
a("\t\t\t\t" + inner + "});")
TEMPLATE = """namespace 成套报价软件
{{
partial class {cls}
{{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
{fields}
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{{
if (disposing && (components != null)) {{
components.Dispose();
}}
base.Dispose(disposing);
}}
#region Designer generated code
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{{
{body}
}}
#endregion
}}
}}
"""
def emit_decls(ordered, decl_types, begin_inits, a):
for n in ordered:
a("\t\t\tthis.%s = new %s();" % (n, decl_types[n]))
if n in begin_inits:
a("\t\t\t((System.ComponentModel.ISupportInitialize)(this.%s)).BeginInit();" % n)
def emit_hierarchy(ordered_set, edges, ch, a, root=None):
"""输出容器层级;root 的孩子挂 this"""
for parent, kids in edges:
if parent == "":
continue
if parent == root:
target = "this"
else:
base = parent.split(".")[0]
if base not in ordered_set:
continue
target = "this." + parent
if not kids:
continue
inner = ",\n\t\t\t\t".join("this.%s" % k for k in kids)
a("\t\t\t%s.Controls.AddRange(new System.Windows.Forms.Control[] {" % target)
a("\t\t\t\t" + inner + "});")
def gen_dockwindow(cls, tab, title, decls, decl_types, begin_inits, ctrl_blocks, ch, edges, ts_edges, splitter_map):
members = subtree(tab, ch)
members.remove(tab)
members_set = set(members)
ordered = [n for n, _t in decls if n in members_set]
# 工具栏项不在 Controls 层级里,补进来
for parent, kids in ts_edges:
if parent in members_set:
for k in kids:
if k not in ordered:
ordered.append(k)
tab_size = (800, 600)
for st in ctrl_blocks.get(tab, []):
m = re.match(r"this\.(" + NAME + r")\.Size = new System\.Drawing\.Size\((\d+), (\d+)\);$", st)
if m:
tab_size = (int(m.group(2)), int(m.group(3)))
L = []
a = L.append
a("\t\t\tthis.components = new System.ComponentModel.Container();")
emit_decls(ordered, decl_types, begin_inits, a)
col_plan = plan_columns(ordered, ctrl_blocks)
for flist in col_plan.values():
for fname, _c in flist:
a("\t\t\tthis.%s = new System.Windows.Forms.DataGridViewTextBoxColumn();" % fname)
a("\t\t\tthis.SuspendLayout();")
emit_control_blocks(ordered, decl_types, ctrl_blocks, ts_edges, col_plan, a)
# 层级
emit_hierarchy(members_set, edges, ch, a, root=tab)
a("\t\t\t// ")
a("\t\t\t// %s" % cls)
a("\t\t\t// ")
a("\t\t\tthis.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);")
a("\t\t\tthis.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;")
a("\t\t\tthis.ClientSize = new System.Drawing.Size(%d, %d);" % tab_size)
a("\t\t\tthis.Name = \"%s\";" % cls)
a("\t\t\tthis.Text = \"%s\";" % title)
for n in ordered:
if n in begin_inits:
a("\t\t\t((System.ComponentModel.ISupportInitialize)(this.%s)).EndInit();" % n)
a("\t\t\tthis.ResumeLayout(false);")
a("\t\t\tthis.PerformLayout();")
for n in ordered:
if n in splitter_map:
a("\t\t\tthis.%s.SplitterDistance = %d;" % (n, splitter_map[n]))
fields = ["\t\tprivate %s %s;" % (decl_types[n], n) for n in ordered]
for flist in col_plan.values():
for fname, _c in flist:
fields.append("\t\tprivate System.Windows.Forms.DataGridViewTextBoxColumn %s;" % fname)
return TEMPLATE.format(cls=cls, body="\n".join(L), fields="\n".join(fields))
# ---------------------------------------------------------------- MainForm
def gen_mainform(decls, decl_types, begin_inits, ctrl_blocks, ch, edges, ts_edges, splitter_map):
# MainForm 使用的旧控件:tabControl1 三页签的子树 + statusStrip1
main_roots = ["tabPage1", "tabPage2", "tabPage8"]
members = set()
for r in main_roots:
members.update(subtree(r, ch))
members.remove("tabPage1"); members.remove("tabPage2"); members.remove("tabPage8")
members.add("statusStrip1")
ordered = [n for n, _t in decls if n in members]
for parent, kids in ts_edges:
if parent in members:
for k in kids:
if k not in ordered:
ordered.append(k)
L = []
a = L.append
for i in range(1, 10):
a("\t\t\tSmart.CustomComponents.DockWindows.DockWindowItem dockWindowItem%d = new Smart.CustomComponents.DockWindows.DockWindowItem();" % i)
a("\t\t\tthis.tabControl1 = new System.Windows.Forms.TabControl();")
a("\t\t\tthis.tabPage1 = new System.Windows.Forms.TabPage();")
a("\t\t\tthis.tabPage2 = new System.Windows.Forms.TabPage();")
a("\t\t\tthis.tabPage3 = new System.Windows.Forms.TabPage();")
for n in ordered:
a("\t\t\tthis.%s = new %s();" % (n, decl_types[n]))
a("\t\t\tthis.dockSurface1 = new Smart.CustomComponents.DockSurface();")
col_plan = plan_columns(ordered, ctrl_blocks)
for flist in col_plan.values():
for fname, _c in flist:
a("\t\t\tthis.%s = new System.Windows.Forms.DataGridViewTextBoxColumn();" % fname)
a("\t\t\tthis.tabControl1.SuspendLayout();")
a("\t\t\tthis.SuspendLayout();")
emit_control_blocks(ordered, decl_types, ctrl_blocks, ts_edges, col_plan, a)
# tabControl1 属性(旧值 + 新尺寸)
a("\t\t\t// ")
a("\t\t\t// tabControl1")
a("\t\t\t// ")
tc_props = []
for st in ctrl_blocks.get("tabControl1", []):
if should_drop(st, "TabControl"):
continue
if re.search(r"\.(Size|Location|Name|TabIndex|Dock) = ", st):
continue
tc_props.append(st)
for st in tc_props:
a("\t\t\t" + st)
a("\t\t\tthis.tabControl1.Dock = System.Windows.Forms.DockStyle.Top;")
a("\t\t\tthis.tabControl1.Location = new System.Drawing.Point(0, 0);")
a("\t\t\tthis.tabControl1.Name = \"tabControl1\";")
a("\t\t\tthis.tabControl1.SelectedIndex = 0;")
a("\t\t\tthis.tabControl1.Size = new System.Drawing.Size(1884, 111);")
a("\t\t\tthis.tabControl1.TabIndex = 0;")
# 三个页签
for old, new, text in [("tabPage1", "tabPage1", "项目"), ("tabPage2", "tabPage2", "报价"), ("tabPage8", "tabPage3", "设置")]:
a("\t\t\t// ")
a("\t\t\t// %s" % new)
a("\t\t\t// ")
kids = ch.get(old, [])
if kids:
inner = ",\n\t\t\t\t".join("this.%s" % k for k in kids)
a("\t\t\tthis.%s.Controls.AddRange(new System.Windows.Forms.Control[] {" % new)
a("\t\t\t\t" + inner + "});")
for st in ctrl_blocks.get(old, []):
if should_drop(st, "TabPage"):
continue
if re.search(r"\.(Size|Location|Name|TabIndex|Padding|Text|BackColor) = ", st):
continue
a("\t\t\t" + re.sub(r"^this\.%s\b" % old, "this.%s" % new, st))
a("\t\t\tthis.%s.Location = new System.Drawing.Point(4, 22);" % new)
a("\t\t\tthis.%s.Name = \"%s\";" % (new, new))
a("\t\t\tthis.%s.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);" % new)
a("\t\t\tthis.%s.Size = new System.Drawing.Size(1876, 82);" % new)
a("\t\t\tthis.%s.TabIndex = %d;" % (new, ["tabPage1", "tabPage2", "tabPage3"].index(new)))
a("\t\t\tthis.%s.Text = \"%s\";" % (new, text))
a("\t\t\tthis.%s.UseVisualStyleBackColor = true;" % new)
# statusStrip1
a("\t\t\t// ")
a("\t\t\t// statusStrip1")
a("\t\t\t// ")
for st in ctrl_blocks.get("statusStrip1", []):
if should_drop(st, "StatusStrip"):
continue
if re.search(r"\.(Location|Size|Name|TabIndex) = ", st):
continue
a("\t\t\t" + st)
a("\t\t\tthis.statusStrip1.Dock = System.Windows.Forms.DockStyle.Bottom;")
a("\t\t\tthis.statusStrip1.Location = new System.Drawing.Point(0, 932);")
a("\t\t\tthis.statusStrip1.Name = \"statusStrip1\";")
a("\t\t\tthis.statusStrip1.Size = new System.Drawing.Size(1884, 22);")
a("\t\t\tthis.statusStrip1.TabIndex = 2;")
# dockSurface1(保持现有内容)
a("\t\t\t// ")
a("\t\t\t// dockSurface1")
a("\t\t\t// ")
a("\t\t\tthis.dockSurface1.Dock = System.Windows.Forms.DockStyle.Fill;")
a("\t\t\tthis.dockSurface1.DockBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(242)))));")
a("\t\t\tdockWindowItem1.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;")
a("\t\t\tdockWindowItem1.Title = \"项目\";")
a("\t\t\tdockWindowItem2.ClassName = \"DockWindow2\";")
a("\t\t\tdockWindowItem2.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;")
a("\t\t\tdockWindowItem2.Title = \"报价\";")
a("\t\t\tdockWindowItem3.ClassName = \"DockWindow3\";")
a("\t\t\tdockWindowItem3.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;")
a("\t\t\tdockWindowItem3.Title = \"选型\";")
a("\t\t\tdockWindowItem4.ClassName = \"DockWindow4\";")
a("\t\t\tdockWindowItem4.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem4.Title = \"元件库\";")
a("\t\t\tdockWindowItem5.ClassName = \"DockWindow5\";")
a("\t\t\tdockWindowItem5.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem5.Title = \"用户库\";")
a("\t\t\tdockWindowItem6.ClassName = \"DockWindow6\";")
a("\t\t\tdockWindowItem6.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem6.Title = \"柜体库\";")
a("\t\t\tdockWindowItem7.ClassName = \"DockWindow7\";")
a("\t\t\tdockWindowItem7.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem7.Title = \"母排\";")
a("\t\t\tdockWindowItem8.ClassName = \"DockWindow8\";")
a("\t\t\tdockWindowItem8.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem8.Title = \"方案\";")
a("\t\t\tdockWindowItem9.ClassName = \"DockWindow9\";")
a("\t\t\tdockWindowItem9.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockRight;")
a("\t\t\tdockWindowItem9.Title = \"箱体计算\";")
for i in range(1, 10):
a("\t\t\tthis.dockSurface1.DockWindows.Add(dockWindowItem%d);" % i)
a("\t\t\tthis.dockSurface1.Location = new System.Drawing.Point(0, 111);")
a("\t\t\tthis.dockSurface1.Name = \"dockSurface1\";")
a("\t\t\tthis.dockSurface1.Padding = new System.Windows.Forms.Padding(6);")
a("\t\t\tthis.dockSurface1.ShowAutoHideContentOnHover = false;")
a("\t\t\tthis.dockSurface1.Size = new System.Drawing.Size(1884, 821);")
a("\t\t\tthis.dockSurface1.TabIndex = 1;")
# 窗体
a("\t\t\t// ")
a("\t\t\t// MainForm")
a("\t\t\t// ")
a("\t\t\tthis.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);")
a("\t\t\tthis.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;")
a("\t\t\tthis.ClientSize = new System.Drawing.Size(1884, 954);")
a("\t\t\tthis.Controls.Add(this.dockSurface1);")
a("\t\t\tthis.Controls.Add(this.statusStrip1);")
a("\t\t\tthis.Controls.Add(this.tabControl1);")
a("\t\t\tthis.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);")
a("\t\t\tthis.Name = \"MainForm\";")
a("\t\t\tthis.Text = \"成套报价软件\";")
a("\t\t\tthis.tabControl1.ResumeLayout(false);")
a("\t\t\tthis.ResumeLayout(false);")
a("\t\t\tthis.PerformLayout();")
fields = []
fields.append("\t\tprivate System.Windows.Forms.TabControl tabControl1;")
fields.append("\t\tprivate System.Windows.Forms.TabPage tabPage1;")
fields.append("\t\tprivate System.Windows.Forms.TabPage tabPage2;")
fields.append("\t\tprivate System.Windows.Forms.TabPage tabPage3;")
for n in ordered:
fields.append("\t\tprivate %s %s;" % (decl_types[n], n))
fields.append("\t\tprivate Smart.CustomComponents.DockSurface dockSurface1;")
for flist in col_plan.values():
for fname, _c in flist:
fields.append("\t\tprivate System.Windows.Forms.DataGridViewTextBoxColumn %s;" % fname)
header = """/*
* 由SharpDevelop创建。
* 用户: 099978
* 日期: 2026-08-25
* 时间: 20:59
*
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
*/
namespace 成套报价软件
{
partial class MainForm
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
%s
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
%s
}
}
}
""" % ("\n".join(fields), "\n".join(L))
return header
# ---------------------------------------------------------------- main
def main():
text = io.open(SRC, encoding="utf-8-sig").read()
decls, begin_inits, blocks, top_statements, edges, ts_edges = parse(text)
ctrl_blocks, form_block = classify(blocks)
ch = build_children(edges)
decl_types = dict(decls)
splitter_map = {}
for st in form_block + top_statements:
m = re.match(r"this\.(" + NAME + r")\.SplitterDistance = (\d+);$", st)
if m:
splitter_map[m.group(1)] = int(m.group(2))
missing = [t for _c, t, _ti in DOCK_MAP if t not in decl_types]
if missing:
print("缺少页签:", missing)
sys.exit(1)
for cls, tab, title in DOCK_MAP:
out = gen_dockwindow(cls, tab, title, decls, decl_types, begin_inits, ctrl_blocks, ch, edges, ts_edges, splitter_map)
path = os.path.join(DST_PROJECT, "DockWindows", cls, cls + ".Designer.cs")
io.open(path, "w", encoding="utf-8-sig", newline="\r\n").write(out)
n_ctrl = len(subtree(tab, ch)) - 1
print("生成 %-60s ← %-9s (%s) 控件%d个" % (path, tab, title, n_ctrl))
mf = gen_mainform(decls, decl_types, begin_inits, ctrl_blocks, ch, edges, ts_edges, splitter_map)
path = os.path.join(DST_PROJECT, "MainForm.Designer.cs")
io.open(path, "w", encoding="utf-8-sig", newline="\r\n").write(mf)
print("生成", path)
# 覆盖检查
covered = set()
for _c, tab, _t in DOCK_MAP:
covered.update(subtree(tab, ch))
main_used = set(["tabControl1", "tabControl2", "tabControl3", "splitContainer1", "statusStrip1"])
for r in ["tabControl1", "statusStrip1"]:
main_used.update(subtree(r, ch))
leftover = [n for n, _ in decls if n not in covered and n not in main_used]
print("未覆盖控件:", leftover)
# 边完整性检查
all_kids = [k for _p, kk in edges for k in kk]
no_parent = [k for k in all_kids if k not in decl_types]
print("边中未声明的子控件:", no_parent)
if __name__ == "__main__":
main()