using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using CadParamPluging.Common;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
namespace CadParamPluging.Cad
{
///
/// 辅助类:用于操作 AutoCAD 的扩展字典 (Extension Dictionary / NOD)
///
public static class DictionaryHelper
{
// 我们在 NOD (Named Objects Dictionary) 中使用的根字典名称
private const string AppDictionaryName = "CadParamPluging_Data";
// 存储参数的 XRecord 名称
private const string ParamsRecordName = "DrawingParams";
///
/// 将参数包保存到当前文档的 Extension Dictionary (NOD) 中
///
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();
}
}
///
/// (可选) 从当前文档读取参数
///
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;
}
}
}