CadParamPluging/Cad/DictionaryHelper.cs

185 lines
6.9 KiB
C#
Raw Permalink 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.

using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using CadParamPluging.Common;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
namespace CadParamPluging.Cad
{
/// <summary>
/// 辅助类:用于操作 AutoCAD 的扩展字典 (Extension Dictionary / NOD)
/// </summary>
public static class DictionaryHelper
{
// 我们在 NOD (Named Objects Dictionary) 中使用的根字典名称
private const string AppDictionaryName = "CadParamPluging_Data";
// 存储参数的 XRecord 名称
private const string ParamsRecordName = "DrawingParams";
/// <summary>
/// 将参数包保存到当前文档的 Extension Dictionary (NOD) 中
/// </summary>
public static void SaveParams(Database db, ParamBag bag)
{
if (db == null || bag == null || bag.Items == null || bag.Items.Count == 0)
{
return;
}
using (var tr = db.TransactionManager.StartTransaction())
{
var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
// 1. 获取或创建我们的应用专属字典
DBDictionary appDict;
if (nod.Contains(AppDictionaryName))
{
appDict = (DBDictionary)tr.GetObject(nod.GetAt(AppDictionaryName), OpenMode.ForWrite);
}
else
{
appDict = new DBDictionary();
nod.SetAt(AppDictionaryName, appDict);
tr.AddNewlyCreatedDBObject(appDict, true);
}
// 2. 准备数据 (XRecord)
// XRecord 本质上是一个 ResultBuffer 链表
// 我们使用 DxfCode.Text (1000) 来存储 key=value 字符串
var rb = new ResultBuffer();
// serialize user inputs into a single text block
var fullString = "";
foreach (var item in bag.Items)
{
if (!string.IsNullOrWhiteSpace(item.Key))
{
fullString += $"{item.Key}={item.Value ?? string.Empty}\n";
}
}
// DxfCode.Text has a 255-character limit in AutoCAD ResultBuffer.
// We use code 301 (XTextString) and chunk the string to support any length.
var temp = fullString;
while (temp.Length > 0)
{
var chunk = temp.Length > 250 ? temp.Substring(0, 250) : temp;
rb.Add(new TypedValue(301, chunk)); // 301 = DxfCode.XTextString
temp = temp.Length > 250 ? temp.Substring(250) : "";
}
try
{
// Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n[CadParamPluging] Saving Params: Count={bag.Items.Count}\n");
}
catch {}
var xrec = new Xrecord();
xrec.Data = rb;
// 如果已存在则覆盖,否则添加
if (appDict.Contains(ParamsRecordName))
{
// 为了简单起见,这里选择直接删除旧的再添加新的,或者覆盖
// 如果用 GetObject 获取旧的 xrec可以直接 xrec.Data = rb
var oldId = appDict.GetAt(ParamsRecordName);
var oldXrec = (Xrecord)tr.GetObject(oldId, OpenMode.ForWrite);
oldXrec.Data = rb;
}
else
{
appDict.SetAt(ParamsRecordName, xrec);
tr.AddNewlyCreatedDBObject(xrec, true);
}
tr.Commit();
}
}
/// <summary>
/// (可选) 从当前文档读取参数
/// </summary>
public static ParamBag ReadParams(Database db)
{
var bag = new ParamBag();
using (var tr = db.TransactionManager.StartTransaction())
{
var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
if (!nod.Contains(AppDictionaryName))
{
return bag;
}
var appDict = (DBDictionary)tr.GetObject(nod.GetAt(AppDictionaryName), OpenMode.ForRead);
if (!appDict.Contains(ParamsRecordName))
{
return bag;
}
var xrec = (Xrecord)tr.GetObject(appDict.GetAt(ParamsRecordName), OpenMode.ForRead);
var rb = xrec.Data;
if (rb == null)
{
return bag;
}
var sb = new System.Text.StringBuilder();
bool hasCode301 = false;
// Read chunks from new format
foreach (var tv in rb)
{
if (tv.TypeCode == 301)
{
hasCode301 = true;
if (tv.Value is string s)
{
sb.Append(s);
}
}
}
if (hasCode301)
{
var fullText = sb.ToString();
foreach (var line in fullText.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
{
var parts = line.Split(new[] { '=' }, 2);
if (parts.Length == 2) bag.Set(parts[0], parts[1]);
else if (parts.Length == 1) bag.Set(parts[0], "");
}
return bag;
}
// Fallback to read from old Code 1 format
foreach (var tv in rb)
{
if (tv.TypeCode == (int)DxfCode.Text)
{
var line = tv.Value as string;
if (!string.IsNullOrWhiteSpace(line))
{
var parts = line.Split(new[] { '=' }, 2);
if (parts.Length == 2)
{
bag.Set(parts[0], parts[1]);
try
{
// Log Hardness read
}
catch {}
}
else if (parts.Length == 1)
{
bag.Set(parts[0], "");
}
}
}
}
}
return bag;
}
}
}