261 lines
16 KiB
C#
261 lines
16 KiB
C#
// 关于软件:经典关于页模板(页头 图标/名称/版本/简介 + 选项卡 功能介绍|开源致谢 + 底部版权栏)
|
||
// 富文本用 SelectionColor/Font 逐段设置(■ 小节标题深蓝加粗、协议名按协议配色,纯 WinForms 无新依赖)
|
||
using System;
|
||
using System.Drawing;
|
||
using System.Windows.Forms;
|
||
|
||
namespace 成套报价软件
|
||
{
|
||
public partial class 关于软件 : Form
|
||
{
|
||
public 关于软件()
|
||
{
|
||
InitializeComponent();
|
||
this.BackColor = System.Drawing.Color.White;
|
||
|
||
// 页头排版在 Load 里做(AutoScale 完成后):版本号紧随软件名实际宽度、
|
||
// 简介对齐软件名左侧,避免高 DPI 下固定坐标互相压字;图标 Zoom 充满框
|
||
pic图标.SizeMode = PictureBoxSizeMode.Zoom;
|
||
// ★ 版本号从程序集读取(唯一事实源=AssemblyInfo 的 AssemblyVersion,递增后这里自动跟随;
|
||
// Designer 里的 v1.0.0 只是设计期占位文本)。显示三段:主.次.修订
|
||
lbl版本.Text = "v" + System.Reflection.Assembly.GetExecutingAssembly()
|
||
.GetName().Version.ToString(3);
|
||
this.Load += (s, e) =>
|
||
{
|
||
try
|
||
{
|
||
lbl版本.Left = lbl软件名.Right + 12;
|
||
lbl版本.Top = lbl软件名.Top + Math.Max(0, (lbl软件名.Height - lbl版本.Height) / 2);
|
||
lbl简介.Left = lbl软件名.Left;
|
||
lbl简介.Top = lbl软件名.Bottom + 4;
|
||
using (var ic = Icon.ExtractAssociatedIcon(Application.ExecutablePath))
|
||
pic图标.Image = new Bitmap(ic.ToBitmap(), pic图标.Width, pic图标.Height);
|
||
}
|
||
catch { }
|
||
};
|
||
|
||
填功能介绍();
|
||
填开源致谢();
|
||
}
|
||
|
||
// ---------- 富文本辅助:追加一段带样式的文本 ----------
|
||
private static void 追加(RichTextBox rtb, string text, Color color, bool bold, float size)
|
||
{
|
||
rtb.SelectionStart = rtb.TextLength;
|
||
rtb.SelectionLength = 0;
|
||
rtb.SelectionColor = color;
|
||
rtb.SelectionFont = new Font("Microsoft YaHei UI", size, bold ? FontStyle.Bold : FontStyle.Regular);
|
||
rtb.AppendText(text);
|
||
rtb.SelectionColor = rtb.ForeColor;
|
||
rtb.SelectionFont = rtb.Font;
|
||
}
|
||
private static void 标题(RichTextBox rtb, string text)
|
||
{
|
||
追加(rtb, text + "\r\n", Color.FromArgb(43, 87, 154), true, 10.5f); // 深蓝粗
|
||
}
|
||
private static void 条目(RichTextBox rtb, string text)
|
||
{
|
||
追加(rtb, text + "\r\n", SystemColors.WindowText, false, 9f);
|
||
}
|
||
private static void 协议(RichTextBox rtb, string name)
|
||
{
|
||
// 协议配色(徽章感):MIT 绿 / Apache 橙 / BSD 蓝 / ISC 紫 / MS-PL 青 / 公有领域 灰 / 微软条款 深灰
|
||
Color c = Color.Gray;
|
||
if (name.IndexOf("MIT", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(33, 115, 70);
|
||
else if (name.IndexOf("Apache", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(200, 102, 30);
|
||
else if (name.IndexOf("BSD", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(43, 87, 154);
|
||
else if (name.IndexOf("ISC", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(122, 82, 168);
|
||
else if (name.IndexOf("MS-PL", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(0, 138, 158);
|
||
else if (name.IndexOf("公有领域", StringComparison.Ordinal) >= 0 || name.IndexOf("Public", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.DimGray;
|
||
else if (name.IndexOf("微软", StringComparison.Ordinal) >= 0) c = Color.DimGray;
|
||
追加(rtb, "[" + name + "]", c, true, 9f);
|
||
}
|
||
private static void 空行(RichTextBox rtb) { 追加(rtb, "\r\n", SystemColors.WindowText, false, 4f); }
|
||
|
||
// ---------- 选项卡一:功能介绍 ----------
|
||
private void 填功能介绍()
|
||
{
|
||
var rtb = txt功能;
|
||
rtb.ReadOnly = false; // 追加着色需要,结束后置回只读
|
||
|
||
标题(rtb, "■ 项目管理");
|
||
条目(rtb, " 新建 / 修改 / 删除 / 复制项目,zip 项目包导入导出,最近项目自动恢复。");
|
||
空行(rtb);
|
||
标题(rtb, "■ 报价三表");
|
||
条目(rtb, " 图号 / 箱号 / 元件三级联动;虚拟模式万行秒开;编辑实时保存;");
|
||
条目(rtb, " 公式自动计算(成本价 / 报出价 / 利润 / 毛利率,公式可自定义);");
|
||
条目(rtb, " 批量粘贴 / 删除 / 撤销,行移动排序。");
|
||
空行(rtb);
|
||
标题(rtb, "■ CAD 扒图");
|
||
条目(rtb, " 网页 CAD 查看器打开 DWG/DXF 图纸;框选扒图号 / 箱号 / 扒元件;");
|
||
条目(rtb, " 箱号自动记图纸名,元件记图纸规格原文;F1/F2/F3 元件合并;");
|
||
条目(rtb, " 表格点行定位图上蒙版、删行删框。");
|
||
空行(rtb);
|
||
标题(rtb, "■ PDF 扒图");
|
||
条目(rtb, " PDF 渲染查看 + 框选 OCR,五种引擎:百度高精度 / 智谱 GLM-OCR /");
|
||
条目(rtb, " 百度千帆 PaddleOCR-VL / UApiPro / Umi-OCR 本地离线;自动纠正文本");
|
||
条目(rtb, " 方向;图形符号误读过滤;入库 / 合并 / 定位同 CAD 扒图。");
|
||
空行(rtb);
|
||
标题(rtb, "■ 元件库与选型");
|
||
条目(rtb, " 厂家 / 系列 / 价格网页选型;收藏一键跳转系列;选中即插入报价;");
|
||
条目(rtb, " 方案库独立库文件双击打开;用户库 / 柜体库管理与 CSV 导入导出。");
|
||
空行(rtb);
|
||
标题(rtb, "■ 计算与报表");
|
||
条目(rtb, " GCS 母排计算与铜排推荐;批量调系数;元件排序;甲方报表导出。");
|
||
空行(rtb);
|
||
标题(rtb, "■ 其它");
|
||
条目(rtb, " 停靠布局保存恢复;数据备份与恢复;功能区页签与窗口双向联动;登录门禁。");
|
||
|
||
rtb.ReadOnly = true;
|
||
rtb.SelectionStart = 0; rtb.SelectionLength = 0; rtb.ScrollToCaret();
|
||
}
|
||
|
||
// ---------- 选项卡二:开源致谢(TreeView 树形折叠,默认全部收起) ----------
|
||
|
||
/// <summary>建父节点:标题行「组件名 [协议] 用途」,子节点=版权/要求/查看全文。默认折叠。
|
||
/// 许可文件覆盖:同协议但需展示某组件自带许可证全文时指定(如 ZCode 的 Apache-2.0-ZCode.txt)。</summary>
|
||
private TreeNode 建节点(string 标题, string 协议名, string 副标题, string[] 子节点文本, string 许可文件覆盖 = null)
|
||
{
|
||
string text = 标题;
|
||
if (!string.IsNullOrEmpty(协议名)) text += " [" + 协议名 + "]";
|
||
if (!string.IsNullOrEmpty(副标题)) text += " —— " + 副标题;
|
||
var n = new TreeNode(text);
|
||
n.NodeFont = new Font("Microsoft YaHei UI", 9F, FontStyle.Bold);
|
||
n.ForeColor = SystemColors.WindowText;
|
||
foreach (var t in 子节点文本)
|
||
{
|
||
var c = new TreeNode(t);
|
||
c.NodeFont = new Font("Microsoft YaHei UI", 9F);
|
||
c.ForeColor = t.StartsWith("协议要求") || t.StartsWith("修改")
|
||
? Color.FromArgb(80, 80, 80) : Color.DimGray;
|
||
n.Nodes.Add(c);
|
||
}
|
||
// ★ 追加「查看许可证全文」链接子节点(按协议名映射 licenses 文件;协议为空不加)
|
||
string 许可文件 = 许可文件覆盖 ?? 许可证文件名(协议名);
|
||
if (许可文件 != null)
|
||
{
|
||
var link = new TreeNode("查看许可证全文 →");
|
||
link.NodeFont = new Font("Microsoft YaHei UI", 9F, FontStyle.Underline);
|
||
link.ForeColor = Color.FromArgb(43, 87, 154);
|
||
link.Tag = new string[] { 协议名, 许可文件 }; // 点击时取出
|
||
n.Nodes.Add(link);
|
||
}
|
||
return n; // 新节点默认收起,不调 ExpandAll 即全部折叠
|
||
}
|
||
|
||
/// <summary>协议名 → licenses 目录文件名(无对应文件的返回 null)。
|
||
/// Umi-OCR 的 "MIT / Apache-2.0" 双协议按 Apache-2.0 全文展示(MIT 全文见其它 MIT 条目)。</summary>
|
||
private static string 许可证文件名(string 协议名)
|
||
{
|
||
if (string.IsNullOrEmpty(协议名)) return null;
|
||
if (协议名.IndexOf("Apache", StringComparison.OrdinalIgnoreCase) >= 0) return "Apache-2.0.txt";
|
||
if (协议名.IndexOf("BSD", StringComparison.OrdinalIgnoreCase) >= 0) return "BSD-3-Clause.txt";
|
||
if (协议名.IndexOf("ISC", StringComparison.OrdinalIgnoreCase) >= 0) return "ISC.txt";
|
||
if (协议名.IndexOf("MS-PL", StringComparison.OrdinalIgnoreCase) >= 0) return "MS-PL.txt";
|
||
if (协议名.IndexOf("公有领域", StringComparison.Ordinal) >= 0) return "PublicDomain.txt";
|
||
if (协议名.IndexOf("微软", StringComparison.Ordinal) >= 0) return "WebView2-terms.txt";
|
||
if (协议名.IndexOf("MIT", StringComparison.OrdinalIgnoreCase) >= 0) return "MIT.txt";
|
||
return null;
|
||
}
|
||
|
||
private void tree开源_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
|
||
{
|
||
// 点「查看许可证全文 →」子节点 → 弹窗显示该协议标准全文
|
||
var arr = e.Node.Tag as string[];
|
||
if (arr != null && arr.Length == 2)
|
||
{
|
||
using (var dlg = new 许可证文本(arr[0], arr[1]))
|
||
dlg.ShowDialog(this);
|
||
}
|
||
}
|
||
|
||
private void 填开源致谢()
|
||
{
|
||
var tv = tree开源;
|
||
tv.BeginUpdate();
|
||
tv.Nodes.Clear();
|
||
|
||
// ---- 开源组件(13 项):子节点=版权声明 + 协议要求 ----
|
||
tv.Nodes.Add(建节点("WeifenLuo WinFormsUI Docking", "MIT", "停靠窗口框架",
|
||
new string[] { "Copyright © Weifen Luo 及贡献者",
|
||
"协议要求:分发时保留版权声明与许可证文本,其余无义务,可商用可闭源。" }));
|
||
tv.Nodes.Add(建节点("Zuby ADGV / AdvancedDataGridView", "MIT", "增强数据表格",
|
||
new string[] { "Copyright © 2017 Zuby",
|
||
"协议要求:分发时保留版权声明与许可证文本。" }));
|
||
tv.Nodes.Add(建节点("NPOI", "Apache-2.0", "Excel/OOXML 文件生成",
|
||
new string[] { "Copyright © 2008-2023 NPOI Contributors",
|
||
"协议要求:提供许可证副本并保留声明;有 NOTICE 文件须传递;修改文件须标注;含专利授权;不得用原作者商标推广。" }));
|
||
tv.Nodes.Add(建节点("DotNetZip", "MS-PL", "zip 压缩",
|
||
new string[] { "Copyright © 2008-2018 Dino Chiesa",
|
||
"协议要求:分发时保留版权/专利/商标/署名声明并随附许可条款;含专利授权,允许闭源。" }));
|
||
tv.Nodes.Add(建节点("ICSharpCode.SharpZipLib", "MIT", "zip/gzip 压缩",
|
||
new string[] { "Copyright © 2000-2022 SharpZipLib 贡献者",
|
||
"协议要求:分发时保留版权声明与许可证文本。" }));
|
||
tv.Nodes.Add(建节点("unvell.ReoGrid", "MIT", "表格控件",
|
||
new string[] { "Copyright © 2012 unvell Inc., Jing Lu",
|
||
"协议要求:分发时保留版权声明与许可证文本。" }));
|
||
tv.Nodes.Add(建节点("System.Data.SQLite", "公有领域", "SQLite 数据库驱动",
|
||
new string[] { "Public Domain · Robert Simpson 及 SQLite 团队贡献",
|
||
"协议要求:作者放弃版权,无附加义务。" }));
|
||
tv.Nodes.Add(建节点("pdfium (Google)", "BSD-3-Clause", "PDF 渲染引擎",
|
||
new string[] { "Copyright 2014-2024 The PDFium Authors",
|
||
"协议要求:源码/二进制分发保留版权声明与免责声明;不得以原作者名义为衍生品背书。" }));
|
||
tv.Nodes.Add(建节点("Microsoft Edge WebView2 运行时", "微软补充条款", "内嵌网页组件",
|
||
new string[] { "© Microsoft Corporation. 保留所有权利",
|
||
"协议要求:运行时可免费随本软件再分发,按微软《软件补充许可条款》使用。" }));
|
||
tv.Nodes.Add(建节点("Node.js", "MIT", "本地静态服务运行时",
|
||
new string[] { "Copyright Node.js contributors · OpenSSL: Copyright © OpenSSL Project Authors",
|
||
"协议要求:分发时保留版权声明与许可证文本(OpenSSL 按 Apache-2.0)。" }));
|
||
tv.Nodes.Add(建节点("ZCode(zai-org/ZCode 开源版)", "Apache-2.0", "AI 助手引擎(终端/网页 Agent)",
|
||
new string[] { "Copyright 2026 Z.AI Co., Ltd · 源码仓库 github.com/zai-org/ZCode",
|
||
"协议要求:提供许可证副本并保留声明;随附其 NOTICE 文件;修改文件须标注;含专利授权;不得用原作者商标推广。",
|
||
"本软件从其开源仓库官方源码构建并原样分发,未修改其代码。" },
|
||
"Apache-2.0-ZCode.txt"));
|
||
tv.Nodes.Add(建节点("mlightcad / CAD-Viewer", "MIT", "网页 CAD 引擎(含 three.js)",
|
||
new string[] { "Copyright © mlightcad · three.js: Copyright © 2010-2024 three.js authors",
|
||
"协议要求:分发时保留版权声明与许可证文本。本软件对其有修改,见下方修改说明。" }));
|
||
tv.Nodes.Add(建节点("Umi-OCR", "MIT / Apache-2.0", "本地离线 OCR(可选下载)",
|
||
new string[] { "Copyright © 2022 hiroi-sora · PaddleOCR: Copyright © Baidu Inc.",
|
||
"协议要求:MIT 项保留版权声明;PaddleOCR(Apache-2.0)另需保留 NOTICE 与修改标注。" }));
|
||
tv.Nodes.Add(建节点("Lucide", "ISC", "图标库",
|
||
new string[] { "Copyright © 2020 Lucide Labs",
|
||
"协议要求:与 MIT 等价,分发时保留版权声明与许可证文本。本软件对图标有换色调整,见下方修改说明。" }));
|
||
|
||
// ---- 修改说明与汇总 ----
|
||
tv.Nodes.Add(建节点("修改说明:mlightcad / CAD-Viewer —— 已修改", "", "",
|
||
new string[] {
|
||
"为适配本软件,对其网页构建产物(dist)作了以下修改并随软件分发:",
|
||
"修改① 字体与模板加载路径本地化(base-url 改为根相对,离线可用);",
|
||
"修改② 扒图完成消息(paPicked)附带当前图纸文件名,并在打开图纸时主动上报文档标题,供报价表格记录图纸名;",
|
||
"修改③ 静态服务脚本(server.cjs)响应头增加 Cache-Control: no-store。",
|
||
"其余代码未改动;原项目版权归 mlightcad 所有。" }));
|
||
tv.Nodes.Add(建节点("修改说明:Lucide —— 已修改", "", "",
|
||
new string[] {
|
||
"修改内容:图标 SVG 经描边配色替换与线宽调整(stroke-width 调细)后渲染为 PNG 使用,未改动图形本身。" }));
|
||
tv.Nodes.Add(建节点("其余组件 —— 未修改", "", "",
|
||
new string[] {
|
||
"WeifenLuo Docking、ADGV、NPOI、DotNetZip、SharpZipLib、ReoGrid、System.Data.SQLite、pdfium、WebView2 运行时、Node.js、Umi-OCR、ZCode 均为官方原版分发,未作任何修改。",
|
||
"另:Smart.CustomComponents 与 CJZZ.Controls 为本软件配套自研组件,非开源第三方库。" }));
|
||
tv.Nodes.Add(建节点("※ 共同底线", "", "",
|
||
new string[] {
|
||
"所有宽松协议都要求在分发时保留原作者的版权声明与许可证文本;",
|
||
"本软件的分发已包含并遵循以上要求。完整许可证文本以官方发布为准。" }));
|
||
|
||
tv.CollapseAll(); // 默认全部折叠
|
||
tv.EndUpdate();
|
||
}
|
||
|
||
private void pnl页头_Paint(object sender, PaintEventArgs e)
|
||
{
|
||
// 页头底部分隔线
|
||
using (var pen = new Pen(Color.FromArgb(220, 220, 220)))
|
||
e.Graphics.DrawLine(pen, 0, pnl页头.Height - 1, pnl页头.Width, pnl页头.Height - 1);
|
||
}
|
||
|
||
private void btn确定_Click(object sender, EventArgs e)
|
||
{
|
||
Close();
|
||
}
|
||
}
|
||
}
|