Complete language support to all GUI tabs#873
Conversation
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 openstudiocoalition#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>
…penstudiocoalition#680) 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 openstudiocoalition#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>
…#680) 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>
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
This is awesome @Ski90Moo! I will check this out! |
|
Thank you @macumber. It is rough, but a good start. I would like your feedback on the html issue. |
There was a problem hiding this comment.
Pull request overview
This PR expands internationalization across the OpenStudio Application UI by wrapping user-facing strings with Qt translation APIs and adding a significantly more complete Spanish translation as a proof of concept (Issue #680). It also introduces tests to validate the .ts file structure/content and (optionally) runtime .qm translation loading.
Changes:
- Wrapped many GUI string literals in
tr()/QCoreApplication::translate()across tabs, inspectors, and grid views. - Added bilingual display formatting for SDK-driven names (eg. Output Variables, IDD fields) to show
Translated (English)when non-English. - Added a new translation-focused GTest suite and wired it into the app test target.
Reviewed changes
Copilot reviewed 98 out of 100 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared_gui_components/WorkflowView.cpp | Translates “drop measure” placeholder text. |
| src/shared_gui_components/WorkflowController.cpp | Translates section headers for measure categories. |
| src/shared_gui_components/OSGridController.cpp | Translates “Custom” category label and apply-button text. |
| src/shared_gui_components/LocalLibraryView.cpp | Translates tooltips/button labels in the local library footer. |
| src/shared_gui_components/LocalLibraryController.cpp | Translates taxonomy category names at render time. |
| src/openstudio_lib/WindowMaterialSimpleGlazingSystemInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialShadeInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialScreenInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialGlazingRefractionExtinctionMethodInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialGlazingInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialGasMixtureInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialGasInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialDaylightRedirectionDeviceInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WindowMaterialBlindInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/WaterUseEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/VRFGraphicsItems.cpp | Translates VRF drag/drop placeholder labels. |
| src/openstudio_lib/VariablesTabView.cpp | Adds translated+bilingual output variable display and localized frequency display with English data values. |
| src/openstudio_lib/ThermalZonesTabView.cpp | Translates main tab title. |
| src/openstudio_lib/ThermalZonesGridView.cpp | Translates grid headers/categories via QCoreApplication::translate. |
| src/openstudio_lib/SteamEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/StandardsInformationMaterialWidget.cpp | Translates standards/measure-tags labels. |
| src/openstudio_lib/StandardsInformationConstructionWidget.cpp | Translates standards/measure-tags labels. |
| src/openstudio_lib/SpaceTypesTabView.cpp | Translates main tab title. |
| src/openstudio_lib/SpaceTypesGridView.cpp | Translates headers/categories/filter labels; some tooltips still hardcoded. |
| src/openstudio_lib/SpacesTabController.cpp | Translates spaces sub-tab titles. |
| src/openstudio_lib/SpacesSurfacesGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SpacesSubtabGridView.cpp | Translates filter labels; stores English keys in combo box data for SDK values. |
| src/openstudio_lib/SpacesSubsurfacesGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SpacesSpacesGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SpacesShadingGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SpacesLoadsGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SpacesInteriorPartitionsGridView.cpp | Translates grid headers/categories. |
| src/openstudio_lib/SimSettingsTabController.cpp | Translates “Simulation Settings” tab title. |
| src/openstudio_lib/ServiceWaterGridItems.cpp | Translates tooltips and drop-zone placeholder text. |
| src/openstudio_lib/ScriptsTabView.cpp | Translates “Measures” tab title and sync button strings. |
| src/openstudio_lib/SchedulesTabView.cpp | Translates schedules sub-tab title. |
| src/openstudio_lib/SchedulesTabController.cpp | Translates schedules sub-tab titles. |
| src/openstudio_lib/ScheduleSetInspectorView.cpp | Translates schedule set inspector section labels. |
| src/openstudio_lib/ScheduleOthersView.cpp | Translates “Schedule Others” type names returned to the list view. |
| src/openstudio_lib/ScheduleOthersController.cpp | Translates unsupported-action message text. |
| src/openstudio_lib/ScheduleFileInspectorView.cpp | Translates labels and attempts to translate separator choices (but bind() will overwrite). |
| src/openstudio_lib/ScheduleDialog.cpp | Translates dialog labels and “None/unitless” strings. |
| src/openstudio_lib/ScheduleDayView.hpp | Adds Q_DECLARE_TR_FUNCTIONS for QGraphicsItem subclasses to enable tr(). |
| src/openstudio_lib/ScheduleDayView.cpp | Translates schedule day UI strings/tooltips and keyboard prompt text. |
| src/openstudio_lib/ScheduleConstantInspectorView.cpp | Translates labels (one includes leading whitespace in the source string). |
| src/openstudio_lib/ScheduleCompactInspectorView.cpp | Translates labels. |
| src/openstudio_lib/RunTabView.cpp | Translates run tab title, button/checkbox labels, and status text. |
| src/openstudio_lib/ResultsTabView.cpp | Translates Results UI labels and some report names; “Custom Report N” uses concatenation. |
| src/openstudio_lib/ResultsTabController.cpp | Translates “Results Summary” tab title. |
| src/openstudio_lib/RefrigerationGraphicsItems.cpp | Translates refrigeration drop-zone placeholder text. |
| src/openstudio_lib/PeopleInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/OtherEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/OSItemSelectorButtons.cpp | Translates toolbar button tooltips. |
| src/openstudio_lib/OSDropZone.hpp | Changes default text arg to empty so ctor can apply translated default. |
| src/openstudio_lib/OSDropZone.cpp | Applies translated default “Drag From Library” when text is empty. |
| src/openstudio_lib/OSDocument.cpp | Translates left-side main tab button labels. |
| src/openstudio_lib/MaterialsView.cpp | Translates materials category names returned to list view. |
| src/openstudio_lib/MaterialRoofVegetationInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/MaterialNoMassInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/MaterialInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/MaterialAirGapInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/LuminaireInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/LoopLibraryDialog.cpp | Translates HVAC library dialog titles/buttons/system names. |
| src/openstudio_lib/LoadsView.cpp | Translates loads category names returned to list view. |
| src/openstudio_lib/LightsInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/library/geometry_editor_start.html | Adds an in-HTML Spanish translation dictionary + DOM rewrite for headings/paragraphs. |
| src/openstudio_lib/InternalMassInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/HVACSystemsTabView.cpp | Translates main tab title. |
| src/openstudio_lib/HVACSystemsController.cpp | Translates system selector entries and HVAC type labels; translates some drop-zone text. |
| src/openstudio_lib/HotWaterEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/GridItem.cpp | Translates drop-zone placeholder and “Supply/Demand Equipment” labels. |
| src/openstudio_lib/GeometryTabController.cpp | Translates geometry tab title and sub-tab titles. |
| src/openstudio_lib/GeometryPreviewView.cpp | Injects locale into embedded web content; translates some UI strings. |
| src/openstudio_lib/GeometryEditorView.cpp | Injects locale into embedded editor; translates most UI strings and some dialogs. |
| src/openstudio_lib/GasEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/FacilityTabView.cpp | Translates facility tab title. |
| src/openstudio_lib/FacilityTabController.cpp | Translates facility sub-tab titles. |
| src/openstudio_lib/FacilityStoriesGridView.cpp | Translates grid headers/categories and filter label. |
| src/openstudio_lib/FacilityShadingGridView.cpp | Translates grid headers/categories and uses English keys in filter combo data. |
| src/openstudio_lib/FacilityExteriorEquipmentGridView.cpp | Translates grid headers/categories and view titles. |
| src/openstudio_lib/ElectricEquipmentInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/ConstructionsView.cpp | Translates constructions category names returned to list view. |
| src/openstudio_lib/ConstructionsTabController.cpp | Translates constructions sub-tab titles and main tab title. |
| src/openstudio_lib/ConstructionInternalSourceInspectorView.cpp | Translates inspector labels and drop-zone text (and file gained a BOM). |
| src/openstudio_lib/ConstructionInspectorView.cpp | Translates inspector labels and drop-zone text. |
| src/openstudio_lib/ConstructionFfactorGroundFloorInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/ConstructionCfactorUndergroundWallInspectorView.cpp | Translates inspector labels (and file gained a BOM). |
| src/openstudio_lib/ConstructionAirBoundaryInspectorView.cpp | Translates inspector labels and comments (and file gained a BOM). |
| src/openstudio_lib/BuildingInspectorView.cpp | Translates building inspector labels. |
| src/openstudio_app/test/Translation_GTest.cpp | Adds tests to validate .ts content and optionally .qm runtime translation. |
| src/openstudio_app/CMakeLists.txt | Adds Translation_GTest.cpp to the test sources. |
| src/model_editor/InspectorGadget.cpp | Adds bilingual IDD field display names with runtime translation lookup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| m_combobox = new OSComboBox2(); | ||
| m_combobox->setFixedWidth(200); | ||
| connect(m_combobox, static_cast<void (OSComboBox2::*)(const QString&)>(&OSComboBox2::currentTextChanged), this, &VariableListItem::indexChanged); | ||
| populateFrequencyComboBox(m_combobox); | ||
| if (m_variable) { | ||
| // m_combobox->bind(*m_variable, "reportingFrequency"); | ||
| m_combobox->bind<std::string>( | ||
| *m_variable, static_cast<std::string (*)(const std::string&)>(&openstudio::toString), | ||
| std::bind(&model::OutputVariable::reportingFrequencyValues), std::bind(&model::OutputVariable::reportingFrequency, m_variable.get_ptr()), | ||
| std::bind(&model::OutputVariable::setReportingFrequency, m_variable.get_ptr(), std::placeholders::_1), | ||
| boost::optional<NoFailAction>(std::bind(&model::OutputVariable::resetReportingFrequency, m_variable.get_ptr())), | ||
| boost::optional<BasicQuery>(std::bind(&model::OutputVariable::isReportingFrequencyDefaulted, m_variable.get_ptr()))); | ||
| const int idx = m_combobox->findData(QString::fromStdString(m_variable->reportingFrequency())); | ||
| if (idx >= 0) { | ||
| m_combobox->setCurrentIndex(idx); | ||
| } |
| m_columnSeparator = new OSComboBox2(); | ||
| m_columnSeparator->addItem("Comma"); | ||
| m_columnSeparator->addItem("Tab"); | ||
| m_columnSeparator->addItem("Space"); | ||
| m_columnSeparator->addItem("Semicolon"); | ||
| m_columnSeparator->addItem(tr("Comma")); | ||
| m_columnSeparator->addItem(tr("Tab")); | ||
| m_columnSeparator->addItem(tr("Space")); | ||
| m_columnSeparator->addItem(tr("Semicolon")); | ||
| m_columnSeparator->setEnabled(true); | ||
| vLayout->addWidget(m_columnSeparator); |
| checkbox->setToolTip(tr("Check to select all rows")); | ||
| connect(checkbox.data(), &OSSelectAllCheckBox::checkStateChanged, this, &SpaceTypesGridController::onSelectAllStateChanged); | ||
| connect(this, &SpaceTypesGridController::gridRowSelectionChanged, checkbox.data(), &OSSelectAllCheckBox::onGridRowSelectionChanged); | ||
| addSelectColumn(Heading(QString(SELECTED), false, false, checkbox), "Check to select this row", DataSource(allLoads, true)); |
| m_geometryDiagnosticsBox->setText(tr("Geometry Diagnostics")); | ||
| m_geometryDiagnosticsBox->setChecked(verboseOutput); | ||
| m_geometryDiagnosticsBox->setToolTip( | ||
| "Enables adjacency issues. Enables checks for Surface/Space Convexity, due to this the ThreeJS export is slightly slower"); |
| m_refreshBtn(new QPushButton(tr("Refresh"))), | ||
| m_previewBtn(new QPushButton(tr("Preview OSM"))), | ||
| m_mergeBtn(new QPushButton(tr("Merge with Current OSM"))), | ||
| m_debugBtn(new QPushButton("Debug")) { |
| if ((startingIndex == -1) || (endingIndex == -1) || (startingIndex >= endingIndex)) { | ||
| m_comboBox->addItem(QString("Custom Report ") + QString::number(num), fullPathString); | ||
| m_comboBox->addItem(tr("Custom Report ") + QString::number(num), fullPathString); | ||
| } else { |
| @@ -1,4 +1,4 @@ | |||
| /*********************************************************************************************************************** | |||
| /*********************************************************************************************************************** | |||
| // Value | ||
|
|
||
| label = new QLabel(" Value: "); | ||
| label = new QLabel(tr(" Value: ")); | ||
| label->setObjectName("H2"); | ||
| mainGridLayout->addWidget(label, row++, 0); |
| @@ -1474,7 +1486,7 @@ void EditorWebView::mergeExport() { | |||
| QMessageBox::warning(this, "Merging Models", errorsAndWarnings); | |||
| // | ||
| // To add or refine translations: add entries to the IDD context in | ||
| // OpenStudioApp_<lang>.ts and recompile with lrelease — no C++ changes needed. | ||
| static QString iddFieldDisplayName(const std::string& englishName) { |
There was a problem hiding this comment.
This is really cool, I just wonder how we will be able to maintain this. The Translation test could possibly loop over each IddObject and verify that there is an entry for each one?
Same concern for the OutputVariables
There was a problem hiding this comment.
That was one my concerns as well. I did a handful of them, but I could imagine the list of these objects would be enormous and difficult to maintain. It also makes the .ts file huge; no small task for the language contributors to review. I envision it would be more of a reactionary process whereby the contributors review the general GUI stuff, but we would get feedback as users stumble upon poorly translated objects.
The OutputVariables should be complete though. I will look into modifying the Translation test.
| <meta charset=utf-8> | ||
| <title>OpenStudio Geometry Editor</title> | ||
| <script> | ||
| var _translations = { |
There was a problem hiding this comment.
I'm not as thrilled about this, I would prefer something using the Qt facilities
There was a problem hiding this comment.
I will look into moving the translations out of the HTML into the .ts file.
| @@ -1049,6 +1134,81 @@ Si le gustaría ver la AplicaciónOpenStudio traducido a algun otro lenguaje, le | |||
| <source>Online BCL</source> | |||
| <translation type="vanished">BCL en Linea</translation> | |||
There was a problem hiding this comment.
Could be a separate pull request but we probably need github actions to detect vanished or unfinished strings to maintain this
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Material, "Materials")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Material_NoMass, "No Mass Materials")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Material_AirGap, "Air Gap Materials")); | ||
| auto tr = [](const char* s) { return QCoreApplication::translate("openstudio::MaterialsView", s).toStdString(); }; |
There was a problem hiding this comment.
Can we just change the return type to std::vector<std::pair<IddObjectType, QString>> and use the normal tr? I don't like shadowing it with this local definition.
| {IddObjectType::OS_Schedule_Constant, "Schedule Constant"}, | ||
| {IddObjectType::OS_Schedule_Compact, "Schedule Compact"}, | ||
| {IddObjectType::OS_Schedule_File, "Schedule File"}, | ||
| {IddObjectType::OS_Schedule_Constant, QCoreApplication::translate("ScheduleOthersView", "Schedule Constant").toStdString()}, |
There was a problem hiding this comment.
Let's try changing the return type to std::vector<std::pair<IddObjectType, QString>> in these situations
| const QStringList monthNames = {tr("January"), tr("February"), tr("March"), tr("April"), | ||
| tr("May"), tr("June"), tr("July"), tr("August"), | ||
| tr("September"), tr("October"), tr("November"), tr("December")}; | ||
| m_monthLabel->setText((month >= 1 && month <= 12) ? monthNames[month - 1] : QString::fromStdString(monthOfYear(month).valueName())); |
There was a problem hiding this comment.
| const QStringList monthNames = {tr("January"), tr("February"), tr("March"), tr("April"), | |
| tr("May"), tr("June"), tr("July"), tr("August"), | |
| tr("September"), tr("October"), tr("November"), tr("December")}; | |
| m_monthLabel->setText((month >= 1 && month <= 12) ? monthNames[month - 1] : QString::fromStdString(monthOfYear(month).valueName())); | |
| const QStringList monthNames = {"January", "February", "March", "April", | |
| "May"), "June"), "July", "August", | |
| "September", "October", "November", "December"}; | |
| m_monthLabel->setText((month >= 1 && month <= 12) ? tr(monthNames[month - 1]) : QString::fromStdString(monthOfYear(month).valueName())); |
Would this be better? I don't really know?
| #include <QCheckBox> | ||
| #include <QCoreApplication> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesInteriorPartitionsGridController", s) |
There was a problem hiding this comment.
Let's not use defines, just use the normal tr pattern, we need to keep consistent to maintain this
| #define SELECTED "All" | ||
| #define DISPLAYNAME "Display Name" | ||
| #define CADOBJECTID "CAD Object ID" | ||
| #define NAME TR("Space Name") |
There was a problem hiding this comment.
| #define NAME TR("Space Name") | |
| #define NAME tr("Space Name") |
Can we use the normal tr here and remove define TR(s) above?
| #include <QCheckBox> | ||
| #include <QCoreApplication> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesShadingGridController", s) |
There was a problem hiding this comment.
Let's avoid this if we can
| #include <QCheckBox> | ||
| #include <QCoreApplication> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesSpacesGridController", s) |
| #include <QCheckBox> | ||
| #include <QCoreApplication> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesSubsurfacesGridController", s) |
| #include <QLabel> | ||
| #include <QLineEdit> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesSubtabGridView", s) |
| #include <QCheckBox> | ||
| #include <QCoreApplication> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::SpacesSurfacesGridController", s) |
|
|
||
| #define NAME "Space Type Name" | ||
| #define SELECTED "All" | ||
| #define TR(s) QCoreApplication::translate("openstudio::SpaceTypesGridController", s) |
| #include <QSettings> | ||
| #include <QTimer> | ||
|
|
||
| #define TR(s) QCoreApplication::translate("openstudio::ThermalZonesGridController", s) |
| } | ||
|
|
||
| // i18n translation support | ||
| var _translations = { |
There was a problem hiding this comment.
Not sure we want to do this
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Construction, "Constructions")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Construction_AirBoundary, "Air Boundary Constructions")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_Construction_InternalSource, "Internal Source Constructions")); | ||
| auto tr = [](const char* s) { return QCoreApplication::translate("openstudio::ConstructionsView", s).toStdString(); }; |
There was a problem hiding this comment.
Let's change return type to std::vector<std::pair<IddObjectType, QString>> to avoid re-defining tr
| #define SELECTED "All" | ||
| #define DISPLAYNAME "Display Name" | ||
| #define CADOBJECTID "CAD Object ID" | ||
| #define TR(s) QCoreApplication::translate("openstudio::FacilityExteriorEquipmentGridController", s) |
There was a problem hiding this comment.
Let's avoid defining a TR macro, just do #define NAME tr("Name") instead
| #define SELECTED "All" | ||
| #define DISPLAYNAME "Display Name" | ||
| #define CADOBJECTID "CAD Object ID" | ||
| #define TR(s) QCoreApplication::translate("openstudio::FacilityShadingGridController", s) |
There was a problem hiding this comment.
Let's avoid this if we can
| #define SELECTED "All" | ||
| #define DISPLAYNAME "Display Name" | ||
| #define CADOBJECTID "CAD Object ID" | ||
| #define TR(s) QCoreApplication::translate("openstudio::FacilityStoriesGridController", s) |
There was a problem hiding this comment.
Let's avoid this if we can
| m_view->setPage(m_page); // note, view does not take ownership of page | ||
|
|
||
| { | ||
| QWebEngineScript langScript; |
There was a problem hiding this comment.
I wonder if there is a more canonical way do this.
|
|
||
| // Inject locale so geometry_preview.html can select translations | ||
| { | ||
| QWebEngineScript langScript; |
There was a problem hiding this comment.
I wonder if there is a more canonical way to do this?
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_InternalMass_Definition, "Internal Mass Definitions")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_WaterUse_Equipment_Definition, "Water Use Equipment Definitions")); | ||
| result.push_back(std::make_pair<IddObjectType, std::string>(IddObjectType::OS_HotWaterEquipment_Definition, "Hot Water Equipment Definitions")); | ||
| auto tr = [](const char* s) { return QCoreApplication::translate("openstudio::LoadsView", s).toStdString(); }; |
There was a problem hiding this comment.
Change return type to avoid re-defining tr
| myModelList->addModelObjectType(IddObjectType::OS_Construction_AirBoundary, "Air Boundary Constructions"); | ||
| myModelList->addModelObjectType(IddObjectType::OS_Construction, "Constructions"); | ||
| myModelList->addModelObjectCategoryPlaceholder("Constructions"); | ||
| myModelList->addModelObjectType(IddObjectType::OS_Construction_WindowDataFile, tr("Window Data File Constructions").toStdString()); |
There was a problem hiding this comment.
This is fine, could also change addModelObjectType to take a QString
|
|
||
| public: | ||
| explicit OSDropZone(OSVectorController* vectorController, const QString& text = "Drag From Library", const QSize& size = QSize(0, 0), | ||
| explicit OSDropZone(OSVectorController* vectorController, const QString& text = QString(), const QSize& size = QSize(0, 0), |
| // used on column headers, and other grid widgets | ||
|
|
||
| #define SELECTED "All" | ||
| #define TR_CASE(s) QCoreApplication::translate("openstudio::RefrigerationCaseGridController", s) |
There was a problem hiding this comment.
Let's avoid adding this TR_CASE macro
|
|
||
| static void populateFrequencyComboBox(QComboBox* combo) { | ||
| // Uses the same context as VariablesList::tr() so existing translations apply. | ||
| const auto tr = [](const char* s) { |
There was a problem hiding this comment.
Let's avoid redefining tr
There was a problem hiding this comment.
This tab will require extra testing
|
|
||
| auto* header = new DarkGradientHeader(); | ||
| header->label->setText(item->name()); | ||
| header->label->setText(QCoreApplication::translate("TaxonomyCategories", item->name().toUtf8().constData())); |
| void OSGridController::setCategoriesAndFields() { | ||
| std::vector<QString> fields; | ||
| std::pair<QString, std::vector<QString>> categoryAndFields = std::make_pair(QString("Custom"), fields); | ||
| std::pair<QString, std::vector<QString>> categoryAndFields = std::make_pair(QCoreApplication::translate("openstudio::OSGridController", "Custom"), fields); |
There was a problem hiding this comment.
We can just use tr if we add Q_DECLARE_TR_FUNCTIONS to the class right?
|
This looks pretty good @Ski90Moo, thanks! I found a few anti-patterns I'd like to avoid, hopefully you can address those. I am also not sure if I like the approach for the html files, maybe we skip those for now? I made an internal PR at #874 which seems to complete the build CI actions, maybe those are failing here because this is an external PR? In any case, you can fix the cppcheck and Clang Format failures on your PR. |
|
One last question, did you get Claude to actually do the string translations, or just to add the |
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:
translations/OpenStudioApp_es.ts grows from ~200 to 3017 entries.
New languages only require a new .ts file with no further C++ changes.
The exception is the Geometry tab HTML files (geometry_editor_start.html and geometry_preview.html) each contain a hardcoded JavaScript dictionary keyed by locale code. We could:
Option A — Keep the Geometry tab HTML as an exception requiring separate edits.
Option B — Improve the architecture (better): Have the C++ side inject the locale into the HTML page at load time via QWebEnginePage::runJavaScript(), and move the translations out of the HTML into the .ts file.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com