Skip to content

Latest commit

 

History

History
178 lines (155 loc) · 12.4 KB

Code-Migration-DevExpressReport.md

File metadata and controls

178 lines (155 loc) · 12.4 KB

PVAD Migration: DevExpress XtraReport → PVADE Designer

Goal

Convert a C# DevExpress XtraReport class (Report Designer output) into a PVADE design that opens and is editable in pvad-designer — replacing the dead-end CANMIGDEVEXP020 "report export requires manual migration" warning emitted by the code converter (DevExpressPdfMigration.cs).

  • Input: a C# XtraReport subclass + designer code (InitializeComponent() configuring XRLabel, XRLine, XRPictureBox, XRShape, XRTable, … via LocationF/SizeF/Text/Font/ForeColor).
  • Output: a DesignExportDto (pages + ElementDto[]) loaded into the visual designer — not a C# code string (this is distinct from the other Code-Migration-* providers).

Status

V1 shipped. C#-source XtraReports convert end-to-end and open in the designer: band flattening, unit conversion, real page size, repeating page headers/footers, tables, and data bindings. V2 below is the next, unstarted milestone.


V1 — Shipped ✅

Scope

  • Static-content reports (literal Text, fixed positions/sizes, fonts, colours).
  • Input is C# source (Roslyn). .repx XML input is a V2 item.

Core conversion

  • Unit conversion — ReportUnit default HundredthsOfAnInch (×0.72); Pixels (×0.75, 96 DPI); TenthsOfAMillimeter; defaults to hundredths-of-inch.
  • Band flattening — accumulate each band's HeightF (canonical order) to turn band-relative LocationF.Y into absolute page coordinates.
  • Page size — from PaperKind (A4/A3/A5/Letter/Legal/Tabloid), or PageWidth/PageHeight (report units) when Custom; Landscape swaps dimensions; defaults to A4.
  • Page header/footer → DesignExportDto.SharedElements (repeat on every page); footer anchored to the page bottom (pageHeight − bottomMargin − footerHeight).

Architecture

  • Isolated project src/Migrations/Report/PVAD.Migration.Report.Designer.DevExpress (refs PVAD.Core + Roslyn); returns a DesignExportDto, not a code string.
  • XtraReportToDesignConverter.Convert(string) → { DesignExportDto Design, IReadOnlyList<MigrationDiagnostic> Diagnostics }.
  • Roslyn pre-scan: locate : XtraReport; collect control field declarations; read InitializeComponent() assignments into per-control property bags; band membership + table rows/cells from *.Controls/Rows/Cells.Add(Range).

Control mapping

XtraReport control PVADE ElementDto.Type Status
XRLabel / XRPageInfo text (+ font/colour/align style) [x]
XRLine line [x]
XRShape / XRPanel rect [x]
XRPictureBox image (placeholder, CANMIGDEVREP013) [x]
XRTable/XRTableRow/XRTableCell table (CellData from cell .Text) [x]
XRBarCode barcode [x]
XRRichText richtext [x]
Data binding (ExpressionBindings/DataBindings) binding for [Field], expression otherwise [x]

Delivery

  • Backend POST /api/migration/report-to-design → { design, diagnostics } (MigrationController.cs).
  • Frontend "DevExpress Reports" entry + Open in Designer (loads via bulkReplaceContent, navigates to the editor) (MigrationsPage.tsx).

Tests (17 passing)

  • Band-flattened + unit-converted coordinates; label style mapping; line/rect/image.
  • ReportUnit = Pixels scaling; PaperKind/Custom/Landscape page sizes.
  • XRTable rows/cells; single-field binding + complex expression; page header/footer → shared.
  • Unsupported control → CANMIGDEVREP011.
  • End-to-end: a converted report (C# and .repx) renders to a valid PDF through the real export pipeline (DesignJsonMapper → ToBytes) — in PVAD.Export.Tests.

Diagnostics (implemented)

ID Severity Meaning
CANMIGDEVREP001 Info XtraReport + bands detected (N bands, M controls)
CANMIGDEVREP002 Info Per-control mapping (name (XRType) → PVADE type)
CANMIGDEVREP010 Info / Warning Text binding mapped — [X] → binding (Info); complex expression → expression (Warning)
CANMIGDEVREP011 Warning Unsupported control skipped
CANMIGDEVREP012 Warning Sub-report placeholder inserted, or report scripts/event handlers require manual migration
CANMIGDEVREP013 Warning Picture data not embeddable — placeholder inserted
CANMIGDEVREP014 Warning DetailReportBand / sub-detail layout flattened; data-repeat semantics require PVADE template wiring
CANMIGDEVREP015 Warning GroupHeaderBand / GroupFooterBand layout flattened; group/sort repeat semantics require PVADE template wiring
CANMIGDEVREP016 Warning CanGrow / CanShrink imported as PVADE text wrapping/overflow hints; dynamic band reflow requires review
CANMIGDEVREP017 Warning DevExpress anchoring imported as metadata; responsive positioning requires review
CANMIGDEVREP018 Warning XRChart imported as editable PVADE chart placeholder; XRGauge/XRPivotGrid imported as positioned placeholders
CANMIGDEVREP019 Warning XRShape arrow imported as PVADE arrow; direction/head style requires visual review
CANMIGDEVREP020 Warning DevExpress Visible expression preserved as PVADE visibleExpression; simple BookingReceipt-style cases are evaluated during PDF export
CANMIGDEVREP021 Warning C# designer image resource key preserved; .resx/resource payload is needed for automatic image embedding
CANMIGDEVREP022 Warning DevExpress MultiColumn band mode detected; repeated column flow requires manual review
CANMIGDEVREP023 Warning DevExpress TextFitMode / TextTrimming imported as metadata; text shrink/trimming requires manual review

V2 — Next 🔜

Pick from these, roughly in value order:

Current recommendation: make DevExpress the first fidelity pass because it is a core customer path and the gaps show up immediately in real designer files. Prioritize group/repeat semantics, once-at-end report footers, auto-sizing/anchoring, sub-detail bands, non-text bindings, and high-use visual controls before lower-value table styling.

1. .repx XML input ✅ (done)

  • Parse the serialized DevExpress report XML (.repx) — shares the band-flatten / unit / page-size / mapping / binding core via a neutral RawReport model. ConvertAuto detects XML vs C#; the report-to-design endpoint accepts either. Covers page size, bands, label/line/shape/table controls, fonts/colours, alignment, expression bindings, and page header/footer → shared elements.

2. Richer controls & styling (partly done)

  • XRPictureBox embedded image (.repx base64 ImageSource/Image → PVADE image Content data URL), replacing the CANMIGDEVREP013 placeholder when image data is present.
  • C# XRPictureBox.ImageSource = new ImageSource("img", resources.GetString("...")) preserves the resource key as style.devExpressImageResourceKey and emits CANMIGDEVREP021 when the .resx payload is not available.
  • Optional resources payload on POST /api/migration/report-to-design resolves resources.GetString(...) for C# designer image payloads and expression bindings, so .resx image base64 and binding strings can be embedded/mapped automatically.
  • Direct .resx workflow: POST /api/migration/report-to-design accepts optional resourceXml, parses <data name="..."><value>...</value></data> entries, and the Designer Migration UI can load a matching .resx file while still allowing JSON overrides.
  • XRCheckBox → checkmark with CheckState (from CheckBoxState/Checked).
  • XRShape ellipse → circle, line → line, otherwise rect.
  • Label BackColor → text backgroundColor; font Underline/Strikeout → textDecoration.
  • XRControlStyle / StyleName → inherited PVADE font/colour/border/padding style hints.
  • TextFitMode / TextTrimming → style.devExpressTextFitMode / style.devExpressTextTrimming with CANMIGDEVREP023.
  • Table column alignments from the header-row cell TextAlignment → ColumnAlignments.
  • Per-cell font/colour table styling — XRTableCell BackColor/ForeColor/TextAlignment/Font/ Borders are extracted into sparse PVADE CellStyles (uniform + per-side borders) and rendered by the canvas/preview and all exporters.
  • Standard expressions are executable in the designer/preview: non-trivial bindings emit a translated PVAD-grammar Expression via ExpressionTranslator.TranslateDevExpress (raw kept on style.devExpressExpression). See Migration_RDL+DevExpress.md. Custom functions / aggregates remain out of scope.
  • P0 More controls: XRChart → editable PVADE chart; XRGauge/XRPivotGrid → positioned placeholders with CANMIGDEVREP018 diagnostics instead of layout holes.
  • XRLine/XRShape LineWidth → strokeWidth/borderWidth; XRLine LineStyle → dashStyle.
  • P1 XRShape arrow kinds; per-side .Borders selection.

3. Data & layout fidelity

  • [~] Translate DevExpress expression syntax to the PVADE expression DSL. Not worth doing — PVADE's ExpressionEvaluator (src/Core/PVAD.Core/Primitives/ExpressionEvaluator.cs) is a stub (bare-identifier substitution + ==/!= only; no arithmetic/functions), so there's no richer target to translate into. Single-field [X] → binding (done); other expressions are preserved verbatim on expression with a warning.
  • Detect sub-reports (XRSubreport) and insert positioned placeholders; report scripts/event handlers → CANMIGDEVREP012.
  • P0 Grouping/sorting bands (GroupHeaderBand/GroupFooterBand) — group/footer layout is imported and stacked in band order; C# GroupFields/SortFields and .repx <GroupFields>/ <SortFields> are captured in CANMIGDEVREP015 diagnostics. Repeat semantics: each group-band control now carries PVADE RepeatDto (data path from the first group field) plus style.devExpressGroup (name/role/band/fields/sorts), mirroring the RDL/Jasper group-repeat mapping, so the band can be wired as a repeating template. Runtime data-binding still needs PVADE template wiring.
  • P0 AnchorVertical/AnchorHorizontal and CanGrow/CanShrink auto-sizing: imported as PVADE style hints (whiteSpace, overflow, verticalAlign) plus DevExpress metadata, with CANMIGDEVREP016/017 diagnostics for dynamic reflow/anchoring review.
  • P0 ReportFooterBand once-at-end semantics: report-footer elements are imported as PageScope = "last" so export renders them only on the final page while single-page designs still show them.

4. Polish

  • Emit CANMIGDEVREP002 per mapped control (traceability beyond the 001 summary).
  • Nested controls inside an XRPanel are flattened to absolute positions (container chain walked up to the owning band, accumulating panel offsets) — both C# and .repx.
  • P0 Map non-text data bindings instead of the generic warning: XRBarCode text/value bindings now update BarcodeValue, and XRPictureBox image bindings now update image Content.
  • P0 Preserve Visible expression bindings as visibleExpression metadata with CANMIGDEVREP020 diagnostics; PDF export evaluates simple cases such as Len([X]) > 0, [A].[B] == 'Value', [Collection].Count > 0, and IIF(condition, True, False).
  • P0 Multi-DetailReportBand (sub-detail) handling: nested child bands are parsed from C# detailReport.Bands.AddRange(...) and .repx nested <Bands>, flattened below their parent DetailReportBand, with CANMIGDEVREP014 warning for repeat semantics.
  • P1 MultiColumn.Mode detection on bands with CANMIGDEVREP022 diagnostic.

Assumptions

  • Use PVAD.Migration.Report.Designer.DevExpress, separate from PVAD.Migration.Pdf.Code.DevExpress.
  • Output target is PVADE design JSON (designer), not PVAD.Pdf C# code.
  • Default page size A4 when the report declares none.