feat: activate p-rec-annot line-number edit commands
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using PRecAnnot.Abstractions;
|
||||
|
||||
namespace PRecAnnot.Plant3D2026;
|
||||
|
||||
internal sealed class LineNumberOwnedAnnotationReader
|
||||
{
|
||||
private const string ApplicationName = "PXP-LN";
|
||||
|
||||
public IReadOnlyList<LineNumberOwnedRow> ReadList(Document document, ObjectId listId)
|
||||
{
|
||||
using var transaction = document.Database.TransactionManager.StartOpenCloseTransaction();
|
||||
if (transaction.GetObject(listId, OpenMode.ForRead) is not BlockReference list || !HasRole(list, "LIST"))
|
||||
throw new InvalidOperationException("LINE_NUMBER_LIST_NOT_SELECTED");
|
||||
|
||||
var rows = new Dictionary<int, (string? StableId, string? Text)>();
|
||||
foreach (ObjectId id in list.AttributeCollection)
|
||||
{
|
||||
var attribute = (AttributeReference)transaction.GetObject(id, OpenMode.ForRead);
|
||||
var ownership = ReadOwnership(attribute);
|
||||
if (ownership is null) continue;
|
||||
rows.TryGetValue(ownership.Value.MarkerNumber, out var row);
|
||||
rows[ownership.Value.MarkerNumber] = ownership.Value.Role == "LINENUMBER"
|
||||
? (ownership.Value.StableId, attribute.TextString.Replace("\\P", "\n", StringComparison.Ordinal))
|
||||
: (ownership.Value.StableId ?? row.StableId, row.Text);
|
||||
}
|
||||
|
||||
var result = rows.OrderBy(value => value.Key)
|
||||
.Select(value => new LineNumberOwnedRow(
|
||||
value.Value.StableId ?? throw new InvalidOperationException("LINE_NUMBER_ROW_STABLE_ID_MISSING"),
|
||||
value.Key,
|
||||
value.Value.Text ?? throw new InvalidOperationException("LINE_NUMBER_ROW_TEXT_MISSING"),
|
||||
default))
|
||||
.ToArray();
|
||||
if (result.Length == 0) throw new InvalidOperationException("LINE_NUMBER_LIST_EMPTY");
|
||||
return result;
|
||||
}
|
||||
|
||||
public LineNumberOwnedRow ReadMarker(Document document, ObjectId markerId)
|
||||
{
|
||||
using var transaction = document.Database.TransactionManager.StartOpenCloseTransaction();
|
||||
if (transaction.GetObject(markerId, OpenMode.ForRead) is not BlockReference marker)
|
||||
throw new InvalidOperationException("LINE_NUMBER_MARKER_NOT_SELECTED");
|
||||
var values = marker.GetXDataForApplication(ApplicationName)?.AsArray() ?? [];
|
||||
var stableId = values.Where(value => value.TypeCode == 1000).Select(value => value.Value as string)
|
||||
.FirstOrDefault(value => !string.Equals(value, "MARKER", StringComparison.OrdinalIgnoreCase));
|
||||
var markerNumber = values.Where(value => value.TypeCode == 1071).Select(value => Convert.ToInt32(value.Value)).FirstOrDefault();
|
||||
var text = values.Where(value => value.TypeCode == 1000).Select(value => value.Value as string).LastOrDefault() ?? string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(stableId) || markerNumber <= 0) throw new InvalidOperationException("LINE_NUMBER_MARKER_OWNERSHIP_MISSING");
|
||||
var localPosition = Point3d.Origin;
|
||||
foreach (ObjectId id in marker.AttributeCollection)
|
||||
{
|
||||
var attribute = (AttributeReference)transaction.GetObject(id, OpenMode.ForRead);
|
||||
if (!string.Equals(attribute.Tag, "NUMBER", StringComparison.OrdinalIgnoreCase)) continue;
|
||||
localPosition = attribute.Position.TransformBy(marker.BlockTransform.Inverse());
|
||||
break;
|
||||
}
|
||||
return new(stableId, markerNumber, text, new(localPosition.X, localPosition.Y, localPosition.Z));
|
||||
}
|
||||
|
||||
private static bool HasRole(BlockReference reference, string role) =>
|
||||
reference.GetXDataForApplication(ApplicationName)?.AsArray().Any(value =>
|
||||
value.TypeCode == 1000 && string.Equals(value.Value as string, role, StringComparison.OrdinalIgnoreCase)) == true;
|
||||
|
||||
private static (string? StableId, string Role, int MarkerNumber)? ReadOwnership(AttributeReference attribute)
|
||||
{
|
||||
var values = attribute.GetXDataForApplication(ApplicationName)?.AsArray();
|
||||
if (values is null) return null;
|
||||
var strings = values.Where(value => value.TypeCode == 1000).Select(value => value.Value as string).ToArray();
|
||||
var role = strings.FirstOrDefault(value => value is "MARKER" or "LINENUMBER");
|
||||
var number = values.Where(value => value.TypeCode == 1071).Select(value => Convert.ToInt32(value.Value)).FirstOrDefault();
|
||||
return role is null || number <= 0 ? null : (strings.FirstOrDefault(value => value != role), role, number);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user