forked from 1b-agent/opencadstudio-upstream
fix: open-issue sweep — drawing, plot, snap, layout and UI fixes
Fixes: - Font prompt no longer lists bundled ltypeshp/qcadshp shape files (#1626) - Wide polylines step at a discontinuous segment width; PEDIT marks the current vertex; keyword steps refresh the command preview (#1628) - Radius-0 fillet drops the zero-length segment it left, so the corner fillets again (#1422) - FILLET Trim / No trim option (#1558) - True-colour wires plot in their own colour; colour picker stores the value it shows (#1621) - Model tab keeps its page setup; "Save changes to layout" in Model (#1620) - QNEW default template in Options > Files; .dwt in the open dialog (#1134, #1113) - GRIDUNIT / GRIDMODE / PERSPECTIVE variables (#1618, #1524) - PTYPE (#1433) - ZOOM nX / nXP (#1465) - CHSPACE between model and paper space through a viewport (#1428) - Moving a dimension keeps its automatic text placement - Shell icon; "&&" button labels (#1554) - LINETYPE Load from a .lin file (#1588) - XLINE / RAY hide the crosshair arms (#1437) - Dynamic-input boxes keep clear of the crosshair and each other (#1546) - Snap marker colour setting, dark default on light canvases (#1497, #1229, #1128) - Dimension style precision as a 0.00 pattern dropdown (#1426) - Node graph nodes left of the origin no longer clip away (#1592) - Collapse button in the command history header (#1094) - Freeze-in-current-viewport toggle in the ribbon layer list (#1466) - Geometric Center object snap for closed polylines (#1369) New strings translated in all 21 locales. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
abf302eba5
commit
178c7dff41
70 files changed
+1227
-145
No files matched your search
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64">
|
||||
<rect x="1.5" y="3.5" width="21" height="17" rx="1.5" fill="none" stroke="#8FA3B5" stroke-width="1.6"/>
|
||||
<g stroke="#6DB7ED" stroke-width="1.8" stroke-linecap="round">
|
||||
<line x1="12" y1="6.5" x2="12" y2="17.5"/>
|
||||
<line x1="6.5" y1="12" x2="17.5" y2="12"/>
|
||||
<line x1="8.1" y1="8.1" x2="15.9" y2="15.9"/>
|
||||
<line x1="15.9" y1="8.1" x2="8.1" y2="15.9"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 463 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64">
|
||||
<rect x="1.5" y="3.5" width="21" height="17" rx="1.5" fill="none" stroke="#8FA3B5" stroke-width="1.6"/>
|
||||
<circle cx="12" cy="12" r="2.6" fill="#f0c040" fill-opacity="0.4" stroke="#f0c040" stroke-width="1.6"/>
|
||||
<g stroke="#f0c040" stroke-width="1.6" stroke-linecap="round">
|
||||
<line x1="12" y1="6.3" x2="12" y2="7.6"/>
|
||||
<line x1="12" y1="16.4" x2="12" y2="17.7"/>
|
||||
<line x1="6.3" y1="12" x2="7.6" y2="12"/>
|
||||
<line x1="16.4" y1="12" x2="17.7" y2="12"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 563 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="Shell">
|
||||
<g stroke="#526B80" stroke-width="1.1" stroke-linejoin="round">
|
||||
<path d="M8.5 10 15 6.6V14L8.5 17.4Z" fill="#526B80"/>
|
||||
<path d="M15 6.6 23.5 10V17.4L15 14Z" fill="#3F5466"/>
|
||||
<path d="M8.5 17.4 15 14 23.5 17.4 17 20.8Z" fill="#6DB7ED"/>
|
||||
<path d="M4 10 17 16V28L4 22Z" fill="#A9BFCE"/>
|
||||
<path d="M17 16 28 10V22L17 28Z" fill="#718C9E"/>
|
||||
<path d="M4 10 15 4 28 10 17 16ZM8.5 10 15 6.6 23.5 10 17 13.4Z" fill="#DCE7F0" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 567 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#B4B6B9" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5 20.5 9.7 17.3 19.5H6.7L3.5 9.7Z"/><circle cx="12" cy="12.5" r="1.6" fill="#B4B6B9"/></svg>
|
||||
|
After Width: | Height: | Size: 263 B |
@@ -1531,10 +1531,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = هل تريد بالتأكيد إعادة الضبط؟ ستفقد جميع اختصاراتك الحالية!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = الاختصار مستخدم بالفعل للأمر: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = ستُتجاهل التغييرات غير المحفوظة.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = التحكم عبر MCP متوقف
|
||||
.mcp-is-handling-a-request = يعالج MCP طلبًا
|
||||
@@ -2333,6 +2333,21 @@ common =
|
||||
.wblock-err-no-path = يرجى تحديد اسم الملف والمسار.
|
||||
.wblock-err-current-drawing = لا يمكن الكتابة إلى ملف الرسم الحالي.
|
||||
.wblock-help-info = يقوم WBLOCK بكتابة كائنات أو كتلة أو الرسم بالكامل إلى ملف رسم جديد.
|
||||
.blank-drawing = رسم فارغ
|
||||
.default-template-new-drawings = القالب الافتراضي للرسومات الجديدة
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = ملفات أنواع الخطوط
|
||||
.load-linetypes = تحميل أنواع الخطوط
|
||||
.requires-two-positive-values = يتطلب قيمتين موجبتين (x,y) أو قيمة واحدة لكليهما.
|
||||
.snap-marker-color = لون علامة الالتقاط
|
||||
.linetypes-loaded = تم تحميل __ocs_fmt_0__ من أنواع الخطوط.
|
||||
.geometric-center-snap = المركز الهندسي
|
||||
.no-trim-option = بدون تشذيب
|
||||
.chspace-model-tab = CHSPACE: الأمر غير مسموح به في علامة تبويب النموذج.
|
||||
.chspace-no-viewport = CHSPACE: لا توجد نافذة عرض مسقطية لتغيير الفضاء من خلالها.
|
||||
.chspace-to-paper = CHSPACE: تم نقل __ocs_fmt_0__ كائن إلى فضاء الورق.
|
||||
.chspace-to-model = CHSPACE: تم نقل __ocs_fmt_0__ كائن إلى فضاء النموذج.
|
||||
errors =
|
||||
.save-warning = تحذير الحفظ
|
||||
.unable-to-save-drawing = تعذر حفظ الرسم
|
||||
@@ -5502,7 +5517,7 @@ styles =
|
||||
.isavebak-set-to-1 = عُيّن ISAVEBAK إلى 1
|
||||
.keep-with-dim-line = إبقاء مع خط البُعد
|
||||
.layers = الطبقات
|
||||
.linetype-list-set = LINETYPE [قائمة / تعيين]:
|
||||
.linetype-list-set = LINETYPE [قائمة / تعيين / تحميل]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET اسم نوع الخط (حسب الطبقة / حسب الكتلة / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: لم يُحمّل "__ocs_fmt_0__". استخدم LINETYPE LIST لرؤية أنواع الخطوط المتاحة.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE مقياس نوع الخط العام الجديد:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Сигурни ли сте, че искате нулиране? Ще загубите всички текущи преки пътища!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Прекият път вече се използва за команда: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Незаписаните промени ще бъдат отхвърлени.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Управлението чрез MCP е изключено
|
||||
.mcp-is-handling-a-request = MCP обработва заявка
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Моля, задайте име и път на файла.
|
||||
.wblock-err-current-drawing = Не може да се записва в текущия файл с чертеж.
|
||||
.wblock-help-info = WBLOCK записва обекти, блок или целия чертеж в нов чертожен файл.
|
||||
.blank-drawing = Празен чертеж
|
||||
.default-template-new-drawings = Шаблон по подразбиране за нови чертежи
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Файлове с типове линии
|
||||
.load-linetypes = Зареждане на типове линии
|
||||
.requires-two-positive-values = Изискват се две положителни стойности (x,y) или една за двете.
|
||||
.snap-marker-color = Цвят на маркера за прихващане
|
||||
.linetypes-loaded = Заредени типове линии: __ocs_fmt_0__.
|
||||
.geometric-center-snap = Геометричен център
|
||||
.no-trim-option = Без подрязване
|
||||
.chspace-model-tab = CHSPACE: Командата не е разрешена в раздела Модел.
|
||||
.chspace-no-viewport = CHSPACE: Няма прозорец в план, през който да се смени пространството.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ обекта преместени в пространството на листа.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ обекта преместени в пространството на модела.
|
||||
errors =
|
||||
.save-warning = Предупреждение при запазване
|
||||
.unable-to-save-drawing = Чертежът не може да бъде запазен
|
||||
@@ -5490,7 +5505,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK зададен на 1
|
||||
.keep-with-dim-line = Пази с линията за оразм.
|
||||
.layers = СЛоеве
|
||||
.linetype-list-set = LINETYPE [Списък / Задай]:
|
||||
.linetype-list-set = LINETYPE [Списък / Задай / Зареждане]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET име на тип линия (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" не е зареден. Използвай LINETYPE LIST, за да видиш наличните типове линии.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE нов глобален мащаб на тип линия:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Opravdu chcete obnovit výchozí nastavení? Ztratíte všechny aktuální zkratky!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Zkratka je již použita pro příkaz: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Neuložené změny budou zahozeny.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Ovládání MCP je vypnuté
|
||||
.mcp-is-handling-a-request = MCP zpracovává požadavek
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Zadejte název souboru a cestu.
|
||||
.wblock-err-current-drawing = Nelze zapisovat do aktuálního souboru výkresu.
|
||||
.wblock-help-info = WBLOCK zapíše objekty, blok nebo celý výkres do nového výkresového souboru.
|
||||
.blank-drawing = Prázdný výkres
|
||||
.default-template-new-drawings = Výchozí šablona pro nové výkresy
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Soubory typů čar
|
||||
.load-linetypes = Načíst typy čar
|
||||
.requires-two-positive-values = Vyžaduje dvě kladné hodnoty (x,y) nebo jednu pro obě.
|
||||
.snap-marker-color = Barva značky uchopení
|
||||
.linetypes-loaded = Načteno typů čar: __ocs_fmt_0__.
|
||||
.geometric-center-snap = Geometrický střed
|
||||
.no-trim-option = Neoříznout
|
||||
.chspace-model-tab = CHSPACE: Příkaz není povolen na kartě Model.
|
||||
.chspace-no-viewport = CHSPACE: Není výřez v půdorysném pohledu, přes který změnit prostor.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ objektů přesunuto do výkresového prostoru.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ objektů přesunuto do modelového prostoru.
|
||||
errors =
|
||||
.save-warning = Uložit varování
|
||||
.unable-to-save-drawing = Nákres nelze uložit
|
||||
@@ -5487,7 +5502,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK nastaven na 1
|
||||
.keep-with-dim-line = Držte se tlumené linie
|
||||
.layers = Vrstvy
|
||||
.linetype-list-set = LINETYPE [Seznam / sada]:
|
||||
.linetype-list-set = LINETYPE [Seznam / sada / Načíst]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET název typu čáry (podle hladiny / podle bloku / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" není načteno. Pomocí LINETYPE LIST zobrazíte dostupné typy čar.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nové globální měřítko typu čáry:
|
||||
|
||||
@@ -1519,10 +1519,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Wirklich zurücksetzen? Alle aktuellen Tastenkürzel gehen verloren!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Tastenkürzel bereits für Befehl verwendet: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Nicht gespeicherte Änderungen werden verworfen.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP-Steuerung ausgeschaltet
|
||||
.mcp-is-handling-a-request = MCP verarbeitet eine Anfrage
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Bitte geben Sie einen Dateinamen und Pfad an.
|
||||
.wblock-err-current-drawing = In die aktuelle Zeichnungsdatei kann nicht geschrieben werden.
|
||||
.wblock-help-info = WBLOCK schreibt Objekte, einen Block oder die gesamte Zeichnung in eine neue Zeichnungsdatei.
|
||||
.blank-drawing = Leere Zeichnung
|
||||
.default-template-new-drawings = Standardvorlage für neue Zeichnungen
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Linientypdateien
|
||||
.load-linetypes = Linientypen laden
|
||||
.requires-two-positive-values = Erfordert zwei positive Werte (x,y) oder einen für beide.
|
||||
.snap-marker-color = Farbe der Fangmarkierung
|
||||
.linetypes-loaded = __ocs_fmt_0__ Linientyp(en) geladen.
|
||||
.geometric-center-snap = Geometrischer Mittelpunkt
|
||||
.no-trim-option = Nicht stutzen
|
||||
.chspace-model-tab = CHSPACE: Befehl in der Registerkarte Modell nicht zulässig.
|
||||
.chspace-no-viewport = CHSPACE: Kein Ansichtsfenster in Draufsicht zum Wechseln des Bereichs.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ Objekt(e) in den Papierbereich verschoben.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ Objekt(e) in den Modellbereich verschoben.
|
||||
errors =
|
||||
.save-warning = Warnhinweise speichern
|
||||
.unable-to-save-drawing = Zeichnung konnte nicht gespeichert werden
|
||||
@@ -5488,7 +5503,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK auf 1 gesetzt
|
||||
.keep-with-dim-line = Halten Sie mit Dim Line
|
||||
.layers = SCHIENEN
|
||||
.linetype-list-set = LINETYPE [Liste / Festlegen]:
|
||||
.linetype-list-set = LINETYPE [Liste / Festlegen / Laden]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET Linientypname (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" ist nicht geladen. Mit LINETYPE LIST werden die verfügbaren Linientypen angezeigt.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE Neuer globaler Linientypfaktor:
|
||||
|
||||
@@ -1520,10 +1520,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Σίγουρα θέλετε επαναφορά; Θα χαθούν όλες οι τρέχουσες συντομεύσεις σας!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Η συντόμευση χρησιμοποιείται ήδη για την εντολή: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Οι μη αποθηκευμένες αλλαγές θα απορριφθούν.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Έλεγχος MCP απενεργοποιημένος
|
||||
.mcp-is-handling-a-request = Το MCP επεξεργάζεται ένα αίτημα
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Καθορίστε ένα όνομα και διαδρομή αρχείου.
|
||||
.wblock-err-current-drawing = Δεν είναι δυνατή η εγγραφή στο τρέχον αρχείο σχεδίου.
|
||||
.wblock-help-info = Η εντολή WBLOCK εγγράφει αντικείμενα, ένα μπλοκ ή ολόκληρο το σχέδιο σε ένα νέο αρχείο σχεδίου.
|
||||
.blank-drawing = Κενό σχέδιο
|
||||
.default-template-new-drawings = Προεπιλεγμένο πρότυπο για νέα σχέδια
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Αρχεία τύπων γραμμής
|
||||
.load-linetypes = Φόρτωση τύπων γραμμής
|
||||
.requires-two-positive-values = Απαιτούνται δύο θετικές τιμές (x,y) ή μία και για τις δύο.
|
||||
.snap-marker-color = Χρώμα δείκτη έλξης
|
||||
.linetypes-loaded = Φορτώθηκαν __ocs_fmt_0__ τύποι γραμμής.
|
||||
.geometric-center-snap = Γεωμετρικό κέντρο
|
||||
.no-trim-option = Χωρίς περικοπή
|
||||
.chspace-model-tab = CHSPACE: Η εντολή δεν επιτρέπεται στην καρτέλα Μοντέλο.
|
||||
.chspace-no-viewport = CHSPACE: Δεν υπάρχει παράθυρο προβολής κάτοψης για αλλαγή χώρου.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ αντικείμενα μεταφέρθηκαν στον χώρο χαρτιού.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ αντικείμενα μεταφέρθηκαν στον χώρο μοντέλου.
|
||||
errors =
|
||||
.save-warning = Προειδοποίηση αποθήκευσης
|
||||
.unable-to-save-drawing = Αδυναμία αποθήκευσης σχεδίου
|
||||
@@ -5490,7 +5505,7 @@ styles =
|
||||
.isavebak-set-to-1 = Το ISAVEBAK ορίστηκε σε 1
|
||||
.keep-with-dim-line = Διατήρηση με τη γραμμή διάστασης
|
||||
.layers = ΕΠίπεδα
|
||||
.linetype-list-set = LINETYPE [Λίστα / Ορισμός]:
|
||||
.linetype-list-set = LINETYPE [Λίστα / Ορισμός / Φόρτωση]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET όνομα τύπου γραμμής (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: το "__ocs_fmt_0__" δεν έχει φορτωθεί. Χρησιμοποιήστε LINETYPE LIST για να δείτε τους διαθέσιμους τύπους γραμμών.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE νέα καθολική κλίμακα τύπου γραμμής:
|
||||
|
||||
@@ -1520,10 +1520,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Are you sure you want to reset? You will lose all your current shortcuts!
|
||||
.yes-reset = Yes, reset
|
||||
.reset-to-default = Reset to default
|
||||
.apply-exit = Apply && Exit
|
||||
.apply-exit = Apply & Exit
|
||||
.shortcut-already-used-for-command = Shortcut already used for command: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Unsaved changes will be discarded.
|
||||
.discard-close = Discard && close
|
||||
.discard-close = Discard & close
|
||||
.keep-editing = Keep editing
|
||||
.mcp-control-is-off = MCP control is off
|
||||
.mcp-is-handling-a-request = MCP is handling a request
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Please specify a file name and path.
|
||||
.wblock-err-current-drawing = Cannot write to the current drawing file.
|
||||
.wblock-help-info = WBLOCK writes objects, a block, or the entire drawing to a new drawing file.
|
||||
.blank-drawing = Blank drawing
|
||||
.default-template-new-drawings = Default template for new drawings
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Linetype Files
|
||||
.load-linetypes = Load Linetypes
|
||||
.requires-two-positive-values = Requires two positive values (x,y) or one for both.
|
||||
.snap-marker-color = Snap marker color
|
||||
.linetypes-loaded = __ocs_fmt_0__ linetype(s) loaded.
|
||||
.geometric-center-snap = Geometric Center
|
||||
.no-trim-option = No trim
|
||||
.chspace-model-tab = CHSPACE: Command not allowed in the Model tab.
|
||||
.chspace-no-viewport = CHSPACE: No plan-view viewport to change space through.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ object(s) changed to paper space.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ object(s) changed to model space.
|
||||
errors =
|
||||
.save-warning = Save Warning
|
||||
.unable-to-save-drawing = Unable to Save Drawing
|
||||
@@ -5491,7 +5506,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK set to 1
|
||||
.keep-with-dim-line = Keep with dim line
|
||||
.layers = LAyers
|
||||
.linetype-list-set = LINETYPE [List / Set]:
|
||||
.linetype-list-set = LINETYPE [List / Set / Load]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET linetype name (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" is not loaded. Use LINETYPE LIST to see available linetypes.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE new global line-type scale:
|
||||
|
||||
@@ -1519,10 +1519,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = ¿Seguro que desea restablecer? ¡Perderá todos sus atajos actuales!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Atajo ya usado para el comando: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Se descartarán los cambios sin guardar.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Control MCP desactivado
|
||||
.mcp-is-handling-a-request = MCP está procesando una solicitud
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Especifique un nombre de archivo y una ruta.
|
||||
.wblock-err-current-drawing = No se puede escribir en el archivo de dibujo actual.
|
||||
.wblock-help-info = WBLOCK escribe objetos, un bloque o el dibujo completo en un nuevo archivo de dibujo.
|
||||
.blank-drawing = Dibujo en blanco
|
||||
.default-template-new-drawings = Plantilla predeterminada para dibujos nuevos
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Archivos de tipos de línea
|
||||
.load-linetypes = Cargar tipos de línea
|
||||
.requires-two-positive-values = Requiere dos valores positivos (x,y) o uno para ambos.
|
||||
.snap-marker-color = Color del marcador de referencia
|
||||
.linetypes-loaded = __ocs_fmt_0__ tipo(s) de línea cargado(s).
|
||||
.geometric-center-snap = Centro geométrico
|
||||
.no-trim-option = No recortar
|
||||
.chspace-model-tab = CHSPACE: Comando no permitido en la ficha Modelo.
|
||||
.chspace-no-viewport = CHSPACE: No hay ventana gráfica en vista en planta para cambiar de espacio.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ objeto(s) pasado(s) al espacio papel.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ objeto(s) pasado(s) al espacio modelo.
|
||||
errors =
|
||||
.save-warning = Advertencia de guardado
|
||||
.unable-to-save-drawing = No se puede guardar el dibujo
|
||||
@@ -5490,7 +5505,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK definido como 1
|
||||
.keep-with-dim-line = Mantener con línea de cota
|
||||
.layers = Capas
|
||||
.linetype-list-set = LINETYPE [Listar/Definir]:
|
||||
.linetype-list-set = LINETYPE [Listar/Definir / Cargar]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET Nombre del tipo de línea (PorCapa/PorBloque/…):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: «__ocs_fmt_0__» no está cargado. Use LINETYPE LIST para ver los tipos disponibles.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE Nueva escala global de tipo de línea:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Haluatko varmasti palauttaa oletukset? Kaikki nykyiset pikanäppäimet menetetään!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Pikanäppäin on jo käytössä komennolla: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Tallentamattomat muutokset hylätään.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP-ohjaus pois käytöstä
|
||||
.mcp-is-handling-a-request = MCP käsittelee pyyntöä
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Määritä tiedoston nimi ja polku.
|
||||
.wblock-err-current-drawing = Nykyiseen piirustustiedostoon ei voi kirjoittaa.
|
||||
.wblock-help-info = WBLOCK kirjoittaa kohteet, lohkon tai koko piirustuksen uuteen piirustustiedostoon.
|
||||
.blank-drawing = Tyhjä piirustus
|
||||
.default-template-new-drawings = Uusien piirustusten oletusmalli
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Viivatyyppitiedostot
|
||||
.load-linetypes = Lataa viivatyypit
|
||||
.requires-two-positive-values = Vaatii kaksi positiivista arvoa (x,y) tai yhden molemmille.
|
||||
.snap-marker-color = Kohdistusmerkin väri
|
||||
.linetypes-loaded = Ladattu __ocs_fmt_0__ viivatyyppiä.
|
||||
.geometric-center-snap = Geometrinen keskipiste
|
||||
.no-trim-option = Ei trimmausta
|
||||
.chspace-model-tab = CHSPACE: Komento ei ole sallittu Malli-välilehdellä.
|
||||
.chspace-no-viewport = CHSPACE: Ei tasokuvan näkymäikkunaa tilan vaihtoon.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ objektia siirretty paperitilaan.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ objektia siirretty mallitilaan.
|
||||
errors =
|
||||
.save-warning = Tallenna varoitus
|
||||
.unable-to-save-drawing = Piirustusta ei voi tallentaa
|
||||
@@ -5489,7 +5504,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK asetettu arvoon 1
|
||||
.keep-with-dim-line = Pysy himmeällä viivalla
|
||||
.layers = Kerrokset
|
||||
.linetype-list-set = LINETYPE [Lista / sarja]:
|
||||
.linetype-list-set = LINETYPE [Lista / sarja / Lataa]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET viivatyypin nimi (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" ei ole ladattu. Käytä LINETYPE LIST nähdäksesi käytettävissä olevat linjatyypit.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE uusi globaali viivatyyppinen asteikko:
|
||||
|
||||
@@ -1519,10 +1519,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Voulez-vous vraiment réinitialiser ? Tous vos raccourcis actuels seront perdus !
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Raccourci déjà utilisé pour la commande : __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Les modifications non enregistrées seront perdues.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Contrôle MCP désactivé
|
||||
.mcp-is-handling-a-request = MCP traite une requête
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Veuillez spécifier un nom de fichier et un chemin d'accès.
|
||||
.wblock-err-current-drawing = Impossible d'écrire dans le fichier de dessin actuel.
|
||||
.wblock-help-info = WBLOCK écrit des objets, un bloc ou l'ensemble du dessin dans un nouveau fichier de dessin.
|
||||
.blank-drawing = Dessin vierge
|
||||
.default-template-new-drawings = Gabarit par défaut des nouveaux dessins
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Fichiers de types de ligne
|
||||
.load-linetypes = Charger des types de ligne
|
||||
.requires-two-positive-values = Nécessite deux valeurs positives (x,y) ou une seule pour les deux.
|
||||
.snap-marker-color = Couleur du marqueur d'accrochage
|
||||
.linetypes-loaded = __ocs_fmt_0__ type(s) de ligne chargé(s).
|
||||
.geometric-center-snap = Centre géométrique
|
||||
.no-trim-option = Sans ajuster
|
||||
.chspace-model-tab = CHSPACE : commande non autorisée dans l'onglet Objet.
|
||||
.chspace-no-viewport = CHSPACE : aucune fenêtre en vue en plan pour changer d'espace.
|
||||
.chspace-to-paper = CHSPACE : __ocs_fmt_0__ objet(s) déplacé(s) dans l'espace papier.
|
||||
.chspace-to-model = CHSPACE : __ocs_fmt_0__ objet(s) déplacé(s) dans l'espace objet.
|
||||
errors =
|
||||
.save-warning = Enregistrer l' avertissement
|
||||
.unable-to-save-drawing = Impossible de sauvegarder le dessin
|
||||
@@ -5490,7 +5505,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK réglé à 1
|
||||
.keep-with-dim-line = Gardez avec la ligne dim
|
||||
.layers = Autres
|
||||
.linetype-list-set = LINETYPE [Liste / Définir] :
|
||||
.linetype-list-set = LINETYPE [Liste / Définir / Charger] :
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET nom de type de ligne (ByLayer / ByBlock / ...):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" n'est pas chargé. Utilisez LINETYPE LIST pour voir les types de lignes disponibles.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nouvelle échelle de type ligne mondiale:
|
||||
|
||||
@@ -1507,10 +1507,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = क्या आप वाकई रीसेट करना चाहते हैं? आपके सभी वर्तमान शॉर्टकट खो जाएँगे!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = शॉर्टकट पहले से इस कमांड के लिए उपयोग में है: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = बिना सहेजे बदलाव हटा दिए जाएँगे।
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP नियंत्रण बंद है
|
||||
.mcp-is-handling-a-request = MCP अनुरोध संसाधित कर रहा है
|
||||
@@ -2309,6 +2309,21 @@ common =
|
||||
.wblock-err-no-path = कृपया फ़ाइल का नाम और पथ निर्दिष्ट करें।
|
||||
.wblock-err-current-drawing = वर्तमान आरेखण फ़ाइल में नहीं लिखा जा सकता।
|
||||
.wblock-help-info = WBLOCK ऑब्जेक्ट, एक ब्लॉक, या संपूर्ण रेखाचित्र को एक नई रेखाचित्र फ़ाइल में लिखता है।
|
||||
.blank-drawing = रिक्त ड्रॉइंग
|
||||
.default-template-new-drawings = नई ड्रॉइंग के लिए डिफ़ॉल्ट टेम्पलेट
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = लाइनटाइप फ़ाइलें
|
||||
.load-linetypes = लाइनटाइप लोड करें
|
||||
.requires-two-positive-values = दो धनात्मक मान (x,y) या दोनों के लिए एक मान आवश्यक है।
|
||||
.snap-marker-color = स्नैप मार्कर का रंग
|
||||
.linetypes-loaded = __ocs_fmt_0__ लाइनटाइप लोड हुए।
|
||||
.geometric-center-snap = ज्यामितीय केंद्र
|
||||
.no-trim-option = ट्रिम नहीं
|
||||
.chspace-model-tab = CHSPACE: मॉडल टैब में कमांड की अनुमति नहीं है।
|
||||
.chspace-no-viewport = CHSPACE: स्पेस बदलने के लिए कोई प्लान-व्यू व्यूपोर्ट नहीं।
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ ऑब्जेक्ट पेपर स्पेस में बदले गए।
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ ऑब्जेक्ट मॉडल स्पेस में बदले गए।
|
||||
errors =
|
||||
.save-warning = चेतावनी सहेजें
|
||||
.unable-to-save-drawing = ड्रॉइंग सहेजी नहीं जा सकी
|
||||
@@ -5478,7 +5493,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK सेट 1
|
||||
.keep-with-dim-line = डिम लाइन के साथ रखें
|
||||
.layers = लेयर
|
||||
.linetype-list-set = LINETYPE [सूची / सेट]:
|
||||
.linetype-list-set = LINETYPE [सूची / सेट / लोड]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET लाइनटाइप का नाम (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" को लोड नहीं किया गया है। उपलब्ध लाइनटाइप देखने के लिए LINETYPE LIST का प्रयोग करें।
|
||||
.ltscale-new-global-line-type-scale = LTSCALE नई वैश्विक लाइन-प्रकार पैमाने:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Biztosan visszaállítja? Az összes jelenlegi gyorsbillentyű elveszik!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = A gyorsbillentyű már használatban van: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = A nem mentett módosítások elvesznek.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP-vezérlés kikapcsolva
|
||||
.mcp-is-handling-a-request = Az MCP kérést dolgoz fel
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Adja meg a fájlnevet és az elérési utat.
|
||||
.wblock-err-current-drawing = Nem lehet írni az aktuális rajzfájlba.
|
||||
.wblock-help-info = A WBLOCK objektumokat, egy blokkot vagy a teljes rajzot új rajzfájlba menti.
|
||||
.blank-drawing = Üres rajz
|
||||
.default-template-new-drawings = Alapértelmezett sablon új rajzokhoz
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Vonaltípus-fájlok
|
||||
.load-linetypes = Vonaltípusok betöltése
|
||||
.requires-two-positive-values = Két pozitív érték (x,y) vagy egy közös érték szükséges.
|
||||
.snap-marker-color = Illesztési jelölő színe
|
||||
.linetypes-loaded = __ocs_fmt_0__ vonaltípus betöltve.
|
||||
.geometric-center-snap = Geometriai középpont
|
||||
.no-trim-option = Nincs vágás
|
||||
.chspace-model-tab = CHSPACE: A parancs a Modell lapon nem engedélyezett.
|
||||
.chspace-no-viewport = CHSPACE: Nincs felülnézeti nézetablak a tér váltásához.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ objektum papírtérbe helyezve.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ objektum modelltérbe helyezve.
|
||||
errors =
|
||||
.save-warning = Figyelmeztetés mentése
|
||||
.unable-to-save-drawing = Nem sikerült menteni a rajzot
|
||||
@@ -5489,7 +5504,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK 1-re állítva
|
||||
.keep-with-dim-line = Tartsa halvány vonallal
|
||||
.layers = Rétegek
|
||||
.linetype-list-set = LINETYPE [Lista / Készlet]:
|
||||
.linetype-list-set = LINETYPE [Lista / Készlet / Betöltés]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET vonaltípus neve (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: A "__ocs_fmt_0__" nincs betöltve. A rendelkezésre álló vonaltípusok megtekintéséhez használja a LINETYPE LIST parancsot.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE új globális vonal típusú skála:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Vuoi davvero reimpostare? Perderai tutte le scorciatoie attuali!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Scorciatoia già usata per il comando: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Le modifiche non salvate verranno scartate.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Controllo MCP disattivato
|
||||
.mcp-is-handling-a-request = MCP sta elaborando una richiesta
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Specificare un nome file e un percorso.
|
||||
.wblock-err-current-drawing = Impossibile scrivere nel file di disegno corrente.
|
||||
.wblock-help-info = WBLOCK scrive gli oggetti, un blocco o l'intero disegno in un nuovo file di disegno.
|
||||
.blank-drawing = Disegno vuoto
|
||||
.default-template-new-drawings = Modello predefinito per i nuovi disegni
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = File dei tipi di linea
|
||||
.load-linetypes = Carica tipi di linea
|
||||
.requires-two-positive-values = Richiede due valori positivi (x,y) o uno per entrambi.
|
||||
.snap-marker-color = Colore del marcatore di snap
|
||||
.linetypes-loaded = __ocs_fmt_0__ tipo/i di linea caricato/i.
|
||||
.geometric-center-snap = Centro geometrico
|
||||
.no-trim-option = Non tagliare
|
||||
.chspace-model-tab = CHSPACE: comando non consentito nella scheda Modello.
|
||||
.chspace-no-viewport = CHSPACE: nessuna finestra in vista in pianta attraverso cui cambiare spazio.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ oggetto/i spostato/i nello spazio carta.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ oggetto/i spostato/i nello spazio modello.
|
||||
errors =
|
||||
.save-warning = Salva avviso
|
||||
.unable-to-save-drawing = Impossibile salvare il disegno
|
||||
@@ -5489,7 +5504,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK impostato su 1
|
||||
.keep-with-dim-line = Continua con la linea debole
|
||||
.layers = Livelli
|
||||
.linetype-list-set = LINETYPE [Elenco/Imposta]:
|
||||
.linetype-list-set = LINETYPE [Elenco/Imposta / Carica]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET nome del tipo di linea (DaLayer / DaBlocco / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" non è caricato. Utilizza LINETYPE LIST per vedere i tipi di linea disponibili.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nuova scala globale di tipo linea:
|
||||
|
||||
@@ -1509,10 +1509,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = リセットしてもよろしいですか?現在のすべてのショートカットが失われます!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = ショートカットは既に次のコマンドで使用されています: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = 未保存の変更は破棄されます。
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP制御は無効です
|
||||
.mcp-is-handling-a-request = MCPがリクエストを処理中です
|
||||
@@ -2311,6 +2311,21 @@ common =
|
||||
.wblock-err-no-path = ファイル名とパスを指定してください。
|
||||
.wblock-err-current-drawing = 現在の図面ファイルには書き込めません。
|
||||
.wblock-help-info = WBLOCK はオブジェクト、ブロック、または図面全体を新しい図面ファイルに書き出します。
|
||||
.blank-drawing = 空の図面
|
||||
.default-template-new-drawings = 新規図面の既定テンプレート
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = 線種ファイル
|
||||
.load-linetypes = 線種をロード
|
||||
.requires-two-positive-values = 2つの正の値 (x,y)、または両方に共通の1つの値が必要です。
|
||||
.snap-marker-color = スナップ マーカーの色
|
||||
.linetypes-loaded = __ocs_fmt_0__ 個の線種をロードしました。
|
||||
.geometric-center-snap = 図心
|
||||
.no-trim-option = トリムしない
|
||||
.chspace-model-tab = CHSPACE: モデル タブではこのコマンドを使用できません。
|
||||
.chspace-no-viewport = CHSPACE: 空間を変更できる平面ビューのビューポートがありません。
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ 個のオブジェクトをペーパー空間に移動しました。
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ 個のオブジェクトをモデル空間に移動しました。
|
||||
errors =
|
||||
.save-warning = 保存の警告
|
||||
.unable-to-save-drawing = 図面を保存できません
|
||||
@@ -5478,7 +5493,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK を 1 に設定しました
|
||||
.keep-with-dim-line = 寸法線と共に保持
|
||||
.layers = レイヤー
|
||||
.linetype-list-set = LINETYPE [一覧 / 設定]:
|
||||
.linetype-list-set = LINETYPE [一覧 / 設定 / ロード]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET 線種名(レイヤー依存 / ブロック依存 / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" は未読込です。LINETYPE LIST で利用可能な線種を確認してください。
|
||||
.ltscale-new-global-line-type-scale = LTSCALE 新しいグローバル線種尺度:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = 정말 초기화하시겠습니까? 현재 단축키가 모두 삭제됩니다!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = 단축키가 이미 다음 명령에 사용 중입니다: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = 저장하지 않은 변경 사항은 삭제됩니다.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP 제어가 꺼져 있습니다
|
||||
.mcp-is-handling-a-request = MCP가 요청을 처리 중입니다
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = 파일 이름과 경로를 지정하십시오.
|
||||
.wblock-err-current-drawing = 현재 도면 파일에는 쓸 수 없습니다.
|
||||
.wblock-help-info = WBLOCK은 객체, 블록 또는 도면 전체를 새 도면 파일로 내보냅니다.
|
||||
.blank-drawing = 빈 도면
|
||||
.default-template-new-drawings = 새 도면의 기본 템플릿
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = 선종류 파일
|
||||
.load-linetypes = 선종류 로드
|
||||
.requires-two-positive-values = 양수 값 두 개(x,y) 또는 둘 다에 쓸 값 하나가 필요합니다.
|
||||
.snap-marker-color = 스냅 마커 색상
|
||||
.linetypes-loaded = 선종류 __ocs_fmt_0__개를 로드했습니다.
|
||||
.geometric-center-snap = 기하학적 중심
|
||||
.no-trim-option = 자르지 않기
|
||||
.chspace-model-tab = CHSPACE: 모델 탭에서는 명령을 사용할 수 없습니다.
|
||||
.chspace-no-viewport = CHSPACE: 공간을 변경할 평면 뷰포트가 없습니다.
|
||||
.chspace-to-paper = CHSPACE: 객체 __ocs_fmt_0__개를 도면 공간으로 옮겼습니다.
|
||||
.chspace-to-model = CHSPACE: 객체 __ocs_fmt_0__개를 모형 공간으로 옮겼습니다.
|
||||
errors =
|
||||
.save-warning = 경고 저장
|
||||
.unable-to-save-drawing = 도면을 저장할 수 없습니다
|
||||
@@ -5489,7 +5504,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK가 1로 설정됨
|
||||
.keep-with-dim-line = 희미한 선으로 유지
|
||||
.layers = 레이어
|
||||
.linetype-list-set = LINETYPE [목록/설정]:
|
||||
.linetype-list-set = LINETYPE [목록/설정 / 로드]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET 선종류 이름(ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__"가 로드되지 않았습니다. 사용 가능한 선종류를 보려면 LINETYPE LIST를 사용하세요.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE 새로운 글로벌 라인형 스케일:
|
||||
|
||||
@@ -1517,10 +1517,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Weet u zeker dat u wilt herstellen? Al uw huidige sneltoetsen gaan verloren!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Sneltoets al gebruikt voor opdracht: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Niet-opgeslagen wijzigingen worden verworpen.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP-besturing uitgeschakeld
|
||||
.mcp-is-handling-a-request = MCP verwerkt een verzoek
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Geef een bestandsnaam en pad op.
|
||||
.wblock-err-current-drawing = Kan niet schrijven naar het huidige tekeningbestand.
|
||||
.wblock-help-info = WBLOCK schrijft objecten, een blok of de volledige tekening naar een nieuw tekeningbestand.
|
||||
.blank-drawing = Lege tekening
|
||||
.default-template-new-drawings = Standaardsjabloon voor nieuwe tekeningen
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Lijntypebestanden
|
||||
.load-linetypes = Lijntypen laden
|
||||
.requires-two-positive-values = Vereist twee positieve waarden (x,y) of één voor beide.
|
||||
.snap-marker-color = Kleur van snapmarkering
|
||||
.linetypes-loaded = __ocs_fmt_0__ lijntype(n) geladen.
|
||||
.geometric-center-snap = Geometrisch middelpunt
|
||||
.no-trim-option = Niet trimmen
|
||||
.chspace-model-tab = CHSPACE: opdracht niet toegestaan op het tabblad Model.
|
||||
.chspace-no-viewport = CHSPACE: geen viewport in bovenaanzicht om de ruimte via te wisselen.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ object(en) naar de papierruimte verplaatst.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ object(en) naar de modelruimte verplaatst.
|
||||
errors =
|
||||
.save-warning = Waarschuwing opslaan
|
||||
.unable-to-save-drawing = Kan tekening niet opslaan
|
||||
@@ -5488,7 +5503,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK ingesteld op 1
|
||||
.keep-with-dim-line = Houden met dim lijn
|
||||
.layers = Lagen
|
||||
.linetype-list-set = LINETYPE [Lijst / Instellen]:
|
||||
.linetype-list-set = LINETYPE [Lijst / Instellen / Laden]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET Lijntypenaam (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" is niet geladen. Gebruik LINETYPE LIST om de beschikbare lijntypen te bekijken.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nieuwe mondiale lijnschaal:
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Na pewno zresetować? Wszystkie bieżące skróty zostaną utracone!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Skrót jest już używany dla polecenia: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Niezapisane zmiany zostaną odrzucone.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Sterowanie MCP wyłączone
|
||||
.mcp-is-handling-a-request = MCP przetwarza żądanie
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = Podaj nazwę pliku i ścieżkę.
|
||||
.wblock-err-current-drawing = Nie można zapisać do bieżącego pliku rysunku.
|
||||
.wblock-help-info = WBLOCK zapisuje obiekty, blok lub cały rysunek do nowego pliku rysunku.
|
||||
.blank-drawing = Pusty rysunek
|
||||
.default-template-new-drawings = Domyślny szablon nowych rysunków
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Pliki rodzajów linii
|
||||
.load-linetypes = Wczytaj rodzaje linii
|
||||
.requires-two-positive-values = Wymaga dwóch wartości dodatnich (x,y) lub jednej dla obu.
|
||||
.snap-marker-color = Kolor znacznika przyciągania
|
||||
.linetypes-loaded = Wczytano rodzaje linii: __ocs_fmt_0__.
|
||||
.geometric-center-snap = Środek geometryczny
|
||||
.no-trim-option = Bez przycinania
|
||||
.chspace-model-tab = CHSPACE: polecenie niedostępne na karcie Model.
|
||||
.chspace-no-viewport = CHSPACE: brak rzutni w widoku z góry do zmiany obszaru.
|
||||
.chspace-to-paper = CHSPACE: przeniesiono obiekty do obszaru papieru: __ocs_fmt_0__.
|
||||
.chspace-to-model = CHSPACE: przeniesiono obiekty do obszaru modelu: __ocs_fmt_0__.
|
||||
errors =
|
||||
.save-warning = Zapisz ostrzeżenie
|
||||
.unable-to-save-drawing = Nie można zapisać rysunku
|
||||
@@ -5489,7 +5504,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK ustawione na 1
|
||||
.keep-with-dim-line = Trzymaj się ciemnej linii
|
||||
.layers = Warstwy
|
||||
.linetype-list-set = LINETYPE [Lista / Zestaw]:
|
||||
.linetype-list-set = LINETYPE [Lista / Zestaw / Wczytaj]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET nazwa rodzaju linii (JakWarstwa / JakBlok / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: „__ocs_fmt_0__” nie jest załadowany. Użyj LINETYPE LIST, aby zobaczyć dostępne rodzaje linii.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nowa globalna skala liniowa:
|
||||
|
||||
@@ -1519,10 +1519,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Deseja mesmo redefinir? Todos os atalhos atuais serão perdidos!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Atalho já usado para o comando: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = As alterações não salvas serão descartadas.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Controle MCP desativado
|
||||
.mcp-is-handling-a-request = MCP está processando uma solicitação
|
||||
@@ -2321,6 +2321,21 @@ common =
|
||||
.wblock-err-no-path = Especifique um nome de arquivo e caminho.
|
||||
.wblock-err-current-drawing = Não é possível gravar no arquivo de desenho atual.
|
||||
.wblock-help-info = O WBLOCK grava objetos, um bloco ou o desenho inteiro em um novo arquivo de desenho.
|
||||
.blank-drawing = Desenho em branco
|
||||
.default-template-new-drawings = Modelo padrão para novos desenhos
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Arquivos de tipos de linha
|
||||
.load-linetypes = Carregar tipos de linha
|
||||
.requires-two-positive-values = Requer dois valores positivos (x,y) ou um para ambos.
|
||||
.snap-marker-color = Cor do marcador de snap
|
||||
.linetypes-loaded = __ocs_fmt_0__ tipo(s) de linha carregado(s).
|
||||
.geometric-center-snap = Centro geométrico
|
||||
.no-trim-option = Não aparar
|
||||
.chspace-model-tab = CHSPACE: comando não permitido na guia Modelo.
|
||||
.chspace-no-viewport = CHSPACE: nenhuma janela de vista em planta para mudar de espaço.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ objeto(s) movido(s) para o espaço do papel.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ objeto(s) movido(s) para o espaço do modelo.
|
||||
errors =
|
||||
.save-warning = Aviso de salvamento
|
||||
.unable-to-save-drawing = Não foi possível salvar o desenho
|
||||
@@ -5490,7 +5505,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK definido como 1
|
||||
.keep-with-dim-line = Manter com a linha de cota
|
||||
.layers = CAmadas
|
||||
.linetype-list-set = LINETYPE [Listar / Definir]:
|
||||
.linetype-list-set = LINETYPE [Listar / Definir / Carregar]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET nome do tipo de linha (PorCamada / PorBloco / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: “__ocs_fmt_0__” não está carregado. Use LINETYPE LIST para ver os tipos disponíveis.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE nova escala global de tipos de linha:
|
||||
|
||||
@@ -1522,10 +1522,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Сбросить настройки? Все текущие сочетания клавиш будут потеряны!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Сочетание уже используется для команды: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Несохранённые изменения будут потеряны.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = Управление MCP выключено
|
||||
.mcp-is-handling-a-request = MCP обрабатывает запрос
|
||||
@@ -2324,6 +2324,21 @@ common =
|
||||
.wblock-err-no-path = Укажите имя файла и путь к нему.
|
||||
.wblock-err-current-drawing = Невозможно записать в текущий файл чертежа.
|
||||
.wblock-help-info = WBLOCK записывает объекты, блок или весь чертеж в новый файл чертежа.
|
||||
.blank-drawing = Пустой чертёж
|
||||
.default-template-new-drawings = Шаблон по умолчанию для новых чертежей
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Файлы типов линий
|
||||
.load-linetypes = Загрузить типы линий
|
||||
.requires-two-positive-values = Требуются два положительных значения (x,y) или одно для обоих.
|
||||
.snap-marker-color = Цвет маркера привязки
|
||||
.linetypes-loaded = Загружено типов линий: __ocs_fmt_0__.
|
||||
.geometric-center-snap = Геометрический центр
|
||||
.no-trim-option = Без обрезки
|
||||
.chspace-model-tab = CHSPACE: команда недоступна на вкладке «Модель».
|
||||
.chspace-no-viewport = CHSPACE: нет видового экрана в плане для смены пространства.
|
||||
.chspace-to-paper = CHSPACE: перенесено в пространство листа объектов: __ocs_fmt_0__.
|
||||
.chspace-to-model = CHSPACE: перенесено в пространство модели объектов: __ocs_fmt_0__.
|
||||
errors =
|
||||
.save-warning = Спасти предостережение
|
||||
.unable-to-save-drawing = Не удалось сохранить чертёж
|
||||
@@ -5491,7 +5506,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK установленный на 1
|
||||
.keep-with-dim-line = Оставлять рядом с размерной линией
|
||||
.layers = Лэйерс
|
||||
.linetype-list-set = LINETYPE [Список / Задать]:
|
||||
.linetype-list-set = LINETYPE [Список / Задать / Загрузить]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET Имя типа линии (ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" не загружен. Используйте LINETYPE LIST для просмотра доступных типов линий.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE Новый глобальный масштаб типов линий:
|
||||
|
||||
@@ -1505,10 +1505,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = Sıfırlamak istediğinizden emin misiniz? Mevcut tüm kısayollarınız silinecek!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = Kısayol zaten şu komut için kullanılıyor: __ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = Kaydedilmemiş değişiklikler atılacak.
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP denetimi kapalı
|
||||
.mcp-is-handling-a-request = MCP bir isteği işliyor
|
||||
@@ -2305,6 +2305,21 @@ common =
|
||||
.wblock-err-no-path = Lütfen bir dosya adı ve yolu belirtin.
|
||||
.wblock-err-current-drawing = Geçerli çizim dosyasına yazılamıyor.
|
||||
.wblock-help-info = WBLOCK nesneleri, bir bloğu veya tüm çizimi yeni bir çizim dosyasına yazar.
|
||||
.blank-drawing = Boş çizim
|
||||
.default-template-new-drawings = Yeni çizimler için varsayılan şablon
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = Çizgi tipi dosyaları
|
||||
.load-linetypes = Çizgi tiplerini yükle
|
||||
.requires-two-positive-values = İki pozitif değer (x,y) ya da ikisi için tek değer gerekir.
|
||||
.snap-marker-color = Yakalama işaretçisi rengi
|
||||
.linetypes-loaded = __ocs_fmt_0__ çizgi tipi yüklendi.
|
||||
.geometric-center-snap = Geometrik merkez
|
||||
.no-trim-option = Budama yok
|
||||
.chspace-model-tab = CHSPACE: Komut Model sekmesinde kullanılamaz.
|
||||
.chspace-no-viewport = CHSPACE: Alan değiştirmek için plan görünümlü görünüm penceresi yok.
|
||||
.chspace-to-paper = CHSPACE: __ocs_fmt_0__ nesne kağıt alanına taşındı.
|
||||
.chspace-to-model = CHSPACE: __ocs_fmt_0__ nesne model alanına taşındı.
|
||||
errors =
|
||||
.save-warning = Kaydetme Uyarısı
|
||||
.unable-to-save-drawing = Çizim Kaydedilemiyor
|
||||
@@ -5430,7 +5445,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK 1 olarak ayarlandı
|
||||
.keep-with-dim-line = Ölçü çizgisiyle birlikte tut
|
||||
.layers = Katmanlar
|
||||
.linetype-list-set = LINETYPE [Listele / Ayarla]:
|
||||
.linetype-list-set = LINETYPE [Listele / Ayarla / Yükle]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET Çizgi tipi adı (Katmandan / Bloktan / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE: "__ocs_fmt_0__" yüklü değil. Kullanılabilir çizgi tipleri için LINETYPE LIST komutunu kullanın.
|
||||
.ltscale-new-global-line-type-scale = LTSCALE Yeni genel çizgi tipi ölçeği:
|
||||
|
||||
@@ -1506,10 +1506,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = 确定要重置吗?所有当前快捷键都将丢失!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = 快捷键已用于命令:__ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = 未保存的更改将被丢弃。
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP 控制已关闭
|
||||
.mcp-is-handling-a-request = MCP 正在处理请求
|
||||
@@ -2308,6 +2308,21 @@ common =
|
||||
.wblock-err-no-path = 请指定文件名和路径。
|
||||
.wblock-err-current-drawing = 无法写入当前图形文件。
|
||||
.wblock-help-info = WBLOCK 将对象、块或整个图形写入新的图形文件。
|
||||
.blank-drawing = 空白图形
|
||||
.default-template-new-drawings = 新图形的默认样板
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = 线型文件
|
||||
.load-linetypes = 加载线型
|
||||
.requires-two-positive-values = 需要两个正值 (x,y),或一个同时用于两者的值。
|
||||
.snap-marker-color = 捕捉标记颜色
|
||||
.linetypes-loaded = 已加载 __ocs_fmt_0__ 个线型。
|
||||
.geometric-center-snap = 几何中心
|
||||
.no-trim-option = 不修剪
|
||||
.chspace-model-tab = CHSPACE: 在“模型”选项卡中不允许使用此命令。
|
||||
.chspace-no-viewport = CHSPACE: 没有可用于更改空间的平面视图视口。
|
||||
.chspace-to-paper = CHSPACE: 已将 __ocs_fmt_0__ 个对象移到图纸空间。
|
||||
.chspace-to-model = CHSPACE: 已将 __ocs_fmt_0__ 个对象移到模型空间。
|
||||
errors =
|
||||
.save-warning = 保存警告
|
||||
.unable-to-save-drawing = 无法保存图形
|
||||
@@ -5473,7 +5488,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK 设置为 1
|
||||
.keep-with-dim-line = 保持暗线
|
||||
.layers = 图层
|
||||
.linetype-list-set = LINETYPE [列表 / 设置]:
|
||||
.linetype-list-set = LINETYPE [列表 / 设置 / 加载]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET 线型名称(ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE:“__ocs_fmt_0__”未加载。使用 LINETYPE LIST 查看可用线型。
|
||||
.ltscale-new-global-line-type-scale = LTSCALE 新的全局线型尺度 :
|
||||
|
||||
@@ -1518,10 +1518,10 @@ common =
|
||||
.are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts = 確定要重設嗎?所有目前快捷鍵都將遺失!
|
||||
.yes-reset = { common.yes }, { common.reset }
|
||||
.reset-to-default = { common.reset } · { common.default-title-case }
|
||||
.apply-exit = { common.apply } && { draw.sketch-exit }
|
||||
.apply-exit = { common.apply } & { draw.sketch-exit }
|
||||
.shortcut-already-used-for-command = 快捷鍵已用於指令:__ocs_fmt_0__ → __ocs_fmt_1__
|
||||
.unsaved-changes-will-be-discarded = 未儲存的變更將被捨棄。
|
||||
.discard-close = { common.discard } && { action.close }
|
||||
.discard-close = { common.discard } & { action.close }
|
||||
.keep-editing = { common.continue } · { layers.edit }
|
||||
.mcp-control-is-off = MCP 控制已關閉
|
||||
.mcp-is-handling-a-request = MCP 正在處理要求
|
||||
@@ -2320,6 +2320,21 @@ common =
|
||||
.wblock-err-no-path = 請指定檔名和路徑。
|
||||
.wblock-err-current-drawing = 無法寫入目前圖面檔案。
|
||||
.wblock-help-info = WBLOCK 將物件、圖塊或整個圖面寫入新的圖面檔案。
|
||||
.blank-drawing = 空白圖面
|
||||
.default-template-new-drawings = 新圖面的預設樣板
|
||||
.fillet-trim-mode-trim = FILLET Enter Trim mode option [Trim/No trim] <Trim>:
|
||||
.fillet-trim-mode-no-trim = FILLET Enter Trim mode option [Trim/No trim] <No trim>:
|
||||
.linetype-files = 線型檔案
|
||||
.load-linetypes = 載入線型
|
||||
.requires-two-positive-values = 需要兩個正值 (x,y),或一個同時用於兩者的值。
|
||||
.snap-marker-color = 鎖點標記顏色
|
||||
.linetypes-loaded = 已載入 __ocs_fmt_0__ 個線型。
|
||||
.geometric-center-snap = 幾何中心
|
||||
.no-trim-option = 不修剪
|
||||
.chspace-model-tab = CHSPACE: 在「模型」頁籤中不允許使用此指令。
|
||||
.chspace-no-viewport = CHSPACE: 沒有可用於變更空間的平面視圖視埠。
|
||||
.chspace-to-paper = CHSPACE: 已將 __ocs_fmt_0__ 個物件移到圖紙空間。
|
||||
.chspace-to-model = CHSPACE: 已將 __ocs_fmt_0__ 個物件移到模型空間。
|
||||
errors =
|
||||
.save-warning = 儲存警告
|
||||
.unable-to-save-drawing = 無法儲存圖形
|
||||
@@ -5485,7 +5500,7 @@ styles =
|
||||
.isavebak-set-to-1 = ISAVEBAK 設定為 1
|
||||
.keep-with-dim-line = 保持暗線
|
||||
.layers = 圖層
|
||||
.linetype-list-set = LINETYPE [清單 / 設定]:
|
||||
.linetype-list-set = LINETYPE [清單 / 設定 / 載入]:
|
||||
.linetype-set-linetype-name-bylayer-byblock = LINETYPE SET 線型名稱(ByLayer / ByBlock / …):
|
||||
.linetype-name-is-not-loaded-use-linetype-list = LINETYPE:“__ocs_fmt_0__”未載入。使用 LINETYPE LIST 查看可用線型。
|
||||
.ltscale-new-global-line-type-scale = LTSCALE 新的全局線型尺度 :
|
||||
|
||||
@@ -677,6 +677,7 @@ impl OpenCADStudio {
|
||||
None
|
||||
};
|
||||
let is_escape = matches!(&input, StepInput::Escape);
|
||||
let keyed = matches!(&input, StepInput::Text(_) | StepInput::Enter);
|
||||
let result: Option<CmdResult> = {
|
||||
let Some(cmd) = self.tabs[i].active_cmd.as_mut() else {
|
||||
return (Task::none(), false);
|
||||
@@ -703,7 +704,15 @@ impl OpenCADStudio {
|
||||
self.tabs[i].pending_pause_tokens = None;
|
||||
}
|
||||
match result {
|
||||
Some(r) => (self.apply_cmd_result(r), true),
|
||||
Some(r) => {
|
||||
let task = self.apply_cmd_result(r);
|
||||
// A keyword can move the step without the cursor moving
|
||||
// (PEDIT Next vertex): redraw its preview now (#1628).
|
||||
if keyed && self.active_tab == i {
|
||||
self.refresh_active_cmd_preview(i);
|
||||
}
|
||||
(task, true)
|
||||
}
|
||||
None => (Task::none(), false),
|
||||
}
|
||||
}
|
||||
|
||||
+20
-4
@@ -911,13 +911,29 @@ impl OpenCADStudio {
|
||||
.or_else(|| cmd.strip_prefix("ZOOM S "))
|
||||
.or_else(|| cmd.strip_prefix("ZS "))
|
||||
.unwrap_or("1");
|
||||
if let Ok(factor) = rest.trim().parse::<f32>() {
|
||||
if factor > 0.0 {
|
||||
self.tabs[i].scene.remember_current_view();
|
||||
self.tabs[i].scene.zoom_camera(1.0 / factor);
|
||||
// nXP scales the active viewport against paper space, nX (or
|
||||
// a bare n) the current view (#1465). n may be an expression
|
||||
// such as 1/50.
|
||||
let rest = rest.trim().to_ascii_uppercase();
|
||||
let (number, xp) = match rest.strip_suffix("XP") {
|
||||
Some(n) => (n, true),
|
||||
None => (rest.strip_suffix('X').unwrap_or(&rest), false),
|
||||
};
|
||||
let factor = crate::app::expr_eval::eval_number(number.trim())
|
||||
.filter(|f| f.is_finite() && *f > 0.0);
|
||||
match factor {
|
||||
Some(factor) if xp && self.tabs[i].scene.set_viewport_scale_factor(factor) => {
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(crate::tf!("Zoom Scale ×{factor:.3}").as_ref());
|
||||
}
|
||||
Some(factor) => {
|
||||
self.tabs[i].scene.remember_current_view();
|
||||
self.tabs[i].scene.zoom_camera(1.0 / factor as f32);
|
||||
self.command_line
|
||||
.push_output(crate::tf!("Zoom Scale ×{factor:.3}").as_ref());
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -634,6 +634,9 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"FITSPLINE",
|
||||
// System variables (typeable directly).
|
||||
"MIRRTEXT",
|
||||
"PERSPECTIVE",
|
||||
"GRIDMODE",
|
||||
"GRIDUNIT",
|
||||
"ZOOMWHEEL",
|
||||
"ZOOMFACTOR",
|
||||
"SHORTCUTMENU",
|
||||
@@ -844,6 +847,7 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"MLSTYLE",
|
||||
"MS",
|
||||
"MSPACE",
|
||||
"CHSPACE",
|
||||
"NAVVCUBE",
|
||||
"NEW",
|
||||
"OBJIMPORT",
|
||||
|
||||
@@ -3,6 +3,65 @@ use super::*;
|
||||
impl OpenCADStudio {
|
||||
pub(super) fn dispatch_styleprops(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
||||
match cmd {
|
||||
// View / grid variables held by the app rather than the header,
|
||||
// typed bare or through SETVAR (#1524, #1618).
|
||||
cmd if matches!(
|
||||
cmd.strip_prefix("SETVAR ").unwrap_or(cmd).split_whitespace().next(),
|
||||
Some("PERSPECTIVE" | "GRIDMODE" | "GRIDUNIT")
|
||||
) =>
|
||||
{
|
||||
let mut words = cmd.strip_prefix("SETVAR ").unwrap_or(cmd).splitn(2, ' ');
|
||||
let name = words.next().unwrap_or_default().to_string();
|
||||
let value = words.next().map(str::trim).filter(|v| !v.is_empty());
|
||||
let current = match name.as_str() {
|
||||
"PERSPECTIVE" => {
|
||||
let persp = self.tabs[i].scene.camera.borrow().projection
|
||||
== crate::scene::Projection::Perspective;
|
||||
(persp as i32).to_string()
|
||||
}
|
||||
"GRIDMODE" => (self.show_grid as i32).to_string(),
|
||||
_ => format!("{},{}", self.grid_spacing_x, self.grid_spacing_y),
|
||||
};
|
||||
let Some(value) = value else {
|
||||
self.command_line
|
||||
.push_output(&crate::tf!("Enter new value for {name} <{current}>:"));
|
||||
self.pending_setvar = Some(name);
|
||||
return Some(Task::none());
|
||||
};
|
||||
match (name.as_str(), value) {
|
||||
("PERSPECTIVE", "0" | "1") => {
|
||||
return Some(Task::done(Message::SetProjection(value == "0")));
|
||||
}
|
||||
("GRIDMODE", "0" | "1") => {
|
||||
if (value == "1") != self.show_grid {
|
||||
return Some(Task::done(Message::ToggleGrid));
|
||||
}
|
||||
}
|
||||
("GRIDUNIT", _) => {
|
||||
let mut parts = value.split(',').map(|p| p.trim().parse::<f32>());
|
||||
let x = parts.next().and_then(Result::ok).filter(|v| *v > 0.0);
|
||||
let y = match parts.next() {
|
||||
Some(p) => p.ok().filter(|v| *v > 0.0),
|
||||
None => x,
|
||||
};
|
||||
let (Some(x), Some(y)) = (x, y) else {
|
||||
self.command_line.push_error(
|
||||
crate::t!("Requires two positive values (x,y) or one for both.")
|
||||
.as_ref(),
|
||||
);
|
||||
return Some(Task::none());
|
||||
};
|
||||
self.grid_spacing_x = x;
|
||||
self.grid_spacing_y = y;
|
||||
self.sync_vport_display(i);
|
||||
self.persist_settings_if_changed();
|
||||
}
|
||||
_ => self
|
||||
.command_line
|
||||
.push_error(crate::t!("Requires 0 or 1").as_ref()),
|
||||
}
|
||||
return Some(Task::none());
|
||||
}
|
||||
"CETRANSPARENCY" => return self.dispatch_styleprops("SETVAR CETRANSPARENCY", i),
|
||||
cmd if cmd.starts_with("CETRANSPARENCY ") => {
|
||||
return self.dispatch_styleprops(&format!("SETVAR {cmd}"), i);
|
||||
@@ -84,9 +143,10 @@ impl OpenCADStudio {
|
||||
use crate::command::KeywordCommand;
|
||||
let c = KeywordCommand::new(
|
||||
"LINETYPE",
|
||||
"LINETYPE [List / Set]:",
|
||||
"LINETYPE [List / Set / Load]:",
|
||||
vec![
|
||||
("List", "LIST", None),
|
||||
("Load", "LOAD", None),
|
||||
("Set", "SET", Some("LINETYPE SET linetype name (ByLayer / ByBlock / …):")),
|
||||
],
|
||||
);
|
||||
@@ -98,6 +158,13 @@ impl OpenCADStudio {
|
||||
let parts: Vec<&str> = raw_rest.split_whitespace().collect();
|
||||
let sub = parts.get(0).map(|s| s.to_uppercase()).unwrap_or_default();
|
||||
match sub.as_str() {
|
||||
// Load the definitions of a `.lin` file (#1588).
|
||||
"LOAD" | "L" => {
|
||||
return Some(Task::perform(
|
||||
crate::io::pick_linetype_file(),
|
||||
Message::LinetypeLoaded,
|
||||
));
|
||||
}
|
||||
"" | "LIST" | "?" => {
|
||||
let ltypes: Vec<String> = self.tabs[i]
|
||||
.scene
|
||||
@@ -3247,7 +3314,7 @@ impl OpenCADStudio {
|
||||
);
|
||||
}
|
||||
}
|
||||
cmd if cmd == "DDPTYPE" => {
|
||||
cmd if cmd == "DDPTYPE" || cmd == "PTYPE" => {
|
||||
// The dialog shows the magnitude; the sign (relative/absolute)
|
||||
// is driven by the radio buttons. A positive PDSIZE is absolute;
|
||||
// zero or negative is relative.
|
||||
|
||||
@@ -548,6 +548,102 @@ impl OpenCADStudio {
|
||||
return Some(Task::done(Message::PspaceCommand));
|
||||
}
|
||||
|
||||
// ── CHSPACE — move objects between model and paper space through
|
||||
// a viewport, keeping their apparent size and place (#1428).
|
||||
// Inside a viewport the selection goes to the sheet; on the
|
||||
// sheet it goes into the model through the viewport under it.
|
||||
"CHSPACE" => {
|
||||
let handles: Vec<codec::Handle> = self.tabs[i]
|
||||
.scene
|
||||
.selected_entities()
|
||||
.into_iter()
|
||||
.map(|(h, _)| h)
|
||||
.collect();
|
||||
if self.tabs[i].scene.current_layout == "Model" {
|
||||
self.command_line
|
||||
.push_error(crate::t!("CHSPACE: Command not allowed in the Model tab.").as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
if handles.is_empty() {
|
||||
use crate::modules::draw::select::SelectObjectsCommand;
|
||||
let cmd = SelectObjectsCommand::new("CHSPACE");
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
return Some(Task::none());
|
||||
}
|
||||
let scene = &self.tabs[i].scene;
|
||||
let to_paper = scene.active_viewport.is_some();
|
||||
let frame = match scene.active_viewport {
|
||||
Some(vp) => scene.viewport_frame(vp),
|
||||
None => {
|
||||
// The viewport under the middle of the selection.
|
||||
let (mut lo, mut hi) = (glam::DVec2::MAX, glam::DVec2::MIN);
|
||||
for wire in scene.wire_models_for(&handles) {
|
||||
let [x0, y0, x1, y1] = wire.aabb.map(f64::from);
|
||||
if [x0, y0, x1, y1].iter().all(|v| v.is_finite()) {
|
||||
lo = lo.min(glam::DVec2::new(x0, y0));
|
||||
hi = hi.max(glam::DVec2::new(x1, y1));
|
||||
}
|
||||
}
|
||||
let mid = (lo + hi) * 0.5;
|
||||
mid.is_finite()
|
||||
.then(|| scene.viewport_frames_at_paper_point(mid.extend(0.0)))
|
||||
.and_then(|frames| frames.into_iter().next())
|
||||
}
|
||||
};
|
||||
let Some(frame) = frame else {
|
||||
self.command_line.push_error(
|
||||
crate::t!("CHSPACE: No plan-view viewport to change space through.").as_ref(),
|
||||
);
|
||||
return Some(Task::none());
|
||||
};
|
||||
use crate::command::EntityTransform as T;
|
||||
let z = glam::DVec3::Z;
|
||||
let steps = if to_paper {
|
||||
[
|
||||
T::Translate((-frame.model_target).extend(0.0)),
|
||||
T::Rotate { center: glam::DVec3::ZERO, axis: z, angle_rad: frame.twist },
|
||||
T::Scale { center: glam::DVec3::ZERO, factor: frame.scale },
|
||||
T::Translate(frame.paper_center.extend(0.0)),
|
||||
]
|
||||
} else {
|
||||
[
|
||||
T::Translate((-frame.paper_center).extend(0.0)),
|
||||
T::Scale { center: glam::DVec3::ZERO, factor: 1.0 / frame.scale },
|
||||
T::Rotate { center: glam::DVec3::ZERO, axis: z, angle_rad: -frame.twist },
|
||||
T::Translate(frame.model_target.extend(0.0)),
|
||||
]
|
||||
};
|
||||
self.push_undo_snapshot(i, "CHSPACE");
|
||||
let scene = &mut self.tabs[i].scene;
|
||||
let entities: Vec<codec::EntityType> = handles
|
||||
.iter()
|
||||
.filter_map(|h| scene.document.get_entity(*h).cloned())
|
||||
.collect();
|
||||
scene.deselect_all();
|
||||
scene.erase_entities(&handles);
|
||||
// The clones land in the other space: the sheet with no active
|
||||
// viewport, the model with one.
|
||||
let active = scene.active_viewport;
|
||||
scene.active_viewport = if to_paper { None } else { Some(frame.viewport) };
|
||||
let moved: Vec<codec::Handle> =
|
||||
entities.into_iter().map(|e| scene.add_entity_clone(e)).collect();
|
||||
scene.active_viewport = active;
|
||||
for step in &steps {
|
||||
scene.transform_entities(&moved, step);
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
let count = moved.len();
|
||||
self.command_line.push_output(
|
||||
if to_paper {
|
||||
crate::tf!("CHSPACE: {count} object(s) changed to paper space.")
|
||||
} else {
|
||||
crate::tf!("CHSPACE: {count} object(s) changed to model space.")
|
||||
}
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
|
||||
// ── Viewport arrangement shortcuts ────────────────────────────
|
||||
// Tile the model viewports into preset splits. Each delegates to the
|
||||
// matching VPORTS configuration so the Model/paper handling stays in
|
||||
|
||||
@@ -88,6 +88,11 @@ impl OpenCADStudio {
|
||||
return;
|
||||
}
|
||||
let active = self.tabs[i].active_layer.clone();
|
||||
let vp_column = self.tabs[i].scene.active_viewport.and_then(|vp| {
|
||||
(self.tabs[i].scene.current_layout != "Model")
|
||||
.then(|| self.tabs[i].layers.vp_cols.iter().position(|c| c.handle == vp))
|
||||
.flatten()
|
||||
});
|
||||
let infos: Vec<crate::ui::ribbon::LayerInfo> = self.tabs[i]
|
||||
.layers
|
||||
.layers
|
||||
@@ -100,6 +105,8 @@ impl OpenCADStudio {
|
||||
visible: l.visible,
|
||||
frozen: l.frozen,
|
||||
locked: l.locked,
|
||||
vp_frozen: vp_column
|
||||
.map(|column| (column, l.vp_frozen.get(column).copied().unwrap_or(false))),
|
||||
})
|
||||
.collect();
|
||||
let names: Vec<String> = infos.iter().map(|l| l.name.clone()).collect();
|
||||
|
||||
@@ -590,6 +590,10 @@ pub(super) struct OpenCADStudio {
|
||||
crosshair_color: Option<[u8; 3]>,
|
||||
/// Editable Options buffer for the crosshair colour.
|
||||
crosshair_color_input: String,
|
||||
/// Explicit object-snap marker colour; `None` keeps the automatic one.
|
||||
snap_marker_color: Option<[u8; 3]>,
|
||||
/// Editable Options buffer for the snap marker colour.
|
||||
snap_marker_color_input: String,
|
||||
/// Defer the ISOLINES mesh rebuild until the slider is released.
|
||||
isolines_awaiting_regen: bool,
|
||||
/// Edit buffer for the SNAPANG field on the Options Drafting page. Kept
|
||||
@@ -1024,6 +1028,8 @@ pub(super) struct OpenCADStudio {
|
||||
check_missing_fonts: bool,
|
||||
/// Custom font source base URL; empty selects the community repository.
|
||||
font_source_url: String,
|
||||
/// Template a new drawing starts from (QNEW); empty = blank.
|
||||
qnew_template: String,
|
||||
/// Editable copy of `font_source_url` shown in the missing-fonts prompt.
|
||||
font_source_input: String,
|
||||
donation_prompt_version: String,
|
||||
@@ -2289,6 +2295,10 @@ pub enum Message {
|
||||
LineweightDisplayScaleChanged(i32),
|
||||
/// Edit the optional crosshair RGB value; blank restores automatic contrast.
|
||||
CrosshairColorChanged(String),
|
||||
SnapMarkerColorChanged(String),
|
||||
/// Options → Files: the default template for new drawings.
|
||||
QnewTemplateChanged(String),
|
||||
QnewTemplateBrowse,
|
||||
/// Set the default type/version used when first saving a new drawing.
|
||||
DefaultSaveFormatChanged(String),
|
||||
/// Select one of Iced's built-in themes or the editable Custom theme.
|
||||
@@ -3678,6 +3688,8 @@ pub enum Message {
|
||||
// ── Plot Style Table ─────────────────────────────────────────────────
|
||||
/// Open file dialog to load a CTB/STB plot style table.
|
||||
PlotStyleLoad,
|
||||
/// LINETYPE Load: the picked `.lin` file's text, `None` when cancelled.
|
||||
LinetypeLoaded(Option<String>),
|
||||
/// Callback when the user picks (or cancels) a CTB/STB file.
|
||||
/// The Load… picker finished: a table, nothing (cancelled), or why the
|
||||
/// file could not be read.
|
||||
@@ -4151,6 +4163,8 @@ impl OpenCADStudio {
|
||||
cursor_type: settings::CursorType::Crosshair,
|
||||
crosshair_color: None,
|
||||
crosshair_color_input: String::new(),
|
||||
snap_marker_color: None,
|
||||
snap_marker_color_input: String::new(),
|
||||
isolines_awaiting_regen: false,
|
||||
snap_angle_input: "0".to_string(),
|
||||
lineweight_display_scale: 100,
|
||||
@@ -4338,6 +4352,7 @@ impl OpenCADStudio {
|
||||
default_assoc_prompted: false,
|
||||
check_missing_fonts: true,
|
||||
font_source_url: String::new(),
|
||||
qnew_template: String::new(),
|
||||
font_source_input: String::new(),
|
||||
donation_prompt_version: String::new(),
|
||||
read_only: false,
|
||||
|
||||
@@ -251,6 +251,7 @@ const SNAP_ORDER: &[SnapType] = &[
|
||||
SnapType::Endpoint,
|
||||
SnapType::Midpoint,
|
||||
SnapType::Center,
|
||||
SnapType::GeometricCenter,
|
||||
SnapType::Node,
|
||||
SnapType::Quadrant,
|
||||
SnapType::Intersection,
|
||||
@@ -276,6 +277,7 @@ fn snap_bit(s: SnapType) -> Option<i32> {
|
||||
SnapType::Midpoint => 2,
|
||||
SnapType::Center => 4,
|
||||
SnapType::Node => 8,
|
||||
SnapType::GeometricCenter => 1024,
|
||||
SnapType::Quadrant => 16,
|
||||
SnapType::Intersection => 32,
|
||||
SnapType::Insertion => 64,
|
||||
@@ -430,6 +432,8 @@ pub struct UserSettings {
|
||||
pub cursor_type: CursorType,
|
||||
/// Explicit crosshair RGB. `None` keeps automatic background contrast.
|
||||
pub crosshair_color: Option<[u8; 3]>,
|
||||
/// Explicit object-snap marker RGB. `None` keeps the automatic colour.
|
||||
pub snap_marker_color: Option<[u8; 3]>,
|
||||
/// Model-space lineweight preview scale as a percentage.
|
||||
pub lineweight_display_scale: i32,
|
||||
/// Isometric drafting changes the grid and crosshair to the active axis
|
||||
@@ -459,6 +463,9 @@ pub struct UserSettings {
|
||||
/// so an intranet folder or a private GitHub raw folder both work.
|
||||
#[serde(default)]
|
||||
pub font_source_url: String,
|
||||
/// Drawing new tabs start from (QNEW template); empty = a blank drawing.
|
||||
#[serde(default)]
|
||||
pub qnew_template: String,
|
||||
/// App version whose donation prompt has been displayed.
|
||||
pub donation_prompt_version: String,
|
||||
/// The graphics verdict (`GpuStatus::identity()`) whose warning popup the
|
||||
@@ -819,6 +826,7 @@ impl Default for UserSettings {
|
||||
ncopy_bind: false,
|
||||
cursor_type: CursorType::Crosshair,
|
||||
crosshair_color: None,
|
||||
snap_marker_color: None,
|
||||
lineweight_display_scale: 100,
|
||||
isometric_drafting: false,
|
||||
iso_plane: IsoPlane::Left,
|
||||
@@ -827,6 +835,7 @@ impl Default for UserSettings {
|
||||
default_assoc_prompted: false,
|
||||
check_missing_fonts: true,
|
||||
font_source_url: String::new(),
|
||||
qnew_template: String::new(),
|
||||
donation_prompt_version: String::new(),
|
||||
gpu_warning_silenced: String::new(),
|
||||
disabled_plugins: Vec::new(),
|
||||
|
||||
@@ -1311,6 +1311,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
self.tabs[i]
|
||||
.layers
|
||||
.sync_with_viewports(&doc_layers, vp_info);
|
||||
self.sync_ribbon_layers();
|
||||
// Per-viewport layer visibility changes the resident
|
||||
// assembly, not any entity's tessellated geometry.
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
|
||||
+13
-2
@@ -681,6 +681,7 @@ impl OpenCADStudio {
|
||||
ncopy_bind: self.ncopy_bind,
|
||||
cursor_type: self.cursor_type,
|
||||
crosshair_color: self.crosshair_color,
|
||||
snap_marker_color: self.snap_marker_color,
|
||||
lineweight_display_scale: self.lineweight_display_scale,
|
||||
isometric_drafting: self.isometric_drafting,
|
||||
iso_plane: self.iso_plane,
|
||||
@@ -689,6 +690,7 @@ impl OpenCADStudio {
|
||||
default_assoc_prompted: self.default_assoc_prompted,
|
||||
check_missing_fonts: self.check_missing_fonts,
|
||||
font_source_url: self.font_source_url.clone(),
|
||||
qnew_template: self.qnew_template.clone(),
|
||||
donation_prompt_version: self.donation_prompt_version.clone(),
|
||||
gpu_warning_silenced: self.gpu_warning_silenced.clone(),
|
||||
disabled_plugins: {
|
||||
@@ -791,6 +793,11 @@ impl OpenCADStudio {
|
||||
.crosshair_color
|
||||
.map(crate::app::config::rgb_to_hex)
|
||||
.unwrap_or_default();
|
||||
self.snap_marker_color = s.snap_marker_color;
|
||||
self.snap_marker_color_input = s
|
||||
.snap_marker_color
|
||||
.map(crate::app::config::rgb_to_hex)
|
||||
.unwrap_or_default();
|
||||
self.lineweight_display_scale = s.lineweight_display_scale.clamp(25, 200);
|
||||
self.isometric_drafting = s.isometric_drafting;
|
||||
self.iso_plane = s.iso_plane;
|
||||
@@ -808,6 +815,7 @@ impl OpenCADStudio {
|
||||
self.default_assoc_prompted = s.default_assoc_prompted;
|
||||
self.check_missing_fonts = s.check_missing_fonts;
|
||||
self.font_source_url = s.font_source_url.clone();
|
||||
self.qnew_template = s.qnew_template.clone();
|
||||
self.font_source_input = s.font_source_url.clone();
|
||||
self.donation_prompt_version = s.donation_prompt_version.clone();
|
||||
self.gpu_warning_silenced = s.gpu_warning_silenced.clone();
|
||||
@@ -3603,10 +3611,13 @@ impl OpenCADStudio {
|
||||
pub(super) fn apply_plot_page_settings(&mut self) {
|
||||
let i = self.active_tab;
|
||||
let layout_name = self.tabs[i].scene.current_layout.clone();
|
||||
let ps = self.plot_settings_from_dialog(self.dialog_base_settings());
|
||||
if layout_name == "Model" {
|
||||
// Model keeps its page setup too (#1620); it has no sheet limits.
|
||||
self.tabs[i].scene.set_layout_plot_settings(&layout_name, &ps);
|
||||
self.tabs[i].dirty = true;
|
||||
return;
|
||||
}
|
||||
let ps = self.plot_settings_from_dialog(self.dialog_base_settings());
|
||||
let (w, h) = plot_dialog_sheet_mm(&self.plot_dialog);
|
||||
let plot_area = self.plot_dialog.area.clone();
|
||||
let center = ps.flags.plot_centered;
|
||||
@@ -5360,7 +5371,7 @@ impl OpenCADStudio {
|
||||
// into it when "Save changes to layout" is on, so the page setup
|
||||
// remembers the last plot the way other applications expect. The
|
||||
// runtime paper/scale choices drive this one plot operation either way.
|
||||
if !preview && d.save_to_layout && d.paper_space {
|
||||
if !preview && d.save_to_layout {
|
||||
self.apply_dialog_to_layout();
|
||||
} else {
|
||||
self.sync_dialog_plot_runtime();
|
||||
|
||||
@@ -1877,6 +1877,20 @@ impl OpenCADStudio {
|
||||
self.sync_ribbon_from_selection();
|
||||
// A fresh drawing starts with grid/snap off (its tile defaults).
|
||||
self.adopt_view_display(self.active_tab);
|
||||
// QNEW: start from the default template when one is set (#1113).
|
||||
let template = self.qnew_template.trim().to_string();
|
||||
if !template.is_empty() {
|
||||
match self.apply_template(&template) {
|
||||
Ok(_) => {
|
||||
self.tabs[idx].dirty = false;
|
||||
self.refresh_layer_panel();
|
||||
self.sync_ribbon_styles();
|
||||
}
|
||||
Err(error) => self.command_line.push_error(
|
||||
error["error"].as_str().unwrap_or("template"),
|
||||
),
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -5809,6 +5823,10 @@ impl OpenCADStudio {
|
||||
if id == crate::modules::insert::insert_block::GALLERY_ID {
|
||||
self.refresh_block_palette();
|
||||
}
|
||||
// The per-viewport freeze column follows the active viewport.
|
||||
if id == crate::ui::ribbon::widgets::LAYER_COMBO_ID {
|
||||
self.refresh_layer_panel();
|
||||
}
|
||||
self.ribbon.toggle_dropdown(&id);
|
||||
}
|
||||
Task::none()
|
||||
@@ -8005,6 +8023,39 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::QnewTemplateChanged(path) => {
|
||||
self.qnew_template = path;
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
Message::QnewTemplateBrowse => Task::perform(
|
||||
async {
|
||||
crate::sys::file_dialog()
|
||||
.add_filter(
|
||||
crate::t!("Drawing Template (*.dwt)").as_ref(),
|
||||
&["dwt", "DWT", "dwg", "DWG", "dxf", "DXF"],
|
||||
)
|
||||
.pick_file()
|
||||
.await
|
||||
.map(|handle| crate::sys::handle_path(&handle).display().to_string())
|
||||
},
|
||||
|path| match path {
|
||||
Some(path) => Message::QnewTemplateChanged(path),
|
||||
None => Message::Noop,
|
||||
},
|
||||
),
|
||||
Message::SnapMarkerColorChanged(value) => {
|
||||
self.snap_marker_color_input = value.clone();
|
||||
if value.trim().is_empty() {
|
||||
self.snap_marker_color = None;
|
||||
self.persist_settings_if_changed();
|
||||
} else if let Some(rgb) = crate::app::config::parse_hex(&value) {
|
||||
self.snap_marker_color = Some(rgb);
|
||||
self.persist_settings_if_changed();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::DefaultSaveFormatChanged(format) => {
|
||||
self.default_save_format = crate::io::canonical_save_format(&format).to_string();
|
||||
self.persist_settings_if_changed();
|
||||
@@ -9835,6 +9886,22 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// ── Plot Style Table ──────────────────────────────────────────────
|
||||
Message::LinetypeLoaded(Some(source)) => {
|
||||
let i = self.active_tab;
|
||||
self.push_undo_snapshot(i, "LINETYPE");
|
||||
let added = crate::io::linetypes::populate_document_from_source(
|
||||
&mut self.tabs[i].scene.document,
|
||||
&source,
|
||||
);
|
||||
if added > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
self.command_line
|
||||
.push_output(crate::tf!("{added} linetype(s) loaded.").as_ref());
|
||||
Task::none()
|
||||
}
|
||||
Message::LinetypeLoaded(None) => Task::none(),
|
||||
Message::PlotStyleLoad => {
|
||||
Task::perform(crate::io::pick_plot_style(), Message::PlotStyleLoaded)
|
||||
}
|
||||
|
||||
@@ -925,6 +925,13 @@ bg={bg_ms:.1}ms n={view_count}"
|
||||
iso_plane: self.iso_plane,
|
||||
snap_angle_deg: self.snap_angle_deg,
|
||||
pick_pending: self.pending_pick_label().is_some(),
|
||||
// An infinite-line preview runs along the arms; drop them
|
||||
// so the preview stays visible (#1437).
|
||||
hide_arms: tab
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.is_some_and(|c| matches!(c.name(), "XLINE" | "RAY")),
|
||||
snap_color: self.snap_marker_color,
|
||||
},
|
||||
crate::ui::overlay::SelectionVisualOptions {
|
||||
area: self.model_space.selection_area,
|
||||
|
||||
@@ -383,11 +383,14 @@ impl OpenCADStudio {
|
||||
crate::ui::window::options::Folders::default()
|
||||
}
|
||||
},
|
||||
&self.qnew_template,
|
||||
self.double_click_block_refedit,
|
||||
self.double_click_block_attedit,
|
||||
self.cursor_type,
|
||||
self.crosshair_color,
|
||||
&self.crosshair_color_input,
|
||||
self.snap_marker_color,
|
||||
&self.snap_marker_color_input,
|
||||
self.lineweight_display_scale,
|
||||
&self.model_space,
|
||||
&self.model_bg_input,
|
||||
|
||||
+16
-7
@@ -951,25 +951,34 @@ pub(crate) fn tapered_band_points(
|
||||
let seg_count = if is_closed { n } else { n.saturating_sub(1) };
|
||||
let mut pts: Vec<[f64; 3]> = Vec::with_capacity(seg_count + 1);
|
||||
let mut widths: Vec<f32> = Vec::with_capacity(seg_count + 1);
|
||||
let mut push = |x: f64, y: f64, w: f32| {
|
||||
let (wx, wy, wz) = to_wcs(x, y);
|
||||
pts.push([wx, wy, wz]);
|
||||
let mut push = |xy: Option<(f64, f64)>, w: f32| {
|
||||
// `None` is the NaN separator that breaks the band.
|
||||
pts.push(xy.map_or([f64::NAN; 3], |(x, y)| to_wcs(x, y).into()));
|
||||
widths.push(w);
|
||||
};
|
||||
let mut prev_end_width: Option<f64> = None;
|
||||
for i in 0..seg_count {
|
||||
let (p0, bulge, sw0, ew0) = verts[i];
|
||||
let (p1, _, _, _) = verts[(i + 1) % n];
|
||||
if i == 0 {
|
||||
push(p0[0], p0[1], sw0 as f32);
|
||||
match prev_end_width {
|
||||
None => push(Some((p0[0], p0[1])), sw0 as f32),
|
||||
// A segment starting at another width than the last one ended
|
||||
// steps there: break the band and restart it (#1628).
|
||||
Some(prev) if (prev - sw0).abs() > 1e-9 => {
|
||||
push(None, 0.0);
|
||||
push(Some((p0[0], p0[1])), sw0 as f32);
|
||||
}
|
||||
Some(_) => {}
|
||||
}
|
||||
prev_end_width = Some(ew0);
|
||||
if bulge.abs() < 1e-9 {
|
||||
push(p1[0], p1[1], ew0 as f32);
|
||||
push(Some((p1[0], p1[1])), ew0 as f32);
|
||||
} else if let Some(arc) = BulgeArc::from_bulge(p0, p1, bulge) {
|
||||
let samples = arc.tessellate_angle(kernel::tessellation::DEFAULT_ANGLE);
|
||||
let segments = samples.len().saturating_sub(1).max(1);
|
||||
for (index, s) in samples.into_iter().enumerate().skip(1) {
|
||||
let t = index as f64 / segments as f64;
|
||||
push(s[0], s[1], (sw0 + (ew0 - sw0) * t) as f32);
|
||||
push(Some((s[0], s[1])), (sw0 + (ew0 - sw0) * t) as f32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,12 +842,22 @@ fn large_radial_rotation(d: &DimensionLargeRadial) -> f64 {
|
||||
}
|
||||
|
||||
fn apply_transform(dim: &mut Dimension, t: &EntityTransform) {
|
||||
// A zero text point is the "placed automatically" sentinel, not a
|
||||
// location: moving it to wherever the origin lands left the text there.
|
||||
let auto_text = {
|
||||
let base = dim.base();
|
||||
let p = base.text_middle_point;
|
||||
!base.text_user_positioned && p.x == 0.0 && p.y == 0.0 && p.z == 0.0
|
||||
};
|
||||
crate::scene::view::transform::apply_standard_entity_transform(dim, t, |entity, p1, p2| {
|
||||
codec::Entity::apply_transform(
|
||||
entity,
|
||||
&crate::scene::view::transform::reflection_about_xy_line(p1, p2),
|
||||
);
|
||||
});
|
||||
if auto_text {
|
||||
reset_automatic_text_position(dim.base_mut());
|
||||
}
|
||||
}
|
||||
|
||||
impl PropertyEditable for Dimension {
|
||||
|
||||
+4
-1
@@ -82,7 +82,10 @@ pub fn missing_shx_fonts(doc: &CadDocument) -> Vec<String> {
|
||||
// The primary font and the big font (Asian double-byte glyphs) are
|
||||
// both plain .shx files the style depends on.
|
||||
for file in [style.font_file.trim(), style.big_font_file.trim()] {
|
||||
if file.is_empty() || !file.to_ascii_lowercase().ends_with(".shx") {
|
||||
if file.is_empty()
|
||||
|| !file.to_ascii_lowercase().ends_with(".shx")
|
||||
|| crate::io::linetypes::is_bundled_shape_file(file)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let resolved = crate::io::resolve_image_file(file, base).is_some()
|
||||
|
||||
@@ -345,6 +345,13 @@ fn bundled_shape_name(file: &str, number: i16) -> Option<&'static str> {
|
||||
.map(|(_, name, _)| *name)
|
||||
}
|
||||
|
||||
/// Whether `file` is a shape file the bundled LFF substitutes stand in for,
|
||||
/// so its absence on disk never needs reporting.
|
||||
pub fn is_bundled_shape_file(file: &str) -> bool {
|
||||
let stem = shape_file_stem(file);
|
||||
BUNDLED_SHAPES.iter().any(|(f, _, _)| *f == stem)
|
||||
}
|
||||
|
||||
/// The drawing's shape-file STYLE for `file`, added when missing (an empty
|
||||
/// name, as shape files are stored).
|
||||
fn shape_file_style(doc: &mut CadDocument, file: &str) -> codec::Handle {
|
||||
|
||||
+12
-1
@@ -170,9 +170,10 @@ impl From<&str> for OpenLoadError {
|
||||
pub async fn pick_open_path() -> Option<(PathBuf, u64)> {
|
||||
let handle = crate::sys::file_dialog()
|
||||
.set_title(crate::t!("Open CAD file").as_ref())
|
||||
.add_filter(crate::t!("CAD Files").as_ref(), &["dwg", "dxf", "bak", "sv$", "DWG", "DXF", "BAK"])
|
||||
.add_filter(crate::t!("CAD Files").as_ref(), &["dwg", "dxf", "dwt", "bak", "sv$", "DWG", "DXF", "DWT", "BAK"])
|
||||
.add_filter(crate::t!("DWG Files").as_ref(), &["dwg", "DWG"])
|
||||
.add_filter(crate::t!("DXF Files").as_ref(), &["dxf", "DXF"])
|
||||
.add_filter(crate::t!("Drawing Template (*.dwt)").as_ref(), &["dwt", "DWT"])
|
||||
.add_filter(crate::t!("Backup / Autosave").as_ref(), &["bak", "sv$", "BAK"])
|
||||
.add_filter(crate::t!("All Files").as_ref(), &["*"])
|
||||
.pick_file()
|
||||
@@ -1761,6 +1762,16 @@ mod save_failure_tests {
|
||||
/// picked from outside the plot styles folder is copied into it (unless a
|
||||
/// file of that name is already there), so the dialog lists it from now on
|
||||
/// and page setups naming it resolve after a restart.
|
||||
/// Pick a `.lin` linetype definition file and return its text (#1588).
|
||||
pub async fn pick_linetype_file() -> Option<String> {
|
||||
let handle = crate::sys::file_dialog()
|
||||
.set_title(crate::t!("Load Linetypes").as_ref())
|
||||
.add_filter(crate::t!("Linetype Files").as_ref(), &["lin", "LIN"])
|
||||
.pick_file()
|
||||
.await?;
|
||||
Some(String::from_utf8_lossy(&handle.read().await).into_owned())
|
||||
}
|
||||
|
||||
pub async fn pick_plot_style() -> Result<Option<plot_style::PlotStyleTable>, String> {
|
||||
let dialog = crate::sys::file_dialog()
|
||||
.set_title(crate::t!("Load Plot Style Table").as_ref())
|
||||
|
||||
@@ -771,7 +771,9 @@ fn append_pdf_page(
|
||||
}
|
||||
// Near-white and near-yellow (viewport active border) → dark grey for print
|
||||
// (only when no CTB override was applied).
|
||||
if !color_overridden {
|
||||
// `aci == 0` is an explicit true colour and plots as drawn, like the
|
||||
// hatch pass (#1621); only a pure white there is an unresolved colour 7.
|
||||
if !color_overridden && (wire.aci != 0 || [r, g, b] == [1.0; 3]) {
|
||||
// An authored white (not colour 7) plots as drawn, like on screen.
|
||||
let is_light = r > 0.80
|
||||
&& g > 0.80
|
||||
|
||||
+18
-3
@@ -1768,7 +1768,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"LINE Specify first point:" => Some(("draw", "line-specify-first-point")),
|
||||
"LINE Specify next point [Close/Undo]:" => Some(("draw", "line-specify-next-point-close-undo")),
|
||||
"LINE Specify next point [Undo]:" => Some(("draw", "line-specify-next-point-undo")),
|
||||
"LINETYPE [List / Set]:" => Some(("styles", "linetype-list-set")),
|
||||
"LINETYPE [List / Set / Load]:" => Some(("styles", "linetype-list-set")),
|
||||
"LINETYPE SET linetype name (ByLayer / ByBlock / …):" => Some(("styles", "linetype-set-linetype-name-bylayer-byblock")),
|
||||
"LINETYPE: \"{name}\" is not loaded. Use LINETYPE LIST to see available linetypes." => Some(("styles", "linetype-name-is-not-loaded-use-linetype-list")),
|
||||
"LIST: no entities selected. Select entities first." => Some(("inquiry", "list-no-entities-selected-select-entities-firs")),
|
||||
@@ -4873,11 +4873,26 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Are you sure you want to reset? You will lose all your current shortcuts!" => Some(("common", "are-you-sure-you-want-to-reset-you-will-lose-all-your-current-shortcuts")),
|
||||
"Yes, reset" => Some(("common", "yes-reset")),
|
||||
"Reset to default" => Some(("common", "reset-to-default")),
|
||||
"Apply && Exit" => Some(("common", "apply-exit")),
|
||||
"Apply & Exit" => Some(("common", "apply-exit")),
|
||||
"Shortcut already used for command: {} → {}" => Some(("common", "shortcut-already-used-for-command")),
|
||||
"Unknown command: {}" => Some(("command", "unknown-command-cmd")),
|
||||
"Unsaved changes will be discarded." => Some(("common", "unsaved-changes-will-be-discarded")),
|
||||
"Discard && close" => Some(("common", "discard-close")),
|
||||
"Discard & close" => Some(("common", "discard-close")),
|
||||
"CHSPACE: Command not allowed in the Model tab." => Some(("common", "chspace-model-tab")),
|
||||
"CHSPACE: No plan-view viewport to change space through." => Some(("common", "chspace-no-viewport")),
|
||||
"CHSPACE: {count} object(s) changed to paper space." => Some(("common", "chspace-to-paper")),
|
||||
"CHSPACE: {count} object(s) changed to model space." => Some(("common", "chspace-to-model")),
|
||||
"Blank drawing" => Some(("common", "blank-drawing")),
|
||||
"Default template for new drawings" => Some(("common", "default-template-new-drawings")),
|
||||
"FILLET Enter Trim mode option [Trim/No trim] <Trim>:" => Some(("common", "fillet-trim-mode-trim")),
|
||||
"FILLET Enter Trim mode option [Trim/No trim] <No trim>:" => Some(("common", "fillet-trim-mode-no-trim")),
|
||||
"Linetype Files" => Some(("common", "linetype-files")),
|
||||
"Load Linetypes" => Some(("common", "load-linetypes")),
|
||||
"Requires two positive values (x,y) or one for both." => Some(("common", "requires-two-positive-values")),
|
||||
"Snap marker color" => Some(("common", "snap-marker-color")),
|
||||
"{added} linetype(s) loaded." => Some(("common", "linetypes-loaded")),
|
||||
"Geometric Center" => Some(("common", "geometric-center-snap")),
|
||||
"No trim" => Some(("common", "no-trim-option")),
|
||||
"Keep editing" => Some(("common", "keep-editing")),
|
||||
"MCP control is off" => Some(("common", "mcp-control-is-off")),
|
||||
"MCP is handling a request" => Some(("common", "mcp-is-handling-a-request")),
|
||||
|
||||
@@ -32,6 +32,7 @@ thread_local! {
|
||||
static HELIX_HEIGHT: Cell<f64> = Cell::new(1.0);
|
||||
static HELIX_TURNS: Cell<f64> = Cell::new(3.0);
|
||||
static HELIX_COUNTER_CLOCKWISE: Cell<bool> = Cell::new(true);
|
||||
static FILLET_TRIM: Cell<bool> = Cell::new(true); // TRIMMODE
|
||||
}
|
||||
|
||||
macro_rules! accessors {
|
||||
@@ -85,6 +86,13 @@ pub fn get_helix_counter_clockwise() -> bool {
|
||||
pub fn set_helix_counter_clockwise(value: bool) {
|
||||
HELIX_COUNTER_CLOCKWISE.with(|current| current.set(value));
|
||||
}
|
||||
pub fn get_fillet_trim() -> bool {
|
||||
FILLET_TRIM.with(|value| value.get())
|
||||
}
|
||||
|
||||
pub fn set_fillet_trim(value: bool) {
|
||||
FILLET_TRIM.with(|current| current.set(value));
|
||||
}
|
||||
accessors!(
|
||||
get_donut_inner_diameter,
|
||||
set_donut_inner_diameter,
|
||||
|
||||
@@ -81,5 +81,5 @@ impl CadCommand for PointCommand {
|
||||
inventory::submit!(crate::command::CommandRegistration { names: &["POINT", "MULTIPOINT"] }); // PointCommand
|
||||
// Point display style system variables + dialog.
|
||||
inventory::submit!(crate::command::CommandRegistration {
|
||||
names: &["PDMODE", "PDSIZE", "DDPTYPE"]
|
||||
names: &["PDMODE", "PDSIZE", "DDPTYPE", "PTYPE"]
|
||||
});
|
||||
@@ -9,7 +9,7 @@
|
||||
// Pick two lines (line-only; arcs are not chamferable).
|
||||
// Finds intersection, backs off dist1 along line 1 and dist2 along line 2.
|
||||
|
||||
use codec::entities::{Arc as ArcEnt, Line as LineEnt, LwPolyline};
|
||||
use codec::entities::{Arc as ArcEnt, Line as LineEnt, LwPolyline, LwVertex};
|
||||
|
||||
// Shared plane geometry, from opencadkernel via the local adapters.
|
||||
use super::geom;
|
||||
@@ -1354,6 +1354,9 @@ enum FilletStep {
|
||||
// Radius may be typed directly or measured by picking two points.
|
||||
WaitingForRadius,
|
||||
|
||||
/// Trim / No trim: whether the picked objects are cut back to the arc.
|
||||
TrimMode,
|
||||
|
||||
RadiusSecondPoint {
|
||||
first: DVec3,
|
||||
},
|
||||
@@ -1398,12 +1401,16 @@ impl FilletCommand {
|
||||
/// Switch to the radius sub-step, remembering the first pick (if any) so
|
||||
/// it can be restored afterwards.
|
||||
fn enter_radius_substep(&mut self) {
|
||||
self.enter_substep(FilletStep::WaitingForRadius);
|
||||
}
|
||||
|
||||
fn enter_substep(&mut self, step: FilletStep) {
|
||||
self.resume_second = if let FilletStep::Second { h1, e1, click1 } = &self.step {
|
||||
Some((*h1, e1.clone(), *click1))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.step = FilletStep::WaitingForRadius;
|
||||
self.step = step;
|
||||
}
|
||||
|
||||
/// Leave the radius sub-step, resuming the second pick when a first object
|
||||
@@ -1415,7 +1422,12 @@ impl FilletCommand {
|
||||
};
|
||||
}
|
||||
|
||||
fn continue_after_fillet(&mut self, replacements: Vec<(Handle, Vec<EntityType>)>) -> CmdResult {
|
||||
fn continue_after_fillet(&mut self, mut replacements: Vec<(Handle, Vec<EntityType>)>) -> CmdResult {
|
||||
for entity in replacements.iter_mut().flat_map(|(_, entities)| entities.iter_mut()) {
|
||||
if let EntityType::LwPolyline(poly) = entity {
|
||||
drop_zero_length_segments(poly);
|
||||
}
|
||||
}
|
||||
self.all_entities.retain(|entity| {
|
||||
!replacements
|
||||
.iter()
|
||||
@@ -1488,6 +1500,12 @@ impl CadCommand for FilletCommand {
|
||||
FilletStep::RadiusSecondPoint { .. } => {
|
||||
crate::t!("FILLET Specify second point for radius:").into_owned()
|
||||
}
|
||||
FilletStep::TrimMode => if defaults::get_fillet_trim() {
|
||||
crate::t!("FILLET Enter Trim mode option [Trim/No trim] <Trim>:")
|
||||
} else {
|
||||
crate::t!("FILLET Enter Trim mode option [Trim/No trim] <No trim>:")
|
||||
}
|
||||
.into_owned(),
|
||||
FilletStep::Second { .. } => {
|
||||
crate::tf!(
|
||||
"FILLET Select second object (Line/Arc/LwPolyline) [R={:.4}]:",
|
||||
@@ -1509,10 +1527,14 @@ impl CadCommand for FilletCommand {
|
||||
}
|
||||
opts.push(CmdOption::new("Polyline", "P"));
|
||||
opts.push(CmdOption::new("Radius", "R"));
|
||||
opts.push(CmdOption::new("Trim", "T"));
|
||||
opts
|
||||
}
|
||||
FilletStep::Second { .. } => {
|
||||
vec![CmdOption::new("Radius", "R")]
|
||||
vec![CmdOption::new("Radius", "R"), CmdOption::new("Trim", "T")]
|
||||
}
|
||||
FilletStep::TrimMode => {
|
||||
vec![CmdOption::new("Trim", "T"), CmdOption::new("No trim", "N")]
|
||||
}
|
||||
FilletStep::Polyline
|
||||
| FilletStep::WaitingForRadius
|
||||
@@ -1521,7 +1543,7 @@ impl CadCommand for FilletCommand {
|
||||
}
|
||||
|
||||
fn wants_text_input(&self) -> bool {
|
||||
matches!(self.step, FilletStep::WaitingForRadius)
|
||||
matches!(self.step, FilletStep::WaitingForRadius | FilletStep::TrimMode)
|
||||
}
|
||||
|
||||
fn dyn_field(&self) -> crate::command::DynField {
|
||||
@@ -1552,6 +1574,16 @@ impl CadCommand for FilletCommand {
|
||||
// Invalid — stay and re-prompt
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
FilletStep::TrimMode => {
|
||||
match text.trim().to_uppercase().as_str() {
|
||||
"" => {}
|
||||
"T" | "TRIM" => defaults::set_fillet_trim(true),
|
||||
"N" | "NO TRIM" | "NOTRIM" => defaults::set_fillet_trim(false),
|
||||
_ => return Some(CmdResult::NeedPoint),
|
||||
}
|
||||
self.resume_after_radius();
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
FilletStep::First | FilletStep::Second { .. } => {
|
||||
let t = text.trim();
|
||||
let upper = t.to_uppercase();
|
||||
@@ -1562,6 +1594,10 @@ impl CadCommand for FilletCommand {
|
||||
if upper == "U" || upper == "UNDO" {
|
||||
return self.undo_last();
|
||||
}
|
||||
if upper == "T" || upper == "TRIM" {
|
||||
self.enter_substep(FilletStep::TrimMode);
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
// "R" alone → enter sub-step to collect radius
|
||||
if upper == "R" {
|
||||
self.enter_radius_substep();
|
||||
@@ -1594,6 +1630,7 @@ impl CadCommand for FilletCommand {
|
||||
self.step,
|
||||
FilletStep::WaitingForRadius
|
||||
| FilletStep::RadiusSecondPoint { .. }
|
||||
| FilletStep::TrimMode
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1619,7 +1656,8 @@ impl CadCommand for FilletCommand {
|
||||
|
||||
match &self.step {
|
||||
FilletStep::WaitingForRadius
|
||||
| FilletStep::RadiusSecondPoint { .. } => {
|
||||
| FilletStep::RadiusSecondPoint { .. }
|
||||
| FilletStep::TrimMode => {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
|
||||
@@ -1689,6 +1727,17 @@ impl CadCommand for FilletCommand {
|
||||
|
||||
if let Some(e2) = e2 {
|
||||
match compute_fillet_entities(&e1, click1, &e2, click, self.radius) {
|
||||
// No trim: the objects stay as they are; only the arc
|
||||
// is added (#1558).
|
||||
Some((_, _, maybe_arc)) if !defaults::get_fillet_trim() => {
|
||||
let Some(arc) = maybe_arc else {
|
||||
return CmdResult::NeedPoint;
|
||||
};
|
||||
self.step = FilletStep::First;
|
||||
self.resume_second = None;
|
||||
self.made += 1;
|
||||
CmdResult::CommitEntity(arc)
|
||||
}
|
||||
Some((new_e1, new_e2, maybe_arc)) => {
|
||||
let mut first_replacements = vec![new_e1];
|
||||
if let Some(arc) = maybe_arc {
|
||||
@@ -1719,7 +1768,8 @@ impl CadCommand for FilletCommand {
|
||||
|
||||
match &self.step {
|
||||
FilletStep::WaitingForRadius
|
||||
| FilletStep::RadiusSecondPoint { .. } => vec![],
|
||||
| FilletStep::RadiusSecondPoint { .. }
|
||||
| FilletStep::TrimMode => vec![],
|
||||
FilletStep::Polyline => {
|
||||
let preview = self
|
||||
.entity_index
|
||||
@@ -1780,20 +1830,21 @@ impl CadCommand for FilletCommand {
|
||||
if let Some((new_e1, new_e2, maybe_arc)) =
|
||||
compute_fillet_entities(&e1, click1, &e2, click, self.radius)
|
||||
{
|
||||
let mut out = vec![
|
||||
WireModel::solid(
|
||||
let mut out = Vec::new();
|
||||
if defaults::get_fillet_trim() {
|
||||
out.push(WireModel::solid(
|
||||
"fillet_e1".into(),
|
||||
entity_pts(&new_e1),
|
||||
WireModel::CYAN,
|
||||
false,
|
||||
),
|
||||
WireModel::solid(
|
||||
));
|
||||
out.push(WireModel::solid(
|
||||
"fillet_e2".into(),
|
||||
entity_pts(&new_e2),
|
||||
WireModel::CYAN,
|
||||
false,
|
||||
),
|
||||
];
|
||||
));
|
||||
}
|
||||
if let Some(arc) = maybe_arc {
|
||||
out.push(WireModel::solid(
|
||||
"fillet_arc".into(),
|
||||
@@ -1856,6 +1907,29 @@ impl CadCommand for FilletCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// A radius-0 fillet over an existing arc leaves its two ends on one point;
|
||||
/// the zero-length segment between them blocked every later fillet of that
|
||||
/// corner (#1422). The later vertex carries the next segment, so it survives.
|
||||
fn drop_zero_length_segments(poly: &mut LwPolyline) {
|
||||
let same = |a: &LwVertex, b: &LwVertex| {
|
||||
(a.location.x - b.location.x).abs() < 1e-9 && (a.location.y - b.location.y).abs() < 1e-9
|
||||
};
|
||||
let mut i = 0;
|
||||
while i + 1 < poly.vertices.len() && poly.vertices.len() > 2 {
|
||||
if same(&poly.vertices[i], &poly.vertices[i + 1]) {
|
||||
poly.vertices.remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
if poly.is_closed && poly.vertices.len() > 2 {
|
||||
let n = poly.vertices.len();
|
||||
if same(&poly.vertices[n - 1], &poly.vertices[0]) {
|
||||
poly.vertices.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// ChamferCommand
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
@@ -2448,16 +2522,16 @@ mod tests {
|
||||
1.0,
|
||||
vec![line(0.0, 0.0, 10.0, 0.0, 1), line(0.0, 0.0, 0.0, 10.0, 2)],
|
||||
);
|
||||
assert_eq!(keywords(&command), ["P", "R"]);
|
||||
assert_eq!(keywords(&command), ["P", "R", "T"]);
|
||||
assert!(command.on_text_input("U").is_none(), "nothing to undo yet");
|
||||
command.on_entity_pick(Handle::new(1), DVec3::new(5.0, 0.0, 0.0));
|
||||
assert!(matches!(
|
||||
command.on_entity_pick(Handle::new(2), DVec3::new(0.0, 5.0, 0.0)),
|
||||
CmdResult::ReplaceManyContinue(_)
|
||||
));
|
||||
assert_eq!(keywords(&command), ["U", "P", "R"]);
|
||||
assert_eq!(keywords(&command), ["U", "P", "R", "T"]);
|
||||
assert!(matches!(command.on_text_input("U"), Some(CmdResult::UndoDocument)));
|
||||
assert_eq!(keywords(&command), ["P", "R"]);
|
||||
assert_eq!(keywords(&command), ["P", "R", "T"]);
|
||||
// The host hands the restored document back; the cache follows it.
|
||||
let mut doc = codec::CadDocument::new();
|
||||
let _ = doc.add_entity(line(0.0, 0.0, 20.0, 0.0, 7));
|
||||
|
||||
@@ -9,6 +9,7 @@ use glam::DVec3;
|
||||
use rustc_hash::FxHashMap as HashMap;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
const TAU: f64 = std::f64::consts::TAU;
|
||||
@@ -188,6 +189,24 @@ impl PeditCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// WCS location of a vertex of the polyline being edited.
|
||||
fn vertex_world(&self, index: usize) -> Option<DVec3> {
|
||||
let entity = self.target.and_then(|handle| self.entities.get(&handle.value()))?;
|
||||
let (ocs, n) = match entity {
|
||||
EntityType::LwPolyline(p) => {
|
||||
let v = p.vertices.get(index)?;
|
||||
((v.location.x, v.location.y, p.elevation), &p.normal)
|
||||
}
|
||||
EntityType::Polyline2D(p) => {
|
||||
let v = p.vertices.get(index)?;
|
||||
((v.location.x, v.location.y, p.elevation), &p.normal)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let (x, y, z) = crate::scene::view::transform::ocs_point_to_wcs(ocs, (n.x, n.y, n.z));
|
||||
Some(DVec3::new(x, y, z))
|
||||
}
|
||||
|
||||
fn vertex_count(&self) -> usize {
|
||||
self.target.and_then(|handle| self.entities.get(&handle.value())).map_or(0, |entity| match entity {
|
||||
EntityType::LwPolyline(polyline) => polyline.vertices.len(),
|
||||
@@ -237,6 +256,40 @@ impl CadCommand for PeditCommand {
|
||||
"PEDIT"
|
||||
}
|
||||
|
||||
/// Edit-vertex steps mark the current vertex with a screen-sized X (#1628).
|
||||
fn on_mouse_move(&mut self, _pt: DVec3) -> Option<WireModel> {
|
||||
let index = match self.mode {
|
||||
Mode::PolyVertex(i)
|
||||
| Mode::PolyTangent(i)
|
||||
| Mode::PolyMove(i)
|
||||
| Mode::PolyInsert(i)
|
||||
| Mode::PolyWidthStart(i, _)
|
||||
| Mode::PolyWidthEnd(i, _) => i,
|
||||
Mode::PolyRange { end, .. } => end,
|
||||
_ => return None,
|
||||
};
|
||||
let origin = self.vertex_world(index)?;
|
||||
let at = |dx: f64, dy: f64| {
|
||||
let p = origin + DVec3::new(dx, dy, 0.0);
|
||||
[p.x, p.y, p.z]
|
||||
};
|
||||
let h = 0.5;
|
||||
let mut wire = WireModel::solid_f64(
|
||||
"pedit_vertex_marker".into(),
|
||||
vec![at(-h, -h), at(h, h), [f64::NAN; 3], at(-h, h), at(h, -h)],
|
||||
WireModel::CYAN,
|
||||
false,
|
||||
);
|
||||
wire.point_marker = Some(crate::scene::model::wire_model::PointMarker {
|
||||
origin,
|
||||
normal: DVec3::Z,
|
||||
axis_x: DVec3::X,
|
||||
axis_y: DVec3::Y,
|
||||
viewport_percent: 3.0,
|
||||
});
|
||||
Some(wire)
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.mode {
|
||||
Mode::PickTarget => {
|
||||
|
||||
@@ -31,6 +31,7 @@ const SUBTRACT_ICON: &[u8] = include_bytes!("../../../assets/icons/model/subtrac
|
||||
const INTERSECT_ICON: &[u8] = include_bytes!("../../../assets/icons/model/intersect.svg");
|
||||
const FILLET_ICON: &[u8] = include_bytes!("../../../assets/icons/model/fillet.svg");
|
||||
const CHAMFER_ICON: &[u8] = include_bytes!("../../../assets/icons/model/chamfer.svg");
|
||||
const SHELL_ICON: &[u8] = include_bytes!("../../../assets/icons/model/shell.svg");
|
||||
|
||||
/// Helper to declare a ribbon tool that fires a named command.
|
||||
fn tool(id: &'static str, label: &'static str, icon: &'static [u8]) -> ToolDef {
|
||||
@@ -93,7 +94,7 @@ impl CadModule for ModelModule {
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("FILLETEDGE", "Fillet Edge", FILLET_ICON)),
|
||||
RibbonItem::LargeTool(tool("CHAMFEREDGE", "Chamfer", CHAMFER_ICON)),
|
||||
RibbonItem::LargeTool(tool("SHELL", "Shell", PRESSPULL_ICON)),
|
||||
RibbonItem::LargeTool(tool("SHELL", "Shell", SHELL_ICON)),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -97,6 +97,13 @@ impl CadCommand for ZoomWindowCommand {
|
||||
self.scale_prompt = true;
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
// A scale factor straight at the first prompt: n, nX or nXP.
|
||||
upper if upper.ends_with('X')
|
||||
|| upper.ends_with("XP")
|
||||
|| crate::app::expr_eval::eval_number(&upper).is_some() =>
|
||||
{
|
||||
return Some(CmdResult::Dispatch(format!("ZOOM SCALE {text}")));
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(CmdResult::Dispatch(command.to_string()))
|
||||
|
||||
@@ -180,6 +180,21 @@ pub(crate) fn text_contrast_background(
|
||||
/// Split each absolute f64 source point into double-single (high, low) f32
|
||||
/// buffers in one pass — the relative-to-eye residual the GPU/CPU reconstruct
|
||||
/// to f64 precision at UTM-scale coordinates.
|
||||
/// Area centroid of a closed polyline, for the Geometric Center snap.
|
||||
fn geometric_center(entity: &EntityType) -> Option<glam::DVec3> {
|
||||
let closed = match entity {
|
||||
EntityType::LwPolyline(p) => p.is_closed && p.vertices.len() >= 3,
|
||||
EntityType::Polyline2D(p) => p.is_closed() && p.vertices.len() >= 3,
|
||||
_ => false,
|
||||
};
|
||||
if !closed {
|
||||
return None;
|
||||
}
|
||||
let planar = crate::entities::curve::entity_curve(entity)?;
|
||||
let center = planar.curve.enclosed_centroid()?;
|
||||
Some(glam::DVec3::from_array(planar.plane.point_at(center)))
|
||||
}
|
||||
|
||||
pub(crate) fn points_to_ds(
|
||||
src: impl IntoIterator<Item = [f64; 3]>,
|
||||
) -> (Vec<[f32; 3]>, Vec<[f32; 3]>) {
|
||||
@@ -1102,7 +1117,10 @@ pub fn tessellate(
|
||||
)),
|
||||
_ => convert(entity, document),
|
||||
});
|
||||
if let Some(te) = te {
|
||||
if let Some(mut te) = te {
|
||||
if let Some(center) = geometric_center(entity) {
|
||||
te.snap_pts.push((center, SnapHint::GeometricCenter));
|
||||
}
|
||||
match te.object {
|
||||
// ── Text / MText: pre-tessellated glyph strokes ───────────────
|
||||
//
|
||||
|
||||
@@ -54,7 +54,7 @@ pub(crate) fn osnap_type_for(snap: crate::snap::SnapType) -> u8 {
|
||||
S::Nearest | S::Extension => osnap::NEAR,
|
||||
S::ApparentIntersection => osnap::APPARENT_INT,
|
||||
S::Parallel => osnap::PARA,
|
||||
S::Grid | S::ObjectPick | S::Vertex | S::EdgeMidpoint | S::FaceCenter | S::Knot | S::FacePerpendicular | S::NearestFace => {
|
||||
S::GeometricCenter | S::Grid | S::ObjectPick | S::Vertex | S::EdgeMidpoint | S::FaceCenter | S::Knot | S::FacePerpendicular | S::NearestFace => {
|
||||
osnap::NONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6300,6 +6300,39 @@ impl Scene {
|
||||
Some(scale_handle)
|
||||
}
|
||||
|
||||
/// Scale the active viewport to `factor` paper units per model unit
|
||||
/// (ZOOM nXP). A named scale of that factor is linked as its annotation
|
||||
/// scale; otherwise the viewport keeps a custom scale.
|
||||
pub fn set_viewport_scale_factor(&mut self, factor: f64) -> bool {
|
||||
let Some(viewport) = self.explicit_viewport_handle() else {
|
||||
return false;
|
||||
};
|
||||
let unit_factor = self.annotation_scale_unit_factor();
|
||||
let named = self.document.objects.values().find_map(|object| match object {
|
||||
ObjectType::Scale(scale)
|
||||
if !scale.is_temporary
|
||||
&& (scale.factor() * unit_factor - factor).abs() <= 1.0e-9 * factor.max(1.0) =>
|
||||
{
|
||||
Some(scale.name.clone())
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
if let Some(name) = named {
|
||||
return self.set_viewport_scale_named_for(viewport, &name).is_some();
|
||||
}
|
||||
match self.document.get_entity_mut(viewport) {
|
||||
Some(EntityType::Viewport(vp)) if !vp.status.locked && factor > 1.0e-9 => {
|
||||
vp.custom_scale = factor;
|
||||
vp.view_height = vp.height / factor;
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
self.notify_viewport_changed(viewport);
|
||||
self.resident_wire_sets.borrow_mut().clear();
|
||||
self.bump_geometry();
|
||||
true
|
||||
}
|
||||
|
||||
pub fn viewport_annotation_scale_synced(&self) -> Option<bool> {
|
||||
let viewport = self.explicit_viewport_handle()?;
|
||||
let EntityType::Viewport(vp) = self.document.get_entity(viewport)? else {
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
pub enum SnapHint {
|
||||
/// Geometric center of a circle, arc, or ellipse.
|
||||
Center,
|
||||
/// Area centroid of a closed polyline.
|
||||
GeometricCenter,
|
||||
/// Point entity location.
|
||||
Node,
|
||||
/// 0 / 90 / 180 / 270 ° point on a circle/arc (within arc span).
|
||||
|
||||
+9
-1
@@ -30,6 +30,8 @@ pub enum SnapType {
|
||||
Endpoint,
|
||||
Midpoint,
|
||||
Center,
|
||||
/// Area centroid of a closed polyline (#1369).
|
||||
GeometricCenter,
|
||||
Node,
|
||||
Quadrant,
|
||||
Intersection,
|
||||
@@ -83,6 +85,7 @@ pub const ALL_SNAP_MODES: &[(SnapType, &str, &str)] = &[
|
||||
(SnapType::Endpoint, "◻", "Endpoint"),
|
||||
(SnapType::Midpoint, "△", "Midpoint"),
|
||||
(SnapType::Center, "◯", "Center"),
|
||||
(SnapType::GeometricCenter, "⊙", "Geometric Center"),
|
||||
(SnapType::Node, "◆", "Node"),
|
||||
(SnapType::Quadrant, "◇", "Quadrant"),
|
||||
(SnapType::Intersection, "✕", "Intersection"),
|
||||
@@ -1440,6 +1443,10 @@ impl Snapper {
|
||||
// else stays on the 2D master + mode set.
|
||||
let (snap_type, on) = match hint {
|
||||
SnapHint::Center => (SnapType::Center, self.is_on(SnapType::Center)),
|
||||
SnapHint::GeometricCenter => (
|
||||
SnapType::GeometricCenter,
|
||||
self.is_on(SnapType::GeometricCenter),
|
||||
),
|
||||
SnapHint::Node => (SnapType::Node, self.is_on(SnapType::Node)),
|
||||
SnapHint::Quadrant => (SnapType::Quadrant, self.is_on(SnapType::Quadrant)),
|
||||
SnapHint::Insertion => (SnapType::Insertion, self.is_on(SnapType::Insertion)),
|
||||
@@ -2602,6 +2609,7 @@ pub(crate) fn snap_tier(t: SnapType) -> u8 {
|
||||
| SnapType::ApparentIntersection
|
||||
| SnapType::Midpoint
|
||||
| SnapType::Center
|
||||
| SnapType::GeometricCenter
|
||||
| SnapType::Node
|
||||
| SnapType::Quadrant
|
||||
| SnapType::Insertion
|
||||
@@ -2663,7 +2671,7 @@ pub(crate) fn snap_priority(t: SnapType) -> u8 {
|
||||
SnapType::Intersection => 1,
|
||||
SnapType::ApparentIntersection => 2,
|
||||
SnapType::Midpoint => 3,
|
||||
SnapType::Center => 4,
|
||||
SnapType::Center | SnapType::GeometricCenter => 4,
|
||||
SnapType::Node => 5,
|
||||
SnapType::Quadrant => 6,
|
||||
SnapType::Insertion => 7,
|
||||
|
||||
@@ -37,8 +37,11 @@ pub fn color_to_aci_string(c: AcadColor) -> String {
|
||||
/// Convert an Iced colour chosen by `iced_aw::ColorPicker` into a DWG true
|
||||
/// colour. ACI-only destinations map it to their closest indexed colour later.
|
||||
pub fn iced_to_acad_color(color: Color) -> AcadColor {
|
||||
let [r, g, b, _] = color.into_rgba8();
|
||||
AcadColor::Rgb { r, g, b }
|
||||
// Truncate the way the picker labels its channels, so the stored colour
|
||||
// is the one the dialog showed; rounding drifted dragged values by one
|
||||
// (#1621).
|
||||
let byte = |c: f32| (c * 255.0) as u8;
|
||||
AcadColor::Rgb { r: byte(color.r), g: byte(color.g), b: byte(color.b) }
|
||||
}
|
||||
|
||||
/// Return the closest CAD Color Index for an RGB colour.
|
||||
|
||||
@@ -985,8 +985,13 @@ impl CommandLine {
|
||||
.on_press(Message::CommandHistoryClear)
|
||||
.style(header_btn_style)
|
||||
.padding([2, 6]);
|
||||
// Collapses the console back to the single input line (#1094).
|
||||
let collapse_btn = button(crate::ui::icons::themed_arrow_down(11.0))
|
||||
.on_press(Message::CommandHistoryToggle)
|
||||
.style(header_btn_style)
|
||||
.padding([2, 6]);
|
||||
let header = container(
|
||||
row![Space::new().width(Length::Fill), copy_btn, clear_btn]
|
||||
row![Space::new().width(Length::Fill), copy_btn, clear_btn, collapse_btn]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
|
||||
@@ -32,6 +32,8 @@ static REDO: &[u8] = include_bytes!("../../assets/icons/ui/redo.svg");
|
||||
static OSNAP_ENDPOINT: &[u8] = include_bytes!("../../assets/icons/osnap/endpoint.svg");
|
||||
static OSNAP_MIDPOINT: &[u8] = include_bytes!("../../assets/icons/osnap/midpoint.svg");
|
||||
static OSNAP_CENTER: &[u8] = include_bytes!("../../assets/icons/osnap/center.svg");
|
||||
static OSNAP_GEOMETRIC_CENTER: &[u8] =
|
||||
include_bytes!("../../assets/icons/osnap/geometric_center.svg");
|
||||
static OSNAP_NODE: &[u8] = include_bytes!("../../assets/icons/osnap/node.svg");
|
||||
static OSNAP_QUADRANT: &[u8] = include_bytes!("../../assets/icons/osnap/quadrant.svg");
|
||||
static OSNAP_INTERSECTION: &[u8] = include_bytes!("../../assets/icons/osnap/intersection.svg");
|
||||
@@ -51,6 +53,8 @@ static LAY_ON: &[u8] = include_bytes!("../../assets/icons/layers/layon.svg");
|
||||
static LAY_OFF: &[u8] = include_bytes!("../../assets/icons/layers/layoff.svg");
|
||||
static LAY_FRZ: &[u8] = include_bytes!("../../assets/icons/layers/layfrz.svg");
|
||||
static LAY_THW: &[u8] = include_bytes!("../../assets/icons/layers/laythw.svg");
|
||||
static LAY_VP_FRZ: &[u8] = include_bytes!("../../assets/icons/layers/layvpfrz.svg");
|
||||
static LAY_VP_THW: &[u8] = include_bytes!("../../assets/icons/layers/layvpthw.svg");
|
||||
static LAY_LCK: &[u8] = include_bytes!("../../assets/icons/layers/laylck.svg");
|
||||
static LAY_ULK: &[u8] = include_bytes!("../../assets/icons/layers/layulk.svg");
|
||||
|
||||
@@ -630,6 +634,7 @@ pub fn osnap(snap: crate::snap::SnapType) -> &'static [u8] {
|
||||
S::Endpoint => OSNAP_ENDPOINT,
|
||||
S::Midpoint => OSNAP_MIDPOINT,
|
||||
S::Center => OSNAP_CENTER,
|
||||
S::GeometricCenter => OSNAP_GEOMETRIC_CENTER,
|
||||
S::Node => OSNAP_NODE,
|
||||
S::Quadrant => OSNAP_QUADRANT,
|
||||
S::Intersection => OSNAP_INTERSECTION,
|
||||
@@ -694,6 +699,15 @@ pub fn layer_freeze(frozen: bool) -> &'static [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
/// Freeze-in-current-viewport icon bytes (frozen / thawed).
|
||||
pub fn layer_vp_freeze(frozen: bool) -> &'static [u8] {
|
||||
if frozen {
|
||||
LAY_VP_FRZ
|
||||
} else {
|
||||
LAY_VP_THW
|
||||
}
|
||||
}
|
||||
|
||||
/// Layer lock icon bytes (locked / unlocked).
|
||||
pub fn layer_lock(locked: bool) -> &'static [u8] {
|
||||
if locked {
|
||||
|
||||
+1
-1
@@ -275,7 +275,7 @@ pub fn discard_guard<'a>(
|
||||
iced::widget::text(crate::t!("Unsaved changes will be discarded.")).size(13.5),
|
||||
Space::new().height(12),
|
||||
row![
|
||||
button(iced::widget::text(crate::t!("Discard && close")).size(12))
|
||||
button(iced::widget::text(crate::t!("Discard & close")).size(12))
|
||||
.on_press(on_discard)
|
||||
.padding([5, 14])
|
||||
.style(button::danger),
|
||||
|
||||
+11
-5
@@ -518,12 +518,20 @@ impl Graph {
|
||||
_ => None,
|
||||
};
|
||||
let zoom = self.zoom();
|
||||
// Lay the nodes out relative to the visible area's top-left rather
|
||||
// than the graph origin: a `pin` clips to its own bounds, so nodes
|
||||
// left of / above the origin vanished once panned or zoomed out (#1592).
|
||||
let shift = Vector::new(self.pan.x / zoom, self.pan.y / zoom);
|
||||
let mut nodes = stack![];
|
||||
for (node, node_sections) in self.engine.nodes.iter().zip(sections) {
|
||||
let Some(ui) = self.ui.get(&node.id) else {
|
||||
continue;
|
||||
};
|
||||
nodes = nodes.push(pin(self.node_view(node, node_sections)).x(ui.pos.x).y(ui.pos.y));
|
||||
nodes = nodes.push(
|
||||
pin(self.node_view(node, node_sections))
|
||||
.x(ui.pos.x + shift.x)
|
||||
.y(ui.pos.y + shift.y),
|
||||
);
|
||||
}
|
||||
let mut layers = stack![
|
||||
canvas(Wires { wires, pending, width: 2.0 * zoom.max(0.5) })
|
||||
@@ -531,7 +539,6 @@ impl Graph {
|
||||
.height(Length::Fill),
|
||||
Zoomed {
|
||||
content: nodes.width(Length::Fill).height(Length::Fill).into(),
|
||||
pan: self.pan,
|
||||
zoom,
|
||||
},
|
||||
];
|
||||
@@ -955,17 +962,16 @@ impl canvas::Program<Message> for Wires {
|
||||
}
|
||||
|
||||
/// Lays its content out in graph space and draws and hit-tests it through
|
||||
/// `pan` and `zoom`, so every widget inside scales as one picture.
|
||||
/// `zoom`, so every widget inside scales as one picture.
|
||||
struct Zoomed<'a> {
|
||||
content: Element<'a, Message>,
|
||||
pan: Vector,
|
||||
zoom: f32,
|
||||
}
|
||||
|
||||
impl Zoomed<'_> {
|
||||
/// Content coordinates → screen, for a layer whose top-left is `origin`.
|
||||
fn transformation(&self, origin: Point) -> Transformation {
|
||||
Transformation::translate(origin.x + self.pan.x, origin.y + self.pan.y)
|
||||
Transformation::translate(origin.x, origin.y)
|
||||
* Transformation::scale(self.zoom)
|
||||
* Transformation::translate(-origin.x, -origin.y)
|
||||
}
|
||||
|
||||
+70
-1
@@ -239,6 +239,12 @@ pub struct CrosshairOptions {
|
||||
/// the crosshair arms disappear and a blue pickbox remains — the
|
||||
/// screen-level "the client wants YOU to pick" signal.
|
||||
pub pick_pending: bool,
|
||||
/// Draw only the pickbox: the active command previews a line that the
|
||||
/// full-length arms would cover.
|
||||
pub hide_arms: bool,
|
||||
/// Explicit object-snap marker colour; `None` picks one that reads on
|
||||
/// the canvas.
|
||||
pub snap_color: Option<[u8; 3]>,
|
||||
}
|
||||
|
||||
/// Rendering style for the viewport grid.
|
||||
@@ -1517,6 +1523,10 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||
if let Some((sp, snap_type)) = self.snap {
|
||||
let (r, g, b) = if snap_type == SnapType::ObjectPick {
|
||||
(0.95_f32, 0.50, 0.08) // orange object-snap marker
|
||||
} else if let Some([r, g, b]) = self.crosshair.snap_color {
|
||||
(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0)
|
||||
} else if crate::ui::style::common::canvas_is_light(self.crosshair_bg) {
|
||||
(0.80, 0.45, 0.0) // dark amber: yellow vanishes on a light canvas
|
||||
} else {
|
||||
(1.0, 0.9, 0.1) // classic yellow OSNAP
|
||||
};
|
||||
@@ -1569,6 +1579,25 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||
let path = canvas::Path::circle(sp, r);
|
||||
frame.stroke(&path, stroke);
|
||||
}
|
||||
SnapType::GeometricCenter => {
|
||||
// Pentagon around a centre dot: the area centroid.
|
||||
let r = 6.5_f32;
|
||||
let path = canvas::Path::new(|b| {
|
||||
for k in 0..5 {
|
||||
let a = -std::f32::consts::FRAC_PI_2
|
||||
+ k as f32 * std::f32::consts::TAU / 5.0;
|
||||
let p = Point::new(sp.x + r * a.cos(), sp.y + r * a.sin());
|
||||
if k == 0 {
|
||||
b.move_to(p);
|
||||
} else {
|
||||
b.line_to(p);
|
||||
}
|
||||
}
|
||||
b.close();
|
||||
});
|
||||
frame.stroke(&path, stroke.clone());
|
||||
frame.fill(&canvas::Path::circle(sp, 1.6), marker);
|
||||
}
|
||||
SnapType::Node => {
|
||||
// Circle with an inscribed X.
|
||||
let r = 5.5_f32;
|
||||
@@ -1915,7 +1944,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||
// The arms stay only for the normal (non-pending) cursor: a
|
||||
// waiting pick shows the box alone, regardless of the UCS
|
||||
// rotation, so the square is unmistakable.
|
||||
if !pick_pending {
|
||||
if !pick_pending && !self.crosshair.hide_arms {
|
||||
for angle in base_angles {
|
||||
let rad = (angle + self.crosshair.snap_angle_deg as f64).to_radians();
|
||||
let dir = Point::new(rad.cos() as f32, -rad.sin() as f32);
|
||||
@@ -3363,6 +3392,37 @@ impl DynInputCanvas {
|
||||
(Self::box_content(b).len() as f32 * DYN_CHAR_W) + DYN_PAD * 2.0
|
||||
}
|
||||
|
||||
/// Slide a box centred at `center` straight away from the crosshair until
|
||||
/// it neither covers the aim point nor a box already placed (#1546).
|
||||
fn clear_of(center: Point, w: f32, cursor: Point, placed: &[iced::Rectangle]) -> Point {
|
||||
const KEEP: f32 = 18.0;
|
||||
let hits = |c: Point| {
|
||||
let r = iced::Rectangle {
|
||||
x: c.x - w * 0.5,
|
||||
y: c.y - DYN_BOX_H * 0.5,
|
||||
width: w,
|
||||
height: DYN_BOX_H,
|
||||
};
|
||||
r.expand(KEEP).contains(cursor) || placed.iter().any(|p| p.intersects(&r))
|
||||
};
|
||||
let (mut dx, mut dy) = (center.x - cursor.x, center.y - cursor.y);
|
||||
let len = (dx * dx + dy * dy).sqrt();
|
||||
if len < 1.0 {
|
||||
(dx, dy) = (0.0, 1.0);
|
||||
} else {
|
||||
(dx, dy) = (dx / len, dy / len);
|
||||
}
|
||||
let mut c = center;
|
||||
for _ in 0..60 {
|
||||
if !hits(c) {
|
||||
break;
|
||||
}
|
||||
c.x += dx * 4.0;
|
||||
c.y += dy * 4.0;
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
/// Draw a value box centred at `center`, clamped inside `bounds`.
|
||||
fn draw_box(
|
||||
frame: &mut canvas::Frame,
|
||||
@@ -3647,6 +3707,7 @@ impl DynInputCanvas {
|
||||
}
|
||||
|
||||
// ── Box placement by role ──
|
||||
let mut placed: Vec<iced::Rectangle> = Vec::with_capacity(self.boxes.len());
|
||||
for b in &self.boxes {
|
||||
let center = b.center.unwrap_or_else(|| match b.role {
|
||||
DynRole::Angle => self.label_screen.unwrap_or_else(|| {
|
||||
@@ -3690,6 +3751,14 @@ impl DynInputCanvas {
|
||||
y: base.y + dy * len * 0.5 + ny * 16.0,
|
||||
},
|
||||
});
|
||||
let w = Self::box_width(b);
|
||||
let center = Self::clear_of(center, w, cursor, &placed);
|
||||
placed.push(iced::Rectangle {
|
||||
x: center.x - w * 0.5,
|
||||
y: center.y - DYN_BOX_H * 0.5,
|
||||
width: w,
|
||||
height: DYN_BOX_H,
|
||||
});
|
||||
Self::draw_box(frame, b, center, bounds, theme);
|
||||
}
|
||||
// Keep the tracking hint near the crosshair in guided layouts.
|
||||
|
||||
@@ -521,6 +521,7 @@ fn snap_override_items() -> Vec<MenuItem> {
|
||||
snap("Apparent Intersection", SnapType::ApparentIntersection),
|
||||
snap("Extension", SnapType::Extension),
|
||||
snap("Center", SnapType::Center),
|
||||
snap("Geometric Center", SnapType::GeometricCenter),
|
||||
snap("Quadrant", SnapType::Quadrant),
|
||||
snap("Tangent", SnapType::Tangent),
|
||||
snap("Perpendicular", SnapType::Perpendicular),
|
||||
|
||||
+13
-1
@@ -128,6 +128,8 @@ pub struct LayerInfo {
|
||||
pub visible: bool,
|
||||
pub frozen: bool,
|
||||
pub locked: bool,
|
||||
/// Layout with an active viewport: (its Layer Manager column, frozen there).
|
||||
pub vp_frozen: Option<(usize, bool)>,
|
||||
}
|
||||
|
||||
/// Full-screen backdrop for an open ribbon dropdown: closes the dropdown when
|
||||
@@ -1042,6 +1044,13 @@ impl Ribbon {
|
||||
crate::ui::icons::layer_lock(ll),
|
||||
Message::LayerToggleLock(info.name.clone()),
|
||||
);
|
||||
// Freeze in the current viewport only (#1466).
|
||||
let vp_freeze = info.vp_frozen.map(|(column, frozen)| {
|
||||
icon_btn(
|
||||
crate::ui::icons::layer_vp_freeze(frozen),
|
||||
Message::LayerToggleVpFreeze(info.name.clone(), column),
|
||||
)
|
||||
});
|
||||
let checkmark: Element<'_, Message> =
|
||||
crate::ui::icons::themed_check_cell(is_active);
|
||||
let label =
|
||||
@@ -1067,7 +1076,10 @@ impl Ribbon {
|
||||
.padding([4, 4]);
|
||||
|
||||
container(
|
||||
row![checkmark, vis, freeze, lock, select]
|
||||
row![checkmark, vis, freeze]
|
||||
.push(vp_freeze)
|
||||
.push(lock)
|
||||
.push(select)
|
||||
.spacing(5)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
|
||||
@@ -310,7 +310,7 @@ pub(super) const TOP_HIST_GAP: f32 = 4.0;
|
||||
|
||||
pub(crate) const UNDO_HISTORY_ID: &str = "UNDO_HISTORY";
|
||||
pub(crate) const REDO_HISTORY_ID: &str = "REDO_HISTORY";
|
||||
pub(super) const LAYER_COMBO_ID: &str = "LAYER_COMBO";
|
||||
pub(crate) const LAYER_COMBO_ID: &str = "LAYER_COMBO";
|
||||
/// Dropdown id for the tab-bar panel-density selector.
|
||||
pub(super) const COLLAPSE_MODE_ID: &str = "COLLAPSE_MODE";
|
||||
pub(super) const PROP_COLOR_ID: &str = "PROP_COLOR";
|
||||
|
||||
+28
-22
@@ -384,6 +384,29 @@ pub fn view_window<'a>(
|
||||
};
|
||||
|
||||
// Linear unit formats shared by DIMLUNIT / DIMALTU.
|
||||
// Precision reads as the number pattern it produces (#1426).
|
||||
const OPT_PREC: &[(&str, &str)] = &[
|
||||
("0", "0"),
|
||||
("1", "0.0"),
|
||||
("2", "0.00"),
|
||||
("3", "0.000"),
|
||||
("4", "0.0000"),
|
||||
("5", "0.00000"),
|
||||
("6", "0.000000"),
|
||||
("7", "0.0000000"),
|
||||
("8", "0.00000000"),
|
||||
];
|
||||
// A precision dropdown, or the read-only value while the option is off.
|
||||
let prec_field = move |label: Cow<'static, str>, fld: DsField, val: &'a str, enabled: bool| -> Element<'a, Message> {
|
||||
if enabled {
|
||||
enum_field(label, fld, val, OPT_PREC)
|
||||
} else {
|
||||
row![lbl(label), mk_field_enabled(fld, val, false)]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
}
|
||||
};
|
||||
const OPT_LUNIT: &[(&str, &str)] = &[
|
||||
("1", "Scientific"),
|
||||
("2", "Decimal"),
|
||||
@@ -900,8 +923,7 @@ pub fn view_window<'a>(
|
||||
4 => column![
|
||||
text(t!("Linear dimensions")).size(11).style(primary_style),
|
||||
enum_field(t!("Unit format"), DsField::Dimlunit, vals.dimlunit, OPT_LUNIT),
|
||||
row![lbl(t!("Precision")), mk_field(DsField::Dimdec, vals.dimdec)]
|
||||
.spacing(8).align_y(iced::Center),
|
||||
prec_field(t!("Precision"), DsField::Dimdec, vals.dimdec, true),
|
||||
if matches!(vals.dimlunit.trim(), "4" | "5") {
|
||||
enum_field(
|
||||
t!("Fraction format"),
|
||||
@@ -946,8 +968,7 @@ pub fn view_window<'a>(
|
||||
vals.dimaunit,
|
||||
&[("0", "Decimal degrees"), ("1", "Degrees, minutes, seconds"), ("2", "Gradians"), ("3", "Radians"), ("4", "Surveyor's units")],
|
||||
),
|
||||
row![lbl(t!("Precision")), mk_field(DsField::Dimadec, vals.dimadec)]
|
||||
.spacing(8).align_y(iced::Center),
|
||||
prec_field(t!("Precision"), DsField::Dimadec, vals.dimadec, true),
|
||||
enum_field(
|
||||
t!("Zero suppression"),
|
||||
DsField::Dimazin,
|
||||
@@ -970,24 +991,14 @@ pub fn view_window<'a>(
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
lbl(t!("Precision")),
|
||||
mk_field_enabled(DsField::Dimaltd, vals.dimaltd, vals.dimalt)
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
prec_field(t!("Precision"), DsField::Dimaltd, vals.dimaltd, vals.dimalt),
|
||||
if vals.dimalt {
|
||||
enum_field(t!("Unit format"), DsField::Dimaltu, vals.dimaltu, OPT_LUNIT)
|
||||
} else {
|
||||
row![lbl(t!("Unit format")), container(text(alternate_unit_name).size(11).style(muted_style)).padding([4, 7]).width(150)]
|
||||
.spacing(8).align_y(iced::Center).into()
|
||||
},
|
||||
row![
|
||||
lbl(t!("Tolerance precision")),
|
||||
mk_field_enabled(DsField::Dimalttd, vals.dimalttd, vals.dimalt)
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
prec_field(t!("Tolerance precision"), DsField::Dimalttd, vals.dimalttd, vals.dimalt),
|
||||
row![
|
||||
lbl(t!("Round off")),
|
||||
mk_field_enabled(DsField::Dimaltrnd, vals.dimaltrnd, vals.dimalt)
|
||||
@@ -1042,12 +1053,7 @@ pub fn view_window<'a>(
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
lbl(t!("Precision")),
|
||||
mk_field_enabled(DsField::Dimtdec, vals.dimtdec, vals.dimtol || vals.dimlim)
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
prec_field(t!("Precision"), DsField::Dimtdec, vals.dimtdec, vals.dimtol || vals.dimlim),
|
||||
row![
|
||||
lbl(t!("Height scale")),
|
||||
mk_field_enabled(DsField::Dimtfac, vals.dimtfac, vals.dimtol || vals.dimlim)
|
||||
|
||||
@@ -218,7 +218,7 @@ pub fn view_window<'a>(
|
||||
.on_press(Message::AliasEditorApply)
|
||||
.padding([4, 16])
|
||||
.style(button::primary);
|
||||
let apply_exit = button(text(t!("Apply && Exit")).size(12))
|
||||
let apply_exit = button(text(t!("Apply & Exit")).size(12))
|
||||
.on_press(Message::AliasEditorApplyExit)
|
||||
.padding([4, 16])
|
||||
.style(button::primary);
|
||||
@@ -307,7 +307,7 @@ pub fn view_window<'a>(
|
||||
text(t!("Unsaved changes will be discarded.")).size(14),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
button(text(t!("Discard && close")).size(12))
|
||||
button(text(t!("Discard & close")).size(12))
|
||||
.on_press(Message::AliasEditorCloseDiscard)
|
||||
.padding([4, 12])
|
||||
.style(button::danger),
|
||||
|
||||
@@ -209,11 +209,14 @@ pub fn view_window<'a>(
|
||||
zoom_factor_input: &'a str,
|
||||
drawing_prefs: DrawingPrefs,
|
||||
folders: Folders,
|
||||
qnew_template: &'a str,
|
||||
double_click_block_refedit: bool,
|
||||
double_click_block_attedit: bool,
|
||||
cursor_type: CursorType,
|
||||
crosshair_color: Option<[u8; 3]>,
|
||||
crosshair_color_input: &'a str,
|
||||
snap_marker_color: Option<[u8; 3]>,
|
||||
snap_marker_color_input: &'a str,
|
||||
lineweight_display_scale: i32,
|
||||
model_space: &'a crate::app::config::ModelSpaceThemeConfig,
|
||||
model_bg_input: &'a str,
|
||||
@@ -522,6 +525,24 @@ pub fn view_window<'a>(
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let snap_rgb = snap_marker_color.unwrap_or([255, 230, 26]);
|
||||
let snap_swatch = container(Space::new())
|
||||
.width(28)
|
||||
.height(22)
|
||||
.style(move |theme: &Theme| container::Style {
|
||||
background: Some(Background::Color(iced::Color::from_rgb8(
|
||||
snap_rgb[0],
|
||||
snap_rgb[1],
|
||||
snap_rgb[2],
|
||||
))),
|
||||
border: Border {
|
||||
color: theme.palette().background.strong.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let model_bg_rgb = model_space.custom_bg.unwrap_or(crate::app::config::CLASSIC_CAD_DARK_BG);
|
||||
|
||||
let paper_bg_rgb = model_space.custom_paper_bg.unwrap_or(crate::app::config::DEFAULT_PAPER_BG);
|
||||
@@ -769,6 +790,18 @@ pub fn view_window<'a>(
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.push(Space::new().height(10))
|
||||
.push(
|
||||
row![
|
||||
text(crate::t!("Snap marker color")).size(12).width(140),
|
||||
snap_swatch,
|
||||
text_input(crate::t!("#RRGGBB or blank").as_ref(), snap_marker_color_input)
|
||||
.on_input(Message::SnapMarkerColorChanged)
|
||||
.width(150),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.push(Space::new().height(6))
|
||||
.push(
|
||||
text(crate::t!("Leave the color blank to keep automatic viewport contrast."))
|
||||
@@ -1666,6 +1699,21 @@ pub fn view_window<'a>(
|
||||
folder_row(crate::t!("Plugins"), folders.plugins.clone()),
|
||||
Space::new().height(12),
|
||||
folder_row(crate::t!("Autosave files"), folders.autosave.clone()),
|
||||
Space::new().height(16),
|
||||
text(crate::t!("Default template for new drawings")).size(12),
|
||||
Space::new().height(4),
|
||||
row![
|
||||
text_input(crate::t!("Blank drawing").as_ref(), qnew_template)
|
||||
.on_input(Message::QnewTemplateChanged)
|
||||
.size(11)
|
||||
.width(Fill),
|
||||
button(text(crate::t!("Browse...")).size(11))
|
||||
.padding([4, 10])
|
||||
.style(button::secondary)
|
||||
.on_press(Message::QnewTemplateBrowse),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
]
|
||||
.spacing(0)
|
||||
.width(sizing.width);
|
||||
|
||||
@@ -1553,7 +1553,7 @@ pub fn view_window(
|
||||
paper_space_option(s.paperspace_last, t!("Paper space last"), PlotFlag::PaperspaceLast),
|
||||
check(t!("Merge overlapping lines"), s.merge_lines, PlotFlag::MergeLines),
|
||||
check(t!("Plot stamp"), s.stamp, PlotFlag::Stamp),
|
||||
paper_space_option(s.save_to_layout, t!("Save changes to layout"), PlotFlag::SaveToLayout),
|
||||
check(t!("Save changes to layout"), s.save_to_layout, PlotFlag::SaveToLayout),
|
||||
]
|
||||
.spacing(6)
|
||||
.width(width),
|
||||
|
||||
@@ -241,7 +241,7 @@ pub fn view_window<'a>(
|
||||
.on_press(Message::ShortcutEditorApply)
|
||||
.padding([4, 16])
|
||||
.style(button::primary);
|
||||
let apply_exit = button(text(t!("Apply && Exit")).size(12))
|
||||
let apply_exit = button(text(t!("Apply & Exit")).size(12))
|
||||
.on_press(Message::ShortcutEditorApplyExit)
|
||||
.padding([4, 16])
|
||||
.style(button::primary);
|
||||
@@ -330,7 +330,7 @@ pub fn view_window<'a>(
|
||||
text(t!("Unsaved changes will be discarded.")).size(14),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
button(text(t!("Discard && close")).size(12))
|
||||
button(text(t!("Discard & close")).size(12))
|
||||
.on_press(Message::ShortcutEditorCloseDiscard)
|
||||
.padding([4, 12])
|
||||
.style(button::danger),
|
||||
|
||||
Reference in new issue
Block a user