forked from 1b-agent/opencadstudio-upstream
Attach Underlay ribbon menu, DWF/DGN attach dialog, DGN true colours
- Insert > Reference: the PDF Attach button becomes an Attach Underlay menu (PDF / DWF / DGN); its face runs the last one chosen. - DWFATTACH, DGNATTACH and ATTACH on a .dwf/.dwfx/.dgn open the Attach dialog for that kind: sheets or models with thumbnails (one chosen), placement, path type, file details with the sheet / model size, and for DGN the conversion units (sub units offer 1 / sub units per master as the scale). - DGN V8 true colours come from the ExtendedColors record packed in the non-model attributes stream; the colour word's high part numbers them. - A DGN model's extent includes each text's box (its length along the baseline and 1.5 x its height), as the reference sizes a model. - DWFx text uses the family named in its embedded (deobfuscated) font. - DWF contrast pivots at 0.73 once colours are turned over for a dark background. - Hairline strokes are drawn solid one pixel wide, and underlay rasters are made at or below their size on screen so those lines stay unbroken. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
fecbcd8138
commit
5b6cbff5b2
33 files changed
+745
-59
No files matched your search
@@ -3564,6 +3564,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3549,6 +3549,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3552,6 +3552,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3552,6 +3552,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3553,6 +3553,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3552,6 +3552,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3552,6 +3552,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3540,6 +3540,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3542,6 +3542,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3550,6 +3550,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3552,6 +3552,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3553,6 +3553,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3526,6 +3526,25 @@ insert =
|
||||
.pdfui-search-for-layer = Katman ara
|
||||
.pdfui-reference-name = Referans adı:
|
||||
.pdfui-page-size = Sayfa boyutu:
|
||||
.ul-attach-underlay = Altlık Bağla
|
||||
.ul-attach-dwf = DWF Bağla
|
||||
.ul-attach-dgn = DGN Bağla
|
||||
.ul-attach-dwf-underlay = DWF Altlığı Ekle
|
||||
.ul-attach-dgn-underlay = DGN Altlığı Ekle
|
||||
.ul-sheet-count = __ocs_fmt_0__ pafta
|
||||
.ul-model-count = __ocs_fmt_0__ model
|
||||
.ul-sheets = Paftalar
|
||||
.ul-models = Modeller
|
||||
.ul-selected-sheet = Seçili pafta: __ocs_fmt_0__
|
||||
.ul-selected-model = Seçili model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Pafta boyutu:
|
||||
.ul-model-size = Model boyutu:
|
||||
.ul-conversion-units = Dönüştürme birimleri
|
||||
.ul-master-units = Ana birim
|
||||
.ul-sub-units = Alt birim
|
||||
.ul-sub-units-scale = Alt birim seçilirse varsayılan ölçek __ocs_fmt_0__ olur.
|
||||
.ul-attaches-dwf = Bir DWF veya DWFx dosyasını altlık olarak bağlar.
|
||||
.ul-attaches-dgn = Bir DGN dosyasını altlık olarak bağlar.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = PDF dosyasından bir veya daha fazla sayfa seçin:
|
||||
.pdfui-import-pdf = PDF İçe Aktar
|
||||
.pdfui-pdf-import-settings = PDF İçe Aktarma Ayarları
|
||||
|
||||
@@ -3539,6 +3539,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -3551,6 +3551,25 @@ insert =
|
||||
.pdfui-search-for-layer = Search for layer
|
||||
.pdfui-reference-name = Reference name:
|
||||
.pdfui-page-size = Page size:
|
||||
.ul-attach-underlay = Attach Underlay
|
||||
.ul-attach-dwf = Attach DWF
|
||||
.ul-attach-dgn = Attach DGN
|
||||
.ul-attach-dwf-underlay = Attach DWF Underlay
|
||||
.ul-attach-dgn-underlay = Attach DGN Underlay
|
||||
.ul-sheet-count = __ocs_fmt_0__ sheets
|
||||
.ul-model-count = __ocs_fmt_0__ models
|
||||
.ul-sheets = Sheets
|
||||
.ul-models = Models
|
||||
.ul-selected-sheet = Selected sheet: __ocs_fmt_0__
|
||||
.ul-selected-model = Selected model: __ocs_fmt_0__
|
||||
.ul-sheet-size = Sheet size:
|
||||
.ul-model-size = Model size:
|
||||
.ul-conversion-units = Conversion units
|
||||
.ul-master-units = Master units
|
||||
.ul-sub-units = Sub units
|
||||
.ul-sub-units-scale = Sub units make the default scale __ocs_fmt_0__
|
||||
.ul-attaches-dwf = Attaches a DWF or DWFx file as an underlay.
|
||||
.ul-attaches-dgn = Attaches a DGN file as an underlay.
|
||||
.pdfui-select-one-or-more-pages-from-the-pdf-file = Select one or more pages from the PDF file:
|
||||
.pdfui-import-pdf = Import PDF
|
||||
.pdfui-pdf-import-settings = PDF Import Settings
|
||||
|
||||
@@ -5,7 +5,7 @@ use super::*;
|
||||
use crate::io::xref_model::Pathtype;
|
||||
use crate::modules::insert::pdf_import::{self, PdfFileImport};
|
||||
use crate::ui::window::pdf_dialogs::{
|
||||
click_page, page_thumbs, LayerTarget, PdfAttachState, PdfDialogMsg, PdfImportFileState,
|
||||
click_page, item_thumbs, page_thumbs, LayerTarget, PdfAttachState, PdfDialogMsg, PdfImportFileState,
|
||||
RotationChoice, UnderlayLayersState,
|
||||
};
|
||||
|
||||
@@ -16,6 +16,23 @@ fn page_size_text(path: &str, page: &str) -> String {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// The page's (PDF, inches) or the sheet's / model's size.
|
||||
fn item_size_text(kind: codec::entities::UnderlayType, path: &str, item: &str) -> String {
|
||||
if kind == codec::entities::UnderlayType::Pdf {
|
||||
return page_size_text(path, item);
|
||||
}
|
||||
crate::scene::model::underlay_vector::sheet(kind, path, item)
|
||||
.map(|s| format!("{:.4} × {:.4}", s.rect[2] - s.rect[0], s.rect[3] - s.rect[1]))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn sub_per_master(kind: codec::entities::UnderlayType, path: &str, item: &str) -> f64 {
|
||||
crate::scene::model::underlay_vector::sheet(kind, path, item)
|
||||
.map(|s| s.sub_per_master)
|
||||
.filter(|v| *v > 0.0)
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
fn file_stem(path: &str) -> String {
|
||||
std::path::Path::new(&path.replace('\\', "/"))
|
||||
.file_stem()
|
||||
@@ -45,10 +62,18 @@ impl OpenCADStudio {
|
||||
|
||||
/// PDFATTACH after the file is chosen.
|
||||
pub(in crate::app) fn open_pdf_attach_dialog(&mut self, path: &str) {
|
||||
self.open_underlay_attach_dialog(codec::entities::UnderlayType::Pdf, path);
|
||||
}
|
||||
|
||||
/// PDFATTACH / DWFATTACH / DGNATTACH after the file is chosen.
|
||||
pub(in crate::app) fn open_underlay_attach_dialog(&mut self, kind: codec::entities::UnderlayType, path: &str) {
|
||||
let i = self.active_tab;
|
||||
let mut existing: Vec<(String, String)> = Vec::new();
|
||||
for object in self.tabs[i].scene.document.objects.values() {
|
||||
if let codec::objects::ObjectType::UnderlayDefinition(def) = object {
|
||||
if def.underlay_type != kind {
|
||||
continue;
|
||||
}
|
||||
let name = file_stem(&def.file_path);
|
||||
if !existing.iter().any(|(n, _)| *n == name) {
|
||||
existing.push((name, def.file_path.clone()));
|
||||
@@ -56,6 +81,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
let mut state = PdfAttachState::new(existing);
|
||||
state.kind = kind;
|
||||
self.load_pdf_attach_file(&mut state, path);
|
||||
self.pdf_attach = Some(state);
|
||||
self.active_modal = Some(crate::app::ModalKind::PdfAttach);
|
||||
@@ -64,11 +90,14 @@ impl OpenCADStudio {
|
||||
fn load_pdf_attach_file(&self, state: &mut PdfAttachState, path: &str) {
|
||||
state.path = path.to_string();
|
||||
state.name = file_stem(path);
|
||||
state.pages = page_thumbs(path);
|
||||
state.pages = item_thumbs(state.kind, path);
|
||||
state.selected = vec![0];
|
||||
state.anchor = 0;
|
||||
state.found_in = crate::entities::underlay::display_path(path);
|
||||
state.page_size = page_size_text(path, "1");
|
||||
let first = state.page_labels().into_iter().next().unwrap_or_else(|| "1".to_string());
|
||||
state.page_size = item_size_text(state.kind, path, &first);
|
||||
state.sub_per_master = sub_per_master(state.kind, path, &first);
|
||||
state.sub_units = false;
|
||||
state.saved_path =
|
||||
crate::entities::underlay::display_path(&self.pdf_stored_path(path, state.path_type.0));
|
||||
}
|
||||
@@ -206,7 +235,14 @@ impl OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
match message {
|
||||
PdfDialogMsg::Help(which) => {
|
||||
let kind = self.pdf_attach.as_ref().map(|s| s.kind);
|
||||
let text = match which {
|
||||
"attach" if kind == Some(codec::entities::UnderlayType::Dwf) => {
|
||||
crate::t!("Attaches a DWF or DWFx file as an underlay.")
|
||||
}
|
||||
"attach" if kind == Some(codec::entities::UnderlayType::Dgn) => {
|
||||
crate::t!("Attaches a DGN file as an underlay.")
|
||||
}
|
||||
"attach" => crate::t!("Attaches a PDF file as an underlay."),
|
||||
"layers" => crate::t!("Turns the layers of a PDF underlay on or off."),
|
||||
_ => crate::t!("Imports the geometry, fills, raster images and text of a PDF file as drawing objects."),
|
||||
@@ -220,11 +256,22 @@ impl OpenCADStudio {
|
||||
|
||||
// ── Attach ────────────────────────────────────────────────────
|
||||
PdfDialogMsg::AttachBrowse => {
|
||||
let kind = self.pdf_attach.as_ref().map(|s| s.kind).unwrap_or(codec::entities::UnderlayType::Pdf);
|
||||
if let Some(state) = &self.pdf_attach {
|
||||
state.remember();
|
||||
}
|
||||
if kind != codec::entities::UnderlayType::Pdf {
|
||||
return Task::done(Message::UnderlayAttachPick(kind));
|
||||
}
|
||||
return Task::done(Message::PdfAttachPick);
|
||||
}
|
||||
PdfDialogMsg::AttachSubUnits(sub) => {
|
||||
if let Some(s) = self.pdf_attach.as_mut() {
|
||||
s.sub_units = sub;
|
||||
// The scale offered follows the units, as on the command line.
|
||||
s.scale = if sub { format!("{}", 1.0 / s.sub_per_master) } else { "1.0000".to_string() };
|
||||
}
|
||||
}
|
||||
PdfDialogMsg::AttachName(name) => {
|
||||
let Some(mut state) = self.pdf_attach.take() else {
|
||||
return Task::none();
|
||||
@@ -237,9 +284,16 @@ impl OpenCADStudio {
|
||||
PdfDialogMsg::AttachPage(page) => {
|
||||
let (ctrl, shift) = (self.ctrl_down, self.shift_down);
|
||||
if let Some(state) = self.pdf_attach.as_mut() {
|
||||
click_page(&mut state.selected, &mut state.anchor, page, ctrl, shift);
|
||||
if state.kind == codec::entities::UnderlayType::Pdf {
|
||||
click_page(&mut state.selected, &mut state.anchor, page, ctrl, shift);
|
||||
} else {
|
||||
// One sheet or model at a time.
|
||||
state.selected = vec![page];
|
||||
state.anchor = page;
|
||||
}
|
||||
let first = state.page_labels().into_iter().next().unwrap_or_default();
|
||||
state.page_size = page_size_text(&state.path, &first);
|
||||
state.page_size = item_size_text(state.kind, &state.path, &first);
|
||||
state.sub_per_master = sub_per_master(state.kind, &state.path, &first);
|
||||
}
|
||||
}
|
||||
PdfDialogMsg::AttachPathType(choice) => {
|
||||
@@ -475,12 +529,14 @@ impl OpenCADStudio {
|
||||
}
|
||||
self.close_active_modal();
|
||||
let insunits = self.tabs[i].scene.document.header.insertion_units;
|
||||
let mut command = crate::modules::insert::pdf_attach::PdfAttachCommand::from_dialog(
|
||||
let mut command = crate::modules::insert::pdf_attach::PdfAttachCommand::from_kind_dialog(
|
||||
state.kind,
|
||||
&state.path,
|
||||
&stored,
|
||||
&state.page_labels(),
|
||||
scale,
|
||||
rotation,
|
||||
state.sub_units,
|
||||
insunits,
|
||||
);
|
||||
match insertion {
|
||||
|
||||
@@ -402,8 +402,25 @@ impl OpenCADStudio {
|
||||
} else {
|
||||
codec::entities::UnderlayType::Dwf
|
||||
};
|
||||
let i = self.active_tab;
|
||||
self.start_underlay_attach(i, kind, &path.to_string_lossy());
|
||||
let path = path.to_string_lossy().into_owned();
|
||||
match std::fs::read(&path) {
|
||||
Ok(bytes) => {
|
||||
crate::scene::model::pdf_raster::register_source(&path, std::sync::Arc::new(bytes));
|
||||
crate::scene::model::underlay_vector::forget(&path);
|
||||
if crate::scene::model::underlay_vector::item_names(kind, &path).is_some_and(|n| !n.is_empty()) {
|
||||
self.open_underlay_attach_dialog(kind, &path);
|
||||
} else {
|
||||
self.command_line.push_error(&format!(
|
||||
"{} not found.",
|
||||
crate::entities::underlay::display_path(&path)
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(_) => self.command_line.push_error(&format!(
|
||||
"{} not found.",
|
||||
crate::entities::underlay::display_path(&path)
|
||||
)),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
"png" | "jpg" | "jpeg" | "bmp" | "tif" | "tiff" => {
|
||||
|
||||
@@ -24,7 +24,11 @@ impl OpenCADStudio {
|
||||
Some(K::LayerTranslator) => crate::t!("Layer Translator").into_owned(),
|
||||
Some(K::DrawingUnits) => crate::t!("Drawing Units").into_owned(),
|
||||
Some(K::BlockDefinition) => crate::t!("Block Definition").into_owned(),
|
||||
Some(K::PdfAttach) => crate::t!("Attach PDF Underlay").into_owned(),
|
||||
Some(K::PdfAttach) => match self.pdf_attach.as_ref().map(|s| s.kind) {
|
||||
Some(codec::entities::UnderlayType::Dwf) => crate::t!("Attach DWF Underlay").into_owned(),
|
||||
Some(codec::entities::UnderlayType::Dgn) => crate::t!("Attach DGN Underlay").into_owned(),
|
||||
_ => crate::t!("Attach PDF Underlay").into_owned(),
|
||||
},
|
||||
Some(K::UnderlayLayers) => crate::t!("Underlay Layers").into_owned(),
|
||||
Some(K::PdfImportSettings) => crate::t!("PDF Import Settings").into_owned(),
|
||||
Some(K::PdfImportFile) => crate::t!("Import PDF").into_owned(),
|
||||
|
||||
@@ -2983,6 +2983,25 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Import PDF" => Some(("insert", "pdfui-import-pdf")),
|
||||
"Select one or more pages from the PDF file:" => Some(("insert", "pdfui-select-one-or-more-pages-from-the-pdf-file")),
|
||||
"Page size:" => Some(("insert", "pdfui-page-size")),
|
||||
"Attach Underlay" => Some(("insert", "ul-attach-underlay")),
|
||||
"Attach DWF" => Some(("insert", "ul-attach-dwf")),
|
||||
"Attach DGN" => Some(("insert", "ul-attach-dgn")),
|
||||
"Attach DWF Underlay" => Some(("insert", "ul-attach-dwf-underlay")),
|
||||
"Attach DGN Underlay" => Some(("insert", "ul-attach-dgn-underlay")),
|
||||
"{count} sheets" => Some(("insert", "ul-sheet-count")),
|
||||
"{count} models" => Some(("insert", "ul-model-count")),
|
||||
"Sheets" => Some(("insert", "ul-sheets")),
|
||||
"Models" => Some(("insert", "ul-models")),
|
||||
"Selected sheet: {sheet}" => Some(("insert", "ul-selected-sheet")),
|
||||
"Selected model: {model}" => Some(("insert", "ul-selected-model")),
|
||||
"Sheet size:" => Some(("insert", "ul-sheet-size")),
|
||||
"Model size:" => Some(("insert", "ul-model-size")),
|
||||
"Conversion units" => Some(("insert", "ul-conversion-units")),
|
||||
"Master units" => Some(("insert", "ul-master-units")),
|
||||
"Sub units" => Some(("insert", "ul-sub-units")),
|
||||
"Sub units make the default scale {scale}" => Some(("insert", "ul-sub-units-scale")),
|
||||
"Attaches a DWF or DWFx file as an underlay." => Some(("insert", "ul-attaches-dwf")),
|
||||
"Attaches a DGN file as an underlay." => Some(("insert", "ul-attaches-dgn")),
|
||||
"Reference name:" => Some(("insert", "pdfui-reference-name")),
|
||||
"Search for layer" => Some(("insert", "pdfui-search-for-layer")),
|
||||
"This file does not contain any layers" => Some(("insert", "pdfui-this-file-does-not-contain-any-layers")),
|
||||
|
||||
@@ -53,7 +53,18 @@ impl CadModule for InsertModule {
|
||||
title: "Reference",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(xattach::tool()),
|
||||
RibbonItem::LargeTool(pdf_attach::tool()),
|
||||
// PDF, DWF or DGN; the face runs the last one chosen.
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "UNDERLAY_ATTACH",
|
||||
label: "Attach Underlay",
|
||||
icon: pdf_attach::ICON,
|
||||
items: vec![
|
||||
("PDFATTACH", "Attach PDF", pdf_attach::ICON),
|
||||
("DWFATTACH", "Attach DWF", pdf_attach::ICON),
|
||||
("DGNATTACH", "Attach DGN", pdf_attach::ICON),
|
||||
],
|
||||
default: "PDFATTACH",
|
||||
},
|
||||
RibbonItem::LargeTool(xclip::tool()),
|
||||
RibbonItem::LargeTool(xadjust::tool()),
|
||||
RibbonItem::LabeledTool(underlay_layers::tool()),
|
||||
|
||||
@@ -23,20 +23,11 @@ use glam::DVec3;
|
||||
|
||||
use crate::command::{CadCommand, CmdOption, CmdResult, InputKind, WorkingPlane};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::modules::IconKind;
|
||||
|
||||
pub const ICON: IconKind =
|
||||
IconKind::Svg(include_bytes!("../../../assets/icons/underlay_layers.svg"));
|
||||
|
||||
pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "PDFATTACH",
|
||||
label: "Attach PDF",
|
||||
icon: ICON,
|
||||
event: ModuleEvent::Command("PDFATTACH".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Units the Unit option offers: keyword, the name the prompt shows.
|
||||
const UNITS: [(&str, &str); 9] = [
|
||||
("MM", "Millimeters"),
|
||||
@@ -172,11 +163,6 @@ impl PdfAttachCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// PDFATTACH with a file already chosen: starts at the page prompt.
|
||||
pub fn with_file(path: &str, insunits: i16) -> Self {
|
||||
Self::with_kind_file(UnderlayType::Pdf, path, insunits)
|
||||
}
|
||||
|
||||
/// DWFATTACH / DGNATTACH / PDFATTACH with the file chosen: starts at the
|
||||
/// page, sheet or model prompt.
|
||||
pub fn with_kind_file(kind: UnderlayType, path: &str, insunits: i16) -> Self {
|
||||
@@ -216,23 +202,34 @@ impl PdfAttachCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// The dialog's attach with the insertion point asked on screen: pages
|
||||
/// chosen, the path to store, and any scale / rotation already given.
|
||||
pub fn from_dialog(
|
||||
/// The DWF / DGN (or PDF) Attach dialog: the sheet or model chosen and,
|
||||
/// for DGN, whether sub units were chosen (their scale is then offered).
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn from_kind_dialog(
|
||||
kind: UnderlayType,
|
||||
read_path: &str,
|
||||
stored_path: &str,
|
||||
pages: &[String],
|
||||
scale: Option<f64>,
|
||||
rotation_deg: Option<f64>,
|
||||
sub_units: bool,
|
||||
insunits: i16,
|
||||
) -> Self {
|
||||
let mut command = Self::with_file(read_path, insunits);
|
||||
let mut command = Self::with_kind_file(kind, read_path, insunits);
|
||||
command.stored_path = Some(stored_path.to_string());
|
||||
if let Some((first, rest)) = pages.split_first() {
|
||||
command.page = first.clone();
|
||||
command.extra_pages = rest.to_vec();
|
||||
}
|
||||
command.rect = command.page_rect(&command.page);
|
||||
if kind == UnderlayType::Dgn && sub_units {
|
||||
let sub = crate::scene::model::underlay_vector::sheet(kind, read_path, &command.page)
|
||||
.map(|s| s.sub_per_master)
|
||||
.filter(|v| *v > 0.0)
|
||||
.unwrap_or(1.0);
|
||||
command.default_scale = 1.0 / sub;
|
||||
command.scale = command.default_scale;
|
||||
}
|
||||
command.preset_scale = scale;
|
||||
if let Some(s) = scale {
|
||||
command.scale = s;
|
||||
|
||||
+2
-2
@@ -2753,7 +2753,7 @@ impl Scene {
|
||||
let Some(wpp) = self.world_per_pixel() else {
|
||||
return;
|
||||
};
|
||||
let step = (f64::from(wpp).log2() * 4.0).floor() as i32;
|
||||
let step = (f64::from(wpp).log2() * 4.0).ceil() as i32;
|
||||
let current = self.underlay_world_per_pixel.map(|w| (w.log2() * 4.0).round() as i32);
|
||||
if current == Some(step) {
|
||||
self.underlay_scale_pending = None;
|
||||
@@ -2783,7 +2783,7 @@ impl Scene {
|
||||
let Some(wpp) = self.world_per_pixel() else {
|
||||
return false;
|
||||
};
|
||||
let step = (f64::from(wpp).log2() * 4.0).floor() as i32;
|
||||
let step = (f64::from(wpp).log2() * 4.0).ceil() as i32;
|
||||
self.underlay_world_per_pixel.map(|w| (w.log2() * 4.0).round() as i32) != Some(step)
|
||||
}
|
||||
|
||||
|
||||
@@ -207,7 +207,8 @@ impl ImageModel {
|
||||
let page = crate::entities::underlay::page_of(def);
|
||||
let rect = crate::entities::underlay::definition_rect(def)?;
|
||||
// The page's longest side on screen, pixels (the view scale is taken
|
||||
// a step finer, so the raster is never enlarged on screen).
|
||||
// a step coarser, so the raster is never reduced on screen and its
|
||||
// one-pixel lines stay unbroken).
|
||||
let screen_side = world_per_pixel
|
||||
.filter(|wpp| *wpp > 0.0)
|
||||
.map(|wpp| {
|
||||
@@ -258,8 +259,15 @@ impl ImageModel {
|
||||
&raster,
|
||||
PageAdjust {
|
||||
contrast: u.contrast.min(100),
|
||||
// Measured: PDF 0.5; DWF 0.243, or 0.73 once its colours are
|
||||
// turned over for a dark background; DGN 0.65.
|
||||
contrast_pivot: match def.underlay_type {
|
||||
UnderlayType::Pdf => 500,
|
||||
UnderlayType::Dwf
|
||||
if u.flags.contains(UnderlayDisplayFlags::ADJUST_FOR_BACKGROUND) && bg_lum < 0.5 =>
|
||||
{
|
||||
730
|
||||
}
|
||||
UnderlayType::Dwf => 243,
|
||||
UnderlayType::Dgn => 650,
|
||||
},
|
||||
|
||||
@@ -212,19 +212,57 @@ struct Styles {
|
||||
levels: HashMap<u32, u32>,
|
||||
/// Levels the underlay turns off: their elements are left out.
|
||||
hidden: std::collections::HashSet<u32>,
|
||||
/// True colours, in the order colour words number them (1 first).
|
||||
extended: Vec<[u8; 3]>,
|
||||
}
|
||||
|
||||
/// The true colours of the file: a zlib-packed UTF-16 record in the
|
||||
/// non-model attributes stream reading
|
||||
/// `<ExtendedColors><Entry Color="(r,g,b)"/>…</ExtendedColors>`.
|
||||
fn extended_colors(cfb: &Cfb) -> Vec<[u8; 3]> {
|
||||
let Some(attrs) = cfb.streams().iter().find(|(p, _)| p == "Dgn^NmA/$1").map(|(_, e)| inflate(&cfb.stream(e))) else {
|
||||
return Vec::new();
|
||||
};
|
||||
for at in 0..attrs.len().saturating_sub(2) {
|
||||
// A zlib header: deflate, and a check value divisible by 31.
|
||||
let (a, b) = (attrs[at], attrs[at + 1]);
|
||||
if a & 0x0f != 8 || ((a as u16) << 8 | b as u16) % 31 != 0 {
|
||||
continue;
|
||||
}
|
||||
let mut out = Vec::new();
|
||||
if flate2::read::ZlibDecoder::new(&attrs[at..]).read_to_end(&mut out).is_err() || out.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
let units: Vec<u16> = out.chunks_exact(2).map(|c| u16::from_le_bytes([c[0], c[1]])).collect();
|
||||
let text = String::from_utf16_lossy(&units);
|
||||
if !text.contains("<ExtendedColors") {
|
||||
continue;
|
||||
}
|
||||
return text
|
||||
.split("Color=\"(")
|
||||
.skip(1)
|
||||
.filter_map(|rest| {
|
||||
let v: Vec<u8> = rest.split(')').next()?.split(',').filter_map(|n| n.trim().parse().ok()).collect();
|
||||
(v.len() == 3).then(|| [v[0], v[1], v[2]])
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
impl Styles {
|
||||
fn color(&self, e: &[u8]) -> [u8; 3] {
|
||||
// The colour word: an index into the colour table, 0xFFFFFFFF for
|
||||
// the level's colour, or a true colour — n × 256 plus the index of
|
||||
// its nearest table colour.
|
||||
// ponytail: a true colour draws as that nearest index; the RGB it
|
||||
// stands for is not read.
|
||||
// the level's colour, or true colour n (from 1) × 256 plus the index
|
||||
// of its nearest table colour, drawn in its own RGB when the file
|
||||
// lists it.
|
||||
let explicit = u32_at(e, 52).unwrap_or(u32::MAX);
|
||||
let index = if explicit == u32::MAX {
|
||||
self.levels.get(&u32_at(e, 12).unwrap_or(0)).copied().unwrap_or(0)
|
||||
} else {
|
||||
if let Some(rgb) = (explicit >> 8).checked_sub(1).and_then(|n| self.extended.get(n as usize)) {
|
||||
return *rgb;
|
||||
}
|
||||
explicit & 0xff
|
||||
};
|
||||
self.colors.get(index as usize).copied().unwrap_or([255, 255, 255])
|
||||
@@ -580,7 +618,7 @@ pub fn model(bytes: &[u8], name: &str, hidden: &[String]) -> Option<Sheet> {
|
||||
.filter(|l| hidden.iter().any(|h| h.eq_ignore_ascii_case(&l.1)))
|
||||
.map(|l| l.0)
|
||||
.collect();
|
||||
let styles = Styles { colors, levels, hidden };
|
||||
let styles = Styles { colors, levels, hidden, extended: extended_colors(&cfb) };
|
||||
// Shared cell definitions: a type-34 element and its components.
|
||||
let mut defs = HashMap::new();
|
||||
let mut i = 0;
|
||||
|
||||
@@ -164,12 +164,69 @@ pub fn sheet(bytes: &[u8], name: &str) -> Option<Sheet> {
|
||||
w2d::read(data)?
|
||||
} else {
|
||||
let w2x = entry.w2x.as_ref().and_then(|p| files.get(p));
|
||||
xps::read(data, w2x.map(|v| v.as_slice()), entry)?
|
||||
// An embedded font (FontUri, relative to the page) names its family.
|
||||
let page_dir = entry.graphics.rsplit_once('/').map(|(d, _)| d.to_string()).unwrap_or_default();
|
||||
let family = |uri: &str| -> Option<String> {
|
||||
let uri = uri.trim_start_matches("./");
|
||||
let key = if let Some(abs) = uri.strip_prefix('/') { abs.to_string() } else { format!("{page_dir}/{uri}") };
|
||||
let data = files.get(&key)?;
|
||||
let name = key.rsplit('/').next()?;
|
||||
font_family(&deobfuscate(data, name)?)
|
||||
};
|
||||
xps::read(data, w2x.map(|v| v.as_slice()), entry, &family)?
|
||||
};
|
||||
let rect = view.or_else(|| paths_bounds(&paths))?;
|
||||
Some(Sheet { rect, paths, texts, sub_per_master: 1.0 })
|
||||
}
|
||||
|
||||
/// An XPS obfuscated font (.odttf): its first 32 bytes are XORed with the
|
||||
/// GUID of its file name, byte order reversed.
|
||||
fn deobfuscate(data: &[u8], file_name: &str) -> Option<Vec<u8>> {
|
||||
let hex: String = file_name.split('.').next()?.chars().filter(|c| c.is_ascii_hexdigit()).collect();
|
||||
if hex.len() != 32 || data.len() < 32 {
|
||||
return None;
|
||||
}
|
||||
let bytes: Vec<u8> = (0..16).filter_map(|i| u8::from_str_radix(&hex[i * 2..i * 2 + 2], 16).ok()).collect();
|
||||
let key: Vec<u8> = bytes.into_iter().rev().collect();
|
||||
let mut out = data.to_vec();
|
||||
for i in 0..32 {
|
||||
out[i] ^= key[i % 16];
|
||||
}
|
||||
Some(out)
|
||||
}
|
||||
|
||||
/// The family name (name id 1) of a TrueType font.
|
||||
fn font_family(font: &[u8]) -> Option<String> {
|
||||
let u16be = |at: usize| Some(u16::from_be_bytes(font.get(at..at + 2)?.try_into().ok()?));
|
||||
let u32be = |at: usize| Some(u32::from_be_bytes(font.get(at..at + 4)?.try_into().ok()?));
|
||||
let tables = u16be(4)? as usize;
|
||||
let name = (0..tables).find_map(|t| {
|
||||
let at = 12 + t * 16;
|
||||
(font.get(at..at + 4)? == b"name").then(|| u32be(at + 8)).flatten()
|
||||
})? as usize;
|
||||
let count = u16be(name + 2)? as usize;
|
||||
let strings = name + u16be(name + 4)? as usize;
|
||||
let mut fallback = None;
|
||||
for r in 0..count {
|
||||
let at = name + 6 + r * 12;
|
||||
let (platform, name_id) = (u16be(at)?, u16be(at + 6)?);
|
||||
if name_id != 1 {
|
||||
continue;
|
||||
}
|
||||
let (len, off) = (u16be(at + 8)? as usize, u16be(at + 10)? as usize);
|
||||
let raw = font.get(strings + off..strings + off + len)?;
|
||||
match platform {
|
||||
// Windows: UTF-16 big endian.
|
||||
3 | 0 => {
|
||||
let units: Vec<u16> = raw.chunks_exact(2).map(|c| u16::from_be_bytes([c[0], c[1]])).collect();
|
||||
return Some(String::from_utf16_lossy(&units));
|
||||
}
|
||||
_ => fallback = Some(String::from_utf8_lossy(raw).to_string()),
|
||||
}
|
||||
}
|
||||
fallback
|
||||
}
|
||||
|
||||
/// The default colour map of a W2D stream: ten system colours, a 6×6×6
|
||||
/// colour cube from index 10 (red 36 steps, green 6, blue 1), a grey ramp
|
||||
/// at 226-245 and ten more system colours (measured against plotted files:
|
||||
@@ -617,7 +674,12 @@ mod xps {
|
||||
}
|
||||
|
||||
/// The fixed page's paths and text in model units, and the plotted view.
|
||||
pub fn read(page: &[u8], w2x: Option<&[u8]>, entry: &SheetEntry) -> Option<(Vec<Path>, Option<[f64; 4]>, Vec<Text>)> {
|
||||
pub fn read(
|
||||
page: &[u8],
|
||||
w2x: Option<&[u8]>,
|
||||
entry: &SheetEntry,
|
||||
family: &dyn Fn(&str) -> Option<String>,
|
||||
) -> Option<(Vec<Path>, Option<[f64; 4]>, Vec<Text>)> {
|
||||
let mut units = Units::identity();
|
||||
let mut view_log = None;
|
||||
if let Some(w2x) = w2x.and_then(|b| std::str::from_utf8(b).ok()) {
|
||||
@@ -660,9 +722,7 @@ mod xps {
|
||||
};
|
||||
if node.tag_name().name() == "Glyphs" {
|
||||
// Text: its baseline origin and em size in page units (y
|
||||
// down), drawn in the plotted family.
|
||||
// ponytail: the embedded font is obfuscated and not read;
|
||||
// DWFx text is drawn in Arial.
|
||||
// down), drawn in the embedded font's family.
|
||||
let num = |name: &str| attr(node, name).and_then(|v| v.parse::<f64>().ok());
|
||||
let (Some(em), Some(text)) = (num("FontRenderingEmSize"), attr(node, "UnicodeString")) else { return };
|
||||
let o = [num("OriginX").unwrap_or(0.0), num("OriginY").unwrap_or(0.0)];
|
||||
@@ -677,7 +737,7 @@ mod xps {
|
||||
width_factor: if len(up) > 0.0 { len(along) / len(up) } else { 1.0 },
|
||||
rotation: (along[1] - a[1]).atan2(along[0] - a[0]),
|
||||
color: attr(node, "Fill").and_then(parse_color).unwrap_or([0, 0, 0]),
|
||||
font: "Arial".to_string(),
|
||||
font: attr(node, "FontUri").and_then(family).unwrap_or_else(|| "Arial".to_string()),
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -93,15 +93,31 @@ pub fn sheet_without(kind: UnderlayType, path: &str, item: &str, hidden: &[Strin
|
||||
UnderlayType::Dgn => dgn8::model(&bytes, item, hidden).unwrap_or_default(),
|
||||
UnderlayType::Pdf => return None,
|
||||
};
|
||||
outline_texts(&mut sheet);
|
||||
// A DGN model's extent is its geometry, text included (a DWF sheet
|
||||
// keeps its plotted view).
|
||||
// A DGN model's extent includes its text: each text's box runs its
|
||||
// length along the baseline and 1.5 × its height above it (as the
|
||||
// reference measures a model). A DWF sheet keeps its plotted view.
|
||||
if kind == UnderlayType::Dgn {
|
||||
if let Some(b) = model::paths_bounds(&sheet.paths) {
|
||||
let r = sheet.rect;
|
||||
sheet.rect = [r[0].min(b[0]), r[1].min(b[1]), r[2].max(b[2]), r[3].max(b[3])];
|
||||
let mut r = sheet.rect;
|
||||
for t in &sheet.texts {
|
||||
let (strokes, _) = crate::scene::text::lff::tessellate_text_ex(
|
||||
[0.0, 0.0],
|
||||
t.height as f32,
|
||||
0.0,
|
||||
t.width_factor as f32,
|
||||
0.0,
|
||||
&t.font,
|
||||
&t.text,
|
||||
);
|
||||
let length = strokes.iter().flatten().map(|p| p[0] as f64).fold(0.0, f64::max);
|
||||
let (c, s) = (t.rotation.cos(), t.rotation.sin());
|
||||
for [x, y] in [[0.0, 0.0], [length, 0.0], [length, 1.5 * t.height], [0.0, 1.5 * t.height]] {
|
||||
let p = [t.origin[0] + x * c - y * s, t.origin[1] + x * s + y * c];
|
||||
r = [r[0].min(p[0]), r[1].min(p[1]), r[2].max(p[0]), r[3].max(p[1])];
|
||||
}
|
||||
}
|
||||
sheet.rect = r;
|
||||
}
|
||||
outline_texts(&mut sheet);
|
||||
if !hidden.is_empty() {
|
||||
sheet.rect = sheet_without(kind, path, item, &[])?.rect;
|
||||
}
|
||||
@@ -206,10 +222,13 @@ fn rasterize(sheet: &Sheet, side: f64) -> Option<PdfPage> {
|
||||
if let Some((c, width)) = path.stroke {
|
||||
let mut paint = tiny_skia::Paint::default();
|
||||
paint.set_color_rgba8(c[0], c[1], c[2], 255);
|
||||
paint.anti_alias = true;
|
||||
// A negative width is in pixels (DGN line weights).
|
||||
let px = if width < 0.0 { (-width) as f32 } else { ((width * scale) as f32).max(1.0) };
|
||||
// Hairlines are drawn solid, one pixel wide, as the reference
|
||||
// draws them; anti-aliasing would spread them to half intensity.
|
||||
paint.anti_alias = px > 1.5;
|
||||
let stroke = tiny_skia::Stroke {
|
||||
// A negative width is in pixels (DGN line weights).
|
||||
width: if width < 0.0 { (-width) as f32 } else { ((width * scale) as f32).max(1.0) },
|
||||
width: px,
|
||||
line_cap: tiny_skia::LineCap::Round,
|
||||
line_join: tiny_skia::LineJoin::Round,
|
||||
..Default::default()
|
||||
|
||||
@@ -24,6 +24,8 @@ pub enum PdfDialogMsg {
|
||||
AttachName(String),
|
||||
AttachBrowse,
|
||||
AttachPage(usize),
|
||||
/// DGN conversion units: sub (true) or master.
|
||||
AttachSubUnits(bool),
|
||||
AttachPathType(PathTypeChoice),
|
||||
AttachInsertOnScreen(bool),
|
||||
AttachInsert(usize, String),
|
||||
@@ -134,6 +136,23 @@ pub fn page_thumbs(path: &str) -> Vec<PageThumb> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Thumbnails of a file's pages (PDF), sheets (DWF) or models (DGN).
|
||||
pub fn item_thumbs(kind: codec::entities::UnderlayType, path: &str) -> Vec<PageThumb> {
|
||||
use crate::scene::model::underlay_vector;
|
||||
if kind == codec::entities::UnderlayType::Pdf {
|
||||
return page_thumbs(path);
|
||||
}
|
||||
underlay_vector::item_names(kind, path)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|label| {
|
||||
let image = underlay_vector::display_raster(kind, path, &label, &[], 220.0)
|
||||
.map(|page| image::Handle::from_rgba(page.width, page.height, page.pixels.to_vec()));
|
||||
PageThumb { label, image }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Ctrl adds or removes a page, Shift takes the range from the last click,
|
||||
/// a plain click selects that page alone.
|
||||
pub fn click_page(selected: &mut Vec<usize>, anchor: &mut usize, page: usize, ctrl: bool, shift: bool) {
|
||||
@@ -413,6 +432,12 @@ impl Default for AttachMemory {
|
||||
pub static ATTACH_MEMORY: std::sync::Mutex<Option<AttachMemory>> = std::sync::Mutex::new(None);
|
||||
|
||||
pub struct PdfAttachState {
|
||||
/// PDF pages, DWF sheets or DGN models.
|
||||
pub kind: codec::entities::UnderlayType,
|
||||
/// DGN: sub units chosen (the scale then turns them into master units).
|
||||
pub sub_units: bool,
|
||||
/// DGN: sub units per master unit of the chosen model.
|
||||
pub sub_per_master: f64,
|
||||
/// The file read (absolute).
|
||||
pub path: String,
|
||||
pub name: String,
|
||||
@@ -444,6 +469,9 @@ impl PdfAttachState {
|
||||
.unwrap_or_default();
|
||||
let names = existing.iter().map(|(name, _)| name.clone()).collect();
|
||||
Self {
|
||||
kind: codec::entities::UnderlayType::Pdf,
|
||||
sub_units: false,
|
||||
sub_per_master: 1.0,
|
||||
path: String::new(),
|
||||
name: String::new(),
|
||||
existing,
|
||||
@@ -501,9 +529,13 @@ pub fn view_attach<'a>(
|
||||
.size(12)
|
||||
.padding([5, 8])
|
||||
.width(Fill);
|
||||
let count = container(
|
||||
text(crate::tf!("{count} pages", count = state.pages.len())).size(11).style(accent_text),
|
||||
)
|
||||
use codec::entities::UnderlayType;
|
||||
let count_text = match state.kind {
|
||||
UnderlayType::Pdf => crate::tf!("{count} pages", count = state.pages.len()),
|
||||
UnderlayType::Dwf => crate::tf!("{count} sheets", count = state.pages.len()),
|
||||
UnderlayType::Dgn => crate::tf!("{count} models", count = state.pages.len()),
|
||||
};
|
||||
let count = container(text(count_text).size(11).style(accent_text))
|
||||
.padding([4, 10])
|
||||
.style(well_style);
|
||||
let file = row![
|
||||
@@ -519,15 +551,20 @@ pub fn view_attach<'a>(
|
||||
|
||||
// Pages: the thumbnails, then which ones are chosen.
|
||||
let chosen = state.page_labels().join(", ");
|
||||
let (items_title, chosen_text, size_label) = match state.kind {
|
||||
UnderlayType::Pdf => (t!("Pages"), crate::tf!("Selected pages: {pages}", pages = chosen), t!("Page size:")),
|
||||
UnderlayType::Dwf => (t!("Sheets"), crate::tf!("Selected sheet: {sheet}", sheet = chosen), t!("Sheet size:")),
|
||||
UnderlayType::Dgn => (t!("Models"), crate::tf!("Selected model: {model}", model = chosen), t!("Model size:")),
|
||||
};
|
||||
let pages = card(
|
||||
t!("Pages").into_owned(),
|
||||
items_title.into_owned(),
|
||||
column![
|
||||
container(page_tiles(&state.pages, &state.selected, PdfDialogMsg::AttachPage))
|
||||
.padding(6)
|
||||
.height(Length::Fixed(226.0))
|
||||
.width(Fill)
|
||||
.style(well_style),
|
||||
text(crate::tf!("Selected pages: {pages}", pages = chosen)).size(11).style(muted_style),
|
||||
text(chosen_text).size(11).style(muted_style),
|
||||
]
|
||||
.spacing(6),
|
||||
);
|
||||
@@ -588,14 +625,35 @@ pub fn view_attach<'a>(
|
||||
column![
|
||||
info_line(t!("Found in:").into_owned(), &state.found_in),
|
||||
info_line(t!("Saved path:").into_owned(), &state.saved_path),
|
||||
info_line(t!("Page size:").into_owned(), &state.page_size),
|
||||
info_line(size_label.into_owned(), &state.page_size),
|
||||
]
|
||||
.spacing(4),
|
||||
);
|
||||
|
||||
let mut right = column![placement, path].spacing(8).width(Length::FillPortion(2));
|
||||
// A DGN model is attached in its master or its sub units.
|
||||
if state.kind == UnderlayType::Dgn {
|
||||
right = right.push(card(
|
||||
t!("Conversion units").into_owned(),
|
||||
column![
|
||||
segmented(
|
||||
vec![(false, t!("Master units").into_owned()), (true, t!("Sub units").into_owned())],
|
||||
state.sub_units,
|
||||
PdfDialogMsg::AttachSubUnits,
|
||||
),
|
||||
text(crate::tf!(
|
||||
"Sub units make the default scale {scale}",
|
||||
scale = 1.0 / state.sub_per_master.max(1e-12)
|
||||
))
|
||||
.size(11)
|
||||
.style(muted_style),
|
||||
]
|
||||
.spacing(6),
|
||||
));
|
||||
}
|
||||
let body = row![
|
||||
column![pages, details].spacing(8).width(Length::FillPortion(3)),
|
||||
column![placement, path].spacing(8).width(Length::FillPortion(2)),
|
||||
right,
|
||||
]
|
||||
.spacing(10);
|
||||
|
||||
|
||||
Reference in new issue
Block a user