Skip to content

Complete language support to all GUI tabs#873

Open
Ski90Moo wants to merge 4 commits into
openstudiocoalition:developfrom
Ski90Moo:develop
Open

Complete language support to all GUI tabs#873
Ski90Moo wants to merge 4 commits into
openstudiocoalition:developfrom
Ski90Moo:develop

Conversation

@Ski90Moo
Copy link
Copy Markdown

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.

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

Ski90Moo and others added 4 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 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>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 10, 2026

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@Ski90Moo
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request May 10, 2026
@macumber
Copy link
Copy Markdown
Collaborator

This is awesome @Ski90Moo! I will check this out!

@Ski90Moo
Copy link
Copy Markdown
Author

Thank you @macumber. It is rough, but a good start. I would like your feedback on the html issue.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines 89 to +97
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);
}
Comment on lines 133 to 139
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);
Comment on lines +1061 to 1064
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")) {
Comment on lines 317 to 319
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 @@
/***********************************************************************************************************************
/***********************************************************************************************************************
Comment on lines 58 to 62
// 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) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not as thrilled about this, I would prefer something using the Qt facilities

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(); };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try changing the return type to std::vector<std::pair<IddObjectType, QString>> in these situations

Comment on lines +2017 to +2020
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()));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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)
Copy link
Copy Markdown
Collaborator

@macumber macumber May 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#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)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid this if we can

#include <QCheckBox>
#include <QCoreApplication>

#define TR(s) QCoreApplication::translate("openstudio::SpacesSpacesGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can

#include <QCheckBox>
#include <QCoreApplication>

#define TR(s) QCoreApplication::translate("openstudio::SpacesSubsurfacesGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can

#include <QLabel>
#include <QLineEdit>

#define TR(s) QCoreApplication::translate("openstudio::SpacesSubtabGridView", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can

#include <QCheckBox>
#include <QCoreApplication>

#define TR(s) QCoreApplication::translate("openstudio::SpacesSurfacesGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can


#define NAME "Space Type Name"
#define SELECTED "All"
#define TR(s) QCoreApplication::translate("openstudio::SpaceTypesGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can

#include <QSettings>
#include <QTimer>

#define TR(s) QCoreApplication::translate("openstudio::ThermalZonesGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid if we can

}

// i18n translation support
var _translations = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(); };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid this if we can

m_view->setPage(m_page); // note, view does not take ownership of page

{
QWebEngineScript langScript;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there is a more canonical way do this.


// Inject locale so geometry_preview.html can select translations
{
QWebEngineScript langScript;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(); };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed default?

// used on column headers, and other grid widgets

#define SELECTED "All"
#define TR_CASE(s) QCoreApplication::translate("openstudio::RefrigerationCaseGridController", s)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid redefining tr

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be simplified?

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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just use tr if we add Q_DECLARE_TR_FUNCTIONS to the class right?

@macumber
Copy link
Copy Markdown
Collaborator

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.

@macumber
Copy link
Copy Markdown
Collaborator

One last question, did you get Claude to actually do the string translations, or just to add the tr wrappers throughout the app? Do you think Claude could do the string translations for all the languages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants