fix(task-17): a layout plot never writes CenterPlot, and a refused COM write unwinds every landed one
The ActiveX Reference (CenterPlot Property, acadauto.chm, AutoCAD 2026):
"This property cannot be set to True on a layout object whose PlotType
property is set to acLayout." The shipped sequence wrote PlotType=5 and
then CenterPlot=True for the *default* call, so page_setup_apply(layout,
resolve_page_setup("ISO_A3")) could not succeed live — either COM raised
with nine writes landed and nothing put back, or the result claimed
applied.center=True over a read-back of False.
- resolve_page_setup resolves `center` to None for plot_area="layout"
(validated as a bool first; kept as the bool for "extents"), and
`center_applies(plot_type)` carries the rule for both read-backs.
- Both engines: page_setup_list reports `center: None` under acLayout
instead of a stored flag nothing honours; apply never sets the centre
bit / CenterPlot for a layout plot (ezdxf clears bit 4, the state
AutoCAD stores for acLayout; COM clears a stale CenterPlot=True *before*
PlotType moves to acLayout, and writes CenterPlot for an extents plot
only *after* PlotType=acExtents).
- COM: every write is journaled and unwound in reverse when AutoCAD
refuses one; the ValueError names the refused property and says the
layout was restored (or what could not be). The old device-only
rollback is the same mechanism now.
- tests: the fake enforces the documented CenterPlot rule (the shipped
sequence fails under it, which is the reviewer's repro), and can refuse
a named property; new cases pin the no-write, the ordering both ways,
the reverse unwind including SetCustomScale, and the None read-backs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
70f18efb4b
commit
20ca39d28a
@@ -2336,6 +2336,7 @@ class EzdxfBackend(AutoCADBackend):
|
||||
def _page_setup_row(layout) -> dict:
|
||||
from engineering.standards.papers import (
|
||||
PLOT_TYPE_NAMES,
|
||||
center_applies,
|
||||
dxf_scale_label,
|
||||
paper_from_size,
|
||||
scale_label,
|
||||
@@ -2355,6 +2356,7 @@ class EzdxfBackend(AutoCADBackend):
|
||||
scale = dxf_scale_label(int(dxf.standard_scale_type), numerator, denominator)
|
||||
else:
|
||||
scale = scale_label(numerator, denominator)
|
||||
plot_type = int(dxf.plot_type)
|
||||
return {
|
||||
"layout": layout.name,
|
||||
"paper": paper_from_size(width, height) or media,
|
||||
@@ -2363,7 +2365,7 @@ class EzdxfBackend(AutoCADBackend):
|
||||
"orientation": "landscape" if width >= height else "portrait",
|
||||
"plot_style": str(dxf.current_style_sheet),
|
||||
"scale": scale,
|
||||
"plot_area": PLOT_TYPE_NAMES.get(int(dxf.plot_type), str(dxf.plot_type)),
|
||||
"plot_area": PLOT_TYPE_NAMES.get(plot_type, str(dxf.plot_type)),
|
||||
"device": str(dxf.plot_configuration_file),
|
||||
"margins_mm": [
|
||||
round(float(dxf.top_margin), 3),
|
||||
@@ -2371,7 +2373,9 @@ class EzdxfBackend(AutoCADBackend):
|
||||
round(float(dxf.left_margin), 3),
|
||||
round(float(dxf.right_margin), 3),
|
||||
],
|
||||
"center": bool(flags & layout.PLOT_CENTERED),
|
||||
# A layout plot has no centring (AutoCAD greys it out; ActiveX
|
||||
# refuses CenterPlot=True under acLayout): None, not a bit nobody honours.
|
||||
"center": bool(flags & layout.PLOT_CENTERED) if center_applies(plot_type) else None,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -2474,6 +2478,9 @@ class EzdxfBackend(AutoCADBackend):
|
||||
dxf.standard_scale_type = 16
|
||||
dxf.scale_numerator, dxf.scale_denominator = numerator, denominator
|
||||
target.use_standard_scale(False)
|
||||
# resolve_page_setup hands over None for a layout plot: the bit is
|
||||
# cleared, never set — the state AutoCAD itself stores for acLayout,
|
||||
# and the mirror of the live engine never writing CenterPlot there.
|
||||
target.plot_centered(bool(resolved["center"]))
|
||||
# Limits follow the paper; viewports are deliberately left alone
|
||||
# (Paperspace.page_setup() would delete them).
|
||||
|
||||
Reference in New Issue
Block a user