forked from 1b-agent/opencadstudio-upstream
feat(plot): PSETUPIN and page-setup import, page setup for new layouts
- PSETUPIN / -PSETUPIN: with no arguments a file picker offers the chosen drawing's named page setups in the Plot dialog; `PSETUPIN <file>` opens the same chooser on that file; `PSETUPIN <file> *` or `PSETUPIN <file> name,name` import straight away. Same-named setups are replaced, the import is one undo step, and the report counts both. - The Plot dialog's page-setup list gains "Import…": the chooser shows the source drawing's setups with a tick each, All, Import and Cancel, and selects the first imported setup afterwards. The source is read off the UI thread with the same reader the editor uses for its own setups (`scene::document_page_setups`), and handles that only meant something in the source drawing (plot view, visual style) are dropped on import. - Options → General → Plotting: "Show the page setup for new layouts" opens the Plot / Page Setup dialog whenever a layout is created (persisted with the plot preferences). Tests: the document reader, the command (all / named / unknown / missing file / undo) against a drawing saved by the app, the chooser flow, and the new-layout option. Nine new strings in all 21 locales. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
1 parent
7efb04a666
commit
74936063f9
35 files changed
+786
-48
No files matched your search
@@ -5111,6 +5111,15 @@ plot =
|
||||
.system-default-printer = طابعة النظام الافتراضية
|
||||
.what-to-plot = ما المراد طباعته
|
||||
.x-mm = X (مم)
|
||||
.select-drawing-to-import-page-setups-from = اختر الرسم لاستيراد إعدادات الصفحة منه
|
||||
.drawings-and-templates = الرسومات والقوالب
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: تم استيراد __ocs_fmt_0__ من إعدادات الصفحة، واستبدال __ocs_fmt_1__.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: لا يوجد إعداد صفحة باسم "__ocs_fmt_0__" في __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: لا يوجد ما يمكن استيراده من __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = لا توجد إعدادات صفحة مسماة في هذا الرسم.
|
||||
.import-ellipsis = استيراد…
|
||||
.show-the-page-setup-for-new-layouts = إظهار إعداد الصفحة للتخطيطات الجديدة
|
||||
.x-in = X (بوصة)
|
||||
.y-in = Y (بوصة)
|
||||
.hide-paperspace-objects = إخفاء كائنات مساحة الورق
|
||||
|
||||
@@ -5099,6 +5099,15 @@ plot =
|
||||
.system-default-printer = Системен принтер по подразбиране
|
||||
.what-to-plot = Какво да се плотира
|
||||
.x-mm = X (мм)
|
||||
.select-drawing-to-import-page-setups-from = Изберете чертеж, от който да се импортират настройките на страницата
|
||||
.drawings-and-templates = Чертежи и шаблони
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: импортирани __ocs_fmt_0__ настройки на страницата, __ocs_fmt_1__ заменени.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: няма настройка на страницата с име „__ocs_fmt_0__“ в __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: няма нищо за импортиране от __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = В този чертеж няма именувани настройки на страницата.
|
||||
.import-ellipsis = Импортиране…
|
||||
.show-the-page-setup-for-new-layouts = Показване на настройката на страницата за нови оформления
|
||||
.x-in = X (инча)
|
||||
.y-in = Y (инча)
|
||||
.hide-paperspace-objects = Скриване на обектите в пространството на листа
|
||||
|
||||
@@ -5096,6 +5096,15 @@ plot =
|
||||
.system-default-printer = Výchozí tiskárna systému
|
||||
.what-to-plot = Co fabulovat
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Vyberte výkres pro import nastavení stránky
|
||||
.drawings-and-templates = Výkresy a šablony
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: importováno __ocs_fmt_0__ nastavení stránky, __ocs_fmt_1__ nahrazeno.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: žádné nastavení stránky s názvem „__ocs_fmt_0__“ v __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: z __ocs_fmt_0__ není co importovat.
|
||||
.no-named-page-setups-in-this-drawing = V tomto výkresu nejsou pojmenovaná nastavení stránky.
|
||||
.import-ellipsis = Importovat…
|
||||
.show-the-page-setup-for-new-layouts = Zobrazit nastavení stránky pro nová rozvržení
|
||||
.x-in = X (palce)
|
||||
.y-in = Y (palce)
|
||||
.hide-paperspace-objects = Skrýt objekty výkresového prostoru
|
||||
|
||||
@@ -5097,6 +5097,15 @@ plot =
|
||||
.system-default-printer = Systemstandarddrucker
|
||||
.what-to-plot = Was zu plotten
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Zeichnung für den Seiteneinrichtungs-Import wählen
|
||||
.drawings-and-templates = Zeichnungen und Vorlagen
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ Seiteneinrichtung(en) importiert, __ocs_fmt_1__ ersetzt.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: keine Seiteneinrichtung namens „__ocs_fmt_0__“ in __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nichts zu importieren aus __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Keine benannten Seiteneinrichtungen in dieser Zeichnung.
|
||||
.import-ellipsis = Importieren…
|
||||
.show-the-page-setup-for-new-layouts = Seiteneinrichtung für neue Layouts anzeigen
|
||||
.x-in = X (Zoll)
|
||||
.y-in = Y (Zoll)
|
||||
.hide-paperspace-objects = Papierbereichsobjekte ausblenden
|
||||
|
||||
@@ -5099,6 +5099,15 @@ plot =
|
||||
.system-default-printer = Προεπιλεγμένος εκτυπωτής συστήματος
|
||||
.what-to-plot = Τι θα εκτυπωθεί
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Επιλογή σχεδίου για εισαγωγή page setups
|
||||
.drawings-and-templates = Σχέδια και πρότυπα
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: εισήχθησαν __ocs_fmt_0__ page setup(s), __ocs_fmt_1__ αντικαταστάθηκαν.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: δεν υπάρχει page setup με όνομα «__ocs_fmt_0__» στο __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: τίποτα προς εισαγωγή από το __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Δεν υπάρχουν επώνυμα page setups σε αυτό το σχέδιο.
|
||||
.import-ellipsis = Εισαγωγή…
|
||||
.show-the-page-setup-for-new-layouts = Εμφάνιση του page setup για νέα layouts
|
||||
.x-in = X (in)
|
||||
.y-in = Y (in)
|
||||
.hide-paperspace-objects = Απόκρυψη αντικειμένων χώρου χαρτιού
|
||||
|
||||
@@ -5100,6 +5100,15 @@ plot =
|
||||
.system-default-printer = System default printer
|
||||
.what-to-plot = What to plot
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Select Drawing to Import Page Setups From
|
||||
.drawings-and-templates = Drawings and templates
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ page setup(s) imported, __ocs_fmt_1__ replaced.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: no page setup named "__ocs_fmt_0__" in __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nothing to import from __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = No named page setups in this drawing.
|
||||
.import-ellipsis = Import…
|
||||
.show-the-page-setup-for-new-layouts = Show the page setup for new layouts
|
||||
.x-in = X (in)
|
||||
.y-in = Y (in)
|
||||
.hide-paperspace-objects = Hide paperspace objects
|
||||
|
||||
@@ -5099,6 +5099,15 @@ plot =
|
||||
.system-default-printer = Impresora predeterminada del sistema
|
||||
.what-to-plot = Qué trazar
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Seleccionar dibujo del que importar configuraciones de página
|
||||
.drawings-and-templates = Dibujos y plantillas
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ configuración(es) de página importada(s), __ocs_fmt_1__ reemplazada(s).
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: no hay ninguna configuración de página llamada "__ocs_fmt_0__" en __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nada que importar de __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = No hay configuraciones de página con nombre en este dibujo.
|
||||
.import-ellipsis = Importar…
|
||||
.show-the-page-setup-for-new-layouts = Mostrar la configuración de página para las presentaciones nuevas
|
||||
.x-in = X (pulg)
|
||||
.y-in = Y (pulg)
|
||||
.hide-paperspace-objects = Ocultar objetos del espacio papel
|
||||
|
||||
@@ -5098,6 +5098,15 @@ plot =
|
||||
.system-default-printer = Järjestelmän oletustulostin
|
||||
.what-to-plot = Mitä piirtää
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Valitse piirustus, josta sivuasetukset tuodaan
|
||||
.drawings-and-templates = Piirustukset ja mallipohjat
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ sivuasetusta tuotu, __ocs_fmt_1__ korvattu.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: sivuasetusta "__ocs_fmt_0__" ei ole tiedostossa __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: ei mitään tuotavaa tiedostosta __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Tässä piirustuksessa ei ole nimettyjä sivuasetuksia.
|
||||
.import-ellipsis = Tuo…
|
||||
.show-the-page-setup-for-new-layouts = Näytä sivuasetus uusille asetteluille
|
||||
.x-in = X (tuumaa)
|
||||
.y-in = Y (tuumaa)
|
||||
.hide-paperspace-objects = Piilota paperitilan objektit
|
||||
|
||||
@@ -5099,6 +5099,15 @@ plot =
|
||||
.system-default-printer = Imprimante système par défaut
|
||||
.what-to-plot = Quoi faire?
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Sélectionner le dessin d'où importer les mises en page
|
||||
.drawings-and-templates = Dessins et gabarits
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN : __ocs_fmt_0__ mise(s) en page importée(s), __ocs_fmt_1__ remplacée(s).
|
||||
.psetupin-error = PSETUPIN : __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN : aucune mise en page nommée « __ocs_fmt_0__ » dans __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN : rien à importer depuis __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Aucune mise en page nommée dans ce dessin.
|
||||
.import-ellipsis = Importer…
|
||||
.show-the-page-setup-for-new-layouts = Afficher la mise en page pour les nouvelles présentations
|
||||
.x-in = X (po)
|
||||
.y-in = Y (po)
|
||||
.hide-paperspace-objects = Masquer les objets de l'espace papier
|
||||
|
||||
@@ -5087,6 +5087,15 @@ plot =
|
||||
.system-default-printer = सिस्टम डिफ़ॉल्ट प्रिंटर
|
||||
.what-to-plot = क्या प्लॉट करना है
|
||||
.x-mm = एक्स (मिमी)
|
||||
.select-drawing-to-import-page-setups-from = पेज सेटअप आयात करने के लिए ड्रॉइंग चुनें
|
||||
.drawings-and-templates = ड्रॉइंग और टेम्पलेट
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ पेज सेटअप आयात किए गए, __ocs_fmt_1__ बदले गए।
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: __ocs_fmt_1__ में "__ocs_fmt_0__" नाम का कोई पेज सेटअप नहीं है।
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: __ocs_fmt_0__ से आयात करने के लिए कुछ नहीं है।
|
||||
.no-named-page-setups-in-this-drawing = इस ड्रॉइंग में कोई नामित पेज सेटअप नहीं है।
|
||||
.import-ellipsis = आयात करें…
|
||||
.show-the-page-setup-for-new-layouts = नए लेआउट के लिए पेज सेटअप दिखाएँ
|
||||
.x-in = एक्स (इंच)
|
||||
.y-in = वाई (इंच)
|
||||
.hide-paperspace-objects = पेपर स्पेस ऑब्जेक्ट छिपाएँ
|
||||
|
||||
@@ -5098,6 +5098,15 @@ plot =
|
||||
.system-default-printer = Rendszer alapértelmezett nyomtató
|
||||
.what-to-plot = Mit kell kitalálni
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Válassza ki a rajzot, amelyből oldalbeállításokat importál
|
||||
.drawings-and-templates = Rajzok és sablonok
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ oldalbeállítás importálva, __ocs_fmt_1__ lecserélve.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: nincs „__ocs_fmt_0__” nevű oldalbeállítás a(z) __ocs_fmt_1__ fájlban.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nincs mit importálni innen: __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Ebben a rajzban nincsenek névvel ellátott oldalbeállítások.
|
||||
.import-ellipsis = Importálás…
|
||||
.show-the-page-setup-for-new-layouts = Oldalbeállítás megjelenítése új elrendezésekhez
|
||||
.x-in = X (hüvelyk)
|
||||
.y-in = Y (hüvelyk)
|
||||
.hide-paperspace-objects = Papírtér-objektumok elrejtése
|
||||
|
||||
@@ -5098,6 +5098,15 @@ plot =
|
||||
.system-default-printer = Stampante predefinita del sistema
|
||||
.what-to-plot = Cosa tracciare
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Seleziona il disegno da cui importare le impostazioni di pagina
|
||||
.drawings-and-templates = Disegni e modelli
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ impostazione/i di pagina importata/e, __ocs_fmt_1__ sostituita/e.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: nessuna impostazione di pagina chiamata "__ocs_fmt_0__" in __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: niente da importare da __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Nessuna impostazione di pagina con nome in questo disegno.
|
||||
.import-ellipsis = Importa…
|
||||
.show-the-page-setup-for-new-layouts = Mostra l'impostazione di pagina per i nuovi layout
|
||||
.x-in = X (poll.)
|
||||
.y-in = Y (poll.)
|
||||
.hide-paperspace-objects = Nascondi oggetti dello spazio carta
|
||||
|
||||
@@ -5087,6 +5087,15 @@ plot =
|
||||
.system-default-printer = システムの既定プリンター
|
||||
.what-to-plot = 印刷対象
|
||||
.x-mm = X(mm)
|
||||
.select-drawing-to-import-page-setups-from = ページ設定を読み込む図面を選択
|
||||
.drawings-and-templates = 図面とテンプレート
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ 件のページ設定を読み込み、__ocs_fmt_1__ 件を置き換えました。
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: __ocs_fmt_1__ に「__ocs_fmt_0__」というページ設定はありません。
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: __ocs_fmt_0__ に読み込むものがありません。
|
||||
.no-named-page-setups-in-this-drawing = この図面には名前付きページ設定がありません。
|
||||
.import-ellipsis = 読み込み…
|
||||
.show-the-page-setup-for-new-layouts = 新しいレイアウトでページ設定を表示
|
||||
.x-in = X(インチ)
|
||||
.y-in = Y(インチ)
|
||||
.hide-paperspace-objects = ペーパー空間のオブジェクトを隠す
|
||||
|
||||
@@ -5098,6 +5098,15 @@ plot =
|
||||
.system-default-printer = 시스템 기본 프린터
|
||||
.what-to-plot = 무엇을 플롯할 것인가
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = 페이지 설정을 가져올 도면 선택
|
||||
.drawings-and-templates = 도면 및 템플릿
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: 페이지 설정 __ocs_fmt_0__개를 가져왔고 __ocs_fmt_1__개를 교체했습니다.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: __ocs_fmt_1__에 "__ocs_fmt_0__" 페이지 설정이 없습니다.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: __ocs_fmt_0__에서 가져올 항목이 없습니다.
|
||||
.no-named-page-setups-in-this-drawing = 이 도면에는 명명된 페이지 설정이 없습니다.
|
||||
.import-ellipsis = 가져오기…
|
||||
.show-the-page-setup-for-new-layouts = 새 배치에 페이지 설정 표시
|
||||
.x-in = X (인치)
|
||||
.y-in = Y (인치)
|
||||
.hide-paperspace-objects = 도면 공간 객체 숨기기
|
||||
|
||||
@@ -5097,6 +5097,15 @@ plot =
|
||||
.system-default-printer = Standaardprinter van het systeem
|
||||
.what-to-plot = Wat te plannen
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Tekening kiezen om pagina-instellingen uit te importeren
|
||||
.drawings-and-templates = Tekeningen en sjablonen
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ pagina-instelling(en) geïmporteerd, __ocs_fmt_1__ vervangen.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: geen pagina-instelling met de naam "__ocs_fmt_0__" in __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: niets te importeren uit __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Geen benoemde pagina-instellingen in deze tekening.
|
||||
.import-ellipsis = Importeren…
|
||||
.show-the-page-setup-for-new-layouts = Pagina-instelling tonen voor nieuwe lay-outs
|
||||
.x-in = X (inch)
|
||||
.y-in = Y (inch)
|
||||
.hide-paperspace-objects = Papierruimte-objecten verbergen
|
||||
|
||||
@@ -5098,6 +5098,15 @@ plot =
|
||||
.system-default-printer = Domyślna drukarka systemowa
|
||||
.what-to-plot = Co nakreślić
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Wybierz rysunek, z którego zaimportować ustawienia strony
|
||||
.drawings-and-templates = Rysunki i szablony
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: zaimportowano __ocs_fmt_0__ ustawień strony, zastąpiono __ocs_fmt_1__.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: brak ustawienia strony o nazwie „__ocs_fmt_0__” w __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nie ma nic do zaimportowania z __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Brak nazwanych ustawień strony w tym rysunku.
|
||||
.import-ellipsis = Importuj…
|
||||
.show-the-page-setup-for-new-layouts = Pokaż ustawienia strony dla nowych arkuszy
|
||||
.x-in = X (cale)
|
||||
.y-in = Y (cale)
|
||||
.hide-paperspace-objects = Ukryj obiekty przestrzeni papieru
|
||||
|
||||
@@ -5099,6 +5099,15 @@ plot =
|
||||
.system-default-printer = Impressora padrão do sistema
|
||||
.what-to-plot = O que plotar
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Selecionar desenho de onde importar configurações de página
|
||||
.drawings-and-templates = Desenhos e modelos
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ configuração(ões) de página importada(s), __ocs_fmt_1__ substituída(s).
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: nenhuma configuração de página chamada "__ocs_fmt_0__" em __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: nada para importar de __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = Nenhuma configuração de página nomeada neste desenho.
|
||||
.import-ellipsis = Importar…
|
||||
.show-the-page-setup-for-new-layouts = Mostrar a configuração de página para novos layouts
|
||||
.x-in = X (pol)
|
||||
.y-in = Y (pol)
|
||||
.hide-paperspace-objects = Ocultar objetos do espaço do papel
|
||||
|
||||
@@ -5100,6 +5100,15 @@ plot =
|
||||
.system-default-printer = Системный принтер по умолчанию
|
||||
.what-to-plot = Что спланировать
|
||||
.x-mm = X (мм)
|
||||
.select-drawing-to-import-page-setups-from = Выберите чертёж для импорта наборов параметров листа
|
||||
.drawings-and-templates = Чертежи и шаблоны
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: импортировано наборов: __ocs_fmt_0__, заменено: __ocs_fmt_1__.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: набор параметров листа «__ocs_fmt_0__» не найден в __ocs_fmt_1__.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: нечего импортировать из __ocs_fmt_0__.
|
||||
.no-named-page-setups-in-this-drawing = В этом чертеже нет именованных наборов параметров листа.
|
||||
.import-ellipsis = Импорт…
|
||||
.show-the-page-setup-for-new-layouts = Показывать параметры листа для новых листов
|
||||
.x-in = X (дюймы)
|
||||
.y-in = Y (дюймы)
|
||||
.hide-paperspace-objects = Скрыть объекты пространства листа
|
||||
|
||||
@@ -5039,6 +5039,15 @@ plot =
|
||||
.system-default-printer = Varsayılan sistem yazıcısı
|
||||
.what-to-plot = Yazdırılacak Alan
|
||||
.x-mm = X (mm)
|
||||
.select-drawing-to-import-page-setups-from = Sayfa ayarlarının içe aktarılacağı çizimi seçin
|
||||
.drawings-and-templates = Çizimler ve şablonlar
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN: __ocs_fmt_0__ sayfa ayarı içe aktarıldı, __ocs_fmt_1__ değiştirildi.
|
||||
.psetupin-error = PSETUPIN: __ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN: __ocs_fmt_1__ içinde "__ocs_fmt_0__" adlı sayfa ayarı yok.
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN: __ocs_fmt_0__ içinden içe aktarılacak bir şey yok.
|
||||
.no-named-page-setups-in-this-drawing = Bu çizimde adlandırılmış sayfa ayarı yok.
|
||||
.import-ellipsis = İçe aktar…
|
||||
.show-the-page-setup-for-new-layouts = Yeni yerleşimler için sayfa ayarını göster
|
||||
.x-in = X (inç)
|
||||
.y-in = Y (inç)
|
||||
.hide-paperspace-objects = Kağıt alanı nesnelerini gizle
|
||||
|
||||
@@ -5082,6 +5082,15 @@ plot =
|
||||
.system-default-printer = 系统默认打印机
|
||||
.what-to-plot = 打印内容
|
||||
.x-mm = X (毫米)
|
||||
.select-drawing-to-import-page-setups-from = 选择要从中输入页面设置的图形
|
||||
.drawings-and-templates = 图形和样板
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN:已输入 __ocs_fmt_0__ 个页面设置,替换 __ocs_fmt_1__ 个。
|
||||
.psetupin-error = PSETUPIN:__ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN:__ocs_fmt_1__ 中没有名为“__ocs_fmt_0__”的页面设置。
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN:__ocs_fmt_0__ 中没有可输入的内容。
|
||||
.no-named-page-setups-in-this-drawing = 此图形中没有命名页面设置。
|
||||
.import-ellipsis = 输入…
|
||||
.show-the-page-setup-for-new-layouts = 为新布局显示页面设置
|
||||
.x-in = X(英寸)
|
||||
.y-in = Y(英寸)
|
||||
.hide-paperspace-objects = 隐藏图纸空间对象
|
||||
|
||||
@@ -5094,6 +5094,15 @@ plot =
|
||||
.system-default-printer = 系統預設印表機
|
||||
.what-to-plot = 列印內容
|
||||
.x-mm = X (毫米)
|
||||
.select-drawing-to-import-page-setups-from = 選擇要從中匯入頁面設定的圖面
|
||||
.drawings-and-templates = 圖面與樣板
|
||||
.psetupin-count-page-setup-s-imported-replaced-replaced = PSETUPIN:已匯入 __ocs_fmt_0__ 個頁面設定,取代 __ocs_fmt_1__ 個。
|
||||
.psetupin-error = PSETUPIN:__ocs_fmt_0__
|
||||
.psetupin-no-page-setup-named-want-in-file = PSETUPIN:__ocs_fmt_1__ 中沒有名為「__ocs_fmt_0__」的頁面設定。
|
||||
.psetupin-nothing-to-import-from-file = PSETUPIN:__ocs_fmt_0__ 中沒有可匯入的內容。
|
||||
.no-named-page-setups-in-this-drawing = 此圖面中沒有具名的頁面設定。
|
||||
.import-ellipsis = 匯入…
|
||||
.show-the-page-setup-for-new-layouts = 為新配置顯示頁面設定
|
||||
.x-in = X(英吋)
|
||||
.y-in = Y(英吋)
|
||||
.hide-paperspace-objects = 隱藏圖紙空間物件
|
||||
|
||||
@@ -567,6 +567,8 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"BACKGROUNDPLOT",
|
||||
"CTAB",
|
||||
"TILEMODE",
|
||||
"PSETUPIN",
|
||||
"-PSETUPIN",
|
||||
"DISPSILH",
|
||||
"WORLDVIEW",
|
||||
"LIMCHECK",
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
//! Plot system variables. `PLOTOFFSET`, `PAPERUPDATE`, `PLOTROTMODE`,
|
||||
//! `PLOTTRANSPARENCYOVERRIDE` and `BACKGROUNDPLOT` are plot preferences of
|
||||
//! the application, kept with the Plot dialog's persisted settings; `CTAB`
|
||||
//! and `TILEMODE` say which layout of the drawing is current. Each is
|
||||
//! typeable on its own (`PLOTOFFSET 1`, `CTAB Layout1`) and through
|
||||
//! `SETVAR`, and a bare name prompts for the value like the other variables.
|
||||
//! Plot system variables and the page-setup import command. `PLOTOFFSET`,
|
||||
//! `PAPERUPDATE`, `PLOTROTMODE`, `PLOTTRANSPARENCYOVERRIDE` and
|
||||
//! `BACKGROUNDPLOT` are plot preferences of the application, kept with the
|
||||
//! Plot dialog's persisted settings; `CTAB` and `TILEMODE` say which layout
|
||||
//! of the drawing is current. Each is typeable on its own (`PLOTOFFSET 1`,
|
||||
//! `CTAB Layout1`) and through `SETVAR`, and a bare name prompts for the
|
||||
//! value like the other variables. `PSETUPIN` brings named page setups in
|
||||
//! from another drawing (see `app::update::page_setup_import`).
|
||||
|
||||
use crate::app::{Message, OpenCADStudio};
|
||||
use iced::Task;
|
||||
@@ -39,6 +41,16 @@ enum Outcome {
|
||||
|
||||
impl OpenCADStudio {
|
||||
pub(super) fn dispatch_plotvars(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
||||
// PSETUPIN [file [* | name,name…]] — the dash form is the same
|
||||
// command; both read the file and report on the command line.
|
||||
for name in ["PSETUPIN", "-PSETUPIN"] {
|
||||
if cmd == name {
|
||||
return Some(self.on_psetupin(""));
|
||||
}
|
||||
if let Some(args) = cmd.strip_prefix(name).filter(|rest| rest.starts_with(' ')) {
|
||||
return Some(self.on_psetupin(args));
|
||||
}
|
||||
}
|
||||
let rest = cmd.strip_prefix("SETVAR ").map(str::trim).unwrap_or(cmd);
|
||||
let mut parts = rest.splitn(2, char::is_whitespace);
|
||||
let name = parts.next().unwrap_or("").to_ascii_uppercase();
|
||||
|
||||
@@ -2168,6 +2168,10 @@ pub enum Message {
|
||||
SaveTimeChanged(i32),
|
||||
/// Toggle keeping a `.bak` copy when overwriting a drawing (ISAVEBAK).
|
||||
BackupOnSaveChanged(bool),
|
||||
/// A drawing was picked to import page setups from (`PSETUPIN`).
|
||||
PageSetupImportFile(std::path::PathBuf),
|
||||
/// Options: open the Plot / Page Setup dialog for every new layout.
|
||||
PageSetupOnNewLayoutChanged(bool),
|
||||
/// Toggle filled TrueType glyphs (TEXTFILL).
|
||||
TextFillChanged(bool),
|
||||
/// Change how many prompt lines sit above the command window (CLIPROMPTLINES).
|
||||
|
||||
@@ -4421,6 +4421,7 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
M::PrinterProperties => self.on_printer_properties(),
|
||||
M::Import(msg) => self.on_page_setup_import(msg),
|
||||
M::PrinterOptionsLoaded(printer, result) => {
|
||||
if let Some(draft) = self.plot_dialog.printer_editor.as_mut() {
|
||||
if draft.printer == printer {
|
||||
@@ -4814,7 +4815,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
fn refresh_page_setups(&mut self) {
|
||||
pub(super) fn refresh_page_setups(&mut self) {
|
||||
use crate::ui::window::plot::{SETUP_NONE, SETUP_PREV};
|
||||
let scene = &self.tabs[self.active_tab].scene;
|
||||
// <none> / <previous>, then layouts (`*name*`), then named setups.
|
||||
@@ -4827,7 +4828,7 @@ impl OpenCADStudio {
|
||||
/// Apply a page-setup list selection to the editor. Handles the pseudo
|
||||
/// entries (`<none>` / `<previous>`), layout rows (`*name*`) and named
|
||||
/// setups.
|
||||
fn select_page_setup(&mut self, name: &str) {
|
||||
pub(super) fn select_page_setup(&mut self, name: &str) {
|
||||
use crate::ui::window::plot::{SETUP_NONE, SETUP_PREV};
|
||||
self.plot_dialog.selected_setup = name.to_string();
|
||||
if name == SETUP_NONE {
|
||||
|
||||
@@ -94,6 +94,7 @@ mod context_menu;
|
||||
mod dialog;
|
||||
mod dynamic;
|
||||
mod file;
|
||||
mod page_setup_import;
|
||||
mod style;
|
||||
mod util;
|
||||
mod viewport;
|
||||
@@ -7237,6 +7238,12 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PageSetupImportFile(path) => self.on_page_setup_import_file(path),
|
||||
Message::PageSetupOnNewLayoutChanged(enabled) => {
|
||||
self.plot_dialog.page_setup_on_new_layout = enabled;
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
Message::BackupOnSaveChanged(enabled) => {
|
||||
self.backup_on_save = enabled;
|
||||
self.persist_settings_if_changed();
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
//! Importing named page setups from another drawing (`PSETUPIN`): the
|
||||
//! "Import…" chooser of the Plot dialog and the command that drives the same
|
||||
//! path from the command line.
|
||||
|
||||
use crate::app::{Message, OpenCADStudio};
|
||||
use crate::ui::window::plot::{PageSetupImportDraft, PageSetupImportMsg, PlotDlgMsg};
|
||||
use iced::Task;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Read the named page setups of the drawing at `path` off the UI thread.
|
||||
/// The result names the file the way the chooser shows it.
|
||||
fn read_page_setups_task(path: PathBuf) -> Task<Message> {
|
||||
super::file::background_task(
|
||||
move || {
|
||||
let file = path
|
||||
.file_name()
|
||||
.map(|name| name.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| path.display().to_string());
|
||||
crate::io::load_file(&path)
|
||||
.map(|document| (file, crate::scene::document_page_setups(&document)))
|
||||
},
|
||||
|result| Message::PlotDlg(PlotDlgMsg::Import(PageSetupImportMsg::Loaded(result))),
|
||||
)
|
||||
}
|
||||
|
||||
impl OpenCADStudio {
|
||||
pub(super) fn on_page_setup_import(&mut self, msg: PageSetupImportMsg) -> Task<Message> {
|
||||
match msg {
|
||||
PageSetupImportMsg::Pick => Task::perform(
|
||||
async {
|
||||
let handle = rfd::AsyncFileDialog::new()
|
||||
.set_title(crate::t!("Select Drawing to Import Page Setups From").as_ref())
|
||||
.add_filter(
|
||||
crate::t!("Drawings and templates").as_ref(),
|
||||
&["dwg", "dxf", "dwt", "DWG", "DXF", "DWT"],
|
||||
)
|
||||
.pick_file()
|
||||
.await;
|
||||
handle.map(|h| crate::sys::handle_path(&h))
|
||||
},
|
||||
|picked| match picked {
|
||||
Some(path) => Message::PageSetupImportFile(path),
|
||||
None => Message::Noop,
|
||||
},
|
||||
),
|
||||
PageSetupImportMsg::Loaded(result) => {
|
||||
self.plot_dialog.import_draft = Some(match result {
|
||||
Ok((file, setups)) => PageSetupImportDraft {
|
||||
file,
|
||||
setups: setups.into_iter().map(|(name, ps)| (name, ps, true)).collect(),
|
||||
error: None,
|
||||
},
|
||||
Err(error) => PageSetupImportDraft {
|
||||
file: String::new(),
|
||||
setups: Vec::new(),
|
||||
error: Some(error),
|
||||
},
|
||||
});
|
||||
Task::none()
|
||||
}
|
||||
PageSetupImportMsg::Toggle(name) => {
|
||||
if let Some(draft) = self.plot_dialog.import_draft.as_mut() {
|
||||
if let Some(entry) = draft.setups.iter_mut().find(|(n, _, _)| *n == name) {
|
||||
entry.2 = !entry.2;
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
PageSetupImportMsg::All(on) => {
|
||||
if let Some(draft) = self.plot_dialog.import_draft.as_mut() {
|
||||
for entry in &mut draft.setups {
|
||||
entry.2 = on;
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
PageSetupImportMsg::Apply => {
|
||||
let Some(draft) = self.plot_dialog.import_draft.take() else {
|
||||
return Task::none();
|
||||
};
|
||||
let chosen: Vec<(String, acadrust::objects::PlotSettings)> = draft
|
||||
.selected()
|
||||
.map(|(name, ps)| (name.to_string(), ps.clone()))
|
||||
.collect();
|
||||
let imported = self.import_page_setups(chosen);
|
||||
if let Some(first) = imported.first() {
|
||||
let first = first.clone();
|
||||
self.select_page_setup(&first);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
PageSetupImportMsg::Cancel => {
|
||||
self.plot_dialog.import_draft = None;
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A drawing was picked for import: read it in the background; the
|
||||
/// chooser appears in the Plot dialog once it is read.
|
||||
pub(super) fn on_page_setup_import_file(&mut self, path: PathBuf) -> Task<Message> {
|
||||
// The chooser lives in the Plot dialog; open it if the import was
|
||||
// started from the command line.
|
||||
let open = if self.active_modal == Some(crate::app::ModalKind::Plot) {
|
||||
Task::none()
|
||||
} else {
|
||||
self.on_plot_dialog_open()
|
||||
};
|
||||
Task::batch([open, read_page_setups_task(path)])
|
||||
}
|
||||
|
||||
/// Bring the given setups into the drawing, replacing same-named ones,
|
||||
/// as one undoable step. Returns the names imported.
|
||||
pub(super) fn import_page_setups(
|
||||
&mut self,
|
||||
setups: Vec<(String, acadrust::objects::PlotSettings)>,
|
||||
) -> Vec<String> {
|
||||
if setups.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
let i = self.active_tab;
|
||||
self.push_undo_snapshot(i, "PSETUPIN");
|
||||
let mut replaced = 0usize;
|
||||
let existing = self.tabs[i].scene.page_setup_names();
|
||||
let mut names = Vec::with_capacity(setups.len());
|
||||
for (name, ps) in setups {
|
||||
if existing.iter().any(|n| n.eq_ignore_ascii_case(&name)) {
|
||||
replaced += 1;
|
||||
}
|
||||
self.tabs[i].scene.import_page_setup(&name, ps);
|
||||
names.push(name);
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_page_setups();
|
||||
let count = names.len();
|
||||
self.command_line.push_output(
|
||||
crate::tf!("PSETUPIN: {count} page setup(s) imported, {replaced} replaced.").as_ref(),
|
||||
);
|
||||
names
|
||||
}
|
||||
|
||||
/// `PSETUPIN` / `-PSETUPIN`: with no file, ask for one and offer its
|
||||
/// setups in the Plot dialog; with `<file> *` or `<file> name,name`
|
||||
/// import those straight away; with just `<file>` open the chooser on it.
|
||||
pub(in crate::app) fn on_psetupin(&mut self, args: &str) -> Task<Message> {
|
||||
let args = args.trim();
|
||||
if args.is_empty() {
|
||||
return self.on_page_setup_import(PageSetupImportMsg::Pick);
|
||||
}
|
||||
// The file may carry spaces; the setup list, when given, is the last
|
||||
// word (`*` or a comma-separated list without spaces), so the
|
||||
// arguments are a file followed by names only when what precedes the
|
||||
// last word is itself a file.
|
||||
let (file, names) = match args.rsplit_once(char::is_whitespace) {
|
||||
Some((file, names)) if Path::new(file.trim()).is_file() => {
|
||||
(file.trim(), Some(names.trim()))
|
||||
}
|
||||
_ => (args, None),
|
||||
};
|
||||
let path = PathBuf::from(file);
|
||||
let Some(names) = names else {
|
||||
return self.on_page_setup_import_file(path);
|
||||
};
|
||||
let available = match crate::io::load_file(&path) {
|
||||
Ok(document) => crate::scene::document_page_setups(&document),
|
||||
Err(error) => {
|
||||
self.command_line
|
||||
.push_error(crate::tf!("PSETUPIN: {error}").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
let chosen: Vec<(String, acadrust::objects::PlotSettings)> = if names == "*" {
|
||||
available
|
||||
} else {
|
||||
let wanted: Vec<&str> = names.split(',').map(str::trim).collect();
|
||||
let mut chosen = Vec::new();
|
||||
for want in wanted {
|
||||
match available.iter().find(|(n, _)| n.eq_ignore_ascii_case(want)) {
|
||||
Some(found) => chosen.push(found.clone()),
|
||||
None => self.command_line.push_error(
|
||||
crate::tf!("PSETUPIN: no page setup named \"{want}\" in {file}.")
|
||||
.as_ref(),
|
||||
),
|
||||
}
|
||||
}
|
||||
chosen
|
||||
};
|
||||
if chosen.is_empty() {
|
||||
self.command_line
|
||||
.push_info(crate::tf!("PSETUPIN: nothing to import from {file}.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
self.import_page_setups(chosen);
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, not(target_arch = "wasm32")))]
|
||||
mod tests {
|
||||
use crate::app::{Message, OpenCADStudio};
|
||||
use crate::ui::window::plot::{PageSetupImportMsg as I, PlotDlgMsg};
|
||||
|
||||
const FIXTURE: &str = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/tests/fixtures/plot/page-setups-metric.dxf"
|
||||
);
|
||||
|
||||
fn app() -> OpenCADStudio {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
let _ = app.update(Message::LayoutSwitch("Layout1".into()));
|
||||
app
|
||||
}
|
||||
|
||||
fn last_line(app: &OpenCADStudio) -> String {
|
||||
app.command_line.history.last().map(|line| line.text.clone()).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// The fixture's page setups as the chooser would hold them, read
|
||||
/// through the same document reader the command uses.
|
||||
fn fixture_setups() -> Vec<(String, acadrust::objects::PlotSettings)> {
|
||||
let document = crate::io::load_file(std::path::Path::new(FIXTURE)).unwrap();
|
||||
crate::scene::document_page_setups(&document)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_fixture_reader_lists_its_named_page_setups() {
|
||||
// The fixture carries its page setups on the layouts, not as named
|
||||
// setups; a drawing with named ones lists them in dictionary order.
|
||||
assert!(fixture_setups().is_empty());
|
||||
let mut app = app();
|
||||
let i = app.active_tab;
|
||||
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
|
||||
app.tabs[i].scene.page_setup_save("Site", ps.clone());
|
||||
app.tabs[i].scene.page_setup_save("Detail", ps);
|
||||
let names: Vec<String> = crate::scene::document_page_setups(&app.tabs[i].scene.document)
|
||||
.into_iter()
|
||||
.map(|(name, _)| name)
|
||||
.collect();
|
||||
assert_eq!(names, ["Site", "Detail"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn psetupin_imports_named_setups_from_a_saved_drawing() {
|
||||
use acadrust::objects::PlotRotation;
|
||||
// Author a source drawing with two named setups and save it.
|
||||
let dir = std::env::temp_dir().join(format!("ocs-psetupin-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let source = dir.join("source.dxf");
|
||||
{
|
||||
let mut app = app();
|
||||
let i = app.active_tab;
|
||||
let mut ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
|
||||
ps.printer_name = "DWG To PDF.pc3".into();
|
||||
ps.paper_size = "ISO_A3_(297.00_x_420.00_MM)".into();
|
||||
ps.paper_width = 297.0;
|
||||
ps.paper_height = 420.0;
|
||||
ps.rotation = PlotRotation::Degrees90;
|
||||
ps.plot_view_handle = acadrust::Handle::new(0xBEEF);
|
||||
app.tabs[i].scene.page_setup_save("Site", ps.clone());
|
||||
ps.paper_size = "ISO_A2_(420.00_x_594.00_MM)".into();
|
||||
app.tabs[i].scene.page_setup_save("Overview", ps);
|
||||
let save = format!(r#"{{"op":"save","path":"{}"}}"#, source.display());
|
||||
let reply = app.automation_op(&save);
|
||||
assert_eq!(reply["ok"], true, "{reply}");
|
||||
}
|
||||
let mut app = app();
|
||||
let i = app.active_tab;
|
||||
// One named setup already exists under a name the file also has.
|
||||
let own = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
|
||||
app.tabs[i].scene.page_setup_save("Site", own);
|
||||
// `*` imports everything, replacing the same-named one.
|
||||
let _ = app.run_command_line(&format!("PSETUPIN {} *", source.display()));
|
||||
// The report is translated on localized systems; the counts are not.
|
||||
let report = last_line(&app);
|
||||
assert!(report.starts_with("PSETUPIN"), "{report}");
|
||||
assert!(report.contains('2') && report.contains('1'), "{report}");
|
||||
let names = app.tabs[i].scene.page_setup_names();
|
||||
assert_eq!(names, ["Site", "Overview"]);
|
||||
let site = app.tabs[i].scene.page_setup_get("Site").unwrap();
|
||||
assert_eq!(site.paper_size, "ISO_A3_(297.00_x_420.00_MM)");
|
||||
assert_eq!(site.rotation, PlotRotation::Degrees90);
|
||||
assert!(site.plot_view_handle.is_null(), "foreign handles are dropped");
|
||||
assert!(app.tabs[i].dirty);
|
||||
// Undo takes the whole import back.
|
||||
let _ = app.update(Message::Undo);
|
||||
let names = app.tabs[i].scene.page_setup_names();
|
||||
assert_eq!(names, ["Site"]);
|
||||
assert_ne!(
|
||||
app.tabs[i].scene.page_setup_get("Site").unwrap().paper_size,
|
||||
"ISO_A3_(297.00_x_420.00_MM)"
|
||||
);
|
||||
// A name list imports just those and reports the unknown ones.
|
||||
let _ = app.run_command_line(&format!("PSETUPIN {} Overview,Nothing", source.display()));
|
||||
assert_eq!(app.tabs[i].scene.page_setup_names(), ["Site", "Overview"]);
|
||||
// A missing file is an error, not a crash.
|
||||
let _ = app.run_command_line("PSETUPIN /nowhere/at/all.dwg *");
|
||||
assert!(last_line(&app).starts_with("PSETUPIN:"));
|
||||
std::fs::remove_dir_all(&dir).ok();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_chooser_imports_the_ticked_setups_and_selects_the_first() {
|
||||
let mut app = app();
|
||||
let i = app.active_tab;
|
||||
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
|
||||
let _ = app.on_plot_dialog_open();
|
||||
let setups = ["A", "B", "C"]
|
||||
.into_iter()
|
||||
.map(|name| (name.to_string(), ps.clone()))
|
||||
.collect();
|
||||
let loaded = Ok(("other.dwg".to_string(), setups));
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Loaded(loaded)));
|
||||
let draft = app.plot_dialog.import_draft.as_ref().expect("chooser open");
|
||||
assert_eq!(draft.file, "other.dwg");
|
||||
assert_eq!(draft.selected().count(), 3, "everything ticked to start with");
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::All(false)));
|
||||
assert_eq!(app.plot_dialog.import_draft.as_ref().unwrap().selected().count(), 0);
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Toggle("B".into())));
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Toggle("C".into())));
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Apply));
|
||||
assert!(app.plot_dialog.import_draft.is_none(), "Apply closes the chooser");
|
||||
assert_eq!(app.tabs[i].scene.page_setup_names(), ["B", "C"]);
|
||||
assert_eq!(app.plot_dialog.selected_setup, "B");
|
||||
assert!(app.plot_dialog.page_setups.iter().any(|name| name == "C"));
|
||||
// A failed read shows its reason in the chooser; Cancel closes it.
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Loaded(Err("unreadable".into()))));
|
||||
assert_eq!(
|
||||
app.plot_dialog.import_draft.as_ref().unwrap().error.as_deref(),
|
||||
Some("unreadable")
|
||||
);
|
||||
let _ = app.on_plot_dlg(PlotDlgMsg::Import(I::Cancel));
|
||||
assert!(app.plot_dialog.import_draft.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_new_layout_opens_its_page_setup_when_the_option_is_on() {
|
||||
let mut app = app();
|
||||
let _ = app.update(Message::LayoutCreate);
|
||||
assert_ne!(app.active_modal, Some(crate::app::ModalKind::Plot));
|
||||
let _ = app.update(Message::PageSetupOnNewLayoutChanged(true));
|
||||
assert!(app.current_config().plot.page_setup_on_new_layout, "persisted");
|
||||
let _ = app.update(Message::LayoutCreate);
|
||||
assert_eq!(app.active_modal, Some(crate::app::ModalKind::Plot));
|
||||
assert_eq!(app.plot_dialog.selected_setup, "*Layout3*");
|
||||
}
|
||||
}
|
||||
@@ -6047,6 +6047,12 @@ properties={:.1}ms picked={}",
|
||||
crate::tf!("Layout \"{new_name}\" created — use MVIEW to add a viewport")
|
||||
.as_ref(),
|
||||
);
|
||||
// The option that greets every new layout with its page setup.
|
||||
let switch_task = if self.plot_dialog.page_setup_on_new_layout {
|
||||
Task::batch([switch_task, self.on_plot_dialog_open()])
|
||||
} else {
|
||||
switch_task
|
||||
};
|
||||
self.tabs[i].dirty = true;
|
||||
return Task::batch([cancel_task, switch_task]);
|
||||
}
|
||||
|
||||
@@ -288,6 +288,7 @@ impl OpenCADStudio {
|
||||
crate::ui::window::options::AppPrefs {
|
||||
savetime_min: self.savetime_min,
|
||||
backup_on_save: self.backup_on_save,
|
||||
page_setup_on_new_layout: self.plot_dialog.page_setup_on_new_layout,
|
||||
textfill: crate::scene::text::sdf_atlas::textfill(),
|
||||
cliprompt_lines: self.cliprompt_lines,
|
||||
commandline_fade_ms: self.commandline_fade_ms,
|
||||
|
||||
@@ -3144,6 +3144,15 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"World" => Some(("common", "world")),
|
||||
"Write Block" => Some(("insert", "write-block")),
|
||||
"X (mm)" => Some(("plot", "x-mm")),
|
||||
"Select Drawing to Import Page Setups From" => Some(("plot", "select-drawing-to-import-page-setups-from")),
|
||||
"Drawings and templates" => Some(("plot", "drawings-and-templates")),
|
||||
"PSETUPIN: {count} page setup(s) imported, {replaced} replaced." => Some(("plot", "psetupin-count-page-setup-s-imported-replaced-replaced")),
|
||||
"PSETUPIN: {error}" => Some(("plot", "psetupin-error")),
|
||||
"PSETUPIN: no page setup named \"{want}\" in {file}." => Some(("plot", "psetupin-no-page-setup-named-want-in-file")),
|
||||
"PSETUPIN: nothing to import from {file}." => Some(("plot", "psetupin-nothing-to-import-from-file")),
|
||||
"No named page setups in this drawing." => Some(("plot", "no-named-page-setups-in-this-drawing")),
|
||||
"Import…" => Some(("plot", "import-ellipsis")),
|
||||
"Show the page setup for new layouts" => Some(("plot", "show-the-page-setup-for-new-layouts")),
|
||||
"X (in)" => Some(("plot", "x-in")),
|
||||
"Y (in)" => Some(("plot", "y-in")),
|
||||
"Hide paperspace objects" => Some(("plot", "hide-paperspace-objects")),
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ pub(crate) mod centermark;
|
||||
pub(crate) mod dimension_assoc;
|
||||
pub(crate) mod dimension_assoc_chain;
|
||||
pub use dimension_assoc::{ReferenceStatus, ResolvedReference};
|
||||
pub use page_setup::{apply_default_page_setup, rotated_margins};
|
||||
pub use page_setup::{apply_default_page_setup, document_page_setups, rotated_margins};
|
||||
mod dwg_native_constraints;
|
||||
mod entity;
|
||||
#[cfg(test)]
|
||||
|
||||
+60
-24
@@ -6,7 +6,7 @@
|
||||
|
||||
use super::Scene;
|
||||
use acadrust::objects::{Dictionary, Layout, ObjectType, PlotSettings};
|
||||
use acadrust::Handle;
|
||||
use acadrust::{CadDocument, Handle};
|
||||
|
||||
/// Give a freshly created paper layout the page setup a new drawing starts
|
||||
/// with — ISO A4 landscape on no plotter, plotted 1:1 as a layout — stored the
|
||||
@@ -59,30 +59,59 @@ pub fn rotated_margins(
|
||||
}
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
/// Handle of the `ACAD_PLOTSETTINGS` dictionary, located robustly.
|
||||
///
|
||||
/// The canonical path is the header's `acad_plotsettings_dict_handle`, but
|
||||
/// DWGs written by other programs don't always leave that pointer resolvable
|
||||
/// (the header handle points at no loaded dictionary — see
|
||||
/// [`crate::scene::annotative::root_named_dict_handle`]). In that case fall
|
||||
/// back to the dictionary that owns the drawing's `PlotSettings` objects,
|
||||
/// mirroring [`Scene::scalelist_dict_handle`]. Returns `None` when the
|
||||
/// drawing genuinely has no named page setups.
|
||||
fn plotsettings_dict_handle(&self) -> Option<Handle> {
|
||||
let dh = self.document.header.acad_plotsettings_dict_handle;
|
||||
if matches!(self.document.objects.get(&dh), Some(ObjectType::Dictionary(_))) {
|
||||
return Some(dh);
|
||||
}
|
||||
let owner = self.document.objects.values().find_map(|o| match o {
|
||||
ObjectType::PlotSettings(ps) => Some(ps.owner),
|
||||
/// Handle of a document's `ACAD_PLOTSETTINGS` dictionary, located robustly.
|
||||
///
|
||||
/// The canonical path is the header's `acad_plotsettings_dict_handle`, but
|
||||
/// DWGs written by other programs don't always leave that pointer resolvable
|
||||
/// (the header handle points at no loaded dictionary — see
|
||||
/// [`crate::scene::annotative::root_named_dict_handle`]). In that case fall
|
||||
/// back to the dictionary that owns the drawing's `PlotSettings` objects,
|
||||
/// mirroring [`Scene::scalelist_dict_handle`]. Returns `None` when the
|
||||
/// drawing genuinely has no named page setups.
|
||||
fn plotsettings_dict_handle_in(document: &CadDocument) -> Option<Handle> {
|
||||
let dh = document.header.acad_plotsettings_dict_handle;
|
||||
if matches!(document.objects.get(&dh), Some(ObjectType::Dictionary(_))) {
|
||||
return Some(dh);
|
||||
}
|
||||
let owner = document.objects.values().find_map(|o| match o {
|
||||
ObjectType::PlotSettings(ps) => Some(ps.owner),
|
||||
_ => None,
|
||||
})?;
|
||||
matches!(document.objects.get(&owner), Some(ObjectType::Dictionary(_))).then_some(owner)
|
||||
}
|
||||
|
||||
/// The named page setups of any document — `(name, settings)` in dictionary
|
||||
/// order. Reads a drawing that is not open in the editor (the source of a
|
||||
/// `PSETUPIN` import) the same way the editor reads its own.
|
||||
pub fn document_page_setups(document: &CadDocument) -> Vec<(String, PlotSettings)> {
|
||||
let Some(dh) = plotsettings_dict_handle_in(document) else {
|
||||
return Vec::new();
|
||||
};
|
||||
let Some(ObjectType::Dictionary(dict)) = document.objects.get(&dh) else {
|
||||
return Vec::new();
|
||||
};
|
||||
dict.entries
|
||||
.iter()
|
||||
.filter_map(|(name, handle)| match document.objects.get(handle) {
|
||||
Some(ObjectType::PlotSettings(ps)) => Some((name.clone(), ps.clone())),
|
||||
_ => None,
|
||||
})?;
|
||||
matches!(
|
||||
self.document.objects.get(&owner),
|
||||
Some(ObjectType::Dictionary(_))
|
||||
)
|
||||
.then_some(owner)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A page setup copied out of another drawing, made safe for this one: the
|
||||
/// handles it pointed at (a plot view, a visual style) meant something only
|
||||
/// in its source, so they are dropped while the names, which travel, stay.
|
||||
pub fn detach_page_setup(ps: &mut PlotSettings) {
|
||||
ps.plot_view_handle = Handle::NULL;
|
||||
ps.visual_style_handle = Handle::NULL;
|
||||
ps.reactors.clear();
|
||||
ps.xdictionary_handle = None;
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
fn plotsettings_dict_handle(&self) -> Option<Handle> {
|
||||
plotsettings_dict_handle_in(&self.document)
|
||||
}
|
||||
|
||||
/// Names of the document's named page setups, in dictionary order.
|
||||
@@ -93,6 +122,13 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
/// Bring a page setup from another drawing in under `name`, replacing
|
||||
/// one of that name the way `PSETUPIN` redefines it.
|
||||
pub fn import_page_setup(&mut self, name: &str, mut ps: PlotSettings) {
|
||||
detach_page_setup(&mut ps);
|
||||
self.page_setup_save(name, ps);
|
||||
}
|
||||
|
||||
/// Clone the named page setup's `PlotSettings`, or `None` if absent.
|
||||
pub fn page_setup_get(&self, name: &str) -> Option<PlotSettings> {
|
||||
let dh = self.plotsettings_dict_handle()?;
|
||||
|
||||
+25
-14
@@ -77,6 +77,8 @@ pub struct AppPrefs {
|
||||
pub right_click_mode: RightClickMode,
|
||||
/// SHORTCUTMENUDURATION: time-sensitive hold threshold, ms.
|
||||
pub right_click_hold_ms: i32,
|
||||
/// Open the Plot / Page Setup dialog for every new layout.
|
||||
pub page_setup_on_new_layout: bool,
|
||||
}
|
||||
|
||||
/// The fixed locations the Files page lists.
|
||||
@@ -323,6 +325,29 @@ pub fn view_window<'a>(
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
Space::new().height(22),
|
||||
text(crate::t!("Plotting")).size(15),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
text(crate::t!("Plot device, paper, scale and plot styles"))
|
||||
.size(12)
|
||||
.width(Fill),
|
||||
button(text(crate::t!("Plot and Page Setup…")).size(11))
|
||||
.on_press(Message::PlotDialogOpen)
|
||||
.padding([4, 10])
|
||||
.style(button::secondary),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
iced::widget::checkbox(prefs.page_setup_on_new_layout)
|
||||
.on_toggle(Message::PageSetupOnNewLayoutChanged)
|
||||
.size(15),
|
||||
text(crate::t!("Show the page setup for new layouts")).size(12),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
]
|
||||
.spacing(0)
|
||||
.width(sizing.width);
|
||||
@@ -418,20 +443,6 @@ pub fn view_window<'a>(
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
Space::new().height(22),
|
||||
text(crate::t!("Plotting")).size(15),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
text(crate::t!("Plot device, paper, scale and plot styles"))
|
||||
.size(12)
|
||||
.width(Fill),
|
||||
button(text(crate::t!("Plot and Page Setup…")).size(11))
|
||||
.on_press(Message::PlotDialogOpen)
|
||||
.padding([4, 10])
|
||||
.style(button::secondary),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
]
|
||||
.spacing(0)
|
||||
.width(sizing.width);
|
||||
|
||||
@@ -150,6 +150,43 @@ pub enum PlotFlag {
|
||||
SaveToLayout,
|
||||
}
|
||||
|
||||
/// The page setups of another drawing, offered for import (`PSETUPIN`).
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct PageSetupImportDraft {
|
||||
/// The drawing they come from, as shown to the user.
|
||||
pub file: String,
|
||||
/// Each setup with whether it is ticked for import. The settings are
|
||||
/// carried along so the source file is read once.
|
||||
pub setups: Vec<(String, acadrust::objects::PlotSettings, bool)>,
|
||||
/// Why the file gave nothing, when it did not.
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl PageSetupImportDraft {
|
||||
pub fn selected(&self) -> impl Iterator<Item = (&str, &acadrust::objects::PlotSettings)> {
|
||||
self.setups
|
||||
.iter()
|
||||
.filter(|(_, _, on)| *on)
|
||||
.map(|(name, ps, _)| (name.as_str(), ps))
|
||||
}
|
||||
}
|
||||
|
||||
/// Edits of the page-setup import chooser.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PageSetupImportMsg {
|
||||
/// Ask for the drawing to import from.
|
||||
Pick,
|
||||
/// The drawing was read (or could not be): its name and page setups.
|
||||
Loaded(Result<(String, Vec<(String, acadrust::objects::PlotSettings)>), String>),
|
||||
/// Tick or untick one setup.
|
||||
Toggle(String),
|
||||
/// Tick or untick every setup.
|
||||
All(bool),
|
||||
/// Import the ticked setups and close the chooser.
|
||||
Apply,
|
||||
Cancel,
|
||||
}
|
||||
|
||||
/// Every edit the Plot dialog can emit. Wrapped in `Message::PlotDlg` so the
|
||||
/// top-level match stays a single arm.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -208,6 +245,8 @@ pub enum PlotDlgMsg {
|
||||
CopySetup,
|
||||
/// Begin an inline rename of the given page setup row.
|
||||
RenameStart(String),
|
||||
/// Import named page setups from another drawing (`PSETUPIN`).
|
||||
Import(PageSetupImportMsg),
|
||||
/// Delete the selected named page setup.
|
||||
DeleteSetup,
|
||||
/// Live edit of the new/rename name field.
|
||||
@@ -396,6 +435,12 @@ pub struct PlotDialogState {
|
||||
/// The in-line printer-properties editor while it is open.
|
||||
#[serde(skip)]
|
||||
pub printer_editor: Option<PrinterOptionsDraft>,
|
||||
/// The page-setup import chooser while it is open.
|
||||
#[serde(skip)]
|
||||
pub import_draft: Option<PageSetupImportDraft>,
|
||||
/// Open the Plot / Page Setup dialog whenever a new layout is created,
|
||||
/// the way a page-setup manager is expected to greet a new layout.
|
||||
pub page_setup_on_new_layout: bool,
|
||||
/// Chosen printer name, or `None` for the system default.
|
||||
pub printer: Option<String>,
|
||||
/// Output goes to a PDF file instead of a printer.
|
||||
@@ -501,6 +546,8 @@ impl Default for PlotDialogState {
|
||||
custom_editor: None,
|
||||
driver_options: std::collections::BTreeMap::new(),
|
||||
printer_editor: None,
|
||||
import_draft: None,
|
||||
page_setup_on_new_layout: false,
|
||||
printer: None,
|
||||
to_file: false,
|
||||
paper: paper_catalog::default_paper().canonical.to_string(),
|
||||
@@ -727,6 +774,58 @@ fn check_enabled<'a>(
|
||||
.into()
|
||||
}
|
||||
|
||||
/// The import chooser: the source drawing's name, one tick per page setup,
|
||||
/// All / None, and Import / Cancel.
|
||||
fn page_setup_import_chooser<'a>(
|
||||
draft: &'a PageSetupImportDraft,
|
||||
height: Length,
|
||||
) -> Element<'a, Message> {
|
||||
let msg = |m: PageSetupImportMsg| Message::PlotDlg(PlotDlgMsg::Import(m));
|
||||
let mut rows = column![].spacing(3);
|
||||
if let Some(error) = &draft.error {
|
||||
rows = rows.push(text(error.clone()).size(10).style(muted_style));
|
||||
} else if draft.setups.is_empty() {
|
||||
let none = text(t!("No named page setups in this drawing.")).size(10);
|
||||
rows = rows.push(none.style(muted_style));
|
||||
}
|
||||
for (name, _, on) in &draft.setups {
|
||||
let name = name.clone();
|
||||
rows = rows.push(
|
||||
checkbox(*on)
|
||||
.label(name.clone())
|
||||
.on_toggle(move |_| msg(PageSetupImportMsg::Toggle(name.clone())))
|
||||
.size(13)
|
||||
.text_size(11),
|
||||
);
|
||||
}
|
||||
let all = !draft.setups.is_empty() && draft.setups.iter().all(|(_, _, on)| *on);
|
||||
let any = draft.setups.iter().any(|(_, _, on)| *on);
|
||||
let mut import = button(text(t!("Import")).size(11)).style(btn(true)).padding([4, 8]);
|
||||
if any {
|
||||
import = import.on_press(msg(PageSetupImportMsg::Apply));
|
||||
}
|
||||
column![
|
||||
text(draft.file.clone()).size(10).style(muted_style),
|
||||
scrollable(rows).height(height),
|
||||
checkbox(all)
|
||||
.label(t!("All"))
|
||||
.on_toggle(move |on| msg(PageSetupImportMsg::All(on)))
|
||||
.size(13)
|
||||
.text_size(11),
|
||||
row![
|
||||
import,
|
||||
button(text(t!("Cancel")).size(11))
|
||||
.on_press(msg(PageSetupImportMsg::Cancel))
|
||||
.style(btn(false))
|
||||
.padding([4, 8]),
|
||||
]
|
||||
.spacing(4),
|
||||
]
|
||||
.spacing(6)
|
||||
.padding(4)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// The custom-scale row: `Custom: [paper] mm = [drawing] units`. Editing
|
||||
/// either side replaces the picked scale with the typed ratio.
|
||||
fn custom_scale_row<'a>(s: &'a PlotDialogState, enabled: bool) -> Element<'a, Message> {
|
||||
@@ -1018,6 +1117,12 @@ pub fn view_window(
|
||||
} else {
|
||||
Space::new().height(0).into()
|
||||
};
|
||||
// While an import is being chosen, the list shows the other drawing's
|
||||
// setups with a tick each instead of this drawing's.
|
||||
let list_body: Element<'_, Message> = match &s.import_draft {
|
||||
Some(draft) => page_setup_import_chooser(draft, height),
|
||||
None => list_body,
|
||||
};
|
||||
let list_panel = container(
|
||||
column![
|
||||
text(t!("Page setups")).size(10).style(muted_style),
|
||||
@@ -1069,10 +1174,18 @@ pub fn view_window(
|
||||
if is_named && !print_all_options {
|
||||
delete_button = delete_button.on_press(Message::PlotDlg(PlotDlgMsg::DeleteSetup));
|
||||
}
|
||||
let mut import_button = button(text(t!("Import…")).size(11))
|
||||
.style(btn(false))
|
||||
.padding([4, 12]);
|
||||
if !print_all_options && s.import_draft.is_none() {
|
||||
import_button = import_button
|
||||
.on_press(Message::PlotDlg(PlotDlgMsg::Import(PageSetupImportMsg::Pick)));
|
||||
}
|
||||
let left_bar = row![
|
||||
new_button,
|
||||
copy_button,
|
||||
delete_button,
|
||||
import_button,
|
||||
]
|
||||
.spacing(4);
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Open CAD Studio pid=842697 path=/home/panos/OpenCADStudio/tests/fixtures/plot/page-setups-metric.dxf
|
||||
Open CAD Studio pid=854778 path=/home/panos/OpenCADStudio/tests/fixtures/plot/page-setups-metric.dxf
|
||||
Reference in new issue
Block a user