feat: port p-rec-annot line-number edit mutations

This commit is contained in:
codex
2026-08-07 09:04:07 +03:00
parent 7090321167
commit 91f316d79b
4 changed files with 103 additions and 0 deletions
@@ -87,6 +87,50 @@ internal sealed class LineNumberAnnotationWriter
return new(1, 0, 0);
}
public LineNumberApplyResult ApplyEdits(Document document, IReadOnlyList<LineNumberRowMutation> mutations)
{
if (mutations.Count == 0) return new(0, 0, 1);
using var documentLock = document.LockDocument();
var database = document.Database;
using var transaction = database.TransactionManager.StartTransaction();
var blocks = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
var paper = (BlockTableRecord)transaction.GetObject(blocks[BlockTableRecord.PaperSpace], OpenMode.ForRead);
var updated = 0;
foreach (var mutation in mutations)
{
var marker = FindOwnedMarker(transaction, paper, mutation.SourceStableId) ?? throw new InvalidOperationException("LINE_NUMBER_OWNED_MARKER_NOT_FOUND");
foreach (ObjectId id in marker.AttributeCollection)
{
var attribute = (AttributeReference)transaction.GetObject(id, OpenMode.ForWrite);
if (!string.Equals(attribute.Tag, MarkerAttributeTag, StringComparison.OrdinalIgnoreCase)) continue;
attribute.TextString = mutation.MarkerNumber.ToString(System.Globalization.CultureInfo.InvariantCulture);
if (mutation.MarkerAttributePosition is { } reset) attribute.Position = new Point3d(reset.X, reset.Y, reset.Z).TransformBy(marker.BlockTransform);
}
foreach (ObjectId entityId in paper)
{
if (transaction.GetObject(entityId, OpenMode.ForRead) is not BlockReference list || !list.Name.StartsWith("LN_LIST", StringComparison.OrdinalIgnoreCase)) continue;
foreach (ObjectId attributeId in list.AttributeCollection)
{
var attribute = (AttributeReference)transaction.GetObject(attributeId, OpenMode.ForWrite);
if (string.Equals(attribute.Tag, $"NUMBER{mutation.PreviousMarkerNumber}", StringComparison.OrdinalIgnoreCase))
{
attribute.Tag = $"NUMBER{mutation.MarkerNumber}";
attribute.TextString = mutation.MarkerNumber.ToString(System.Globalization.CultureInfo.InvariantCulture);
}
else if (string.Equals(attribute.Tag, $"LINENUMBER{mutation.PreviousMarkerNumber}", StringComparison.OrdinalIgnoreCase))
{
attribute.Tag = $"LINENUMBER{mutation.MarkerNumber}";
attribute.TextString = mutation.Text.Replace("\n", "\\P", StringComparison.Ordinal);
attribute.UpdateMTextAttribute();
}
}
}
updated++;
}
transaction.Commit();
return new(0, updated, 0);
}
private static void ValidateAssets(Transaction transaction, Database database, LineNumberMarkerAsset marker)
{
var layers = (LayerTable)transaction.GetObject(database.LayerTableId, OpenMode.ForRead);
@@ -169,6 +213,12 @@ internal sealed class LineNumberAnnotationWriter
attribute.SetAttributeFromBlock(source, reference.BlockTransform);
attribute.TextString = values[source.Tag];
attribute.UpdateMTextAttribute();
var row = rows.Single(value => source.Tag.EndsWith(value.MarkerNumber.ToString(System.Globalization.CultureInfo.InvariantCulture), StringComparison.Ordinal));
attribute.XData = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, ApplicationName),
new TypedValue((int)DxfCode.ExtendedDataAsciiString, row.StableId),
new TypedValue((int)DxfCode.ExtendedDataAsciiString, source.Tag.StartsWith("NUMBER", StringComparison.OrdinalIgnoreCase) ? "MARKER" : "LINENUMBER"),
new TypedValue((int)DxfCode.ExtendedDataInteger32, row.MarkerNumber));
reference.AttributeCollection.AppendAttribute(attribute);
transaction.AddNewlyCreatedDBObject(attribute, true);
}