diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 8556475..73f3ddb 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -57,4 +57,5 @@ Generated-in-code assets are original and have no file to list: | Asset | Author | Source | Licence | Notes | |---|---|---|---|---| | `crates/ui-egui/src/i18n/uk.tsv` | @dmatviichuk | Original Ukrainian translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied | +| `crates/ui-egui/src/i18n/de.tsv` | the CADCraft contributors | Original German translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied | | `crates/ui-egui/src/i18n/pt_br.tsv` | @WladmirJunior | Original Brazilian Portuguese translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied | diff --git a/README.md b/README.md index b6075c3..f1bfa8c 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ numbers): | Layouts & plotting | Paper-space layouts, viewports (scale, lock, per-viewport layer freeze), MSPACE/PSPACE through viewports, page setups, PLOT and EXPORTPDF | | Parametric | Geometric and dimensional constraints, AUTOCONSTRAIN, PARAMETERS with expressions, conflict detection; constraints re-solve after every edit | | Grips | Hot grips with Space to cycle Stretch, Move, Rotate, Scale and Mirror | -| Interface languages | English and Ukrainian (Українська), live switching and a remembered Auto/system-language choice; [details](docs/localization.md) | +| Interface languages | English, Ukrainian (Українська) and German (Deutsch), live switching and a remembered Auto/system-language choice; [details](docs/localization.md) | | Automation | MCP server, JSON control channel, `cadcraft-cli` (info, convert, run, commands, mcp) | ## Quick start diff --git a/ROADMAP.md b/ROADMAP.md index 5029789..faf0980 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -80,8 +80,8 @@ Hours are Opus 5.5 agent wall-clock hours, calibrated on this repo's own build: ## Languages -AutoCAD 2027 for Mac ships 8 interface languages; CADCraft ships English only. Detail: -[localization-parity.md](docs/localization-parity.md). +AutoCAD 2027 for Mac ships 8 interface languages; CADCraft ships English plus partial +Ukrainian and German. Detail: [localization-parity.md](docs/localization-parity.md). | Language | Status | UI translated | |---|---|---:| @@ -94,11 +94,11 @@ AutoCAD 2027 for Mac ships 8 interface languages; CADCraft ships English only. D | Portuguese | none | 0% | | Indonesian | none | 0% | | Japanese | none | 0% | -| German | none | 0% | +| German | partial | ≈ 100% of the catalog (989 rows) | | Korean | none | 0% | | Vietnamese | none | 0% | -Other languages shipped: Ukrainian, partial (936 catalog rows, landed with #36; engine messages stay English). +Other languages shipped: Ukrainian and German, both partial (989 catalog rows each; Ukrainian landed with #36; engine messages stay English). ## Upcoming diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv new file mode 100644 index 0000000..2e6082a --- /dev/null +++ b/crates/ui-egui/src/i18n/de.tsv @@ -0,0 +1,995 @@ +# CADCraft German interface catalog — original translations by the CADCraft contributors. +# License: MIT OR Apache-2.0 (the repository LICENSE-MIT and LICENSE-APACHE). +# Written from CADCraft's English strings; no proprietary translations were copied. +# UTF-8: contextEnglish sourceGerman translation. +# Empty context = ordinary label; @plural = one|other forms with {n}. +# Keep command IDs, keywords, technology/product names and user data unchanged. + Cancel Abbrechen + OK OK + or [ oder [ + % of all commits % aller Commits + * Wildcard Match * Wildcard-Abgleich + *VARIES* *VARIIERT* + + | Top | 2D Wireframe + | Oben | 2D-Drahtmodell + +Bin +Binär + +LOC +Zeilen + 1 Viewport 1 Ansichtsfenster + 2 Points 2 Punkte + 2 Viewports 2 Ansichtsfenster + 2D Solid 2D-Vollfläche + 3 Points 3 Punkte + 3 Viewports 3 Ansichtsfenster + 3D Face 3D-Fläche + 3D Operations 3D-Operationen + 3D Polyline 3D-Polylinie + 4 Viewports 4 Ansichtsfenster + < Less than < Kleiner als + <> Not Equal <> Ungleich + = Equals = Gleich + > Greater than > Größer als + About Über + About CADCraft Über CADCraft + Absolute Absolut + Add Leader Führungslinie hinzufügen + Align Ausrichten + Align Text Text ausrichten + Aligned Ausgerichtet + All Alle + All Used Layers Alle verwendeten Layer + All files Alle Dateien + Angle Winkel + Angular Winkelbemaßung + Annotation Visibility Sichtbarkeit der Beschriftungen + Annotation scale Beschriftungsmaßstab + Apparent Intersection Scheinbarer Schnittpunkt + Append to current selection set Zum aktuellen Auswahlsatz hinzufügen + Apply to: Anwenden auf: + Apply true color True Color anwenden + Arc Bogen + Arc Length Bogenlänge + Area Fläche + Arrange Panel Panel anordnen + Array Reihe + Attach Anhängen + Attribute Attribut + Attribute Definition Attributdefinition + Attribute Display Attributanzeige + Audit Zeichnung prüfen + Auto (system language) Auto (Systemsprache) + Auto Constrain Automatische Abhängigkeiten + AutoConstrain Automatische Abhängigkeiten + Axis, End Achse, Ende + Base Basis + Baseline Basislinie + Batch Publish Stapelveröffentlichung + Binary assets added Binärdateien hinzugefügt + Binary assets removed Binärdateien entfernt + Blend Übergang + Block Block + Block Attribute Manager... Blockattribut-Manager... + Block Editor Blockeditor + Block Reference Blockreferenz + Block... Block... + Blocks Blöcke + Blue Blau + Bold Fett + Boolean Boolesche Operationen + Boundary Begrenzung + Boundary... Begrenzung... + Box Quader + Break Umbrechen + Break At Point An Punkt umbrechen + Bring to Front In den Vordergrund + ByBlock VonBlock + ByColor VonFarbe + ByLayer VonLayer + CADCraft Help CADCraft-Hilfe + Cancel Abbrechen + Cartesian (x, y) Kartesisch (x, y) + Center Zentrum + Center Line Mittellinie + Center Mark Zentrumsmarke + Center X Mitte X + Center Y Mitte Y + Center Z Mitte Z + Center, Diameter Zentrum, Durchmesser + Center, Radius Zentrum, Radius + Center, Start, Angle Zentrum, Start, Winkel + Center, Start, End Zentrum, Start, Ende + Center, Start, Length Zentrum, Start, Länge + Chamfer Fase + Change Space Raum wechseln + Change to Current Layer Auf aktuellen Layer ändern + Circle Kreis + Circumference Umfang + Clear Leeren + Clipboard Zwischenablage + Close Schließen + Close All Alle schließen + Closed Geschlossen + Coincident Koinzident + Collapse Tool Sets Werkzeuggruppen einklappen + Collinear Kollinear + Color Farbe + Color 8 Farbe 8 + Color 9 Farbe 9 + Color Index Farbindex + Color... Farbe... + Command History Befehlsprotokoll + Command Line Befehlszeile + Command Line History Lines Protokollzeilen der Befehlszeile + Command Reference Befehlsreferenz + Commits Commits + Company Firma + Computer-aided design and drafting: an open-source, clean-room CAD application written in pure Rust. Rechnergestütztes Konstruieren und Zeichnen: eine quelloffene, unabhängig entwickelte CAD-Anwendung in reinem Rust. + Concentric Konzentrisch + Cone Kegel + Constraint Bars Abhängigkeitsleisten + Constraint Settings Abhängigkeitseinstellungen + Construction Line Konstruktionslinie + Contents Inhalt + Continue Fortfahren + Contributors Mitwirkende + Control Vertices Steuerpunkte + Copy Kopieren + Copy Layout Layout kopieren + Copy Nested Objects Verschachtelte Objekte kopieren + Copy Selection Auswahl kopieren + Copy with Base Point Mit Basispunkt kopieren + Count Anzahl + Create Block Block erstellen + Creates a user parameter Erstellt einen Benutzerparameter + Ctrl+Enter to finish Strg+Eingabe zum Abschließen + Current layer Aktueller Layer + Current selection Aktuelle Auswahl + Current: {color} Aktuell: {color} + Cut Ausschneiden + Cyan Cyan + Cylinder Zylinder + DWG DWG + DXF DXF + Dark Dunkel + Default Standard + Default Save Format Standard-Speicherformat + Define Attributes Attribute definieren + Define Attributes... Attribute definieren... + Defined width Definierte Breite + Degree Grad + Delete Löschen + Delete Column Spalte löschen + Delete Constraints Abhängigkeiten löschen + Delete Dimension Style Bemaßungsstil löschen + Delete Duplicate Objects Doppelte Objekte löschen + Delete Layer Layer löschen + Delete Layer State Layerstatus löschen + Delete Layout Layout löschen + Delete Row Zeile löschen + Delete Text Style Textstil löschen + Delta X Delta X + Delta Y Delta Y + Description Beschreibung + Deselect All Auswahl aufheben + Diameter Durchmesser + Dim style Bemaßungsstil + Dimension Bemaßung + Dimension Space Bemaßungsabstand + Dimension Style Override Bemaßungsstil-Übersteuerung + Dimension Style... Bemaßungsstil... + Dimension Text Edit Bemaßungstext bearbeiten + Dimension style Bemaßungsstil + Dimensional Constraint Bemaßungsabhängigkeit + Dimensional Constraint Parameters Parameter der Bemaßungsabhängigkeiten + Dimensional Constraints Bemaßungsabhängigkeiten + Disassociate Dimensions Assoziativität der Bemaßungen aufheben + Display name Anzeigename + Distance Abstand + Divide Teilen + Do not plot (click: plot) Nicht plotten (Klick: plotten) + Donut Ring + Double-click to edit the description Doppelklicken, um die Beschreibung zu bearbeiten + Down Nach unten + Drafting Zeichnen + Drafting Settings Zeichnungseinstellungen + Drafting Settings... Zeichnungseinstellungen... + Draw Zeichnen + Draw Order Anzeigereihenfolge + Drawing (DWG) Zeichnung (DWG) + Drawing (DXF) Zeichnung (DXF) + Drawing Limits Zeichnungsgrenzen + Drawing Utilities Zeichnungsdienstprogramme + Drawings (DWG, DXF) Zeichnungen (DWG, DXF) + Dynamic Dimensions Dynamische Bemaßungen + Dynamic Input Dynamische Eingabe + Dynamic Input (F12) Dynamische Eingabe (F12) + E O + Edit Bearbeiten + Edit Text... Text bearbeiten... + Elevation Höhenlage + Ellipse Ellipse + Elliptical Arc Ellipsenbogen + Enable Dynamic Input (F12) Dynamische Eingabe aktivieren (F12) + End Width Endbreite + End X Ende X + End Y Ende Y + End angle Endwinkel + Endpoint Endpunkt + Enter Top, Zero or Bottom. Geben Sie Top, Zero oder Bottom ein. + Enter a fit data option Geben Sie eine Option für die Anpassungsdaten ein + Enter a pattern name Geben Sie einen Musternamen ein + Enter a vertex editing option Geben Sie eine Option zur Scheitelpunktbearbeitung ein + Enter an option Geben Sie eine Option ein + Enter angle of xline Geben Sie den Winkel der Konstruktionslinie ein + Enter angle of xline (0) or Geben Sie den Winkel der Konstruktionslinie ein (0) oder + Enter area of rectangle in current units Geben Sie die Fläche des Rechtecks in den aktuellen Einheiten ein + Enter attribute prompt Geben Sie die Attributaufforderung ein + Enter attribute tag name Geben Sie den Attribut-Tag-Namen ein + Enter attribute value Geben Sie den Attributwert ein + Enter block name Geben Sie den Blocknamen ein + Enter constraint type Geben Sie den Abhängigkeitstyp ein + Enter continuity Geben Sie die Kontinuität ein + Enter default attribute value Geben Sie den Standard-Attributwert ein + Enter degree of spline Geben Sie den Grad des Splines ein + Enter delta angle Geben Sie den Delta-Winkel ein + Enter delta length or Geben Sie die Delta-Länge ein oder + Enter dimension text Geben Sie den Bemaßungstext ein + Enter dimension text (<> = measurement) Geben Sie den Bemaßungstext ein (<> = Messwert) + Enter dimension value or [name=expression] Geben Sie einen Bemaßungswert oder [name=expression] ein + Enter dimension variable name to override Geben Sie den Namen der zu übersteuernden Bemaßungsvariablen ein + Enter justification type Geben Sie den Ausrichtungstyp ein + Enter leader text Geben Sie den Führungslinientext ein + Enter mline scale Geben Sie den Multilinien-Maßstab ein + Enter mode Geben Sie den Modus ein + Enter name of block to insert Geben Sie den Namen des einzufügenden Blocks ein + Enter new text Geben Sie den neuen Text ein + Enter next point Geben Sie den nächsten Punkt ein + Enter number of columns Geben Sie die Anzahl der Spalten ein + Enter number of data rows Geben Sie die Anzahl der Datenzeilen ein + Enter number of items Geben Sie die Anzahl der Elemente ein + Enter number of items along path Geben Sie die Anzahl der Elemente entlang des Pfads ein + Enter number of sides Geben Sie die Anzahl der Seiten ein + Enter number of turns Geben Sie die Anzahl der Windungen ein + Enter percentage length Geben Sie die Länge in Prozent ein + Enter rectangle length Geben Sie die Länge des Rechtecks ein + Enter rectangle width Geben Sie die Breite des Rechtecks ein + Enter scale factor Geben Sie den Skalierfaktor ein + Enter text Geben Sie Text ein + Enter text (use \P for new paragraphs) Geben Sie Text ein (\P beginnt einen neuen Absatz) + Enter the number of segments Geben Sie die Anzahl der Segmente ein + Enter twist direction of helix Geben Sie die Drehrichtung der Helix ein + Entire drawing Gesamte Zeichnung + Equal Gleich + Erase Löschen + Exclude from new selection set Aus neuem Auswahlsatz ausschließen + Explode Auflösen + Export Exportieren + Export to PDF... In PDF exportieren... + Expression Ausdruck + Extend Dehnen + Extension Verlängerung + Extents Grenzen + Extrude Extrudieren + File Datei + File Tab Dateireiter + Fillet Abrunden + Filter Filter + Filters Filter + Find and Replace Suchen und Ersetzen + Find... Suchen... + First Erster + First commit Erster Commit + Fit Points Anpassungspunkte + Fix Fixieren + Flatten Objects Objekte abflachen + Format Format + Freehand Freihand + Freeze Frieren + Freeze Layer Layer frieren + Freeze in new viewports In neuen Ansichtsfenstern frieren + Freeze/Thaw Frieren/Tauen + Freeze/Thaw in all viewports In allen Ansichtsfenstern frieren/tauen + Freeze/Thaw in the current viewport Im aktuellen Ansichtsfenster frieren/tauen + From Von + General Allgemein + Geometric Center Geometrischer Mittelpunkt + Geometric Constraint Geometrische Abhängigkeit + Geometric Constraints Geometrische Abhängigkeiten + Geometry Geometrie + Get Variable Variable abrufen + Get View Ansicht abrufen + Global Global + Global width Globale Breite + Grab bag Sammelsurium + Gradient Farbverlauf + Gradient... Farbverlauf... + Green Grün + Grid (F7) Raster (F7) + Grid Display Rasteranzeige + Grid On (F7) Raster ein (F7) + Grid spacing Rasterabstand + Grip Mirror Mit Griffen spiegeln + Grip Rotate Mit Griffen drehen + Grip Scale Mit Griffen skalieren + Grip Stretch Mit Griffen strecken + Group Gruppieren + Group Edit Gruppe bearbeiten + Hatch Schraffur + Hatch Edit Schraffur bearbeiten + Hatch... Schraffur... + Height Höhe + Height: {height} Höhe: {height} + Helix Helix + Help Hilfe + Hide All Alle ausblenden + Hide All Constraint Bars Alle Abhängigkeitsleisten ausblenden + Hide All Dynamic Dimensions Alle dynamischen Bemaßungen ausblenden + Hide Layer List Layerliste ausblenden + Hide Palettes Paletten ausblenden + Home Startansicht + Horizontal Horizontal + HorizontalDistance Horizontaler Abstand + How to apply: Anwendungsweise: + ID Point Punktkoordinaten + Import Importieren + In Vergrößern + In-window Menu Bar Menüleiste im Fenster + Include in new selection set In neuen Auswahlsatz aufnehmen + Increment angle Inkrementwinkel + Index Color Indexfarbe + Index color: {index} Indexfarbe: {index} + Inquiry Abfrage + Insert Einfügen + Insert Block Block einfügen + Insert Column Spalte einfügen + Insert Row Zeile einfügen + Insert this block Diesen Block einfügen + Insertion Einfügepunkt + Insertion X Einfügung X + Insertion Y Einfügung Y + Insertion Z Einfügung Z + Inspect Constraints Abhängigkeiten prüfen + Inspect Drawing Zeichnung untersuchen + Interface Language Oberflächensprache + Interface Theme Oberflächendesign + Intersect Schnittmenge + Intersection Schnittpunkt + Isolate Isolieren + Isolate Layer Layer isolieren + Isometric Drafting Isometrisches Zeichnen + Join Verbinden + Join the ArtCraft Discord… Dem ArtCraft-Discord beitreten… + Join us on Discord Treten Sie uns auf Discord bei + Language Sprache + Last Letzter + Last commit Letzter Commit + Layer Layer + Layer Delete Layer samt Objekten löschen + Layer Match Layer angleichen + Layer Merge Layer zusammenführen + Layer Off Layer ausschalten + Layer Properties Layer-Eigenschaften + Layer Properties Manager Layer-Eigenschaften-Manager + Layer Properties Manager — current viewport Layer-Eigenschaften-Manager — aktuelles Ansichtsfenster + Layer State Layerstatus + Layer States Manager... Layerstatus-Manager... + Layer Tools Layer-Werkzeuge + Layer contains objects (double-click to make current) Layer enthält Objekte (doppelklicken, um ihn zum aktuellen zu machen) + Layer is empty (double-click to make current) Layer ist leer (doppelklicken, um ihn zum aktuellen zu machen) + Layers Layer + Layers Palette Layer-Palette + Layers displayed: {shown} of {total}. Current layer: {layer} Angezeigte Layer: {shown} von {total}. Aktueller Layer: {layer} + Layout Layout + Layout list Layoutliste + Leader Führungslinie + Left Links + Length Länge + Length X Länge X + Length Y Länge Y + Lengthen Länge ändern + Light Hell + Line Linie + Line delta Zeilenänderung + Linear Linear + Lines +/− Zeilen +/− + Lines added Zeilen hinzugefügt + Lines deleted Zeilen gelöscht + Linetype Linientyp + Linetype Scale Linientypfaktor + Linetype scale Linientypfaktor + Ltscale Linientypfaktor + Linetype... Linientyp... + Lineweight Linienstärke + Lineweight... Linienstärke... + List Auflisten + List Blocks Blöcke auflisten + List Dimension Styles Bemaßungsstile auflisten + List Groups Gruppen auflisten + List Layer States Layerstatus auflisten + List Layouts Layouts auflisten + List System Variables Systemvariablen auflisten + List Text Styles Textstile auflisten + Load all Alle laden + Load... Laden... + Loaded linetypes Geladene Linientypen + Lock Sperren + Lock Layer Layer sperren + Lock/Unlock Sperren/Entsperren + Loft Erhebung + MIT OR Apache-2.0. Not affiliated with Autodesk, Inc. MIT OR Apache-2.0. Keine Verbindung zu Autodesk, Inc. + MODEL MODELL + MText Mehrzeiliger Text + Magenta Magenta + Major line every Hauptlinie jede + Make Current Als aktuell festlegen + Make Object's Layer Current Layer des Objekts als aktuell festlegen + Make... Erstellen... + Match Layer Layer angleichen + Match Properties Eigenschaften übertragen + Measure Messen + Measure Distance Abstand messen + Measure Geometry Geometrie messen + Merge Cells Zellen verbinden + Merged PRs Gemergte PRs + Mid Between 2 Points Mitte zwischen 2 Punkten + Midpoint Mittelpunkt + Mirror Spiegeln + Model Modell + Model Space (in viewport) Modellbereich (im Ansichtsfenster) + Modeling Modellieren + Models Modelle + Modify Ändern + Move Verschieben + Multileader Multiführungslinie + Multileader Style... Multiführungslinienstil... + Multileader style Multiführungslinienstil + Multiline Multilinie + Multiline Text Mehrzeiliger Text + Multiline Text... Mehrzeiliger Text... + Multiple Verschiedene + Multiple Point Mehrere Punkte + My Meine + My properties: not available yet Meine Eigenschaften: noch nicht verfügbar + N N + Name Name + Name (A–Z) Name (A–Z) + Nearest Nächstgelegener + New Neu + New (metric) Neu (metrisch) + New Drawing Neue Zeichnung + New Drawing (⌘N) Neue Zeichnung (⌘N) + New Drawing... Neue Zeichnung... + New Layer Neuer Layer + New Layout Neues Layout + New VP Freeze In neuen AF frieren + New Viewports... Neue Ansichtsfenster... + New layout Neues Layout + New state name Name des neuen Status + No Nein + No blocks defined in this drawing. In dieser Zeichnung sind keine Blöcke definiert. + No contributor data was built into this copy. In diese Kopie wurden keine Mitwirkendendaten eingebaut. + No model credits were built into this copy. In diese Kopie wurden keine Modellnachweise eingebaut. + No saved layer states Keine gespeicherten Layerstatus + No selection Keine Auswahl + Node Knoten + None Keine + Not available Nicht verfügbar + Not available yet Noch nicht verfügbar + OK OK + Object Objekt + Object Snap Objektfang + Object Snap (F3) Objektfang (F3) + Object Snap On (F3) Objektfang ein (F3) + Object Snap Tracking Objektfangspur + Object Snap Tracking (F11) Objektfangspur (F11) + Object type: Objekttyp: + Off Aus + Offset Versatz + On Ein + On/Off Ein/Aus + One of the Crafting Apps by the ArtCraft team and community. Eine der Crafting Apps vom ArtCraft-Team und seiner Community. + Open (⌘O) Öffnen (⌘O) + Open Sample Drawing Beispielzeichnung öffnen + Open sample drawing Beispielzeichnung öffnen + Open... Öffnen... + Operator: Operator: + Orbit Orbit + Ordinate Koordinatenbemaßung + Ortho (F8) Ortho (F8) + Ortho Mode Ortho-Modus + Ortho Mode (F8) Ortho-Modus (F8) + Osnap Settings... Objektfang-Einstellungen... + Out Verkleinern + Override Übersteuern + PAPER PAPIER + Percent Prozent + Polar (distance < angle) Polar (Abstand < Winkel) + PRs PRs + Page Setup Manager Seiteneinrichtungs-Manager + Page Setup Manager... Seiteneinrichtungs-Manager... + Pan Schwenken + Pan Down Nach unten schwenken + Pan Left Nach links schwenken + Pan Right Nach rechts schwenken + Pan Up Nach oben schwenken + Paper Space Papierbereich + Parallel Parallel + Parameters Manager Parameter-Manager + Parametric Parametrisch + Paste Einfügen + Paste as Block Als Block einfügen + Paste to Original Coordinates In Originalkoordinaten einfügen + Path Array Pfadreihe + Pattern Muster + Perpendicular Senkrecht + Plot Plotten + Plot (click: do not plot) Plotten (Klick: nicht plotten) + Plot Preview Plotvorschau + Plot style Plotstil + Plot style attached to Plotstil zugeordnet zu + Plot style table Plotstiltabelle + Plot Style... Plotstil... + Plot Style Manager Plotstil-Manager + Plot Style Manager... Plotstil-Manager... + Plot Styles... Plotstile... + New CTB Neue CTB + New STB Neue STB + New style Neuer Stil + Reset Panel Layout Panel-Anordnung zurücksetzen + Use for this layout Für dieses Layout verwenden + Display plot styles Plotstile anzeigen + No plot style tables. Keine Plotstiltabellen. + A built-in table: editing it keeps an edited copy in the drawing. Eine integrierte Tabelle: Beim Bearbeiten wird eine bearbeitete Kopie in der Zeichnung gespeichert. + Keep an editable copy of this table in the drawing Eine bearbeitbare Kopie dieser Tabelle in der Zeichnung behalten + Layout {name}: {table} Layout {name}: {table} + Grayscale Graustufen + Screening Rasterung + Use object linetype Linientyp des Objekts verwenden + Use object lineweight Linienstärke des Objekts verwenden + Remove Entfernen + Add Hinzufügen + Open a drawing first. Öffnen Sie zuerst eine Zeichnung. + Plot table type Plottabellentyp + Color-dependent Farbbasiert + Named Benannt + Plus/minus Plus/Minus + Point Punkt + Point Filters Punktfilter + Point Style... Punktstil... + Polar Array Polare Reihe + Polar Tracking Polarspur + Polar Tracking (F10) Polarspur (F10) + Polar Tracking On (F10) Polarspur ein (F10) + Polar: {distance} < {angle}° Polar: {distance} < {angle}° + Polygon Polygon + Polygonal Polygonal + Polyline Polylinie + Position X Position X + Position Y Position Y + Position Z Position Z + Previous Zurück + Previous Layer Vorheriger Layer + Primitives Primitive + Print Drucken + Print... Drucken... + Properties Eigenschaften + Properties Inspector Eigenschafteninspektor + Properties: Eigenschaften: + Proxy Proxy-Objekt + Purge Bereinigen + Pyramid Pyramide + Quadrant Quadrant + Query Entities Objekte abfragen + Quick Schnell + Quick Dimension Schnellbemaßung + Quick Properties Schnelleigenschaften + Quick Select Schnellauswahl + Quick Select Properties Schnellauswahl-Eigenschaften + Quick Select... Schnellauswahl... + QuickCalc QuickCalc + Quit CADCraft CADCraft beenden + Radius Radius + Raster Image Rasterbild + Ray Strahl + Read-only Schreibgeschützt + Real name Echter Name + Realtime In Echtzeit + Reassociate Dimensions Bemaßungen neu zuordnen + Recent Zuletzt verwendet + Recover... Wiederherstellen... + Rectangle Rechteck + Rectangular Rechteckig + Rectangular Array Rechteckige Reihe + Red Rot + Redo Wiederholen + Redo (⇧⌘Z) Wiederholen (⇧⌘Z) + Redraw Neu zeichnen + Regen Regenerieren + Regen All Alle regenerieren + Region Region + Region/Mass Properties Regions-/Masseneigenschaften + Relative Relativ + Remove Leader Führungslinie entfernen + Remove the viewport override Ansichtsfenster-Übersteuerung entfernen + Rename Dimension Style Bemaßungsstil umbenennen + Rename Layer Layer umbenennen + Rename Layer State Layerstatus umbenennen + Rename Layout Layout umbenennen + Rename Text Style Textstil umbenennen + Rename... Umbenennen... + Repeat {command} {command} wiederholen + Requires a point (x,y, @dx,dy or @d Geben Sie den zweiten Punkt an oder + Specify second source point Geben Sie den zweiten Quellpunkt an + Specify side to offset Geben Sie die Seite für den Versatz an + Specify start angle Geben Sie den Startwinkel an + Specify start point Geben Sie den Startpunkt an + Specify start point of arc Geben Sie den Startpunkt des Bogens an + Specify start point of polyline Geben Sie den Startpunkt der Polylinie an + Specify start point of text Geben Sie den Startpunkt des Textes an + Specify starting width Geben Sie die Startbreite an + Specify starting width for next segment Geben Sie die Startbreite des nächsten Segments an + Specify tangent direction for the start point of arc Geben Sie die Tangentenrichtung für den Startpunkt des Bogens an + Specify the elevation for rectangles Geben Sie die Höhenlage für Rechtecke an + Specify thickness for rectangles Geben Sie die Stärke für Rechtecke an + Specify third point on circle Geben Sie den dritten Punkt auf dem Kreis an + Specify third point on circle: _tan to Geben Sie den dritten Punkt auf dem Kreis an: _tan zu + Specify third source point or Geben Sie den dritten Quellpunkt an oder + Specify through point Geben Sie den Durchgangspunkt an + Specify top diameter Geben Sie den oberen Durchmesser an + Specify top radius or Geben Sie den oberen Radius an oder + Specify total angle Geben Sie den Gesamtwinkel an + Specify total length or Geben Sie die Gesamtlänge an oder + Specify width for rectangles Geben Sie die Breite für Rechtecke an + Sphere Kugel + Spline Spline + Stack (type 1/2 then select) Bruch (1/2 eingeben, dann auswählen) + Standard Standard + Start Start + Start Width Startbreite + Start X Start X + Start Y Start Y + Start angle Startwinkel + Start, Center, Angle Start, Zentrum, Winkel + Start, Center, End Start, Zentrum, Ende + Start, Center, Length Start, Zentrum, Länge + Start, End, Angle Start, Ende, Winkel + Start, End, Direction Start, Ende, Richtung + Start, End, Radius Start, Ende, Radius + Status Status + Status Bar Statusleiste + Stretch Strecken + Style: Standard Stil: Standard + Subtract Subtrahieren + Sweep Sweep + Switch Drawing Zeichnung wechseln + Switch Layout Layout wechseln + Switch between model space in a viewport and paper space Zwischen Modellbereich in einem Ansichtsfenster und Papierbereich wechseln + Symmetric Symmetrisch + Synchronize Attributes Attribute synchronisieren + Toggle PICKADD (off: each pick replaces the selection) PICKADD umschalten (aus: jede Auswahl ersetzt die bisherige Auswahl) + Toggle PICKADD (on: picks add to the selection) PICKADD umschalten (ein: Auswahl wird zur bisherigen Auswahl hinzugefügt) + TOP OBEN + Table Tabelle + Table Style... Tabellenstil... + Table style Tabellenstil + Table... Tabelle... + Tan, Tan, Radius Tan, Tan, Radius + Tan, Tan, Tan Tan, Tan, Tan + Tangent Tangente + Text Text + Text Editor Texteditor + Text Height Texthöhe + Text Style... Textstil... + Text height Texthöhe + Text override Textübersteuerung + Text style Textstil + Thaw All Layers Alle Layer tauen + There is nothing here yet. Hier gibt es noch nichts. + Thickness Stärke + Time Zeit + To get started, create or open a drawing. Erstellen oder öffnen Sie eine Zeichnung, um zu beginnen. + Tool Bar Werkzeugleiste + Tool Sets Werkzeuggruppen + Tools Werkzeuge + Torus Torus + Trace Spur + Transparency Transparenz + Trim Stutzen + True Color True Color + Turn All Layers On Alle Layer einschalten + Turn Off Layer Layer ausschalten + Turn Quick Properties off (QPMODE) Schnelleigenschaften ausschalten (QPMODE) + Type Typ + Type a command Befehl eingeben + Type text; Enter starts a new paragraph Text eingeben; Eingabetaste beginnt einen neuen Absatz + UCS Icon BKS-Symbol + Undo Rückgängig + Undo (⌘Z) Rückgängig (⌘Z) + Ungroup Gruppierung aufheben + Union Vereinigungsmenge + Unisolate Layer Layer-Isolierung aufheben + Units... Einheiten... + Unlock Layer Layer entsperren + Unmerge Cells Zellen trennen + Unsaved Layer State Ungespeicherter Layerstatus + Up Nach oben + Update Aktualisieren + Use System Setting Systemeinstellung verwenden + User Benutzer + User Parameters Benutzerparameter + Username Benutzername + VP Color AF-Farbe + VP Freeze AF-Frieren + Value Wert + Value: Wert: + Version Version + Version {version} Version {version} + Vertical Vertikal + VerticalDistance Vertikaler Abstand + View Ansicht + ViewCube ViewCube + Viewport Ansichtsfenster + Viewport Layer Freeze Layer im Ansichtsfenster frieren + Viewport Properties Ansichtsfenster-Eigenschaften + Viewport {id} Ansichtsfenster {id} + Viewports Ansichtsfenster + W W + WCS ⌄ WKS ⌄ + White Weiß + Width factor Breitenfaktor + Window Fenster + Wipeout Abdeckung + Workspace Switching Arbeitsbereich wechseln + Write Block Block in Datei schreiben + Xline Konstruktionslinie + Yellow Gelb + Yes Ja + Zoom Zoom + Zoom All Zoom Alles + Zoom Extents Zoom Grenzen + Zoom In Zoom Ein + Zoom Object Zoom Objekt + Zoom Out Zoom Aus + Zoom Previous Zoom Zurück + Zoom Window Zoom Fenster + error Fehler + {contributors} · {commits} {contributors} · {commits} + {kind} (constraint {id}) {kind} (Abhängigkeit {id}) + {kind} constraint {name} = {expression} (double-click to edit) Abhängigkeit {kind} {name} = {expression} (Doppelklick zum Bearbeiten) + {name}: {distance} < {angle}° {name}: {distance} < {angle}° + ƒx New User Parameter ƒx Neuer Benutzerparameter + ΔLOC ΔZeilen + −Bin −Binär + −LOC −Zeilen + ⌘↩ to finish ⌘↩ zum Abschließen +@plural {n} commit {n} Commit|{n} Commits +@plural {n} contributor {n} Mitwirkender|{n} Mitwirkende + Drawing as bytes Zeichnung als Bytes + Services Dienste + Hide CADCraft CADCraft ausblenden + Hide Others Andere ausblenden + Accessibility Bedienungshilfen + Show System Cursor Systemzeiger anzeigen diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 1fb0937..79aea27 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -19,10 +19,12 @@ pub enum Preference { Ukrainian, #[serde(rename = "pt-BR")] BrazilianPortuguese, + #[serde(rename = "de")] + German, } impl Preference { - pub const ALL: [Self; 4] = [Self::Auto, Self::English, Self::Ukrainian, Self::BrazilianPortuguese]; + pub const ALL: [Self; 5] = [Self::Auto, Self::English, Self::Ukrainian, Self::BrazilianPortuguese, Self::German]; /// The codes a preference can be given as, for messages ("auto, en or uk"). pub fn codes() -> String { @@ -39,6 +41,7 @@ impl Preference { Self::English => "en", Self::Ukrainian => "uk", Self::BrazilianPortuguese => "pt-BR", + Self::German => "de", } } @@ -48,6 +51,7 @@ impl Preference { Self::English => "English", Self::Ukrainian => "Українська", Self::BrazilianPortuguese => "Português (Brasil)", + Self::German => "Deutsch", } } @@ -65,6 +69,7 @@ impl Preference { Self::English => "en", Self::Ukrainian => "uk", Self::BrazilianPortuguese => "pt-BR", + Self::German => "de", Self::Auto => locales.iter().find_map(|s| locale_language(s)).unwrap_or("en"), } } @@ -81,7 +86,7 @@ pub struct Language { catalog: OnceLock>, } -pub static LANGUAGES: [Language; 3] = [ +pub static LANGUAGES: [Language; 4] = [ Language { code: "en", name: "English", source: "", plural: plural_en, plural_forms: 2, catalog: OnceLock::new() }, Language { code: "uk", name: "Українська", source: include_str!("uk.tsv"), plural: plural_uk, plural_forms: 3, catalog: OnceLock::new() @@ -94,6 +99,8 @@ pub static LANGUAGES: [Language; 3] = [ plural_forms: 2, catalog: OnceLock::new(), }, + // German plurals follow the English rule: one (1), other. + Language { code: "de", name: "Deutsch", source: include_str!("de.tsv"), plural: plural_en, plural_forms: 2, catalog: OnceLock::new() }, ]; /// BCP 47 and POSIX locale tags, including `uk-UA`, `uk_UA.UTF-8` and `pt_BR.UTF-8`. diff --git a/crates/ui-egui/src/i18n/tests.rs b/crates/ui-egui/src/i18n/tests.rs index 465ce52..f0a728e 100644 --- a/crates/ui-egui/src/i18n/tests.rs +++ b/crates/ui-egui/src/i18n/tests.rs @@ -39,7 +39,7 @@ fn catalog_is_valid_and_preserves_placeholders_and_ellipses() { /// to English for what they don't cover yet; their gaps are reported, not enforced, so adding a /// command doesn't require a row in every language. const REQUIRED: &[&str] = &["uk"]; -const REPORTED: &[&str] = &["pt-BR"]; +const REPORTED: &[&str] = &["pt-BR", "de"]; fn check(language: &str, what: &str, missing: Vec) { if REQUIRED.contains(&language) { @@ -142,6 +142,9 @@ fn locale_and_saved_preference_resolution() { for tag in ["uk", "uk-UA", "uk_UA.UTF-8", "UK-ua", " uk-UA ", "uk_UA@euro"] { assert_eq!(locale_language(tag), Some("uk"), "{tag}"); } + for tag in ["de", "de-DE", "de_DE.UTF-8", "DE-at", "de-CH"] { + assert_eq!(locale_language(tag), Some("de"), "{tag}"); + } for tag in ["ua", "ukulele", "ru-RU", "", "garbage", "💙"] { assert_eq!(locale_language(tag), None, "{tag}"); } @@ -155,6 +158,8 @@ fn locale_and_saved_preference_resolution() { let locales = vec!["pl-PL".into(), "uk-UA".into(), "en-US".into()]; assert_eq!(Preference::Auto.resolve(&locales), "uk"); assert_eq!(Preference::English.resolve(&locales), "en"); + assert_eq!(Preference::German.resolve(&locales), "de"); + assert_eq!(Preference::Auto.resolve(&["de-DE".into(), "en-US".into()]), "de"); assert_eq!(Preference::Auto.resolve(&["en-US".into(), "uk-UA".into()]), "en"); assert_eq!(Preference::Auto.resolve(&[]), "en"); assert_eq!(Preference::restore(None), Preference::Auto); @@ -205,6 +210,12 @@ fn plural_forms_and_templates_preserve_inserted_user_data() { assert_eq!(format("{b}/{a}", &[("a", "А".into()), ("b", "Б".into())]), "Б/А"); }); assert_eq!(t("Layers"), "Layers"); + with_language("de", || { + assert_eq!(t("Layers"), "Layer"); + assert_eq!(count(1, "{n} contributor", "{n} contributors"), "1 Mitwirkender"); + assert_eq!(count(2, "{n} contributor", "{n} contributors"), "2 Mitwirkende"); + assert_eq!(count(11, "{n} contributor", "{n} contributors"), "11 Mitwirkende"); + }); with_language("uk", || { assert_eq!(t("Layers"), "Шари"); with_language("en", || assert_eq!(t("Layers"), "Layers")); @@ -338,6 +349,22 @@ fn dialogs_render_in_ukrainian_and_keep_their_source_ids() { } } +#[test] +fn default_fonts_cover_every_german_special_letter_in_the_catalog() { + let ctx = egui::Context::default(); + let mut output = ctx.run_ui(Default::default(), |_| {}); + output.textures_delta.clear(); + let letters: BTreeSet<_> = include_str!("de.tsv").chars().filter(|c| ('\u{00c0}'..='\u{00ff}').contains(c)).collect(); + ctx.fonts_mut(|view| { + for family in [egui::FontFamily::Proportional, egui::FontFamily::Monospace] { + let mut font = view.fonts.font(&family); + for c in &letters { + assert!(font.characters().contains_key(c), "missing {c} in {family:?}"); + } + } + }); +} + #[test] fn default_fonts_cover_every_ukrainian_letter_in_the_catalog() { let ctx = egui::Context::default(); diff --git a/docs/architecture.md b/docs/architecture.md index 17ea6e3..ed366dd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -22,7 +22,7 @@ About 57,000 lines of Rust in 12 library crates, 3 apps and `xtask` (counted 202 | L3 | `io` | 5,124 | DXF ⇄ document mapping (`dxf_read.rs`, `dxf_write.rs`, CADCraft xdata in `dxf_ext.rs`), PDF plotting, SVG and PNG export | | L3 | `dwg` | 149 | DWG through a DXF bridge: the `acadrust` crate (MPL-2.0, unmodified) converts DWG ⇄ DXF bytes; nothing else sees its types. Native only | | L4 | `engine` | 25,090 | `Session`, the command registry (`cmd/*`), command-line parser and prompt machines, object snaps and polar/ortho (`snap.rs`), selection (`select.rs`), grips (`grips.rs`), associativity (`assoc.rs`), system variables, units, undo, R-tree spatial index (`spatial.rs`) | -| L5 | `ui-egui` | 9,849 | The swappable egui front end: GPU canvas (`gpu.rs`, wgpu), menus and shortcuts (`menus.rs`), command line, palettes, Layer Properties Manager and other dialogs, ViewCube, icons drawn in code, themes, the interface string catalog (`i18n/`, English and Ukrainian), JSON control channel (`control.rs`) | +| L5 | `ui-egui` | 9,849 | The swappable egui front end: GPU canvas (`gpu.rs`, wgpu), menus and shortcuts (`menus.rs`), command line, palettes, Layer Properties Manager and other dialogs, ViewCube, icons drawn in code, themes, the interface string catalog (`i18n/`, English, Ukrainian and German), JSON control channel (`control.rs`) | | L5 | `mcp` | 559 | MCP server (JSON-RPC 2.0 over stdio) on a headless session or bridged to a running app | | app | `cadcraft` | 1,102 | Desktop app (eframe/wgpu; DirectX 12 by default on Windows) | | app | `cadcraft-cli` | 823 | `info`, `convert`, `run` (scripts), `commands`, `sample`, `mcp` | diff --git a/docs/control-protocol.md b/docs/control-protocol.md index 0d11533..9c359c3 100644 --- a/docs/control-protocol.md +++ b/docs/control-protocol.md @@ -115,7 +115,7 @@ Select a language with `engine.execute` and the UI command `ui.language`: {"id":1,"method":"engine.execute","params":{"command":"ui.language","params":{"lang":"uk"}}} ``` -Supported values are `auto`, `en` and `uk`. `ui.set` also accepts +Supported values are `auto`, `en`, `uk` and `de`. `ui.set` also accepts `{"interfaceLanguage":"uk"}`; `ui.inspect` reports the saved choice in its UI state. Invalid choices leave the current language unchanged. Menus, command labels and prompt text returned by the control channel retain their English source text. See [localization.md](localization.md). diff --git a/docs/gaps.md b/docs/gaps.md index 8a4aba0..0eb8c85 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -1,6 +1,6 @@ # Where CADCraft falls short of AutoCAD -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (SPLINE, MTEXT and MLEADER prompt options landed, #408: top-10 row 5, F1 and F10 narrowed) · **Target:** Autodesk AutoCAD 2027 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (German catalog landed, L2 narrowed; SPLINE, MTEXT and MLEADER prompt options landed, #408: top-10 row 5, F1 and F10 narrowed) · **Target:** Autodesk AutoCAD 2027 Every known shortfall, one row each, ranked within each section by user impact. This is the work list: agents pick from here (top of a section first), and remove or update a row in the same PR @@ -108,8 +108,8 @@ Detail: [localization-parity.md](localization-parity.md). | # | Gap | Est. | |---|---|---| -| L1 | Catalog covers the UI (936 rows, #36) but not engine diagnostics, CLI/MCP replies or command history | 4–6 | -| L2 | AutoCAD for Mac's 7 other languages (zh-Hans, es, fr, ja, de, ko, it) plus pt, hi, ar, id, vi from the standard's list | 40–60 + native review | +| L1 | Catalog covers the UI (989 rows, #36) but not engine diagnostics, CLI/MCP replies or command history | 4–6 | +| L2 | AutoCAD for Mac's other languages (zh-Hans, es, fr, ja, ko, it; de landed 2026-10-11) plus pt, hi, ar, id, vi from the standard's list | 35–55 + native review | | L3 | Complex-script shaping for Devanagari and other Indic scripts in drawing text; RTL (mirrored) UI. Arabic-script shaping and bidi in drawing text landed (#287) | 20–30 | | L4 | IME fixes on every platform (PRs #110–#119); vertical text styles | 6–10 | @@ -154,6 +154,7 @@ Detail: [localization-parity.md](localization-parity.md). | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | German interface catalog landed: L1 row count 936 → 989, L2 narrowed (de done; 40–60 → 35–55 h) | | 2026-10-11 | minor | SPLINE Knots/Tangency/toLerance/Object, MTEXT Height/Justify/Line spacing/Rotation/Style/Width/Columns, MLEADER spline and no-leader types and block content landed (#408): top-10 row 5, F1 and F10 narrowed | | 2026-10-11 | minor | Object snap tracking, Extension, Parallel and true Apparent Intersection landed (#379): top-10 row 3 and U1 narrowed to the leftovers | | 2026-10-10 | minor | Merged main: closed or narrowed rows for the Ukrainian catalog, UNITS dialog, shortcut display, dynamic input pointer boxes, press-drag windows, SETVAR DIM*, WIPEOUT and gradients, fmt | diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 76e2c05..923f833 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** minor (right-to-left drawing text and Arabic-script shaping, #287) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (German catalog landed: second non-English language, per-language plural rules) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0) How far CADCraft's interface and drawing text are from AutoCAD's languages. Summarised in [ROADMAP.md](../ROADMAP.md#languages); work items in [gaps.md](gaps.md#localization). @@ -23,7 +23,8 @@ shaping and right-to-left text through TrueType, vertical SHX text styles. - **A display-time string catalog** (`crates/ui-egui/src/i18n/`, landed with #36): a TSV per language (context, English source, translation, `@plural` rows), Edit → Interface Language with Auto (system language), live switching, a saved choice, and tests for coverage, placeholders - and plurals ([localization.md](localization.md)). The Ukrainian catalog has **936 rows**, + and plurals ([localization.md](localization.md)). The Ukrainian and German catalogs have + **989 rows** each, covering menus, command labels, tool groups and tooltips, the Start page, tabs, status controls, object snaps, drafting prompts, property labels and dialogs. Engine diagnostics, CLI/MCP responses and command history stay English, and uncatalogued text falls back to @@ -44,7 +45,7 @@ shaping and right-to-left text through TrueType, vertical SHX text styles. Order and columns from craftrules' progress-docs standard. Every UI percentage is **measured** from the catalogs (0 rows for every language without a catalog file). Hours are **estimated**: -about 3–5 h per language for an Opus 5.5 agent to translate the ~940 catalog rows and fix layout, +about 3–5 h per language for an Opus 5.5 agent to translate the ~990 catalog rows and fix layout, plus native review by a human; extending the catalog to the remaining English-only strings (engine diagnostics, uncatalogued text) is about 4–6 h, counted once in the first row. @@ -59,23 +60,24 @@ plus native review by a human; extending the catalog to the remaining English-on | Portuguese | pt | 0 (0%) | 0% | Latin: yes | no | none | 3–5 h | | Indonesian | id | 0 (0%) | 0% | Latin: yes | no | none | 3–5 h | | Japanese | ja | 0 (0%) | 0% | CJK glyphs render; IME pending; no vertical text | no | none | 4–6 h | -| German | de | 0 (0%) | 0% | Latin: yes (long strings will need layout checks) | no | none | 3–5 h | +| German | de | 989 catalog rows (≈ 100% of the catalog; ≈ 80% of all UI strings, estimated: engine diagnostics and uncatalogued text stay English) | dialogs and tooltips yes; command reference searchable in German | Latin: yes (bundled egui fonts cover ä ö ü Ä Ö Ü ß; long strings will need layout checks) | no native review | partial | 1–2 h | | Korean | ko | 0 (0%) | 0% | Hangul renders; macOS Korean IME fixes pending (#118, #119) | no | none | 4–6 h | | Vietnamese | vi | 0 (0%) | 0% | Latin with stacked diacritics: renders per code point, untested | no | none | 3–5 h | -| Ukrainian | uk | 936 catalog rows (≈ 100% of the catalog; ≈ 80% of all UI strings, estimated: engine diagnostics and uncatalogued text stay English) | dialogs and tooltips yes; command reference searchable in Ukrainian | Cyrillic: yes (bundled egui fonts) | translated by a contributor; no second review | partial | 2–4 h | +| Ukrainian | uk | 989 catalog rows (≈ 100% of the catalog; ≈ 80% of all UI strings, estimated: engine diagnostics and uncatalogued text stay English) | dialogs and tooltips yes; command reference searchable in Ukrainian | Cyrillic: yes (bundled egui fonts) | translated by a contributor; no second review | partial | 2–4 h | -Other languages shipped: Ukrainian (partial). AutoCAD for Mac ships 7 non-English languages -(zh-Hans, es, fr, ja, de, ko, it); CADCraft ships none of those, and Ukrainian, which AutoCAD -for Mac doesn't ship. +Other languages shipped: Ukrainian, Brazilian Portuguese and German (all partial). AutoCAD for Mac ships 7 +non-English languages (zh-Hans, es, fr, ja, de, ko, it); of those, CADCraft now ships German, +and additionally Ukrainian, which AutoCAD for Mac doesn't ship. -**Total to put all twelve at `full`:** about 60–100 Opus 5.5 hours (catalog extension 4–6 h, -eleven translations 35–55 h, complex-script shaping and RTL 30–45 h), plus native-speaker review for +**Total to put all twelve at `full`:** about 55–95 Opus 5.5 hours (catalog extension 4–6 h, +ten translations 30–50 h, complex-script shaping and RTL 30–45 h), plus native-speaker review for each language, which needs humans. Translations parallelise fully once the catalog exists. ## Revision history | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | German catalog landed: `de` preference and catalog, per-language plural rules; non-English languages 1 → 2; total hours 60–100 → 55–95 | | 2026-10-10 | minor | Right-to-left drawing text: bidi and Arabic-script shaping in TEXT and MTEXT (#287) | | 2026-10-10 | minor | Ukrainian catalog landed on main (#36): catalog infrastructure exists, Ukrainian partial; total hours 70–110 → 60–100 | | 2026-10-10 | major | First localization measurement against AutoCAD 2027 for Mac's bundle localizations | diff --git a/docs/localization.md b/docs/localization.md index 9c3bceb..bd376fc 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -1,6 +1,8 @@ # Interface languages Choose **Edit → Interface Language** and select **Auto (system language)**, **English**, +**Українська**, or **Deutsch**. The interface updates without restarting, including the native +macOS menus. **Українська**, or **Português (Brasil)**. The interface updates without restarting, including the native macOS menus. The choice is saved with the other interface preferences (`cadcraft.prefs`, beside the theme): eframe storage on the desktop, browser local storage on the web. Installations without a saved @@ -8,6 +10,10 @@ choice use Auto. Auto uses the first supported language in the operating system's preferred locales, or the browser's `navigator.languages` on the web. Ukrainian tags such as `uk-UA` and `uk_UA.UTF-8` +resolve to `uk`, German tags such as `de-DE` and `de_AT.UTF-8` resolve to `de`; unsupported +languages fall back to English. Set `CADCRAFT_LOCALE=uk-UA` to +override the desktop's locale for a launch. An explicit saved English, Ukrainian or German +choice takes precedence over that override. resolve to `uk`, and Portuguese tags such as `pt-BR` and `pt_BR.UTF-8` resolve to `pt-BR`; unsupported languages fall back to English. Set `CADCRAFT_LOCALE=uk-UA` to override the desktop's locale for a launch. An explicit saved English, Ukrainian or Brazilian Portuguese choice @@ -20,11 +26,17 @@ Automation can select the language through the existing control channel: ``` The `ui.set` method also accepts `{"interfaceLanguage":"uk"}`. Supported values are `auto`, +`en`, `uk`, and `de`; invalid values are rejected without changing the current selection. +Resetting palettes keeps the language choice. `en`, `uk`, and `pt-BR`; invalid values are rejected without changing the current selection. Resetting palettes keeps the language choice. ## Translation coverage +Ukrainian and German cover command and menu labels, tool groups and tooltips, the Start page, +file and model-space tabs, status controls, object snaps, drafting prompts, property labels, +dialogs, and the About window's controls. The command reference can be searched by English +command ID, English label, or translated label. The Ukrainian and Brazilian Portuguese catalogs cover command and menu labels, tool groups and tooltips, the Start page, file and model-space tabs, status controls, object snaps, drafting prompts, property labels, dialogs, and the About window's controls. The command reference can be searched by English command @@ -37,8 +49,9 @@ by the engine. CLI/MCP/control responses, engine diagnostics and command history English. Uncatalogued text also falls back to English. Number formatting and the operating system's own file-picker controls follow the existing behavior. -The bundled egui fonts cover Ukrainian, including `Ґґ Єє Іі Її`; the translation adds no font -assets and works on the web without system fonts. +The bundled egui fonts cover Ukrainian, including `Ґґ Єє Іі Її`, and German, including +`ÄÖÜ äöü ß`; the translations add no font +assets and work on the web without system fonts. ## Adding translations @@ -47,8 +60,12 @@ The implementation follows the display-time catalog pattern used by [PdfCraft #106](https://github.com/storytold/pdfcraft/pull/106), and [FilmCraft #238](https://github.com/storytold/filmcraft/pull/238). Its code is local to CADCraft. +- `crates/ui-egui/src/i18n/uk.tsv` and `crates/ui-egui/src/i18n/de.tsv` are UTF-8 with three + tab-separated columns: - `crates/ui-egui/src/i18n/uk.tsv` and `pt_br.tsv` are UTF-8 with three tab-separated columns: `context`, `English source`, and `translation`. Ordinary labels have an empty context. + `@plural` entries hold Ukrainian `one|few|many` forms for integer counts; German uses + `one|other|other` (singular/plural only, so the third form repeats the plural). `@plural` entries hold the language's plural forms for integer counts: Ukrainian `one|few|many`, Brazilian Portuguese `one|other` (0 and 1 are `one`). - Register a new catalog in `i18n::LANGUAGES`, add its preference variant and code/name, diff --git a/docs/roadmap.md b/docs/roadmap.md index 320e576..fbb0d3d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -86,7 +86,7 @@ agents that built each milestone, are in the progress log of [ROADMAP.md](../ROA | M10 | Performance: 1M entities at 60 fps, large DWG loads | ≈ 60% (internal numbers only) | 20–40 | | M11 | 3D: UCS, orbit, visual styles, solids, surfaces, meshes, sections, rendering | ≈ 2% | 300–450 | | M12 | Automation: AutoLISP, SCRIPT, action recorder, sheet sets, Express Tools | ≈ 15% (MCP, CLI, control channel done) | 130–220 | -| M13 | 1.0 polish: preferences, workspaces, localisation, accessibility, signed packages, docs | ≈ 15% (signed packages for every platform exist; themes done; string catalog with Ukrainian, live language switching, #36) | 110–170 | +| M13 | 1.0 polish: preferences, workspaces, localisation, accessibility, signed packages, docs | ≈ 15% (signed packages for every platform exist; themes done; string catalog with Ukrainian and German, live language switching, #36) | 110–170 | | — | Geometry precision (cross-cutting, see [geometry-parity.md](geometry-parity.md)) | ≈ 40% | 70–110 | | — | AI features | ≈ 0% in-app | 40–80 | | | **Remaining to full parity** | | **≈ 1,300–2,100** |