Skip to content

Complete language support to all GUI tabs (#876)#877

Merged
macumber merged 62 commits into
developfrom
ski90moo-develop
Jun 21, 2026
Merged

Complete language support to all GUI tabs (#876)#877
macumber merged 62 commits into
developfrom
ski90moo-develop

Conversation

@macumber

Copy link
Copy Markdown
Collaborator

Duplicates #873 from @Ski90Moo on internal branch for CI

Ski90Moo and others added 30 commits May 4, 2026 15:21
Wraps all user-facing string literals in the three Schedules sub-tabs
(Schedule Sets, Schedules, Other Schedules) with Qt tr() calls to enable
multi-language support, addressing issue #680.

Files modified:
- ScheduleSetInspectorView: 12 section/field labels
- SchedulesView: 23 strings across ScheduleTabContent, ScheduleTabDefault,
  NewProfileView, DefaultScheduleDayView, SpecialScheduleDayView,
  ScheduleRuleView, ScheduleRulesetNameWidget, MonthView
- ScheduleFileInspectorView: 15 field labels and combo box items
- ScheduleDialog: 10 strings including runtime-appended values
- ScheduleDayView + .hpp: 6 button/label strings; adds
  Q_DECLARE_TR_FUNCTIONS to 3 QGraphicsItem subclasses for tooltip tr()
- ScheduleCompactInspectorView: 2 labels
- ScheduleConstantInspectorView: 2 labels
- ScheduleOthersController: 1 error message
- ScheduleOthersView: 3 sidebar type names via QCoreApplication::translate()
- MainRightColumnController: 9 sidebar nav strings via tr().toStdString()

Adds Spanish translations for all new strings to OpenStudioApp_es.ts.
Day-of-week single-letter buttons S/T marked unfinished pending source-level
disambiguation (tr("S", "Sunday") etc.).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
)

Wraps user-facing string literals with tr() across all major tabs and
adds a complete Spanish (es) translation file as proof of concept for
multi-language support, addressing issue #680.

Tabs covered: Site/Weather Data, Construction Sets, Materials, Schedules,
Thermal Zones, Space Types, Loads, Facility, HVAC Systems, Inspector panel
IDD fields, Output Variables (1051 names), Simulation Settings, Measures,
Run Simulation, and Results Summary.

Key patterns established:
- tr() for compile-time strings in Q_OBJECT classes
- QCoreApplication::translate(IDD/OutputVariables/TaxonomyCategories)
  for runtime strings from the OpenStudio SDK and taxonomy.xml
- addItem(tr(Display), EnglishData) + currentData() for model-bound
  combo boxes where SDK values must stay in English
- Bilingual display format for IDD fields and output variable names so
  engineers can cross-reference EnergyPlus documentation without switching
  the application language

translations/OpenStudioApp_es.ts grows from ~200 to 3017 entries.
New languages only require a new .ts file with no further C++ changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Translation_GTest.cpp to the OpenStudioApp test target, covering:

Translation_ts suite (no build-path dependency, uses .ts source file):
- ValidXml: verifies OpenStudioApp_es.ts parses as well-formed XML
- HasExpectedContexts: checks all new translation contexts are present
  (IDD, OutputVariables, TaxonomyCategories, SimSettingsView, RunView, etc.)
- TranslationCountIsSubstantial: guards against accidental file truncation
- IddContextHasEntries: IDD context has >50 field-name translations
- OutputVariablesContextHasEntries: OutputVariables context has >=1000 entries
- TaxonomyCategoriesContextHasEntries: taxonomy categories are present

Translation_qm suite (requires compiled .qm, skipped gracefully if absent):
- QmFileLoads: QTranslator::load() succeeds for OpenStudioApp_es.qm
- SpanishSimSettingsStringsTranslated: spot-checks Simulation Settings labels
- SpanishRunViewStringsTranslated: spot-checks Run Simulation labels
- TaxonomyCategoriesTranslated: spot-checks library sidebar category names
- OutputVariablesSampleTranslated: spot-checks output variable name translations
- EnglishStringsReturnedWithoutTranslator: verifies English fallback when no
  QTranslator is installed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…680)

- Expand language support from Spanish proof-of-concept to 18 languages:
  Arabic, Catalan, German, Greek, Persian, French, Hebrew, Hindi, Indonesian,
  Italian, Japanese, Korean, Polish, Portuguese, Turkish, Vietnamese,
  Simplified Chinese (new), plus Spanish
- Add Portuguese, Korean, Turkish, Indonesian to Preferences > Language menu
  with proper QAction wiring in MainMenu.cpp/.hpp
- Fix RTL layout direction: setLayoutDirection(RightToLeft) for ar/fa/he,
  reset to LeftToRight when switching away from RTL languages
- Enable Arabic in Language menu (was commented out)
- Translate ~7,000 strings per language via Claude Haiku Batches API:
  UI strings, IDD field names, and OutputVariable display names
- Fix apply_translations counter-shift bug: use same regex pattern as
  extract_unfinished so XML comments and <location/> tags don't cause
  wrong translations to be assigned to wrong source strings
- Escape HTML entities (bare <, >, & and named entities like &aacute;)
  in all translation files to produce valid XML for lrelease
- Add batch translation scripts: translate_all_languages.py,
  translate_new_languages.py, retranslate_stubborn.py, recover_batches.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap hardcoded strings in GeometryEditorView.cpp (Debug button) and
  GeometryPreviewView.cpp (Geometry Diagnostics checkbox tooltip) with tr()
- Remove UTF-8 BOM from 27 inspector view .cpp files introduced by editor
- Run clang-format on all modified C++ files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Translation_ts.IddCoverageForAllFields GTest that loops over every
IddObject in the OpenStudio IDD (via IddFactory) and verifies each field
name has a corresponding source entry in the IDD translation context of
OpenStudioApp_es.ts.

When the SDK adds new IDD objects/fields and the .ts file is not updated,
the test fails with a list of missing field names. The fix is to run
add_idd_skeleton.py then translate_skeleton.py to restore coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend IddCoverageAllLanguages (renamed from IddCoverageForAllFields) to
iterate every OpenStudioApp_*.ts file in the translations directory rather
than only Spanish. For each language file the test independently extracts
the IDD context source strings and reports any field names missing from
that specific file, so drift after an SDK update is caught per-language.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds translation_check.yml workflow that runs on every PR and push to
master/develop. After running lupdate6 with -locations none:

- git diff detects if any .ts file changed — meaning strings were added
  to or removed from the C++ source without the translation files being
  updated.
- ci/check_translations.py classifies the diff: new type="unfinished"
  stubs (new tr() calls needing translation) vs type="obsolete" entries
  (tr() calls removed from source). Reports actionable fix instructions
  for each case and exits 1 so CI fails.

If the diff is empty, all .ts files are in sync and CI passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…680)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…th tr()

- OSGridController: use tr() directly (class has Q_OBJECT, context matches)
- VariablesTabView: remove translate lambda, use QCoreApplication::translate
  with a named ctx string to avoid redefining tr in free function scope

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Explicit include required; cannot rely on transitive pulls from other Qt
headers on all build configurations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Not part of the project source; was accidentally committed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bring in tr() coverage for dialogs added since the last PR #873 update:
- Apply Measure Now, OSDialog buttons, Measure select prompt
- Online BCL / Find Measures, Find Components category tree (tid_api.xml)
- Component panel section headers and metadata row labels
- Sync Measures dialog, BCL taxonomy categories
- Change Default Libraries dialog
- Preferences > Change External Tools dialog
- Refrigeration, VRF, and other grid-view drop zone strings
- Measures sidebar labels, Python CLI tooltip
- Additional grid views across Facility, Spaces, Thermal Zones tabs

All 19 language .ts files updated; 0 unfinished entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 'Units Conversion' Yes/No dialog shown by DView when opening an
Energy+ SQL file is untranslatable via Qt's .ts system (external binary).

Add tr() wrappers for both strings and translate into all 18 supported
languages. The OpenStudio dialog and --ip/--si CLI forwarding are
commented out pending an updated DView build (Ski90Moo/wex
feat/ip-units-cli-flag); DView's own English prompt remains active
in the meantime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the mandatory pipeline for adding/updating translations,
including the fix_and_unvanish.py step that must follow every lupdate
run. Also covers common mistakes (lambda wrapping, currentText() with
model setters, unescaped ampersands).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps all user-facing string literals in the three Schedules sub-tabs
(Schedule Sets, Schedules, Other Schedules) with Qt tr() calls to enable
multi-language support, addressing issue #680.

Files modified:
- ScheduleSetInspectorView: 12 section/field labels
- SchedulesView: 23 strings across ScheduleTabContent, ScheduleTabDefault,
  NewProfileView, DefaultScheduleDayView, SpecialScheduleDayView,
  ScheduleRuleView, ScheduleRulesetNameWidget, MonthView
- ScheduleFileInspectorView: 15 field labels and combo box items
- ScheduleDialog: 10 strings including runtime-appended values
- ScheduleDayView + .hpp: 6 button/label strings; adds
  Q_DECLARE_TR_FUNCTIONS to 3 QGraphicsItem subclasses for tooltip tr()
- ScheduleCompactInspectorView: 2 labels
- ScheduleConstantInspectorView: 2 labels
- ScheduleOthersController: 1 error message
- ScheduleOthersView: 3 sidebar type names via QCoreApplication::translate()
- MainRightColumnController: 9 sidebar nav strings via tr().toStdString()

Adds Spanish translations for all new strings to OpenStudioApp_es.ts.
Day-of-week single-letter buttons S/T marked unfinished pending source-level
disambiguation (tr("S", "Sunday") etc.).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
)

Wraps user-facing string literals with tr() across all major tabs and
adds a complete Spanish (es) translation file as proof of concept for
multi-language support, addressing issue #680.

Tabs covered: Site/Weather Data, Construction Sets, Materials, Schedules,
Thermal Zones, Space Types, Loads, Facility, HVAC Systems, Inspector panel
IDD fields, Output Variables (1051 names), Simulation Settings, Measures,
Run Simulation, and Results Summary.

Key patterns established:
- tr() for compile-time strings in Q_OBJECT classes
- QCoreApplication::translate(IDD/OutputVariables/TaxonomyCategories)
  for runtime strings from the OpenStudio SDK and taxonomy.xml
- addItem(tr(Display), EnglishData) + currentData() for model-bound
  combo boxes where SDK values must stay in English
- Bilingual display format for IDD fields and output variable names so
  engineers can cross-reference EnergyPlus documentation without switching
  the application language

translations/OpenStudioApp_es.ts grows from ~200 to 3017 entries.
New languages only require a new .ts file with no further C++ changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Translation_GTest.cpp to the OpenStudioApp test target, covering:

Translation_ts suite (no build-path dependency, uses .ts source file):
- ValidXml: verifies OpenStudioApp_es.ts parses as well-formed XML
- HasExpectedContexts: checks all new translation contexts are present
  (IDD, OutputVariables, TaxonomyCategories, SimSettingsView, RunView, etc.)
- TranslationCountIsSubstantial: guards against accidental file truncation
- IddContextHasEntries: IDD context has >50 field-name translations
- OutputVariablesContextHasEntries: OutputVariables context has >=1000 entries
- TaxonomyCategoriesContextHasEntries: taxonomy categories are present

Translation_qm suite (requires compiled .qm, skipped gracefully if absent):
- QmFileLoads: QTranslator::load() succeeds for OpenStudioApp_es.qm
- SpanishSimSettingsStringsTranslated: spot-checks Simulation Settings labels
- SpanishRunViewStringsTranslated: spot-checks Run Simulation labels
- TaxonomyCategoriesTranslated: spot-checks library sidebar category names
- OutputVariablesSampleTranslated: spot-checks output variable name translations
- EnglishStringsReturnedWithoutTranslator: verifies English fallback when no
  QTranslator is installed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…680)

- Expand language support from Spanish proof-of-concept to 18 languages:
  Arabic, Catalan, German, Greek, Persian, French, Hebrew, Hindi, Indonesian,
  Italian, Japanese, Korean, Polish, Portuguese, Turkish, Vietnamese,
  Simplified Chinese (new), plus Spanish
- Add Portuguese, Korean, Turkish, Indonesian to Preferences > Language menu
  with proper QAction wiring in MainMenu.cpp/.hpp
- Fix RTL layout direction: setLayoutDirection(RightToLeft) for ar/fa/he,
  reset to LeftToRight when switching away from RTL languages
- Enable Arabic in Language menu (was commented out)
- Translate ~7,000 strings per language via Claude Haiku Batches API:
  UI strings, IDD field names, and OutputVariable display names
- Fix apply_translations counter-shift bug: use same regex pattern as
  extract_unfinished so XML comments and <location/> tags don't cause
  wrong translations to be assigned to wrong source strings
- Escape HTML entities (bare <, >, & and named entities like &aacute;)
  in all translation files to produce valid XML for lrelease
- Add batch translation scripts: translate_all_languages.py,
  translate_new_languages.py, retranslate_stubborn.py, recover_batches.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap hardcoded strings in GeometryEditorView.cpp (Debug button) and
  GeometryPreviewView.cpp (Geometry Diagnostics checkbox tooltip) with tr()
- Remove UTF-8 BOM from 27 inspector view .cpp files introduced by editor
- Run clang-format on all modified C++ files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Translation_ts.IddCoverageForAllFields GTest that loops over every
IddObject in the OpenStudio IDD (via IddFactory) and verifies each field
name has a corresponding source entry in the IDD translation context of
OpenStudioApp_es.ts.

When the SDK adds new IDD objects/fields and the .ts file is not updated,
the test fails with a list of missing field names. The fix is to run
add_idd_skeleton.py then translate_skeleton.py to restore coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ski90Moo and others added 6 commits May 30, 2026 22:18
Not part of the project source; was accidentally committed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bring in tr() coverage for dialogs added since the last PR #873 update:
- Apply Measure Now, OSDialog buttons, Measure select prompt
- Online BCL / Find Measures, Find Components category tree (tid_api.xml)
- Component panel section headers and metadata row labels
- Sync Measures dialog, BCL taxonomy categories
- Change Default Libraries dialog
- Preferences > Change External Tools dialog
- Refrigeration, VRF, and other grid-view drop zone strings
- Measures sidebar labels, Python CLI tooltip
- Additional grid views across Facility, Spaces, Thermal Zones tabs

All 19 language .ts files updated; 0 unfinished entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 'Units Conversion' Yes/No dialog shown by DView when opening an
Energy+ SQL file is untranslatable via Qt's .ts system (external binary).

Add tr() wrappers for both strings and translate into all 18 supported
languages. The OpenStudio dialog and --ip/--si CLI forwarding are
commented out pending an updated DView build (Ski90Moo/wex
feat/ip-units-cli-flag); DView's own English prompt remains active
in the meantime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the mandatory pipeline for adding/updating translations,
including the fix_and_unvanish.py step that must follow every lupdate
run. Also covers common mistakes (lambda wrapping, currentText() with
model setters, unescaped ampersands).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In Qt 6 the QMenuBar inherits the parent QMainWindow dark background
(#2C3233) instead of using the native platform style. Add explicit
QMenuBar rules alongside the existing MainWindow stylesheet so the
menu bar stays white with black text regardless of locale or restart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In Qt 6 the QMenuBar inherits the parent QMainWindow dark background
(#2C3233) instead of using the native platform style. Add explicit
QMenuBar rules alongside the existing MainWindow stylesheet so the
menu bar stays white with black text regardless of locale or restart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@macumber macumber force-pushed the ski90moo-develop branch from 81c1241 to dbd5fd5 Compare May 31, 2026 17:45
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Ski90Moo

Ski90Moo commented Jun 1, 2026

Copy link
Copy Markdown

Fixed the Clang Format failure — switched to clang-format 18.1.3 (matching CI) and applied formatting to the 5 PR-touched files. Pushed in 0585d1f.

Ski90Moo and others added 18 commits June 1, 2026 17:55
Add the six Python scripts referenced in TRANSLATION_WORKFLOW.md and the
IddCoverageAllLanguages test but absent from the PR:

- fix_and_unvanish.py        — un-vanish translated entries; promote unfinished
- translate_all_languages.py — batch-translate new strings into all 18 languages
- retranslate_stubborn.py    — re-translate remaining empty entries
- recover_batches.py         — re-poll batch IDs after network failure
- add_idd_skeleton.py        — add missing IDD field names as unfinished stubs
- translate_skeleton.py      — translate IDD context stubs via Claude batch API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add OpenStudioApp_{id,ko,pt,tr}.ts to qt6_add_translations TS_FILES so
  the .qm files are compiled and deployed on all platforms, not just when
  pre-built .qm files happen to be present in the source tree.
- Add post-build copy commands for Qt system translations (qt_ko, qt_tr,
  qt_pt_BR, qtbase_*) and WebEngine pak files for the four new languages.
  Indonesian follows the same commented-out pattern as Hindi/Vietnamese/Greek
  since Qt does not ship qt_id / qtbase_id translations.
- Remove stale moc_*.cpp entry from .gitignore; Qt 6 + CMake always
  generates moc files in the build directory, never in the source tree.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IDD field display (InspectorGadget.cpp):
- Replace 'Translation (English)' inline format with HTML: translated name
  on first line, English original in small gray italics on second line.
  Non-English speakers can cross-reference EnergyPlus docs without switching
  languages; tooltip approach was rejected as cursor-precision-dependent.

Whitespace restoration (fix_and_unvanish.py + all .ts files):
- Add Step 4 to fix_and_unvanish.py: restore leading/trailing spaces in
  translations to match source strings (stripped by .strip() in translation
  scripts). Fixes ~6900 Qt Linguist whitespace-mismatch warnings.

Newline fixes (all .ts files):
- For LoopLibraryDialog strings: remove hard \n breaks from both C++ source
  and all translations now that the dialog is resizable.
- For all other \n-containing strings (grid headers, drop zones, etc.):
  apply proportional-position insertion to restore missing \n in translations.

LoopLibraryDialog resize (LoopLibraryDialog.cpp):
- Replace setFixedSize(280,584) with setMinimumSize(280,400) + setSizeGripEnabled.
- Add setWordWrap(true) and remove Qt::AlignLeft from addWidget so label
  stretches to full item width and reflows correctly on resize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per jmarrec review: add a callout at the top noting this doc covers the
AI-assisted bootstrap pipeline, and linking to the wiki for the preferred
human-translation workflow via Qt Linguist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
translations/CMakeLists.txt line 151 was copying vi.pak (Vietnamese)
instead of de.pak. Copy-paste error from the Vietnamese section
directly above it. Audited all 18 language blocks — only mismatch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fix_and_unvanish.py: add Step 5 to escape bare XML chars (<, >, &) in
  finished translation text, preventing lrelease parse errors
- translate_all_languages.py: add --lang and --skip-contexts CLI args;
  extract_unfinished now marks skipped-context entries so IDs stay stable
- add_language_to_menu.py: new script that automates all 5 C++ touch
  points when wiring a new language into MainMenu.hpp/.cpp

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a six-step "Adding a new language" section covering the C++ menu
wiring script, CMakeLists.txt entries, translate_all_languages.py update,
and the standard pipeline. Expand the helper scripts table with
add_language_to_menu.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apply fix_and_unvanish.py Step 5 retroactively: escape bare > characters
as &gt; in finished translation text for consistency. Bare < characters
(the hard XML error) were not present in the existing 18 files, but > is
normalized here for correctness and to prevent future lrelease surprises.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces two new scripts for improving machine translations of
EnergyPlus output variable names using BigLadder I/O Reference context:

- scrape_output_var_definitions.py: crawls all 52 BigLadder I/O Reference
  group pages (h3/h4/h5 headings) to extract variable definitions and units
  into output_var_definitions.json (2,733 entries)

- retranslate_output_vars.py: re-translates the OutputVariables context in
  .ts files using definition-aware prompts, canonical category/sub-category
  splitting, and a three-level Zone hierarchy (Zone: SubCat: Measurement)

Translation improvements for ES and FR:
- Category:Measurement structure prevents word-order mangling across the
  category boundary
- ~51% of variables receive full definition context from the I/O Reference
- Template fallback covers fuel-type variants (Boiler <Fuel Type>, etc.)
- Zone variables use three-level prompting for consistency

Also adds output_var_definitions.json, output_vars_comparison_v3.csv, and
output_var_zone_splits.csv as reference artifacts for quality review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all helper scripts, data files, and comparison CSVs from the repo
root into translations/. Delete 8 superseded one-shot scripts. Add three
new retranslate scripts (gui_strings, idd_fields, output_vars) with a
--mode option (unfinished|all) so finished human translations are never
overwritten by default. Add Part 3 (IDD fields) to update_comparison_csvs.py.
Standardise CSV names (drop version suffix, rename other_contexts →
gui_comparison). Update TRANSLATION_WORKFLOW.md throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e translations

Surgically restore 133 ES and 191 FR human-provided translations from
origin/develop that had been overwritten by retranslate scripts run
without the --mode unfinished guard. All machine-translated slots retain
the improved definition-aware translations. Also fixes a pre-existing bug
where the FR file had the Spanish text for "Purge unused objects".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Retranslate ar, ca, de, el, fa, he, hi, id, it, ja, ko, pl, pt, tr, vi, and
zh_CN end-to-end with the definition-aware IDD/OutputVariables/GUI pipeline
from ac13885, while preserving every existing human translation verbatim.
es and fr get the same XML-escaping and trailing-whitespace normalization
that fix_and_unvanish.py applies elsewhere. This represents a significant
quality improvement (translation drift) over the prior machine translations,
which lacked field-definition and category context.

Fix a regex crossing bug in extract_unfinished/apply_translations:
<source>([\s\S]+?)</source> could backtrack across an already-translated
message into the next <source>/<translation> pair. This silently dropped
~110 entries per language (in the 11 languages with pre-existing
translations) from the batch entirely, or translated them but never applied
the result. Switch to <source>([^<]+)</source> -- .ts source text is
XML-escaped and can never contain a literal '<', so the match can no longer
cross message boundaries. Also stop apply_translations' tag-stripping step
from emptying out translations that are themselves bracketed placeholders
(e.g. "<New Profile>" -> "<Nuevo Perfil>"), which had left one entry stuck
in ar/id/ko/pt/tr.

Add recover_batch.py, a general-purpose --lang/--batch-id tool for applying
results from a batch that timed out or failed to download, replacing the
one-off recover_*.py scripts written during this effort. Document it in
TRANSLATION_WORKFLOW.md with a new "Recovering a stuck or failed batch"
section, and point translate_all_languages.py's polling-timeout message at
it.

All 18 .ts files now show 0 vanished / 0 unfinished entries after
fix_and_unvanish.py, and `cmake --build . --config Release` succeeds with
the regenerated .qm files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# Conflicts:
#	src/openstudio_lib/ScheduleFileInspectorView.cpp
@macumber macumber merged commit ef230a7 into develop Jun 21, 2026
12 checks passed
@macumber macumber deleted the ski90moo-develop branch June 21, 2026 04:34
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants