From e118470b5f25759142ecd5a336be8f41dfbf3cb6 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 16 Mar 2026 18:36:21 -0600 Subject: [PATCH 01/26] First draft --- .github/prompts/update-docs.prompt.md | 369 ++++++++++++++++++ developer/doc/architecture.md | 275 +++++++++++++ developer/doc/ci/jenkins.md | 60 +++ developer/doc/ci/overview.md | 138 +++++++ developer/doc/ci/scripts.md | 143 +++++++ developer/doc/ci/workflows/app_build.md | 139 +++++++ .../doc/ci/workflows/check_osm_versions.md | 64 +++ developer/doc/ci/workflows/cla.md | 65 +++ developer/doc/ci/workflows/clangformat.md | 77 ++++ developer/doc/ci/workflows/cppcheck.md | 85 ++++ .../doc/ci/workflows/export_standards_data.md | 82 ++++ developer/doc/ci/workflows/manual_cli_test.md | 92 +++++ developer/doc/ci/workflows/release_notes.md | 76 ++++ .../classes/bimserver/BIMserverConnection.md | 111 ++++++ .../doc/classes/bimserver/ProjectImporter.md | 100 +++++ .../classes/model_editor/AccessPolicyStore.md | 69 ++++ .../classes/model_editor/InspectorDialog.md | 72 ++++ .../classes/model_editor/InspectorGadget.md | 96 +++++ .../classes/openstudio_app/OpenStudioApp.md | 115 ++++++ .../doc/classes/openstudio_app/StartupView.md | 60 +++ .../openstudio_lib/ConstructionsController.md | 61 +++ .../GeometryEditorController.md | 85 ++++ .../openstudio_lib/HVACSystemsController.md | 124 ++++++ .../classes/openstudio_lib/HVACSystemsView.md | 60 +++ .../openstudio_lib/InspectorController.md | 66 ++++ .../MainRightColumnController.md | 111 ++++++ .../openstudio_lib/MainTabController.md | 105 +++++ .../doc/classes/openstudio_lib/MainWindow.md | 109 ++++++ .../openstudio_lib/MaterialsController.md | 50 +++ .../openstudio_lib/ModelObjectListView.md | 74 ++++ .../doc/classes/openstudio_lib/OSAppBase.md | 110 ++++++ .../doc/classes/openstudio_lib/OSDocument.md | 116 ++++++ .../doc/classes/openstudio_lib/OSDropZone.md | 96 +++++ .../doc/classes/openstudio_lib/OSItem.md | 109 ++++++ .../openstudio_lib/OSVectorController.md | 111 ++++++ .../classes/openstudio_lib/OSWebEnginePage.md | 87 +++++ .../openstudio_lib/ResultsTabController.md | 57 +++ .../openstudio_lib/RunTabController.md | 76 ++++ .../openstudio_lib/SchedulesController.md | 66 ++++ .../openstudio_lib/SpaceTypesController.md | 54 +++ .../openstudio_lib/ThermalZonesController.md | 46 +++ .../shared_gui_components/BCLMeasureDialog.md | 60 +++ .../classes/shared_gui_components/BaseApp.md | 63 +++ .../BuildingComponentDialog.md | 63 +++ .../LocalLibraryController.md | 93 +++++ .../shared_gui_components/MeasureManager.md | 92 +++++ .../shared_gui_components/OSGridController.md | 100 +++++ .../shared_gui_components/OSGridView.md | 73 ++++ developer/doc/libraries/bimserver.md | 133 +++++++ developer/doc/libraries/model_editor.md | 108 +++++ developer/doc/libraries/openstudio_app.md | 97 +++++ developer/doc/libraries/openstudio_lib.md | 173 ++++++++ developer/doc/libraries/qtwinmigrate.md | 71 ++++ .../doc/libraries/shared_gui_components.md | 177 +++++++++ developer/doc/libraries/utilities.md | 65 +++ 55 files changed, 5429 insertions(+) create mode 100644 .github/prompts/update-docs.prompt.md create mode 100644 developer/doc/architecture.md create mode 100644 developer/doc/ci/jenkins.md create mode 100644 developer/doc/ci/overview.md create mode 100644 developer/doc/ci/scripts.md create mode 100644 developer/doc/ci/workflows/app_build.md create mode 100644 developer/doc/ci/workflows/check_osm_versions.md create mode 100644 developer/doc/ci/workflows/cla.md create mode 100644 developer/doc/ci/workflows/clangformat.md create mode 100644 developer/doc/ci/workflows/cppcheck.md create mode 100644 developer/doc/ci/workflows/export_standards_data.md create mode 100644 developer/doc/ci/workflows/manual_cli_test.md create mode 100644 developer/doc/ci/workflows/release_notes.md create mode 100644 developer/doc/classes/bimserver/BIMserverConnection.md create mode 100644 developer/doc/classes/bimserver/ProjectImporter.md create mode 100644 developer/doc/classes/model_editor/AccessPolicyStore.md create mode 100644 developer/doc/classes/model_editor/InspectorDialog.md create mode 100644 developer/doc/classes/model_editor/InspectorGadget.md create mode 100644 developer/doc/classes/openstudio_app/OpenStudioApp.md create mode 100644 developer/doc/classes/openstudio_app/StartupView.md create mode 100644 developer/doc/classes/openstudio_lib/ConstructionsController.md create mode 100644 developer/doc/classes/openstudio_lib/GeometryEditorController.md create mode 100644 developer/doc/classes/openstudio_lib/HVACSystemsController.md create mode 100644 developer/doc/classes/openstudio_lib/HVACSystemsView.md create mode 100644 developer/doc/classes/openstudio_lib/InspectorController.md create mode 100644 developer/doc/classes/openstudio_lib/MainRightColumnController.md create mode 100644 developer/doc/classes/openstudio_lib/MainTabController.md create mode 100644 developer/doc/classes/openstudio_lib/MainWindow.md create mode 100644 developer/doc/classes/openstudio_lib/MaterialsController.md create mode 100644 developer/doc/classes/openstudio_lib/ModelObjectListView.md create mode 100644 developer/doc/classes/openstudio_lib/OSAppBase.md create mode 100644 developer/doc/classes/openstudio_lib/OSDocument.md create mode 100644 developer/doc/classes/openstudio_lib/OSDropZone.md create mode 100644 developer/doc/classes/openstudio_lib/OSItem.md create mode 100644 developer/doc/classes/openstudio_lib/OSVectorController.md create mode 100644 developer/doc/classes/openstudio_lib/OSWebEnginePage.md create mode 100644 developer/doc/classes/openstudio_lib/ResultsTabController.md create mode 100644 developer/doc/classes/openstudio_lib/RunTabController.md create mode 100644 developer/doc/classes/openstudio_lib/SchedulesController.md create mode 100644 developer/doc/classes/openstudio_lib/SpaceTypesController.md create mode 100644 developer/doc/classes/openstudio_lib/ThermalZonesController.md create mode 100644 developer/doc/classes/shared_gui_components/BCLMeasureDialog.md create mode 100644 developer/doc/classes/shared_gui_components/BaseApp.md create mode 100644 developer/doc/classes/shared_gui_components/BuildingComponentDialog.md create mode 100644 developer/doc/classes/shared_gui_components/LocalLibraryController.md create mode 100644 developer/doc/classes/shared_gui_components/MeasureManager.md create mode 100644 developer/doc/classes/shared_gui_components/OSGridController.md create mode 100644 developer/doc/classes/shared_gui_components/OSGridView.md create mode 100644 developer/doc/libraries/bimserver.md create mode 100644 developer/doc/libraries/model_editor.md create mode 100644 developer/doc/libraries/openstudio_app.md create mode 100644 developer/doc/libraries/openstudio_lib.md create mode 100644 developer/doc/libraries/qtwinmigrate.md create mode 100644 developer/doc/libraries/shared_gui_components.md create mode 100644 developer/doc/libraries/utilities.md diff --git a/.github/prompts/update-docs.prompt.md b/.github/prompts/update-docs.prompt.md new file mode 100644 index 000000000..1989c78b8 --- /dev/null +++ b/.github/prompts/update-docs.prompt.md @@ -0,0 +1,369 @@ +--- +mode: agent +description: Update and maintain the OpenStudio Application developer documentation in developer/doc/ +tools: + - read_file + - grep_search + - file_search + - semantic_search + - replace_string_in_file + - create_file + - multi_replace_string_in_file +applyTo: | + developer/doc/**/*.md + src/**/*.hpp + src/**/*.cpp + .github/workflows/**/*.yml + Jenkinsfile_* + ci/** + CMakeLists.txt + src/**/CMakeLists.txt +--- + +# Documentation Maintenance Agent + +You are a senior developer on the OpenStudio Application project. Your task is to keep the documentation in `developer/doc/` accurate and complete. All documentation is written in Markdown with embedded Mermaid diagrams. The audience is the internal development team (C++/Qt background assumed). + +--- + +## 1. Documentation Structure Map + +Every source file has a corresponding documentation home. Consult this map before editing any doc: + +``` +developer/doc/ +├── architecture.md ← CMakeLists.txt, README.md, all module CMakeLists.txt +├── libraries/ +│ ├── openstudio_app.md ← src/openstudio_app/CMakeLists.txt + headers +│ ├── openstudio_lib.md ← src/openstudio_lib/CMakeLists.txt + headers +│ ├── shared_gui_components.md ← src/shared_gui_components/CMakeLists.txt + headers +│ ├── model_editor.md ← src/model_editor/CMakeLists.txt + headers +│ ├── bimserver.md ← src/bimserver/CMakeLists.txt + headers +│ ├── utilities.md ← src/utilities/CMakeLists.txt +│ └── qtwinmigrate.md ← src/qtwinmigrate/CMakeLists.txt +├── classes/ +│ ├── openstudio_app/ +│ │ ├── OpenStudioApp.md ← src/openstudio_app/OpenStudioApp.hpp/.cpp +│ │ └── StartupView.md ← src/openstudio_app/StartupView.hpp/.cpp +│ ├── openstudio_lib/ +│ │ ├── OSAppBase.md ← src/openstudio_lib/OSAppBase.hpp +│ │ ├── OSDocument.md ← src/openstudio_lib/OSDocument.hpp +│ │ ├── MainWindow.md ← src/openstudio_lib/MainWindow.hpp +│ │ ├── MainTabController.md ← src/openstudio_lib/MainTabController.hpp +│ │ ├── MainRightColumnController.md ← src/openstudio_lib/MainRightColumnController.hpp +│ │ ├── OSVectorController.md ← src/openstudio_lib/OSVectorController.hpp +│ │ ├── OSItem.md ← src/openstudio_lib/OSItem.hpp +│ │ ├── OSDropZone.md ← src/openstudio_lib/OSDropZone.hpp +│ │ ├── HVACSystemsController.md ← src/openstudio_lib/HVACSystemsController.hpp +│ │ ├── HVACSystemsView.md ← src/openstudio_lib/HVACSystemsView.hpp +│ │ ├── GeometryEditorController.md ← src/openstudio_lib/GeometryEditorController.hpp +│ │ ├── ConstructionsController.md ← src/openstudio_lib/ConstructionsController.hpp +│ │ ├── MaterialsController.md ← src/openstudio_lib/MaterialsController.hpp +│ │ ├── SchedulesController.md ← src/openstudio_lib/SchedulesController.hpp +│ │ ├── SpaceTypesController.md ← src/openstudio_lib/SpaceTypesController.hpp +│ │ ├── ThermalZonesController.md ← src/openstudio_lib/ThermalZonesController.hpp +│ │ ├── RunTabController.md ← src/openstudio_lib/RunTabController.hpp +│ │ ├── ResultsTabController.md ← src/openstudio_lib/ResultsTabController.hpp +│ │ ├── OSWebEnginePage.md ← src/openstudio_lib/OSWebEnginePage.hpp +│ │ ├── InspectorController.md ← src/openstudio_lib/InspectorController.hpp +│ │ └── ModelObjectListView.md ← src/openstudio_lib/ModelObjectListView.hpp +│ ├── shared_gui_components/ +│ │ ├── BaseApp.md ← src/shared_gui_components/BaseApp.hpp +│ │ ├── OSGridController.md ← src/shared_gui_components/OSGridController.hpp +│ │ ├── OSGridView.md ← src/shared_gui_components/OSGridView.hpp +│ │ ├── MeasureManager.md ← src/shared_gui_components/MeasureManager.hpp +│ │ ├── BCLMeasureDialog.md ← src/shared_gui_components/BCLMeasureDialog.hpp +│ │ ├── LocalLibraryController.md ← src/shared_gui_components/LocalLibraryController.hpp +│ │ └── BuildingComponentDialog.md ← src/shared_gui_components/BuildingComponentDialog.hpp +│ ├── model_editor/ +│ │ ├── InspectorGadget.md ← src/model_editor/InspectorGadget.hpp +│ │ ├── InspectorDialog.md ← src/model_editor/InspectorDialog.hpp +│ │ └── AccessPolicyStore.md ← src/model_editor/AccessPolicyStore.hpp +│ └── bimserver/ +│ ├── BIMserverConnection.md ← src/bimserver/BIMserverConnection.hpp +│ └── ProjectImporter.md ← src/bimserver/ProjectImporter.hpp +└── ci/ + ├── overview.md ← .github/workflows/*.yml, Jenkinsfile_*, ci/*, CMake/CodeSigning.cmake + ├── jenkins.md ← Jenkinsfile_linux, Jenkinsfile_osx, Jenkinsfile_windows + ├── scripts.md ← ci/* scripts + └── workflows/ + ├── app_build.md ← .github/workflows/app_build.yml + ├── check_osm_versions.md ← .github/workflows/check_osm_versions.yml + ├── cla.md ← .github/workflows/cla.yml + ├── clangformat.md ← .github/workflows/clangformat.yml + ├── cppcheck.md ← .github/workflows/cppcheck.yml + ├── export_standards_data.md ← .github/workflows/export_standards_data.yml + ├── manual_cli_test.md ← .github/workflows/manual_cli_test.yml + └── release_notes.md ← .github/workflows/release_notes.yml +``` + +--- + +## 2. Trigger Conditions + +Update documentation when ANY of the following changes occur: + +| Change | Docs to update | +|---|---| +| `.hpp` or `.cpp` file modified in a documented class | Corresponding class `.md` in `developer/doc/classes/` | +| New class added matching library conventions (see §6) | Create new class `.md`; add entry to library `.md` | +| Class deleted | Delete class `.md`; remove from library `.md` | +| `CMakeLists.txt` in a module changes (new deps, new targets) | Corresponding library `.md` + `architecture.md` dependency graph | +| Top-level `CMakeLists.txt` changes (version, new sub-project) | `architecture.md` | +| `.github/workflows/*.yml` changes | Corresponding `developer/doc/ci/workflows/*.md` + `ci/overview.md` | +| New workflow added | Create new workflow `.md`; add entry to `ci/overview.md` | +| `Jenkinsfile_*` changes | `developer/doc/ci/jenkins.md` + `ci/overview.md` | +| `ci/` script changes | `developer/doc/ci/scripts.md` | +| New secret added to any workflow | `ci/overview.md` secrets table | +| `conanfile.py` dependency version changes | `architecture.md` tech stack section | + +--- + +## 3. Document Templates + +### 3a. Architecture Document (`architecture.md`) + +```markdown +# OpenStudio Application — Architecture + +> Version: {version} | Tech stack: C++20, Qt {qt_version}, CMake+Conan 2 + +## 1. System Context + +\`\`\`mermaid +C4Context + title System Context — OpenStudio Application + Person(user, "Energy Modeler", "...") + System(app, "OpenStudio Application", "...") + ... +\`\`\` + +## 2. Container View + +\`\`\`mermaid +C4Container + ... +\`\`\` + +## 3. Module Dependency Graph + +\`\`\`mermaid +flowchart LR + ... +\`\`\` + +## 4. Technology Stack + +| Category | Technology | Version | +|---|---|---| +| ... + +## 5. Key Design Patterns + +... + +## 6. CI/CD Integration + +... + +## 7. Module Index + +| Module | Library | Doc | +|---|---|---| +| ... +``` + +### 3b. Library Document (`libraries/{name}.md`) + +```markdown +# Library: `{name}` + +> CMake target: `openstudio_{name}` | Location: `src/{name}/` + +## Purpose +One-paragraph description of responsibility. + +## Mermaid Context +\`\`\`mermaid +flowchart LR + {name}["**{name}**\n..."] --> dep1["dependency"] +\`\`\` + +## Key Classes +| Class | Role | +|---|---| + +## Dependencies +| Dependency | Usage | +|---|---| + +## Design Notes +... + +## Class Documentation Index +- [{ClassName}](../classes/{name}/{ClassName}.md) +``` + +### 3c. Class Document (`classes/{module}/{ClassName}.md`) + +```markdown +# `{ClassName}` + +> **Defined in:** `src/{module}/{ClassName}.hpp` +> **Library:** [{module}](../../libraries/{module}.md) + +## Role +One-sentence responsibility statement. + +## Class Diagram +\`\`\`mermaid +classDiagram + class {ClassName} { + +key_method() + +another_method() + } + {BaseClass} <|-- {ClassName} +\`\`\` + +## Key Responsibilities +- ... + +## Public API + +### `method_name(params)` +Brief description. + +## Signals / Slots (Qt) + +| Signal / Slot | Description | +|---|---| + +## Interactions +\`\`\`mermaid +sequenceDiagram + ... +\`\`\` + +## Usage Example +\`\`\`cpp +// ... +\`\`\` + +## Notes +- ... +``` + +### 3d. CI Workflow Document (`ci/workflows/{name}.md`) + +```markdown +# Workflow: `{name}.yml` — {Title} + +> **File:** `.github/workflows/{name}.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose +... + +## Trigger +\`\`\`yaml +on: + ... +\`\`\` + +## Job(s) +\`\`\`mermaid +flowchart TD + ... +\`\`\` + +## Steps +... + +## Related Files +| File | Role | +|---|---| +``` + +--- + +## 4. Mermaid Conventions + +| Diagram type | When to use | Size limit | +|---|---|---| +| `flowchart TD/LR` | System-level context and container views (architecture.md) | — | +| `flowchart TD` / `LR` | Job step sequences (CI docs), initialization flows | — | +| `classDiagram` | Class inheritance and key methods | ≤12 nodes | +| `sequenceDiagram` | Inter-object messaging (class docs) | ≤8 participants | + +**Rules:** +- Never use actor/entity names that contain special characters without quoting them. +- Avoid placing raw C++ template syntax inside diagram nodes; use simplified names. +- Always give diagrams a `title` line when C4 context/container type is used. +- Prefer short, readable labels. Put full detail in prose below the diagram. + +--- + +## 5. Cross-Linking Rules + +- Every library doc must link to each of its class docs in a "Class Documentation Index" section. +- Every class doc must link back to its library doc in the header. +- `architecture.md` module index must link to every library doc. +- `ci/overview.md` workflow table must link to every workflow doc. +- `ci/overview.md` must link to `jenkins.md` and `scripts.md`. +- Use **relative Markdown links** only (e.g., `../libraries/openstudio_lib.md`, not absolute paths). + +--- + +## 6. Step-by-Step Maintenance Procedure + +Follow these steps whenever source code or CI configuration changes: + +1. **Identify changed files.** Read the diff or PR description to find which `.hpp`, `.cpp`, `.yml`, `CMakeLists.txt`, or `ci/` files were modified. + +2. **Map to documentation.** Use the Structure Map (§1) and Trigger Conditions (§2) to determine which `.md` files need updating. + +3. **Read the changed source.** Use `read_file` to read the relevant headers and implementation files. Focus on: public API, inheritance, signals/slots, key collaborators. + +4. **Read the existing doc.** Use `read_file` on the current `.md` to understand what is already correct and what has drifted. + +5. **Update the doc.** Use `replace_string_in_file` for targeted edits (prefer this over full rewrites). Update: + - Class diagram if inheritance or key methods changed + - Public API section if method signatures changed + - Signals/Slots table if Qt signals/slots were added/removed + - Interactions sequence diagram if collaboration pattern changed + - Notes section for behavioral changes + +6. **Update cross-links.** If a class was added or removed, update the parent library doc's Class Documentation Index. If a workflow changed its triggers or jobs, update `ci/overview.md`. + +7. **Check for version or dependency changes.** If `CMakeLists.txt` or `conanfile.py` changed dependency versions, update the tech stack table in `architecture.md`. + +8. **Verify Mermaid syntax.** Ensure all diagram blocks are syntactically valid Mermaid. Do not leave unclosed blocks or use unsupported node shapes. + +--- + +## 7. Class Selection Heuristic + +**Document these classes** (already in the doc set or should be added when introduced): +- Base/abstract classes that define cross-cutting interfaces (`BaseApp`, `OSVectorController`, `OSItem`) +- Tab-level controllers that own a UI domain (`HVACSystemsController`, `RunTabController`) +- View+Controller pairs for complex sub-systems (`HVACSystemsView`, `GeometryEditorController`) +- Integration point classes that bridge external systems (`BIMserverConnection`, `OSWebEnginePage`) +- Widely reused components (`OSGridController`, `OSDropZone`, `MeasureManager`) + +**Do NOT create docs for:** +- Concrete derived specializations of documented base classes where the only difference is the domain (e.g., individual inspector row widgets, individual tab view subclasses written purely as template instantiation) +- SWIG `.i` binding files +- `*.ui` Qt Designer files +- Translation `.ts`/`.qm` files +- CPack / install helper scripts + +--- + +## 8. Scope Exclusions + +Never document the following in `developer/doc/` (they are internal plumbing or generated code): + +- Contents of `debug/` or `release/` build directories +- Files under `signatures/` +- Generated files under `src/utilities/` (these are `configure_file` outputs) +- Contents of `ruby/` Ruby gems or vendored external libraries diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md new file mode 100644 index 000000000..a7d66cee0 --- /dev/null +++ b/developer/doc/architecture.md @@ -0,0 +1,275 @@ +# OpenStudio Application — Architecture Overview + +> **Version:** 1.11.0 +> **Audience:** Internal team (C++/Qt familiarity assumed) +> **Last updated:** See git log + +## Contents + +1. [Project Purpose](#1-project-purpose) +2. [System Context](#2-system-context) +3. [Module Containers](#3-module-containers) +4. [Module Dependency Graph](#4-module-dependency-graph) +5. [Technology Stack](#5-technology-stack) +6. [Build & Toolchain](#6-build--toolchain) +7. [Key Architectural Patterns](#7-key-architectural-patterns) +8. [CI/CD Overview](#8-cicd-overview) +9. [Module Index](#9-module-index) + +--- + +## 1. Project Purpose + +The **OpenStudio Application** is a cross-platform (Windows, macOS, Linux) graphical user interface for whole-building energy modeling. It provides a Qt 6 GUI on top of the **[OpenStudio SDK](https://github.com/NREL/OpenStudio)** (NREL), which in turn drives EnergyPlus simulations and Radiance daylighting analysis. + +Users model building envelopes, thermal zones, HVAC systems, loads, schedules, geometry, and OpenStudio Measures through a tab-based interface. The application is maintained by the **OpenStudio Coalition** and is fully open source. + +Key user workflows: +- Open/create/save `.osm` (OpenStudio Model) files +- Configure building geometry, constructions, loads, schedules, and HVAC +- Apply scripted transformations (OpenStudio Measures) via BCL or local directories +- Run EnergyPlus simulations and review results +- Import IFC building data from a BIMserver instance + +--- + +## 2. System Context + +```mermaid +C4Context + title System Context — OpenStudio Application + + Person(user, "Energy Modeler", "Uses the GUI to create, configure, and simulate building energy models") + + System(app, "OpenStudio Application", "Qt 6 GUI for whole-building energy modeling (.osm files)") + + System_Ext(sdk, "OpenStudio SDK", "C++ library providing the model layer, geometry, HVAC objects, workflow execution, Ruby/Python bindings") + System_Ext(eplus, "EnergyPlus", "Whole-building energy simulation engine (launched as a subprocess by the SDK)") + System_Ext(bimserver, "BIMserver", "IFC building model repository (optional integration)") + System_Ext(bcl, "Building Component Library (BCL)", "Remote library of measures and components (NREL hosted)") + System_Ext(radiance, "Radiance", "Daylight simulation engine (optional, invoked by SDK workflows)") + + Rel(user, app, "Creates/edits building models, runs simulations") + Rel(app, sdk, "Calls SDK C++ API for model manipulation, workflows, version translation") + Rel(sdk, eplus, "Launches EnergyPlus as subprocess, parses results") + Rel(sdk, radiance, "Launches Radiance as subprocess for daylight analysis") + Rel(app, bimserver, "REST API via cpprestsdk/Qt Network (optional)") + Rel(app, bcl, "HTTPS for measure/component downloads") +``` + +--- + +## 3. Module Containers + +Each subdirectory under `src/` is compiled as a separate CMake library target. The application executable links them together. + +```mermaid +C4Container + title Containers — src/ Module Breakdown + + Container(app_exe, "OpenStudioApp", "Executable", "Entry point: main(), application lifecycle, startup screen, version translation") + Container(openstudio_lib, "openstudio_lib", "C++ shared library", "All tab controllers, views, HVAC/geometry/schedules/loads GUI. ~200 files. Target: openstudio_lib") + Container(shared_gui, "shared_gui_components", "C++ shared library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs. Target: openstudio_modeleditor (linked via model_editor)") + Container(model_editor, "model_editor", "C++ shared library", "Generic IDD-driven model object inspector. Used by SketchUp plugin and debugging. Target: openstudio_modeleditor") + Container(bimserver, "bimserver", "C++ shared library", "BIMserver REST integration: project import/export via IFC. Target: openstudio_bimserver") + Container(utilities, "utilities", "C++ static/header library", "Runtime path resolution for SDK CLI, EnergyPlus, Radiance. Target: openstudio_utilities") + Container(qtwinmigrate, "qtwinmigrate", "C++ static library (Windows only)", "MFC/Qt bridge for SketchUp plugin embedding. Target: qtwinmigrate") + + Rel(app_exe, openstudio_lib, "Links; creates OSDocument and MainWindow") + Rel(app_exe, shared_gui, "Links; uses MeasureManager, BCL dialogs") + Rel(openstudio_lib, shared_gui, "Uses grid widgets, form controls, measure integration") + Rel(openstudio_lib, model_editor, "Uses InspectorGadget for generic inspection") + Rel(bimserver, model_editor, "Links; uses Qt Network and model types") + Rel(bimserver, openstudio_lib, "Links to openstudio SDK via openstudio_lib") +``` + +--- + +## 4. Module Dependency Graph + +```mermaid +flowchart TD + EXE["OpenStudioApp (executable)"] + LIB["openstudio_lib"] + SHARED["shared_gui_components"] + ME["model_editor"] + BIM["bimserver"] + UTIL["utilities"] + QTWM["qtwinmigrate (Win32 only)"] + SDK["openstudio SDK\n(external)"] + QT["Qt 6\n(external)"] + BOOST["Boost\n(external)"] + CPPREST["cpprestsdk\n(external)"] + + EXE --> LIB + EXE --> SHARED + EXE --> ME + EXE --> BIM + EXE --> UTIL + LIB --> SHARED + LIB --> ME + LIB --> SDK + LIB --> QT + LIB --> BOOST + SHARED --> ME + SHARED --> SDK + SHARED --> QT + ME --> SDK + ME --> QT + BIM --> ME + BIM --> CPPREST + BIM --> QT + BIM --> SDK + QTWM --> QT + EXE -. "Win32\nonly" .-> QTWM +``` + +--- + +## 5. Technology Stack + +| Layer | Technology | Version | Role | +|---|---|---|---| +| GUI framework | **Qt** | ≥6.5.2 | Widgets, WebEngine, Charts, Network, Svg, QML | +| Core model | **OpenStudio SDK** | matched per release | Building model objects, IDF/OSM I/O, workflows, EnergyPlus bridge | +| Simulation engine | **EnergyPlus** | bundled with SDK | Whole-building energy simulation (subprocess) | +| Language | **C++** | C++20 | All application source code | +| Scripting | **Ruby** | 3.2.2 | Measures, CLI scripting, language bindings | +| Scripting | **Python** | 3.x | Measures, CLI scripting, language bindings | +| Build | **CMake** | ≥3.10.2 + Presets | Build configuration, CPack packaging | +| Package mgmt | **Conan 2** | 2.x | C++ dependency management | +| HTTP/REST | **cpprestsdk** | 2.10.19 | BIMserver REST API client | +| General utils | **Boost** | 1.79 | Optional, smart_ptr, filesystem | +| XML | **pugixml / libxml2 / libxslt** | system | XML parsing | +| JSON | **jsoncpp** | 1.9.5 | JSON serialization | +| Formatting | **fmt** | 9.1.0 | String formatting | +| Database | **SQLite3** | system | Local results database | +| 3D geometry | **TinyGLTF** | — | GLTF import/export | +| Language bindings | **SWIG** | 4.1.1 | Ruby/Python binding generation | +| Compiler cache | **ccache / sccache** | any | CI build acceleration | + +--- + +## 6. Build & Toolchain + +The project uses **CMake Presets** with **Conan 2** for reproducible builds across platforms. + +### Quick Start + +```bash +# 1. Install Conan 2, CMake ≥3.10.2, Qt 6.5.2 (via aqtinstall), compiler +# 2. Configure Conan profile (C++20, Release) +conan install . --build=missing -pr:b=default -pr:h=default + +# 3. Configure CMake using the generated preset +cmake --preset conan-release + +# 4. Build +cmake --build --preset conan-release --target package +``` + +See [BUILDING.md](../../BUILDING.md) for the complete, platform-specific instructions. + +### CMake Targets + +| Target | Type | Description | +|---|---|---| +| `OpenStudioApp` | Executable | Main application binary | +| `openstudio_lib` | Shared library | GUI library | +| `openstudio_modeleditor` | Shared library | Generic model inspector | +| `openstudio_bimserver` | Shared library | BIMserver integration | +| `package` | CPack | Platform installer (`.exe`/`.dmg`/`.deb`/`.tar.gz`) | + +### Platform Packaging + +| Platform | Installer format | Archive | +|---|---|---| +| Windows | `.exe` (Qt IFW) + SignPath code signing | `.zip` | +| macOS | `.dmg` (Qt IFW) + Apple notarization | `.tar.gz` | +| Linux (Ubuntu 22/24) | `.deb` | `.tar.gz` | + +--- + +## 7. Key Architectural Patterns + +### 7.1 Tab-Based MVC Triad + +Each major domain (HVAC, Schedules, Constructions, Geometry, etc.) follows a three-class pattern: + +```mermaid +classDiagram + class MainTabController { + +mainContentWidget() MainTabView* + +setSubTab(int index) + signals: modelObjectSelected, dropZoneItemSelected, toggleUnitsClicked + } + class MainTabView { + +setSubTab(QWidget*) + +showDropZone(bool) + } + class InspectorWidget { + +update(ModelObject) + } + MainTabController "1" --> "1" MainTabView : owns + MainTabController "1" --> "0..1" InspectorWidget : controls + note for MainTabController "Each domain derives from MainTabController\ne.g. HVACSystemsTabController" +``` + +The derived tab controller (e.g., `HVACSystemsTabController`) creates the domain-specific view, handles user actions, and coordinates the inspector panel shown in the right column. + +### 7.2 OSVectorController / Drop Zone Pattern + +List-based views (material layers, zone equipment, schedule day segments) use `OSVectorController` as a base: + +- `OSVectorController::makeVector()` — returns the current set of `OSItemId`s from the model +- Items are displayed as `OSItem` widgets inside an `OSItemList` or `OSDropZone` +- User drops/removes trigger signals routed back through the controller to modify the model + +### 7.3 Grid System + +Multi-column tabular views (Thermal Zones, Space Types, Spaces, Facility) use: +- `OSGridController` — base class mapping model objects to rows and defining columns via typed concept functions (`addCheckBoxColumn`, `addComboBoxColumn`, `addDoubleEditColumn`, etc.) +- `OSGridView` — QWidget rendering the grid; reuses `OSCellWrapper` per cell +- `OSObjectSelector` — manages row selection state + +### 7.4 Qt WebEngine Geometry Bridge + +The Geometry tab uses a Qt WebEngine page (`GeometryEditorView`) to display and edit 3D building geometry via a JavaScript/C++ bridge: +- `OSWebEnginePage` subclasses `QWebEnginePage` and exposes a C++ API to the embedded JavaScript engine +- 3D data is transferred as GLTF (via TinyGLTF) serialized to JSON +- User interactions in the web view (select surface, drag vertex) emit Qt signals consumed by `GeometryEditorController` + +### 7.5 Measure / BCL Integration + +OpenStudio Measures (Ruby or Python scripts that transform models) are managed by `MeasureManager`: +- Scans local `myMeasures`, `BCL` directories; deduplicates by UUID +- Exposes a measure browser via `LocalLibraryController`/`BCLMeasureDialog` +- Runs measures via the OpenStudio CLI in a background process +- The `ApplyMeasureNowDialog` provides a modal UI for running a single measure interactively + +--- + +## 8. CI/CD Overview + +Two parallel CI systems are used: + +| System | Trigger | Purpose | +|---|---|---| +| **GitHub Actions** | PR + push to master/develop + version tags | Full 5-platform build matrix, code signing, release publishing, static analysis, CLA enforcement | +| **Jenkins** (NREL internal) | PR builds only | Incremental build checks on NREL infrastructure via shared library `cbci_shared_libs` | + +See [ci/overview.md](ci/overview.md) for the full CI/CD architecture documentation, or browse individual workflow docs under [ci/workflows/](ci/workflows/). + +--- + +## 9. Module Index + +| Module | Library Target | Doc | +|---|---|---| +| `src/openstudio_app/` | `OpenStudioApp` (exe) | [libraries/openstudio_app.md](libraries/openstudio_app.md) | +| `src/openstudio_lib/` | `openstudio_lib` | [libraries/openstudio_lib.md](libraries/openstudio_lib.md) | +| `src/shared_gui_components/` | linked via model_editor | [libraries/shared_gui_components.md](libraries/shared_gui_components.md) | +| `src/model_editor/` | `openstudio_modeleditor` | [libraries/model_editor.md](libraries/model_editor.md) | +| `src/bimserver/` | `openstudio_bimserver` | [libraries/bimserver.md](libraries/bimserver.md) | +| `src/utilities/` | `openstudio_utilities` | [libraries/utilities.md](libraries/utilities.md) | +| `src/qtwinmigrate/` | `qtwinmigrate` (Win32) | [libraries/qtwinmigrate.md](libraries/qtwinmigrate.md) | diff --git a/developer/doc/ci/jenkins.md b/developer/doc/ci/jenkins.md new file mode 100644 index 000000000..3601a931d --- /dev/null +++ b/developer/doc/ci/jenkins.md @@ -0,0 +1,60 @@ +# CI: Jenkins Pipelines + +> **Back to:** [CI/CD Overview](overview.md) + +## Overview + +Three Jenkinsfiles provide integration with NREL's internal Jenkins infrastructure (`cbci`). Each file is minimal — it simply selects a function from the shared library `cbci_shared_libs` and calls it. All build logic lives in that external library. + +--- + +## Files + +| Jenkinsfile | Library Branch | Library Function | +|---|---|---| +| `Jenkinsfile_linux` | `@updateLibs` branch of `cbci_shared_libs` | `openstudio_app_incr_linux()` | +| `Jenkinsfile_osx` | default (`@cbci_shared_libs`) | `openstudio_app_incr_osx()` | +| `Jenkinsfile_windows` | default (`@cbci_shared_libs`) | `openstudio_app_incr_windows()` | + +--- + +## Trigger Condition + +All three pipelines share the same guard: + +```groovy +if (env.CHANGE_ID && env.CHANGE_TARGET) { + // Run — this is a PR build +} else { + // Skip — this is a branch push; handled by GitHub Actions +} +``` + +`CHANGE_ID` is set by the Jenkins GitHub plugin only when building a Pull Request. This means the Jenkins pipelines run **exclusively on PRs** and do not duplicate the push-triggered GitHub Actions builds. + +--- + +## Relationship to GitHub Actions + +| Metric | GitHub Actions (`app_build.yml`) | Jenkins | +|---|---|---| +| Trigger | PR + push + tags | PR only | +| Platforms | 5 (Ubuntu 22/24, Windows, macOS Intel/ARM) | Internal NREL runners | +| Code signing | Yes (on tags) | No | +| Release upload | Yes | No | +| Purpose | Official artifacts + release | Supplemental incremental check | + +Jenkins builds serve as an additional quality gate for NREL contributors without duplicating the official release workflow. + +--- + +## Shared Library + +The `cbci_shared_libs` library is hosted at `github.com/NREL/cbci_jenkins_libs` (internal). The `openstudio_app_incr_*` functions typically: +1. Check out the PR branch +2. Set up the build environment (Conan, CMake, compiler) +3. Run a build (`cmake --build`) +4. Run tests (`ctest`) +5. Report pass/fail back to the PR status check + +The exact steps are defined in the external shared library, not in this repository. diff --git a/developer/doc/ci/overview.md b/developer/doc/ci/overview.md new file mode 100644 index 000000000..074a2d805 --- /dev/null +++ b/developer/doc/ci/overview.md @@ -0,0 +1,138 @@ +# CI/CD Architecture Overview + +> **Back to:** [Architecture Overview](../architecture.md) + +## Contents + +1. [System Overview](#1-system-overview) +2. [End-to-End Pipeline](#2-end-to-end-pipeline) +3. [Build Matrix](#3-build-matrix) +4. [Workflow Index](#4-workflow-index) +5. [Jenkins Pipelines](#5-jenkins-pipelines) +6. [GitHub Secrets](#6-github-secrets) +7. [CI Helper Scripts](#7-ci-helper-scripts) +8. [CMake Code-Signing Modules](#8-cmake-code-signing-modules) + +--- + +## 1. System Overview + +The project uses **two parallel CI systems**: + +| System | Triggers | Purpose | +|---|---|---| +| **GitHub Actions** | PR (all), push to `master`/`develop`, `v*` tags, manual dispatch | Full 5-platform build matrix, static analysis, CLA, code style, release publishing | +| **Jenkins** (NREL internal, `cbci_shared_libs`) | PR builds only (`CHANGE_ID` set) | Incremental build checks on NREL infrastructure | + +GitHub Actions is the **primary** CI system. Jenkins provides supplemental incremental builds for NREL contributors. + +--- + +## 2. End-to-End Pipeline + +```mermaid +flowchart TD + PR["Pull Request opened / pushed"] --> CLA["cla.yml\nCLA signature check"] + PR --> FMT["clangformat.yml\nCode style check"] + PR --> CK["cppcheck.yml\nStatic analysis"] + PR --> OSM["check_osm_versions.yml\nOSM version gate (master only)"] + PR --> BUILD["app_build.yml\nFull 5-platform build matrix"] + + BUILD --> SIGN_WIN["Windows: SignPath\ncode signing"] + BUILD --> SIGN_MAC["macOS: Apple notarization\n(xcrun notarytool)"] + BUILD --> ARTIFACTS["Upload platform artifacts\n(installer + archive)"] + BUILD --> TEST_PKG["test_package_macos\nSignature & install verification"] + ARTIFACTS --> RELEASE["Tag push v*:\nupload to GitHub Release"] + + RELEASE --> RN["release_notes.yml\nAuto-generate changelog"] +``` + +--- + +## 3. Build Matrix + +```mermaid +flowchart LR + MATRIX["app_build.yml\nbuild job matrix"] + MATRIX --> U22["ubuntu-22.04\n→ .deb + .tar.gz"] + MATRIX --> U24["ubuntu-24.04\n→ .deb + .tar.gz"] + MATRIX --> WIN["windows-2022\n→ .exe (IFW) + .zip\n+ SignPath signing on tags"] + MATRIX --> MAC_INTEL["macos-15-intel x86_64\n→ .dmg (IFW) + .tar.gz\n+ Apple notarization"] + MATRIX --> MAC_ARM["macos-15 arm64\n→ .dmg (IFW) + .tar.gz\n+ Apple notarization"] +``` + +--- + +## 4. Workflow Index + +| Workflow | Trigger | Purpose | Doc | +|---|---|---|---| +| `app_build.yml` | Push master/develop, PR, tags | Main 5-platform build, sign, package, release | [workflows/app_build.md](workflows/app_build.md) | +| `check_osm_versions.yml` | PR → master | Validates OSM version translation | [workflows/check_osm_versions.md](workflows/check_osm_versions.md) | +| `cla.yml` | PR events + `issue_comment` | CLA signature enforcement | [workflows/cla.md](workflows/cla.md) | +| `clangformat.yml` | PR → master/develop | C++ code style enforcement | [workflows/clangformat.md](workflows/clangformat.md) | +| `cppcheck.yml` | Push master, PR | Static analysis | [workflows/cppcheck.md](workflows/cppcheck.md) | +| `export_standards_data.yml` | Manual dispatch | Export SDK standards data and commit OSMs | [workflows/export_standards_data.md](workflows/export_standards_data.md) | +| `manual_cli_test.yml` | Manual dispatch | 5-platform CLI smoke tests | [workflows/manual_cli_test.md](workflows/manual_cli_test.md) | +| `release_notes.yml` | Release `created` | Auto-generate changelog from GitHub issues | [workflows/release_notes.md](workflows/release_notes.md) | + +--- + +## 5. Jenkins Pipelines + +Three Jenkinsfiles are provided for NREL's internal Jenkins infrastructure. Each delegates entirely to a **shared library** at `github.com/NREL/cbci_jenkins_libs`: + +| File | Library function | +|---|---| +| `Jenkinsfile_linux` | `openstudio_app_incr_linux()` (branch: `@updateLibs`) | +| `Jenkinsfile_osx` | `openstudio_app_incr_osx()` | +| `Jenkinsfile_windows` | `openstudio_app_incr_windows()` | + +**Trigger condition:** all three pipelines run only when both `env.CHANGE_ID` and `env.CHANGE_TARGET` are set — meaning **PR builds only**. Pushes to branches are handled exclusively by GitHub Actions. + +See [jenkins.md](jenkins.md) for further details. + +--- + +## 6. GitHub Secrets + +| Secret | Used by | Purpose | +|---|---|---| +| `MACOS_DEVELOPER_ID_APPLICATION_CERTIFICATE_P12_BASE64` | `app_build.yml` | Base64-encoded P12 cert for macOS app bundle signing | +| `MACOS_DEVELOPER_ID_INSTALLER_CERTIFICATE_P12_PASSWORD` | `app_build.yml` | Password for the macOS installer signing P12 | +| `MACOS_KEYCHAIN_PASSWORD` | `app_build.yml` | Password for the temporary keychain created during macOS CI | +| `NOTARIZATION_API_KEY` | `app_build.yml` | Apple App Store Connect API key for `xcrun notarytool` | +| `NOTARIZATION_API_TEAM_ID` | `app_build.yml` | Apple Team ID for notarization | +| `NOTARIZATION_API_ISSUER_ID` | `app_build.yml` | Issuer ID for App Store Connect API | +| `SIGNPATH_CI_TOKEN` | `app_build.yml` | Windows code signing token via SignPath | +| `ANALYTICS_API_SECRET` | `app_build.yml` | Google Analytics Measurement Protocol secret embedded in the app binary | +| `ANALYTICS_MEASUREMENT_ID` | `app_build.yml` | Google Analytics measurement ID | +| `CLA_SECRET` | `cla.yml` | Personal access token for cla-assistant GitHub Action | +| `CACHE_KEY` | `app_build.yml` | Rotatable opaque key for invalidating all CI caches | + +--- + +## 7. CI Helper Scripts + +See [scripts.md](scripts.md) for full documentation of all scripts in `ci/`. + +| Script | Purpose | +|---|---| +| `ci/clang-format.sh` | Runs clang-format on PR-changed files; produces patch | +| `ci/pre-commit.sh` | Git pre-commit hook wrapping clang-format | +| `ci/colorize_cppcheck_results.py` | ANSI-colorizes cppcheck output by severity | +| `ci/install_script_qtifw.qs` | Silent QtIFW installer controller for CI | +| `ci/parse_cmake_versions.py` | Extracts version variables from CMake files | + +--- + +## 8. CMake Code-Signing Modules + +| File | Purpose | +|---|---| +| `CMake/CodeSigning.cmake` | `codesign` and `xcrun notarytool` helper CMake functions | +| `CMake/CPackSignAndNotarizeDmg.cmake` | CPack post-build hook: signs and notarizes the `.dmg` | +| `CMake/install_codesign_script.cmake` | CMake install-time signing (all components) | +| `CMake/install_codesign_script_OpenStudioApp.cmake` | Signing script scoped to the `OpenStudioApp` component | +| `CMake/install_codesign_script_Python.cmake` | Signing script scoped to the Python bundle component | +| `FindOpenStudioSDK.cmake` | Defines `OPENSTUDIO_VERSION_*` variables consumed by version parser script | diff --git a/developer/doc/ci/scripts.md b/developer/doc/ci/scripts.md new file mode 100644 index 000000000..2530dbbea --- /dev/null +++ b/developer/doc/ci/scripts.md @@ -0,0 +1,143 @@ +# CI: Helper Scripts + +> **Back to:** [CI/CD Overview](overview.md) + +## Overview + +The `ci/` directory contains five helper scripts used by GitHub Actions workflows and the local development pre-commit hook. + +--- + +## `ci/clang-format.sh` + +**Used by:** [`clangformat.yml`](workflows/clangformat.md), [`ci/pre-commit.sh`](#cipre-commitsh) + +Runs `clang-format` on only the C/C++ files that differ between two git refs, then produces a unified diff patch. + +### Arguments + +```bash +ci/clang-format.sh +# e.g.: ci/clang-format.sh HEAD remotes/origin/develop +``` + +### Behavior + +1. Computes `git diff --name-only ref1 ref2` filtered to `*.cpp`, `*.hpp`, `*.cxx`, `*.h` +2. Runs `clang-format -style=file -i` on each changed file (uses the `.clang-format` in the repo root) +3. Runs `git diff` to detect any formatting changes +4. If changes exist: writes `clang_format.patch` and exits with code 1 +5. If no changes: exits with code 0 + +### Exit Codes + +| Code | Meaning | +|---|---| +| 0 | All changed files are correctly formatted | +| 1 | Formatting changes needed; `clang_format.patch` produced | + +--- + +## `ci/pre-commit.sh` + +**Used by:** Developer local setup (git pre-commit hook) + +A git pre-commit hook that runs `clang-format.sh` on staged changes before each commit. Prevents unformatted code from being committed. + +### Installation + +```bash +cd .git/hooks +ln -s ../../ci/pre-commit.sh pre-commit +``` + +### Behavior + +1. Stashes unstaged changes (`git stash -u`) to isolate staged content +2. Runs `ci/clang-format.sh HEAD origin/develop` +3. If exit code is 1: prints guidance and aborts the commit (exit 1) +4. Restores stashed changes (`git stash pop`) + +--- + +## `ci/colorize_cppcheck_results.py` + +**Used by:** [`cppcheck.yml`](workflows/cppcheck.md) + +Reads cppcheck output from stdin, applies ANSI colors by severity, and prints a summary counter. + +### Input Format + +Expects lines matching: +``` +[file.cpp:42]:(error),[missingOverride],Override has no matching virtual function +``` + +### Color Mapping + +| Severity | ANSI Color | +|---|---| +| `error` | Red | +| `warning` | Yellow | +| `style` | Blue | +| `performance` | Cyan | +| `portability` | Magenta | +| `information` | Green | + +### Usage + +```bash +cppcheck ... 2>&1 | python3 ci/colorize_cppcheck_results.py +``` + +--- + +## `ci/install_script_qtifw.qs` + +**Used by:** [`app_build.yml`](workflows/app_build.md) (Windows and macOS, silent install verification) + +A QtIFW (Qt Installer Framework) controller script for **unattended / silent installation** in CI environments. + +### Behavior + +Implements all QtIFW `Controller` callbacks: +- `WelcomePageCallback` — auto-clicks Next +- `LicenseAgreementPageCallback` — auto-accepts +- `ComponentSelectionPageCallback` — accepts defaults +- `TargetDirectoryPageCallback` — accepts default install path +- `ReadyForInstallationPageCallback` — clicks Install +- `FinishedPageCallback` — disables "Launch after install" checkbox, clicks Finish + +This allows automated installation of the produced `.exe`/`.dmg` installer as part of post-build verification. + +--- + +## `ci/parse_cmake_versions.py` + +**Used by:** [`app_build.yml`](workflows/app_build.md), [`export_standards_data.yml`](workflows/export_standards_data.md) + +Parses version numbers from `CMakeLists.txt` and `FindOpenStudioSDK.cmake` and writes them to `GITHUB_ENV` and `GITHUB_OUTPUT` for use by downstream workflow steps. + +### Variables Extracted + +From `CMakeLists.txt`: +- `OS_APP_VERSION` — e.g., `1.11.0` +- `OS_APP_VERSION_MAJOR`, `OS_APP_VERSION_MINOR`, `OS_APP_VERSION_PATCH` + +From `FindOpenStudioSDK.cmake`: +- `OS_SDK_VERSION` — assembled from major/minor/patch/prerelease components +- `OS_SDK_VERSION_MAJOR`, `OS_SDK_VERSION_MINOR`, `OS_SDK_VERSION_PATCH` +- `OS_SDK_VERSION_PRERELEASE`, `OS_SDK_SHA` (git SHA of the SDK) + +### Usage + +```bash +python3 ci/parse_cmake_versions.py +# Writes to $GITHUB_ENV and $GITHUB_OUTPUT automatically +``` + +After this step, any subsequent GitHub Actions step can use the variables: +```yaml +- name: Use version + run: echo "Building version ${{ env.OS_APP_VERSION }}" +``` diff --git a/developer/doc/ci/workflows/app_build.md b/developer/doc/ci/workflows/app_build.md new file mode 100644 index 000000000..bbaaa2b12 --- /dev/null +++ b/developer/doc/ci/workflows/app_build.md @@ -0,0 +1,139 @@ +# Workflow: `app_build.yml` — Main Build Pipeline + +> **File:** `.github/workflows/app_build.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +The primary CI workflow. Builds the OpenStudio Application on 5 platforms, runs tests and benchmarks, applies code signing (on tags), and uploads installers to GitHub Releases. + +--- + +## Trigger + +```yaml +on: + push: + branches: [master, develop] + tags: ['v*'] + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + branches: [master, develop] +``` + +Draft PRs are skipped via an `if: github.event.pull_request.draft == false` guard. + +--- + +## Jobs + +```mermaid +flowchart TD + BUILD["build\n5-platform matrix"] + TEST_PKG["test_package_macos\nmacos-15-intel + macos-15 arm64"] + + BUILD --> TEST_PKG +``` + +--- + +## `build` Job — Step Sequence + +```mermaid +flowchart TD + CO["Checkout (actions/checkout@v4)"] --> PY["Setup Python 3.12"] + PY --> RB["Setup Ruby 3.2.2"] + RB --> VER["Parse versions\n(ci/parse_cmake_versions.py)"] + VER --> PLATFORM["Platform-specific setup\n(apt / choco / brew)"] + PLATFORM --> SIGN_SETUP["macOS: Code signing setup\n(P12 import, keychain, notarytool profile)"] + SIGN_SETUP --> CONAN["Install Conan 2\nSet profile: C++20, Release\nAdd NREL conan remote"] + CONAN --> CACHE["Restore 3 caches:\ncache1: ccache\ncache2: Conan packages\ncache3: Qt + OpenStudio SDK"] + CACHE --> QT["Install Qt 6.5.2 via aqtinstall\n(qtwebengine, qtcharts, etc.)"] + QT --> CMAKE["conan install → cmake --preset conan-release"] + CMAKE --> BUILD_PKG["cmake --build --target package"] + BUILD_PKG --> WIN_SIGN["Windows (tags only):\nSignPath signs .exe\nRepack with CPack\nSignPath signs installer .exe"] + WIN_SIGN --> UPLOAD["Upload artifact:\ninstaller + archive"] + UPLOAD --> MAC_VERIFY["macOS: verify_signature.py\non IFW + TGZ"] + MAC_VERIFY --> CTEST["CTest\n(xvfb-run on Linux,\nautomationmodetool on macOS)"] + CTEST --> BENCH["Benchmarks:\nSpacesSurfaces_Benchmark → CSV"] + BENCH --> RELEASE["Tag push v*:\nupload to GitHub Release\n(svenstaro/upload-release-action)"] + RELEASE --> KC["macOS: Always delete temp keychain"] +``` + +--- + +## `test_package_macos` Job + +Depends on `build` and runs on `macos-15-intel` and `macos-15` (arm64) only. + +**Steps:** +1. Download `.dmg` artifact from the `build` job +2. `spctl --assess --type install` — verify DMG signature +3. Mount DMG, verify installer app bundle signature with `codesign -dvvv` +4. Silent install via `installer -pkg` or QtIFW with `ci/install_script_qtifw.qs` +5. `codesign -dvvv` on all critical inner libs: `libopenstudiolib.dylib`, `libpythonengine.so`, `librubyengine.so`, `energyplus`, `libenergyplusapi.dylib` +6. Full deep signature check via `developer/python/verify_signature.py` +7. Run an EnergyPlus Python plugin simulation to verify end-to-end install +8. Upload `otool` JSON as artifact + +--- + +## Platform-Specific Setup Details + +### Linux (ubuntu-22.04, ubuntu-24.04) + +```bash +sudo apt-get install mesa-common-dev libxkbcommon-x11-dev \ + libxcb-util1 libxcb-keysyms1 libxcb-image0 libxcb-render-util0 \ + libxcb-randr0 libxcb-xinerama0 libxcb-icccm4 librsvg2-dev \ + chrpath ccache ninja-build patchelf +``` + +### Windows (windows-2022) + +- Downloads QtIFW 4.6.1 +- Installs `ninja` + `ccache` via Chocolatey +- Locates MSVC via `vswhere` + +### macOS (macos-15-intel, macos-15 arm64) + +- Sets `MACOSX_DEPLOYMENT_TARGET` and `SDKROOT` +- Selects Xcode 16.4 via `xcode-select` +- Installs `ccache` + `ninja` via Homebrew +- Removes conflicting system OpenSSL pkg-config files +- Downloads a patched QtIFW from `jmarrec/QtIFW-fixup` (for silent install) + +--- + +## Caching Strategy + +Three independent caches keyed to avoid stale data: + +| Cache | Key components | +|---|---| +| **CCache** | OS + build type + Conan profile hash + `CACHE_KEY` secret + `CMakeLists.txt` sha | +| **Conan packages** | OS + Conan profile hash + `conanfile.py` sha | +| **Qt + OpenStudio SDK** | OS + Qt version + Conan profile hash | + +Rotating the `CACHE_KEY` secret busts all caches immediately. + +--- + +## Artifacts + +| Artifact | Platforms | +|---|---| +| `OpenStudioApplication--.exe` | Windows | +| `OpenStudioApplication--.zip` | Windows | +| `OpenStudioApplication--.dmg` | macOS | +| `OpenStudioApplication--.tar.gz` | macOS, Linux | +| `OpenStudioApplication--.deb` | Linux | +| `otool-output.json` | macOS (test_package_macos job) | +| CTest XML results | all platforms | +| Benchmark CSV | all platforms | + +--- + +## Required Secrets + +All secrets from the [Secrets table](../overview.md#6-github-secrets) are consumed by this workflow. diff --git a/developer/doc/ci/workflows/check_osm_versions.md b/developer/doc/ci/workflows/check_osm_versions.md new file mode 100644 index 000000000..dafbfc22b --- /dev/null +++ b/developer/doc/ci/workflows/check_osm_versions.md @@ -0,0 +1,64 @@ +# Workflow: `check_osm_versions.yml` — OSM Version Gate + +> **File:** `.github/workflows/check_osm_versions.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Ensures that all `.osm` files bundled with the application have been version-translated to the current OpenStudio SDK version before a PR is merged to `master`. This prevents shipping stale template models that would trigger the version translation warning at startup. + +--- + +## Trigger + +```yaml +on: + pull_request: + branches: [master] +``` + +Runs only on PRs targeting `master` (not `develop`). + +--- + +## Jobs + +```mermaid +flowchart TD + A["osm-versions job\nubuntu-latest"] --> B["Checkout"] + B --> C["Setup Ruby 3.2"] + C --> D["Run developer/ruby/CheckOSMVersions.rb"] + D --> PASS{Exit 0?} + PASS -- yes --> OK["✓ Check passes"] + PASS -- no --> FAIL["✗ Check fails\nPrint guidance message"] +``` + +--- + +## Key Step + +```yaml +- name: Check OSM versions + run: ruby developer/ruby/CheckOSMVersions.rb +``` + +`CheckOSMVersions.rb` reads all `.osm` files in `src/openstudio_app/Resources/` and verifies that each file's `OS:Version` object matches the expected SDK version (extracted from `FindOpenStudioSDK.cmake`). + +--- + +## Failure Guidance + +On failure, the workflow prints: + +> Run the `export_standards_data` workflow (see [workflows/export_standards_data.md](export_standards_data.md)) to regenerate the OSM files, or run `developer/ruby/UpdateOSMVersions.rb` locally and commit the result. + +--- + +## Related Files + +| File | Role | +|---|---| +| `developer/ruby/CheckOSMVersions.rb` | The version-checking script | +| `developer/ruby/UpdateOSMVersions.rb` | Locally run script to translate OSM files | +| `src/openstudio_app/Resources/*.osm` | OSM template files that are checked | +| `FindOpenStudioSDK.cmake` | Source of the expected SDK version | diff --git a/developer/doc/ci/workflows/cla.md b/developer/doc/ci/workflows/cla.md new file mode 100644 index 000000000..d05dc3ebe --- /dev/null +++ b/developer/doc/ci/workflows/cla.md @@ -0,0 +1,65 @@ +# Workflow: `cla.yml` — CLA Enforcement + +> **File:** `.github/workflows/cla.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Enforces the Contributor License Agreement (CLA) for all external contributors. Any PR author who has not yet signed the CLA will see a blocking status check with instructions on how to sign. + +--- + +## Trigger + +```yaml +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] +``` + +`pull_request_target` runs in the context of the **base branch** (not the PR branch), which gives the workflow write access needed to post comments and update PR status even from fork PRs. + +--- + +## Job + +```mermaid +flowchart TD + PR["PR opened / synchronized / closed\nor comment created"] --> CLA_BOT["CLA Assistant\n(cla-assistant/github-action@v2.3.1)"] + CLA_BOT --> CHECK{Signature found\nin cla.json?} + CHECK -- yes --> PASS["✓ CLA signed - status check passes"] + CHECK -- no --> COMMENT["Bot posts comment with\nsigning instructions"] + COMMENT --> WAIT["Wait for magic comment"] + WAIT --> SIGN["Contributor comments:\n'I have read the CLA Document\nand I hereby sign the CLA'"] + SIGN --> UPDATE["Signature recorded in\nsignatures/version1/cla.json\non develop branch"] + UPDATE --> PASS +``` + +--- + +## Configuration + +| Setting | Value | +|---|---| +| CLA document | [CLA.md](../../../../CLA.md) | +| Signature storage | `signatures/version1/cla.json` on `develop` branch | +| Sign magic comment | `"I have read the CLA Document and I hereby sign the CLA"` | +| Re-check comment | `"recheck"` | + +--- + +## Required Secrets + +| Secret | Purpose | +|---|---| +| `CLA_SECRET` | GitHub personal access token with `repo` scope; allows the action to read/write `cla.json` on the `develop` branch | + +--- + +## Notes + +- Organization members are typically excluded from CLA requirements (configured in the action). +- Bots (`[bot]` suffix in username) are automatically excluded. +- Signatures persist across PRs; a contributor only needs to sign once. diff --git a/developer/doc/ci/workflows/clangformat.md b/developer/doc/ci/workflows/clangformat.md new file mode 100644 index 000000000..d5f660f4f --- /dev/null +++ b/developer/doc/ci/workflows/clangformat.md @@ -0,0 +1,77 @@ +# Workflow: `clangformat.yml` — Code Style Enforcement + +> **File:** `.github/workflows/clangformat.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Enforces that all C/C++ source files changed in a PR are formatted according to the project's `.clang-format` style. PRs with formatting violations produce a downloadable patch and a failing status check. + +--- + +## Trigger + +```yaml +on: + pull_request: + branches: [master, develop] +``` + +--- + +## Job + +```mermaid +flowchart TD + A["build job\nubuntu-latest"] --> B["Checkout\n(full fetch-depth: 0 to include all branches)"] + B --> C["ci/clang-format.sh HEAD remotes/origin/$GITHUB_BASE_REF"] + C --> RESULT{Exit code?} + RESULT -- 0 --> PASS["✓ Formatting correct"] + RESULT -- 1 --> PATCH["Upload clang_format.patch artifact\nas OpenStudioApplication-SHA-clang_format.patch"] + PATCH --> FAIL["✗ Check fails"] +``` + +--- + +## Key Step + +```bash +ci/clang-format.sh HEAD remotes/origin/$GITHUB_BASE_REF +``` + +This runs clang-format only on the files changed by the PR (diff between `HEAD` and the base branch). See [scripts.md](../scripts.md#ciclang-formatsh) for full script documentation. + +--- + +## Fixing Violations + +Download the `clang_format.patch` artifact and apply it: + +```bash +git apply clang_format.patch +git commit -am "Apply clang-format" +git push +``` + +Or run locally before committing: + +```bash +ci/clang-format.sh HEAD origin/develop +git diff # should be empty +``` + +Install the pre-commit hook to catch violations before pushing: + +```bash +cd .git/hooks && ln -s ../../ci/pre-commit.sh pre-commit +``` + +--- + +## Related Files + +| File | Role | +|---|---| +| `.clang-format` | Style configuration file | +| `ci/clang-format.sh` | Script invoked by this workflow | +| `ci/pre-commit.sh` | Local pre-commit hook equivalent | diff --git a/developer/doc/ci/workflows/cppcheck.md b/developer/doc/ci/workflows/cppcheck.md new file mode 100644 index 000000000..e71dbd8fe --- /dev/null +++ b/developer/doc/ci/workflows/cppcheck.md @@ -0,0 +1,85 @@ +# Workflow: `cppcheck.yml` — Static Analysis + +> **File:** `.github/workflows/cppcheck.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Runs `cppcheck` static analysis on the entire `src/` tree to detect potential bugs, style violations, and undefined behavior. Output is colorized by severity and stored as a build artifact. + +--- + +## Trigger + +```yaml +on: + push: + branches: [master] + pull_request: + branches: [master, develop] +``` + +--- + +## Job + +```mermaid +flowchart TD + A["build job\nubuntu-latest"] --> B["Checkout"] + B --> C["Build cppcheck 2.9 from source\n(cmake -DBUILD_TESTING=OFF .)"] + C --> D["Run cppcheck on ./src\n(excluding ./src/qtwinmigrate)"] + D --> E["Pipe through ci/colorize_cppcheck_results.py"] + E --> F["Always: upload cppcheck.txt artifact"] + D --> RESULT{Exit code?} + RESULT -- 0 --> PASS["✓ No errors"] + RESULT -- 1 --> FAIL["✗ Errors found"] +``` + +--- + +## Cppcheck Configuration + +```bash +cppcheck \ + --std=c++20 \ + --enable=all \ + --library=qt \ + --suppress=useStlAlgorithm \ + --inconclusive \ + --template='[{file}:{line}]:({severity}),[{id}],{message}' \ + -j $(nproc) \ + --output-file=cppcheck.txt \ + -i ./src/qtwinmigrate \ + ./src +``` + +| Option | Purpose | +|---|---| +| `--std=c++20` | Parse using C++20 standard | +| `--enable=all` | Enable all check categories | +| `--library=qt` | Use Qt-specific definitions to reduce false positives | +| `--suppress=useStlAlgorithm` | Suppress noisy "use `std::find` instead of loop" suggestions | +| `--inconclusive` | Include checks that may have false positives | +| `-i ./src/qtwinmigrate` | Exclude the third-party Qt/Win32 bridge | + +--- + +## Why Build cppcheck from Source? + +The Ubuntu system `cppcheck` package is typically several major versions behind. Building version 2.9 from source ensures consistent results across CI runs and access to newer checks. + +--- + +## Artifacts + +| Artifact | Contents | +|---|---| +| `cppcheck.txt` | Full cppcheck output (always uploaded, regardless of pass/fail) | + +--- + +## Related Files + +| File | Role | +|---|---| +| `ci/colorize_cppcheck_results.py` | Post-processes cppcheck output with ANSI colors | diff --git a/developer/doc/ci/workflows/export_standards_data.md b/developer/doc/ci/workflows/export_standards_data.md new file mode 100644 index 000000000..c1b4a513b --- /dev/null +++ b/developer/doc/ci/workflows/export_standards_data.md @@ -0,0 +1,82 @@ +# Workflow: `export_standards_data.yml` — Manual Standards Export + +> **File:** `.github/workflows/export_standards_data.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Manually triggered workflow that downloads the current OpenStudio SDK, runs the Ruby script that generates OpenStudio Standards template `.osm` files, and commits the results back to the repository. This is how the bundled template models in `src/openstudio_app/Resources/` are kept up to date with new SDK releases. + +--- + +## Trigger + +```yaml +on: + workflow_dispatch: + inputs: + os_installer_link: + description: 'URL of the OpenStudio SDK Linux .deb (optional override)' + required: false + branch_name: + description: 'Branch to commit results to (optional, defaults to current)' + required: false +``` + +--- + +## Job + +```mermaid +flowchart TD + A["export-os-standards job\nubuntu-latest"] --> B["Checkout"] + B --> C["Parse SDK version from FindOpenStudioSDK.cmake\n(inline Python)"] + C --> D{os_installer_link input set?} + D -- yes --> DIRECT["Use provided URL"] + D -- no --> DETECT["Try default URL\nFallback: S3 alternate URL\nFallback: latest GitHub release"] + DIRECT --> E["Download + install OpenStudio SDK .deb"] + DETECT --> E + E --> F[Setup target branch\n(create if not exists)] + F --> G["Run: N=$(nproc) openstudio export_openstudio_standards_libraries.rb\nin developer/ruby/"] + G --> H["Copy generated .osm files\nto src/openstudio_app/Resources/"] + H --> I["Copy export logs"] + I --> J["git add + git commit + git push\nto target branch"] +``` + +--- + +## When to Run + +Run this workflow when: +- A new OpenStudio SDK version is released and the template OSM files need to be regenerated +- The `check_osm_versions.yml` gate is failing on the `master` PR +- Structural changes to the standards data require a full regeneration + +--- + +## Inputs + +| Input | Required | Default | Description | +|---|---|---|---| +| `os_installer_link` | No | Auto-detected | Direct URL to an OpenStudio SDK `.deb` installer | +| `branch_name` | No | Current branch | Target branch to commit the generated OSM files to | + +--- + +## Outputs + +After the workflow runs, it commits to the target branch: +- Updated `.osm` files in `src/openstudio_app/Resources/` +- Export log files from the Ruby script + +Create a PR from the target branch to merge the updated OSMs into `develop` or `master`. + +--- + +## Related Files + +| File | Role | +|---|---| +| `developer/ruby/export_openstudio_standards_libraries.rb` | Ruby script that generates the OSM files | +| `FindOpenStudioSDK.cmake` | Source of the SDK version number for download URL construction | +| `src/openstudio_app/Resources/*.osm` | Generated template files committed by this workflow | diff --git a/developer/doc/ci/workflows/manual_cli_test.md b/developer/doc/ci/workflows/manual_cli_test.md new file mode 100644 index 000000000..a48c17ba7 --- /dev/null +++ b/developer/doc/ci/workflows/manual_cli_test.md @@ -0,0 +1,92 @@ +# Workflow: `manual_cli_test.yml` — Manual CLI Integration Test + +> **File:** `.github/workflows/manual_cli_test.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Manually triggered smoke test workflow that downloads a previously built installer archive from a specific workflow run and verifies that the OpenStudio CLI works correctly on all 5 platforms. Tests cover both the classic Ruby CLI and the newer C++ (labs) CLI, including EnergyPlus and Python scripting. + +--- + +## Trigger + +```yaml +on: + workflow_dispatch: + inputs: + run_id: + description: 'Run ID of the app_build workflow to test' + required: true +``` + +--- + +## Matrix + +```mermaid +flowchart LR + MATRIX["5-platform matrix"] --> U20["ubuntu-20.04"] + MATRIX --> U22["ubuntu-22.04"] + MATRIX --> WIN["windows-2022"] + MATRIX --> M13["macos-13 x86_64"] + MATRIX --> MARM["macos arm64\n(self-hosted runner)"] +``` + +--- + +## Job Steps + +```mermaid +flowchart TD + A["Download archive artifact\nfrom run_id"] --> B["Extract archive"] + B --> C["Locate Examples/compact_osw/ directory"] + C --> D["Detect default CLI:\nRuby (classic) or C++ (labs)"] + D --> E["EnergyPlus smoke test:\n'energyplus --version'"] + E --> F["Classic Ruby CLI tests"] + F --> G["Labs C++ CLI tests"] + G --> H["'tree' output of install structure"] + H --> I["ldd / otool lib inspection"] +``` + +--- + +## Test Coverage + +### Classic Ruby CLI Tests + +| Test | Command | +|---|---| +| Help | `openstudio --help` | +| Version | `openstudio --version` | +| Ruby snippet | `openstudio -e "puts OpenStudio::openStudioVersion()"` | +| Gem require | `openstudio -e "require 'oga'; puts 'oga OK'"` | +| Execute script | `openstudio execute_ruby_script test.rb` | +| Run workflow | `openstudio run -w compact_ruby_only.osw` | + +### Labs C++ CLI Tests + +All Ruby tests above, plus: + +| Test | Command | +|---|---| +| Python version | `openstudio labs python --version` | +| Execute Python script | `openstudio labs execute_python_script test.py` | +| Mixed Ruby/Python OSW | `openstudio run -w compact_ruby_python.osw` | +| Multiple mixed workflows | Additional OSW permutations | + +--- + +## When to Run + +- After a successful `app_build.yml` run produces installer artifacts that you want to validate before releasing +- When investigating CLI regressions on a specific platform +- After updating Ruby or Python bindings + +--- + +## Required Inputs + +| Input | Description | +|---|---| +| `run_id` | The numeric ID of a prior `app_build.yml` workflow run (visible in the GitHub Actions URL) | diff --git a/developer/doc/ci/workflows/release_notes.md b/developer/doc/ci/workflows/release_notes.md new file mode 100644 index 000000000..b36a66475 --- /dev/null +++ b/developer/doc/ci/workflows/release_notes.md @@ -0,0 +1,76 @@ +# Workflow: `release_notes.yml` — Automated Changelog + +> **File:** `.github/workflows/release_notes.yml` +> **Back to:** [CI/CD Overview](../overview.md) + +## Purpose + +Automatically generates and appends a changelog to a GitHub Release when the release is created. The changelog is built by querying the GitHub Issues API for all issues closed since the last release. + +--- + +## Trigger + +```yaml +on: + release: + types: [created] +``` + +Fires once when a new GitHub Release is created (not on draft creation). + +--- + +## Job + +```mermaid +flowchart TD + A["release-notes job\nubuntu-latest"] --> B["Checkout"] + B --> C["Setup Ruby 3.2"] + C --> D["Setup Python 3.8"] + D --> E["Install github_api gem\nInstall requests Python package"] + E --> F["Run developer/ruby/GitHubIssueStats.rb\n→ changelog.txt"] + F --> G["PATCH /repos/:owner/:repo/releases/:id\nAppend changelog to release body"] +``` + +--- + +## Key Step + +`developer/ruby/GitHubIssueStats.rb` queries the GitHub Issues API for issues closed between the previous release tag and the current one, formats them into a Markdown changelog, and writes `changelog.txt`. + +The changelog is then appended to the release body via: +```bash +curl -X PATCH \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"body\": \"$RELEASE_BODY\n\n$CHANGELOG\"}" \ + https://api.github.com/repos/openstudiocoalition/OpenStudioApplication/releases/$RELEASE_ID +``` + +--- + +## Outputs + +The GitHub Release body is updated to include a section like: + +```markdown +## Changes + +### Bug Fixes +- Fix crash when opening models with orphan spaces (#1234) + +### New Features +- Add support for EnergyPlus 24.1 output variables (#1198) + +### Improvements +- Improve geometry editor performance on large models (#1201) +``` + +--- + +## Related Files + +| File | Role | +|---|---| +| `developer/ruby/GitHubIssueStats.rb` | Generates the changelog from GitHub Issues API | diff --git a/developer/doc/classes/bimserver/BIMserverConnection.md b/developer/doc/classes/bimserver/BIMserverConnection.md new file mode 100644 index 000000000..5ec5945a2 --- /dev/null +++ b/developer/doc/classes/bimserver/BIMserverConnection.md @@ -0,0 +1,111 @@ +# Class: `BIMserverConnection` + +> **Module:** `bimserver` +> **Header:** [src/bimserver/BIMserverConnection.hpp](../../../../src/bimserver/BIMserverConnection.hpp) +> **Library doc:** [libraries/bimserver.md](../../libraries/bimserver.md) + +## Purpose + +`BIMserverConnection` is the HTTP client for the BIMserver REST API. It uses Qt's `QNetworkAccessManager` to send JSON-RPC style POST requests to a BIMserver instance and routes responses back to callers via Qt signals (async) or blocking return values (sync). + +A single `BIMserverConnection` is associated with one BIMserver address/port pair. All authentication state (session token) is maintained internally after a successful login. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QObject { + <> + } + class BIMserverConnection { + <> + -addr: QString + -port: QString + -token: QString + -manager: QNetworkAccessManager* + +BIMserverConnection(parent, addr, port) + +login(username, password) + +getAllProjects() + +download(revisionID) + +createProject(name) + +deleteProject(projectID) + +checkInIFCFile(projectID, path) + +getIFCRevisionList(projectID) + +loginBlocked(username, password, timeout) bool + +getAllProjectsBlocked(timeout) optional~QStringList~ + +downloadBlocked(projectID, timeout) optional~QString~ + +createProjectBlocked(name, timeout) bool + +deleteProjectBlocked(projectID, timeout) bool + +checkInIFCFileBlocked(projectID, path, timeout) bool + +getIFCRevisionListBlocked(projectID, timeout) optional~QStringList~ + signals: loginSuccess() + signals: loginFailed() + signals: allProjectsAvailable(QStringList) + signals: osmStringAvailable(QString) + signals: newProjectAdded() + signals: projectDeleted() + signals: ifcCheckedIn() + signals: ifcRevisionListAvailable(QStringList) + signals: errorOccured(QString) + signals: progressUpdated(int) + } + + QObject <|-- BIMserverConnection +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `parent` | `QObject*` | Qt parent (typically `ProjectImporter`) | +| `bimserverAddr` | `const QString&` | Hostname or IP of the BIMserver instance | +| `bimserverPort` | `const QString&` | Port number (e.g., `"8080"`) | + +--- + +## Non-Blocking API + +All non-blocking methods POST a JSON request and return immediately. The result is delivered asynchronously via the corresponding signal. + +| Method | Response signal | +|---|---| +| `login(username, password)` | `loginSuccess()` / `loginFailed()` | +| `getAllProjects()` | `allProjectsAvailable(QStringList)` | +| `download(revisionID)` | `osmStringAvailable(QString)` | +| `createProject(name)` | `newProjectAdded()` | +| `deleteProject(projectID)` | `projectDeleted()` | +| `checkInIFCFile(projectID, path)` | `ifcCheckedIn()` + `progressUpdated(int)` | +| `getIFCRevisionList(projectID)` | `ifcRevisionListAvailable(QStringList)` | + +--- + +## Blocking API + +Each blocking variant spins a `QEventLoop` with a `QTimer` timeout. Returns a result or `boost::none` on timeout/failure. + +| Method | Returns | +|---|---| +| `loginBlocked(username, password, timeout)` | `bool` | +| `getAllProjectsBlocked(timeout)` | `optional` | +| `downloadBlocked(projectID, timeout)` | `optional` (OSM string) | +| `createProjectBlocked(name, timeout)` | `bool` | +| `deleteProjectBlocked(projectID, timeout)` | `bool` | +| `checkInIFCFileBlocked(projectID, path, timeout)` | `bool` | +| `getIFCRevisionListBlocked(projectID, timeout)` | `optional` | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `loginSuccess` | — | Login POST succeeded and a session token was received | +| `loginFailed` | — | Login failed (wrong credentials or server unreachable) | +| `allProjectsAvailable` | `QStringList projects` | List of project names returned by the server | +| `osmStringAvailable` | `QString osmString` | Full OSM file content returned after download | +| `errorOccured` | `QString message` | Any network or protocol error | +| `progressUpdated` | `int percent` | IFC check-in progress (0–100) | diff --git a/developer/doc/classes/bimserver/ProjectImporter.md b/developer/doc/classes/bimserver/ProjectImporter.md new file mode 100644 index 000000000..795b18161 --- /dev/null +++ b/developer/doc/classes/bimserver/ProjectImporter.md @@ -0,0 +1,100 @@ +# Class: `ProjectImporter` + +> **Module:** `bimserver` +> **Header:** [src/bimserver/ProjectImporter.hpp](../../../../src/bimserver/ProjectImporter.hpp) +> **Library doc:** [libraries/bimserver.md](../../libraries/bimserver.md) + +## Purpose + +`ProjectImporter` is a dialog-based workflow that guides the user through connecting to a BIMserver, listing available projects, selecting one, and importing it as an OpenStudio Model. + +It owns a `BIMserverConnection` and orchestrates the multi-step process: +1. Show the BIMserver address/port/credentials form +2. Log in and retrieve the project list +3. Let the user select a project and revision +4. Download the OSM content and parse it into an `openstudio::model::Model` + +--- + +## Class Diagram + +```mermaid +classDiagram + class QDialog { + <> + } + class ProjectImporter { + <> + +ProjectImporter(parent) + +exec() int + +getModel() optional~Model~ + signals: modelImported(Model) + slots: onLoginClicked() + slots: onProjectSelected(QString) + slots: onDownloadClicked() + slots: onLoginSuccess() + slots: onLoginFailed() + slots: onAllProjectsAvailable(QStringList) + slots: onOsmStringAvailable(QString) + slots: onErrorOccured(QString) + } + class BIMserverConnection { + +loginBlocked(...) bool + +getAllProjects() + +download(revisionID) + signals: loginSuccess, allProjectsAvailable, osmStringAvailable, errorOccured + } + + QDialog <|-- ProjectImporter + ProjectImporter "1" *-- "1" BIMserverConnection : owns +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `parent` | `QWidget*` | Qt parent widget | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `exec()` | `int` | Shows the dialog modally; returns `QDialog::Accepted` if the user successfully imported a project | +| `getModel()` | `boost::optional` | Returns the imported model after `exec()` returns `Accepted` | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelImported` | `model::Model` | Emitted when the import is complete; callers can connect to this to receive the model without waiting for `exec()` | + +--- + +## Import Workflow + +```mermaid +sequenceDiagram + participant User + participant Dialog as ProjectImporter + participant Conn as BIMserverConnection + + User->>Dialog: Enter BIMserver URL, credentials + User->>Dialog: Click Login + Dialog->>Conn: login(username, password) + Conn-->>Dialog: loginSuccess() + Dialog->>Conn: getAllProjects() + Conn-->>Dialog: allProjectsAvailable(projectList) + Dialog-->>User: Show project list + User->>Dialog: Select project + revision + User->>Dialog: Click Import + Dialog->>Conn: download(revisionID) + Conn-->>Dialog: osmStringAvailable(osmString) + Dialog->>Dialog: parse OSM string into Model + Dialog-->>User: Close dialog (Accepted) +``` diff --git a/developer/doc/classes/model_editor/AccessPolicyStore.md b/developer/doc/classes/model_editor/AccessPolicyStore.md new file mode 100644 index 000000000..cd76a1750 --- /dev/null +++ b/developer/doc/classes/model_editor/AccessPolicyStore.md @@ -0,0 +1,69 @@ +# Class: `AccessPolicyStore` + +> **Module:** `model_editor` +> **Header:** [src/model_editor/AccessPolicyStore.hpp](../../../../src/model_editor/AccessPolicyStore.hpp) +> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) + +## Purpose + +`AccessPolicyStore` is a singleton that controls which IDD fields `InspectorGadget` renders as editable, read-only, or hidden. It reads an XML policy file at startup and provides per-field `AccessPolicy` queries to `InspectorGadget` during widget construction. + +Without a loaded policy, all fields default to `FREE` (editable). + +--- + +## Class Diagram + +```mermaid +classDiagram + class AccessPolicyStore { + <> + +instance() AccessPolicyStore& + +loadFile(path) bool + +getPolicy(iddObjectType, fieldIndex) AccessPolicy + +setPolicy(iddObjectType, fieldIndex, policy) + } + class InspectorGadget { + # queries AccessPolicyStore per field + } + + AccessPolicyStore <-- InspectorGadget : queries +``` + +--- + +## `AccessPolicy` Enum + +| Value | Meaning | +|---|---| +| `FREE` | Field is editable; rendered as an input widget (spinbox, combobox, lineedit) | +| `LOCKED` | Field is read-only; rendered as a `QLabel` | +| `HIDDEN` | Field is not rendered at all | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `instance()` | `AccessPolicyStore&` | Returns the singleton instance | +| `loadFile(path)` | `bool` | Parses an XML policy file; returns `false` if the file cannot be opened or parsed | +| `getPolicy(iddObjectType, fieldIndex)` | `AccessPolicy` | Returns the policy for a specific IDD object type and field index | +| `setPolicy(iddObjectType, fieldIndex, policy)` | `void` | Programmatically overrides a policy at runtime | + +--- + +## Policy File Format + +The XML policy file specifies overrides from the `FREE` default: + +```xml + + + + + + +``` + +Fields not listed default to `FREE`. To lock all fields for an object type, specify policy `LOCKED` with `index="*"`. diff --git a/developer/doc/classes/model_editor/InspectorDialog.md b/developer/doc/classes/model_editor/InspectorDialog.md new file mode 100644 index 000000000..0c73bff27 --- /dev/null +++ b/developer/doc/classes/model_editor/InspectorDialog.md @@ -0,0 +1,72 @@ +# Class: `InspectorDialog` + +> **Module:** `model_editor` +> **Header:** [src/model_editor/InspectorDialog.hpp](../../../../src/model_editor/InspectorDialog.hpp) +> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) + +## Purpose + +`InspectorDialog` is a modal or modeless top-level dialog that hosts an `InspectorGadget`. It subscribes to a `Workspace` (or `Model`) to track object additions/removals and update the gadget whenever the selected object changes. + +It is primarily used as a standalone debugging tool and in the SketchUp plugin to inspect arbitrary model objects. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QDialog { + <> + } + class InspectorDialog { + +InspectorDialog(workspace, parent) + +setWorkspace(workspace) + +selectedObjectHandles() vector~Handle~ + +setSelectedObjectHandles(handles) + signals: workspaceChanged() + signals: workspaceObjectAdded(WorkspaceObject, IddObjectType, UUID) + signals: workspaceObjectRemoved(WorkspaceObject, IddObjectType, UUID) + signals: selectedObjectHandlesChanged(vector~Handle~) + } + class InspectorGadget { + +layoutModel(workspaceObj, ...) + } + class Workspace { + <> + } + + QDialog <|-- InspectorDialog + InspectorDialog "1" *-- "1" InspectorGadget : embeds + InspectorDialog --> Workspace : observes +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `workspace` | `openstudio::Workspace&` | The workspace to observe; the dialog subscribes to its object change signals | +| `parent` | `QWidget*` | Qt parent (can be nullptr for modeless usage) | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `setWorkspace(workspace)` | `void` | Detaches from old workspace, subscribes to new; clears and re-populates the gadget | +| `selectedObjectHandles()` | `vector` | Returns the handles of objects currently selected in the object type list | +| `setSelectedObjectHandles(handles)` | `void` | Programmatically selects objects to inspect | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `workspaceChanged` | — | Emitted when the workspace is replaced | +| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | +| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | +| `selectedObjectHandlesChanged` | `vector` | Emitted when selection changes | diff --git a/developer/doc/classes/model_editor/InspectorGadget.md b/developer/doc/classes/model_editor/InspectorGadget.md new file mode 100644 index 000000000..c2d675c65 --- /dev/null +++ b/developer/doc/classes/model_editor/InspectorGadget.md @@ -0,0 +1,96 @@ +# Class: `InspectorGadget` + +> **Module:** `model_editor` +> **Header:** [src/model_editor/InspectorGadget.hpp](../../../../src/model_editor/InspectorGadget.hpp) +> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) + +## Purpose + +`InspectorGadget` is the core widget of the `model_editor` module. It accepts any `WorkspaceObject` or `ModelObject` and automatically generates a widget layout for all its IDD-defined fields, using `AccessPolicyStore` to determine which fields are editable, read-only, or hidden. + +This provides a "free" generic inspector for any OpenStudio object type without writing bespoke UI code. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class Nano_Observer { + <> + } + class IGWidget { + <> + +sizeHint() QSize + } + class InspectorGadget { + <> + +layoutModel(workspaceObj, recursive, hideChildren) + +layoutModelObj(modelObj, recursive, hideChildren, locked) + +clear() + +toggleGreenButton(isPushButton) + +setEnabled(enabled) + signals: nameChanged(QString) + signals: toggleUnitsClicked(bool) + signals: workspaceObjectAdded(WorkspaceObject, IddObjectType, UUID) + signals: workspaceObjectRemoved(WorkspaceObject, IddObjectType, UUID) + } + class AccessPolicyStore { + <> + +getPolicy(type, fieldIndex) AccessPolicy + } + + QWidget <|-- IGWidget + Nano_Observer <|.. IGWidget + QWidget <|-- InspectorGadget + Nano_Observer <|.. InspectorGadget + InspectorGadget --> AccessPolicyStore : queries per field + InspectorGadget *-- IGWidget : renders fields into +``` + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `layoutModel(wObj, recursive, hideChildren)` | `void` | Populates the widget from a `WorkspaceObject`; recursively follows references if `recursive = true` | +| `layoutModelObj(mObj, recursive, hideChildren, locked)` | `void` | Same, but starts from a `ModelObject`; `locked = true` forces all fields into read-only mode | +| `clear()` | `void` | Removes all generated widgets | +| `toggleGreenButton(isPushButton)` | `void` | Switches the "inspect object" button style | +| `setEnabled(bool)` | `void` | Enables/disables all child widgets | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `nameChanged` | `QString newName` | Emitted when the user edits the object's Name field | +| `toggleUnitsClicked` | `bool displayIP` | Emitted when the IP/SI toggle button is clicked | +| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace; keeps the inspector in sync | +| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | + +--- + +## Field Generation Rules + +| IDD Field Type | `FREE` policy | `LOCKED` policy | +|---|---|---| +| Real | `QDoubleSpinBox` | `QLabel` | +| Integer | `QSpinBox` | `QLabel` | +| Alpha / String | `QLineEdit` | `QLabel` | +| Choice | `IGComboBox` | `QLabel` | +| Boolean | `QCheckBox` | `QLabel` | +| Object reference | `QLineEdit` + lookup button | `QLabel` (hyperlink) | + +Fields with `AccessPolicy::HIDDEN` are not rendered at all. + +--- + +## `IGWidget` + +`IGWidget` is a thin `QWidget`/`Nano::Observer` subclass that serves as the scroll area content host for the generated controls. It overrides `sizeHint()` to correctly report its natural size after field generation. diff --git a/developer/doc/classes/openstudio_app/OpenStudioApp.md b/developer/doc/classes/openstudio_app/OpenStudioApp.md new file mode 100644 index 000000000..79f352910 --- /dev/null +++ b/developer/doc/classes/openstudio_app/OpenStudioApp.md @@ -0,0 +1,115 @@ +# Class: `OpenStudioApp` + +> **Module:** `openstudio_app` +> **Header:** [src/openstudio_app/OpenStudioApp.hpp](../../../../src/openstudio_app/OpenStudioApp.hpp) +> **Library doc:** [libraries/openstudio_app.md](../../libraries/openstudio_app.md) + +## Purpose + +`OpenStudioApp` is the concrete application object for the standalone OpenStudio Application. It extends `OSAppBase` (which extends `QApplication`) and is instantiated once in `main()`. + +Responsibilities: +- Constructs the initial `StartupView` and `StartupMenu` at launch +- Opens new or existing `.osm` files and wraps them in an `OSDocument` +- Runs `osversion::VersionTranslator` asynchronously (via `QFutureWatcher`) when opening older model files +- Provides access to the component library and HVAC template library models +- Manages translation (i18n) via `QTranslator` +- Handles the `dview` external tool path preference + +--- + +## Class Diagram + +```mermaid +classDiagram + class QApplication { + <> + } + class BaseApp { + <> + } + class OSAppBase { + <> + +instance() OSAppBase* + +measureManager() MeasureManager& + +currentDocument() OSDocument* = 0 + } + class OpenStudioApp { + +OpenStudioApp(argc, argv) + +currentDocument() OSDocument* + +instance() OpenStudioApp* + +componentLibrary() Model + +hvacComponentLibrary() Model + +resourcesPath() path + +openstudioCLIPath() path + +dviewPath() path + } + + QApplication <|-- OSAppBase + BaseApp <|.. OSAppBase + OSAppBase <|-- OpenStudioApp +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `argc` | `int&` | Standard C++ `argc` (passed through to `QApplication`) | +| `argv` | `char**` | Standard C++ `argv` (passed through to `QApplication`) | + +The constructor initialises the Qt application, registers `QMetaTypes`, installs the application icon, loads the QSS stylesheet (`resources/openstudio.qss`), instantiates `MeasureManager`, and shows the `StartupView`. + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `currentDocument()` | `shared_ptr` | Returns the currently open document, or `nullptr` if no document is open | +| `instance()` | `OpenStudioApp*` | Static method; returns the singleton application instance cast to `OpenStudioApp*` | +| `componentLibrary()` | `model::Model` | Returns the loaded component library model (for drag-and-drop from the right column library tab) | +| `hvacComponentLibrary()` | `model::Model` | Returns the HVAC template library containing pre-built loop templates | +| `resourcesPath()` | `openstudio::path` | Absolute path to the application's resources directory, resolved relative to the running executable | +| `openstudioCLIPath()` | `openstudio::path` | Absolute path to the `openstudio` CLI executable bundled with the application | +| `dviewPath()` | `openstudio::path` | Path to the DView results viewer, from settings or inferred from `PATH` | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `requestCloseAll` | — | Emitted when the application is about to quit; triggers document close | +| `newModelDropped` | — | Emitted when the user drops a new model file onto the application window | + +--- + +## Key Data Members + +| Member | Type | Description | +|---|---|---| +| `m_startupView` | `StartupView*` | Splash/welcome screen shown before a document is open | +| `m_startupMenu` | `StartupMenu*` | Minimal menu bar for the startup screen | +| `m_document` | `shared_ptr` | The currently open document | +| `m_versionTranslator` | `QFutureWatcher<...>` | Async watcher for version translation tasks | +| `m_translators` | `QList` | Loaded i18n translators | + +--- + +## Usage Pattern + +```cpp +// main.cpp +int main(int argc, char *argv[]) { + OpenStudioApp app(argc, argv); + return app.exec(); +} +``` + +All subsequent access to the application object is via the static accessor: +```cpp +OpenStudioApp* app = OpenStudioApp::instance(); +auto model = app->currentDocument()->model(); +``` diff --git a/developer/doc/classes/openstudio_app/StartupView.md b/developer/doc/classes/openstudio_app/StartupView.md new file mode 100644 index 000000000..651fc3ba2 --- /dev/null +++ b/developer/doc/classes/openstudio_app/StartupView.md @@ -0,0 +1,60 @@ +# Class: `StartupView` + +> **Module:** `openstudio_app` +> **Header:** [src/openstudio_app/StartupView.hpp](../../../../src/openstudio_app/StartupView.hpp) +> **Library doc:** [libraries/openstudio_app.md](../../libraries/openstudio_app.md) + +## Purpose + +`StartupView` is the welcome/splash screen displayed when the OpenStudio Application launches and no document is yet open. It presents the user with options to create a new model, open an existing file, or select a recently used file. + +It is shown and hidden by `OpenStudioApp` in response to document open/close events. When the user opens a document, `StartupView` is hidden; when they close the last document, it reappears. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class StartupView { + +StartupView(parent) + signals: newFromTemplateClicked(NewFromTemplateAction) + signals: openClicked() + signals: recentModelClicked(path) + } + class OpenStudioApp { + -m_startupView: StartupView* + } + + QWidget <|-- StartupView + OpenStudioApp "1" --> "1" StartupView : owns, shows/hides +``` + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `newFromTemplateClicked` | `NewFromTemplateAction` | User clicked one of the "New from template" buttons; the action enum identifies which template | +| `openClicked` | — | User clicked "Open..." — triggers a file dialog in `OpenStudioApp` | +| `recentModelClicked` | `openstudio::path` | User selected a recently used model from the list | + +--- + +## Key Data Members + +The view contains: +- A logo/banner area with the OpenStudio Coalition branding +- A list of "New from template" buttons for common starting points (empty model, residential, commercial) +- An "Open..." button +- A scrollable recent files list showing the last N opened `.osm` files with their paths + +--- + +## Relationship to `StartupMenu` + +`StartupMenu` provides a minimal menu bar (File → New, Open, Quit) that is installed on the application's main window while `StartupView` is visible. When a document is loaded, the full `MainMenu` replaces it. diff --git a/developer/doc/classes/openstudio_lib/ConstructionsController.md b/developer/doc/classes/openstudio_lib/ConstructionsController.md new file mode 100644 index 000000000..4f04dfebb --- /dev/null +++ b/developer/doc/classes/openstudio_lib/ConstructionsController.md @@ -0,0 +1,61 @@ +# Class: `ConstructionsController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/ConstructionsController.hpp](../../../../src/openstudio_lib/ConstructionsController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`ConstructionsController` manages the Constructions sub-tab within the Constructions & Materials domain tab. It provides a list of all construction objects in the model, allows adding new constructions (by dropping from the component library or creating new ones), and drives the right-column inspector to show construction details when one is selected. + +It extends `OSVectorController` to supply the list of construction `OSItemId`s. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSVectorController { + <> + } + class ConstructionsController { + +ConstructionsController(model) + #makeVector() vector~OSItemId~ + #onDrop(itemId) + #onRemoveItem(item) + signals: modelObjectSelected(OptionalModelObject, bool) + } + class ConstructionsView { + <> + } + class ConstructionInspectorView { + +setConstruction(Construction) + } + + OSVectorController <|-- ConstructionsController + ConstructionsController --> ConstructionsView : populates + ConstructionsController --> ConstructionInspectorView : drives +``` + +--- + +## `makeVector()` Override + +Returns `OSItemId`s for all `openstudio::model::Construction`, `ConstructionWithInternalSource`, `ConstructionCfactorUndergroundWall`, `ConstructionFfactorGroundFloor`, and `ConstructionAirBoundary` objects in the model. + +## `onDrop()` Override + +Handles drops from the component library: if the dropped `OSItemId` references a BCL component or a component library construction, loads it into the model. + +## `onRemoveItem()` Override + +Removes the selected construction from the model after confirming there are no dependent surfaces still referencing it. + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelObjectSelected` | `OptionalModelObject, bool readOnly` | Emitted on selection; drives the inspector | diff --git a/developer/doc/classes/openstudio_lib/GeometryEditorController.md b/developer/doc/classes/openstudio_lib/GeometryEditorController.md new file mode 100644 index 000000000..c0f0b64c3 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/GeometryEditorController.md @@ -0,0 +1,85 @@ +# Class: `GeometryEditorController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/GeometryEditorController.hpp](../../../../src/openstudio_lib/GeometryEditorController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`GeometryEditorController` manages the Geometry tab's interactive 3D editor. The editor is implemented as a Qt WebEngine view hosting a JavaScript application that renders and edits OpenStudio geometry. The controller bridges the C++ model layer and the JavaScript geometry engine via `OSWebEnginePage`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class GeometryEditorController { + +GeometryEditorController(isIP, model) + +view() QWidget* + #m_view: QWidget* + } + class GeometryEditorView { + <> + +webEngineView() QWebEngineView* + } + class OSWebEnginePage { + <> + +setModel(model) + +getModel() Model + signals: modelChanged(Model) + } + + OSQObjectController <|-- GeometryEditorController + GeometryEditorController "1" *-- "1" GeometryEditorView : creates and stores as m_view + GeometryEditorView "1" *-- "1" OSWebEnginePage : hosts +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `isIP` | `bool` | Whether to display dimensions in imperial units | +| `model` | `const model::Model&` | The OpenStudio model whose geometry is displayed | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `view()` | `QWidget*` | The view widget (`GeometryEditorView`) to embed in the tab | + +--- + +## Architecture Note + +The geometry editor is built around a JS/C++ bridge: + +```mermaid +flowchart LR + CPP["C++ Model\n(openstudio::model::Model)"] + CTRL["GeometryEditorController"] + PAGE["OSWebEnginePage\n(QWebEnginePage)"] + WEB["Qt WebEngine\n(Chromium)"] + JS["JavaScript\nGeometry Engine\n(Three.js / custom)"] + GLTF["GLTF\n(TinyGLTF)"] + + CPP --"serialize to GLTF"--> GLTF + GLTF --> PAGE + PAGE --"postMessage / QWebChannel"--> WEB + WEB --> JS + JS --"user edits"--> WEB + WEB --"runJavaScript callback"--> PAGE + PAGE --"deserialize GLTF"--> CPP + CTRL --> PAGE +``` + +Model geometry is serialised to GLTF JSON and injected into the JavaScript engine; user edits in 3D are sent back as GLTF diffs, which `OSWebEnginePage` deserialises back into OpenStudio model objects. + +See [OSWebEnginePage](OSWebEnginePage.md) for the JS bridge API details. diff --git a/developer/doc/classes/openstudio_lib/HVACSystemsController.md b/developer/doc/classes/openstudio_lib/HVACSystemsController.md new file mode 100644 index 000000000..daeb438b9 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/HVACSystemsController.md @@ -0,0 +1,124 @@ +# Class: `HVACSystemsController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/HVACSystemsController.hpp](../../../../src/openstudio_lib/HVACSystemsController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`HVACSystemsController` manages the HVAC Systems tab, which is the most complex tab in the application. It displays a graphical scene of HVAC loops (air loops, plant loops, service water loops, VRF systems, refrigeration systems) and allows users to add, remove, and configure HVAC components by dragging them on the scene. + +The controller owns sub-controllers for different aspects of HVAC display: +- `HVACLayoutController` — manages the loop topology `QGraphicsScene` (component placement) +- `HVACControlsController` — manages the controls view (setpoint managers, availability managers, mechanical ventilation) +- `RefrigerationController` / `RefrigerationGridController` — dedicated refrigeration system view +- `VRFController` — dedicated VRF system view + +--- + +## Class Diagram + +```mermaid +classDiagram + class QObject { + <> + } + class Nano_Observer { + <> + } + class HVACSystemsController { + +HVACSystemsController(isIP, model) + +hvacSystemsView() HVACSystemsView* + +model() Model + +currentLoop() optional~Loop~ + +setCurrentLoop(loop) + signals: modelObjectSelected(OptionalModelObject, bool) + signals: itemRemoveClicked(OSItem*) + slots: addToModel(OSItemId) + slots: removeFromModel(OSItemId) + slots: toggleUnitsClicked(bool) + } + class HVACSystemsView { + +hvacGraphicsView() HVACGraphicsView* + signals: addSystemClicked, removeLoopClicked + } + class HVACLayoutController { + +loopScene() LoopScene* + } + class HVACControlsController { + +hvacControlsView() QWidget* + } + class VRFController { + +vrfView() QWidget* + } + class RefrigerationController { + +refrigerationView() QWidget* + } + class LoopListModel { + <> + +data(index, role) + } + + QObject <|-- HVACSystemsController + Nano_Observer <|.. HVACSystemsController + HVACSystemsController "1" *-- "1" HVACSystemsView : owns + HVACSystemsController "1" *-- "1" HVACLayoutController : owns + HVACSystemsController "1" *-- "1" HVACControlsController : owns + HVACSystemsController "1" *-- "1" VRFController : owns + HVACSystemsController "1" *-- "1" RefrigerationController : owns + HVACSystemsController --> LoopListModel : populates loop selector +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `isIP` | `bool` | Whether to display values in imperial units | +| `model` | `const model::Model&` | The OpenStudio model containing HVAC objects | + +--- + +## `SceneType` Enum + +| Value | Description | +|---|---| +| `TOPOLOGY` | Shows the graphical loop diagram (default) | +| `CONTROLS` | Shows the setpoint managers and controls configuration | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `hvacSystemsView()` | `HVACSystemsView*` | The main view widget for the HVAC tab | +| `model()` | `model::Model` | The current model | +| `currentLoop()` | `optional` | The currently selected loop (air, plant, or VRF) | +| `setCurrentLoop(loop)` | `void` | Switches the scene to display the given loop | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelObjectSelected` | `OptionalModelObject, bool readOnly` | Emitted when user clicks an HVAC component; drives the right-column inspector | +| `itemRemoveClicked` | `OSItem*` | Emitted when user removes a component | + +--- + +## Qt Slots + +| Slot | Arguments | Description | +|---|---|---| +| `addToModel` | `OSItemId` | Adds the identified HVAC component type to the current loop | +| `removeFromModel` | `OSItemId` | Removes the identified component from the current loop | +| `toggleUnitsClicked` | `bool displayIP` | Refreshes all numeric displays on units change | + +--- + +## HVAC Scenes + +The topology scene is built from `LoopScene` (for air/plant loops), `ServiceWaterScene` (for service hot water loops), and custom scenes for VRF and refrigeration. Each scene is a `QGraphicsScene` subclass containing `GridItem` and `SystemCenterItem` nodes connected by `TwoConnectorItem` edges, mirroring the loop topology in the model. diff --git a/developer/doc/classes/openstudio_lib/HVACSystemsView.md b/developer/doc/classes/openstudio_lib/HVACSystemsView.md new file mode 100644 index 000000000..1d07f7b34 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/HVACSystemsView.md @@ -0,0 +1,60 @@ +# Class: `HVACSystemsView` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/HVACSystemsView.hpp](../../../../src/openstudio_lib/HVACSystemsView.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`HVACSystemsView` is the top-level view widget for the HVAC Systems tab. It contains: +- A **loop selector** combo box listing all HVAC loops in the model +- A **scene type toggle** (Topology / Controls) +- A `HVACGraphicsView` (`QGraphicsView`) displaying either the loop diagram or the controls panel +- Toolbar buttons for adding/removing loops and HVAC systems + +It delegates all display and interaction logic to `HVACSystemsController`, which calls into `HVACLayoutController` and `HVACControlsController`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class HVACSystemsView { + +hvacGraphicsView() HVACGraphicsView* + +loopComboBox() QComboBox* + +topologyViewButton() QPushButton* + +controlsViewButton() QPushButton* + signals: addSystemClicked() + signals: removeLoopClicked() + signals: systemComboBoxIndexChanged(int) + signals: topologyViewClicked() + signals: controlsViewClicked() + } + class HVACGraphicsView { + <> + +setScene(QGraphicsScene*) + } + class HVACSystemsController { + +hvacSystemsView() HVACSystemsView* + } + + QWidget <|-- HVACSystemsView + HVACSystemsView "1" *-- "1" HVACGraphicsView : contains + HVACSystemsController "1" *-- "1" HVACSystemsView : owns +``` + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `addSystemClicked` | — | User clicked the "Add System" button to add a new HVAC template | +| `removeLoopClicked` | — | User clicked the "Remove Loop" button | +| `systemComboBoxIndexChanged` | `int index` | User selected a different loop from the drop-down | +| `topologyViewClicked` | — | User switched to the loop topology diagram | +| `controlsViewClicked` | — | User switched to the loop controls view | diff --git a/developer/doc/classes/openstudio_lib/InspectorController.md b/developer/doc/classes/openstudio_lib/InspectorController.md new file mode 100644 index 000000000..059fc9876 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/InspectorController.md @@ -0,0 +1,66 @@ +# Class: `InspectorController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/InspectorController.hpp](../../../../src/openstudio_lib/InspectorController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`InspectorController` manages the "Edit" tab of the right-column sidebar (`MainRightColumnController`). It receives `modelObjectSelected` signals from the active tab controller, determines the appropriate inspector view for the selected object type, and displays it. + +Each domain has its own set of `*InspectorView` classes. `InspectorController` acts as the dispatcher that selects and shows the correct view. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class InspectorController { + +inspectorView() InspectorView* + slots: selectItem(OSItem*) + slots: onClearSelection() + slots: onSelectModelObject(ModelObject) + } + class InspectorView { + <> + +selectModelObject(ModelObject) + +clearSelection() + signals: toggleUnitsClicked(bool) + } + class ScheduleDayView { + <> + } + class ConstructionInspectorView { + <> + } + + OSQObjectController <|-- InspectorController + InspectorController "1" *-- "1" InspectorView : owns + InspectorView <|-- ScheduleDayView + InspectorView <|-- ConstructionInspectorView +``` + +--- + +## Qt Slots + +| Slot | Arguments | Description | +|---|---|---| +| `selectItem(item)` | `OSItem*` | Called when an item is selected in any list or drop zone; looks up the model object and dispatches to `onSelectModelObject` | +| `onClearSelection()` | — | Clears the inspector (shows a blank/default pane) | +| `onSelectModelObject(obj)` | `model::ModelObject` | Determines the appropriate inspector view for `obj`'s IDD type and switches to it | + +--- + +## Inspector View Selection + +`InspectorController` maintains a `QStackedWidget` containing one inspector view per supported object type. On `onSelectModelObject()`, it: +1. Casts the `ModelObject` to the appropriate subtype +2. Calls `QStackedWidget::setCurrentWidget()` with the matching view +3. Calls `view->update(obj)` (or equivalent) to populate the fields + +Object types without a dedicated inspector view fall back to a generic `InspectorGadget`-based view from `model_editor`. diff --git a/developer/doc/classes/openstudio_lib/MainRightColumnController.md b/developer/doc/classes/openstudio_lib/MainRightColumnController.md new file mode 100644 index 000000000..5cac7c83d --- /dev/null +++ b/developer/doc/classes/openstudio_lib/MainRightColumnController.md @@ -0,0 +1,111 @@ +# Class: `MainRightColumnController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/MainRightColumnController.hpp](../../../../src/openstudio_lib/MainRightColumnController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`MainRightColumnController` manages the right-column sidebar that appears alongside every tab. The sidebar has three tabs: + +| Tab | ID | Contents | +|---|---|---| +| **My Model** | `MY_MODEL` | A list of model objects relevant to the currently active domain tab (e.g., schedule types while on the Schedules tab) | +| **Library** | `LIBRARY` | The local measure/component library browser (`LocalLibraryController`) | +| **Edit** | `EDIT` | An inspector/editor for the currently selected model object | + +`OSDocument` calls the `configureFor*SubTab()` slots whenever the active domain tab or sub-tab changes, which switches the right column's content to match the current context. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class MainRightColumnController { + +MainRightColumnController(model, resourcesPath) + +mainRightColumnView() HorizontalTabWidget* + +measureLibraryController() QSharedPointer~LocalLibraryController~ + +inspectorController() shared_ptr~InspectorController~ + +hideMyModelTab(bool) + +isMyModelTabHidden() bool + +registerSystemItem(handle, item) + +unregisterSystemItem(handle) + +systemItem(handle) SystemItem* + slots: configureForSiteSubTab(int) + slots: configureForSchedulesSubTab(int) + slots: configureForConstructionsSubTab(int) + slots: configureForGeometrySubTab(int) + slots: configureForHVACSystemsSubTab(int) + signals: toggleUnitsClicked(bool) + signals: itemRemoveClicked(OSItem*) + } + class HorizontalTabWidget { + +addTab(widget, label) + +selectTab(int) + } + class InspectorController { + +inspectorView() InspectorView* + +selectItem(OSItem*) + } + class LocalLibraryController { + +localLibraryView() LocalLibraryView* + } + + OSQObjectController <|-- MainRightColumnController + MainRightColumnController "1" *-- "1" HorizontalTabWidget : owns view + MainRightColumnController "1" *-- "1" InspectorController : owns (Edit tab) + MainRightColumnController "1" *-- "1" LocalLibraryController : owns (Library tab) +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `model` | `model::Model` | The document's model; passed to the inspector controller | +| `resourcesPath` | `openstudio::path` | Path used to resolve icon and library resources | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `mainRightColumnView()` | `HorizontalTabWidget*` | The widget to embed in the main window's sidebar area | +| `measureLibraryController()` | `QSharedPointer` | The Library tab's measure browser controller | +| `inspectorController()` | `shared_ptr` | The Edit tab's inspector controller | +| `hideMyModelTab(bool)` | `void` | Hides the My Model tab when the active domain does not use it (e.g., Run tab) | +| `registerSystemItem(handle, item)` | `void` | Registers a `SystemItem` (HVAC loop) by handle for colour-coordination with the HVAC view | +| `systemItem(handle)` | `SystemItem*` | Returns the registered `SystemItem` for a given handle | + +--- + +## Qt Slots (configureFor* methods) + +Each of these is called by `OSDocument` when the user navigates to the corresponding domain: + +| Slot | Purpose | +|---|---| +| `configureForSiteSubTab(int)` | Sets up the My Model tab for the Site/Geometry domain | +| `configureForSchedulesSubTab(int)` | Shows relevant schedule types in My Model | +| `configureForConstructionsSubTab(int)` | Shows constructions/materials in My Model | +| `configureForGeometrySubTab(int)` | Hides My Model; shows geometry-specific edit panel | +| `configureForHVACSystemsSubTab(int)` | Shows HVAC component library | +| `configureForSpacesSubTab(int)` | Shows space-related objects | +| `configureForSimSettingsSubTab(int)` | Shows simulation settings objects | +| `configureForRunSubTab(int)` | Hides My Model tab | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `toggleUnitsClicked` | `bool displayIP` | Forwarded from the inspector view to the document | +| `toggleDisplayAdditionalPropsClicked` | `bool` | Forwarded from the inspector view | +| `itemRemoveClicked` | `OSItem*` | Forwarded when the user removes an item from the inspector | diff --git a/developer/doc/classes/openstudio_lib/MainTabController.md b/developer/doc/classes/openstudio_lib/MainTabController.md new file mode 100644 index 000000000..25e772150 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/MainTabController.md @@ -0,0 +1,105 @@ +# Class: `MainTabController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/MainTabController.hpp](../../../../src/openstudio_lib/MainTabController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`MainTabController` is the abstract base class for every domain tab controller. A tab controller is responsible for: +- Creating and owning the domain's `MainTabView` (the central content widget) +- Implementing `setSubTab(int)` to switch between sub-tabs within the domain +- Forwarding model-object selection events, drag-and-drop zone interactions, and unit toggle signals up to `OSDocument` via signals + +Concrete sub-classes include `HVACSystemsTabController`, `ConstructionsTabController`, `SchedulesTabController`, `RunTabController`, etc. Each follows the pattern: construct the domain view in the constructor, populate it with sub-views, and emit signals when the user interacts with model objects. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class MainTabController { + <> + +MainTabController(mainContentWidget) + +mainContentWidget() MainTabView* + +setSubTab(int) = 0 + signals: modelObjectSelected(OptionalModelObject, bool) + signals: dropZoneItemSelected(OSItem*, bool) + signals: dropZoneItemClicked(OSItem*) + signals: toggleUnitsClicked(bool) + signals: toggleDisplayAdditionalPropsClicked(bool) + signals: itemRemoveClicked(OSItem*) + signals: downloadComponentsClicked() + signals: openLibDlgClicked() + } + class MainTabView { + +addTabWidget(QWidget*, QString label) + +setSubTab(int) + } + class HVACSystemsTabController { + +setSubTab(int) + } + class ConstructionsTabController { + +setSubTab(int) + } + class RunTabController { + +setSubTab(int) + signals: resultsGenerated(sqlPath, radianceOutputPath) + } + + OSQObjectController <|-- MainTabController + MainTabController "1" *-- "1" MainTabView : owns + MainTabController <|-- HVACSystemsTabController + MainTabController <|-- ConstructionsTabController + MainTabController <|-- RunTabController +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `mainContentWidget` | `MainTabView*` | The tab view owned by this controller | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `mainContentWidget()` | `MainTabView*` | The view managed by this controller | +| `setSubTab(int index)` | `void` | **Pure virtual** — switch to sub-tab at `index`. Implemented by each domain controller | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelObjectSelected` | `model::OptionalModelObject, bool readOnly` | Emitted when the user selects a model object; triggers the right-column inspector | +| `dropZoneItemSelected` | `OSItem*, bool readOnly` | Emitted when an item in a drop zone is selected | +| `dropZoneItemClicked` | `OSItem*` | Emitted on click (without necessarily selecting a different inspector) | +| `toggleUnitsClicked` | `bool displayIP` | Relays the IP/SI toggle from the view to the document | +| `toggleDisplayAdditionalPropsClicked` | `bool` | Relays the additional properties toggle | +| `itemRemoveClicked` | `OSItem*` | Emitted when the remove (×) button on an item is clicked | +| `downloadComponentsClicked` | — | Triggers opening the BCL component browser | +| `openLibDlgClicked` | — | Triggers opening the library selection dialog | + +--- + +## Implementing a New Tab Controller + +To add a new domain tab: + +1. Create a class that extends `MainTabController` +2. In the constructor, create the domain `MainTabView` and pass it to `MainTabController(view)` +3. Override `setSubTab(int)` to switch sub-views +4. Connect domain-specific interactions to the inherited signals above +5. Register the new tab in `OSDocument` by creating the controller and calling `MainWindow::addVerticalTabButton()` + +See [developer/doc/AddingHVACComponentsToGUI.md](../../AddingHVACComponentsToGUI.md) for a detailed walkthrough. diff --git a/developer/doc/classes/openstudio_lib/MainWindow.md b/developer/doc/classes/openstudio_lib/MainWindow.md new file mode 100644 index 000000000..7e1943b85 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/MainWindow.md @@ -0,0 +1,109 @@ +# Class: `MainWindow` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/MainWindow.hpp](../../../../src/openstudio_lib/MainWindow.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`MainWindow` is the application's top-level `QMainWindow`. It owns the vertical tab bar on the left side (which switches between domains like Geometry, HVAC, Schedules, etc.), the central tab content area, and the right-column inspector/library sidebar. + +`OSDocument` creates and owns one `MainWindow`. The main window is shown when a document opens and closed when the document closes. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QMainWindow { + <> + } + class MainWindow { + +MainWindow(isPlugin, parent) + +addVerticalTabButton(id, toolTip, selectedImg, unselectedImg, disabledImg) + +setView(MainTabView*, id) + +view() MainTabView* + +setMainRightColumnView(QWidget*) + +selectVerticalTab(id) + +selectVerticalTabByIndex(index) + +verticalTabIndex() int + +displayIP() bool + +verboseOutput() bool + +useClassicCLI() bool + +displayAdditionalProps() bool + +enableRevertToSavedAction(bool) + +closeSidebar() + +openSidebar() + +geometryDiagnostics() bool + +lastPath() QString + signals: closeClicked, displayIPClicked, displayAdditionalPropsClicked + signals: newClicked, loadFileClicked, saveAsFileClicked + signals: importClicked, importSDDClicked, importIFCClicked + signals: revertFileClicked, preferencesClicked, quitClicked + } + class VerticalTabWidget { + +addTabButton(id, toolTip, selectedImg, unselectedImg) + +selectTab(id) + signals: tabSelected(int) + } + class MainMenu { + +MenuBar items + } + class AnalyticsHelper { + +sendMessage(event) + } + + QMainWindow <|-- MainWindow + MainWindow "1" *-- "1" VerticalTabWidget : left sidebar + MainWindow "1" *-- "1" MainMenu : menu bar + MainWindow "1" --> "1" AnalyticsHelper : sends usage events +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `isPlugin` | `bool` | When `true`, hides the menu bar and adjusts layout for embedding in SketchUp | +| `parent` | `QWidget*` | Optional Qt parent widget | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `addVerticalTabButton(id, toolTip, ...)` | `void` | Adds a domain tab button to the left vertical tab bar | +| `setView(view, id)` | `void` | Replaces the central content area with the given `MainTabView` | +| `view()` | `MainTabView*` | Returns the currently displayed tab view | +| `setMainRightColumnView(widget)` | `void` | Sets the widget displayed in the right-column sidebar | +| `selectVerticalTab(id)` | `void` | Programmatically switches to the tab with the given ID | +| `verticalTabIndex()` | `int` | Returns the index of the currently selected tab | +| `displayIP()` | `bool` | Returns the current unit display preference (true = imperial) | +| `verboseOutput()` | `bool` | Returns whether verbose EnergyPlus output is requested | +| `useClassicCLI()` | `bool` | Returns whether the Ruby CLI (classic) is preferred over the C++ labs CLI | +| `displayAdditionalProps()` | `bool` | Returns whether additional properties columns are shown in grid views | +| `enableRevertToSavedAction(bool)` | `void` | Enables/disables the Revert menu action | +| `closeSidebar()` / `openSidebar()` | `void` | Collapses or expands the right-column sidebar | +| `geometryDiagnostics()` | `bool` | Returns whether geometry diagnostics mode is active | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `closeClicked` | — | User clicked the window close button | +| `displayIPClicked` | `bool` | User toggled IP/SI unit display | +| `displayAdditionalPropsClicked` | `bool` | User toggled additional properties columns | +| `newClicked` | — | File → New | +| `loadFileClicked` | — | File → Open | +| `saveAsFileClicked` | — | File → Save As | +| `importClicked` | — | File → Import (OSM) | +| `importSDDClicked` | — | File → Import SDD | +| `importIFCClicked` | — | File → Import IFC | +| `revertFileClicked` | — | File → Revert to Saved | +| `preferencesClicked` | — | Edit → Preferences | +| `quitClicked` | — | File → Quit | diff --git a/developer/doc/classes/openstudio_lib/MaterialsController.md b/developer/doc/classes/openstudio_lib/MaterialsController.md new file mode 100644 index 000000000..c11061d7a --- /dev/null +++ b/developer/doc/classes/openstudio_lib/MaterialsController.md @@ -0,0 +1,50 @@ +# Class: `MaterialsController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/MaterialsController.hpp](../../../../src/openstudio_lib/MaterialsController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`MaterialsController` manages the Materials sub-tab, listing all material objects in the model (opaque layer materials, glazing, window gas layers, blinds, screens, shades, etc.). Selecting a material in the list opens its type-specific inspector view in the right column. + +Like `ConstructionsController`, it extends `OSVectorController` to supply its item list. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSVectorController { + <> + } + class MaterialsController { + +MaterialsController(model) + #makeVector() vector~OSItemId~ + #onDrop(itemId) + #onRemoveItem(item) + signals: modelObjectSelected(OptionalModelObject, bool) + } + + OSVectorController <|-- MaterialsController +``` + +--- + +## Material Types Covered + +`makeVector()` scans the model for all of the following IDD types and returns one `OSItemId` per object: + +| Category | IDD Types | +|---|---| +| Opaque | `StandardOpaqueMaterial`, `MasslessOpaqueMaterial`, `RoofVegetation`, `AirGap` | +| Glazing | `SimpleGlazing`, `StandardGlazing`, `RefractionExtinctionGlazing`, `ThermochromicGlazing` | +| Window controls | `Blind`, `Screen`, `Shade`, `DaylightRedirectionDevice` | +| Gas layers | `Gas`, `GasMixture`, `GasCustom`, `AirWall` | + +--- + +## Inspector View Pattern + +`OSDocument` (or the parent tab controller) connects `modelObjectSelected` to `InspectorController`. The inspector then casts the `ModelObject` to its specific subtype and shows the matching inspector view (e.g., `StandardOpaqueMaterialInspectorView`, `SimpleGlazingInspectorView`). diff --git a/developer/doc/classes/openstudio_lib/ModelObjectListView.md b/developer/doc/classes/openstudio_lib/ModelObjectListView.md new file mode 100644 index 000000000..ca054ca91 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/ModelObjectListView.md @@ -0,0 +1,74 @@ +# Class: `ModelObjectListView` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/ModelObjectListView.hpp](../../../../src/openstudio_lib/ModelObjectListView.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`ModelObjectListView` is a generic list view for displaying any collection of model objects as `OSItem` rows. It is used throughout the application for the "My Model" tab contents — e.g., showing all space types, all constructions, all schedules — providing a simple way to browse and select model objects without a full grid view. + +It wraps an `OSVectorController` to obtain its item list, and re-renders whenever the controller emits `itemIds`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class ModelObjectListView { + +ModelObjectListView(iddObjectType, model, addScrollArea, overrideLock, parent) + +selectedItem() optional~ModelObject~ + +setIddObjectType(IddObjectType) + signals: itemSelected(ModelObject) + signals: itemRemoveClicked(ModelObject) + signals: selectionCleared() + } + class OSVectorController { + <> + } + class OSItemList { + <> + } + class OSItem { + } + + QWidget <|-- ModelObjectListView + ModelObjectListView "1" *-- "1" OSVectorController : uses + ModelObjectListView "1" *-- "1" OSItemList : renders into + OSItemList "1..*" *-- "0..*" OSItem : contains +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `iddObjectType` | `IddObjectType` | The IDD type of objects to display (e.g., `IddObjectType::OS_SpaceType`) | +| `model` | `model::Model` | The model to scan | +| `addScrollArea` | `bool` | Wraps the list in a `QScrollArea` when true | +| `overrideLock` | `bool` | When true, ignores field-lock policies (used in plugin mode) | +| `parent` | `QWidget*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `selectedItem()` | `optional` | Returns the currently selected model object, if any | +| `setIddObjectType(type)` | `void` | Changes the object type being displayed; triggers a full refresh | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `itemSelected` | `model::ModelObject` | Emitted when the user clicks an item; drives the right-column inspector | +| `itemRemoveClicked` | `model::ModelObject` | Emitted when the × button is clicked; the controller above handles deletion from the model | +| `selectionCleared` | — | Emitted when the selection is cleared (e.g., user clicks empty space) | diff --git a/developer/doc/classes/openstudio_lib/OSAppBase.md b/developer/doc/classes/openstudio_lib/OSAppBase.md new file mode 100644 index 000000000..b91d299c1 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSAppBase.md @@ -0,0 +1,110 @@ +# Class: `OSAppBase` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSAppBase.hpp](../../../../src/openstudio_lib/OSAppBase.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSAppBase` is the abstract base class for the application object. It extends both `QApplication` and the `BaseApp` interface, providing a concrete implementation of measure management, workspace signal routing, and the static singleton accessor — while leaving `currentDocument()` abstract for the concrete subclass (`OpenStudioApp`) to implement. + +This split allows the SketchUp plugin and standalone application to share all `MeasureManager`, BCL dialog, and workspace notification logic without duplicating it. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QApplication { + <> + } + class BaseApp { + <> + +mainWidget() QWidget* = 0 + +measureManager() MeasureManager& = 0 + +currentModel() optional~Model~ = 0 + +tempDir() optional~path~ = 0 + } + class OSAppBase { + <> + +instance() OSAppBase* + +currentDocument() OSDocument* = 0 + +mainWidget() QWidget* + +measureManager() MeasureManager& + +tempDir() optional~path~ + +currentModel() optional~Model~ + +updateSelectedMeasureState() + +addMeasure() + +updateMyMeasures() + +updateBCLMeasures() + +openBclDlg() + +notify(receiver, event) bool + slots: addWorkspaceObject, removeWorkspaceObject + signals: workspaceObjectAdded, workspaceObjectRemoved + } + class OpenStudioApp { + +currentDocument() OSDocument* + } + + QApplication <|-- OSAppBase + BaseApp <|.. OSAppBase + OSAppBase <|-- OpenStudioApp +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `argc` | `int&` | Passed through to `QApplication` | +| `argv` | `char**` | Passed through to `QApplication` | +| `t_measureManager` | `QSharedPointer` | Pre-constructed measure manager instance | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `instance()` | `OSAppBase*` | Returns the singleton application instance | +| `currentDocument()` | `shared_ptr` | **Pure virtual** — implemented by `OpenStudioApp` | +| `mainWidget()` | `QWidget*` | Returns the main window widget of the current document | +| `measureManager()` | `MeasureManager&` | Returns the application-wide measure manager | +| `tempDir()` | `optional` | Returns the path to a per-session temporary directory | +| `currentModel()` | `optional` | Returns the model from the current document, if one is open | +| `waitDialog()` | `shared_ptr` | Returns the shared "please wait" modal dialog | +| `dviewPath()` | `openstudio::path` | Returns the path to the DView results viewer | +| `notify(receiver, event)` | `bool` | Override of `QApplication::notify` — catches and logs C++ exceptions thrown inside Qt event handlers | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the current document's model; allows global listeners to react to any model object addition | +| `workspaceObjectAddedPtr` | `shared_ptr, IddObjectType, UUID` | Pointer variant for performance-sensitive listeners | +| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the current document's model | +| `workspaceObjectRemovedPtr` | `shared_ptr, IddObjectType, UUID` | Pointer variant | + +--- + +## Qt Slots + +| Slot | Arguments | Description | +|---|---|---| +| `addWorkspaceObject` | `WorkspaceObject, IddObjectType, UUID` | Connected to the model's object-added signal; re-emits as `workspaceObjectAdded` | +| `addWorkspaceObjectPtr` | `shared_ptr, ...` | Pointer variant | +| `removeWorkspaceObject` | `WorkspaceObject, IddObjectType, UUID` | Connected to the model's object-removed signal; re-emits as `workspaceObjectRemoved` | +| `removeWorkspaceObjectPtr` | `shared_ptr, ...` | Pointer variant | + +--- + +## Key Data Members + +| Member | Type | Description | +|---|---|---| +| `m_measureManager` | `QSharedPointer` | Shared measure management instance | +| `m_waitDialog` | `boost::shared_ptr` | Application-wide modal progress dialog | diff --git a/developer/doc/classes/openstudio_lib/OSDocument.md b/developer/doc/classes/openstudio_lib/OSDocument.md new file mode 100644 index 000000000..85366cedd --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSDocument.md @@ -0,0 +1,116 @@ +# Class: `OSDocument` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSDocument.hpp](../../../../src/openstudio_lib/OSDocument.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSDocument` is the central document class of the application. It owns exactly one `openstudio::model::Model` and orchestrates the entire GUI around it: it creates the `MainWindow`, instantiates all tab controllers, and connects model change signals to view updates. + +It corresponds to an open `.osm` file. When the user creates a new model or opens an existing one, a new `OSDocument` is constructed; when they close it, the `OSDocument` is destroyed along with all tabs and views. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class OSDocument { + +OSDocument(library, resourcesPath, model, filePath, isPlugin, startTabIndex, startSubTabIndex) + +model() Model + +mainWindow() MainWindow* + +savePath() QString + +modelTempDir() QString + +modified() bool + +setModel(model, modified, saveCurrentTabs) + +fromModel(itemId) bool + +fromComponentLibrary(itemId) bool + +fromBCL(itemId) bool + +save() + +saveAs() + signals: modelSaved(path), modelClosed, fileNameChanged(QString) + signals: toggleUnitsClicked(bool), toggleDisplayAdditionalPropsClicked(bool) + } + class MainWindow { + <> + } + class MainTabController { + <> + } + class MainRightColumnController { + } + class model_Model { + <> + } + + OSQObjectController <|-- OSDocument + OSDocument "1" *-- "1" MainWindow : creates and owns + OSDocument "1" *-- "1" MainTabController : active tab controller + OSDocument "1" *-- "1" MainRightColumnController : right column + OSDocument "1" --> "1" model_Model : wraps +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `library` | `model::Model` | Component library model used for drag-and-drop into the document | +| `resourcesPath` | `openstudio::path` | Path to application resources (icons, default files) | +| `model` | `model::OptionalModel` | Initial model to display; if empty, a new blank model is created | +| `filePath` | `QString` | Path of the file on disk; empty for new unsaved models | +| `isPlugin` | `bool` | `true` when hosted inside the SketchUp plugin (modifies layout) | +| `startTabIndex` | `int` | Which tab to show initially (0 = Site / Geometry) | +| `startSubTabIndex` | `int` | Which sub-tab to select within the initial tab | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `mainWindow()` | `MainWindow*` | The top-level `QMainWindow` associated with this document | +| `model()` | `model::Model` | The current OpenStudio model | +| `setModel(model, modified, saveCurrentTabs)` | `void` | Replaces the model (used after version translation, format import); saves and restores tab index | +| `modified()` | `bool` | `true` if the model has unsaved changes | +| `savePath()` | `QString` | Absolute path to the saved `.osm` file; empty if unsaved | +| `modelTempDir()` | `QString` | Path to the temporary working directory for this document's resources | +| `componentLibrary()` | `model::Model` | The component library model | +| `setComponentLibrary(model)` | `void` | Replaces the component library | +| `fromModel(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to an object in the current model | +| `fromComponentLibrary(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to an object in the component library | +| `fromBCL(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to a BCL component | +| `save()` | `bool` | Saves to the current `savePath()`; prompts "Save As" if unsaved | +| `saveAs()` | `bool` | Opens a file dialog for Save As | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelSaved` | `openstudio::path` | Emitted after a successful save, with the saved path | +| `modelClosed` | — | Emitted just before the document is destroyed | +| `fileNameChanged` | `QString` | Emitted when the save path changes (new save or Save As) | +| `toggleUnitsClicked` | `bool displayIP` | Relays the "Display IP/SI units" toggle from `MainWindow` to all tab views | +| `toggleDisplayAdditionalPropsClicked` | `bool` | Relays the "additional properties" visibility toggle | +| `treeChanged` | `openstudio::UUID` | Emitted when the model object hierarchy changes | + +--- + +## Key Data Members + +| Member | Type | Description | +|---|---|---| +| `m_model` | `model::Model` | The OpenStudio model being edited | +| `m_mainWindow` | `MainWindow*` | The document's top-level window | +| `m_mainTabController` | pointer to active controller | The currently displayed tab controller | +| `m_mainRightColumnController` | `MainRightColumnController*` | The right inspector/library column controller | +| `m_savePath` | `QString` | Current file path on disk | +| `m_modified` | `bool` | Dirty flag | +| `m_isPlugin` | `bool` | Whether hosted in SketchUp plugin mode | diff --git a/developer/doc/classes/openstudio_lib/OSDropZone.md b/developer/doc/classes/openstudio_lib/OSDropZone.md new file mode 100644 index 000000000..1deace1f0 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSDropZone.md @@ -0,0 +1,96 @@ +# Class: `OSDropZone` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSDropZone.hpp](../../../../src/openstudio_lib/OSDropZone.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSDropZone` is a widget that displays a single `OSItem` (or a placeholder when empty) and accepts drag-and-drop of model objects onto it. It is the standard UI element for one-to-one model relationships — e.g., "the heating coil for this air loop terminal", or "the schedule for this lights definition". + +When a user drags an item from a list and drops it onto an `OSDropZone`, the drop zone routes the event through its associated `OSVectorController`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class OSDropZone { + +OSDropZone(vectorController, text, size, growsDown, parent) + +setItemsAcceptable(acceptable) + +setItemsRemoveable(removeable) + +setAcceptedMimeType(type) + +setMaxItems(max) + signals: itemDropped(OSItemId) + signals: itemSelected(OSItem*) + signals: itemRemoveClicked(OSItem*) + signals: inFocus(bool, bool) + } + class OSVectorController { + <> + +drop(OSItemId) + signals: itemIds(vector~OSItemId~) + } + class OSItem { + +setRemoveable(bool) + } + + QWidget <|-- OSDropZone + OSDropZone "1" --> "1" OSVectorController : delegates drops + OSDropZone "1" --> "0..1" OSItem : displays current item +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `vectorController` | `OSVectorController*` | The controller managing the underlying model relationship | +| `text` | `QString` | Placeholder text shown when the zone is empty | +| `size` | `QSize` | Preferred size | +| `growsDown` | `bool` | If true, multiple items can be stacked vertically (acts as a multi-item zone) | +| `parent` | `QWidget*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `setItemsAcceptable(bool)` | `void` | Whether drops are currently accepted (may be disabled e.g. when a field is locked) | +| `setItemsRemoveable(bool)` | `void` | Whether the remove button is shown on the displayed item | +| `setAcceptedMimeType(QString)` | `void` | Restricts accepted drops to items with the given MIME type (object type filter) | +| `setMaxItems(int)` | `void` | Caps the number of items when `growsDown` is true | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `itemDropped` | `OSItemId` | Emitted when a valid item is dropped; forwarded to the vector controller's `drop()` slot | +| `itemSelected` | `OSItem*` | Emitted when the displayed item is clicked | +| `itemRemoveClicked` | `OSItem*` | Emitted when the × button is clicked on the current item | +| `inFocus` | `bool focused, bool readOnly` | Emitted when the drop zone gains or loses focus (used to update the right-column inspector) | + +--- + +## Usage Pattern + +`OSDropZone` is typically used inside an inspector view for a single-object relationship: + +```cpp +// In some inspector constructor: +auto ctrl = new MyRelationshipVectorController(m_model); +auto dropZone = new OSDropZone(ctrl, "Drop Coil Here"); +connect(dropZone, &OSDropZone::itemSelected, + this, &MyInspectorView::onItemSelected); +layout->addWidget(dropZone); +``` + +For multi-item ordered lists, use `OSItemList` or `OSDropZone` with `growsDown = true`. diff --git a/developer/doc/classes/openstudio_lib/OSItem.md b/developer/doc/classes/openstudio_lib/OSItem.md new file mode 100644 index 000000000..d26ad163a --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSItem.md @@ -0,0 +1,109 @@ +# Class: `OSItem` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSItem.hpp](../../../../src/openstudio_lib/OSItem.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSItem` is the base class for all draggable, selectable model object items rendered in the application's lists, drop zones, and library panels. It wraps an `OSItemId` (a lightweight identifier for a model object or BCL component) and provides the visual representation plus drag-and-drop support. + +`OSItemId` is a companion value type that identifies an item by its model object UUID (or BCL identifier), its source (model, component library, or BCL), and optional positional information. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class Nano_Observer { + <> + } + class OSItemId { + +itemId() QString + +sourceId() QString + +isDefaulted() bool + +position() optional~int~ + +mimeDataText() QString + +operator==(other) bool + } + class OSItem { + +makeItem(itemId, itemType) OSItem* + +itemId() OSItemId + +isDefaulted() bool + +selected() bool + +removeable() bool + +draggable() bool + +inspector() bool + +setSelected(bool) + +setRemoveable(bool) + +setDraggable(bool) + signals: itemSelected(OSItem*) + signals: itemRemoveClicked(OSItem*) + signals: itemReplacementDropped(OSItem*, OSItemId) + } + class ModelObjectItem { + +modelObject() ModelObject + } + class BCLComponentItem { + +bclComponent() BCLComponent + } + + QWidget <|-- OSItem + Nano_Observer <|.. OSItem + OSItem "1" *-- "1" OSItemId : wraps + OSItem <|-- ModelObjectItem + OSItem <|-- BCLComponentItem +``` + +--- + +## `OSItemId` Value Type + +| Method | Returns | Description | +|---|---|---| +| `itemId()` | `QString` | The UUID string of the underlying model object, or BCL identifier | +| `sourceId()` | `QString` | Identifies the source: model, component library, or `BCL_SOURCE_ID` | +| `isDefaulted()` | `bool` | True if this item represents a default (inherited) value | +| `position()` | `optional` | Positional index within an ordered list (e.g., construction layer) | +| `mimeDataText()` | `QString` | Full serialized representation for Qt drag-and-drop MIME data | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `makeItem(itemId, itemType)` | `OSItem*` (static) | Factory: creates the appropriate `OSItem` subclass for the given item ID and display type | +| `itemId()` | `OSItemId` | The underlying item identifier | +| `selected()` | `bool` | Whether this item is currently selected (highlighted) | +| `setSelected(bool)` | `void` | Selects/deselects this item; triggers visual update | +| `removeable()` | `bool` | Whether the remove (×) button is visible | +| `setRemoveable(bool)` | `void` | Shows/hides the remove button | +| `draggable()` | `bool` | Whether the item can be dragged | +| `inspector()` | `bool` | Whether clicking this item opens the right-column inspector | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `itemSelected` | `OSItem*` | Emitted when the item is clicked/selected | +| `itemRemoveClicked` | `OSItem*` | Emitted when the × remove button is clicked | +| `itemReplacementDropped` | `OSItem* current, OSItemId replacement` | Emitted when another item is dropped onto this one, triggering a replace operation | + +--- + +## `OSItemType` Enum + +Controls which visual style is applied to the item: + +| Value | Appearance | +|---|---| +| `ListItem` | Full-width horizontal bar with label | +| `DropzoneSquare` | Square compact tile for drop zones | +| `CollapsibleListHeader` | Header row for collapsible sections | diff --git a/developer/doc/classes/openstudio_lib/OSVectorController.md b/developer/doc/classes/openstudio_lib/OSVectorController.md new file mode 100644 index 000000000..b88085a27 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSVectorController.md @@ -0,0 +1,111 @@ +# Class: `OSVectorController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSVectorController.hpp](../../../../src/openstudio_lib/OSVectorController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSVectorController` is the abstract base class for all list/vector controllers in the application. It provides the protocol for managing an ordered list of `OSItemId`s that represent model objects displayed in an `OSItemList` or `OSDropZone` widget. + +Concrete subclasses implement `makeVector()` to return the current set of item IDs from the model. The base class handles the scheduling of re-renders (deduped with a mutex) and the routing of user interactions (remove, replace, drop, create) through virtual dispatch. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QObject { + <> + } + class Nano_Observer { + <> + } + class OSVectorController { + <> + +reportItems() + +removeItem(OSItem*) + +replaceItem(currentItem, replacementId) + +drop(OSItemId) + +makeNewItem() + #makeVector() vector~OSItemId~ = 0 + #onRemoveItem(item) + #onReplaceItem(item, replacementId) + #onDrop(itemId) + #onMakeNewItem() + signals: itemIds(vector~OSItemId~) + signals: selectedItemId(OSItemId) + } + class ConstructionObjectVectorController { + #makeVector() vector~OSItemId~ + #onDrop(itemId) + #onRemoveItem(item) + } + class DefaultConstructionSetsController { + #makeVector() vector~OSItemId~ + #onDrop(itemId) + } + + QObject <|-- OSVectorController + Nano_Observer <|.. OSVectorController + OSVectorController <|-- ConstructionObjectVectorController + OSVectorController <|-- DefaultConstructionSetsController +``` + +--- + +## Key Public Slots + +| Slot | Arguments | Description | +|---|---|---| +| `reportItems()` | — | Triggers `makeVector()` and emits `itemIds` with the result. Calls are deduplicated using a mutex so that rapid model changes only cause one repaint. | +| `removeItem(item)` | `OSItem*` | Called when the user removes an item (clicks the × button); dispatches to `onRemoveItem()` | +| `replaceItem(currentItem, replacementId)` | `OSItem*, OSItemId` | Called when an item is replaced by drag-and-drop; dispatches to `onReplaceItem()` | +| `drop(itemId)` | `OSItemId` | Called when an item is dropped into an associated `OSDropZone`; dispatches to `onDrop()` | +| `makeNewItem()` | — | Called when the user requests a new empty item; dispatches to `onMakeNewItem()` | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `itemIds` | `vector` | Emitted by `reportItems()` with the current ordered list of item IDs | +| `selectedItemId` | `OSItemId` | Emitted when the controller wants to notify listeners of a newly selected item | + +--- + +## Protected Virtual Methods (override points) + +| Method | Description | +|---|---| +| `makeVector()` | **Must override.** Return the current ordered list of `OSItemId`s from the model. | +| `onRemoveItem(item)` | Called when the user removes an item. Default: no-op. Override to delete from model. | +| `onReplaceItem(item, replacementId)` | Called when an item is replaced. Default: removes old, drops new. | +| `onDrop(itemId)` | Called when an item is dropped. Default: no-op. Override to insert into model. | +| `onMakeNewItem()` | Called to create a new blank item. Default: no-op. | + +--- + +## Usage Pattern + +```cpp +class MyController : public OSVectorController { +protected: + std::vector makeVector() override { + // Return OSItemIds for all objects of interest in the model + std::vector ids; + for (auto& obj : m_model.getModelObjects()) { + ids.push_back(modelObjectToItemId(obj, false)); + } + return ids; + } + + void onDrop(const OSItemId& itemId) override { + // Handle drop: add the dropped object to the model collection + } +}; +``` + +The controller is paired with an `OSDropZone` or `OSItemList` widget, which connects to `itemIds` to re-render whenever the model changes. diff --git a/developer/doc/classes/openstudio_lib/OSWebEnginePage.md b/developer/doc/classes/openstudio_lib/OSWebEnginePage.md new file mode 100644 index 000000000..71b6edb4d --- /dev/null +++ b/developer/doc/classes/openstudio_lib/OSWebEnginePage.md @@ -0,0 +1,87 @@ +# Class: `OSWebEnginePage` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/OSWebEnginePage.hpp](../../../../src/openstudio_lib/OSWebEnginePage.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`OSWebEnginePage` is a `QWebEnginePage` subclass that serves as the C++/JavaScript bridge for the geometry editor. It exposes a Qt-registered C++ object to the JavaScript engine so the web-based 3D geometry editor can read and write the OpenStudio model. + +The bridge is established via Qt WebChannel (`QWebChannel`), which makes the registered C++ object callable from JavaScript as if it were a native JS object. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWebEnginePage { + <> + } + class OSWebEnginePage { + +OSWebEnginePage(model, parent) + +setModel(model) + +getModel() Model + +translateModel(model) string + +javaScriptConsoleMessage(level, msg, lineNo, sourceID) + signals: modelChanged(Model) + } + class QWebChannel { + +registerObject(name, QObject*) + } + class GeometryEditorView { + <> + +webEngineView() QWebEngineView* + } + + QWebEnginePage <|-- OSWebEnginePage + OSWebEnginePage "1" *-- "1" QWebChannel : uses to expose self to JS + GeometryEditorView --> OSWebEnginePage : sets as page on QWebEngineView +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `model` | `const model::Model&` | Initial model whose geometry is serialised and sent to the JS engine | +| `parent` | `QObject*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `setModel(model)` | `void` | Serialises the model geometry to GLTF JSON and sends it to the JavaScript engine via `runJavaScript()` | +| `getModel()` | `model::Model` | Returns the current model maintained on the C++ side | +| `translateModel(model)` | `std::string` | Converts an `openstudio::model::Model` to a GLTF JSON string (uses TinyGLTF) | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelChanged` | `model::Model` | Emitted when the JavaScript editor sends back geometry changes; carries the updated model | + +--- + +## JavaScript Bridge API + +The following slots are exposed to JavaScript via `QWebChannel` under the registered object name `"openstudioApi"`: + +| JS-callable slot | C++ signature | Description | +|---|---|---| +| `getFloorplanJS()` | `Q_INVOKABLE QString getFloorplanJS()` | Returns the current model geometry as a floorplan JSON string | +| `setFloorplanJS(json)` | `Q_INVOKABLE void setFloorplanJS(QString)` | Receives updated floorplan JSON from the JS editor; deserialises into the model | +| `getGLTF()` | `Q_INVOKABLE QString getGLTF()` | Returns GLTF geometry JSON | +| `setGLTF(json)` | `Q_INVOKABLE void setGLTF(QString)` | Receives GLTF from the JS editor | + +--- + +## Console Message Logging + +`javaScriptConsoleMessage()` is overridden to forward JavaScript `console.log`/`console.error` messages to the C++ logger, making JavaScript errors visible in the application's debug output. diff --git a/developer/doc/classes/openstudio_lib/ResultsTabController.md b/developer/doc/classes/openstudio_lib/ResultsTabController.md new file mode 100644 index 000000000..6cc26b3c7 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/ResultsTabController.md @@ -0,0 +1,57 @@ +# Class: `ResultsTabController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/ResultsTabController.hpp](../../../../src/openstudio_lib/ResultsTabController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`ResultsTabController` manages the Results tab. After a simulation completes, `RunTabController` emits `resultsGenerated(sqlPath)`, which this controller receives to load and display the SQL results database. + +The results view shows: +- Summary metrics (site energy use intensity, end-use breakdown) +- Time-series charts for user-selected output variables +- Optional links to DView for advanced charting + +--- + +## Class Diagram + +```mermaid +classDiagram + class MainTabController { + <> + } + class ResultsTabController { + +ResultsTabController(model, sqlPath, radiancePath) + +setSubTab(int) + slots: onResultsGenerated(sqlPath, radiancePath) + } + class ResultsTabView { + <> + +loadResults(sqlPath) + +showSummary() + +showTimeSeries() + } + + MainTabController <|-- ResultsTabController + ResultsTabController "1" *-- "1" ResultsTabView : owns + ResultsTabController <.. RunTabController : receives resultsGenerated signal +``` + +--- + +## Qt Slots + +| Slot | Arguments | Description | +|---|---|---| +| `onResultsGenerated` | `openstudio::path sqlFile, openstudio::path radianceOutputFile` | Loads the SQL results database and re-populates the results views. Connected to `RunTabController::resultsGenerated`. | + +--- + +## Results View Content + +The `ResultsTabView` uses `QtCharts` to render: +- **End-use bar chart** — energy by end use (heating, cooling, lighting, equipment, fans, pumps, etc.) +- **Time-series chart** — selectable EnergyPlus output variable over the run period +- **Utility summary table** — site EUI, source EUI, annual cost estimate diff --git a/developer/doc/classes/openstudio_lib/RunTabController.md b/developer/doc/classes/openstudio_lib/RunTabController.md new file mode 100644 index 000000000..6842fe1d9 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/RunTabController.md @@ -0,0 +1,76 @@ +# Class: `RunTabController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/RunTabController.hpp](../../../../src/openstudio_lib/RunTabController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`RunTabController` manages the Run tab, which allows users to run an EnergyPlus simulation of the current model and monitor live output from the simulation process. When the simulation completes, it emits a signal with the path to the SQL results file, which triggers the Results tab to load them. + +--- + +## Class Diagram + +```mermaid +classDiagram + class MainTabController { + <> + } + class RunTabController { + +RunTabController(model, modelPath, tempFolder) + +setSubTab(int) + +updateToolsWarnings() + signals: resultsGenerated(sqlPath, radianceOutputPath) + signals: toolsUpdated() + } + class RunView { + +showSimulationControls() + +showOutputLog() + } + + MainTabController <|-- RunTabController + RunTabController "1" *-- "1" RunView : owns +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `model` | `const model::Model&` | Current model to simulate | +| `t_modelPath` | `const openstudio::path&` | Path to the saved `.osm` file | +| `t_tempFolder` | `const openstudio::path&` | Temporary working directory for simulation files | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `resultsGenerated` | `openstudio::path sqlFile, openstudio::path radianceOutputFile` | Emitted when the simulation completes successfully; drives the Results tab to load the SQL database | +| `toolsUpdated` | — | Emitted when EnergyPlus/Radiance tool paths change; may trigger warning banner updates | + +--- + +## Qt Slots + +| Slot | Description | +|---|---| +| `updateToolsWarnings()` | Checks whether EnergyPlus and Radiance are correctly located and updates any warning badges on the Run tab button | + +--- + +## Run Workflow + +```mermaid +flowchart TD + USER["User clicks Run"] --> SAVE["OSDocument saves model to temp dir"] + SAVE --> CLI["OpenStudio CLI spawned as QProcess\nwith the saved workflow file"] + CLI --> LOG["RunView streams stdout/stderr"] + LOG --> DONE{Exit code 0?} + DONE -- yes --> SIGNAL["emit resultsGenerated(sqlPath, ...)"] + DONE -- no --> ERR["Show error in output log"] + SIGNAL --> RESULTS["ResultsTabController loads SQL"] +``` diff --git a/developer/doc/classes/openstudio_lib/SchedulesController.md b/developer/doc/classes/openstudio_lib/SchedulesController.md new file mode 100644 index 000000000..6004003fd --- /dev/null +++ b/developer/doc/classes/openstudio_lib/SchedulesController.md @@ -0,0 +1,66 @@ +# Class: `SchedulesController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/SchedulesController.hpp](../../../../src/openstudio_lib/SchedulesController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`SchedulesController` manages the Schedules domain tab. It displays a tree of schedule rule sets and schedule types, and provides a `ScheduleDayView` inspector that lets users graphically edit day-profile values with a chart-based editor. + +--- + +## Class Diagram + +```mermaid +classDiagram + class MainTabController { + <> + } + class SchedulesTabController { + +setSubTab(int) + } + class SchedulesController { + +SchedulesController(model, isIP) + #makeVector() vector~OSItemId~ + signals: modelObjectSelected(OptionalModelObject, bool) + } + class SchedulesDayView { + <> + +setScheduleDay(ScheduleDay) + signals: scheduleValueChanged(double time, double value) + } + class ScheduleDialog { + +exec() int + +schedule() ScheduleRuleset + } + + MainTabController <|-- SchedulesTabController + SchedulesTabController "1" *-- "1" SchedulesController : owns + SchedulesController --> SchedulesDayView : drives + SchedulesController ..> ScheduleDialog : opens for new schedules +``` + +--- + +## Day Schedule Editor + +The `SchedulesDayView` provides a graphical plot of a schedule day profile: +- X axis: time of day (00:00–24:00) +- Y axis: fractional value or absolute value (depending on schedule type limits) +- User can click and drag to set values at any time point +- Supports fractional interpolation and step profiles + +--- + +## Schedule Types Shown + +`makeVector()` returns all `ScheduleRuleset`, `ScheduleConstant`, `ScheduleCompact`, and `ScheduleFile` objects. + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelObjectSelected` | `OptionalModelObject, bool` | Emitted when a schedule is selected; drives the day-schedule editor | diff --git a/developer/doc/classes/openstudio_lib/SpaceTypesController.md b/developer/doc/classes/openstudio_lib/SpaceTypesController.md new file mode 100644 index 000000000..b64f06d2c --- /dev/null +++ b/developer/doc/classes/openstudio_lib/SpaceTypesController.md @@ -0,0 +1,54 @@ +# Class: `SpaceTypesController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/SpaceTypesController.hpp](../../../../src/openstudio_lib/SpaceTypesController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`SpaceTypesController` manages the Space Types tab, which shows all space type objects in the model in a grid view. Each row is a space type; columns show its name, default construction set, default schedule set, lighting power density, people density, equipment, outdoor air, and rendering color. + +It is a `MainTabController` subclass that owns a `SpaceTypesGridView` powered by a domain-specific `OSGridController`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class MainTabController { + <> + } + class SpaceTypesController { + +SpaceTypesController(isIP, model) + +setSubTab(int) + signals: modelObjectSelected(OptionalModelObject, bool) + } + class SpaceTypesGridView { + <> + } + class SpaceTypeInspectorView { + <> + +setSpaceType(SpaceType) + } + + MainTabController <|-- SpaceTypesController + SpaceTypesController "1" *-- "1" SpaceTypesGridView : owns + SpaceTypesController --> SpaceTypeInspectorView : drives on selection +``` + +--- + +## Grid Columns + +The `SpaceTypesGridController` defines these columns (not exhaustive): + +| Column | Field | +|---|---| +| Name | `SpaceType::name()` | +| Default Construction Set | `SpaceType::defaultConstructionSet()` | +| Default Schedule Set | `SpaceType::defaultScheduleSet()` | +| Space Type Color | `SpaceType::renderingColor()` | +| Lighting Power Density | `SpaceType::lightingPowerDensity()` | +| People Definition | `SpaceType::people()` | +| Outdoor Air | `SpaceType::designSpecificationOutdoorAir()` | diff --git a/developer/doc/classes/openstudio_lib/ThermalZonesController.md b/developer/doc/classes/openstudio_lib/ThermalZonesController.md new file mode 100644 index 000000000..5ca79c473 --- /dev/null +++ b/developer/doc/classes/openstudio_lib/ThermalZonesController.md @@ -0,0 +1,46 @@ +# Class: `ThermalZonesController` + +> **Module:** `openstudio_lib` +> **Header:** [src/openstudio_lib/ThermalZonesController.hpp](../../../../src/openstudio_lib/ThermalZonesController.hpp) +> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) + +## Purpose + +`ThermalZonesController` manages the Thermal Zones tab, showing all thermal zone objects in the model in a grid view. Each row represents one zone; columns expose thermostat types, humidistats, zone multipliers, cooling/heating ideal air loads, zone equipment, and DOAS connections. + +--- + +## Class Diagram + +```mermaid +classDiagram + class MainTabController { + <> + } + class ThermalZonesController { + +ThermalZonesController(isIP, model) + +setSubTab(int) + signals: modelObjectSelected(OptionalModelObject, bool) + } + class ThermalZonesGridView { + <> + } + + MainTabController <|-- ThermalZonesController + ThermalZonesController "1" *-- "1" ThermalZonesGridView : owns +``` + +--- + +## Grid Columns (representative) + +| Column | Field | +|---|---| +| Name | `ThermalZone::name()` | +| Thermostat | `ThermalZone::thermostat()` | +| Humidistat | `ThermalZone::zoneControlHumidistat()` | +| Multiplier | `ThermalZone::multiplier()` | +| Use Ideal Air Loads | `ThermalZone::useIdealAirLoads()` | +| DOAS Airloop | `ThermalZone::airLoopHVAC()` | +| Zone Conditioning Equip | `ThermalZone::equipment()` | +| Rendering Color | `ThermalZone::renderingColor()` | diff --git a/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md b/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md new file mode 100644 index 000000000..8d3f5d546 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md @@ -0,0 +1,60 @@ +# Class: `BCLMeasureDialog` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/BCLMeasureDialog.hpp](../../../../src/shared_gui_components/BCLMeasureDialog.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`BCLMeasureDialog` is a modal dialog that lets users search and download OpenStudio Measures from the NREL Building Component Library (BCL). It queries the BCL REST API, displays results with taxonomy filtering and free-text search, and downloads selected measures to the local BCL cache. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QDialog { + <> + } + class BCLMeasureDialog { + +BCLMeasureDialog(app, parent) + +exec() int + +selectedMeasure() optional~BCLMeasure~ + slots: onSearchClicked() + slots: onDownloadClicked() + signals: measureDownloaded(BCLMeasure) + } + class MeasureManager { + +downloadMeasure(uid) + } + + QDialog <|-- BCLMeasureDialog + BCLMeasureDialog --> MeasureManager : triggers download via +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `app` | `BaseApp*` | Application interface for accessing `MeasureManager` | +| `parent` | `QWidget*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `exec()` | `int` | Shows the dialog modally; returns `QDialog::Accepted` if the user downloaded a measure | +| `selectedMeasure()` | `optional` | Returns the last downloaded/selected measure after `exec()` returns | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `measureDownloaded` | `BCLMeasure` | Emitted when a measure is successfully downloaded to the local cache | diff --git a/developer/doc/classes/shared_gui_components/BaseApp.md b/developer/doc/classes/shared_gui_components/BaseApp.md new file mode 100644 index 000000000..c3ee238b7 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/BaseApp.md @@ -0,0 +1,63 @@ +# Class: `BaseApp` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/BaseApp.hpp](../../../../src/shared_gui_components/BaseApp.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`BaseApp` is a pure abstract interface that decouples all shared GUI components from any specific application implementation. Widgets like `MeasureManager`, `LocalLibraryController`, and `BuildingComponentDialog` depend only on `BaseApp`, not on `OSAppBase` or `OpenStudioApp`. This isolation enables the shared components to be hosted inside the SketchUp plugin or any other Qt host without modification. + +`OSAppBase` implements `BaseApp`, satisfying the contract for both the standalone application and plugin contexts. + +--- + +## Class Diagram + +```mermaid +classDiagram + class BaseApp { + <> + +mainWidget() QWidget* = 0 + +measureManager() MeasureManager& = 0 + +updateSelectedMeasureState() = 0 + +addMeasure() = 0 + +duplicateSelectedMeasure() = 0 + +updateMyMeasures() = 0 + +updateBCLMeasures() = 0 + +openBclDlg() = 0 + +checkForRemoteBCLUpdates() = 0 + +chooseHorizontalEditTab() = 0 + +editController() QSharedPointer~EditController~ = 0 + +tempDir() optional~path~ = 0 + +currentModel() optional~Model~ = 0 + } + class OSAppBase { + +mainWidget() QWidget* + +measureManager() MeasureManager& + +currentModel() optional~Model~ + ... + } + + BaseApp <|.. OSAppBase +``` + +--- + +## Abstract Methods + +| Method | Returns | Description | +|---|---|---| +| `mainWidget()` | `QWidget*` | The application's main window widget | +| `measureManager()` | `MeasureManager&` | Access to the application's measure manager | +| `updateSelectedMeasureState()` | `void` | Refresh the enable/disable state of measure-related actions | +| `addMeasure()` | `void` | Trigger the "Add Measure" workflow | +| `duplicateSelectedMeasure()` | `void` | Duplicate the currently selected measure | +| `updateMyMeasures()` | `void` | Re-scan the user's local measures directory | +| `updateBCLMeasures()` | `void` | Re-scan the BCL local cache | +| `openBclDlg()` | `void` | Open the BCL measure browser dialog | +| `checkForRemoteBCLUpdates()` | `void` | Query the BCL server for updated measures | +| `chooseHorizontalEditTab()` | `void` | Switch the right column to the Edit tab | +| `editController()` | `QSharedPointer` | The right-column edit controller | +| `tempDir()` | `optional` | Path to the session temporary directory | +| `currentModel()` | `optional` | The current model, if any | diff --git a/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md b/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md new file mode 100644 index 000000000..fe79dc573 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md @@ -0,0 +1,63 @@ +# Class: `BuildingComponentDialog` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/BuildingComponentDialog.hpp](../../../../src/shared_gui_components/BuildingComponentDialog.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`BuildingComponentDialog` is a modal dialog for browsing and downloading building components (constructions, materials, schedules, etc.) from the NREL Building Component Library (BCL). Once downloaded, the component is available for drag-and-drop into the relevant model views. + +It is analogous to `BCLMeasureDialog` but targets BCL *components* rather than *measures*. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QDialog { + <> + } + class BCLSearchResult { + +uid() QString + +name() QString + +description() QString + } + class BuildingComponentDialog { + +BuildingComponentDialog(filterType, app, parent) + +exec() int + +selectedComponent() optional~BCLComponent~ + signals: componentDownloaded(BCLComponent) + } + + QDialog <|-- BuildingComponentDialog + BuildingComponentDialog --> BCLSearchResult : displays search results +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `filterType` | `QString` | BCL component type to filter results (e.g., `"Construction"`, `"Material"`) | +| `app` | `BaseApp*` | Application interface | +| `parent` | `QWidget*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `exec()` | `int` | Shows the dialog modally | +| `selectedComponent()` | `optional` | The downloaded component after `exec()` returns | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `componentDownloaded` | `BCLComponent` | Emitted after a successful component download | diff --git a/developer/doc/classes/shared_gui_components/LocalLibraryController.md b/developer/doc/classes/shared_gui_components/LocalLibraryController.md new file mode 100644 index 000000000..1208dc893 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/LocalLibraryController.md @@ -0,0 +1,93 @@ +# Class: `LocalLibraryController` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/LocalLibraryController.hpp](../../../../src/shared_gui_components/LocalLibraryController.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`LocalLibraryController` manages the "Library" tab of the right-column sidebar. It provides a searchable, filterable browser of all locally available OpenStudio Measures (from both `myMeasures` and the BCL cache), organized by taxonomy category. + +Users can browse, search, and select measures from this list; the selected measure can then be dragged into the workflow or applied immediately via `ApplyMeasureNowDialog`. + +--- + +## Class Diagram + +```mermaid +classDiagram + class OSQObjectController { + <> + } + class LocalLibraryController { + +LocalLibraryController(app, parent) + +localLibraryView() LocalLibraryView* + signals: addMeasureClicked() + signals: duplicateMeasureClicked() + signals: removeMeasureClicked() + signals: applyMeasureClicked(BCLMeasure) + slots: onMeasureSelected(BCLMeasure) + slots: refresh() + } + class LocalLibraryView { + <> + +searchBox() QLineEdit* + +categoryTree() QTreeView* + +measureList() QListView* + } + class MeasureManager { + +combinedMeasures() vector~BCLMeasure~ + } + class TIDItemModel { + <> + # taxonomy tree data model + } + + OSQObjectController <|-- LocalLibraryController + LocalLibraryController "1" *-- "1" LocalLibraryView : owns + LocalLibraryController --> MeasureManager : queries + LocalLibraryController --> TIDItemModel : populates taxonomy tree +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `app` | `BaseApp*` | Application interface for accessing `MeasureManager` | +| `parent` | `QObject*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `localLibraryView()` | `LocalLibraryView*` | The view widget to embed in the right-column sidebar | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `addMeasureClicked` | — | User clicked the "Add Measure" button; opens the new measure wizard | +| `duplicateMeasureClicked` | — | User duplicated the selected measure | +| `removeMeasureClicked` | — | User deleted the selected measure from local disk | +| `applyMeasureClicked` | `BCLMeasure` | User pressed "Apply Now"; triggers `ApplyMeasureNowDialog` | + +--- + +## Qt Slots + +| Slot | Description | +|---|---| +| `onMeasureSelected(BCLMeasure)` | Updates the detail panel with the selected measure's metadata | +| `refresh()` | Rebuilds the taxonomy tree and measure list from `MeasureManager::combinedMeasures()` | + +--- + +## Taxonomy Browsing + +`LocalLibraryController` uses `TIDItemModel` to display measures in a hierarchical taxonomy tree (e.g., Whole Building > Space Types > Lighting > ...). The taxonomy IDs come from the BCL taxonomy metadata embedded in each `BCLMeasure`. diff --git a/developer/doc/classes/shared_gui_components/MeasureManager.md b/developer/doc/classes/shared_gui_components/MeasureManager.md new file mode 100644 index 000000000..5bca1af7b --- /dev/null +++ b/developer/doc/classes/shared_gui_components/MeasureManager.md @@ -0,0 +1,92 @@ +# Class: `MeasureManager` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/MeasureManager.hpp](../../../../src/shared_gui_components/MeasureManager.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`MeasureManager` is the central manager for all OpenStudio Measures available to the application. It: +- Scans the user's `myMeasures` directory and the local BCL cache for available measures +- Deduplicates measures across both locations by UUID (preferring `myMeasures`) +- Checks for newer versions of measures in the project against the local library +- Provides the data source for the `LocalLibraryController` (measure browser) +- Manages the background update workflow for syncing project measures + +--- + +## Class Diagram + +```mermaid +classDiagram + class QObject { + <> + } + class MeasureManager { + +MeasureManager(app: BaseApp*) + +url() QUrl + +myMeasures() vector~BCLMeasure~ + +bclMeasures() vector~BCLMeasure~ + +combinedMeasures() vector~BCLMeasure~ + +getMeasureByUID(uid) optional~BCLMeasure~ + +checkForLocalUpdates() + +updateMeasures(app, measures, force) + +downloadMeasure(uid) + signals: measureUpdated(BCLMeasure) + signals: localLibraryChanged() + } + class BaseApp { + <> + } + class LocalLibraryController { + +localLibraryView() LocalLibraryView* + } + + QObject <|-- MeasureManager + MeasureManager --> BaseApp : uses + MeasureManager <-- LocalLibraryController : observes +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `t_app` | `BaseApp*` | The application interface; provides `tempDir()`, `currentModel()`, and UI hooks | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `myMeasures()` | `vector` | All measures found in the user's `myMeasures` directory | +| `bclMeasures()` | `vector` | All measures in the local BCL cache | +| `combinedMeasures()` | `vector` | Merged and deduplicated list (myMeasures preferred when UUID collides) | +| `getMeasureByUID(uid)` | `optional` | Looks up a measure by its UUID string | +| `checkForLocalUpdates()` | `void` | Re-scans both measure directories and emits `localLibraryChanged` if anything changed | +| `updateMeasures(app, measures, force)` | `void` | For each measure in the project workflow, checks if a newer version exists locally and optionally updates | +| `downloadMeasure(uid)` | `void` | Downloads a measure from the BCL to the local cache | +| `url()` | `QUrl` | The BCL API base URL | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `measureUpdated` | `BCLMeasure` | Emitted when a measure in the project has been updated to a newer local version | +| `localLibraryChanged` | — | Emitted after a rescan finds changes; triggers `LocalLibraryController` to refresh | + +--- + +## Thread Safety + +`MeasureManager` uses a `QMutex` to protect its internal measure index. BCL download network requests are performed on the Qt network thread; completion signals are delivered on the GUI thread via queued connections. + +--- + +## Measure Priority + +When the same UUID exists in both `myMeasures` and the BCL cache, `combinedMeasures()` always returns the `myMeasures` copy. This supports the workflow of: download from BCL → customise locally → `myMeasures` version takes precedence. diff --git a/developer/doc/classes/shared_gui_components/OSGridController.md b/developer/doc/classes/shared_gui_components/OSGridController.md new file mode 100644 index 000000000..380719a54 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/OSGridController.md @@ -0,0 +1,100 @@ +# Class: `OSGridController` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/OSGridController.hpp](../../../../src/shared_gui_components/OSGridController.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`OSGridController` is the abstract base class for all multi-column tabular model views. It provides a declarative column-definition API (`add*Column()` methods) and manages row-object mapping, selection state, and cell widget creation on demand. + +Concrete subclasses declare their columns in their constructor by calling the `add*Column()` methods, which the base class uses to render each cell through an `OSCellWrapper`. Data is fetched lazily via `std::function` getters/setters rather than through Qt's model/view. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QObject { + <> + } + class OSGridController { + <> + +rowCount() int + +columnCount() int + +objectAt(row) ModelObject + +addCheckBoxColumn(heading, getter, setter) + +addComboBoxColumn(heading, choices, getter, setter) + +addDoubleEditColumn(heading, getter, setter, precision) + +addDropZoneColumn(heading, vectorController) + +addLineEditColumn(heading, getter, setter) + +addIntegerEditColumn(heading, getter, setter) + +addRenderingColorColumn(heading, getter) + +refreshAll() + signals: modelReset() + signals: itemSelected(OSItem*, bool) + } + class OSObjectSelector { + +selectRow(int) + +selectedRows() vector~int~ + +selectedObjects() vector~ModelObject~ + } + class OSCellWrapper { + <> + +setContent(QWidget*) + } + class ThermalZonesGridController { + +ThermalZonesGridController(isIP, model) + # defines columns in ctor + } + class SpaceTypesGridController { + +SpaceTypesGridController(isIP, model) + } + + QObject <|-- OSGridController + OSGridController "1" *-- "1" OSObjectSelector : owns + OSGridController "1" *-- "N" OSCellWrapper : creates lazily + OSGridController <|-- ThermalZonesGridController + OSGridController <|-- SpaceTypesGridController +``` + +--- + +## Column Definition API + +All `add*Column()` methods accept a heading string and typed getter/setter functions: + +| Method | Widget type | Getter | Setter | +|---|---|---|---| +| `addCheckBoxColumn` | `OSCheckBox2` | `function` | `function` | +| `addComboBoxColumn` | `OSComboBox2` | `function` | `function` | +| `addDoubleEditColumn` | `OSDoubleEdit2` | `function(ModelObject)>` | `function` | +| `addDropZoneColumn` | `OSDropZone` | `OSVectorController` subclass | — | +| `addLineEditColumn` | `OSLineEdit2` | `function` | `function` | +| `addIntegerEditColumn` | `OSIntegerEdit2` | `function(ModelObject)>` | `function` | +| `addRenderingColorColumn` | `RenderingColorWidget` | `function(ModelObject)>` | — | + +### `DataSource` Adapter + +Columns can optionally be wrapped in a `DataSource`, which maps a `ModelObject` to a `std::vector` of sub-objects, creating a stacked column to display multiple widgets per row cell (e.g., all space load instances for a space type). + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `rowCount()` | `int` | Number of data rows (model objects) | +| `columnCount()` | `int` | Number of defined columns | +| `objectAt(row)` | `model::ModelObject` | Returns the model object for the given row | +| `refreshAll()` | `void` | Forces a full re-render of all cells | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `modelReset` | — | Emitted when the underlying object list changes and all rows must be re-generated | +| `itemSelected` | `OSItem*, bool readOnly` | Emitted when a row object is selected; drives the right-column inspector | diff --git a/developer/doc/classes/shared_gui_components/OSGridView.md b/developer/doc/classes/shared_gui_components/OSGridView.md new file mode 100644 index 000000000..8e266b171 --- /dev/null +++ b/developer/doc/classes/shared_gui_components/OSGridView.md @@ -0,0 +1,73 @@ +# Class: `OSGridView` + +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/OSGridView.hpp](../../../../src/shared_gui_components/OSGridView.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) + +## Purpose + +`OSGridView` is the `QWidget` that hosts and renders an `OSGridController`. It manages a `QScrollArea` containing a grid of `OSCellWrapper` widgets arranged in rows and columns. It handles row selection highlighting and forwards keyboard navigation events to the controller. + +Domain views (e.g., `ThermalZonesGridView`, `SpaceTypesGridView`) typically subclass `OSGridView` or compose it into a larger layout with filter/search bars. + +--- + +## Class Diagram + +```mermaid +classDiagram + class QWidget { + <> + } + class OSGridView { + +OSGridView(gridController, headerText, dropZoneText, isIP, parent) + +setGridController(OSGridController*) + +gridController() OSGridController* + +selectRow(int) + +selectedRows() vector~int~ + signals: rowSelected(int) + signals: dropZoneClicked() + } + class OSGridController { + <> + } + class OSCellWrapper { + <> + } + + QWidget <|-- OSGridView + OSGridView "1" --> "1" OSGridController : references + OSGridView "1..*" *-- "N" OSCellWrapper : renders +``` + +--- + +## Constructor + +| Parameter | Type | Description | +|---|---|---| +| `gridController` | `OSGridController*` | The controller providing row/column data | +| `headerText` | `QString` | Text shown in the column header row | +| `dropZoneText` | `QString` | Placeholder text for the "add new object" drop zone at the top or bottom | +| `isIP` | `bool` | IP/SI unit display preference | +| `parent` | `QWidget*` | Qt parent | + +--- + +## Key Public Methods + +| Method | Returns | Description | +|---|---|---| +| `setGridController(ctrl)` | `void` | Replaces the grid controller and re-renders all cells | +| `gridController()` | `OSGridController*` | The current controller | +| `selectRow(int)` | `void` | Programmatically selects a row and scrolls it into view | +| `selectedRows()` | `vector` | Returns indices of all currently selected rows | + +--- + +## Qt Signals + +| Signal | Arguments | Description | +|---|---|---| +| `rowSelected` | `int rowIndex` | Emitted when the user clicks or keyboard-navigates to a row | +| `dropZoneClicked` | — | Emitted when the user clicks the "add new object" drop area | diff --git a/developer/doc/libraries/bimserver.md b/developer/doc/libraries/bimserver.md new file mode 100644 index 000000000..db48acf8a --- /dev/null +++ b/developer/doc/libraries/bimserver.md @@ -0,0 +1,133 @@ +# Library: `bimserver` — BIMserver Integration + +> **Source:** `src/bimserver/` +> **CMake target:** `openstudio_bimserver` +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +The `bimserver` module provides optional integration with a [BIMserver](http://bimserver.org/) instance — an open-source BIM server that stores and versions IFC building models. + +It enables users to: +1. Log on to a BIMserver instance +2. Browse available projects +3. Select a project revision and download it as an OpenStudio Model (`.osm`) +4. Check in new or updated IFC files from local disk + +The module offers both **non-blocking (async)** and **blocking** APIs for all operations, allowing it to be used from GUI code (non-blocking + signals) and scripted CLI-style workflows (blocking with timeout). + +--- + +## Key Classes + +```mermaid +classDiagram + class BIMserverConnection { + <> + -addr: QString + -port: QString + -manager: QNetworkAccessManager + +login(username, password) + +getAllProjects() + +download(revisionID) + +createProject(name) + +deleteProject(projectID) + +checkInIFCFile(projectID, path) + +getIFCRevisionList(projectID) + +loginBlocked(username, password, timeout) bool + +getAllProjectsBlocked(timeout) optional~QStringList~ + +downloadBlocked(projectID, timeout) optional~QString~ + signals: loginSuccess, loginFailed + signals: allProjectsAvailable(QStringList) + signals: osmStringAvailable(QString) + signals: errorOccured(QString) + signals: progressUpdated(int) + } + class ProjectImporter { + <> + -connection: BIMserverConnection* + +exec() int + +getModel() optional~Model~ + signals: modelImported(Model) + } + + ProjectImporter "1" --> "1" BIMserverConnection : owns and drives +``` + +--- + +## Communication Protocol + +BIMserver exposes a JSON-over-HTTP API. `BIMserverConnection` uses Qt Network (`QNetworkAccessManager`) to issue HTTP POST requests: + +```mermaid +sequenceDiagram + participant UI as ProjectImporter (UI) + participant CONN as BIMserverConnection + participant NET as QNetworkAccessManager + participant BIM as BIMserver (remote) + + UI->>CONN: login(username, password) + CONN->>NET: POST /json [login request] + NET->>BIM: HTTP request + BIM-->>NET: JSON response (token) + NET-->>CONN: QNetworkReply::finished + CONN-->>UI: emit loginSuccess / loginFailed + + UI->>CONN: getAllProjects() + CONN->>NET: POST /json [getAllProjects + token] + BIM-->>NET: JSON project list + CONN-->>UI: emit allProjectsAvailable(QStringList) + + UI->>CONN: download(revisionID) + CONN->>NET: POST /json [getFileFromRevision] + BIM-->>NET: OSM string payload + CONN-->>UI: emit osmStringAvailable(osmString) +``` + +--- + +## Blocking vs. Non-Blocking API + +| Non-blocking (async) | Blocking | +|---|---| +| `login(username, password)` → `loginSuccess`/`loginFailed` | `loginBlocked(username, password, timeout) → bool` | +| `getAllProjects()` → `allProjectsAvailable(QStringList)` | `getAllProjectsBlocked(timeout) → optional` | +| `download(revisionID)` → `osmStringAvailable(QString)` | `downloadBlocked(projectID, timeout) → optional` | + +Blocking variants spin a `QEventLoop` with a `QTimer` for the timeout, making them usable in non-GUI contexts. + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtNetwork`, `QtCore`, `QtWidgets`) | HTTP client, JSON parsing, dialog UI | +| **OpenStudio SDK** | Parsed from OSM string returned by BIMserver | +| **Boost** | `optional` | + +--- + +## Internal Dependencies + +| Module | Usage | +|---|---| +| `model_editor` | `QMetaTypes` registration, base types | +| `openstudio_lib` | Links to `openstudio::openstudiolib` for SDK access | +| `qtwinmigrate` (Win32 only) | MFC/Qt bridge for SketchUp plugin | + +--- + +## Patterns & Conventions + +- **Signal-based error handling** — errors from network operations surface via `errorOccured(QString)` rather than exceptions. +- **Progress reporting** — `progressUpdated(int)` (0–100) for long-running IFC check-in operations. +- **`boost::optional` returns** — blocking APIs return `boost::none` on timeout/failure. + +--- + +## Class Documentation + +- [BIMserverConnection](../classes/bimserver/BIMserverConnection.md) +- [ProjectImporter](../classes/bimserver/ProjectImporter.md) diff --git a/developer/doc/libraries/model_editor.md b/developer/doc/libraries/model_editor.md new file mode 100644 index 000000000..1f84ee586 --- /dev/null +++ b/developer/doc/libraries/model_editor.md @@ -0,0 +1,108 @@ +# Library: `model_editor` — Generic Model Inspector + +> **Source:** `src/model_editor/` +> **CMake target:** `openstudio_modeleditor` +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`model_editor` provides a generic, IDD schema-driven inspector for any OpenStudio `ModelObject` or `WorkspaceObject`. Rather than hand-coding a bespoke widget for every object type, it interrogates the object's IDD definition at runtime and generates the appropriate input controls (spinboxes, comboboxes, labels) automatically. + +It is used: +- By the SketchUp plugin as a standalone model inspector window +- By `openstudio_lib` for the right-column object inspector +- As a debugging tool to inspect arbitrary model objects without domain-specific views + +--- + +## Key Classes + +```mermaid +classDiagram + class InspectorGadget { + <> + +layoutModel(workspaceObj, recursive, hideChildren) + +layoutModelObj(modelObj, recursive, hideChildren, locked) + +removeWorkspaceObject(wObj, type, uuid) + +toggleGreenButton(isPushButton) + signals: nameChanged(QString) + signals: toggleUnitsClicked(bool) + } + class IGWidget { + <> + +sizeHint() QSize + } + class InspectorDialog { + <> + +setWorkspace(workspace) + +selectedObjectHandles() vector~Handle~ + signals: workspaceChanged, workspaceObjectAdded, workspaceObjectRemoved + } + class AccessPolicyStore { + <> + +loadFile(path) bool + +getPolicy(iddObjectType, fieldIndex) AccessPolicy + } + + InspectorDialog "1" *-- "1" InspectorGadget : embeds + InspectorGadget --> AccessPolicyStore : consults for field visibility + InspectorGadget *-- IGWidget : renders fields into +``` + +| Class | File | Description | +|---|---|---| +| `InspectorGadget` | [InspectorGadget.hpp](../../../src/model_editor/InspectorGadget.hpp) | Core widget. Accepts any `WorkspaceObject` or `ModelObject` and auto-generates input controls from the IDD field definitions. | +| `IGWidget` | [InspectorGadget.hpp](../../../src/model_editor/InspectorGadget.hpp) | Lightweight `QWidget` / `Nano::Observer` base used as the scroll area content for the generated controls. | +| `InspectorDialog` | [InspectorDialog.hpp](../../../src/model_editor/InspectorDialog.hpp) | Modal or modeless dialog that hosts an `InspectorGadget`. Can observe a `Workspace` and keeps the display in sync as objects change. | +| `AccessPolicyStore` | [AccessPolicyStore.hpp](../../../src/model_editor/AccessPolicyStore.hpp) | Singleton that reads an XML policy file to determine whether each IDD field is `FREE` (editable), `LOCKED` (read-only), or hidden. | +| `Application` | [Application.hpp](../../../src/model_editor/Application.hpp) | Standalone `QApplication` wrapper for running the model editor outside the main OpenStudio app. | +| `GithubReleases` | [GithubReleases.hpp](../../../src/model_editor/GithubReleases.hpp) | Checks GitHub releases API for newer application versions. | +| `BridgeClasses` | [BridgeClasses.hpp](../../../src/model_editor/BridgeClasses.hpp) | Adapts OpenStudio nano signals to Qt slots so workspace change notifications reach Qt-connected widgets. | + +--- + +## Field Rendering Rules + +`InspectorGadget` generates different Qt widgets for each IDD field type based on the `AccessPolicyStore` policy: + +| IDD Field Type | `FREE` policy | `LOCKED` policy | +|---|---|---| +| Real | `QDoubleSpinBox` | `QLabel` | +| Integer | `QSpinBox` | `QLabel` | +| Alpha / String | `QLineEdit` | `QLabel` | +| Choice | `IGComboBox` (custom) | `QLabel` | +| Boolean | `QCheckBox` | `QLabel` | +| Object reference | `QLineEdit` + lookup button | `QLabel` | + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtCore`) | Widget rendering, event handling | +| **OpenStudio SDK** (`WorkspaceObject`, `ModelObject`, `IddObject`, `IddField`) | IDD schema introspection for field type/name/range | +| **Nano signal-slot** | `Nano::Observer` mixin for low-overhead workspace change notifications | + +--- + +## Internal Dependencies + +None — `model_editor` is intentionally the lowest layer of the application stack. It does not depend on `openstudio_lib` or `shared_gui_components`. + +--- + +## Patterns & Conventions + +- **IDD-driven layout** — the widget layout is entirely data-driven from the OpenStudio IDD schema, requiring no code changes when new object types are added to the SDK. +- **Policy file** — `AccessPolicyStore` reads an XML file at startup. To lock or hide a field for a specific object type, edit the policy file rather than the widget code. +- **Nano signals (not Qt signals)** — `InspectorGadget` and `IGWidget` use `Nano::Observer` (a lightweight signal-slot system that does not require `QObject`) for model change notifications, minimising MOC overhead. +- **SWIG interface** — `ModelEditor.i` and `Qt.i` are SWIG interface files used to generate Ruby and Python bindings for the model editor library (used by the SketchUp plugin). + +--- + +## Class Documentation + +- [InspectorGadget](../classes/model_editor/InspectorGadget.md) +- [InspectorDialog](../classes/model_editor/InspectorDialog.md) +- [AccessPolicyStore](../classes/model_editor/AccessPolicyStore.md) diff --git a/developer/doc/libraries/openstudio_app.md b/developer/doc/libraries/openstudio_app.md new file mode 100644 index 000000000..8e6e1482f --- /dev/null +++ b/developer/doc/libraries/openstudio_app.md @@ -0,0 +1,97 @@ +# Library: `openstudio_app` — Application Entry Point + +> **Source:** `src/openstudio_app/` +> **CMake target:** `OpenStudioApp` (executable) +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`openstudio_app` is the top-level executable module. It owns the `main()` entry point, constructs the `OSAppBase`-derived `OpenStudioApp` instance, manages the Qt application lifecycle, and provides the startup experience (splash screen, library selection, version migration dialogs) shown before an `OSDocument` is opened. + +This module is intentionally thin: all substantive GUI logic lives in `openstudio_lib`. `openstudio_app` acts as the glue that wires together the document model, the main window, and the startup flow. + +--- + +## Key Classes + +```mermaid +classDiagram + class OpenStudioApp { + +OpenStudioApp(argc, argv) + +currentDocument() OSDocument* + +openFile(path) + +newModel() + -versionTranslate(path) Model + signals: requestCloseAll, newModelDropped + } + class OSAppBase { + <> + +currentDocument() OSDocument* = 0 + +measureManager() MeasureManager& + +instance() OSAppBase* + } + class StartupView { + +show() + signals: newFromTemplateClicked, openClicked, recentModelClicked + } + class StartupMenu { + +menuBar() QMenuBar* + } + class LibraryDialog { + +exec() int + +selectedLibraryPaths() vector~path~ + } + class ExternalToolsDialog { + +exec() int + } + + OSAppBase <|-- OpenStudioApp : extends + OpenStudioApp "1" --> "0..1" StartupView : shows at launch + OpenStudioApp "1" --> "1" StartupMenu : installs menu bar + OpenStudioApp ..> LibraryDialog : opens on demand + OpenStudioApp ..> ExternalToolsDialog : opens on demand +``` + +| Class | File | Description | +|---|---|---| +| `OpenStudioApp` | [OpenStudioApp.hpp](../../../src/openstudio_app/OpenStudioApp.hpp) | Main application object. Extends `OSAppBase` (which extends `QApplication`). Manages document lifecycle, version translation, and initial template models. | +| `StartupView` | [StartupView.hpp](../../../src/openstudio_app/StartupView.hpp) | Splash/welcome screen shown before any document is open. Provides New/Open/Recent actions. | +| `StartupMenu` | [StartupMenu.hpp](../../../src/openstudio_app/StartupMenu.hpp) | Minimal menu bar shown during the startup screen (no document-specific items). | +| `LibraryDialog` | [LibraryDialog.hpp](../../../src/openstudio_app/LibraryDialog.hpp) | Dialog allowing users to select component library `.osm` files to load alongside the project. | +| `ExternalToolsDialog` | [ExternalToolsDialog.hpp](../../../src/openstudio_app/ExternalToolsDialog.hpp) | Dialog for configuring paths to external tools (EnergyPlus, Radiance, etc.). | + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtCore`, `QApplication`, `QProcess`, `QFutureWatcher`, `QTranslator`) | GUI event loop, async version translation, i18n | +| **OpenStudio SDK** (`openstudio/model/Model.hpp`, HVAC headers, `osversion/VersionTranslator`) | Model construction, version migration from older `.osm` files | +| **Boost** | `optional`, path utilities | + +--- + +## Internal Dependencies + +| Module | Usage | +|---|---| +| `openstudio_lib` | `OSAppBase`, `OSDocument`, `MainWindow` — instantiated here | +| `shared_gui_components` | `BusyWidget`, `OSDialog`, `WaitDialog` — directly compiled into this target | +| `model_editor` | `QMetaTypes` registration for Qt signal/slot compatibility | + +--- + +## Patterns & Conventions + +- **Singleton via `OSAppBase::instance()`** — `OpenStudioApp` registers itself so any code can retrieve the app via `OSAppBase::instance()`. +- **Version translation** — when opening a `.osm` file from a prior OpenStudio version, the app runs `osversion::VersionTranslator` asynchronously (via `QFutureWatcher`) before displaying the document. +- **Initial template models** — several pre-built HVAC templates (VAV, DOAS, packaged RTU, etc.) are embedded; the relevant model headers are included directly in `OpenStudioApp.hpp` to make their HVAC component types available. +- **`TouchEater`** — a `QObject` event filter that suppresses touch events on Windows to avoid accidental UI manipulation with touch screens. + +--- + +## Class Documentation + +- [OpenStudioApp](../classes/openstudio_app/OpenStudioApp.md) +- [StartupView](../classes/openstudio_app/StartupView.md) diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md new file mode 100644 index 000000000..767d4bb09 --- /dev/null +++ b/developer/doc/libraries/openstudio_lib.md @@ -0,0 +1,173 @@ +# Library: `openstudio_lib` — Main GUI Library + +> **Source:** `src/openstudio_lib/` +> **CMake target:** `openstudio_lib` +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`openstudio_lib` is the largest module (~200+ source files). It implements the complete building model editing GUI: every tab, every inspector view, every drag-and-drop list, and the geometry editor. It also defines the shared base types (`OSAppBase`, `OSDocument`, `MainWindow`) that the executable and the SketchUp plugin both build upon. + +The module follows a consistent **Controller / View / Inspector triad** per domain: a controller manages data access and inter-widget coordination, a tab view provides the domain's layout, and inspector widgets display the selected object's properties. + +--- + +## Key Classes Overview + +```mermaid +classDiagram + class OSAppBase { + <> + +currentDocument() OSDocument* = 0 + +measureManager() MeasureManager& + +instance() OSAppBase* + signals: workspaceObjectAdded, workspaceObjectRemoved + } + class OSDocument { + +model() Model + +mainWindow() MainWindow* + +savePath() QString + +modified() bool + +setModel(model, modified) + signals: modelSaved, modelClosed, toggleUnitsClicked + } + class MainWindow { + <> + +addVerticalTabButton(id, ...) + +setView(MainTabView*, id) + +selectVerticalTab(id) + +displayIP() bool + signals: closeClicked, displayIPClicked + } + class MainTabController { + <> + +mainContentWidget() MainTabView* + +setSubTab(int) = 0 + signals: modelObjectSelected, dropZoneItemSelected, toggleUnitsClicked + } + class MainRightColumnController { + +inspectorController() InspectorController* + +chooseMyModelTab(item, readOnly) + +chooseLibraryTab() + +chooseEditTab() + } + class OSVectorController { + <> + +reportItems() + +removeItem(OSItem*) + +drop(OSItemId) + +makeNewItem() + signals: itemIds, selectedItemId + } + + OSAppBase "1" *-- "0..1" OSDocument : manages current + OSDocument "1" *-- "1" MainWindow : owns + OSDocument "1" *-- "1" MainTabController : owns active + OSDocument "1" *-- "1" MainRightColumnController : owns + MainTabController <|-- HVACSystemsTabController + MainTabController <|-- ConstructionsTabController + MainTabController <|-- SchedulesTabController + MainTabController <|-- SpaceTypesTabController + MainTabController <|-- FacilityTabController + MainTabController <|-- RunTabController + OSVectorController <|-- ConstructionObjectVectorController + OSVectorController <|-- DefaultConstructionSetsController +``` + +--- + +## Domain Modules Within `openstudio_lib` + +| Domain | Key Controller | Key View | Notes | +|---|---|---|---| +| Application shell | `OSAppBase`, `OSDocument` | `MainWindow` | Foundation for all tabs | +| Geometry editor | `GeometryEditorController` | `GeometryEditorView` | Qt WebEngine + JS bridge | +| Geometry preview | `GeometryPreviewController` | `GeometryPreviewView` | Read-only 3D preview | +| HVAC Systems | `HVACSystemsTabController`, `HVACSystemsController` | `HVACSystemsTabView`, `HVACSystemsView` | Loop/service water/VRF scenes | +| Refrigeration | `RefrigerationController`, `RefrigerationGridController` | `RefrigerationView`, `RefrigerationScene` | Custom QGraphicsScene | +| Constructions | `ConstructionsTabController`, `ConstructionsController` | `ConstructionsTabView`, `ConstructionsView` | Many derived inspector views | +| Materials | `MaterialsController` | `MaterialsView` | Per-material inspector views | +| Loads | `LoadsController` | `LoadsView` | Equipment, people, lights inspectors | +| Schedules | `SchedulesTabController`, `SchedulesController` | `SchedulesTabView`, `SchedulesDayView` | Day schedule chart editor | +| Space Types | `SpaceTypesController` | `SpaceTypesGridView`, `SpaceTypeInspectorView` | Grid view | +| Thermal Zones | `ThermalZonesController` | `ThermalZonesGridView` | Grid view | +| Spaces | `SpacesTabController` | Multiple `Spaces*GridView` | Surfaces, loads, shading sub-tabs | +| Facility | `FacilityTabController` | `FacilityStoriesGridView`, `FacilityShadingGridView` | Building stories, shading | +| Simulation Settings | `SimSettingsTabController` | `SimSettingsTabView`, `DesignDayGridView` | Run period, design days | +| Run | `RunTabController` | `RunTabView` | Triggers EnergyPlus | +| Results | `ResultsTabController` | `ResultsTabView` | Post-run output charts | +| Variables | `VariablesTabController` | `VariablesTabView` | EnergyPlus output variables | +| Measures/Scripts | `ScriptsTabController` | `ScriptsTabView` | Measure workflow | +| Utility Bills | `UtilityBillsController` | `UtilityBillsView` | Calibration data | +| Inspector (generic) | `InspectorController` | `InspectorView` | Right-column inspector | +| BCL | — | — | `BCLComponentItem` | + +--- + +## Reusable Widget Primitives + +| Class | Description | +|---|---| +| `OSItem` | Base class for all draggable/selectable model object items | +| `OSDropZone` | Widget that accepts model object drops | +| `OSItemList` / `OSCollapsibleItem` | Container widgets for ordered lists of `OSItem`s | +| `OSVectorController` | Abstract base for list controllers backed by model vectors | +| `ModelObjectListView` | Generic list view displaying any collection of model objects | +| `ModelObjectTreeWidget` | Generic tree view for hierarchical model data | +| `OSWebEnginePage` | `QWebEnginePage` subclass for the geometry JS bridge | +| `RenderingColorWidget` | Color picker for object rendering colors | +| `IconLibrary` | Singleton cache of domain icons keyed by IDD object type | + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtWebEngineWidgets`, `QtCharts`, `QtNetwork`, `QtSvg`) | All GUI rendering, WebEngine geometry view, charts for results | +| **OpenStudio SDK** | Model objects, HVAC components, workspace I/O, analytics | +| **Boost** | `optional`, `shared_ptr`, `smart_ptr` | + +--- + +## Internal Dependencies + +| Module | Usage | +|---|---| +| `shared_gui_components` | Grid system, form widgets, `MeasureManager`, `BCLMeasureDialog` | +| `model_editor` | `InspectorGadget`, `QMetaTypes` | + +--- + +## Patterns & Conventions + +- **MVC triad** — every domain has a `*TabController`, a `*TabView`, and one or more `*InspectorView` classes. +- **`OSQObjectController`** — `OSDocument` and most controllers extend `OSQObjectController`, which provides a thread-safe `QObject` parent management pattern. +- **`OPENSTUIDO_API` macro** — applied to classes exported from `openstudio_lib.dll` on Windows. +- **Analytics** — `AnalyticsHelper` sends anonymized usage pings (configurable via `ANALYTICS_API_SECRET`/`ANALYTICS_MEASUREMENT_ID` build-time secrets). + +--- + +## Class Documentation + +- [OSAppBase](../classes/openstudio_lib/OSAppBase.md) +- [OSDocument](../classes/openstudio_lib/OSDocument.md) +- [MainWindow](../classes/openstudio_lib/MainWindow.md) +- [MainTabController](../classes/openstudio_lib/MainTabController.md) +- [MainRightColumnController](../classes/openstudio_lib/MainRightColumnController.md) +- [OSVectorController](../classes/openstudio_lib/OSVectorController.md) +- [InspectorController](../classes/openstudio_lib/InspectorController.md) +- [ModelObjectListView](../classes/openstudio_lib/ModelObjectListView.md) +- [OSItem](../classes/openstudio_lib/OSItem.md) +- [OSDropZone](../classes/openstudio_lib/OSDropZone.md) +- [HVACSystemsController](../classes/openstudio_lib/HVACSystemsController.md) +- [HVACSystemsView](../classes/openstudio_lib/HVACSystemsView.md) +- [GeometryEditorController](../classes/openstudio_lib/GeometryEditorController.md) +- [ConstructionsController](../classes/openstudio_lib/ConstructionsController.md) +- [MaterialsController](../classes/openstudio_lib/MaterialsController.md) +- [SchedulesController](../classes/openstudio_lib/SchedulesController.md) +- [SpaceTypesController](../classes/openstudio_lib/SpaceTypesController.md) +- [ThermalZonesController](../classes/openstudio_lib/ThermalZonesController.md) +- [RunTabController](../classes/openstudio_lib/RunTabController.md) +- [ResultsTabController](../classes/openstudio_lib/ResultsTabController.md) +- [OSWebEnginePage](../classes/openstudio_lib/OSWebEnginePage.md) diff --git a/developer/doc/libraries/qtwinmigrate.md b/developer/doc/libraries/qtwinmigrate.md new file mode 100644 index 000000000..96caea611 --- /dev/null +++ b/developer/doc/libraries/qtwinmigrate.md @@ -0,0 +1,71 @@ +# Library: `qtwinmigrate` — Windows MFC/Qt Bridge + +> **Source:** `src/qtwinmigrate/` +> **CMake target:** `qtwinmigrate` (Windows only) +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`qtwinmigrate` is a third-party compatibility library (originally from Qt Solutions) that enables Qt widgets to be embedded inside a Win32 or MFC (Microsoft Foundation Class) application window. It is used specifically to host the OpenStudio GUI inside the SketchUp plugin on Windows, where SketchUp provides a native Win32 host window. + +This module is **compiled only on Windows** (`if(WIN32)` in CMake). It has no effect on macOS or Linux builds. + +--- + +## Key Classes + +```mermaid +classDiagram + class QMfcApp { + <> + +pluginInstance(instance) bool + +run(instance) int + +translate(msg) bool + } + class QWinHost { + <> + +QWinHost(parent, flags) + +createWindow(parent, instance) HWND + +window() HWND + } + class QWinWidget { + <> + +QWinWidget(hParentWnd, parent, flags) + +childWindow() HWND + +show() + +move(x, y) + } + + QMfcApp .. QWinWidget : used together + QWinHost <.. QWinWidget : related pattern +``` + +| Class | File | Description | +|---|---|---| +| `QMfcApp` | [QMfcApp/qmfcapp.h](../../../src/qtwinmigrate/QMfcApp/qmfcapp.h) | Bridges the Qt event loop with an MFC `CWinApp`. Allows Qt to be initialised as a plugin within an existing MFC process. | +| `QWinHost` | [QWinHost/qwinhost.h](../../../src/qtwinmigrate/QWinHost/qwinhost.h) | A `QWidget` subclass that hosts an arbitrary Win32 `HWND` child window inside a Qt widget hierarchy. | +| `QWinWidget` | [QWinWidget/qwinwidget.h](../../../src/qtwinmigrate/QWinWidget/qwinwidget.h) | A `QWidget` that is itself a child of a native `HWND`, allowing Qt widgets to be embedded inside a non-Qt Win32 parent window. | + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtCore`) | Qt event loop and widget hierarchy integration | +| **Win32 API** (`windows.h`, `commctrl.h`) | Native window handles (`HWND`), message translation | +| **MFC** (optional, link-time) | `QMfcApp` integration with `CWinApp` (only needed for MFC hosts) | + +--- + +## Internal Dependencies + +None. + +--- + +## Patterns & Conventions + +- **Plugin pattern** — `QMfcApp::pluginInstance()` is the entry point for Qt-as-plugin use. It initialises Qt without creating a new `QApplication` (since one already exists in the host process). +- **Message translation** — `QMfcApp::translate()` must be called from the host's message loop to forward Windows messages to Qt's event dispatcher. +- **Not used in standalone app** — in the standalone `OpenStudioApp` executable, none of these classes are instantiated. They exist in the compiled binary only because the `openstudio_bimserver` target links `qtwinmigrate` on Windows. diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md new file mode 100644 index 000000000..d095ceddf --- /dev/null +++ b/developer/doc/libraries/shared_gui_components.md @@ -0,0 +1,177 @@ +# Library: `shared_gui_components` — Shared UI Widgets + +> **Source:** `src/shared_gui_components/` +> **CMake target:** compiled into `openstudio_modeleditor` and `openstudio_lib` +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`shared_gui_components` provides the reusable Qt widgets and controllers that are shared between the standalone OpenStudio Application and any plugin host (e.g., the SketchUp plugin). It is designed to be independent of the specific application shell, conforming only to the `BaseApp` interface. + +Key responsibilities: +- **Grid system** — a generic multi-column tabular view for OpenStudio model objects +- **Form controls** — typed input widgets for real, integer, boolean, and string model fields +- **Measure management** — discovery, update-checking, and execution of OpenStudio Measures +- **BCL integration** — browse and download building components and measures from NREL's BCL +- **Common dialogs** — network proxy, progress bars, wait dialogs + +--- + +## Key Classes + +```mermaid +classDiagram + class BaseApp { + <> + +mainWidget() QWidget* = 0 + +measureManager() MeasureManager& = 0 + +updateSelectedMeasureState() = 0 + +addMeasure() = 0 + +openBclDlg() = 0 + +tempDir() optional~path~ = 0 + +currentModel() optional~Model~ = 0 + } + class MeasureManager { + +url() QUrl + +myMeasures() vector~BCLMeasure~ + +bclMeasures() vector~BCLMeasure~ + +getMeasureByUID(uid) optional~BCLMeasure~ + +updateMeasures(app, measures, force) + +checkForLocalUpdates() + signals: measureUpdated + } + class OSGridController { + <> + +addCheckBoxColumn(heading, getter, setter) + +addComboBoxColumn(heading, choices, getter, setter) + +addDoubleEditColumn(heading, getter, setter) + +addDropZoneColumn(heading, getter, setter) + +rowCount() int + +objectAt(row) ModelObject + } + class OSGridView { + +setGridController(OSGridController*) + +selectRow(int) + +selectedRows() vector~int~ + } + class LocalLibraryController { + +localLibraryView() LocalLibraryView* + signals: addMeasureClicked, duplicateMeasureClicked + } + class BCLMeasureDialog { + +exec() int + +selectedMeasure() optional~BCLMeasure~ + } + class BuildingComponentDialog { + +exec() int + } + + BaseApp <|.. OSAppBase : implements + MeasureManager --> BaseApp : uses + OSGridView --> OSGridController : owned by + LocalLibraryController --> MeasureManager : uses + BCLMeasureDialog --> MeasureManager : uses +``` + +--- + +## Grid System in Detail + +The grid system powers all multi-column, tabular model views (Thermal Zones, Space Types, Spaces, Facility, Design Days, etc.). + +```mermaid +flowchart LR + GC["OSGridController\n(abstract)"] --"creates columns"--> CELL["OSCellWrapper\n(QWidget per cell)"] + GC --"tracks selection"--> SEL["OSObjectSelector"] + GV["OSGridView\n(QScrollArea)"] --"hosts"--> CELL + GV --> GC + DOMAIN["DomainGridController\ne.g. ThermalZonesGridController"] --"extends"--> GC + DOMAIN --"calls addXxxColumn()"--> GC +``` + +Each concrete grid controller (e.g., `ThermalZonesGridController`, `SpaceTypesGridController`) extends `OSGridController` and calls the `add*Column()` methods in its constructor to declaratively define the column layout. The grid controller reads data lazily from the model as the view scrolls. + +--- + +## Form Controls + +All typed input widgets follow the same pattern: they read from and write to a `ModelObject` field via getter/setter callbacks provided by the owning `OSGridController` or inspector view. + +| Widget | Purpose | +|---|---| +| `OSDoubleEdit` / `OSDoubleEdit2` | Real-valued field editor with unit conversion support | +| `OSIntegerEdit` / `OSIntegerEdit2` | Integer field editor | +| `OSUnsignedEdit` | Non-negative integer editor | +| `OSLineEdit` / `OSLineEdit2` | String field editor | +| `OSComboBox` / `OSComboBox2` | Enumeration/choice field selector | +| `OSCheckBox` / `OSCheckBox2` | Boolean field toggle | +| `OSSwitch` | Toggle switch for boolean fields (styled alternative to checkbox) | +| `OSQuantityEdit` / `OSQuantityEdit2` | Dimensional quantity editor with SI/IP toggle | +| `OSOptionalQuantityEdit` | Optional dimensional quantity (blank = unset) | + +The `2` suffix variants use `std::function` callbacks instead of `QObject` signal/slot; they are preferred in newer code. + +--- + +## Measure & BCL Integration + +```mermaid +flowchart TD + MM["MeasureManager"] + LLC["LocalLibraryController"] + LLV["LocalLibraryView"] + BMD["BCLMeasureDialog"] + BCD["BuildingComponentDialog"] + WC["WorkflowController"] + WV["WorkflowView"] + + MM --> LLC + LLC --> LLV + MM --> BMD + MM --> BCD + MM --> WC + WC --> WV +``` + +- `MeasureManager` maintains an in-memory index of all available measures, dedupes by UUID, and manages update-checking against local copies. +- `SyncMeasuresDialog` / `SyncMeasuresDialogCentralWidget` — modal workflow to synchronize project measure versions with the local library. +- `WorkflowController` / `WorkflowView` — displays the ordered list of measures in the project workflow (the Measures tab). + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtCore`, `QtNetwork`) | All widgets, networking for BCL downloads | +| **OpenStudio SDK** (`BCLMeasure`, `WorkflowJSON`, `OSArgument`) | Measure definitions, workflow serialization, argument types | +| **Boost** | `optional`, path utilities | + +--- + +## Internal Dependencies + +| Module | Usage | +|---|---| +| `model_editor` | `QMetaTypes` for meta-type registration | +| `openstudio_lib` | `OSItem`, `OSVectorController` (used in OSGridController) | + +--- + +## Patterns & Conventions + +- **`BaseApp` interface** — all components that need access to the application (e.g., `MeasureManager`) depend only on `BaseApp`, never on `OpenStudioApp` or `OSAppBase` directly. This enables reuse in plugin contexts. +- **`add*Column()` DSL** — `OSGridController` subclasses define their columns declaratively in their constructor, producing a clean, readable column specification without procedural layout code. +- **Thread safety** — `MeasureManager` uses a `QMutex` to protect its measure index; BCL network requests are made on the Qt network thread. + +--- + +## Class Documentation + +- [BaseApp](../classes/shared_gui_components/BaseApp.md) +- [OSGridController](../classes/shared_gui_components/OSGridController.md) +- [OSGridView](../classes/shared_gui_components/OSGridView.md) +- [MeasureManager](../classes/shared_gui_components/MeasureManager.md) +- [BCLMeasureDialog](../classes/shared_gui_components/BCLMeasureDialog.md) +- [LocalLibraryController](../classes/shared_gui_components/LocalLibraryController.md) +- [BuildingComponentDialog](../classes/shared_gui_components/BuildingComponentDialog.md) diff --git a/developer/doc/libraries/utilities.md b/developer/doc/libraries/utilities.md new file mode 100644 index 000000000..3374af9ef --- /dev/null +++ b/developer/doc/libraries/utilities.md @@ -0,0 +1,65 @@ +# Library: `utilities` — Path Helpers + +> **Source:** `src/utilities/` +> **CMake target:** `openstudio_apputils` (header/static) +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +The `utilities` module is a minimal helper library that resolves runtime filesystem paths to key components: the OpenStudio CLI, EnergyPlus, Radiance, and the application's own resources directory. + +Because the application is packaged differently on each platform (macOS bundle, Windows installer tree, Linux deb), path resolution must be centralised and aware of the deployment layout. This module provides that abstraction. + +--- + +## Files + +| File | Description | +|---|---| +| `OpenStudioApplicationPathHelpers.hpp` | Public API — declares free functions for locating SDK CLI, EnergyPlus, Radiance, and resource paths | +| `OpenStudioApplicationPathHelpers.cxx.in` | CMake template — `configure_file` substitutes the actual install-time paths at build time, producing `OpenStudioApplicationPathHelpers.cxx` | +| `OpenStudioApplicationUtilitiesAPI.hpp` | DLL export macro (`OPENSDTUDIOAPPLICATIONUTILITIES_API`) for Windows shared library symbol visibility | + +--- + +## Key API + +```cpp +namespace openstudio { + // Returns the path to the OpenStudio CLI executable + path getOpenStudioCoreCLI(); + + // Returns the path to the application's shared resources directory + path getOpenStudioApplicationSourceDirectory(); + + // Returns the path to the EnergyPlus executable (from SDK install layout) + boost::optional findEnergyPlus(); + + // Returns the path to the Radiance installation (from SDK install layout) + boost::optional findRadiance(); +} +``` + +Paths are resolved relative to the running executable (`QCoreApplication::applicationDirPath()`), making them work correctly whether the app is run from a development build tree or an installed package. + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **OpenStudio SDK** (`openstudio/utilities/core/Path.hpp`) | `openstudio::path` type alias for `std::filesystem::path` | +| **Qt 6** (`QCoreApplication`) | `applicationDirPath()` for relative path resolution | + +--- + +## Internal Dependencies + +None — this is the lowest-dependency module in the application. + +--- + +## Patterns & Conventions + +- **CMake `configure_file`** — the `.cxx.in` file contains `@VARIABLE@` placeholders that CMake fills in at configure time based on install prefix, SDK path, and platform. This is how install-time paths are baked in without hardcoding. +- **`boost::optional` returns** — EnergyPlus and Radiance are optional; functions return `boost::none` if the expected path does not exist on disk, allowing callers to gracefully degrade. From 8580809cde80ac35e195a08886ad83c79d013c04 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 14:24:37 -0600 Subject: [PATCH 02/26] refactor: extract openstudio_qt_utils; reorganize shared_gui_components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New library openstudio_qt_utils: move Application, OSProgressBar, QMetaTypes, Utilities out of model_editor; add OpenStudioQtUtilsAPI.hpp. shared_gui_components now has its own CMakeLists (openstudio_shared_gui): - Move IconLibrary, OSVectorController, UserSettings out of openstudio_lib/model_editor - Add OSItemId.hpp (extracted from OSItem.hpp) and OpenStudioSharedGuiAPI.hpp - Fix missing OSVectorController.hpp in qt6_wrap_cpp (caused LNK2001 on all Qt meta-object/signal symbols) - Register OSItemId metatypes in OSGridController Add BaseApp::mouseOverInspectorView() pure virtual; implement in OSAppBase; use it in OSLineEdit2::focusOutEvent instead of inline 3-level chain. All include paths updated; no circular shared_gui→openstudio_lib dependency. --- CMakeLists.txt | 4 + developer/doc/architecture.md | 108 +++++----- developer/doc/libraries/openstudio_lib.md | 5 +- .../doc/libraries/openstudio_qt_utils.md | 139 +++++++++++++ .../doc/libraries/shared_gui_components.md | 4 +- llms.txt | 177 ++++++++++++++++ src/bimserver/BIMserverConnection.cpp | 4 +- src/bimserver/CMakeLists.txt | 12 +- src/model_editor/AccessPolicyStore.hpp | 4 +- src/model_editor/CMakeLists.txt | 17 +- src/model_editor/GithubReleases.cpp | 2 +- src/model_editor/InspectorDialog.cpp | 4 +- src/model_editor/InspectorGadget.cpp | 2 +- src/model_editor/ModalDialogs.cpp | 4 +- src/model_editor/ModelEditor.i | 2 +- src/model_editor/ModelEditorAPI.hpp | 2 +- src/model_editor/PathWatcher.cpp | 4 +- .../test/GithubReleases_GTest.cpp | 2 +- src/model_editor/test/ModelEditorFixture.cpp | 2 +- src/model_editor/test/PathWatcher_GTest.cpp | 2 +- src/model_editor/test/QMetaTypes_GTest.cpp | 2 +- src/model_editor/test/Utilities_GTest.cpp | 4 +- src/openstudio_app/CMakeLists.txt | 15 -- src/openstudio_app/ExternalToolsDialog.cpp | 3 +- src/openstudio_app/LibraryDialog.cpp | 2 +- src/openstudio_app/OpenStudioApp.cpp | 2 +- src/openstudio_app/main.cpp | 4 +- .../test/OpenStudioAppFixture.cpp | 2 +- src/openstudio_app/test/Resources_GTest.cpp | 2 +- src/openstudio_lib/AnalyticsHelper.cpp | 4 +- src/openstudio_lib/ApplyMeasureNowDialog.cpp | 2 +- src/openstudio_lib/BuildingInspectorView.cpp | 4 +- src/openstudio_lib/CMakeLists.txt | 174 +--------------- src/openstudio_lib/GeometryEditorView.cpp | 2 +- src/openstudio_lib/GeometryPreviewView.cpp | 2 +- src/openstudio_lib/GridItem.cpp | 4 +- src/openstudio_lib/GridViewSubTab.hpp | 2 + src/openstudio_lib/GroundTemperatureView.cpp | 2 +- src/openstudio_lib/HVACSystemsController.cpp | 2 +- src/openstudio_lib/HVACSystemsController.hpp | 2 +- src/openstudio_lib/InspectorView.cpp | 2 +- src/openstudio_lib/LocationTabView.cpp | 2 +- src/openstudio_lib/LoopChooserView.cpp | 2 +- src/openstudio_lib/LoopScene.hpp | 2 +- .../MainRightColumnController.hpp | 3 +- src/openstudio_lib/MainWindow.cpp | 2 +- .../ModelObjectInspectorView.cpp | 2 +- src/openstudio_lib/ModelObjectItem.cpp | 2 +- src/openstudio_lib/ModelObjectListView.cpp | 2 +- src/openstudio_lib/ModelObjectListView.hpp | 4 +- src/openstudio_lib/ModelObjectTreeItems.cpp | 4 +- src/openstudio_lib/ModelObjectTreeWidget.hpp | 2 +- .../ModelObjectVectorController.hpp | 4 +- src/openstudio_lib/OSAppBase.cpp | 14 +- src/openstudio_lib/OSAppBase.hpp | 4 +- src/openstudio_lib/OSDocument.cpp | 6 +- src/openstudio_lib/OSDocument.hpp | 2 +- src/openstudio_lib/OSDropZone.cpp | 4 +- src/openstudio_lib/OSItem.cpp | 4 +- src/openstudio_lib/OSItem.hpp | 30 +-- src/openstudio_lib/OSItemList.cpp | 2 +- src/openstudio_lib/OSItemSelectorButtons.cpp | 2 +- .../RefrigerationController.cpp | 4 +- .../RefrigerationController.hpp | 2 +- src/openstudio_lib/ResultsTabView.cpp | 2 +- src/openstudio_lib/ResultsTabView.hpp | 2 +- src/openstudio_lib/RunTabView.cpp | 4 +- .../ScheduleCompactInspectorView.cpp | 2 +- src/openstudio_lib/ScheduleDayView.cpp | 2 +- src/openstudio_lib/ScheduleDialog.cpp | 2 +- .../ScheduleFileInspectorView.cpp | 2 +- src/openstudio_lib/SchedulesView.cpp | 2 +- src/openstudio_lib/SchedulesView.hpp | 2 +- src/openstudio_lib/ScriptItem.cpp | 2 +- src/openstudio_lib/ServiceWaterGridItems.cpp | 2 +- src/openstudio_lib/ServiceWaterScene.hpp | 2 +- .../SpaceLoadInstancesWidget.cpp | 4 +- src/openstudio_lib/SpaceTypesGridView.cpp | 2 +- src/openstudio_lib/SpacesSubtabGridView.cpp | 2 +- .../StandardOpaqueMaterialInspectorView.cpp | 2 +- ...StandardsInformationConstructionWidget.cpp | 2 +- .../StandardsInformationMaterialWidget.cpp | 2 +- .../SwimmingPoolIndoorFloorSurfaceDialog.cpp | 2 +- .../UtilityBillFuelTypeListView.cpp | 2 +- .../UtilityBillFuelTypeListView.hpp | 4 +- src/openstudio_lib/VRFController.cpp | 2 +- src/openstudio_lib/VariablesTabView.cpp | 2 +- src/openstudio_lib/VariablesTabView.hpp | 2 +- src/openstudio_lib/YearSettingsWidget.cpp | 2 +- src/openstudio_lib/YearSettingsWidget.hpp | 2 +- src/openstudio_lib/ZoneChooserView.cpp | 2 +- src/openstudio_lib/test/IconLibrary_GTest.cpp | 2 +- .../test/OpenStudioLibFixture.cpp | 4 +- .../test/SpacesSurfaces_Benchmark.cpp | 2 +- .../Application.cpp | 11 - .../Application.hpp | 9 +- src/openstudio_qt_utils/CMakeLists.txt | 35 ++++ .../OSProgressBar.cpp | 10 - .../OSProgressBar.hpp | 10 +- .../OpenStudioQtUtilsAPI.hpp | 26 +++ .../QMetaTypes.cpp | 11 - .../QMetaTypes.hpp | 21 +- .../Utilities.cpp | 0 .../Utilities.hpp | 27 +-- .../BCLMeasureDialog.cpp | 4 +- src/shared_gui_components/BaseApp.hpp | 4 +- .../BuildingComponentDialogCentralWidget.cpp | 2 +- src/shared_gui_components/CMakeLists.txt | 194 ++++++++++++++++++ src/shared_gui_components/Component.cpp | 2 +- src/shared_gui_components/EditController.cpp | 2 +- src/shared_gui_components/EditView.cpp | 2 +- .../IconLibrary.cpp | 0 .../IconLibrary.hpp | 10 +- .../LocalLibraryController.cpp | 4 +- src/shared_gui_components/MeasureDragData.cpp | 2 +- src/shared_gui_components/MeasureManager.cpp | 6 +- src/shared_gui_components/MeasureManager.hpp | 4 +- .../NetworkProxyDialog.cpp | 4 +- src/shared_gui_components/OSDoubleEdit.cpp | 2 +- .../OSGridController.cpp | 7 + .../OSGridController.hpp | 9 +- src/shared_gui_components/OSGridView.cpp | 2 +- src/shared_gui_components/OSGridView.hpp | 2 +- src/shared_gui_components/OSIntegerEdit.cpp | 2 +- src/shared_gui_components/OSItemId.hpp | 46 +++++ src/shared_gui_components/OSLineEdit.cpp | 8 +- .../OSLoadNamePixmapLineEdit.cpp | 2 +- src/shared_gui_components/OSQuantityEdit.cpp | 2 +- src/shared_gui_components/OSUnsignedEdit.cpp | 2 +- .../OSVectorController.cpp | 0 .../OSVectorController.hpp | 10 +- .../ProcessEventsProgressBar.cpp | 2 +- .../ProcessEventsProgressBar.hpp | 2 +- .../UserSettings.cpp | 2 +- .../UserSettings.hpp | 6 +- .../WorkflowController.cpp | 2 +- src/utilities/CMakeLists.txt | 5 +- 137 files changed, 894 insertions(+), 530 deletions(-) create mode 100644 developer/doc/libraries/openstudio_qt_utils.md create mode 100644 llms.txt rename src/{model_editor => openstudio_qt_utils}/Application.cpp (92%) rename src/{model_editor => openstudio_qt_utils}/Application.hpp (94%) create mode 100644 src/openstudio_qt_utils/CMakeLists.txt rename src/{model_editor => openstudio_qt_utils}/OSProgressBar.cpp (92%) rename src/{model_editor => openstudio_qt_utils}/OSProgressBar.hpp (91%) create mode 100644 src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp rename src/{model_editor => openstudio_qt_utils}/QMetaTypes.cpp (69%) rename src/{model_editor => openstudio_qt_utils}/QMetaTypes.hpp (64%) rename src/{model_editor => openstudio_qt_utils}/Utilities.cpp (100%) rename src/{model_editor => openstudio_qt_utils}/Utilities.hpp (51%) create mode 100644 src/shared_gui_components/CMakeLists.txt rename src/{openstudio_lib => shared_gui_components}/IconLibrary.cpp (100%) rename src/{openstudio_lib => shared_gui_components}/IconLibrary.hpp (89%) create mode 100644 src/shared_gui_components/OSItemId.hpp rename src/{openstudio_lib => shared_gui_components}/OSVectorController.cpp (100%) rename src/{openstudio_lib => shared_gui_components}/OSVectorController.hpp (89%) rename src/{model_editor => shared_gui_components}/UserSettings.cpp (97%) rename src/{model_editor => shared_gui_components}/UserSettings.hpp (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d34f5b643..9a3719089 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -723,8 +723,10 @@ get_target_property(OS_CLI_IMPORTED_PATH openstudio::openstudio LOCATION) get_filename_component(OS_CLI_IMPORTED_NAME ${OS_CLI_IMPORTED_PATH} NAME) list(APPEND project_directories "utilities") +list(APPEND project_directories "openstudio_qt_utils") list(APPEND project_directories "model_editor") list(APPEND project_directories "bimserver") +list(APPEND project_directories "shared_gui_components") list(APPEND project_directories "openstudio_lib") list(APPEND project_directories "openstudio_app") @@ -740,8 +742,10 @@ add_subdirectory("translations") # E X P O R T T A R G E T S # ############################################################################### +list(APPEND all_lib_targets "openstudio_qt_utils") list(APPEND all_lib_targets "openstudio_modeleditor") list(APPEND all_lib_targets "openstudio_bimserver") +list(APPEND all_lib_targets "openstudio_shared_gui") list(APPEND all_lib_targets "openstudio_lib") list(APPEND all_exe_targets "OpenStudioApp") diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index a7d66cee0..db5477af7 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -29,7 +29,6 @@ Key user workflows: - Configure building geometry, constructions, loads, schedules, and HVAC - Apply scripted transformations (OpenStudio Measures) via BCL or local directories - Run EnergyPlus simulations and review results -- Import IFC building data from a BIMserver instance --- @@ -42,19 +41,16 @@ C4Context Person(user, "Energy Modeler", "Uses the GUI to create, configure, and simulate building energy models") System(app, "OpenStudio Application", "Qt 6 GUI for whole-building energy modeling (.osm files)") - + System_Ext(bcl, "Building Component Library (BCL)", "Remote library of measures and components (NREL hosted)") System_Ext(sdk, "OpenStudio SDK", "C++ library providing the model layer, geometry, HVAC objects, workflow execution, Ruby/Python bindings") System_Ext(eplus, "EnergyPlus", "Whole-building energy simulation engine (launched as a subprocess by the SDK)") - System_Ext(bimserver, "BIMserver", "IFC building model repository (optional integration)") - System_Ext(bcl, "Building Component Library (BCL)", "Remote library of measures and components (NREL hosted)") System_Ext(radiance, "Radiance", "Daylight simulation engine (optional, invoked by SDK workflows)") Rel(user, app, "Creates/edits building models, runs simulations") + Rel(app, bcl, "HTTPS for measure/component downloads") Rel(app, sdk, "Calls SDK C++ API for model manipulation, workflows, version translation") Rel(sdk, eplus, "Launches EnergyPlus as subprocess, parses results") Rel(sdk, radiance, "Launches Radiance as subprocess for daylight analysis") - Rel(app, bimserver, "REST API via cpprestsdk/Qt Network (optional)") - Rel(app, bcl, "HTTPS for measure/component downloads") ``` --- @@ -69,18 +65,17 @@ C4Container Container(app_exe, "OpenStudioApp", "Executable", "Entry point: main(), application lifecycle, startup screen, version translation") Container(openstudio_lib, "openstudio_lib", "C++ shared library", "All tab controllers, views, HVAC/geometry/schedules/loads GUI. ~200 files. Target: openstudio_lib") - Container(shared_gui, "shared_gui_components", "C++ shared library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs. Target: openstudio_modeleditor (linked via model_editor)") - Container(model_editor, "model_editor", "C++ shared library", "Generic IDD-driven model object inspector. Used by SketchUp plugin and debugging. Target: openstudio_modeleditor") - Container(bimserver, "bimserver", "C++ shared library", "BIMserver REST integration: project import/export via IFC. Target: openstudio_bimserver") - Container(utilities, "utilities", "C++ static/header library", "Runtime path resolution for SDK CLI, EnergyPlus, Radiance. Target: openstudio_utilities") - Container(qtwinmigrate, "qtwinmigrate", "C++ static library (Windows only)", "MFC/Qt bridge for SketchUp plugin embedding. Target: qtwinmigrate") + Container(shared_gui, "shared_gui_components", "C++ shared library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs, user settings. Target: openstudio_shared_gui") + Container(model_editor, "model_editor", "C++ shared library", "Generic IDD-driven model object inspector; AccessPolicyStore (field-level access policies for IDD objects). Target: openstudio_modeleditor") + Container(qt_utils, "openstudio_qt_utils", "C++ shared library", "Qt/OpenStudio primitives: string/UUID/path conversions, Application singleton, OSProgressBar, Qt metatype registration for SDK types. Target: openstudio_qt_utils") + Container(utilities, "utilities", "C++ static/header library", "Runtime path resolution for SDK CLI, EnergyPlus, Radiance. Target: openstudioapp_utilities") Rel(app_exe, openstudio_lib, "Links; creates OSDocument and MainWindow") - Rel(app_exe, shared_gui, "Links; uses MeasureManager, BCL dialogs") - Rel(openstudio_lib, shared_gui, "Uses grid widgets, form controls, measure integration") - Rel(openstudio_lib, model_editor, "Uses InspectorGadget for generic inspection") - Rel(bimserver, model_editor, "Links; uses Qt Network and model types") - Rel(bimserver, openstudio_lib, "Links to openstudio SDK via openstudio_lib") + Rel(openstudio_lib, shared_gui, "Links; uses grid widgets, form controls, measure integration") + Rel(openstudio_lib, model_editor, "Links; uses InspectorGadget, QMetaTypes") + Rel(shared_gui, qt_utils, "Links; Qt string/UUID conversions, Application singleton, metatype registration") + Rel(model_editor, qt_utils, "Links; Qt string/UUID conversions, Application singleton, OSProgressBar") + Rel(qt_utils, utilities, "Links; runtime path resolution for SDK CLI, EnergyPlus, Radiance") ``` --- @@ -93,35 +88,23 @@ flowchart TD LIB["openstudio_lib"] SHARED["shared_gui_components"] ME["model_editor"] - BIM["bimserver"] + QTUTILS["openstudio_qt_utils"] UTIL["utilities"] - QTWM["qtwinmigrate (Win32 only)"] - SDK["openstudio SDK\n(external)"] - QT["Qt 6\n(external)"] - BOOST["Boost\n(external)"] - CPPREST["cpprestsdk\n(external)"] + QTWEB["QT_WEB_LIBS
(external)"] + QTLIB["QT_LIBS
(external)"] + OSSDK["OpenStudio SDK
(external)"] + BOOST["Boost
(external)"] EXE --> LIB - EXE --> SHARED - EXE --> ME - EXE --> BIM - EXE --> UTIL LIB --> SHARED LIB --> ME - LIB --> SDK - LIB --> QT - LIB --> BOOST - SHARED --> ME - SHARED --> SDK - SHARED --> QT - ME --> SDK - ME --> QT - BIM --> ME - BIM --> CPPREST - BIM --> QT - BIM --> SDK - QTWM --> QT - EXE -. "Win32\nonly" .-> QTWM + LIB --> QTWEB + SHARED --> QTUTILS + ME --> QTUTILS + QTUTILS --> UTIL + QTUTILS --> QTLIB + UTIL --> OSSDK + UTIL --> BOOST ``` --- @@ -138,7 +121,6 @@ flowchart TD | Scripting | **Python** | 3.x | Measures, CLI scripting, language bindings | | Build | **CMake** | ≥3.10.2 + Presets | Build configuration, CPack packaging | | Package mgmt | **Conan 2** | 2.x | C++ dependency management | -| HTTP/REST | **cpprestsdk** | 2.10.19 | BIMserver REST API client | | General utils | **Boost** | 1.79 | Optional, smart_ptr, filesystem | | XML | **pugixml / libxml2 / libxslt** | system | XML parsing | | JSON | **jsoncpp** | 1.9.5 | JSON serialization | @@ -158,13 +140,18 @@ The project uses **CMake Presets** with **Conan 2** for reproducible builds acro ```bash # 1. Install Conan 2, CMake ≥3.10.2, Qt 6.5.2 (via aqtinstall), compiler -# 2. Configure Conan profile (C++20, Release) -conan install . --build=missing -pr:b=default -pr:h=default +# 2. Add NREL Conan remote +conan remote add -f nrel-v2 http://conan.openstudio.net/artifactory/api/conan/conan-v2 -# 3. Configure CMake using the generated preset -cmake --preset conan-release +# 3. Install dependencies +conan install . --output-folder=../OSApp-build-release --build=missing \ + -c tools.cmake.cmaketoolchain:generator=Ninja \ + -s compiler.cppstd=20 -s build_type=Release -# 4. Build +# 4. Configure CMake using the generated preset +cmake --preset conan-release -DQT_INSTALL_DIR:PATH=/path/to/Qt/6.x.x/ + +# 5. Build cmake --build --preset conan-release --target package ``` @@ -175,9 +162,11 @@ See [BUILDING.md](../../BUILDING.md) for the complete, platform-specific instruc | Target | Type | Description | |---|---|---| | `OpenStudioApp` | Executable | Main application binary | -| `openstudio_lib` | Shared library | GUI library | -| `openstudio_modeleditor` | Shared library | Generic model inspector | -| `openstudio_bimserver` | Shared library | BIMserver integration | +| `openstudio_lib` | Shared library | Tab GUI library | +| `openstudio_shared_gui` | Shared library | Reusable widget library | +| `openstudio_modeleditor` | Shared library | Generic IDD-driven model inspector | +| `openstudio_qt_utils` | Shared library | Qt/OpenStudio primitives: string/UUID/path conversions, `Application` singleton, `OSProgressBar`, Qt metatype registration for SDK types | +| `openstudioapp_utilities` | Static library | Runtime path helpers | | `package` | CPack | Platform installer (`.exe`/`.dmg`/`.deb`/`.tar.gz`) | ### Platform Packaging @@ -192,9 +181,9 @@ See [BUILDING.md](../../BUILDING.md) for the complete, platform-specific instruc ## 7. Key Architectural Patterns -### 7.1 Tab-Based MVC Triad +### 7.1 Tab-Based Master-Detail Pattern -Each major domain (HVAC, Schedules, Constructions, Geometry, etc.) follows a three-class pattern: +Each major domain (HVAC, Schedules, Constructions, Geometry, etc.) follows a three-class pattern. The **Model** role is played by the OpenStudio SDK model objects (`openstudio::model::Model` and its children); the controller mediates between those objects and two views: ```mermaid classDiagram @@ -210,12 +199,19 @@ classDiagram class InspectorWidget { +update(ModelObject) } + class OpenStudio::ModelObject { + <> + } MainTabController "1" --> "1" MainTabView : owns MainTabController "1" --> "0..1" InspectorWidget : controls + MainTabController --> ModelObject : reads / mutates + InspectorWidget --> ModelObject : reads / mutates note for MainTabController "Each domain derives from MainTabController\ne.g. HVACSystemsTabController" ``` -The derived tab controller (e.g., `HVACSystemsTabController`) creates the domain-specific view, handles user actions, and coordinates the inspector panel shown in the right column. +This is a **master-detail** variant of MVC: `MainTabView` is the master (list or primary content area) and `InspectorWidget` is the detail panel shown in the right column when an object is selected. Views do observe model changes — `ModelObjectListView` connects directly to `OSAppBase::workspaceObjectAddedPtr` / `workspaceObjectRemovedPtr`, which are Qt signals re-broadcast from the SDK model. `OSAppBase` acts as a model-change event bus shared across the application. + +The derived tab controller (e.g., `HVACSystemsTabController`) creates the domain-specific view, handles user actions, mutates the SDK model objects, and refreshes the inspector panel accordingly. ### 7.2 OSVectorController / Drop Zone Pattern @@ -268,8 +264,8 @@ See [ci/overview.md](ci/overview.md) for the full CI/CD architecture documentati |---|---|---| | `src/openstudio_app/` | `OpenStudioApp` (exe) | [libraries/openstudio_app.md](libraries/openstudio_app.md) | | `src/openstudio_lib/` | `openstudio_lib` | [libraries/openstudio_lib.md](libraries/openstudio_lib.md) | -| `src/shared_gui_components/` | linked via model_editor | [libraries/shared_gui_components.md](libraries/shared_gui_components.md) | -| `src/model_editor/` | `openstudio_modeleditor` | [libraries/model_editor.md](libraries/model_editor.md) | +| `src/shared_gui_components/` | `openstudio_shared_gui` | [libraries/shared_gui_components.md](libraries/shared_gui_components.md) | | `src/bimserver/` | `openstudio_bimserver` | [libraries/bimserver.md](libraries/bimserver.md) | -| `src/utilities/` | `openstudio_utilities` | [libraries/utilities.md](libraries/utilities.md) | -| `src/qtwinmigrate/` | `qtwinmigrate` (Win32) | [libraries/qtwinmigrate.md](libraries/qtwinmigrate.md) | +| `src/model_editor/` | `openstudio_modeleditor` | [libraries/model_editor.md](libraries/model_editor.md) | +| `src/openstudio_qt_utils/` | `openstudio_qt_utils` | [libraries/openstudio_qt_utils.md](libraries/openstudio_qt_utils.md) | +| `src/utilities/` | `openstudioapp_utilities` | [libraries/utilities.md](libraries/utilities.md) | diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index 767d4bb09..f75dcf5bb 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -134,8 +134,9 @@ classDiagram | Module | Usage | |---|---| -| `shared_gui_components` | Grid system, form widgets, `MeasureManager`, `BCLMeasureDialog` | -| `model_editor` | `InspectorGadget`, `QMetaTypes` | +| `shared_gui_components` | Grid system, form widgets, `MeasureManager`, `BCLMeasureDialog`, `UserSettings` | +| `model_editor` | `InspectorGadget`, `QMetaTypes` (for `OSItemId` metatype registration) | +| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions) | --- diff --git a/developer/doc/libraries/openstudio_qt_utils.md b/developer/doc/libraries/openstudio_qt_utils.md new file mode 100644 index 000000000..99369fe62 --- /dev/null +++ b/developer/doc/libraries/openstudio_qt_utils.md @@ -0,0 +1,139 @@ +# Library: `openstudio_qt_utils` — Qt/OpenStudio Primitives + +> **Source:** `src/openstudio_qt_utils/` +> **CMake target:** `openstudio_qt_utils` +> **Back to:** [Architecture Overview](../architecture.md) + +## Purpose + +`openstudio_qt_utils` is the lowest-level Qt-aware library in the application. It contains utilities that are needed by both `shared_gui_components` and `model_editor`, but which have no dependency on either. Placing them here breaks the old cycle where `shared_gui_components` was forced to link `model_editor` just to access string conversion helpers. + +Key responsibilities: +- **String / UUID / path conversions** — bidirectional translation between `std::string`, `std::wstring`, `openstudio::path`, `openstudio::UUID`, and `QString` +- **Application singleton** — manages the `QCoreApplication` / `QApplication` lifecycle and provides a cross-module `QSettings` accessor +- **Qt metatype registration** — `Q_DECLARE_METATYPE` and `qRegisterMetaType` calls for OpenStudio SDK types used in queued signals/slots (`IddObjectType`, `UUID`, `Quantity`, etc.) +- **Progress bar widget** — `OSProgressBar`, a thin Qt wrapper around `openstudio::ProgressBar` for displaying SDK-driven progress in a `QProgressBar` + +--- + +## Key Classes + +```mermaid +classDiagram + class Application { + <> + +instance() Application& + +application(gui) QCoreApplication* + +setApplication(QCoreApplication*) + +hasApplication() bool + +hasGUI() bool + +processEvents() + +hasSetting(key) bool$ + +getSettingValueAsBool(key) optional~bool~$ + +setSettingValue(key, value)$ + } + class OSProgressBar { + +OSProgressBar(parent) + +setRange(min, max) + +setValue(int) + +setWindowTitle(string) + +isVisible() bool + +onPercentageUpdated(double) + } + Application --> QCoreApplication : manages lifecycle + OSProgressBar --> QProgressBar : wraps + OSProgressBar --> openstudio_SDK_ProgressBar : extends +``` + +--- + +## Files + +| File | Description | +|---|---| +| `OpenStudioQtUtilsAPI.hpp` | DLL export macro (`OPENSTUDIOQTUTILS_API`) for Windows shared library symbol visibility | +| `Application.hpp/cpp` | `openstudio::Application` singleton — `QApplication` lifecycle management and `QSettings` read/write | +| `Utilities.hpp/cpp` | Free functions for converting between `QString`, `std::string`, `std::wstring`, `openstudio::path`, and `openstudio::UUID` | +| `QMetaTypes.hpp/cpp` | `Q_DECLARE_METATYPE` declarations and `qRegisterMetaType` calls for SDK types used in queued signal/slot connections | +| `OSProgressBar.hpp/cpp` | `OSProgressBar` — wraps `QProgressBar` and implements the `openstudio::ProgressBar` interface | + +--- + +## Key API + +### Utilities + +```cpp +namespace openstudio { + std::string toString(const QString& q); + std::wstring toWString(const QString& q); + QString toQString(const std::string& s); + QString toQString(const std::wstring& w); + QString toQString(const UUID& uuid); + QString toQString(const path& p); + UUID toUUID(const QString& str); + path toPath(const QString& q); +} +``` + +### Application + +```cpp +namespace openstudio { + // Retrieve (or lazily create) the QApplication/QCoreApplication + QCoreApplication* Application::instance().application(bool gui = true); + + // Wrap an existing QApplication created by a host (e.g. SketchUp) + Application::instance().setApplication(QCoreApplication*); + + // Cross-module QSettings access + Application::hasSetting(const std::string& key); + Application::getSettingValueAsBool(const std::string& key); // → boost::optional + Application::getSettingValueAsInt(const std::string& key); // → boost::optional + Application::getSettingValueAsDouble(const std::string& key); // → boost::optional + Application::getSettingValueAsString(const std::string& key); // → boost::optional + Application::setSettingValue(const std::string& key, T value); +} +``` + +### Metatypes registered + +| Type | Registered name | +|---|---| +| `openstudio::IddObjectType` | `"openstudio::IddObjectType"` | +| `openstudio::IddFileType` | `"openstudio::IddFileType"` | +| `openstudio::UUID` | `"openstudio::UUID"` | +| `std::string` | `"std::string"` | +| `std::vector` | `"std::vector"` | +| `boost::optional` | respective names | +| `openstudio::Quantity` | `"openstudio::Quantity"` | +| `openstudio::OSOptionalQuantity` | `"openstudio::OSOptionalQuantity"` | +| `std::shared_ptr` | _(anonymous)_ | + +> **Note:** `OSItemId` and `std::vector` are registered in `model_editor/QMetaTypes.cpp` since they depend on `openstudio_lib/OSItem.hpp`, which sits above this library in the dependency graph. + +--- + +## External Dependencies + +| Dependency | Usage | +|---|---| +| **Qt 6** (`QtWidgets`, `QtCore`) | `QApplication`, `QCoreApplication`, `QSettings`, `QString`, `QProgressBar`, metatype system | +| **OpenStudio SDK** (`utilities/core`, `utilities/idd`, `utilities/units`, `utilities/idf`, `utilities/plot`) | `UUID`, `path`, `IddObjectType`, `Quantity`, `WorkspaceObject_Impl`, `ProgressBar` | +| **Boost** | `boost::optional` in `Application` settings API | + +--- + +## Internal Dependencies + +| Module | Usage | +|---|---| +| `openstudioapp_utilities` | `getOpenStudioModuleDirectory()` used by `Application` to configure Qt plugin search paths | + +--- + +## Patterns & Conventions + +- **Singleton via local static** — `Application::instance()` uses a function-local `static Application` for thread-safe lazy initialisation (C++11 magic statics). +- **Lazy `QApplication` creation** — `application(bool gui)` creates a headless `QCoreApplication` or full `QApplication` only if no `QCoreApplication::instance()` already exists, making it safe to call from both GUI and CLI contexts. +- **Global metatype registration via namespace-scope statics** — the `int __xxx_type = qRegisterMetaType(...)` variables in `QMetaTypes.cpp` run at shared library load time, ensuring types are registered before any signal/slot connection is made. diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index d095ceddf..4570137b2 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -153,8 +153,8 @@ flowchart TD | Module | Usage | |---|---| -| `model_editor` | `QMetaTypes` for meta-type registration | -| `openstudio_lib` | `OSItem`, `OSVectorController` (used in OSGridController) | +| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration), `OSProgressBar` | +| `openstudio_lib` | `OSItem`, `OSVectorController` (used in `OSGridController`) | --- diff --git a/llms.txt b/llms.txt new file mode 100644 index 000000000..438957095 --- /dev/null +++ b/llms.txt @@ -0,0 +1,177 @@ +# OpenStudio Application — LLM Agent Reference + +For a human-readable architecture overview see developer/doc/architecture.md. +This file is optimised for LLM coding agents: dense facts, rules, and quick lookups. + +--- + +## Repo layout + +``` +src/ + openstudio_app/ → executable (OpenStudioApp) + openstudio_lib/ → openstudio_lib (main GUI tab library) + shared_gui_components/ → openstudio_shared_gui (reusable widgets) + model_editor/ → openstudio_modeleditor (IDD-driven inspector) + openstudio_qt_utils/ → openstudio_qt_utils (Qt/OpenStudio primitives) + utilities/ → openstudioapp_utilities (path resolution, static lib) + bimserver/ → openstudio_bimserver (optional BIM server integration) +developer/doc/ → architecture docs, per-library docs +resources/ → runtime resources (icons, policy XML, etc.) +``` + +--- + +## Dependency graph (enforced — do not violate) + +``` +OpenStudioApp (exe) + └── openstudio_lib + ├── openstudio_shared_gui + │ └── openstudio_qt_utils + │ └── openstudioapp_utilities + │ └── OpenStudio SDK (external) + └── openstudio_modeleditor + └── openstudio_qt_utils (same chain as above) +``` + +**Hard rules:** +- `shared_gui_components` MUST NOT include headers from `openstudio_lib` or `model_editor`. +- `model_editor` MUST NOT include headers from `shared_gui_components` or `openstudio_lib`. +- `openstudio_qt_utils` MUST NOT include headers from any of the above. +- `utilities` MUST NOT include Qt headers (it is a static lib with no Qt dependency). +- Cross-library includes use relative paths: `"../other_lib/Header.hpp"`. +- SDK headers use angle-bracket includes: ``. + +--- + +## API macros → library mapping + +| Macro | Library target | Header | +|---|---|---| +| `MODELEDITOR_API` | `openstudio_modeleditor` | `src/model_editor/ModelEditorAPI.hpp` | +| `OPENSTUDIO_API` | `openstudio_lib` | `src/openstudio_lib/OpenStudioAPI.hpp` | +| `OPENSTUDIOQTUTILS_API` | `openstudio_qt_utils` | `src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp` | +| `SHARED_OSAPP_LIBS` | all shared libs | compile-time flag for dllexport/dllimport | + +When adding a new class to a library, inherit its `*_API` macro from that library's API header — never from another library's macro. + +--- + +## CMake target → depends (what to add when you need a new dependency) + +To use a class from library X in library Y, add X's CMake target to Y's `set(${target_name}_depends ...)` block in `src/Y/CMakeLists.txt`. + +| You are in | You need | Add to depends | +|---|---|---| +| `openstudio_lib` | anything from `model_editor` | `openstudio_modeleditor` | +| `openstudio_lib` | anything from `shared_gui_components` | `openstudio_shared_gui` | +| `shared_gui_components` | Qt primitives, Application, QMetaTypes | `openstudio_qt_utils` | +| `model_editor` | Qt primitives, Application, QMetaTypes | `openstudio_qt_utils` | +| any library | SDK types | `openstudioapp_utilities` (pulls in SDK transitively) | + +`openstudio_qt_utils` already depends on `${QT_LIBS}` and `openstudioapp_utilities`; don't re-add them to higher-level libs. + +--- + +## File-level inventory: where key classes live + +### openstudio_qt_utils (`src/openstudio_qt_utils/`) +| File | Key class / function | +|---|---| +| `Application.hpp/.cpp` | `openstudio::Application` — Qt application singleton, OpenGL format setup | +| `Utilities.hpp/.cpp` | `openstudio::toQString()`, `toString()`, `toPath()`, `toUUID()`, etc. | +| `QMetaTypes.hpp/.cpp` | `Q_DECLARE_METATYPE` + `qRegisterMetaType` for all SDK types (`IddObjectType`, `UUID`, `OSItemId`, etc.) | +| `OSProgressBar.hpp/.cpp` | `openstudio::OSProgressBar` — Qt progress bar wrapping SDK `ProgressBar` | +| `OpenStudioQtUtilsAPI.hpp` | `OPENSTUDIOQTUTILS_API` macro | + +### model_editor (`src/model_editor/`) +| File | Key class | +|---|---| +| `AccessPolicyStore.hpp/.cpp` | `openstudio::model::AccessPolicy`, `AccessPolicyStore` — field-level access policies (FREE/LOCKED/HIDDEN) for IDD object types; used by InspectorGadget | +| `InspectorGadget.hpp/.cpp` | `openstudio::InspectorGadget` — IDD-driven field editor widget | +| `InspectorDialog.hpp/.cpp` | `openstudio::InspectorDialog` — standalone dialog wrapping InspectorGadget | +| `PathWatcher.hpp/.cpp` | `openstudio::PathWatcher` — filesystem path change notifications | +| `GithubReleases.hpp/.cpp` | `openstudio::GithubReleases` — checks GitHub releases API for new versions | +| `ModalDialogs.hpp/.cpp` | `openstudio::ModelObjectSelectorDialog` — generic model-object picker dialog | +| `ModelEditorAPI.hpp` | `MODELEDITOR_API` macro; also includes `openstudio_qt_utils/QMetaTypes.hpp` | + +### shared_gui_components (`src/shared_gui_components/`) +| File | Key class | +|---|---| +| `BaseApp.hpp` | `openstudio::BaseApp` — pure virtual interface implemented by `OSAppBase`; provides `currentModel()`, `currentDocument()`, `mouseOverInspectorView()`, etc. | +| `OSGridController.hpp/.cpp` | `openstudio::OSGridController` — base for tabular views; registers `OSItemId` metatype | +| `OSGridView.hpp/.cpp` | `openstudio::OSGridView` — renders the grid | +| `OSObjectSelector.hpp/.cpp` | `openstudio::OSObjectSelector` — manages row selection in grids | +| `OSLineEdit.hpp/.cpp` | `openstudio::OSLineEdit2` — line edit bound to a model object field | +| `MeasureManager.hpp/.cpp` | `openstudio::MeasureManager` — scans/runs OpenStudio Measures | +| `UserSettings.hpp/.cpp` | `openstudio::UserSettings` — persistent user preferences | + +### openstudio_lib (`src/openstudio_lib/`) +| File | Key class | +|---|---| +| `OSAppBase.hpp/.cpp` | `openstudio::OSAppBase` — concrete `BaseApp`; app-wide event bus, current document, current model | +| `OSDocument.hpp/.cpp` | `openstudio::OSDocument` — owns one OSM model, all tab controllers | +| `InspectorView.hpp/.cpp` | `openstudio::InspectorView` — right-column inspector; overrides `AccessPolicy` fields | +| `InspectorController.hpp/.cpp` | `openstudio::InspectorController` — mediates between inspector view and model objects | +| `MainRightColumnController.hpp/.cpp` | `openstudio::MainRightColumnController` — manages the right column (inspector vs. library vs. edit) | +| `ModelObjectItem.hpp/.cpp` | `openstudio::ModelObjectItem` — OSItem subclass for model objects | +| `HVACSystemsController.hpp/.cpp` | `openstudio::HVACSystemsController` — HVAC tab | +| `GeometryEditorView.hpp/.cpp` | `openstudio::GeometryEditorView` — WebEngine-based 3D geometry editor | + +--- + +## Include path conventions + +```cpp +// Within same library — use bare name: +#include "AccessPolicyStore.hpp" + +// From model_editor, reaching into openstudio_qt_utils: +#include "../openstudio_qt_utils/Application.hpp" + +// From openstudio_lib, reaching into model_editor: +#include "../model_editor/InspectorGadget.hpp" + +// From openstudio_lib, reaching into shared_gui_components: +#include "../shared_gui_components/BaseApp.hpp" + +// OpenStudio SDK (always angle-bracket): +#include +#include + +// Qt (always angle-bracket): +#include +#include +``` + +--- + +## Interface extension pattern + +When `shared_gui_components` needs runtime information that lives in `openstudio_lib` (to avoid a circular dependency): + +1. Add a pure virtual method to `BaseApp` in `src/shared_gui_components/BaseApp.hpp`. +2. Implement it in `OSAppBase` in `src/openstudio_lib/OSAppBase.hpp/.cpp`. +3. Call it in `shared_gui_components` via `OSAppBase::instance()->theNewMethod()`. + +Example: `mouseOverInspectorView()` was added this way so `OSLineEdit.cpp` (in `shared_gui`) could query the inspector without including `InspectorView.hpp`. + +--- + +## Qt metatype registration + +All SDK type metatype registrations live in `src/openstudio_qt_utils/QMetaTypes.hpp/.cpp`. +`OSItemId` registration is in `src/shared_gui_components/OSGridController.cpp` (requires the type definition from `openstudio_lib`). +Do NOT add metatype registrations to `model_editor/ModelEditorAPI.hpp` — that header is included everywhere. + +--- + +## Common mistakes to avoid + +- Do not add `#include "../model_editor/..."` to any file in `shared_gui_components/`. +- Do not add `#include "../openstudio_lib/..."` to any file in `shared_gui_components/` or `model_editor/`. +- Do not add `#include "../shared_gui_components/..."` to any file in `model_editor/`. +- Do not use `MODELEDITOR_API` for classes that live in `openstudio_qt_utils` (use `OPENSTUDIOQTUTILS_API`). +- Do not call `qRegisterMetaType` at global scope in headers — only in `.cpp` or in `QMetaTypes.cpp`. +- When moving a class between libraries, update both the source-list in `CMakeLists.txt` AND all `#include` paths in consumers. diff --git a/src/bimserver/BIMserverConnection.cpp b/src/bimserver/BIMserverConnection.cpp index 21ed625bf..2a20bd873 100644 --- a/src/bimserver/BIMserverConnection.cpp +++ b/src/bimserver/BIMserverConnection.cpp @@ -5,8 +5,8 @@ #include "BIMserverConnection.hpp" -#include "../model_editor/Application.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/bimserver/CMakeLists.txt b/src/bimserver/CMakeLists.txt index 3ae7fafb6..4bae08653 100644 --- a/src/bimserver/CMakeLists.txt +++ b/src/bimserver/CMakeLists.txt @@ -23,21 +23,13 @@ set(${target_name}_swig_src ) set(${target_name}_depends - ${Boost_LIBRARIES} - ${CMAKE_THREAD_LIBS} - openstudio_modeleditor - openstudio::openstudiolib - ${QT_LIBS} + openstudio_qt_utils ) add_library(${target_name} ${${target_name}_src}) -target_link_libraries(${target_name} ${${target_name}_depends}) +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) AddPCH(${target_name}) -if(BUILD_MICRO_PROFILING) - target_link_libraries(${target_name} ${MICRO_PROFILER_LIB} ) -endif() - #if(NOT APPLE) #install(TARGETS ${target_name} # RUNTIME DESTINATION bin diff --git a/src/model_editor/AccessPolicyStore.hpp b/src/model_editor/AccessPolicyStore.hpp index 465df464a..bb8a1555a 100644 --- a/src/model_editor/AccessPolicyStore.hpp +++ b/src/model_editor/AccessPolicyStore.hpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODEL_ACCESSPOLICYSTORE_HPP -#define MODEL_ACCESSPOLICYSTORE_HPP +#ifndef MODELEDITOR_ACCESSPOLICYSTORE_HPP +#define MODELEDITOR_ACCESSPOLICYSTORE_HPP #include "ModelEditorAPI.hpp" diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index 63aca23c1..a8825598c 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -9,8 +9,6 @@ include_directories(${QT_INCLUDES}) # lib files set(${target_name}_src - Application.hpp - Application.cpp AccessPolicyStore.hpp AccessPolicyStore.cpp BridgeClasses.hpp @@ -25,22 +23,14 @@ set(${target_name}_src ListWidget.cpp ModalDialogs.hpp ModalDialogs.cpp - OSProgressBar.hpp - OSProgressBar.cpp PathWatcher.hpp PathWatcher.cpp - QMetaTypes.hpp - QMetaTypes.cpp TableView.hpp TableView.cpp TableWidget.hpp TableWidget.cpp TestButton.hpp TestButton.cpp - UserSettings.hpp - UserSettings.cpp - Utilities.hpp - Utilities.cpp IGLineEdit.hpp IGLineEdit.cpp IGSpinBoxes.hpp @@ -88,14 +78,11 @@ add_library(${target_name} # lib dependencies set(${target_name}_depends - openstudio::openstudiolib - openstudioapp_utilities - ${QT_LIBS} - #Ruby::Ruby + openstudio_qt_utils ) add_dependencies(${target_name} ${${target_name}_depends}) -target_link_libraries(${target_name} ${${target_name}_depends}) +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) if(BUILD_SHARED_LIBS) #target_compile_definitions(${target_name} PUBLIC model_editor_EXPORTS) diff --git a/src/model_editor/GithubReleases.cpp b/src/model_editor/GithubReleases.cpp index 84a5f12bc..3b3b902a4 100644 --- a/src/model_editor/GithubReleases.cpp +++ b/src/model_editor/GithubReleases.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "GithubReleases.hpp" -#include "Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include diff --git a/src/model_editor/InspectorDialog.cpp b/src/model_editor/InspectorDialog.cpp index 3ba0cbcb9..782d60384 100644 --- a/src/model_editor/InspectorDialog.cpp +++ b/src/model_editor/InspectorDialog.cpp @@ -5,9 +5,9 @@ #include "InspectorGadget.hpp" #include "InspectorDialog.hpp" -#include "Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include "AccessPolicyStore.hpp" -#include "Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/model_editor/InspectorGadget.cpp b/src/model_editor/InspectorGadget.cpp index aae9a1d08..061830399 100644 --- a/src/model_editor/InspectorGadget.cpp +++ b/src/model_editor/InspectorGadget.cpp @@ -14,7 +14,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/model_editor/ModalDialogs.cpp b/src/model_editor/ModalDialogs.cpp index 81b3c480d..03a0ca257 100644 --- a/src/model_editor/ModalDialogs.cpp +++ b/src/model_editor/ModalDialogs.cpp @@ -5,8 +5,8 @@ #include "ModalDialogs.hpp" -#include "Application.hpp" -#include "Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/model_editor/ModelEditor.i b/src/model_editor/ModelEditor.i index 0a70be9a1..38b4371ba 100644 --- a/src/model_editor/ModelEditor.i +++ b/src/model_editor/ModelEditor.i @@ -22,7 +22,7 @@ %{ #include - #include + #include #include #include diff --git a/src/model_editor/ModelEditorAPI.hpp b/src/model_editor/ModelEditorAPI.hpp index 9f7cd5504..b3f998d43 100644 --- a/src/model_editor/ModelEditorAPI.hpp +++ b/src/model_editor/ModelEditorAPI.hpp @@ -3,7 +3,7 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #ifndef MODELEDITOR_MODELEDITORAPI_HPP # define MODELEDITOR_MODELEDITORAPI_HPP diff --git a/src/model_editor/PathWatcher.cpp b/src/model_editor/PathWatcher.cpp index efa930828..6cfc0a345 100644 --- a/src/model_editor/PathWatcher.cpp +++ b/src/model_editor/PathWatcher.cpp @@ -4,9 +4,9 @@ ***********************************************************************************************************************/ #include "PathWatcher.hpp" -#include "Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/model_editor/test/GithubReleases_GTest.cpp b/src/model_editor/test/GithubReleases_GTest.cpp index 94dd09e19..181c636fa 100644 --- a/src/model_editor/test/GithubReleases_GTest.cpp +++ b/src/model_editor/test/GithubReleases_GTest.cpp @@ -8,7 +8,7 @@ #include "ModelEditorFixture.hpp" #include "../GithubReleases.hpp" -#include "../Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include diff --git a/src/model_editor/test/ModelEditorFixture.cpp b/src/model_editor/test/ModelEditorFixture.cpp index 9b0b71a01..5126f1623 100644 --- a/src/model_editor/test/ModelEditorFixture.cpp +++ b/src/model_editor/test/ModelEditorFixture.cpp @@ -5,7 +5,7 @@ #include "ModelEditorFixture.hpp" -#include "../../model_editor/Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include diff --git a/src/model_editor/test/PathWatcher_GTest.cpp b/src/model_editor/test/PathWatcher_GTest.cpp index 3ea85d974..2573c094e 100644 --- a/src/model_editor/test/PathWatcher_GTest.cpp +++ b/src/model_editor/test/PathWatcher_GTest.cpp @@ -10,7 +10,7 @@ #include "ModelEditorFixture.hpp" #include "../PathWatcher.hpp" -#include "../Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include #include diff --git a/src/model_editor/test/QMetaTypes_GTest.cpp b/src/model_editor/test/QMetaTypes_GTest.cpp index 022ee330b..9f3f90e1c 100644 --- a/src/model_editor/test/QMetaTypes_GTest.cpp +++ b/src/model_editor/test/QMetaTypes_GTest.cpp @@ -10,7 +10,7 @@ #include #include -#include "../QMetaTypes.hpp" +#include "../../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/model_editor/test/Utilities_GTest.cpp b/src/model_editor/test/Utilities_GTest.cpp index 3fadfdaef..08b7cbb53 100644 --- a/src/model_editor/test/Utilities_GTest.cpp +++ b/src/model_editor/test/Utilities_GTest.cpp @@ -8,7 +8,7 @@ #include #include "ModelEditorFixture.hpp" -#include "../Utilities.hpp" +#include "../../openstudio_qt_utils/Utilities.hpp" #include #include @@ -145,4 +145,4 @@ TEST_F(ModelEditorFixture, MorePath_Conversions) { << "QPath: " << qPath.toStdString() << ", " << "Url: " << url.toString().toStdString() << std::endl; } -} \ No newline at end of file +} diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index b2620d38d..d535b4c9b 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -16,13 +16,6 @@ set(${target_name}_SRC LibraryDialog.cpp ExternalToolsDialog.hpp ExternalToolsDialog.cpp - - ../shared_gui_components/BusyWidget.cpp - ../shared_gui_components/BusyWidget.hpp - ../shared_gui_components/OSDialog.cpp - ../shared_gui_components/OSDialog.hpp - ../shared_gui_components/WaitDialog.cpp - ../shared_gui_components/WaitDialog.hpp ) # moc files @@ -32,10 +25,6 @@ set(${target_name}_moc StartupMenu.hpp LibraryDialog.hpp ExternalToolsDialog.hpp - - ../shared_gui_components/BusyWidget.hpp - ../shared_gui_components/OSDialog.hpp - ../shared_gui_components/WaitDialog.hpp ) ## Qt UI generation @@ -294,10 +283,6 @@ endif() set(depends openstudio_lib openstudio_bimserver - openstudio_modeleditor - openstudioapp_utilities - openstudio::openstudiolib - ${QT_WEB_LIBS} ) target_link_libraries(${target_name} ${depends}) diff --git a/src/openstudio_app/ExternalToolsDialog.cpp b/src/openstudio_app/ExternalToolsDialog.cpp index 9754a8192..3cd9fe83b 100644 --- a/src/openstudio_app/ExternalToolsDialog.cpp +++ b/src/openstudio_app/ExternalToolsDialog.cpp @@ -5,8 +5,9 @@ #include "./ExternalToolsDialog.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" +#include #include #include diff --git a/src/openstudio_app/LibraryDialog.cpp b/src/openstudio_app/LibraryDialog.cpp index 32c914860..2a716c83b 100644 --- a/src/openstudio_app/LibraryDialog.cpp +++ b/src/openstudio_app/LibraryDialog.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "./LibraryDialog.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_app/OpenStudioApp.cpp b/src/openstudio_app/OpenStudioApp.cpp index 6d4c54d4e..ea602cf7e 100644 --- a/src/openstudio_app/OpenStudioApp.cpp +++ b/src/openstudio_app/OpenStudioApp.cpp @@ -14,7 +14,7 @@ #include "../model_editor/AccessPolicyStore.hpp" #include "../model_editor/GithubReleases.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/WaitDialog.hpp" #include "../shared_gui_components/MeasureManager.hpp" diff --git a/src/openstudio_app/main.cpp b/src/openstudio_app/main.cpp index d6938e324..a16eeaaca 100644 --- a/src/openstudio_app/main.cpp +++ b/src/openstudio_app/main.cpp @@ -6,9 +6,9 @@ #define COMPILING_FROM_OSAPP #include "../openstudio_lib/OpenStudioAPI.hpp" #include "OpenStudioApp.hpp" -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include "../model_editor/AccessPolicyStore.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_app/test/OpenStudioAppFixture.cpp b/src/openstudio_app/test/OpenStudioAppFixture.cpp index 46f8f5229..812de1394 100644 --- a/src/openstudio_app/test/OpenStudioAppFixture.cpp +++ b/src/openstudio_app/test/OpenStudioAppFixture.cpp @@ -5,7 +5,7 @@ #include "OpenStudioAppFixture.hpp" -#include "../../model_editor/Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include #include diff --git a/src/openstudio_app/test/Resources_GTest.cpp b/src/openstudio_app/test/Resources_GTest.cpp index e462c400e..cbedb3a3d 100644 --- a/src/openstudio_app/test/Resources_GTest.cpp +++ b/src/openstudio_app/test/Resources_GTest.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../model_editor/Utilities.hpp" +#include "../../openstudio_qt_utils/Utilities.hpp" // Include our OS App specific one #include "../../utilities/OpenStudioApplicationPathHelpers.hpp" diff --git a/src/openstudio_lib/AnalyticsHelper.cpp b/src/openstudio_lib/AnalyticsHelper.cpp index c7fb74155..4c0decc6c 100644 --- a/src/openstudio_lib/AnalyticsHelper.cpp +++ b/src/openstudio_lib/AnalyticsHelper.cpp @@ -6,8 +6,8 @@ #include "AnalyticsHelper.hpp" #include "AnalyticsHelperSecrets.hxx" -#include "../model_editor/Application.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include diff --git a/src/openstudio_lib/ApplyMeasureNowDialog.cpp b/src/openstudio_lib/ApplyMeasureNowDialog.cpp index 0f9f9fb12..23014e022 100644 --- a/src/openstudio_lib/ApplyMeasureNowDialog.cpp +++ b/src/openstudio_lib/ApplyMeasureNowDialog.cpp @@ -20,7 +20,7 @@ #include "OSDocument.hpp" #include "MainWindow.hpp" #include "OSItem.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index eff88aac6..402d090b4 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -13,8 +13,8 @@ #include "ModelObjectItem.hpp" #include "OSDropZone.hpp" -#include "OSVectorController.hpp" -#include "../model_editor/Utilities.hpp" +#include "../shared_gui_components/OSVectorController.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 28977df89..f5e1b6da7 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -105,8 +105,6 @@ set(${target_name}_SRC HVACSystemsView.hpp HVACTemplateHelperDialog.cpp HVACTemplateHelperDialog.hpp - IconLibrary.cpp - IconLibrary.hpp InspectorController.cpp InspectorController.hpp InspectorView.cpp @@ -210,8 +208,6 @@ set(${target_name}_SRC OSItemSelectorButtons.hpp OSWebEnginePage.cpp OSWebEnginePage.hpp - OSVectorController.cpp - OSVectorController.hpp OtherEquipmentInspectorView.cpp OtherEquipmentInspectorView.hpp PeopleInspectorView.cpp @@ -395,115 +391,6 @@ set(${target_name}_SRC ZoneChooserView.cpp ZoneChooserView.hpp - ../shared_gui_components/BCLMeasureDialog.cpp - ../shared_gui_components/BCLMeasureDialog.hpp - ../shared_gui_components/BuildingComponentDialog.cpp - ../shared_gui_components/BuildingComponentDialog.hpp - ../shared_gui_components/BuildingComponentDialogCentralWidget.cpp - ../shared_gui_components/BuildingComponentDialogCentralWidget.hpp - ../shared_gui_components/BusyWidget.cpp - ../shared_gui_components/BusyWidget.hpp - ../shared_gui_components/Buttons.cpp - ../shared_gui_components/Buttons.hpp - ../shared_gui_components/CollapsibleComponent.cpp - ../shared_gui_components/CollapsibleComponent.hpp - ../shared_gui_components/CollapsibleComponentHeader.cpp - ../shared_gui_components/CollapsibleComponentHeader.hpp - ../shared_gui_components/CollapsibleComponentList.cpp - ../shared_gui_components/CollapsibleComponentList.hpp - ../shared_gui_components/ColorPalettes.hpp - ../shared_gui_components/Component.cpp - ../shared_gui_components/Component.hpp - ../shared_gui_components/ComponentList.cpp - ../shared_gui_components/ComponentList.hpp - ../shared_gui_components/EditController.cpp - ../shared_gui_components/EditController.hpp - ../shared_gui_components/EditView.cpp - ../shared_gui_components/EditView.hpp - ../shared_gui_components/FieldMethodTypedefs.hpp - ../shared_gui_components/GraphicsItems.cpp - ../shared_gui_components/GraphicsItems.hpp - ../shared_gui_components/HeaderViews.cpp - ../shared_gui_components/HeaderViews.hpp - ../shared_gui_components/LocalLibrary.hpp - ../shared_gui_components/LocalLibraryController.cpp - ../shared_gui_components/LocalLibraryController.hpp - ../shared_gui_components/LocalLibraryView.cpp - ../shared_gui_components/LocalLibraryView.hpp - ../shared_gui_components/MeasureBadge.cpp - ../shared_gui_components/MeasureBadge.hpp - ../shared_gui_components/MeasureDragData.cpp - ../shared_gui_components/MeasureDragData.hpp - ../shared_gui_components/MeasureManager.cpp - ../shared_gui_components/MeasureManager.hpp - ../shared_gui_components/NetworkProxyDialog.cpp - ../shared_gui_components/NetworkProxyDialog.hpp - ../shared_gui_components/OSCellWrapper.cpp - ../shared_gui_components/OSCellWrapper.hpp - ../shared_gui_components/OSCheckBox.cpp - ../shared_gui_components/OSCheckBox.hpp - ../shared_gui_components/OSCollapsibleView.cpp - ../shared_gui_components/OSCollapsibleView.hpp - ../shared_gui_components/OSComboBox.cpp - ../shared_gui_components/OSComboBox.hpp - ../shared_gui_components/OSConcepts.hpp - ../shared_gui_components/OSDialog.cpp - ../shared_gui_components/OSDialog.hpp - ../shared_gui_components/OSDoubleEdit.cpp - ../shared_gui_components/OSDoubleEdit.hpp - ../shared_gui_components/OSDragableView.cpp - ../shared_gui_components/OSDragableView.hpp - ../shared_gui_components/OSGridController.cpp - ../shared_gui_components/OSGridController.hpp - ../shared_gui_components/OSGridView.cpp - ../shared_gui_components/OSGridView.hpp - ../shared_gui_components/OSIntegerEdit.cpp - ../shared_gui_components/OSIntegerEdit.hpp - ../shared_gui_components/OSLineEdit.cpp - ../shared_gui_components/OSLineEdit.hpp - ../shared_gui_components/OSListController.cpp - ../shared_gui_components/OSListController.hpp - ../shared_gui_components/OSListView.cpp - ../shared_gui_components/OSListView.hpp - ../shared_gui_components/OSLoadNamePixmapLineEdit.cpp - ../shared_gui_components/OSLoadNamePixmapLineEdit.hpp - ../shared_gui_components/OSObjectSelector.cpp - ../shared_gui_components/OSObjectSelector.hpp - ../shared_gui_components/OSQObjectController.cpp - ../shared_gui_components/OSQObjectController.hpp - ../shared_gui_components/OSQuantityEdit.cpp - ../shared_gui_components/OSQuantityEdit.hpp - ../shared_gui_components/OSSwitch.cpp - ../shared_gui_components/OSSwitch.hpp - ../shared_gui_components/OSUnsignedEdit.cpp - ../shared_gui_components/OSUnsignedEdit.hpp - ../shared_gui_components/OSViewSwitcher.cpp - ../shared_gui_components/OSViewSwitcher.hpp - ../shared_gui_components/OSWidgetHolder.cpp - ../shared_gui_components/OSWidgetHolder.hpp - ../shared_gui_components/PageNavigator.cpp - ../shared_gui_components/PageNavigator.hpp - ../shared_gui_components/ProcessEventsProgressBar.cpp - ../shared_gui_components/ProcessEventsProgressBar.hpp - ../shared_gui_components/ProgressBarWithError.cpp - ../shared_gui_components/ProgressBarWithError.hpp - ../shared_gui_components/SyncMeasuresDialog.cpp - ../shared_gui_components/SyncMeasuresDialog.hpp - ../shared_gui_components/SyncMeasuresDialogCentralWidget.cpp - ../shared_gui_components/SyncMeasuresDialogCentralWidget.hpp - ../shared_gui_components/TextEditDialog.cpp - ../shared_gui_components/TextEditDialog.hpp - ../shared_gui_components/TIDItemModel.cpp - ../shared_gui_components/TIDItemModel.hpp - ../shared_gui_components/WorkflowController.cpp - ../shared_gui_components/WorkflowController.hpp - ../shared_gui_components/WorkflowView.cpp - ../shared_gui_components/WorkflowView.hpp - ../shared_gui_components/WaitDialog.cpp - ../shared_gui_components/WaitDialog.hpp - ../shared_gui_components/WorkflowTools.cpp - ../shared_gui_components/WorkflowTools.hpp - #"${CMAKE_CURRENT_BINARY_DIR}/SWIGRubyRuntime.h" ) @@ -605,7 +492,6 @@ set(${target_name}_moc OSItemSelector.hpp OSItemSelectorButtons.hpp OSWebEnginePage.hpp - OSVectorController.hpp OtherEquipmentInspectorView.hpp PeopleInspectorView.hpp PlanarSurfaceWidget.hpp @@ -698,56 +584,6 @@ set(${target_name}_moc YearSettingsWidget.hpp ZoneChooserView.hpp - ../shared_gui_components/BCLMeasureDialog.hpp - ../shared_gui_components/BuildingComponentDialog.hpp - ../shared_gui_components/BuildingComponentDialogCentralWidget.hpp - ../shared_gui_components/BusyWidget.hpp - ../shared_gui_components/Buttons.hpp - ../shared_gui_components/CollapsibleComponent.hpp - ../shared_gui_components/CollapsibleComponentHeader.hpp - ../shared_gui_components/CollapsibleComponentList.hpp - ../shared_gui_components/Component.hpp - ../shared_gui_components/ComponentList.hpp - ../shared_gui_components/EditController.hpp - ../shared_gui_components/EditView.hpp - ../shared_gui_components/GraphicsItems.hpp - ../shared_gui_components/HeaderViews.hpp - ../shared_gui_components/LocalLibraryController.hpp - ../shared_gui_components/LocalLibraryView.hpp - ../shared_gui_components/MeasureBadge.hpp - ../shared_gui_components/MeasureDragData.hpp - ../shared_gui_components/MeasureManager.hpp - ../shared_gui_components/OSCellWrapper.hpp - ../shared_gui_components/OSCheckBox.hpp - ../shared_gui_components/OSCollapsibleView.hpp - ../shared_gui_components/OSComboBox.hpp - ../shared_gui_components/OSDialog.hpp - ../shared_gui_components/OSDoubleEdit.hpp - ../shared_gui_components/OSDragableView.hpp - ../shared_gui_components/OSGridController.hpp - ../shared_gui_components/OSGridView.hpp - ../shared_gui_components/OSIntegerEdit.hpp - ../shared_gui_components/OSLineEdit.hpp - ../shared_gui_components/OSListController.hpp - ../shared_gui_components/OSListView.hpp - ../shared_gui_components/OSLoadNamePixmapLineEdit.hpp - ../shared_gui_components/OSObjectSelector.hpp - ../shared_gui_components/OSQObjectController.hpp - ../shared_gui_components/OSQuantityEdit.hpp - ../shared_gui_components/OSSwitch.hpp - ../shared_gui_components/OSUnsignedEdit.hpp - ../shared_gui_components/OSViewSwitcher.hpp - ../shared_gui_components/OSWidgetHolder.hpp - ../shared_gui_components/PageNavigator.hpp - ../shared_gui_components/ProgressBarWithError.hpp - ../shared_gui_components/SyncMeasuresDialog.hpp - ../shared_gui_components/SyncMeasuresDialogCentralWidget.hpp - ../shared_gui_components/TextEditDialog.hpp - ../shared_gui_components/TIDItemModel.hpp - ../shared_gui_components/WorkflowController.hpp - ../shared_gui_components/WorkflowView.hpp - ../shared_gui_components/WaitDialog.hpp - ../shared_gui_components/NetworkProxyDialog.hpp ) #include_directories(SYSTEM ${Ruby_INCLUDE_DIRS}) @@ -779,13 +615,12 @@ if (NINJA) endif() set(${target_name}_depends + openstudio_shared_gui openstudio_modeleditor - openstudio::openstudiolib - ${QT_LIBS} ${QT_WEB_LIBS} ) -target_link_libraries(${target_name} ${${target_name}_depends}) +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) AddPCH(${target_name}) @@ -828,7 +663,8 @@ if(BUILD_BENCHMARK) get_filename_component(bench_name ${bench_file} NAME_WE) message("bench_name=${bench_name}") add_executable( ${bench_name} ${bench_file} ) - target_link_libraries(${bench_name} + target_link_libraries(${bench_name} + PUBLIC benchmark::benchmark ${target_name} ${${target_name}_test_depends} @@ -836,5 +672,3 @@ if(BUILD_BENCHMARK) endforeach() endif() - - diff --git a/src/openstudio_lib/GeometryEditorView.cpp b/src/openstudio_lib/GeometryEditorView.cpp index 27f2a1878..a9f9ba6db 100644 --- a/src/openstudio_lib/GeometryEditorView.cpp +++ b/src/openstudio_lib/GeometryEditorView.cpp @@ -40,7 +40,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/GeometryPreviewView.cpp b/src/openstudio_lib/GeometryPreviewView.cpp index 0e71d0621..4a2e2f49d 100644 --- a/src/openstudio_lib/GeometryPreviewView.cpp +++ b/src/openstudio_lib/GeometryPreviewView.cpp @@ -8,7 +8,7 @@ #include "OSDocument.hpp" #include "MainWindow.hpp" -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include #include diff --git a/src/openstudio_lib/GridItem.cpp b/src/openstudio_lib/GridItem.cpp index 483d46f4e..2b3ec9adc 100644 --- a/src/openstudio_lib/GridItem.cpp +++ b/src/openstudio_lib/GridItem.cpp @@ -5,7 +5,7 @@ #include "GridItem.hpp" #include "ServiceWaterGridItems.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include "LoopScene.hpp" #include "OSDocument.hpp" #include "OSAppBase.hpp" @@ -95,7 +95,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/GridViewSubTab.hpp b/src/openstudio_lib/GridViewSubTab.hpp index f329f7d7e..aa78dec32 100644 --- a/src/openstudio_lib/GridViewSubTab.hpp +++ b/src/openstudio_lib/GridViewSubTab.hpp @@ -12,6 +12,8 @@ #include #include +#include "OSItem.hpp" + #include class QScrollArea; diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index 4ce5d28ba..c0ea67850 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -8,7 +8,7 @@ #include "OSAppBase.hpp" #include "OSDocument.hpp" #include "OSItemSelectorButtons.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/HVACSystemsController.cpp b/src/openstudio_lib/HVACSystemsController.cpp index be4e0c3f1..b36deb694 100644 --- a/src/openstudio_lib/HVACSystemsController.cpp +++ b/src/openstudio_lib/HVACSystemsController.cpp @@ -118,7 +118,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/HVACSystemsController.hpp b/src/openstudio_lib/HVACSystemsController.hpp index 409354efe..6392d6825 100644 --- a/src/openstudio_lib/HVACSystemsController.hpp +++ b/src/openstudio_lib/HVACSystemsController.hpp @@ -20,7 +20,7 @@ #include #include #include // Signal-Slot replacement -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" class QMutex; diff --git a/src/openstudio_lib/InspectorView.cpp b/src/openstudio_lib/InspectorView.cpp index 72aa8065d..a188ef63e 100644 --- a/src/openstudio_lib/InspectorView.cpp +++ b/src/openstudio_lib/InspectorView.cpp @@ -114,7 +114,7 @@ #include #include "../model_editor/InspectorGadget.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index ce6cdb460..87349756d 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -38,7 +38,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/LoopChooserView.cpp b/src/openstudio_lib/LoopChooserView.cpp index 98040ed62..8acbec072 100644 --- a/src/openstudio_lib/LoopChooserView.cpp +++ b/src/openstudio_lib/LoopChooserView.cpp @@ -14,7 +14,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/LoopScene.hpp b/src/openstudio_lib/LoopScene.hpp index 020608be3..8f0e8dceb 100644 --- a/src/openstudio_lib/LoopScene.hpp +++ b/src/openstudio_lib/LoopScene.hpp @@ -12,7 +12,7 @@ #include #include "OSItem.hpp" #include "GridScene.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" namespace openstudio { diff --git a/src/openstudio_lib/MainRightColumnController.hpp b/src/openstudio_lib/MainRightColumnController.hpp index 5f49abd0f..1cb9ee2dc 100644 --- a/src/openstudio_lib/MainRightColumnController.hpp +++ b/src/openstudio_lib/MainRightColumnController.hpp @@ -14,6 +14,8 @@ #include +#include "OSItem.hpp" + class QStackedWidget; namespace openstudio { @@ -23,7 +25,6 @@ class HorizontalTabWidget; class InspectorController; class LocalLibraryController; class SystemItem; -class OSItem; class MainRightColumnController : public OSQObjectController { diff --git a/src/openstudio_lib/MainWindow.cpp b/src/openstudio_lib/MainWindow.cpp index b221c9240..f49cbb06f 100644 --- a/src/openstudio_lib/MainWindow.cpp +++ b/src/openstudio_lib/MainWindow.cpp @@ -14,7 +14,7 @@ #include "VerticalTabWidget.hpp" #include "../shared_gui_components/NetworkProxyDialog.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/ModelObjectInspectorView.cpp b/src/openstudio_lib/ModelObjectInspectorView.cpp index bb943446e..9825cc294 100644 --- a/src/openstudio_lib/ModelObjectInspectorView.cpp +++ b/src/openstudio_lib/ModelObjectInspectorView.cpp @@ -6,7 +6,7 @@ #include "ModelObjectInspectorView.hpp" #include "ModelObjectItem.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ModelObjectItem.cpp b/src/openstudio_lib/ModelObjectItem.cpp index a95d3047d..0cfdec76c 100644 --- a/src/openstudio_lib/ModelObjectItem.cpp +++ b/src/openstudio_lib/ModelObjectItem.cpp @@ -14,7 +14,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/ModelObjectListView.cpp b/src/openstudio_lib/ModelObjectListView.cpp index b2f66843b..2652892d2 100644 --- a/src/openstudio_lib/ModelObjectListView.cpp +++ b/src/openstudio_lib/ModelObjectListView.cpp @@ -18,7 +18,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ModelObjectListView.hpp b/src/openstudio_lib/ModelObjectListView.hpp index ed53b3f27..633753d05 100644 --- a/src/openstudio_lib/ModelObjectListView.hpp +++ b/src/openstudio_lib/ModelObjectListView.hpp @@ -7,11 +7,11 @@ #define OPENSTUDIO_MODELOBJECTLISTVIEW_HPP #include "OSItemList.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include #include -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" class QMutex; diff --git a/src/openstudio_lib/ModelObjectTreeItems.cpp b/src/openstudio_lib/ModelObjectTreeItems.cpp index c7012a2ff..cdf0e96f4 100644 --- a/src/openstudio_lib/ModelObjectTreeItems.cpp +++ b/src/openstudio_lib/ModelObjectTreeItems.cpp @@ -5,7 +5,7 @@ #include "ModelObjectTreeItems.hpp" #include "ModelObjectItem.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include #include @@ -63,7 +63,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ModelObjectTreeWidget.hpp b/src/openstudio_lib/ModelObjectTreeWidget.hpp index c343869d3..d853705ea 100644 --- a/src/openstudio_lib/ModelObjectTreeWidget.hpp +++ b/src/openstudio_lib/ModelObjectTreeWidget.hpp @@ -10,7 +10,7 @@ #include // Signal-Slot replacement #include -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" class QTreeWidget; diff --git a/src/openstudio_lib/ModelObjectVectorController.hpp b/src/openstudio_lib/ModelObjectVectorController.hpp index 301d38276..5fa61200a 100644 --- a/src/openstudio_lib/ModelObjectVectorController.hpp +++ b/src/openstudio_lib/ModelObjectVectorController.hpp @@ -6,10 +6,10 @@ #ifndef OPENSTUDIO_MODELOBJECTVECTORCONTROLLER_HPP #define OPENSTUDIO_MODELOBJECTVECTORCONTROLLER_HPP -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include #include -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include namespace openstudio { diff --git a/src/openstudio_lib/OSAppBase.cpp b/src/openstudio_lib/OSAppBase.cpp index ad13758b5..c349382db 100644 --- a/src/openstudio_lib/OSAppBase.cpp +++ b/src/openstudio_lib/OSAppBase.cpp @@ -6,10 +6,12 @@ #include "OSAppBase.hpp" #include "ApplyMeasureNowDialog.hpp" +#include "InspectorController.hpp" +#include "InspectorView.hpp" #include "MainRightColumnController.hpp" #include "MainWindow.hpp" #include "OSDocument.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/EditController.hpp" #include "../shared_gui_components/MeasureManager.hpp" @@ -17,7 +19,7 @@ #include "../shared_gui_components/LocalLibraryController.hpp" #include "../shared_gui_components/WaitDialog.hpp" -#include "../model_editor/UserSettings.hpp" +#include "../shared_gui_components/UserSettings.hpp" #include #include @@ -132,6 +134,14 @@ boost::optional OSAppBase::currentModel() { } } +bool OSAppBase::mouseOverInspectorView() { + std::shared_ptr document = currentDocument(); + if (document) { + return document->mainRightColumnController()->inspectorController()->inspectorView()->mouseOverInspectorView(); + } + return false; +} + //boost::optional OSAppBase::currentWorkspace() //{ // std::shared_ptr document = currentDocument(); diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index ab7bbb0c7..1d111f21c 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/BaseApp.hpp" #include -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include "OpenStudioAPI.hpp" #include @@ -59,6 +59,8 @@ class OPENSTUDIO_API OSAppBase boost::shared_ptr waitDialog() { return m_waitDialog; } + virtual bool mouseOverInspectorView() override; + virtual openstudio::path dviewPath() const; virtual bool notify(QObject* receiver, QEvent* e) override; diff --git a/src/openstudio_lib/OSDocument.cpp b/src/openstudio_lib/OSDocument.cpp index c8bd04539..79001b096 100644 --- a/src/openstudio_lib/OSDocument.cpp +++ b/src/openstudio_lib/OSDocument.cpp @@ -46,8 +46,8 @@ #include "../shared_gui_components/MeasureManager.hpp" #include "../shared_gui_components/WaitDialog.hpp" -#include "../model_editor/UserSettings.hpp" -#include "../model_editor/Utilities.hpp" +#include "../shared_gui_components/UserSettings.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" //#include "../analysis/Analysis.hpp" @@ -82,7 +82,7 @@ //#include "../runmanager/lib/WorkItem.hpp" -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index b90673135..435914145 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -9,7 +9,7 @@ #include "OpenStudioAPI.hpp" #include "../shared_gui_components/OSQObjectController.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/OSDropZone.cpp b/src/openstudio_lib/OSDropZone.cpp index ebef87824..cdf429d31 100644 --- a/src/openstudio_lib/OSDropZone.cpp +++ b/src/openstudio_lib/OSDropZone.cpp @@ -5,7 +5,7 @@ #include "OSDropZone.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include "InspectorController.hpp" #include "InspectorView.hpp" #include "MainRightColumnController.hpp" @@ -13,7 +13,7 @@ #include "OSAppBase.hpp" #include "OSDocument.hpp" #include "OSItem.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include #include diff --git a/src/openstudio_lib/OSItem.cpp b/src/openstudio_lib/OSItem.cpp index c0b5fa2e7..dcc8975a4 100644 --- a/src/openstudio_lib/OSItem.cpp +++ b/src/openstudio_lib/OSItem.cpp @@ -6,7 +6,7 @@ #include "OSItem.hpp" #include "BCLComponentItem.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include "ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" @@ -18,7 +18,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/OSItem.hpp b/src/openstudio_lib/OSItem.hpp index 1934e77bc..024087608 100644 --- a/src/openstudio_lib/OSItem.hpp +++ b/src/openstudio_lib/OSItem.hpp @@ -7,6 +7,7 @@ #define OPENSTUDIO_OSITEM_HPP #include "../shared_gui_components/LocalLibrary.hpp" +#include "../shared_gui_components/OSItemId.hpp" #include #include @@ -17,41 +18,12 @@ class QDragEnterEvent; class QDropEvent; class QLabel; -class QMimeData; class QPushButton; namespace openstudio { class MeasureBadge; -class OSItemId -{ - public: - static const QString BCL_SOURCE_ID; - OSItemId(); - OSItemId(const QString& itemId, const QString& sourceId, bool isDefaulted, const QString& otherData = ""); - explicit OSItemId(const QMimeData* mimeData); - QString itemId() const; - QString sourceId() const; - QString otherData() const; - QString mimeDataText() const; - - bool isDefaulted() const; - void setIsDefaulted(bool isDefaulted); - - boost::optional position() const; - void setPosition(int position); - - bool operator==(const OSItemId& other) const; - - private: - QString m_itemId; - QString m_sourceId; - QString m_otherData; - bool m_isDefaulted; - boost::optional m_position_; -}; - class OSItem : public QWidget , public Nano::Observer diff --git a/src/openstudio_lib/OSItemList.cpp b/src/openstudio_lib/OSItemList.cpp index 9d9045154..4767acac7 100644 --- a/src/openstudio_lib/OSItemList.cpp +++ b/src/openstudio_lib/OSItemList.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "OSItemList.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include diff --git a/src/openstudio_lib/OSItemSelectorButtons.cpp b/src/openstudio_lib/OSItemSelectorButtons.cpp index b4b4bd317..6f094d5d1 100644 --- a/src/openstudio_lib/OSItemSelectorButtons.cpp +++ b/src/openstudio_lib/OSItemSelectorButtons.cpp @@ -6,7 +6,7 @@ #include "OSItemSelectorButtons.hpp" #include "OSDropZone.hpp" #include "OSItem.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include diff --git a/src/openstudio_lib/RefrigerationController.cpp b/src/openstudio_lib/RefrigerationController.cpp index f3fc10e18..48d3c11eb 100644 --- a/src/openstudio_lib/RefrigerationController.cpp +++ b/src/openstudio_lib/RefrigerationController.cpp @@ -10,7 +10,7 @@ #include "OSItem.hpp" #include "MainWindow.hpp" #include "MainRightColumnController.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include #include #include @@ -34,7 +34,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/RefrigerationController.hpp b/src/openstudio_lib/RefrigerationController.hpp index c52e63c7f..1cdb290de 100644 --- a/src/openstudio_lib/RefrigerationController.hpp +++ b/src/openstudio_lib/RefrigerationController.hpp @@ -9,7 +9,7 @@ #include #include #include "../shared_gui_components/OSListController.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include class QGraphicsScene; diff --git a/src/openstudio_lib/ResultsTabView.cpp b/src/openstudio_lib/ResultsTabView.cpp index c63d51afd..46d048245 100644 --- a/src/openstudio_lib/ResultsTabView.cpp +++ b/src/openstudio_lib/ResultsTabView.cpp @@ -6,7 +6,7 @@ #include "ResultsTabView.hpp" #include "OSDocument.hpp" #include "OSAppBase.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ResultsTabView.hpp b/src/openstudio_lib/ResultsTabView.hpp index 0fc5e8365..42ed0dc55 100644 --- a/src/openstudio_lib/ResultsTabView.hpp +++ b/src/openstudio_lib/ResultsTabView.hpp @@ -9,7 +9,7 @@ #include "MainTabView.hpp" #include "OSWebEnginePage.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/RunTabView.cpp b/src/openstudio_lib/RunTabView.cpp index 584268add..eecbd3d69 100644 --- a/src/openstudio_lib/RunTabView.cpp +++ b/src/openstudio_lib/RunTabView.cpp @@ -40,8 +40,8 @@ #include -#include "../model_editor/Application.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "MainWindow.hpp" #include diff --git a/src/openstudio_lib/ScheduleCompactInspectorView.cpp b/src/openstudio_lib/ScheduleCompactInspectorView.cpp index a5c2baf8e..e6dbc65aa 100644 --- a/src/openstudio_lib/ScheduleCompactInspectorView.cpp +++ b/src/openstudio_lib/ScheduleCompactInspectorView.cpp @@ -7,7 +7,7 @@ #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ScheduleDayView.cpp b/src/openstudio_lib/ScheduleDayView.cpp index 94702e9bc..593cde17b 100644 --- a/src/openstudio_lib/ScheduleDayView.cpp +++ b/src/openstudio_lib/ScheduleDayView.cpp @@ -5,7 +5,7 @@ #include "ScheduleDayView.hpp" #include "SchedulesView.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "OSItem.hpp" diff --git a/src/openstudio_lib/ScheduleDialog.cpp b/src/openstudio_lib/ScheduleDialog.cpp index 4f1faa273..eb1073984 100644 --- a/src/openstudio_lib/ScheduleDialog.cpp +++ b/src/openstudio_lib/ScheduleDialog.cpp @@ -11,7 +11,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/ScheduleFileInspectorView.cpp b/src/openstudio_lib/ScheduleFileInspectorView.cpp index 746d5d236..bd7cbcd1e 100644 --- a/src/openstudio_lib/ScheduleFileInspectorView.cpp +++ b/src/openstudio_lib/ScheduleFileInspectorView.cpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSIntegerEdit.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSSwitch.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/SchedulesView.cpp b/src/openstudio_lib/SchedulesView.cpp index 13c4ff4b2..1a3b81b53 100644 --- a/src/openstudio_lib/SchedulesView.cpp +++ b/src/openstudio_lib/SchedulesView.cpp @@ -22,7 +22,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/SchedulesView.hpp b/src/openstudio_lib/SchedulesView.hpp index 91d0e511f..c44c2effb 100644 --- a/src/openstudio_lib/SchedulesView.hpp +++ b/src/openstudio_lib/SchedulesView.hpp @@ -6,7 +6,7 @@ #ifndef OPENSTUDIO_SCHEDULESVIEW_HPP #define OPENSTUDIO_SCHEDULESVIEW_HPP -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/ScriptItem.cpp b/src/openstudio_lib/ScriptItem.cpp index 960a23189..34b515e6e 100644 --- a/src/openstudio_lib/ScriptItem.cpp +++ b/src/openstudio_lib/ScriptItem.cpp @@ -6,7 +6,7 @@ #include "ScriptItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" //#include "../runmanager/lib/RunManager.hpp" //#include "../runmanager/lib/RubyJobUtils.hpp" diff --git a/src/openstudio_lib/ServiceWaterGridItems.cpp b/src/openstudio_lib/ServiceWaterGridItems.cpp index 9c3dd3c70..4a6259cb2 100644 --- a/src/openstudio_lib/ServiceWaterGridItems.cpp +++ b/src/openstudio_lib/ServiceWaterGridItems.cpp @@ -5,7 +5,7 @@ #include "ServiceWaterGridItems.hpp" #include "ServiceWaterScene.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include #include #include diff --git a/src/openstudio_lib/ServiceWaterScene.hpp b/src/openstudio_lib/ServiceWaterScene.hpp index b4e6c218e..25e55f445 100644 --- a/src/openstudio_lib/ServiceWaterScene.hpp +++ b/src/openstudio_lib/ServiceWaterScene.hpp @@ -8,7 +8,7 @@ #include "GridScene.hpp" #include "OSItem.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/SpaceLoadInstancesWidget.cpp b/src/openstudio_lib/SpaceLoadInstancesWidget.cpp index a0cf1fcc8..26635f099 100644 --- a/src/openstudio_lib/SpaceLoadInstancesWidget.cpp +++ b/src/openstudio_lib/SpaceLoadInstancesWidget.cpp @@ -7,10 +7,10 @@ #include "OSAppBase.hpp" -#include "IconLibrary.hpp" +#include "../shared_gui_components/IconLibrary.hpp" #include "ModelObjectItem.hpp" #include "OSDropZone.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" #include "../shared_gui_components/OSIntegerEdit.hpp" diff --git a/src/openstudio_lib/SpaceTypesGridView.cpp b/src/openstudio_lib/SpaceTypesGridView.cpp index 57c387d22..916d5cf97 100644 --- a/src/openstudio_lib/SpaceTypesGridView.cpp +++ b/src/openstudio_lib/SpaceTypesGridView.cpp @@ -81,7 +81,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/SpacesSubtabGridView.cpp b/src/openstudio_lib/SpacesSubtabGridView.cpp index 3b9119436..c372e07cf 100644 --- a/src/openstudio_lib/SpacesSubtabGridView.cpp +++ b/src/openstudio_lib/SpacesSubtabGridView.cpp @@ -52,7 +52,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/StandardOpaqueMaterialInspectorView.cpp b/src/openstudio_lib/StandardOpaqueMaterialInspectorView.cpp index d8a2674a7..fd0d91ff0 100644 --- a/src/openstudio_lib/StandardOpaqueMaterialInspectorView.cpp +++ b/src/openstudio_lib/StandardOpaqueMaterialInspectorView.cpp @@ -7,7 +7,7 @@ #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/StandardsInformationConstructionWidget.cpp b/src/openstudio_lib/StandardsInformationConstructionWidget.cpp index cb9ee4448..bfbd39bbb 100644 --- a/src/openstudio_lib/StandardsInformationConstructionWidget.cpp +++ b/src/openstudio_lib/StandardsInformationConstructionWidget.cpp @@ -7,7 +7,7 @@ #include "OSItem.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSLineEdit.hpp" diff --git a/src/openstudio_lib/StandardsInformationMaterialWidget.cpp b/src/openstudio_lib/StandardsInformationMaterialWidget.cpp index 32a42062d..2d6b4b4c4 100644 --- a/src/openstudio_lib/StandardsInformationMaterialWidget.cpp +++ b/src/openstudio_lib/StandardsInformationMaterialWidget.cpp @@ -13,7 +13,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/SwimmingPoolIndoorFloorSurfaceDialog.cpp b/src/openstudio_lib/SwimmingPoolIndoorFloorSurfaceDialog.cpp index 0296323fc..a049125bf 100644 --- a/src/openstudio_lib/SwimmingPoolIndoorFloorSurfaceDialog.cpp +++ b/src/openstudio_lib/SwimmingPoolIndoorFloorSurfaceDialog.cpp @@ -5,7 +5,7 @@ #include "SwimmingPoolIndoorFloorSurfaceDialog.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/UtilityBillFuelTypeListView.cpp b/src/openstudio_lib/UtilityBillFuelTypeListView.cpp index a861de532..615db288b 100644 --- a/src/openstudio_lib/UtilityBillFuelTypeListView.cpp +++ b/src/openstudio_lib/UtilityBillFuelTypeListView.cpp @@ -14,7 +14,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/UtilityBillFuelTypeListView.hpp b/src/openstudio_lib/UtilityBillFuelTypeListView.hpp index cd5e4396c..3333954f0 100644 --- a/src/openstudio_lib/UtilityBillFuelTypeListView.hpp +++ b/src/openstudio_lib/UtilityBillFuelTypeListView.hpp @@ -7,9 +7,9 @@ #define OPENSTUDIO_UTILITYBILLFUELTYPELISTVIEW_HPP #include "OSItemList.hpp" -#include "OSVectorController.hpp" +#include "../shared_gui_components/OSVectorController.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/VRFController.cpp b/src/openstudio_lib/VRFController.cpp index 8f3c95d2f..46e272e40 100644 --- a/src/openstudio_lib/VRFController.cpp +++ b/src/openstudio_lib/VRFController.cpp @@ -24,7 +24,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/VariablesTabView.cpp b/src/openstudio_lib/VariablesTabView.cpp index d28e2b730..68c912349 100644 --- a/src/openstudio_lib/VariablesTabView.cpp +++ b/src/openstudio_lib/VariablesTabView.cpp @@ -10,7 +10,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/OSDialog.hpp" #include "../shared_gui_components/ProgressBarWithError.hpp" diff --git a/src/openstudio_lib/VariablesTabView.hpp b/src/openstudio_lib/VariablesTabView.hpp index 7192eb111..2fcfc488e 100644 --- a/src/openstudio_lib/VariablesTabView.hpp +++ b/src/openstudio_lib/VariablesTabView.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_VARIABLESTABVIEW_HPP #include "MainTabView.hpp" -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include #include // Signal-Slot replacement diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index fe838aa47..a78df6f8d 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -16,7 +16,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/YearSettingsWidget.hpp b/src/openstudio_lib/YearSettingsWidget.hpp index bd86d0ab9..ccf7a9317 100644 --- a/src/openstudio_lib/YearSettingsWidget.hpp +++ b/src/openstudio_lib/YearSettingsWidget.hpp @@ -6,7 +6,7 @@ #ifndef OPENSTUDIO_YEARSETTINGSWIDGET_HPP #define OPENSTUDIO_YEARSETTINGSWIDGET_HPP -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include #include diff --git a/src/openstudio_lib/ZoneChooserView.cpp b/src/openstudio_lib/ZoneChooserView.cpp index 9d1935d93..1d768f7c8 100644 --- a/src/openstudio_lib/ZoneChooserView.cpp +++ b/src/openstudio_lib/ZoneChooserView.cpp @@ -13,7 +13,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/test/IconLibrary_GTest.cpp b/src/openstudio_lib/test/IconLibrary_GTest.cpp index 6ab0e5592..f4b9503a6 100644 --- a/src/openstudio_lib/test/IconLibrary_GTest.cpp +++ b/src/openstudio_lib/test/IconLibrary_GTest.cpp @@ -7,7 +7,7 @@ #include "OpenStudioLibFixture.hpp" -#include "../IconLibrary.hpp" +#include "../../shared_gui_components/IconLibrary.hpp" #include diff --git a/src/openstudio_lib/test/OpenStudioLibFixture.cpp b/src/openstudio_lib/test/OpenStudioLibFixture.cpp index 62687ea40..9c6a928db 100644 --- a/src/openstudio_lib/test/OpenStudioLibFixture.cpp +++ b/src/openstudio_lib/test/OpenStudioLibFixture.cpp @@ -5,7 +5,7 @@ #include "OpenStudioLibFixture.hpp" -#include "../../model_editor/Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include "../DesignDayGridView.hpp" #include "../GridViewSubTab.hpp" @@ -236,4 +236,4 @@ void OpenStudioLibFixture::checkExpected(OSObjectSelector* os, OSGridView* gv, i var = widget->property("style"); EXPECT_EQ(var.toString().toStdString(), style) << gridRow << ", " << column << ", " << subrow; -} \ No newline at end of file +} diff --git a/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp b/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp index 7471e5a13..c4a4f5f4f 100644 --- a/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp +++ b/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp @@ -5,7 +5,7 @@ #include -#include "../../model_editor/Application.hpp" +#include "../../openstudio_qt_utils/Application.hpp" #include "../SpacesSurfacesGridView.hpp" #include diff --git a/src/model_editor/Application.cpp b/src/openstudio_qt_utils/Application.cpp similarity index 92% rename from src/model_editor/Application.cpp rename to src/openstudio_qt_utils/Application.cpp index c550925e0..af7defc34 100644 --- a/src/model_editor/Application.cpp +++ b/src/openstudio_qt_utils/Application.cpp @@ -5,9 +5,7 @@ #include "Application.hpp" -// TODO: JM 2019-03-28 Do I also need to make a specific version of getOpenStudioModuleDirectory? #include - #include #include "Utilities.hpp" @@ -58,15 +56,6 @@ QCoreApplication* Application::application(bool gui) { openstudioPossibleBinDirPath = openstudioModuleDirPath / openstudio::toPath("../bin/platforms/"); QCoreApplication::addLibraryPath(toQString(openstudioPossibleBinDirPath)); - // Make the ruby path the default plugin search location - //#if defined(Q_OS_DARWIN) - // openstudio::path p = getApplicationRunDirectory().parent_path().parent_path().parent_path() / toPath("Ruby/openstudio"); - // QCoreApplication::addLibraryPath(toQString(p)); - //#elif defined(Q_OS_WIN) - // openstudio::path p = getApplicationRunDirectory().parent_path() / toPath("Ruby/openstudio"); - // QCoreApplication::addLibraryPath(toQString(p)); - //#endif - static char* argv[] = {nullptr}; static int argc = sizeof(argv) / sizeof(char*) - 1; diff --git a/src/model_editor/Application.hpp b/src/openstudio_qt_utils/Application.hpp similarity index 94% rename from src/model_editor/Application.hpp rename to src/openstudio_qt_utils/Application.hpp index f50838c13..be6ebfa6c 100644 --- a/src/model_editor/Application.hpp +++ b/src/openstudio_qt_utils/Application.hpp @@ -3,11 +3,10 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODELEDITOR_APPLICATION_HPP -#define MODELEDITOR_APPLICATION_HPP - -#include "ModelEditorAPI.hpp" +#ifndef OPENSTUDIOQTUTILS_APPLICATION_HPP +#define OPENSTUDIOQTUTILS_APPLICATION_HPP +#include "OpenStudioQtUtilsAPI.hpp" #include "QMetaTypes.hpp" #include @@ -81,4 +80,4 @@ class Application } // namespace openstudio -#endif // MODELEDITOR_APPLICATION_HPP +#endif // OPENSTUDIOQTUTILS_APPLICATION_HPP diff --git a/src/openstudio_qt_utils/CMakeLists.txt b/src/openstudio_qt_utils/CMakeLists.txt new file mode 100644 index 000000000..ebdedf305 --- /dev/null +++ b/src/openstudio_qt_utils/CMakeLists.txt @@ -0,0 +1,35 @@ +set(target_name openstudio_qt_utils) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${QT_INCLUDES}) + +set(${target_name}_src + OpenStudioQtUtilsAPI.hpp + Application.hpp + Application.cpp + OSProgressBar.hpp + OSProgressBar.cpp + QMetaTypes.hpp + QMetaTypes.cpp + Utilities.hpp + Utilities.cpp +) + +add_library(${target_name} ${${target_name}_src}) + +set(${target_name}_depends + openstudioapp_utilities + ${QT_LIBS} +) + +add_dependencies(${target_name} ${${target_name}_depends}) +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) + +if(BUILD_SHARED_LIBS) + #target_compile_definitions(${target_name} PUBLIC openstudio_qt_utils_EXPORTS) +else() + target_compile_definitions(${target_name} PUBLIC openstudio_qt_utils_EXPORTS) +endif() + +CREATE_SRC_GROUPS("${${target_name}_src}") diff --git a/src/model_editor/OSProgressBar.cpp b/src/openstudio_qt_utils/OSProgressBar.cpp similarity index 92% rename from src/model_editor/OSProgressBar.cpp rename to src/openstudio_qt_utils/OSProgressBar.cpp index 59890f0d5..2e0510d27 100644 --- a/src/model_editor/OSProgressBar.cpp +++ b/src/openstudio_qt_utils/OSProgressBar.cpp @@ -41,11 +41,6 @@ OSProgressBar::OSProgressBar(bool visible, QWidget* parent) { updatePercentage(); } -/// constructor from impl -//OSProgressBar::OSProgressBar(const std::shared_ptr& impl) -// : m_impl(impl), m_percentage(0.0) -//{} - /// virtual destructor OSProgressBar::~OSProgressBar() { m_impl->setVisible(false); @@ -123,8 +118,3 @@ void OSProgressBar::setValue(int value) { void OSProgressBar::setWindowTitle(const QString& windowTitle) { m_impl->setWindowTitle(windowTitle); } - -//std::shared_ptr OSProgressBar::impl() const -//{ -// return m_impl; -//} diff --git a/src/model_editor/OSProgressBar.hpp b/src/openstudio_qt_utils/OSProgressBar.hpp similarity index 91% rename from src/model_editor/OSProgressBar.hpp rename to src/openstudio_qt_utils/OSProgressBar.hpp index e62845120..dd184efaf 100644 --- a/src/model_editor/OSProgressBar.hpp +++ b/src/openstudio_qt_utils/OSProgressBar.hpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODELEDITOR_OSProgressBar_HPP -#define MODELEDITOR_OSProgressBar_HPP +#ifndef OPENSTUDIOQTUTILS_OSPROGRESSBAR_HPP +#define OPENSTUDIOQTUTILS_OSPROGRESSBAR_HPP #include #include @@ -79,13 +79,9 @@ class OSProgressBar : public openstudio::ProgressBar /// set window title void setWindowTitle(const QString& windowTitle); - protected: - /// return the impl - //std::shared_ptr impl() const; - private: /// impl std::shared_ptr m_impl; }; -#endif //MODELEDITOR_OSProgressBar_HPP +#endif // OPENSTUDIOQTUTILS_OSPROGRESSBAR_HPP diff --git a/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp b/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp new file mode 100644 index 000000000..6857001c4 --- /dev/null +++ b/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp @@ -0,0 +1,26 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef OPENSTUDIOQTUTILS_API_HPP +#define OPENSTUDIOQTUTILS_API_HPP + +#if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS + +# ifdef openstudio_qt_utils_EXPORTS +# define OPENSTUDIOQTUTILS_API __declspec(dllexport) +# define OPENSTUDIOQTUTILS_TEMPLATE_EXT +# else +# define OPENSTUDIOQTUTILS_API __declspec(dllimport) +# define OPENSTUDIOQTUTILS_TEMPLATE_EXT extern +# endif + +#else + +# define OPENSTUDIOQTUTILS_API +# define OPENSTUDIOQTUTILS_TEMPLATE_EXT + +#endif + +#endif // OPENSTUDIOQTUTILS_API_HPP diff --git a/src/model_editor/QMetaTypes.cpp b/src/openstudio_qt_utils/QMetaTypes.cpp similarity index 69% rename from src/model_editor/QMetaTypes.cpp rename to src/openstudio_qt_utils/QMetaTypes.cpp index 4b0730c99..70e68087b 100644 --- a/src/model_editor/QMetaTypes.cpp +++ b/src/openstudio_qt_utils/QMetaTypes.cpp @@ -14,13 +14,6 @@ namespace detail { int __iddobjectype_type = qRegisterMetaType("openstudio::IddObjectType"); int __iddfiletype_type = qRegisterMetaType("openstudio::IddFileType"); -int __ositemid_type = qRegisterMetaType("OSItemId"); -int __ositemid_vector_type = qRegisterMetaType>("std::vector"); - -// qRegisterMetaType("openstudio::model::ModelObject"); // No default constructor! -// qRegisterMetaType >("boost::optional"); -// qRegisterMetaType >("std::vector" ); - int __uuid_type = qRegisterMetaType("openstudio::UUID"); int __string_type = qRegisterMetaType("std::string"); @@ -31,10 +24,6 @@ int __optional_unsigned_type = qRegisterMetaType>("boo int __optional_int_type = qRegisterMetaType>("boost::optional"); int __optional_string_type = qRegisterMetaType>("boost::optional"); -// qRegisterMetaType("openstudio::Attribute"); -//int __attribute_optional_type__ = qRegisterMetaType>("boost::optional"); -//int __atribute_vector_type = qRegisterMetaType>("std::vector"); - int __quantity_type = qRegisterMetaType("openstudio::Quantity"); int __optionalquantity_type = qRegisterMetaType("openstudio::OSOptionalQuantity"); diff --git a/src/model_editor/QMetaTypes.hpp b/src/openstudio_qt_utils/QMetaTypes.hpp similarity index 64% rename from src/model_editor/QMetaTypes.hpp rename to src/openstudio_qt_utils/QMetaTypes.hpp index 4d28ba27b..21e6e863f 100644 --- a/src/model_editor/QMetaTypes.hpp +++ b/src/openstudio_qt_utils/QMetaTypes.hpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODELEDITOR_QMETATYPES -#define MODELEDITOR_QMETATYPES +#ifndef OPENSTUDIOQTUTILS_QMETATYPES_HPP +#define OPENSTUDIOQTUTILS_QMETATYPES_HPP #include @@ -15,16 +15,6 @@ Q_DECLARE_METATYPE(QModelIndex) Q_DECLARE_METATYPE(openstudio::IddFileType) Q_DECLARE_METATYPE(openstudio::IddObjectType) -#include "../openstudio_lib/OSItem.hpp" -Q_DECLARE_METATYPE(openstudio::OSItemId) -Q_DECLARE_METATYPE(std::vector) - -// #include -// Note JM 2018-12-13: Was already commented out -// Q_DECLARE_METATYPE(openstudio::model::ModelObject); // no default constructor -// Q_DECLARE_METATYPE(boost::optional); -// Q_DECLARE_METATYPE(std::vector); - #include Q_DECLARE_METATYPE(openstudio::UUID); @@ -38,11 +28,6 @@ Q_DECLARE_METATYPE(boost::optional); Q_DECLARE_METATYPE(boost::optional); Q_DECLARE_METATYPE(boost::optional); -#include -//Q_DECLARE_METATYPE(openstudio::Attribute); -//Q_DECLARE_METATYPE(boost::optional); -//Q_DECLARE_METATYPE(std::vector); - #include Q_DECLARE_METATYPE(openstudio::Quantity); @@ -52,4 +37,4 @@ Q_DECLARE_METATYPE(openstudio::OSOptionalQuantity); #include Q_DECLARE_METATYPE(std::shared_ptr) -#endif // MODELEDITOR_QMETATYPES +#endif // OPENSTUDIOQTUTILS_QMETATYPES_HPP diff --git a/src/model_editor/Utilities.cpp b/src/openstudio_qt_utils/Utilities.cpp similarity index 100% rename from src/model_editor/Utilities.cpp rename to src/openstudio_qt_utils/Utilities.cpp diff --git a/src/model_editor/Utilities.hpp b/src/openstudio_qt_utils/Utilities.hpp similarity index 51% rename from src/model_editor/Utilities.hpp rename to src/openstudio_qt_utils/Utilities.hpp index 8a1e29908..2942bd840 100644 --- a/src/model_editor/Utilities.hpp +++ b/src/openstudio_qt_utils/Utilities.hpp @@ -3,39 +3,42 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODELEDITOR_UTILITIES_HPP -#define MODELEDITOR_UTILITIES_HPP +#ifndef OPENSTUDIOQTUTILS_UTILITIES_HPP +#define OPENSTUDIOQTUTILS_UTILITIES_HPP #include #include -#include "ModelEditorAPI.hpp" +#include +#include + +#include "OpenStudioQtUtilsAPI.hpp" namespace openstudio { /** QString to UTF-8 encoded std::string. */ -MODELEDITOR_API std::string toString(const QString& q); +OPENSTUDIOQTUTILS_API std::string toString(const QString& q); /** QString to wstring. */ -MODELEDITOR_API std::wstring toWString(const QString& q); +OPENSTUDIOQTUTILS_API std::wstring toWString(const QString& q); /** UTF-8 encoded std::string to QString. */ -MODELEDITOR_API QString toQString(const std::string& s); +OPENSTUDIOQTUTILS_API QString toQString(const std::string& s); /** wstring to QString. */ -MODELEDITOR_API QString toQString(const std::wstring& w); +OPENSTUDIOQTUTILS_API QString toQString(const std::wstring& w); /// create a UUID from a std::string, does not throw, may return a null UUID -MODELEDITOR_API UUID toUUID(const QString& str); +OPENSTUDIOQTUTILS_API UUID toUUID(const QString& str); /// create a QString from a UUID -MODELEDITOR_API QString toQString(const UUID& uuid); +OPENSTUDIOQTUTILS_API QString toQString(const UUID& uuid); /** path to QString. */ -MODELEDITOR_API QString toQString(const path& p); +OPENSTUDIOQTUTILS_API QString toQString(const path& p); /** QString to path*/ -MODELEDITOR_API path toPath(const QString& q); +OPENSTUDIOQTUTILS_API path toPath(const QString& q); } // namespace openstudio -#endif +#endif // OPENSTUDIOQTUTILS_UTILITIES_HPP diff --git a/src/shared_gui_components/BCLMeasureDialog.cpp b/src/shared_gui_components/BCLMeasureDialog.cpp index 4569cfcbe..36121ea98 100644 --- a/src/shared_gui_components/BCLMeasureDialog.cpp +++ b/src/shared_gui_components/BCLMeasureDialog.cpp @@ -5,8 +5,8 @@ #include "BCLMeasureDialog.hpp" -#include "../model_editor/UserSettings.hpp" -#include "../model_editor/Utilities.hpp" +#include "UserSettings.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" // TODO: delete once the Labs CLI is the default #include "../openstudio_lib/OSAppBase.hpp" diff --git a/src/shared_gui_components/BaseApp.hpp b/src/shared_gui_components/BaseApp.hpp index dfcadf26a..3539cf51b 100644 --- a/src/shared_gui_components/BaseApp.hpp +++ b/src/shared_gui_components/BaseApp.hpp @@ -7,7 +7,7 @@ #define SHAREDGUICOMPONENTS_BASEAPP_HPP #include -#include "../model_editor/QMetaTypes.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include @@ -48,6 +48,8 @@ class BaseApp virtual boost::optional tempDir() = 0; virtual boost::optional currentModel() = 0; //virtual boost::optional currentWorkspace() = 0; + + virtual bool mouseOverInspectorView() = 0; }; } // namespace openstudio diff --git a/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp b/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp index ade6236e9..a54b155a4 100644 --- a/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp +++ b/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp @@ -21,7 +21,7 @@ #include #include -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include "../openstudio_lib/OSAppBase.hpp" #include "../openstudio_lib/OSDocument.hpp" diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt new file mode 100644 index 000000000..7bb0d04bf --- /dev/null +++ b/src/shared_gui_components/CMakeLists.txt @@ -0,0 +1,194 @@ +set(target_name openstudio_shared_gui) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${QT_INCLUDES}) + +set(${target_name}_src + OpenStudioSharedGuiAPI.hpp + BCLMeasureDialog.cpp + BCLMeasureDialog.hpp + BuildingComponentDialog.cpp + BuildingComponentDialog.hpp + BuildingComponentDialogCentralWidget.cpp + BuildingComponentDialogCentralWidget.hpp + BusyWidget.cpp + BusyWidget.hpp + Buttons.cpp + Buttons.hpp + CollapsibleComponent.cpp + CollapsibleComponent.hpp + CollapsibleComponentHeader.cpp + CollapsibleComponentHeader.hpp + CollapsibleComponentList.cpp + CollapsibleComponentList.hpp + ColorPalettes.hpp + Component.cpp + Component.hpp + ComponentList.cpp + ComponentList.hpp + EditController.cpp + EditController.hpp + EditView.cpp + EditView.hpp + FieldMethodTypedefs.hpp + GraphicsItems.cpp + GraphicsItems.hpp + HeaderViews.cpp + HeaderViews.hpp + IconLibrary.cpp + IconLibrary.hpp + LocalLibrary.hpp + LocalLibraryController.cpp + LocalLibraryController.hpp + LocalLibraryView.cpp + LocalLibraryView.hpp + MeasureBadge.cpp + MeasureBadge.hpp + MeasureDragData.cpp + MeasureDragData.hpp + MeasureManager.cpp + MeasureManager.hpp + NetworkProxyDialog.cpp + NetworkProxyDialog.hpp + OSCellWrapper.cpp + OSCellWrapper.hpp + OSCheckBox.cpp + OSCheckBox.hpp + OSCollapsibleView.cpp + OSCollapsibleView.hpp + OSComboBox.cpp + OSComboBox.hpp + OSConcepts.hpp + OSDialog.cpp + OSDialog.hpp + OSDoubleEdit.cpp + OSDoubleEdit.hpp + OSDragableView.cpp + OSDragableView.hpp + OSGridController.cpp + OSGridController.hpp + OSGridView.cpp + OSGridView.hpp + OSIntegerEdit.cpp + OSIntegerEdit.hpp + OSLineEdit.cpp + OSLineEdit.hpp + OSListController.cpp + OSListController.hpp + OSListView.cpp + OSListView.hpp + OSLoadNamePixmapLineEdit.cpp + OSLoadNamePixmapLineEdit.hpp + OSObjectSelector.cpp + OSObjectSelector.hpp + OSQObjectController.cpp + OSQObjectController.hpp + OSQuantityEdit.cpp + OSQuantityEdit.hpp + OSVectorController.cpp + OSVectorController.hpp + OSSwitch.cpp + OSSwitch.hpp + OSUnsignedEdit.cpp + OSUnsignedEdit.hpp + OSViewSwitcher.cpp + OSViewSwitcher.hpp + OSWidgetHolder.cpp + OSWidgetHolder.hpp + PageNavigator.cpp + PageNavigator.hpp + ProcessEventsProgressBar.cpp + ProcessEventsProgressBar.hpp + ProgressBarWithError.cpp + ProgressBarWithError.hpp + SyncMeasuresDialog.cpp + SyncMeasuresDialog.hpp + SyncMeasuresDialogCentralWidget.cpp + SyncMeasuresDialogCentralWidget.hpp + TextEditDialog.cpp + TextEditDialog.hpp + TIDItemModel.cpp + TIDItemModel.hpp + UserSettings.cpp + UserSettings.hpp + WaitDialog.cpp + WaitDialog.hpp + WorkflowController.cpp + WorkflowController.hpp + WorkflowTools.cpp + WorkflowTools.hpp + WorkflowView.cpp + WorkflowView.hpp +) + +set(${target_name}_moc + BCLMeasureDialog.hpp + BuildingComponentDialog.hpp + BuildingComponentDialogCentralWidget.hpp + BusyWidget.hpp + Buttons.hpp + CollapsibleComponent.hpp + CollapsibleComponentHeader.hpp + CollapsibleComponentList.hpp + Component.hpp + ComponentList.hpp + EditController.hpp + EditView.hpp + GraphicsItems.hpp + HeaderViews.hpp + LocalLibraryController.hpp + LocalLibraryView.hpp + MeasureBadge.hpp + MeasureDragData.hpp + MeasureManager.hpp + NetworkProxyDialog.hpp + OSCellWrapper.hpp + OSCheckBox.hpp + OSCollapsibleView.hpp + OSComboBox.hpp + OSDialog.hpp + OSDoubleEdit.hpp + OSDragableView.hpp + OSGridController.hpp + OSGridView.hpp + OSIntegerEdit.hpp + OSLineEdit.hpp + OSListController.hpp + OSListView.hpp + OSLoadNamePixmapLineEdit.hpp + OSObjectSelector.hpp + OSQObjectController.hpp + OSQuantityEdit.hpp + OSVectorController.hpp + OSSwitch.hpp + OSUnsignedEdit.hpp + OSViewSwitcher.hpp + OSWidgetHolder.hpp + PageNavigator.hpp + ProgressBarWithError.hpp + SyncMeasuresDialog.hpp + SyncMeasuresDialogCentralWidget.hpp + TextEditDialog.hpp + TIDItemModel.hpp + WaitDialog.hpp + WorkflowController.hpp + WorkflowView.hpp +) + +## Qt MOC generation +qt6_wrap_cpp(${target_name}_moc_src ${${target_name}_moc}) + +set(${target_name}_depends + openstudio_qt_utils +) + +add_library(${target_name} ${${target_name}_src} ${${target_name}_moc_src}) + +if (NINJA) + target_compile_definitions(${target_name} PRIVATE NINJA=1) +endif() + +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) + +CREATE_SRC_GROUPS("${${target_name}_src}") diff --git a/src/shared_gui_components/Component.cpp b/src/shared_gui_components/Component.cpp index c5283782c..550366d18 100644 --- a/src/shared_gui_components/Component.cpp +++ b/src/shared_gui_components/Component.cpp @@ -5,7 +5,7 @@ #include "Component.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../openstudio_lib/OSAppBase.hpp" #include "../openstudio_lib/OSDocument.hpp" diff --git a/src/shared_gui_components/EditController.cpp b/src/shared_gui_components/EditController.cpp index b889432d7..d7707b191 100644 --- a/src/shared_gui_components/EditController.cpp +++ b/src/shared_gui_components/EditController.cpp @@ -7,7 +7,7 @@ #include "EditView.hpp" #include "OSViewSwitcher.hpp" #include "WorkflowController.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/shared_gui_components/EditView.cpp b/src/shared_gui_components/EditView.cpp index 9778d9e9c..8bb37660e 100644 --- a/src/shared_gui_components/EditView.cpp +++ b/src/shared_gui_components/EditView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "EditView.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/IconLibrary.cpp b/src/shared_gui_components/IconLibrary.cpp similarity index 100% rename from src/openstudio_lib/IconLibrary.cpp rename to src/shared_gui_components/IconLibrary.cpp diff --git a/src/openstudio_lib/IconLibrary.hpp b/src/shared_gui_components/IconLibrary.hpp similarity index 89% rename from src/openstudio_lib/IconLibrary.hpp rename to src/shared_gui_components/IconLibrary.hpp index fb62af16d..7d5413f05 100644 --- a/src/openstudio_lib/IconLibrary.hpp +++ b/src/shared_gui_components/IconLibrary.hpp @@ -3,10 +3,10 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef OPENSTUDIO_ICONLIBRARY_HPP -#define OPENSTUDIO_ICONLIBRARY_HPP +#ifndef SHAREDGUICOMPONENTS_ICONLIBRARY_HPP +#define SHAREDGUICOMPONENTS_ICONLIBRARY_HPP -#include "OpenStudioAPI.hpp" +#include "OpenStudioSharedGuiAPI.hpp" #include #include @@ -22,7 +22,7 @@ namespace openstudio { * it, because it might return NULL. * */ -class OPENSTUDIO_API IconLibrary +class OPENSTUDIO_SHARED_GUI_API IconLibrary { public: @@ -55,4 +55,4 @@ class OPENSTUDIO_API IconLibrary } // namespace openstudio -#endif // OPENSTUDIO_ICONLIBRARY_HPP +#endif // SHAREDGUICOMPONENTS_ICONLIBRARY_HPP diff --git a/src/shared_gui_components/LocalLibraryController.cpp b/src/shared_gui_components/LocalLibraryController.cpp index 0d9c247eb..dc67715ac 100644 --- a/src/shared_gui_components/LocalLibraryController.cpp +++ b/src/shared_gui_components/LocalLibraryController.cpp @@ -20,8 +20,8 @@ #include "MeasureBadge.hpp" -#include "../model_editor/UserSettings.hpp" -#include "../model_editor/Utilities.hpp" +#include "UserSettings.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/shared_gui_components/MeasureDragData.cpp b/src/shared_gui_components/MeasureDragData.cpp index 5127ccd0b..85dd08a6f 100644 --- a/src/shared_gui_components/MeasureDragData.cpp +++ b/src/shared_gui_components/MeasureDragData.cpp @@ -8,7 +8,7 @@ #include #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" namespace openstudio { diff --git a/src/shared_gui_components/MeasureManager.cpp b/src/shared_gui_components/MeasureManager.cpp index 3e01f67dc..82055a7d5 100644 --- a/src/shared_gui_components/MeasureManager.cpp +++ b/src/shared_gui_components/MeasureManager.cpp @@ -13,9 +13,9 @@ #include "BuildingComponentDialog.hpp" #include "OSDialog.hpp" -#include "../model_editor/Application.hpp" -#include "../model_editor/UserSettings.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "UserSettings.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/shared_gui_components/MeasureManager.hpp b/src/shared_gui_components/MeasureManager.hpp index af019005d..291eb85d8 100644 --- a/src/shared_gui_components/MeasureManager.hpp +++ b/src/shared_gui_components/MeasureManager.hpp @@ -63,8 +63,8 @@ class LocalLibraryController; * **/ #if defined(openstudio_lib_EXPORTS) || defined(COMPILING_FROM_OSAPP) -# include "../openstudio_lib/OpenStudioAPI.hpp" -class OPENSTUDIO_API MeasureManager : public QObject +# include "OpenStudioSharedGuiAPI.hpp" +class OPENSTUDIO_SHARED_GUI_API MeasureManager : public QObject #else class MeasureManager : public QObject #endif diff --git a/src/shared_gui_components/NetworkProxyDialog.cpp b/src/shared_gui_components/NetworkProxyDialog.cpp index 716ab5f00..2fe4df651 100644 --- a/src/shared_gui_components/NetworkProxyDialog.cpp +++ b/src/shared_gui_components/NetworkProxyDialog.cpp @@ -5,8 +5,8 @@ #include "NetworkProxyDialog.hpp" -#include "../model_editor/Application.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Application.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/shared_gui_components/OSDoubleEdit.cpp b/src/shared_gui_components/OSDoubleEdit.cpp index 62376b9e7..cae59ed62 100644 --- a/src/shared_gui_components/OSDoubleEdit.cpp +++ b/src/shared_gui_components/OSDoubleEdit.cpp @@ -7,7 +7,7 @@ #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index 8638f9078..65e03d758 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -5,6 +5,13 @@ #include "OSGridController.hpp" +// Register OSItemId metatypes for queued signal/slot connections. +// Q_DECLARE_METATYPE is in OSGridController.hpp; qRegisterMetaType must run at startup. +namespace { + const int __ositemid_type = qRegisterMetaType("OSItemId"); + const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); +} + #include "OSCellWrapper.hpp" #include "OSGridView.hpp" #include "OSObjectSelector.hpp" diff --git a/src/shared_gui_components/OSGridController.hpp b/src/shared_gui_components/OSGridController.hpp index a90a6b07f..9bb1f80d0 100644 --- a/src/shared_gui_components/OSGridController.hpp +++ b/src/shared_gui_components/OSGridController.hpp @@ -8,9 +8,11 @@ #include "OSConcepts.hpp" #include "OSObjectSelector.hpp" -#include "../model_editor/QMetaTypes.hpp" -#include "../openstudio_lib/OSItem.hpp" -#include "../openstudio_lib/OSVectorController.hpp" +#include "OSItemId.hpp" +#include "OSVectorController.hpp" +#include "../openstudio_qt_utils/QMetaTypes.hpp" +Q_DECLARE_METATYPE(openstudio::OSItemId) +Q_DECLARE_METATYPE(std::vector) #include #include @@ -31,6 +33,7 @@ class QButtonGroup; class QColor; class QLabel; class OpenStudioLibFixture; +class OSItem; namespace openstudio { diff --git a/src/shared_gui_components/OSGridView.cpp b/src/shared_gui_components/OSGridView.cpp index 39a4682f5..2545d3cf0 100644 --- a/src/shared_gui_components/OSGridView.cpp +++ b/src/shared_gui_components/OSGridView.cpp @@ -21,7 +21,7 @@ #include "OSUnsignedEdit.hpp" #include "OSWidgetHolder.hpp" -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" #include "../openstudio_lib/ModelObjectInspectorView.hpp" #include "../openstudio_lib/OSDropZone.hpp" diff --git a/src/shared_gui_components/OSGridView.hpp b/src/shared_gui_components/OSGridView.hpp index 1413bc79f..a1083e78b 100644 --- a/src/shared_gui_components/OSGridView.hpp +++ b/src/shared_gui_components/OSGridView.hpp @@ -9,7 +9,7 @@ #include #include -#include "../openstudio_lib/OSItem.hpp" +#include "OSItemId.hpp" #include diff --git a/src/shared_gui_components/OSIntegerEdit.cpp b/src/shared_gui_components/OSIntegerEdit.cpp index ad4056118..28904d7b8 100644 --- a/src/shared_gui_components/OSIntegerEdit.cpp +++ b/src/shared_gui_components/OSIntegerEdit.cpp @@ -7,7 +7,7 @@ #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/shared_gui_components/OSItemId.hpp b/src/shared_gui_components/OSItemId.hpp new file mode 100644 index 000000000..c15e26178 --- /dev/null +++ b/src/shared_gui_components/OSItemId.hpp @@ -0,0 +1,46 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef SHAREDGUICOMPONENTS_OSITEMID_HPP +#define SHAREDGUICOMPONENTS_OSITEMID_HPP + +#include +#include + +class QMimeData; + +namespace openstudio { + +class OSItemId +{ + public: + static const QString BCL_SOURCE_ID; + OSItemId(); + OSItemId(const QString& itemId, const QString& sourceId, bool isDefaulted, const QString& otherData = ""); + explicit OSItemId(const QMimeData* mimeData); + QString itemId() const; + QString sourceId() const; + QString otherData() const; + QString mimeDataText() const; + + bool isDefaulted() const; + void setIsDefaulted(bool isDefaulted); + + boost::optional position() const; + void setPosition(int position); + + bool operator==(const OSItemId& other) const; + + private: + QString m_itemId; + QString m_sourceId; + QString m_otherData; + bool m_isDefaulted; + boost::optional m_position_; +}; + +} // namespace openstudio + +#endif // SHAREDGUICOMPONENTS_OSITEMID_HPP diff --git a/src/shared_gui_components/OSLineEdit.cpp b/src/shared_gui_components/OSLineEdit.cpp index 935b59c1b..d8033eb86 100644 --- a/src/shared_gui_components/OSLineEdit.cpp +++ b/src/shared_gui_components/OSLineEdit.cpp @@ -5,14 +5,11 @@ #include "OSLineEdit.hpp" -#include "../openstudio_lib/InspectorController.hpp" -#include "../openstudio_lib/InspectorView.hpp" -#include "../openstudio_lib/MainRightColumnController.hpp" #include "../openstudio_lib/ModelObjectItem.hpp" #include "../openstudio_lib/OSAppBase.hpp" #include "../openstudio_lib/OSDocument.hpp" #include "../openstudio_lib/OSItem.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include @@ -351,8 +348,7 @@ void OSLineEdit2::focusOutEvent(QFocusEvent* e) { emit inFocus(m_focused, false); - auto mouseOverInspectorView = - OSAppBase::instance()->currentDocument()->mainRightColumnController()->inspectorController()->inspectorView()->mouseOverInspectorView(); + auto mouseOverInspectorView = OSAppBase::instance()->mouseOverInspectorView(); if (!mouseOverInspectorView) { emit itemClicked(nullptr); } diff --git a/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp b/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp index 8997121fb..cfc698278 100644 --- a/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp +++ b/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp @@ -7,7 +7,7 @@ #include "OSLineEdit.hpp" -#include "../openstudio_lib/IconLibrary.hpp" +#include "IconLibrary.hpp" #include "../openstudio_lib/OSItem.hpp" #include diff --git a/src/shared_gui_components/OSQuantityEdit.cpp b/src/shared_gui_components/OSQuantityEdit.cpp index 1111fde65..6ffa49358 100644 --- a/src/shared_gui_components/OSQuantityEdit.cpp +++ b/src/shared_gui_components/OSQuantityEdit.cpp @@ -5,7 +5,7 @@ #include "OSQuantityEdit.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/shared_gui_components/OSUnsignedEdit.cpp b/src/shared_gui_components/OSUnsignedEdit.cpp index 2fc8ab17f..16aec52fc 100644 --- a/src/shared_gui_components/OSUnsignedEdit.cpp +++ b/src/shared_gui_components/OSUnsignedEdit.cpp @@ -7,7 +7,7 @@ #include -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/openstudio_lib/OSVectorController.cpp b/src/shared_gui_components/OSVectorController.cpp similarity index 100% rename from src/openstudio_lib/OSVectorController.cpp rename to src/shared_gui_components/OSVectorController.cpp diff --git a/src/openstudio_lib/OSVectorController.hpp b/src/shared_gui_components/OSVectorController.hpp similarity index 89% rename from src/openstudio_lib/OSVectorController.hpp rename to src/shared_gui_components/OSVectorController.hpp index d2c8ad453..b66a1e77d 100644 --- a/src/openstudio_lib/OSVectorController.hpp +++ b/src/shared_gui_components/OSVectorController.hpp @@ -3,10 +3,10 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef OPENSTUDIO_OSVECTORCONTROLLER_HPP -#define OPENSTUDIO_OSVECTORCONTROLLER_HPP +#ifndef SHAREDGUICOMPONENTS_OSVECTORCONTROLLER_HPP +#define SHAREDGUICOMPONENTS_OSVECTORCONTROLLER_HPP -#include "OSItem.hpp" +#include "OSItemId.hpp" #include #include @@ -19,6 +19,8 @@ class QMutex; namespace openstudio { +class OSItem; + class OSVectorController : public QObject , public Nano::Observer @@ -73,4 +75,4 @@ class OSVectorController } // namespace openstudio -#endif // OPENSTUDIO_OSVECTORCONTROLLER_HPP +#endif // SHAREDGUICOMPONENTS_OSVECTORCONTROLLER_HPP diff --git a/src/shared_gui_components/ProcessEventsProgressBar.cpp b/src/shared_gui_components/ProcessEventsProgressBar.cpp index 3ddee4600..1c0582f06 100644 --- a/src/shared_gui_components/ProcessEventsProgressBar.cpp +++ b/src/shared_gui_components/ProcessEventsProgressBar.cpp @@ -5,7 +5,7 @@ #include "ProcessEventsProgressBar.hpp" -#include "../model_editor/Application.hpp" +#include "../openstudio_qt_utils/Application.hpp" namespace openstudio { diff --git a/src/shared_gui_components/ProcessEventsProgressBar.hpp b/src/shared_gui_components/ProcessEventsProgressBar.hpp index 09914a9f8..862cae09f 100644 --- a/src/shared_gui_components/ProcessEventsProgressBar.hpp +++ b/src/shared_gui_components/ProcessEventsProgressBar.hpp @@ -6,7 +6,7 @@ #ifndef SHAREDGUICOMPONENTS_PROCESSEVENTSPROGRESSBAR_HPP #define SHAREDGUICOMPONENTS_PROCESSEVENTSPROGRESSBAR_HPP -#include "../model_editor/OSProgressBar.hpp" +#include "../openstudio_qt_utils/OSProgressBar.hpp" namespace openstudio { diff --git a/src/model_editor/UserSettings.cpp b/src/shared_gui_components/UserSettings.cpp similarity index 97% rename from src/model_editor/UserSettings.cpp rename to src/shared_gui_components/UserSettings.cpp index 539c44824..bf03798e7 100644 --- a/src/model_editor/UserSettings.cpp +++ b/src/shared_gui_components/UserSettings.cpp @@ -13,7 +13,7 @@ #include #include -#include "Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include diff --git a/src/model_editor/UserSettings.hpp b/src/shared_gui_components/UserSettings.hpp similarity index 88% rename from src/model_editor/UserSettings.hpp rename to src/shared_gui_components/UserSettings.hpp index e249b4e10..95f982903 100644 --- a/src/model_editor/UserSettings.hpp +++ b/src/shared_gui_components/UserSettings.hpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef MODELEDITOR_USERSETTINGS_HPP -#define MODELEDITOR_USERSETTINGS_HPP +#ifndef SHAREDGUICOMPONENTS_USERSETTINGS_HPP +#define SHAREDGUICOMPONENTS_USERSETTINGS_HPP #include #include @@ -24,4 +24,4 @@ bool setUserMeasuresDir(const openstudio::path& userMeasuresDir); /// Clears the path to the user measures directory stored in settings. void clearUserMeasuresDir(); -#endif // MODELEDITOR_USERSETTINGS_HPP +#endif // SHAREDGUICOMPONENTS_USERSETTINGS_HPP diff --git a/src/shared_gui_components/WorkflowController.cpp b/src/shared_gui_components/WorkflowController.cpp index 74ee5f764..c8e62bea0 100644 --- a/src/shared_gui_components/WorkflowController.cpp +++ b/src/shared_gui_components/WorkflowController.cpp @@ -14,7 +14,7 @@ #include "../openstudio_lib/MainWindow.hpp" #include "LocalLibraryController.hpp" #include "WorkflowTools.hpp" -#include "../model_editor/Utilities.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index 52754708e..047eab349 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -28,14 +28,13 @@ add_library(${target_name} if (NINJA) target_compile_definitions(${target_name} PRIVATE NINJA=1) endif() -target_link_libraries(${target_name} ${${target_name}_depends} ) +target_link_libraries(${target_name} PUBLIC ${${target_name}_depends} ) if(BUILD_MICRO_PROFILING) - target_link_libraries(${target_name} ${MICRO_PROFILER_LIB} ) + target_link_libraries(${target_name} PUBLIC ${MICRO_PROFILER_LIB} ) endif() if(BUILD_TESTING) CREATE_TEST_TARGETS(${target_name} "${${target_name}_test_src}" "${${target_name}_depends}") # add_dependencies("${target_name}_tests" openstudio_energyplus_resources) endif() - From 818371d482afc6186b2a147c49ff2fdc3c10028a Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 14:25:17 -0600 Subject: [PATCH 03/26] Missed a few updates --- src/model_editor/test/Utilities_GTest.cpp | 4 +--- src/openstudio_lib/GridItem.cpp | 2 +- src/openstudio_lib/RunTabView.cpp | 5 +---- src/shared_gui_components/OSGridController.cpp | 6 +++--- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/model_editor/test/Utilities_GTest.cpp b/src/model_editor/test/Utilities_GTest.cpp index 08b7cbb53..75a75a0c7 100644 --- a/src/model_editor/test/Utilities_GTest.cpp +++ b/src/model_editor/test/Utilities_GTest.cpp @@ -140,9 +140,7 @@ TEST_F(ModelEditorFixture, MorePath_Conversions) { QUrl url = QUrl::fromLocalFile(qPath); EXPECT_EQ(url.toString(QUrl::FullyEncoded), testCase.expectedUrl); - std::cout << "Input: " << testCase.inputPath << ", " - << "OS Path: " << osPath << ", " - << "QPath: " << qPath.toStdString() << ", " + std::cout << "Input: " << testCase.inputPath << ", " << "OS Path: " << osPath << ", " << "QPath: " << qPath.toStdString() << ", " << "Url: " << url.toString().toStdString() << std::endl; } } diff --git a/src/openstudio_lib/GridItem.cpp b/src/openstudio_lib/GridItem.cpp index 2b3ec9adc..e2a8bace8 100644 --- a/src/openstudio_lib/GridItem.cpp +++ b/src/openstudio_lib/GridItem.cpp @@ -1413,7 +1413,7 @@ void SystemCenterItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* } painter->setPen(QPen(Qt::black, 1, Qt::DashLine, Qt::RoundCap)); - painter->drawLine(0, yOrigin + 50, (m_hLength)*100, yOrigin + 50); + painter->drawLine(0, yOrigin + 50, (m_hLength) * 100, yOrigin + 50); painter->rotate(180); painter->drawPixmap(-62, -(yOrigin + 75), 25, 25, QPixmap(":/images/arrow.png")); diff --git a/src/openstudio_lib/RunTabView.cpp b/src/openstudio_lib/RunTabView.cpp index eecbd3d69..6cba47bb8 100644 --- a/src/openstudio_lib/RunTabView.cpp +++ b/src/openstudio_lib/RunTabView.cpp @@ -286,10 +286,7 @@ void RunView::playButtonClicked(bool t_checked) { } arguments << "-w" << workflowJSONPath; } else { - arguments << "run" - << "--show-stdout" - << "--style-stdout" - << "-w" << workflowJSONPath; + arguments << "run" << "--show-stdout" << "--style-stdout" << "-w" << workflowJSONPath; } LOG(Debug, "openstudioExePath='" << toString(openstudioExePath) << "'"); LOG(Debug, "run arguments = " << arguments.join(";").toStdString()); diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index 65e03d758..4d3dedff6 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -8,9 +8,9 @@ // Register OSItemId metatypes for queued signal/slot connections. // Q_DECLARE_METATYPE is in OSGridController.hpp; qRegisterMetaType must run at startup. namespace { - const int __ositemid_type = qRegisterMetaType("OSItemId"); - const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); -} +const int __ositemid_type = qRegisterMetaType("OSItemId"); +const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); +} // namespace #include "OSCellWrapper.hpp" #include "OSGridView.hpp" From f6edaa909282f858da4e9dc7ab0bcafcd06e68fb Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 14:53:55 -0600 Subject: [PATCH 04/26] Update docs --- developer/doc/libraries/model_editor.md | 7 +++++-- developer/doc/libraries/openstudio_lib.md | 12 ++++++------ developer/doc/libraries/openstudio_qt_utils.md | 2 +- developer/doc/libraries/shared_gui_components.md | 5 +++-- developer/doc/libraries/utilities.md | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/developer/doc/libraries/model_editor.md b/developer/doc/libraries/model_editor.md index 1f84ee586..a4eded4db 100644 --- a/developer/doc/libraries/model_editor.md +++ b/developer/doc/libraries/model_editor.md @@ -55,7 +55,6 @@ classDiagram | `IGWidget` | [InspectorGadget.hpp](../../../src/model_editor/InspectorGadget.hpp) | Lightweight `QWidget` / `Nano::Observer` base used as the scroll area content for the generated controls. | | `InspectorDialog` | [InspectorDialog.hpp](../../../src/model_editor/InspectorDialog.hpp) | Modal or modeless dialog that hosts an `InspectorGadget`. Can observe a `Workspace` and keeps the display in sync as objects change. | | `AccessPolicyStore` | [AccessPolicyStore.hpp](../../../src/model_editor/AccessPolicyStore.hpp) | Singleton that reads an XML policy file to determine whether each IDD field is `FREE` (editable), `LOCKED` (read-only), or hidden. | -| `Application` | [Application.hpp](../../../src/model_editor/Application.hpp) | Standalone `QApplication` wrapper for running the model editor outside the main OpenStudio app. | | `GithubReleases` | [GithubReleases.hpp](../../../src/model_editor/GithubReleases.hpp) | Checks GitHub releases API for newer application versions. | | `BridgeClasses` | [BridgeClasses.hpp](../../../src/model_editor/BridgeClasses.hpp) | Adapts OpenStudio nano signals to Qt slots so workspace change notifications reach Qt-connected widgets. | @@ -88,7 +87,11 @@ classDiagram ## Internal Dependencies -None — `model_editor` is intentionally the lowest layer of the application stack. It does not depend on `openstudio_lib` or `shared_gui_components`. +| Module | Usage | +|---|---| +| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration), `OSProgressBar` | + +> **Note:** `Application`, `OSProgressBar`, `QMetaTypes`, `Utilities`, and `UserSettings` were previously in `model_editor` and have been moved to `openstudio_qt_utils` and `shared_gui_components` respectively. --- diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index f75dcf5bb..8b3568d1c 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -111,12 +111,12 @@ classDiagram | `OSItem` | Base class for all draggable/selectable model object items | | `OSDropZone` | Widget that accepts model object drops | | `OSItemList` / `OSCollapsibleItem` | Container widgets for ordered lists of `OSItem`s | -| `OSVectorController` | Abstract base for list controllers backed by model vectors | | `ModelObjectListView` | Generic list view displaying any collection of model objects | | `ModelObjectTreeWidget` | Generic tree view for hierarchical model data | | `OSWebEnginePage` | `QWebEnginePage` subclass for the geometry JS bridge | | `RenderingColorWidget` | Color picker for object rendering colors | -| `IconLibrary` | Singleton cache of domain icons keyed by IDD object type | + +> **Note:** `OSVectorController`, `IconLibrary` have moved to `shared_gui_components`. --- @@ -134,9 +134,9 @@ classDiagram | Module | Usage | |---|---| -| `shared_gui_components` | Grid system, form widgets, `MeasureManager`, `BCLMeasureDialog`, `UserSettings` | -| `model_editor` | `InspectorGadget`, `QMetaTypes` (for `OSItemId` metatype registration) | -| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions) | +| `shared_gui_components` | Grid system, form widgets, `MeasureManager`, `BCLMeasureDialog`, `UserSettings`, `OSVectorController`, `IconLibrary` | +| `model_editor` | `InspectorGadget`, `AccessPolicyStore` | +| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration) | --- @@ -156,7 +156,7 @@ classDiagram - [MainWindow](../classes/openstudio_lib/MainWindow.md) - [MainTabController](../classes/openstudio_lib/MainTabController.md) - [MainRightColumnController](../classes/openstudio_lib/MainRightColumnController.md) -- [OSVectorController](../classes/openstudio_lib/OSVectorController.md) +- [OSVectorController](../classes/shared_gui_components/OSVectorController.md) - [InspectorController](../classes/openstudio_lib/InspectorController.md) - [ModelObjectListView](../classes/openstudio_lib/ModelObjectListView.md) - [OSItem](../classes/openstudio_lib/OSItem.md) diff --git a/developer/doc/libraries/openstudio_qt_utils.md b/developer/doc/libraries/openstudio_qt_utils.md index 99369fe62..4354bf479 100644 --- a/developer/doc/libraries/openstudio_qt_utils.md +++ b/developer/doc/libraries/openstudio_qt_utils.md @@ -110,7 +110,7 @@ namespace openstudio { | `openstudio::OSOptionalQuantity` | `"openstudio::OSOptionalQuantity"` | | `std::shared_ptr` | _(anonymous)_ | -> **Note:** `OSItemId` and `std::vector` are registered in `model_editor/QMetaTypes.cpp` since they depend on `openstudio_lib/OSItem.hpp`, which sits above this library in the dependency graph. +> **Note:** `OSItemId` and `std::vector` are registered in `shared_gui_components/OSGridController.cpp` (via anonymous-namespace statics), since `OSItemId` is defined in `shared_gui_components` and sits above this library in the dependency graph. --- diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 4570137b2..954958a11 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -1,7 +1,7 @@ # Library: `shared_gui_components` — Shared UI Widgets > **Source:** `src/shared_gui_components/` -> **CMake target:** compiled into `openstudio_modeleditor` and `openstudio_lib` +> **CMake target:** `openstudio_shared_gui` > **Back to:** [Architecture Overview](../architecture.md) ## Purpose @@ -109,6 +109,8 @@ All typed input widgets follow the same pattern: they read from and write to a ` | `OSQuantityEdit` / `OSQuantityEdit2` | Dimensional quantity editor with SI/IP toggle | | `OSOptionalQuantityEdit` | Optional dimensional quantity (blank = unset) | +> **Note:** `OSVectorController`, `OSItemId`, `IconLibrary`, and `UserSettings` are now part of `shared_gui_components` (previously in `openstudio_lib` or `model_editor`). + The `2` suffix variants use `std::function` callbacks instead of `QObject` signal/slot; they are preferred in newer code. --- @@ -154,7 +156,6 @@ flowchart TD | Module | Usage | |---|---| | `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration), `OSProgressBar` | -| `openstudio_lib` | `OSItem`, `OSVectorController` (used in `OSGridController`) | --- diff --git a/developer/doc/libraries/utilities.md b/developer/doc/libraries/utilities.md index 3374af9ef..2e7adfe7e 100644 --- a/developer/doc/libraries/utilities.md +++ b/developer/doc/libraries/utilities.md @@ -1,7 +1,7 @@ # Library: `utilities` — Path Helpers > **Source:** `src/utilities/` -> **CMake target:** `openstudio_apputils` (header/static) +> **CMake target:** `openstudioapp_utilities` (static library) > **Back to:** [Architecture Overview](../architecture.md) ## Purpose From 0c307782f68db3959b369e30c452638b7814c97e Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 15:11:28 -0600 Subject: [PATCH 05/26] Merge remote-tracking branch 'remotes/origin/cleanup_dependencies' into add_documentation # Conflicts: # src/model_editor/ModelEditorAPI.hpp # src/openstudio_qt_utils/Application.hpp # src/openstudio_qt_utils/Utilities.hpp # src/shared_gui_components/IconLibrary.hpp # src/shared_gui_components/MeasureManager.hpp # src/utilities/CMakeLists.txt --- src/bimserver/BIMServer.i | 1 - src/bimserver/BIMserverAPI.hpp | 20 ----------- src/bimserver/BIMserverConnection.hpp | 4 +-- src/bimserver/CMakeLists.txt | 1 - src/bimserver/ProjectImporter.hpp | 3 +- src/model_editor/AccessPolicyStore.hpp | 6 ++-- src/model_editor/BridgeClasses.hpp | 4 +-- src/model_editor/CMakeLists.txt | 6 ---- src/model_editor/GithubReleases.hpp | 9 +++-- src/model_editor/IGLineEdit.hpp | 3 +- src/model_editor/IGSpinBoxes.hpp | 5 ++- src/model_editor/InspectorDialog.hpp | 4 +-- src/model_editor/InspectorGadget.hpp | 6 ++-- src/model_editor/ModalDialogs.hpp | 10 +++--- src/model_editor/ModelEditor.i | 1 - src/model_editor/ModelEditorAPI.hpp | 28 --------------- src/model_editor/PathWatcher.hpp | 4 +-- src/model_editor/TableWidget.cpp | 3 ++ src/model_editor/TableWidget.hpp | 4 +-- src/model_editor/TestButton.hpp | 4 +-- src/openstudio_app/CMakeLists.txt | 4 --- src/openstudio_app/main.cpp | 2 -- src/openstudio_lib/CMakeLists.txt | 5 --- src/openstudio_lib/OSAppBase.hpp | 3 +- src/openstudio_lib/OSDocument.hpp | 4 +-- src/openstudio_lib/OpenStudioAPI.hpp | 20 ----------- src/openstudio_lib/ResultsTabView.cpp | 2 +- src/openstudio_qt_utils/Application.hpp | 1 - src/openstudio_qt_utils/CMakeLists.txt | 1 - .../OpenStudioQtUtilsAPI.hpp | 26 -------------- src/openstudio_qt_utils/Utilities.hpp | 21 +++++------ src/shared_gui_components/CMakeLists.txt | 5 --- src/shared_gui_components/IconLibrary.hpp | 3 +- src/shared_gui_components/MeasureManager.hpp | 5 --- src/utilities/CMakeLists.txt | 3 -- .../OpenStudioApplicationPathHelpers.hpp | 35 +++++++++---------- .../OpenStudioApplicationUtilitiesAPI.hpp | 20 ----------- 37 files changed, 55 insertions(+), 231 deletions(-) delete mode 100644 src/bimserver/BIMserverAPI.hpp delete mode 100644 src/model_editor/ModelEditorAPI.hpp delete mode 100644 src/openstudio_lib/OpenStudioAPI.hpp delete mode 100644 src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp delete mode 100644 src/utilities/OpenStudioApplicationUtilitiesAPI.hpp diff --git a/src/bimserver/BIMServer.i b/src/bimserver/BIMServer.i index d2196ee9b..b307ae846 100644 --- a/src/bimserver/BIMServer.i +++ b/src/bimserver/BIMServer.i @@ -7,7 +7,6 @@ #define UTILITIES_API -#define BIMSERVER_API %include %import diff --git a/src/bimserver/BIMserverAPI.hpp b/src/bimserver/BIMserverAPI.hpp deleted file mode 100644 index ada5ab10c..000000000 --- a/src/bimserver/BIMserverAPI.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef BIMSERVER_BIMSERVERAPI_HPP -#define BIMSERVER_BIMSERVERAPI_HPP - -#if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS - -# ifdef openstudio_bimserver_EXPORTS -# define BIMSERVER_API __declspec(dllexport) -# else -# define BIMSERVER_API __declspec(dllimport) -# endif -#else -# define BIMSERVER_API -#endif - -#endif diff --git a/src/bimserver/BIMserverConnection.hpp b/src/bimserver/BIMserverConnection.hpp index 146f4d875..b276fe0aa 100644 --- a/src/bimserver/BIMserverConnection.hpp +++ b/src/bimserver/BIMserverConnection.hpp @@ -6,8 +6,6 @@ #ifndef BIMSERVER_BIMSERVERCONNECTION_HPP #define BIMSERVER_BIMSERVERCONNECTION_HPP -#include "BIMserverAPI.hpp" - #include #include @@ -30,7 +28,7 @@ class Surface; namespace bimserver { /// This provides utilities to connect to BIMserver -class BIMSERVER_API BIMserverConnection : public QObject +class BIMserverConnection : public QObject { Q_OBJECT diff --git a/src/bimserver/CMakeLists.txt b/src/bimserver/CMakeLists.txt index 4bae08653..1cf776c07 100644 --- a/src/bimserver/CMakeLists.txt +++ b/src/bimserver/CMakeLists.txt @@ -5,7 +5,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${QT_INCLUDES}) set(${target_name}_src - BIMserverAPI.hpp mainpage.hpp BIMserverConnection.hpp BIMserverConnection.cpp diff --git a/src/bimserver/ProjectImporter.hpp b/src/bimserver/ProjectImporter.hpp index 11e2dd678..e9d999e20 100644 --- a/src/bimserver/ProjectImporter.hpp +++ b/src/bimserver/ProjectImporter.hpp @@ -6,7 +6,6 @@ #ifndef BIMSERVER_PROJECTIMPORTER_HPP #define BIMSERVER_PROJECTIMPORTER_HPP -#include "BIMserverAPI.hpp" #include "BIMserverConnection.hpp" #include @@ -23,7 +22,7 @@ namespace openstudio { namespace bimserver { /// This shows a input dialog to gather project id for import -class BIMSERVER_API ProjectImporter : public QDialog +class ProjectImporter : public QDialog { Q_OBJECT diff --git a/src/model_editor/AccessPolicyStore.hpp b/src/model_editor/AccessPolicyStore.hpp index bb8a1555a..b5b7212a0 100644 --- a/src/model_editor/AccessPolicyStore.hpp +++ b/src/model_editor/AccessPolicyStore.hpp @@ -6,8 +6,6 @@ #ifndef MODELEDITOR_ACCESSPOLICYSTORE_HPP #define MODELEDITOR_ACCESSPOLICYSTORE_HPP -#include "ModelEditorAPI.hpp" - #include #include @@ -32,7 +30,7 @@ namespace model { * data manipulation side of things. The idea is that each program might have its * own XML file that tells the AccessPolicy how to display fields. */ -class MODELEDITOR_API AccessPolicy +class AccessPolicy { friend class AccessPolicyStore; friend class openstudio::InspectorView; // For overriding via setAccess @@ -74,7 +72,7 @@ class MODELEDITOR_API AccessPolicy * * */ -class MODELEDITOR_API AccessPolicyStore +class AccessPolicyStore { public: static AccessPolicyStore& Instance(); diff --git a/src/model_editor/BridgeClasses.hpp b/src/model_editor/BridgeClasses.hpp index 46723f572..b53c4386f 100644 --- a/src/model_editor/BridgeClasses.hpp +++ b/src/model_editor/BridgeClasses.hpp @@ -6,11 +6,9 @@ #ifndef MODELEDITOR_BRIDGECLASSES_HPP #define MODELEDITOR_BRIDGECLASSES_HPP -#include "ModelEditorAPI.hpp" - #include -class MODELEDITOR_API ComboHighlightBridge : public QObject +class ComboHighlightBridge : public QObject { Q_OBJECT; diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index a8825598c..71d43da8e 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -84,12 +84,6 @@ set(${target_name}_depends add_dependencies(${target_name} ${${target_name}_depends}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) -if(BUILD_SHARED_LIBS) - #target_compile_definitions(${target_name} PUBLIC model_editor_EXPORTS) -else() - target_compile_definitions(${target_name} PUBLIC model_editor_EXPORTS) -endif() - set(${target_name}_test_src test/ModelEditorFixture.hpp test/ModelEditorFixture.cpp diff --git a/src/model_editor/GithubReleases.hpp b/src/model_editor/GithubReleases.hpp index e122b6c69..10be4752d 100644 --- a/src/model_editor/GithubReleases.hpp +++ b/src/model_editor/GithubReleases.hpp @@ -6,7 +6,6 @@ #ifndef MODELEDITOR_GITHUB_RELEASES_HPP #define MODELEDITOR_GITHUB_RELEASES_HPP -#include "ModelEditorAPI.hpp" #include #include @@ -26,7 +25,7 @@ namespace modeleditor { /** Class to represent a single release on Github. **/ -class MODELEDITOR_API GithubRelease +class GithubRelease { public: GithubRelease(const std::string& tagName, bool preRelease, unsigned numDownloads, const std::string& downloadUrl); @@ -46,7 +45,7 @@ class MODELEDITOR_API GithubRelease /** Class for checking releases on Github. **/ -class MODELEDITOR_API GithubReleases +class GithubReleases { public: @@ -99,8 +98,8 @@ class MODELEDITOR_API GithubReleases }; // prints releases and number of downloads -MODELEDITOR_API std::ostream& operator<<(std::ostream& os, const GithubRelease& release); -MODELEDITOR_API std::ostream& operator<<(std::ostream& os, const GithubReleases& releases); +std::ostream& operator<<(std::ostream& os, const GithubRelease& release); +std::ostream& operator<<(std::ostream& os, const GithubReleases& releases); } // namespace modeleditor diff --git a/src/model_editor/IGLineEdit.hpp b/src/model_editor/IGLineEdit.hpp index 6df0bb884..6a704493c 100644 --- a/src/model_editor/IGLineEdit.hpp +++ b/src/model_editor/IGLineEdit.hpp @@ -6,12 +6,11 @@ #ifndef MODELEDITOR_IGLINEEDIT_HPP #define MODELEDITOR_IGLINEEDIT_HPP -#include "ModelEditorAPI.hpp" #include "InspectorGadget.hpp" #include -class MODELEDITOR_API IGLineEdit : public QLineEdit +class IGLineEdit : public QLineEdit { Q_OBJECT; diff --git a/src/model_editor/IGSpinBoxes.hpp b/src/model_editor/IGSpinBoxes.hpp index b4fd73c06..fda2a573f 100644 --- a/src/model_editor/IGSpinBoxes.hpp +++ b/src/model_editor/IGSpinBoxes.hpp @@ -6,7 +6,6 @@ #ifndef MODELEDITOR_IGSPINBOXES_HPP #define MODELEDITOR_IGSPINBOXES_HPP -#include "ModelEditorAPI.hpp" #include "InspectorGadget.hpp" #include @@ -14,7 +13,7 @@ class QWheelEvent; -class MODELEDITOR_API IGSpinBox : public QSpinBox +class IGSpinBox : public QSpinBox { Q_OBJECT; @@ -27,7 +26,7 @@ class MODELEDITOR_API IGSpinBox : public QSpinBox void triggered(bool); //the radio button got triggered and calls this slot }; -class MODELEDITOR_API IGDSpinBox : public QDoubleSpinBox +class IGDSpinBox : public QDoubleSpinBox { Q_OBJECT; diff --git a/src/model_editor/InspectorDialog.hpp b/src/model_editor/InspectorDialog.hpp index 763fc5514..5336e4d8f 100644 --- a/src/model_editor/InspectorDialog.hpp +++ b/src/model_editor/InspectorDialog.hpp @@ -6,8 +6,6 @@ #ifndef MODELEDITOR_INSPECTORDIALOG_HPP #define MODELEDITOR_INSPECTORDIALOG_HPP -#include "ModelEditorAPI.hpp" - #include #include @@ -41,7 +39,7 @@ class ModelObject; OPENSTUDIO_ENUM(InspectorDialogClient, ((AllOpenStudio))); #endif -class MODELEDITOR_API InspectorDialog +class InspectorDialog : public QMainWindow , public Nano::Observer { diff --git a/src/model_editor/InspectorGadget.hpp b/src/model_editor/InspectorGadget.hpp index 3dcfb8953..aa923bab5 100644 --- a/src/model_editor/InspectorGadget.hpp +++ b/src/model_editor/InspectorGadget.hpp @@ -13,8 +13,6 @@ #include "AccessPolicyStore.hpp" #include -#include "ModelEditorAPI.hpp" - #include // Signal-Slot replacement #include @@ -34,7 +32,7 @@ class QVBoxLayout; class ComboHighlightBridge; -class MODELEDITOR_API IGWidget +class IGWidget : public QWidget , public Nano::Observer { @@ -70,7 +68,7 @@ class IGComboBox : public QComboBox * Choice is displayed as a ComboBox * */ -class MODELEDITOR_API InspectorGadget +class InspectorGadget : public QWidget , public Nano::Observer { diff --git a/src/model_editor/ModalDialogs.hpp b/src/model_editor/ModalDialogs.hpp index 9e0240493..718f66d03 100644 --- a/src/model_editor/ModalDialogs.hpp +++ b/src/model_editor/ModalDialogs.hpp @@ -6,8 +6,6 @@ #ifndef MODELEDITOR_MODALDIALOGS_HPP #define MODELEDITOR_MODALDIALOGS_HPP -#include "ModelEditorAPI.hpp" - #include #include // Signal-Slot replacement @@ -33,7 +31,7 @@ class SpaceLoadInstance; } // namespace model } // namespace openstudio -class MODELEDITOR_API ModelObjectSelectorDialog +class ModelObjectSelectorDialog : public QDialog , public Nano::Observer { @@ -92,7 +90,7 @@ class MODELEDITOR_API ModelObjectSelectorDialog void loadComboBoxData(); }; -class MODELEDITOR_API ModelObjectSelectorDialogWatcher +class ModelObjectSelectorDialogWatcher : public QObject , public Nano::Observer { @@ -116,8 +114,8 @@ class MODELEDITOR_API ModelObjectSelectorDialogWatcher mutable boost::optional m_selectedModelObject; }; -MODELEDITOR_API void ensureThermalZone(openstudio::model::Space& space); +void ensureThermalZone(openstudio::model::Space& space); -MODELEDITOR_API void ensureSpaceLoadDefinition(openstudio::model::SpaceLoadInstance& instance); +void ensureSpaceLoadDefinition(openstudio::model::SpaceLoadInstance& instance); #endif //MODELEDITOR_MODALDIALOGS_HPP diff --git a/src/model_editor/ModelEditor.i b/src/model_editor/ModelEditor.i index 38b4371ba..250aeb51f 100644 --- a/src/model_editor/ModelEditor.i +++ b/src/model_editor/ModelEditor.i @@ -7,7 +7,6 @@ #define UTILITIES_API #define MODEL_API -#define MODELEDITOR_API %include %import diff --git a/src/model_editor/ModelEditorAPI.hpp b/src/model_editor/ModelEditorAPI.hpp deleted file mode 100644 index b3f998d43..000000000 --- a/src/model_editor/ModelEditorAPI.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include "../openstudio_qt_utils/QMetaTypes.hpp" - -#ifndef MODELEDITOR_MODELEDITORAPI_HPP -# define MODELEDITOR_MODELEDITORAPI_HPP - -# if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS - -# ifdef openstudio_modeleditor_EXPORTS -# define MODELEDITOR_API __declspec(dllexport) -# define MODELEDITOR_TEMPLATE_EXT -# else -# define MODELEDITOR_API __declspec(dllimport) -# define MODELEDITOR_TEMPLATE_EXT extern -# endif - -# else - -# define MODELEDITOR_API -# define MODELEDITOR_TEMPLATE_EXT - -# endif - -#endif diff --git a/src/model_editor/PathWatcher.hpp b/src/model_editor/PathWatcher.hpp index a395bc92f..724d8a407 100644 --- a/src/model_editor/PathWatcher.hpp +++ b/src/model_editor/PathWatcher.hpp @@ -6,8 +6,6 @@ #ifndef MODELEDITOR_PATHWATCHER_HPP #define MODELEDITOR_PATHWATCHER_HPP -#include "ModelEditorAPI.hpp" - #include #include @@ -18,7 +16,7 @@ class QTimer; /** Class for watching a file for changes, directories are not supported **/ -class MODELEDITOR_API PathWatcher : public QObject +class PathWatcher : public QObject { Q_OBJECT; diff --git a/src/model_editor/TableWidget.cpp b/src/model_editor/TableWidget.cpp index d4ef4ef77..e17ae0efe 100644 --- a/src/model_editor/TableWidget.cpp +++ b/src/model_editor/TableWidget.cpp @@ -5,6 +5,9 @@ #include "TableWidget.hpp" +#include +#include + using namespace openstudio::model; using namespace openstudio; diff --git a/src/model_editor/TableWidget.hpp b/src/model_editor/TableWidget.hpp index 2796cd034..9f013d0a6 100644 --- a/src/model_editor/TableWidget.hpp +++ b/src/model_editor/TableWidget.hpp @@ -9,11 +9,9 @@ #include #include -#include "ModelEditorAPI.hpp" - namespace modeleditor { -class MODELEDITOR_API TableWidget : public QTableWidget +class TableWidget : public QTableWidget { Q_OBJECT diff --git a/src/model_editor/TestButton.hpp b/src/model_editor/TestButton.hpp index 1a9760b40..df80c5524 100644 --- a/src/model_editor/TestButton.hpp +++ b/src/model_editor/TestButton.hpp @@ -8,9 +8,7 @@ #include -#include "ModelEditorAPI.hpp" - -class MODELEDITOR_API TestButton : public QObject +class TestButton : public QObject { Q_OBJECT diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index d535b4c9b..7394740c7 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -117,10 +117,6 @@ add_executable(${target_name} ${ICON_SRC} ) -if (NINJA) - target_compile_definitions(${target_name} PRIVATE NINJA=1) -endif() - if(WIN32) # increase stack size target_link_options(${target_name} PRIVATE /STACK:8388608) diff --git a/src/openstudio_app/main.cpp b/src/openstudio_app/main.cpp index a16eeaaca..8d6fb1a51 100644 --- a/src/openstudio_app/main.cpp +++ b/src/openstudio_app/main.cpp @@ -3,8 +3,6 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#define COMPILING_FROM_OSAPP -#include "../openstudio_lib/OpenStudioAPI.hpp" #include "OpenStudioApp.hpp" #include "../openstudio_qt_utils/Application.hpp" #include "../model_editor/AccessPolicyStore.hpp" diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index f5e1b6da7..0af6bbdd8 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -181,7 +181,6 @@ set(${target_name}_SRC ModelSubTabController.hpp ModelSubTabView.cpp ModelSubTabView.hpp - OpenStudioAPI.hpp OSAppBase.cpp OSAppBase.hpp OSCategoryPlaceholder.cpp @@ -610,10 +609,6 @@ add_library(${target_name} ${${target_name}_qrcs} ) -if (NINJA) - target_compile_definitions(${target_name} PRIVATE NINJA=1) -endif() - set(${target_name}_depends openstudio_shared_gui openstudio_modeleditor diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index 1d111f21c..f0ee1d7b0 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -11,7 +11,6 @@ #include #include "../openstudio_qt_utils/QMetaTypes.hpp" -#include "OpenStudioAPI.hpp" #include #include @@ -26,7 +25,7 @@ class OSDocument; class WaitDialog; -class OPENSTUDIO_API OSAppBase +class OSAppBase : public QApplication , public BaseApp { diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index 435914145..b7da327a1 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -6,8 +6,6 @@ #ifndef OPENSTUDIO_OSDOCUMENT_HPP #define OPENSTUDIO_OSDOCUMENT_HPP -#include "OpenStudioAPI.hpp" - #include "../shared_gui_components/OSQObjectController.hpp" #include "../openstudio_qt_utils/QMetaTypes.hpp" @@ -44,7 +42,7 @@ class ApplyMeasureNowDialog; class Workspace; -class OPENSTUDIO_API OSDocument : public OSQObjectController +class OSDocument : public OSQObjectController { Q_OBJECT diff --git a/src/openstudio_lib/OpenStudioAPI.hpp b/src/openstudio_lib/OpenStudioAPI.hpp deleted file mode 100644 index cb6af4ee4..000000000 --- a/src/openstudio_lib/OpenStudioAPI.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OPENSTUDIO_OPENSTUDIOAPI_HPP -#define OPENSTUDIO_OPENSTUDIOAPI_HPP - -#if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS - -# ifdef openstudio_lib_EXPORTS -# define OPENSTUDIO_API __declspec(dllexport) -# else -# define OPENSTUDIO_API __declspec(dllimport) -# endif -#else -# define OPENSTUDIO_API -#endif - -#endif diff --git a/src/openstudio_lib/ResultsTabView.cpp b/src/openstudio_lib/ResultsTabView.cpp index 46d048245..011a84d83 100644 --- a/src/openstudio_lib/ResultsTabView.cpp +++ b/src/openstudio_lib/ResultsTabView.cpp @@ -291,7 +291,7 @@ void ResultsView::populateComboBox(const std::vector& reports) m_comboBox->clear(); for (const openstudio::path& report : reports) { - // Here we DO want to call MODELEDITOR_API QString toQString(const path&) overload, which should automatically + // Here we DO want to call the QString toQString(const path&) overload, which should automatically // convert that to a unix-style path (with forward slashes) which is what we do want here. // fullPathString = toQString(report.string()); // This will mix slashes and backslashes (without escaping...) => C:/companion_folder\reports\eplustbl.html // (Alternatively, we could just use QUrl::fromLocalFile in comboBoxChanged instead of manually preprending "file:///" here) diff --git a/src/openstudio_qt_utils/Application.hpp b/src/openstudio_qt_utils/Application.hpp index be6ebfa6c..97b76269c 100644 --- a/src/openstudio_qt_utils/Application.hpp +++ b/src/openstudio_qt_utils/Application.hpp @@ -6,7 +6,6 @@ #ifndef OPENSTUDIOQTUTILS_APPLICATION_HPP #define OPENSTUDIOQTUTILS_APPLICATION_HPP -#include "OpenStudioQtUtilsAPI.hpp" #include "QMetaTypes.hpp" #include diff --git a/src/openstudio_qt_utils/CMakeLists.txt b/src/openstudio_qt_utils/CMakeLists.txt index ebdedf305..fe2e386a5 100644 --- a/src/openstudio_qt_utils/CMakeLists.txt +++ b/src/openstudio_qt_utils/CMakeLists.txt @@ -5,7 +5,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${QT_INCLUDES}) set(${target_name}_src - OpenStudioQtUtilsAPI.hpp Application.hpp Application.cpp OSProgressBar.hpp diff --git a/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp b/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp deleted file mode 100644 index 6857001c4..000000000 --- a/src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OPENSTUDIOQTUTILS_API_HPP -#define OPENSTUDIOQTUTILS_API_HPP - -#if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS - -# ifdef openstudio_qt_utils_EXPORTS -# define OPENSTUDIOQTUTILS_API __declspec(dllexport) -# define OPENSTUDIOQTUTILS_TEMPLATE_EXT -# else -# define OPENSTUDIOQTUTILS_API __declspec(dllimport) -# define OPENSTUDIOQTUTILS_TEMPLATE_EXT extern -# endif - -#else - -# define OPENSTUDIOQTUTILS_API -# define OPENSTUDIOQTUTILS_TEMPLATE_EXT - -#endif - -#endif // OPENSTUDIOQTUTILS_API_HPP diff --git a/src/openstudio_qt_utils/Utilities.hpp b/src/openstudio_qt_utils/Utilities.hpp index 2942bd840..4499c732b 100644 --- a/src/openstudio_qt_utils/Utilities.hpp +++ b/src/openstudio_qt_utils/Utilities.hpp @@ -9,35 +9,32 @@ #include #include -#include #include - -#include "OpenStudioQtUtilsAPI.hpp" - +#include namespace openstudio { /** QString to UTF-8 encoded std::string. */ -OPENSTUDIOQTUTILS_API std::string toString(const QString& q); +std::string toString(const QString& q); /** QString to wstring. */ -OPENSTUDIOQTUTILS_API std::wstring toWString(const QString& q); +std::wstring toWString(const QString& q); /** UTF-8 encoded std::string to QString. */ -OPENSTUDIOQTUTILS_API QString toQString(const std::string& s); +QString toQString(const std::string& s); /** wstring to QString. */ -OPENSTUDIOQTUTILS_API QString toQString(const std::wstring& w); +QString toQString(const std::wstring& w); /// create a UUID from a std::string, does not throw, may return a null UUID -OPENSTUDIOQTUTILS_API UUID toUUID(const QString& str); +UUID toUUID(const QString& str); /// create a QString from a UUID -OPENSTUDIOQTUTILS_API QString toQString(const UUID& uuid); +QString toQString(const UUID& uuid); /** path to QString. */ -OPENSTUDIOQTUTILS_API QString toQString(const path& p); +QString toQString(const path& p); /** QString to path*/ -OPENSTUDIOQTUTILS_API path toPath(const QString& q); +path toPath(const QString& q); } // namespace openstudio diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index 7bb0d04bf..9db3e2e5a 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -5,7 +5,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${QT_INCLUDES}) set(${target_name}_src - OpenStudioSharedGuiAPI.hpp BCLMeasureDialog.cpp BCLMeasureDialog.hpp BuildingComponentDialog.cpp @@ -185,10 +184,6 @@ set(${target_name}_depends add_library(${target_name} ${${target_name}_src} ${${target_name}_moc_src}) -if (NINJA) - target_compile_definitions(${target_name} PRIVATE NINJA=1) -endif() - target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) CREATE_SRC_GROUPS("${${target_name}_src}") diff --git a/src/shared_gui_components/IconLibrary.hpp b/src/shared_gui_components/IconLibrary.hpp index 7d5413f05..c0dff67b0 100644 --- a/src/shared_gui_components/IconLibrary.hpp +++ b/src/shared_gui_components/IconLibrary.hpp @@ -6,7 +6,6 @@ #ifndef SHAREDGUICOMPONENTS_ICONLIBRARY_HPP #define SHAREDGUICOMPONENTS_ICONLIBRARY_HPP -#include "OpenStudioSharedGuiAPI.hpp" #include #include @@ -22,7 +21,7 @@ namespace openstudio { * it, because it might return NULL. * */ -class OPENSTUDIO_SHARED_GUI_API IconLibrary +class IconLibrary { public: diff --git a/src/shared_gui_components/MeasureManager.hpp b/src/shared_gui_components/MeasureManager.hpp index 291eb85d8..7b3a78722 100644 --- a/src/shared_gui_components/MeasureManager.hpp +++ b/src/shared_gui_components/MeasureManager.hpp @@ -62,12 +62,7 @@ class LocalLibraryController; * In this case only one of the measures is displayed. * **/ -#if defined(openstudio_lib_EXPORTS) || defined(COMPILING_FROM_OSAPP) -# include "OpenStudioSharedGuiAPI.hpp" -class OPENSTUDIO_SHARED_GUI_API MeasureManager : public QObject -#else class MeasureManager : public QObject -#endif { Q_OBJECT; diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index 047eab349..7c6c14e96 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -25,9 +25,6 @@ set(${target_name}_depends add_library(${target_name} ${${target_name}_src} ) -if (NINJA) - target_compile_definitions(${target_name} PRIVATE NINJA=1) -endif() target_link_libraries(${target_name} PUBLIC ${${target_name}_depends} ) if(BUILD_MICRO_PROFILING) diff --git a/src/utilities/OpenStudioApplicationPathHelpers.hpp b/src/utilities/OpenStudioApplicationPathHelpers.hpp index 1a334ffc6..b2648ac09 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.hpp +++ b/src/utilities/OpenStudioApplicationPathHelpers.hpp @@ -6,59 +6,58 @@ #ifndef OSAPP_UTILITIES_APPLICATIONPATHHELPERS_HPP #define OSAPP_UTILITIES_APPLICATIONPATHHELPERS_HPP -#include "OpenStudioApplicationUtilitiesAPI.hpp" #include #include namespace openstudio { /// \returns The version of the OpenStudio Application -OSAPP_UTILITIES_API std::string openStudioApplicationVersion(); +std::string openStudioApplicationVersion(); // Return the version in MAJOR.MINOR.PATCH format (eg '3.0.0') -OSAPP_UTILITIES_API std::string openStudioApplicationVersionWithPrerelease(); +std::string openStudioApplicationVersionWithPrerelease(); // Includes the prerelease tag but not the build sha, eg: '1.1.0-alpha'. Should match to a github tag -OSAPP_UTILITIES_API std::string OpenStudioApplicationVersionMajor(); +std::string OpenStudioApplicationVersionMajor(); // Includes prerelease tag if any, and build sha, eg: '3.0.0-rc1+baflkdhsia' -OSAPP_UTILITIES_API std::string OpenStudioApplicationVersionMinor(); +std::string OpenStudioApplicationVersionMinor(); -OSAPP_UTILITIES_API std::string OpenStudioApplicationVersionPatch(); +std::string OpenStudioApplicationVersionPatch(); -OSAPP_UTILITIES_API std::string OpenStudioApplicationVersionPrerelease(); +std::string OpenStudioApplicationVersionPrerelease(); -OSAPP_UTILITIES_API std::string OpenStudioApplicationVersionBuildSHA(); +std::string OpenStudioApplicationVersionBuildSHA(); /// \returns The source directory the application was built from -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationSourceDirectory(); +openstudio::path getOpenStudioApplicationSourceDirectory(); /// \returns The directory the application was built in -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationBuildDirectory(); +openstudio::path getOpenStudioApplicationBuildDirectory(); /// \returns The directory that openstudio-coalition-measures are installed in if running from build directory -OSAPP_UTILITIES_API openstudio::path getOpenStudioCoalitionMeasuresSourceDirectory(); +openstudio::path getOpenStudioCoalitionMeasuresSourceDirectory(); /// \returns The path to the current executable application -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationPath(); +openstudio::path getOpenStudioApplicationPath(); /// \returns The directory of the current executable application -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationDirectory(); +openstudio::path getOpenStudioApplicationDirectory(); /// \returns True if the application is running from the build directory -OSAPP_UTILITIES_API bool isOpenStudioApplicationRunningFromBuildDirectory(); +bool isOpenStudioApplicationRunningFromBuildDirectory(); /// \returns Will return path to the binary containing OpenStudio Utilities, could be openstudio.exe, openstudio.so, etc. -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationModule(); +openstudio::path getOpenStudioApplicationModule(); /// \returns Will return dir containing the binary containing OpenStudio Utilities, could be openstudio.exe, openstudio.so, etc. -OSAPP_UTILITIES_API openstudio::path getOpenStudioApplicationModuleDirectory(); +openstudio::path getOpenStudioApplicationModuleDirectory(); /// \returns True if the OpenStudio Module is running from the build directory -OSAPP_UTILITIES_API bool isOpenStudioApplicationModuleRunningFromBuildDirectory(); +bool isOpenStudioApplicationModuleRunningFromBuildDirectory(); /// \returns The path to the OpenStudio Command Line Interface if it exists. -OSAPP_UTILITIES_API openstudio::path getOpenStudioCoreCLI(); +openstudio::path getOpenStudioCoreCLI(); } // namespace openstudio diff --git a/src/utilities/OpenStudioApplicationUtilitiesAPI.hpp b/src/utilities/OpenStudioApplicationUtilitiesAPI.hpp deleted file mode 100644 index ffa0753dc..000000000 --- a/src/utilities/OpenStudioApplicationUtilitiesAPI.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OSAPP_UTILITIES_OSAPP_UTILITIESAPI_HPP -#define OSAPP_UTILITIES_OSAPP_UTILITIESAPI_HPP - -#if (_WIN32 || _MSC_VER) && SHARED_OSAPP_LIBS - -# ifdef openstudioapp_utilities_EXPORTS -# define OSAPP_UTILITIES_API __declspec(dllexport) -# else -# define OSAPP_UTILITIES_API __declspec(dllimport) -# endif -#else -# define OSAPP_UTILITIES_API -#endif - -#endif From cd14117508f6e4da5d7dab51b3cf688bc2bb0d2e Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 15:17:48 -0600 Subject: [PATCH 06/26] Update llms.txt --- llms.txt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/llms.txt b/llms.txt index 438957095..05078caaa 100644 --- a/llms.txt +++ b/llms.txt @@ -45,19 +45,6 @@ OpenStudioApp (exe) --- -## API macros → library mapping - -| Macro | Library target | Header | -|---|---|---| -| `MODELEDITOR_API` | `openstudio_modeleditor` | `src/model_editor/ModelEditorAPI.hpp` | -| `OPENSTUDIO_API` | `openstudio_lib` | `src/openstudio_lib/OpenStudioAPI.hpp` | -| `OPENSTUDIOQTUTILS_API` | `openstudio_qt_utils` | `src/openstudio_qt_utils/OpenStudioQtUtilsAPI.hpp` | -| `SHARED_OSAPP_LIBS` | all shared libs | compile-time flag for dllexport/dllimport | - -When adding a new class to a library, inherit its `*_API` macro from that library's API header — never from another library's macro. - ---- - ## CMake target → depends (what to add when you need a new dependency) To use a class from library X in library Y, add X's CMake target to Y's `set(${target_name}_depends ...)` block in `src/Y/CMakeLists.txt`. @@ -83,7 +70,6 @@ To use a class from library X in library Y, add X's CMake target to Y's `set(${t | `Utilities.hpp/.cpp` | `openstudio::toQString()`, `toString()`, `toPath()`, `toUUID()`, etc. | | `QMetaTypes.hpp/.cpp` | `Q_DECLARE_METATYPE` + `qRegisterMetaType` for all SDK types (`IddObjectType`, `UUID`, `OSItemId`, etc.) | | `OSProgressBar.hpp/.cpp` | `openstudio::OSProgressBar` — Qt progress bar wrapping SDK `ProgressBar` | -| `OpenStudioQtUtilsAPI.hpp` | `OPENSTUDIOQTUTILS_API` macro | ### model_editor (`src/model_editor/`) | File | Key class | @@ -94,7 +80,6 @@ To use a class from library X in library Y, add X's CMake target to Y's `set(${t | `PathWatcher.hpp/.cpp` | `openstudio::PathWatcher` — filesystem path change notifications | | `GithubReleases.hpp/.cpp` | `openstudio::GithubReleases` — checks GitHub releases API for new versions | | `ModalDialogs.hpp/.cpp` | `openstudio::ModelObjectSelectorDialog` — generic model-object picker dialog | -| `ModelEditorAPI.hpp` | `MODELEDITOR_API` macro; also includes `openstudio_qt_utils/QMetaTypes.hpp` | ### shared_gui_components (`src/shared_gui_components/`) | File | Key class | @@ -163,7 +148,6 @@ Example: `mouseOverInspectorView()` was added this way so `OSLineEdit.cpp` (in ` All SDK type metatype registrations live in `src/openstudio_qt_utils/QMetaTypes.hpp/.cpp`. `OSItemId` registration is in `src/shared_gui_components/OSGridController.cpp` (requires the type definition from `openstudio_lib`). -Do NOT add metatype registrations to `model_editor/ModelEditorAPI.hpp` — that header is included everywhere. --- From 8a1cf1891d5f351ff6d8982185a0b9f74ef5db55 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 15:46:40 -0600 Subject: [PATCH 07/26] Fix copilot review comments --- .../instructions/pr-review.instructions.md | 27 +++++++ .github/prompts/update-docs.prompt.md | 10 +-- CMakeLists.txt | 5 ++ developer/doc/architecture.md | 18 ++--- .../doc/classes/openstudio_lib/OSAppBase.md | 2 + .../classes/shared_gui_components/BaseApp.md | 2 + .../OSVectorController.md | 6 +- developer/doc/libraries/bimserver.md | 4 +- developer/doc/libraries/openstudio_app.md | 5 +- developer/doc/libraries/openstudio_lib.md | 13 +--- .../doc/libraries/openstudio_qt_utils.md | 1 - developer/doc/libraries/qtwinmigrate.md | 71 ------------------- .../doc/libraries/shared_gui_components.md | 1 + developer/doc/libraries/utilities.md | 34 +++++---- src/model_editor/CMakeLists.txt | 2 +- src/openstudio_lib/CMakeLists.txt | 2 +- src/openstudio_qt_utils/CMakeLists.txt | 8 +-- src/openstudio_qt_utils/QMetaTypes.cpp | 24 +++---- src/shared_gui_components/CMakeLists.txt | 2 +- .../OSGridController.cpp | 4 +- src/utilities/CMakeLists.txt | 2 +- 21 files changed, 97 insertions(+), 146 deletions(-) create mode 100644 .github/instructions/pr-review.instructions.md rename developer/doc/classes/{openstudio_lib => shared_gui_components}/OSVectorController.md (93%) delete mode 100644 developer/doc/libraries/qtwinmigrate.md diff --git a/.github/instructions/pr-review.instructions.md b/.github/instructions/pr-review.instructions.md new file mode 100644 index 000000000..758be80e5 --- /dev/null +++ b/.github/instructions/pr-review.instructions.md @@ -0,0 +1,27 @@ +--- +description: "Use when reviewing pull requests, conducting code review, or checking a diff for correctness. Covers documentation accuracy checks for developer/doc/." +--- + +# Pull Request Review Guidelines + +## Documentation Accuracy Check + +On every pull request review, verify that `developer/doc/` documentation is consistent with the code changes: + +1. **Library docs** (`developer/doc/libraries/*.md`): If any `CMakeLists.txt` under `src/` changed (new dependencies, renamed targets, moved files), check the corresponding library doc for stale dependency tables, incorrect CMake target names, or missing/extra class entries. + +2. **Class docs** (`developer/doc/classes/**/*.md`): If a documented class's `.hpp` changed (new methods, changed signals/slots, updated inheritance), check that the class diagram, public API table, and Signals/Slots table still match the header. + +3. **Architecture overview** (`developer/doc/architecture.md`): If the top-level `CMakeLists.txt` or any module `CMakeLists.txt` changes the dependency graph, verify the Module Dependency Graph flowchart and Module Index table are still accurate. + +4. **Class moved between modules**: If a class moved from one `src/` subdirectory to another, check that: + - The class doc's `Module:` header and `Header:` path are updated + - The class doc's `Library doc:` backlink points to the new library + - The old library doc no longer lists the class in its Class Documentation index + - The new library doc adds the class to its Class Documentation index + +5. **Class deleted**: If a class is removed, its class doc should be deleted and its entry removed from the library doc index. + +6. **New class added**: If a new class matching the documentation heuristic (see `developer/doc/` prompt) is introduced, flag it for documentation. + +> For the full documentation maintenance procedure, see [`.github/prompts/update-docs.prompt.md`](../prompts/update-docs.prompt.md). diff --git a/.github/prompts/update-docs.prompt.md b/.github/prompts/update-docs.prompt.md index 1989c78b8..85dcd511e 100644 --- a/.github/prompts/update-docs.prompt.md +++ b/.github/prompts/update-docs.prompt.md @@ -37,10 +37,10 @@ developer/doc/ │ ├── openstudio_app.md ← src/openstudio_app/CMakeLists.txt + headers │ ├── openstudio_lib.md ← src/openstudio_lib/CMakeLists.txt + headers │ ├── shared_gui_components.md ← src/shared_gui_components/CMakeLists.txt + headers +│ ├── openstudio_qt_utils.md ← src/openstudio_qt_utils/CMakeLists.txt + headers │ ├── model_editor.md ← src/model_editor/CMakeLists.txt + headers │ ├── bimserver.md ← src/bimserver/CMakeLists.txt + headers -│ ├── utilities.md ← src/utilities/CMakeLists.txt -│ └── qtwinmigrate.md ← src/qtwinmigrate/CMakeLists.txt +│ └── utilities.md ← src/utilities/CMakeLists.txt ├── classes/ │ ├── openstudio_app/ │ │ ├── OpenStudioApp.md ← src/openstudio_app/OpenStudioApp.hpp/.cpp @@ -51,7 +51,6 @@ developer/doc/ │ │ ├── MainWindow.md ← src/openstudio_lib/MainWindow.hpp │ │ ├── MainTabController.md ← src/openstudio_lib/MainTabController.hpp │ │ ├── MainRightColumnController.md ← src/openstudio_lib/MainRightColumnController.hpp -│ │ ├── OSVectorController.md ← src/openstudio_lib/OSVectorController.hpp │ │ ├── OSItem.md ← src/openstudio_lib/OSItem.hpp │ │ ├── OSDropZone.md ← src/openstudio_lib/OSDropZone.hpp │ │ ├── HVACSystemsController.md ← src/openstudio_lib/HVACSystemsController.hpp @@ -71,6 +70,7 @@ developer/doc/ │ │ ├── BaseApp.md ← src/shared_gui_components/BaseApp.hpp │ │ ├── OSGridController.md ← src/shared_gui_components/OSGridController.hpp │ │ ├── OSGridView.md ← src/shared_gui_components/OSGridView.hpp +│ │ ├── OSVectorController.md ← src/shared_gui_components/OSVectorController.hpp │ │ ├── MeasureManager.md ← src/shared_gui_components/MeasureManager.hpp │ │ ├── BCLMeasureDialog.md ← src/shared_gui_components/BCLMeasureDialog.hpp │ │ ├── LocalLibraryController.md ← src/shared_gui_components/LocalLibraryController.hpp @@ -109,6 +109,7 @@ Update documentation when ANY of the following changes occur: | New class added matching library conventions (see §6) | Create new class `.md`; add entry to library `.md` | | Class deleted | Delete class `.md`; remove from library `.md` | | `CMakeLists.txt` in a module changes (new deps, new targets) | Corresponding library `.md` + `architecture.md` dependency graph | +| `src/openstudio_qt_utils/` file modified | `libraries/openstudio_qt_utils.md` + any affected class doc | | Top-level `CMakeLists.txt` changes (version, new sub-project) | `architecture.md` | | `.github/workflows/*.yml` changes | Corresponding `developer/doc/ci/workflows/*.md` + `ci/overview.md` | | New workflow added | Create new workflow `.md`; add entry to `ci/overview.md` | @@ -344,7 +345,7 @@ Follow these steps whenever source code or CI configuration changes: ## 7. Class Selection Heuristic **Document these classes** (already in the doc set or should be added when introduced): -- Base/abstract classes that define cross-cutting interfaces (`BaseApp`, `OSVectorController`, `OSItem`) +- Base/abstract classes that define cross-cutting interfaces (`BaseApp`, `OSVectorController` in `shared_gui_components`, `OSItem`) - Tab-level controllers that own a UI domain (`HVACSystemsController`, `RunTabController`) - View+Controller pairs for complex sub-systems (`HVACSystemsView`, `GeometryEditorController`) - Integration point classes that bridge external systems (`BIMserverConnection`, `OSWebEnginePage`) @@ -365,5 +366,6 @@ Never document the following in `developer/doc/` (they are internal plumbing or - Contents of `debug/` or `release/` build directories - Files under `signatures/` +- References to BIMserver as this functionality is to be deprecated - Generated files under `src/utilities/` (these are `configure_file` outputs) - Contents of `ruby/` Ruby gems or vendored external libraries diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a3719089..f8a7a1580 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Do not enable compiler specific extensions, for eg on GCC use -std=c++1z (=c++17) and not -std=gnu++17 set(CMAKE_CXX_EXTENSIONS OFF) +# All internal libraries are static. Qt is always linked dynamically via its own +# IMPORTED SHARED targets from find_package(Qt6) and is unaffected by this setting. +# This fulfils the Qt LGPL requirement: Qt shared libraries remain replaceable at runtime. +set(BUILD_SHARED_LIBS OFF) + # Use ccache if available, has to be before "project()" find_program(CCACHE_PROGRAM NAMES ccache sccache) if(CCACHE_PROGRAM) diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index db5477af7..07c40d030 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -64,15 +64,15 @@ C4Container title Containers — src/ Module Breakdown Container(app_exe, "OpenStudioApp", "Executable", "Entry point: main(), application lifecycle, startup screen, version translation") - Container(openstudio_lib, "openstudio_lib", "C++ shared library", "All tab controllers, views, HVAC/geometry/schedules/loads GUI. ~200 files. Target: openstudio_lib") - Container(shared_gui, "shared_gui_components", "C++ shared library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs, user settings. Target: openstudio_shared_gui") - Container(model_editor, "model_editor", "C++ shared library", "Generic IDD-driven model object inspector; AccessPolicyStore (field-level access policies for IDD objects). Target: openstudio_modeleditor") - Container(qt_utils, "openstudio_qt_utils", "C++ shared library", "Qt/OpenStudio primitives: string/UUID/path conversions, Application singleton, OSProgressBar, Qt metatype registration for SDK types. Target: openstudio_qt_utils") + Container(openstudio_lib, "openstudio_lib", "C++ static library", "All tab controllers, views, HVAC/geometry/schedules/loads GUI. ~200 files. Target: openstudio_lib") + Container(shared_gui, "shared_gui_components", "C++ static library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs, user settings. Target: openstudio_shared_gui") + Container(model_editor, "model_editor", "C++ static library", "Generic IDD-driven model object inspector; AccessPolicyStore (field-level access policies for IDD objects). Target: openstudio_modeleditor") + Container(qt_utils, "openstudio_qt_utils", "C++ static library", "Qt/OpenStudio primitives: string/UUID/path conversions, Application singleton, OSProgressBar, Qt metatype registration for SDK types. Target: openstudio_qt_utils") Container(utilities, "utilities", "C++ static/header library", "Runtime path resolution for SDK CLI, EnergyPlus, Radiance. Target: openstudioapp_utilities") Rel(app_exe, openstudio_lib, "Links; creates OSDocument and MainWindow") Rel(openstudio_lib, shared_gui, "Links; uses grid widgets, form controls, measure integration") - Rel(openstudio_lib, model_editor, "Links; uses InspectorGadget, QMetaTypes") + Rel(openstudio_lib, model_editor, "Links; uses InspectorGadget, AccessPolicyStore") Rel(shared_gui, qt_utils, "Links; Qt string/UUID conversions, Application singleton, metatype registration") Rel(model_editor, qt_utils, "Links; Qt string/UUID conversions, Application singleton, OSProgressBar") Rel(qt_utils, utilities, "Links; runtime path resolution for SDK CLI, EnergyPlus, Radiance") @@ -162,10 +162,10 @@ See [BUILDING.md](../../BUILDING.md) for the complete, platform-specific instruc | Target | Type | Description | |---|---|---| | `OpenStudioApp` | Executable | Main application binary | -| `openstudio_lib` | Shared library | Tab GUI library | -| `openstudio_shared_gui` | Shared library | Reusable widget library | -| `openstudio_modeleditor` | Shared library | Generic IDD-driven model inspector | -| `openstudio_qt_utils` | Shared library | Qt/OpenStudio primitives: string/UUID/path conversions, `Application` singleton, `OSProgressBar`, Qt metatype registration for SDK types | +| `openstudio_lib` | Static library | Tab GUI library | +| `openstudio_shared_gui` | Static library | Reusable widget library | +| `openstudio_modeleditor` | Static library | Generic IDD-driven model inspector | +| `openstudio_qt_utils` | Static library | Qt/OpenStudio primitives: string/UUID/path conversions, `Application` singleton, `OSProgressBar`, Qt metatype registration for SDK types | | `openstudioapp_utilities` | Static library | Runtime path helpers | | `package` | CPack | Platform installer (`.exe`/`.dmg`/`.deb`/`.tar.gz`) | diff --git a/developer/doc/classes/openstudio_lib/OSAppBase.md b/developer/doc/classes/openstudio_lib/OSAppBase.md index b91d299c1..8103c9fa6 100644 --- a/developer/doc/classes/openstudio_lib/OSAppBase.md +++ b/developer/doc/classes/openstudio_lib/OSAppBase.md @@ -39,6 +39,7 @@ classDiagram +updateMyMeasures() +updateBCLMeasures() +openBclDlg() + +mouseOverInspectorView() bool +notify(receiver, event) bool slots: addWorkspaceObject, removeWorkspaceObject signals: workspaceObjectAdded, workspaceObjectRemoved @@ -75,6 +76,7 @@ classDiagram | `tempDir()` | `optional` | Returns the path to a per-session temporary directory | | `currentModel()` | `optional` | Returns the model from the current document, if one is open | | `waitDialog()` | `shared_ptr` | Returns the shared "please wait" modal dialog | +| `mouseOverInspectorView()` | `bool` | Returns whether the mouse cursor is over the inspector view; used by `OSLineEdit2::focusOutEvent` to decide whether to keep focus | | `dviewPath()` | `openstudio::path` | Returns the path to the DView results viewer | | `notify(receiver, event)` | `bool` | Override of `QApplication::notify` — catches and logs C++ exceptions thrown inside Qt event handlers | diff --git a/developer/doc/classes/shared_gui_components/BaseApp.md b/developer/doc/classes/shared_gui_components/BaseApp.md index c3ee238b7..9b2d6e54f 100644 --- a/developer/doc/classes/shared_gui_components/BaseApp.md +++ b/developer/doc/classes/shared_gui_components/BaseApp.md @@ -31,6 +31,7 @@ classDiagram +editController() QSharedPointer~EditController~ = 0 +tempDir() optional~path~ = 0 +currentModel() optional~Model~ = 0 + +mouseOverInspectorView() bool = 0 } class OSAppBase { +mainWidget() QWidget* @@ -61,3 +62,4 @@ classDiagram | `editController()` | `QSharedPointer` | The right-column edit controller | | `tempDir()` | `optional` | Path to the session temporary directory | | `currentModel()` | `optional` | The current model, if any | +| `mouseOverInspectorView()` | `bool` | Returns whether the mouse cursor is currently over the inspector view in the right column | diff --git a/developer/doc/classes/openstudio_lib/OSVectorController.md b/developer/doc/classes/shared_gui_components/OSVectorController.md similarity index 93% rename from developer/doc/classes/openstudio_lib/OSVectorController.md rename to developer/doc/classes/shared_gui_components/OSVectorController.md index b88085a27..7a9a7e8ae 100644 --- a/developer/doc/classes/openstudio_lib/OSVectorController.md +++ b/developer/doc/classes/shared_gui_components/OSVectorController.md @@ -1,8 +1,8 @@ # Class: `OSVectorController` -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSVectorController.hpp](../../../../src/openstudio_lib/OSVectorController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) +> **Module:** `shared_gui_components` +> **Header:** [src/shared_gui_components/OSVectorController.hpp](../../../../src/shared_gui_components/OSVectorController.hpp) +> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) ## Purpose diff --git a/developer/doc/libraries/bimserver.md b/developer/doc/libraries/bimserver.md index db48acf8a..8e81dfca5 100644 --- a/developer/doc/libraries/bimserver.md +++ b/developer/doc/libraries/bimserver.md @@ -113,9 +113,7 @@ Blocking variants spin a `QEventLoop` with a `QTimer` for the timeout, making th | Module | Usage | |---|---| -| `model_editor` | `QMetaTypes` registration, base types | -| `openstudio_lib` | Links to `openstudio::openstudiolib` for SDK access | -| `qtwinmigrate` (Win32 only) | MFC/Qt bridge for SketchUp plugin | +| `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration) | --- diff --git a/developer/doc/libraries/openstudio_app.md b/developer/doc/libraries/openstudio_app.md index 8e6e1482f..fa16dde39 100644 --- a/developer/doc/libraries/openstudio_app.md +++ b/developer/doc/libraries/openstudio_app.md @@ -76,9 +76,8 @@ classDiagram | Module | Usage | |---|---| -| `openstudio_lib` | `OSAppBase`, `OSDocument`, `MainWindow` — instantiated here | -| `shared_gui_components` | `BusyWidget`, `OSDialog`, `WaitDialog` — directly compiled into this target | -| `model_editor` | `QMetaTypes` registration for Qt signal/slot compatibility | +| `openstudio_lib` | `OSAppBase`, `OSDocument`, `MainWindow` — instantiated here; transitively pulls in `shared_gui_components`, `model_editor`, and `openstudio_qt_utils` | +| `openstudio_bimserver` | BIMserver import/export integration | --- diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index 8b3568d1c..3257a79f8 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -51,15 +51,6 @@ classDiagram +chooseLibraryTab() +chooseEditTab() } - class OSVectorController { - <> - +reportItems() - +removeItem(OSItem*) - +drop(OSItemId) - +makeNewItem() - signals: itemIds, selectedItemId - } - OSAppBase "1" *-- "0..1" OSDocument : manages current OSDocument "1" *-- "1" MainWindow : owns OSDocument "1" *-- "1" MainTabController : owns active @@ -70,8 +61,6 @@ classDiagram MainTabController <|-- SpaceTypesTabController MainTabController <|-- FacilityTabController MainTabController <|-- RunTabController - OSVectorController <|-- ConstructionObjectVectorController - OSVectorController <|-- DefaultConstructionSetsController ``` --- @@ -144,7 +133,7 @@ classDiagram - **MVC triad** — every domain has a `*TabController`, a `*TabView`, and one or more `*InspectorView` classes. - **`OSQObjectController`** — `OSDocument` and most controllers extend `OSQObjectController`, which provides a thread-safe `QObject` parent management pattern. -- **`OPENSTUIDO_API` macro** — applied to classes exported from `openstudio_lib.dll` on Windows. +- **Static linking** — all internal libraries are built `STATIC`; no DLL export macros are needed. - **Analytics** — `AnalyticsHelper` sends anonymized usage pings (configurable via `ANALYTICS_API_SECRET`/`ANALYTICS_MEASUREMENT_ID` build-time secrets). --- diff --git a/developer/doc/libraries/openstudio_qt_utils.md b/developer/doc/libraries/openstudio_qt_utils.md index 4354bf479..6f36c904c 100644 --- a/developer/doc/libraries/openstudio_qt_utils.md +++ b/developer/doc/libraries/openstudio_qt_utils.md @@ -51,7 +51,6 @@ classDiagram | File | Description | |---|---| -| `OpenStudioQtUtilsAPI.hpp` | DLL export macro (`OPENSTUDIOQTUTILS_API`) for Windows shared library symbol visibility | | `Application.hpp/cpp` | `openstudio::Application` singleton — `QApplication` lifecycle management and `QSettings` read/write | | `Utilities.hpp/cpp` | Free functions for converting between `QString`, `std::string`, `std::wstring`, `openstudio::path`, and `openstudio::UUID` | | `QMetaTypes.hpp/cpp` | `Q_DECLARE_METATYPE` declarations and `qRegisterMetaType` calls for SDK types used in queued signal/slot connections | diff --git a/developer/doc/libraries/qtwinmigrate.md b/developer/doc/libraries/qtwinmigrate.md deleted file mode 100644 index 96caea611..000000000 --- a/developer/doc/libraries/qtwinmigrate.md +++ /dev/null @@ -1,71 +0,0 @@ -# Library: `qtwinmigrate` — Windows MFC/Qt Bridge - -> **Source:** `src/qtwinmigrate/` -> **CMake target:** `qtwinmigrate` (Windows only) -> **Back to:** [Architecture Overview](../architecture.md) - -## Purpose - -`qtwinmigrate` is a third-party compatibility library (originally from Qt Solutions) that enables Qt widgets to be embedded inside a Win32 or MFC (Microsoft Foundation Class) application window. It is used specifically to host the OpenStudio GUI inside the SketchUp plugin on Windows, where SketchUp provides a native Win32 host window. - -This module is **compiled only on Windows** (`if(WIN32)` in CMake). It has no effect on macOS or Linux builds. - ---- - -## Key Classes - -```mermaid -classDiagram - class QMfcApp { - <> - +pluginInstance(instance) bool - +run(instance) int - +translate(msg) bool - } - class QWinHost { - <> - +QWinHost(parent, flags) - +createWindow(parent, instance) HWND - +window() HWND - } - class QWinWidget { - <> - +QWinWidget(hParentWnd, parent, flags) - +childWindow() HWND - +show() - +move(x, y) - } - - QMfcApp .. QWinWidget : used together - QWinHost <.. QWinWidget : related pattern -``` - -| Class | File | Description | -|---|---|---| -| `QMfcApp` | [QMfcApp/qmfcapp.h](../../../src/qtwinmigrate/QMfcApp/qmfcapp.h) | Bridges the Qt event loop with an MFC `CWinApp`. Allows Qt to be initialised as a plugin within an existing MFC process. | -| `QWinHost` | [QWinHost/qwinhost.h](../../../src/qtwinmigrate/QWinHost/qwinhost.h) | A `QWidget` subclass that hosts an arbitrary Win32 `HWND` child window inside a Qt widget hierarchy. | -| `QWinWidget` | [QWinWidget/qwinwidget.h](../../../src/qtwinmigrate/QWinWidget/qwinwidget.h) | A `QWidget` that is itself a child of a native `HWND`, allowing Qt widgets to be embedded inside a non-Qt Win32 parent window. | - ---- - -## External Dependencies - -| Dependency | Usage | -|---|---| -| **Qt 6** (`QtWidgets`, `QtCore`) | Qt event loop and widget hierarchy integration | -| **Win32 API** (`windows.h`, `commctrl.h`) | Native window handles (`HWND`), message translation | -| **MFC** (optional, link-time) | `QMfcApp` integration with `CWinApp` (only needed for MFC hosts) | - ---- - -## Internal Dependencies - -None. - ---- - -## Patterns & Conventions - -- **Plugin pattern** — `QMfcApp::pluginInstance()` is the entry point for Qt-as-plugin use. It initialises Qt without creating a new `QApplication` (since one already exists in the host process). -- **Message translation** — `QMfcApp::translate()` must be called from the host's message loop to forward Windows messages to Qt's event dispatcher. -- **Not used in standalone app** — in the standalone `OpenStudioApp` executable, none of these classes are instantiated. They exist in the compiled binary only because the `openstudio_bimserver` target links `qtwinmigrate` on Windows. diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 954958a11..36276dbeb 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -172,6 +172,7 @@ flowchart TD - [BaseApp](../classes/shared_gui_components/BaseApp.md) - [OSGridController](../classes/shared_gui_components/OSGridController.md) - [OSGridView](../classes/shared_gui_components/OSGridView.md) +- [OSVectorController](../classes/shared_gui_components/OSVectorController.md) - [MeasureManager](../classes/shared_gui_components/MeasureManager.md) - [BCLMeasureDialog](../classes/shared_gui_components/BCLMeasureDialog.md) - [LocalLibraryController](../classes/shared_gui_components/LocalLibraryController.md) diff --git a/developer/doc/libraries/utilities.md b/developer/doc/libraries/utilities.md index 2e7adfe7e..c5f557c73 100644 --- a/developer/doc/libraries/utilities.md +++ b/developer/doc/libraries/utilities.md @@ -16,9 +16,8 @@ Because the application is packaged differently on each platform (macOS bundle, | File | Description | |---|---| -| `OpenStudioApplicationPathHelpers.hpp` | Public API — declares free functions for locating SDK CLI, EnergyPlus, Radiance, and resource paths | +| `OpenStudioApplicationPathHelpers.hpp` | Declares free functions for application version strings and runtime path resolution; no DLL export macro (static library) | | `OpenStudioApplicationPathHelpers.cxx.in` | CMake template — `configure_file` substitutes the actual install-time paths at build time, producing `OpenStudioApplicationPathHelpers.cxx` | -| `OpenStudioApplicationUtilitiesAPI.hpp` | DLL export macro (`OPENSDTUDIOAPPLICATIONUTILITIES_API`) for Windows shared library symbol visibility | --- @@ -26,21 +25,26 @@ Because the application is packaged differently on each platform (macOS bundle, ```cpp namespace openstudio { - // Returns the path to the OpenStudio CLI executable - path getOpenStudioCoreCLI(); - - // Returns the path to the application's shared resources directory - path getOpenStudioApplicationSourceDirectory(); - - // Returns the path to the EnergyPlus executable (from SDK install layout) - boost::optional findEnergyPlus(); - - // Returns the path to the Radiance installation (from SDK install layout) - boost::optional findRadiance(); + // Version strings + std::string openStudioApplicationVersion(); // MAJOR.MINOR.PATCH[-prerelease+sha] + std::string openStudioApplicationVersionWithPrerelease(); // MAJOR.MINOR.PATCH[-prerelease] + + // Path resolution + path getOpenStudioApplicationPath(); // Path to the running executable + path getOpenStudioApplicationDirectory(); // Directory containing the executable + path getOpenStudioApplicationSourceDirectory(); // Resources/source directory (build or install) + path getOpenStudioApplicationBuildDirectory(); // Build directory (empty in installed builds) + path getOpenStudioApplicationModule(); // Path to the OpenStudio SDK shared library + path getOpenStudioApplicationModuleDirectory(); // Directory of the SDK shared library + path getOpenStudioCoreCLI(); // Path to the OpenStudio CLI executable + + // Build-tree detection + bool isOpenStudioApplicationRunningFromBuildDirectory(); + bool isOpenStudioApplicationModuleRunningFromBuildDirectory(); } ``` -Paths are resolved relative to the running executable (`QCoreApplication::applicationDirPath()`), making them work correctly whether the app is run from a development build tree or an installed package. +All path functions resolve relative to the running executable, so they work correctly in both development build trees and installed packages on all platforms. --- @@ -62,4 +66,4 @@ None — this is the lowest-dependency module in the application. ## Patterns & Conventions - **CMake `configure_file`** — the `.cxx.in` file contains `@VARIABLE@` placeholders that CMake fills in at configure time based on install prefix, SDK path, and platform. This is how install-time paths are baked in without hardcoding. -- **`boost::optional` returns** — EnergyPlus and Radiance are optional; functions return `boost::none` if the expected path does not exist on disk, allowing callers to gracefully degrade. +- **No DLL export macro** — the target is explicitly `STATIC`; all symbols are directly linked into the executable and require no `__declspec(dllexport)` decoration. diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index 71d43da8e..61b7c3df7 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -68,7 +68,7 @@ qt6_wrap_cpp(${target_name}_mocs ${${target_name}_moc}) qt6_add_resources(${target_name}_qrcs ${${target_name}_qrc}) # make the shared library -add_library(${target_name} +add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_moc} ${${target_name}_mocs} diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 0af6bbdd8..fa7b167b8 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -602,7 +602,7 @@ qt6_add_resources(${target_name}_qrcs ${${target_name}_qrc}) # add_custom_target(resources DEPENDS ${target_name}_qrcs) # add_dependencies(resources translations) -add_library(${target_name} +add_library(${target_name} STATIC ${${target_name}_SRC} ${${target_name}_moc_src} ${${target_name}_moc} diff --git a/src/openstudio_qt_utils/CMakeLists.txt b/src/openstudio_qt_utils/CMakeLists.txt index fe2e386a5..33f8428b5 100644 --- a/src/openstudio_qt_utils/CMakeLists.txt +++ b/src/openstudio_qt_utils/CMakeLists.txt @@ -15,7 +15,7 @@ set(${target_name}_src Utilities.cpp ) -add_library(${target_name} ${${target_name}_src}) +add_library(${target_name} STATIC ${${target_name}_src}) set(${target_name}_depends openstudioapp_utilities @@ -25,10 +25,4 @@ set(${target_name}_depends add_dependencies(${target_name} ${${target_name}_depends}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) -if(BUILD_SHARED_LIBS) - #target_compile_definitions(${target_name} PUBLIC openstudio_qt_utils_EXPORTS) -else() - target_compile_definitions(${target_name} PUBLIC openstudio_qt_utils_EXPORTS) -endif() - CREATE_SRC_GROUPS("${${target_name}_src}") diff --git a/src/openstudio_qt_utils/QMetaTypes.cpp b/src/openstudio_qt_utils/QMetaTypes.cpp index 70e68087b..714d3be25 100644 --- a/src/openstudio_qt_utils/QMetaTypes.cpp +++ b/src/openstudio_qt_utils/QMetaTypes.cpp @@ -11,23 +11,23 @@ namespace detail { // Note JM 2018-12-19: `Q_DECLARE_METATYPE` is enough to use a type inside a QVariant, but qRegisterMetaType is needed to use the type in // *queued* signals/slots and to dynamically create objects of these types at runtime -int __iddobjectype_type = qRegisterMetaType("openstudio::IddObjectType"); -int __iddfiletype_type = qRegisterMetaType("openstudio::IddFileType"); +[[maybe_unused]] int __iddobjectype_type = qRegisterMetaType("openstudio::IddObjectType"); +[[maybe_unused]] int __iddfiletype_type = qRegisterMetaType("openstudio::IddFileType"); -int __uuid_type = qRegisterMetaType("openstudio::UUID"); +[[maybe_unused]] int __uuid_type = qRegisterMetaType("openstudio::UUID"); -int __string_type = qRegisterMetaType("std::string"); -int __string_vector_type = qRegisterMetaType>("std::vector"); +[[maybe_unused]] int __string_type = qRegisterMetaType("std::string"); +[[maybe_unused]] int __string_vector_type = qRegisterMetaType>("std::vector"); -int __optional_double_type = qRegisterMetaType>("boost::optional"); -int __optional_unsigned_type = qRegisterMetaType>("boost::optional"); -int __optional_int_type = qRegisterMetaType>("boost::optional"); -int __optional_string_type = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int __optional_double_type = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int __optional_unsigned_type = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int __optional_int_type = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int __optional_string_type = qRegisterMetaType>("boost::optional"); -int __quantity_type = qRegisterMetaType("openstudio::Quantity"); -int __optionalquantity_type = qRegisterMetaType("openstudio::OSOptionalQuantity"); +[[maybe_unused]] int __quantity_type = qRegisterMetaType("openstudio::Quantity"); +[[maybe_unused]] int __optionalquantity_type = qRegisterMetaType("openstudio::OSOptionalQuantity"); -int __workspaceobject_type = qRegisterMetaType>(); +[[maybe_unused]] int __workspaceobject_type = qRegisterMetaType>(); } // namespace detail } // namespace openstudio diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index 9db3e2e5a..e41da293a 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -182,7 +182,7 @@ set(${target_name}_depends openstudio_qt_utils ) -add_library(${target_name} ${${target_name}_src} ${${target_name}_moc_src}) +add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_moc_src}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index 4d3dedff6..b09cc9d81 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -8,8 +8,8 @@ // Register OSItemId metatypes for queued signal/slot connections. // Q_DECLARE_METATYPE is in OSGridController.hpp; qRegisterMetaType must run at startup. namespace { -const int __ositemid_type = qRegisterMetaType("OSItemId"); -const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); +[[maybe_unused]] const int __ositemid_type = qRegisterMetaType("OSItemId"); +[[maybe_unused]] const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); } // namespace #include "OSCellWrapper.hpp" diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index 7c6c14e96..e49fb0fa3 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -22,7 +22,7 @@ set(${target_name}_depends boost::boost ) -add_library(${target_name} +add_library(${target_name} STATIC ${${target_name}_src} ) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends} ) From f94ed1cf558c9fc507d72d1e6c00f06f7e4cf6d0 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 18:30:02 -0600 Subject: [PATCH 08/26] Remove all SWIG files Move class level documentation to comments in the classes --- .../instructions/pr-review.instructions.md | 27 +- .github/prompts/update-docs.prompt.md | 223 ++++---------- .github/workflows/app_build.yml | 18 ++ .github/workflows/check_osm_versions.yml | 6 + .github/workflows/cla.yml | 8 +- .github/workflows/clangformat.yml | 5 + .github/workflows/cppcheck.yml | 5 + .github/workflows/export_standards_data.yml | 9 +- .github/workflows/manual_cli_test.yml | 4 + .github/workflows/release_notes.yml | 4 + CMakeLists.txt | 3 - ci/clang-format.sh | 5 +- ci/install_script_qtifw.qs | 6 + conanfile.py | 1 - developer/doc/ci/jenkins.md | 60 ---- developer/doc/ci/overview.md | 138 --------- developer/doc/ci/scripts.md | 143 --------- developer/doc/ci/workflows/app_build.md | 139 --------- .../doc/ci/workflows/check_osm_versions.md | 64 ---- developer/doc/ci/workflows/cla.md | 65 ---- developer/doc/ci/workflows/clangformat.md | 77 ----- developer/doc/ci/workflows/cppcheck.md | 85 ------ .../doc/ci/workflows/export_standards_data.md | 82 ------ developer/doc/ci/workflows/manual_cli_test.md | 92 ------ developer/doc/ci/workflows/release_notes.md | 76 ----- .../classes/bimserver/BIMserverConnection.md | 111 ------- .../doc/classes/bimserver/ProjectImporter.md | 100 ------- .../classes/model_editor/AccessPolicyStore.md | 69 ----- .../classes/model_editor/InspectorDialog.md | 72 ----- .../classes/model_editor/InspectorGadget.md | 96 ------ .../classes/openstudio_app/OpenStudioApp.md | 115 -------- .../doc/classes/openstudio_app/StartupView.md | 60 ---- .../openstudio_lib/ConstructionsController.md | 61 ---- .../GeometryEditorController.md | 85 ------ .../openstudio_lib/HVACSystemsController.md | 124 -------- .../classes/openstudio_lib/HVACSystemsView.md | 60 ---- .../openstudio_lib/InspectorController.md | 66 ----- .../MainRightColumnController.md | 111 ------- .../openstudio_lib/MainTabController.md | 105 ------- .../doc/classes/openstudio_lib/MainWindow.md | 109 ------- .../openstudio_lib/MaterialsController.md | 50 ---- .../openstudio_lib/ModelObjectListView.md | 74 ----- .../doc/classes/openstudio_lib/OSAppBase.md | 112 ------- .../doc/classes/openstudio_lib/OSDocument.md | 116 -------- .../doc/classes/openstudio_lib/OSDropZone.md | 96 ------ .../doc/classes/openstudio_lib/OSItem.md | 109 ------- .../classes/openstudio_lib/OSWebEnginePage.md | 87 ------ .../openstudio_lib/ResultsTabController.md | 57 ---- .../openstudio_lib/RunTabController.md | 76 ----- .../openstudio_lib/SchedulesController.md | 66 ----- .../openstudio_lib/SpaceTypesController.md | 54 ---- .../openstudio_lib/ThermalZonesController.md | 46 --- .../shared_gui_components/BCLMeasureDialog.md | 60 ---- .../classes/shared_gui_components/BaseApp.md | 65 ---- .../BuildingComponentDialog.md | 63 ---- .../LocalLibraryController.md | 93 ------ .../shared_gui_components/MeasureManager.md | 92 ------ .../shared_gui_components/OSGridController.md | 100 ------- .../shared_gui_components/OSGridView.md | 73 ----- .../OSVectorController.md | 111 ------- developer/doc/libraries/bimserver.md | 5 +- developer/doc/libraries/model_editor.md | 6 +- developer/doc/libraries/openstudio_app.md | 5 +- developer/doc/libraries/openstudio_lib.md | 26 +- .../doc/libraries/shared_gui_components.md | 13 +- src/bimserver/BIMServer.i | 32 -- src/bimserver/BIMserverConnection.hpp | 6 +- src/bimserver/CMakeLists.txt | 5 - src/model_editor/InspectorDialog.hpp | 5 + src/model_editor/ModelEditor.i | 48 --- src/model_editor/Qt.i | 278 ------------------ src/openstudio_app/OpenStudioApp.hpp | 5 + src/openstudio_app/StartupView.hpp | 5 + .../ConstructionsController.hpp | 5 + .../GeometryEditorController.hpp | 5 + src/openstudio_lib/HVACSystemsController.hpp | 5 + src/openstudio_lib/HVACSystemsView.hpp | 6 + src/openstudio_lib/InspectorController.hpp | 5 + .../MainRightColumnController.hpp | 6 + src/openstudio_lib/MainTabController.hpp | 5 + src/openstudio_lib/MainWindow.hpp | 5 + src/openstudio_lib/MaterialsController.hpp | 5 + src/openstudio_lib/ModelObjectListView.hpp | 5 + src/openstudio_lib/OSAppBase.hpp | 5 + src/openstudio_lib/OSDocument.hpp | 6 + src/openstudio_lib/OSDropZone.hpp | 6 + src/openstudio_lib/OSItem.hpp | 5 + src/openstudio_lib/OSWebEnginePage.hpp | 5 + src/openstudio_lib/ResultsTabController.hpp | 5 + src/openstudio_lib/RunTabController.hpp | 5 + src/openstudio_lib/SpaceTypesController.hpp | 6 + src/openstudio_lib/ThermalZonesController.hpp | 6 + src/openstudio_qt_utils/QMetaTypes.cpp | 24 +- .../BCLMeasureDialog.hpp | 5 + src/shared_gui_components/BaseApp.hpp | 6 + .../BuildingComponentDialog.hpp | 6 + .../LocalLibraryController.hpp | 7 + .../OSGridController.cpp | 6 +- .../OSGridController.hpp | 11 +- src/shared_gui_components/OSGridView.hpp | 7 + src/shared_gui_components/OSItemId.hpp | 4 + .../OSVectorController.hpp | 7 + 102 files changed, 325 insertions(+), 4587 deletions(-) delete mode 100644 developer/doc/ci/jenkins.md delete mode 100644 developer/doc/ci/overview.md delete mode 100644 developer/doc/ci/scripts.md delete mode 100644 developer/doc/ci/workflows/app_build.md delete mode 100644 developer/doc/ci/workflows/check_osm_versions.md delete mode 100644 developer/doc/ci/workflows/cla.md delete mode 100644 developer/doc/ci/workflows/clangformat.md delete mode 100644 developer/doc/ci/workflows/cppcheck.md delete mode 100644 developer/doc/ci/workflows/export_standards_data.md delete mode 100644 developer/doc/ci/workflows/manual_cli_test.md delete mode 100644 developer/doc/ci/workflows/release_notes.md delete mode 100644 developer/doc/classes/bimserver/BIMserverConnection.md delete mode 100644 developer/doc/classes/bimserver/ProjectImporter.md delete mode 100644 developer/doc/classes/model_editor/AccessPolicyStore.md delete mode 100644 developer/doc/classes/model_editor/InspectorDialog.md delete mode 100644 developer/doc/classes/model_editor/InspectorGadget.md delete mode 100644 developer/doc/classes/openstudio_app/OpenStudioApp.md delete mode 100644 developer/doc/classes/openstudio_app/StartupView.md delete mode 100644 developer/doc/classes/openstudio_lib/ConstructionsController.md delete mode 100644 developer/doc/classes/openstudio_lib/GeometryEditorController.md delete mode 100644 developer/doc/classes/openstudio_lib/HVACSystemsController.md delete mode 100644 developer/doc/classes/openstudio_lib/HVACSystemsView.md delete mode 100644 developer/doc/classes/openstudio_lib/InspectorController.md delete mode 100644 developer/doc/classes/openstudio_lib/MainRightColumnController.md delete mode 100644 developer/doc/classes/openstudio_lib/MainTabController.md delete mode 100644 developer/doc/classes/openstudio_lib/MainWindow.md delete mode 100644 developer/doc/classes/openstudio_lib/MaterialsController.md delete mode 100644 developer/doc/classes/openstudio_lib/ModelObjectListView.md delete mode 100644 developer/doc/classes/openstudio_lib/OSAppBase.md delete mode 100644 developer/doc/classes/openstudio_lib/OSDocument.md delete mode 100644 developer/doc/classes/openstudio_lib/OSDropZone.md delete mode 100644 developer/doc/classes/openstudio_lib/OSItem.md delete mode 100644 developer/doc/classes/openstudio_lib/OSWebEnginePage.md delete mode 100644 developer/doc/classes/openstudio_lib/ResultsTabController.md delete mode 100644 developer/doc/classes/openstudio_lib/RunTabController.md delete mode 100644 developer/doc/classes/openstudio_lib/SchedulesController.md delete mode 100644 developer/doc/classes/openstudio_lib/SpaceTypesController.md delete mode 100644 developer/doc/classes/openstudio_lib/ThermalZonesController.md delete mode 100644 developer/doc/classes/shared_gui_components/BCLMeasureDialog.md delete mode 100644 developer/doc/classes/shared_gui_components/BaseApp.md delete mode 100644 developer/doc/classes/shared_gui_components/BuildingComponentDialog.md delete mode 100644 developer/doc/classes/shared_gui_components/LocalLibraryController.md delete mode 100644 developer/doc/classes/shared_gui_components/MeasureManager.md delete mode 100644 developer/doc/classes/shared_gui_components/OSGridController.md delete mode 100644 developer/doc/classes/shared_gui_components/OSGridView.md delete mode 100644 developer/doc/classes/shared_gui_components/OSVectorController.md delete mode 100644 src/bimserver/BIMServer.i delete mode 100644 src/model_editor/ModelEditor.i delete mode 100644 src/model_editor/Qt.i diff --git a/.github/instructions/pr-review.instructions.md b/.github/instructions/pr-review.instructions.md index 758be80e5..bf678b183 100644 --- a/.github/instructions/pr-review.instructions.md +++ b/.github/instructions/pr-review.instructions.md @@ -4,24 +4,15 @@ description: "Use when reviewing pull requests, conducting code review, or check # Pull Request Review Guidelines -## Documentation Accuracy Check +On every PR review, verify documentation and comments are consistent with the code changes: -On every pull request review, verify that `developer/doc/` documentation is consistent with the code changes: +**`developer/doc/` docs** +- `CMakeLists.txt` changed → check the corresponding `libraries/*.md` for stale dependency tables or target names; check `architecture.md` dependency graph. +- Class added/moved/deleted → check library doc's Key Classes section is accurate and the header has a `/** */` doc comment. -1. **Library docs** (`developer/doc/libraries/*.md`): If any `CMakeLists.txt` under `src/` changed (new dependencies, renamed targets, moved files), check the corresponding library doc for stale dependency tables, incorrect CMake target names, or missing/extra class entries. +**Inline comments** +- Significant class added or refactored (`src/**/*.hpp`) → `/** */` comment above the class must exist, describe current responsibility, and contain no stale references. +- Workflow added or modified (`.github/workflows/*.yml`) → `#` comment block at top must accurately reflect purpose, triggers, and required secrets. +- CI script added or modified (`ci/*.sh`, `ci/*.py`, `ci/*.qs`) → header comment must accurately describe usage, arguments, and exit codes. -2. **Class docs** (`developer/doc/classes/**/*.md`): If a documented class's `.hpp` changed (new methods, changed signals/slots, updated inheritance), check that the class diagram, public API table, and Signals/Slots table still match the header. - -3. **Architecture overview** (`developer/doc/architecture.md`): If the top-level `CMakeLists.txt` or any module `CMakeLists.txt` changes the dependency graph, verify the Module Dependency Graph flowchart and Module Index table are still accurate. - -4. **Class moved between modules**: If a class moved from one `src/` subdirectory to another, check that: - - The class doc's `Module:` header and `Header:` path are updated - - The class doc's `Library doc:` backlink points to the new library - - The old library doc no longer lists the class in its Class Documentation index - - The new library doc adds the class to its Class Documentation index - -5. **Class deleted**: If a class is removed, its class doc should be deleted and its entry removed from the library doc index. - -6. **New class added**: If a new class matching the documentation heuristic (see `developer/doc/` prompt) is introduced, flag it for documentation. - -> For the full documentation maintenance procedure, see [`.github/prompts/update-docs.prompt.md`](../prompts/update-docs.prompt.md). +> Full standards: [`.github/prompts/update-docs.prompt.md`](../prompts/update-docs.prompt.md) diff --git a/.github/prompts/update-docs.prompt.md b/.github/prompts/update-docs.prompt.md index 85dcd511e..99087e49f 100644 --- a/.github/prompts/update-docs.prompt.md +++ b/.github/prompts/update-docs.prompt.md @@ -41,60 +41,6 @@ developer/doc/ │ ├── model_editor.md ← src/model_editor/CMakeLists.txt + headers │ ├── bimserver.md ← src/bimserver/CMakeLists.txt + headers │ └── utilities.md ← src/utilities/CMakeLists.txt -├── classes/ -│ ├── openstudio_app/ -│ │ ├── OpenStudioApp.md ← src/openstudio_app/OpenStudioApp.hpp/.cpp -│ │ └── StartupView.md ← src/openstudio_app/StartupView.hpp/.cpp -│ ├── openstudio_lib/ -│ │ ├── OSAppBase.md ← src/openstudio_lib/OSAppBase.hpp -│ │ ├── OSDocument.md ← src/openstudio_lib/OSDocument.hpp -│ │ ├── MainWindow.md ← src/openstudio_lib/MainWindow.hpp -│ │ ├── MainTabController.md ← src/openstudio_lib/MainTabController.hpp -│ │ ├── MainRightColumnController.md ← src/openstudio_lib/MainRightColumnController.hpp -│ │ ├── OSItem.md ← src/openstudio_lib/OSItem.hpp -│ │ ├── OSDropZone.md ← src/openstudio_lib/OSDropZone.hpp -│ │ ├── HVACSystemsController.md ← src/openstudio_lib/HVACSystemsController.hpp -│ │ ├── HVACSystemsView.md ← src/openstudio_lib/HVACSystemsView.hpp -│ │ ├── GeometryEditorController.md ← src/openstudio_lib/GeometryEditorController.hpp -│ │ ├── ConstructionsController.md ← src/openstudio_lib/ConstructionsController.hpp -│ │ ├── MaterialsController.md ← src/openstudio_lib/MaterialsController.hpp -│ │ ├── SchedulesController.md ← src/openstudio_lib/SchedulesController.hpp -│ │ ├── SpaceTypesController.md ← src/openstudio_lib/SpaceTypesController.hpp -│ │ ├── ThermalZonesController.md ← src/openstudio_lib/ThermalZonesController.hpp -│ │ ├── RunTabController.md ← src/openstudio_lib/RunTabController.hpp -│ │ ├── ResultsTabController.md ← src/openstudio_lib/ResultsTabController.hpp -│ │ ├── OSWebEnginePage.md ← src/openstudio_lib/OSWebEnginePage.hpp -│ │ ├── InspectorController.md ← src/openstudio_lib/InspectorController.hpp -│ │ └── ModelObjectListView.md ← src/openstudio_lib/ModelObjectListView.hpp -│ ├── shared_gui_components/ -│ │ ├── BaseApp.md ← src/shared_gui_components/BaseApp.hpp -│ │ ├── OSGridController.md ← src/shared_gui_components/OSGridController.hpp -│ │ ├── OSGridView.md ← src/shared_gui_components/OSGridView.hpp -│ │ ├── OSVectorController.md ← src/shared_gui_components/OSVectorController.hpp -│ │ ├── MeasureManager.md ← src/shared_gui_components/MeasureManager.hpp -│ │ ├── BCLMeasureDialog.md ← src/shared_gui_components/BCLMeasureDialog.hpp -│ │ ├── LocalLibraryController.md ← src/shared_gui_components/LocalLibraryController.hpp -│ │ └── BuildingComponentDialog.md ← src/shared_gui_components/BuildingComponentDialog.hpp -│ ├── model_editor/ -│ │ ├── InspectorGadget.md ← src/model_editor/InspectorGadget.hpp -│ │ ├── InspectorDialog.md ← src/model_editor/InspectorDialog.hpp -│ │ └── AccessPolicyStore.md ← src/model_editor/AccessPolicyStore.hpp -│ └── bimserver/ -│ ├── BIMserverConnection.md ← src/bimserver/BIMserverConnection.hpp -│ └── ProjectImporter.md ← src/bimserver/ProjectImporter.hpp -└── ci/ - ├── overview.md ← .github/workflows/*.yml, Jenkinsfile_*, ci/*, CMake/CodeSigning.cmake - ├── jenkins.md ← Jenkinsfile_linux, Jenkinsfile_osx, Jenkinsfile_windows - ├── scripts.md ← ci/* scripts - └── workflows/ - ├── app_build.md ← .github/workflows/app_build.yml - ├── check_osm_versions.md ← .github/workflows/check_osm_versions.yml - ├── cla.md ← .github/workflows/cla.yml - ├── clangformat.md ← .github/workflows/clangformat.yml - ├── cppcheck.md ← .github/workflows/cppcheck.yml - ├── export_standards_data.md ← .github/workflows/export_standards_data.yml - ├── manual_cli_test.md ← .github/workflows/manual_cli_test.yml - └── release_notes.md ← .github/workflows/release_notes.yml ``` --- @@ -105,17 +51,9 @@ Update documentation when ANY of the following changes occur: | Change | Docs to update | |---|---| -| `.hpp` or `.cpp` file modified in a documented class | Corresponding class `.md` in `developer/doc/classes/` | -| New class added matching library conventions (see §6) | Create new class `.md`; add entry to library `.md` | -| Class deleted | Delete class `.md`; remove from library `.md` | | `CMakeLists.txt` in a module changes (new deps, new targets) | Corresponding library `.md` + `architecture.md` dependency graph | -| `src/openstudio_qt_utils/` file modified | `libraries/openstudio_qt_utils.md` + any affected class doc | +| `src/openstudio_qt_utils/` file modified | `libraries/openstudio_qt_utils.md` | | Top-level `CMakeLists.txt` changes (version, new sub-project) | `architecture.md` | -| `.github/workflows/*.yml` changes | Corresponding `developer/doc/ci/workflows/*.md` + `ci/overview.md` | -| New workflow added | Create new workflow `.md`; add entry to `ci/overview.md` | -| `Jenkinsfile_*` changes | `developer/doc/ci/jenkins.md` + `ci/overview.md` | -| `ci/` script changes | `developer/doc/ci/scripts.md` | -| New secret added to any workflow | `ci/overview.md` secrets table | | `conanfile.py` dependency version changes | `architecture.md` tech stack section | --- @@ -201,88 +139,9 @@ flowchart LR ## Design Notes ... -## Class Documentation Index -- [{ClassName}](../classes/{name}/{ClassName}.md) -``` - -### 3c. Class Document (`classes/{module}/{ClassName}.md`) - -```markdown -# `{ClassName}` - -> **Defined in:** `src/{module}/{ClassName}.hpp` -> **Library:** [{module}](../../libraries/{module}.md) - -## Role -One-sentence responsibility statement. - -## Class Diagram -\`\`\`mermaid -classDiagram - class {ClassName} { - +key_method() - +another_method() - } - {BaseClass} <|-- {ClassName} -\`\`\` - -## Key Responsibilities -- ... - -## Public API - -### `method_name(params)` -Brief description. - -## Signals / Slots (Qt) - -| Signal / Slot | Description | -|---|---| - -## Interactions -\`\`\`mermaid -sequenceDiagram - ... -\`\`\` - -## Usage Example -\`\`\`cpp -// ... -\`\`\` - -## Notes -- ... -``` - -### 3d. CI Workflow Document (`ci/workflows/{name}.md`) - -```markdown -# Workflow: `{name}.yml` — {Title} - -> **File:** `.github/workflows/{name}.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose -... - -## Trigger -\`\`\`yaml -on: - ... -\`\`\` - -## Job(s) -\`\`\`mermaid -flowchart TD - ... -\`\`\` - -## Steps -... +## Key Classes -## Related Files -| File | Role | -|---|---| +Class-level documentation is in the corresponding header files under [`src/{name}/`](../../../src/{name}/). ``` --- @@ -306,11 +165,7 @@ flowchart TD ## 5. Cross-Linking Rules -- Every library doc must link to each of its class docs in a "Class Documentation Index" section. -- Every class doc must link back to its library doc in the header. - `architecture.md` module index must link to every library doc. -- `ci/overview.md` workflow table must link to every workflow doc. -- `ci/overview.md` must link to `jenkins.md` and `scripts.md`. - Use **relative Markdown links** only (e.g., `../libraries/openstudio_lib.md`, not absolute paths). --- @@ -323,44 +178,70 @@ Follow these steps whenever source code or CI configuration changes: 2. **Map to documentation.** Use the Structure Map (§1) and Trigger Conditions (§2) to determine which `.md` files need updating. -3. **Read the changed source.** Use `read_file` to read the relevant headers and implementation files. Focus on: public API, inheritance, signals/slots, key collaborators. +3. **Read the changed source.** Use `read_file` to read the relevant headers and CMake files. 4. **Read the existing doc.** Use `read_file` on the current `.md` to understand what is already correct and what has drifted. 5. **Update the doc.** Use `replace_string_in_file` for targeted edits (prefer this over full rewrites). Update: - - Class diagram if inheritance or key methods changed - - Public API section if method signatures changed - - Signals/Slots table if Qt signals/slots were added/removed - - Interactions sequence diagram if collaboration pattern changed - - Notes section for behavioral changes + - Dependency tables and module graphs if CMake targets changed + - Tech stack table in `architecture.md` if versions changed -6. **Update cross-links.** If a class was added or removed, update the parent library doc's Class Documentation Index. If a workflow changed its triggers or jobs, update `ci/overview.md`. +6. **Check for version or dependency changes.** If `CMakeLists.txt` or `conanfile.py` changed dependency versions, update the tech stack table in `architecture.md`. -7. **Check for version or dependency changes.** If `CMakeLists.txt` or `conanfile.py` changed dependency versions, update the tech stack table in `architecture.md`. +7. **Verify Mermaid syntax.** Ensure all diagram blocks are syntactically valid Mermaid. + +--- -8. **Verify Mermaid syntax.** Ensure all diagram blocks are syntactically valid Mermaid. Do not leave unclosed blocks or use unsupported node shapes. +## 7. Class Documentation + +Class-level documentation lives in `/** */` doc comments in the header files (`src/**/*.hpp`), not in separate Markdown files. When adding a new significant class (base/abstract classes, major controllers, integration points, widely reused components), add a `/** ... */` doc comment block directly above the class declaration describing its purpose. --- -## 7. Class Selection Heuristic +## 8. Comment Correctness and Completeness Checks + +When source files are changed, verify that inline comments remain accurate. + +### C++ Header Class Comments (`src/**/*.hpp`) + +For every significant class (base/abstract, major controller, integration point, widely reused component) that was added or modified: + +1. **Presence** — a `/** */` doc comment must appear directly above the class declaration (not a forward declaration). +2. **Accuracy** — the comment must reflect the class's current responsibility. Check for: + - Purpose description that no longer matches the class's role after a refactor + - References to removed methods, renamed signals, or deleted dependencies +3. **Completeness** — if the class is one of the following types, the comment should describe what it owns, what signals it emits, and how it fits into the broader system: + - Abstract base / interface classes + - Tab-level controllers (`*Controller` owning a `*View`) + - Classes bridging external systems (web engine, BIMserver, CLI, network) +4. **What to skip** — do not add or require doc comments on: + - Forward declarations + - Member variables, private methods, or trivial getters/setters (unless they have non-obvious side effects) + - Private implementation detail classes nested inside a `.cpp` + - Thin wrappers or trivial value types with self-explanatory names + +### GitHub Actions Workflow Comments (`.github/workflows/*.yml`) + +For every workflow file that was added or modified, verify the file-level comment block at the top: + +1. **Presence** — a `#`-prefixed comment block must appear before the `name:` line. +2. **Accuracy** — check that the comment correctly describes: + - The workflow's purpose (what it builds, tests, or enforces) + - Trigger conditions (branches, tags, events, manual dispatch) + - Any required secrets (add or remove as the `secrets:` block changes) + - When to run it manually (for `workflow_dispatch` workflows) +3. **Completeness** — the comment should be enough for a developer to understand the workflow without reading the full YAML. It does not need to enumerate every step. + +### CI Helper Scripts (`ci/*.sh`, `ci/*.py`, `ci/*.qs`) -**Document these classes** (already in the doc set or should be added when introduced): -- Base/abstract classes that define cross-cutting interfaces (`BaseApp`, `OSVectorController` in `shared_gui_components`, `OSItem`) -- Tab-level controllers that own a UI domain (`HVACSystemsController`, `RunTabController`) -- View+Controller pairs for complex sub-systems (`HVACSystemsView`, `GeometryEditorController`) -- Integration point classes that bridge external systems (`BIMserverConnection`, `OSWebEnginePage`) -- Widely reused components (`OSGridController`, `OSDropZone`, `MeasureManager`) +For every script that was added or modified: -**Do NOT create docs for:** -- Concrete derived specializations of documented base classes where the only difference is the domain (e.g., individual inspector row widgets, individual tab view subclasses written purely as template instantiation) -- SWIG `.i` binding files -- `*.ui` Qt Designer files -- Translation `.ts`/`.qm` files -- CPack / install helper scripts +1. **Presence** — a comment header describing the script's purpose must be present near the top of the file. +2. **Accuracy** — check that usage examples, argument descriptions, and exit-code documentation still match the script's actual behaviour. --- -## 8. Scope Exclusions +## 9. Scope Exclusions Never document the following in `developer/doc/` (they are internal plumbing or generated code): diff --git a/.github/workflows/app_build.yml b/.github/workflows/app_build.yml index 44e6e36d9..eb88aeaa7 100644 --- a/.github/workflows/app_build.yml +++ b/.github/workflows/app_build.yml @@ -1,3 +1,21 @@ +# Main build pipeline. Builds the OpenStudio Application on 5 platforms (ubuntu-22.04, +# ubuntu-24.04, windows-2022, macos-15-intel, macos-15 arm64), runs CTest and benchmarks, +# applies code signing on tag pushes, and uploads installers to GitHub Releases. +# +# Two jobs: +# build - matrix over all 5 platforms +# test_package_macos - downloads and verifies the signed macOS DMG (macos-15-intel + arm64) +# +# Caching: three independent caches keyed by OS + Conan profile + CACHE_KEY secret: +# 1. ccache (compiler output cache) +# 2. Conan package cache +# 3. Qt + OpenStudio SDK download cache +# Rotate the CACHE_KEY secret to bust all caches immediately. +# +# Required secrets: MACOS_DEVELOPER_ID_APPLICATION_CERTIFICATE_P12_BASE64, +# MACOS_DEVELOPER_ID_INSTALLER_CERTIFICATE_P12_PASSWORD, MACOS_KEYCHAIN_PASSWORD, +# NOTARIZATION_API_KEY, NOTARIZATION_API_TEAM_ID, NOTARIZATION_API_ISSUER_ID, +# SIGNPATH_CI_TOKEN, ANALYTICS_API_SECRET, ANALYTICS_MEASUREMENT_ID, CACHE_KEY name: C++ CI for OpenStudioApplication on: diff --git a/.github/workflows/check_osm_versions.yml b/.github/workflows/check_osm_versions.yml index 1857ab306..d12c76b90 100644 --- a/.github/workflows/check_osm_versions.yml +++ b/.github/workflows/check_osm_versions.yml @@ -1,3 +1,9 @@ +# Ensures all .osm template files bundled in src/openstudio_app/Resources/ have been +# version-translated to the current OpenStudio SDK version before a PR merges to master. +# Runs developer/ruby/CheckOSMVersions.rb which verifies each file's OS:Version object. +# +# On failure: run the export_standards_data workflow to regenerate the OSM files, or run +# developer/ruby/UpdateOSMVersions.rb locally and commit the result. name: Check OSM Versions on: diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index dd5687af6..79bf90b68 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,3 +1,9 @@ +# Enforces the Contributor License Agreement for all external contributors. +# Uses pull_request_target (runs in base branch context) so it has write access +# even from fork PRs. Signatures are stored in signatures/version1/cla.json on the +# develop branch. Contributors sign by commenting the magic phrase on their PR. +# Organization members and bots are automatically excluded. +# Required secret: CLA_SECRET (GitHub PAT with repo scope) name: "CLA Assistant" on: issue_comment: @@ -33,4 +39,4 @@ jobs: #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) - #use-dco-flag: true - If you are using DCO instead of CLA \ No newline at end of file + #use-dco-flag: true - If you are using DCO instead of CLA diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index aca7ba496..039366d44 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -1,3 +1,8 @@ +# Enforces .clang-format style on all C/C++ files changed in a PR. +# Runs ci/clang-format.sh which diffs HEAD against the base branch, formats only +# changed files, and exits 1 if any changes were needed. +# On failure: download the clang_format.patch artifact and apply with 'git apply clang_format.patch'. +# Install ci/pre-commit.sh as a git pre-commit hook to catch violations locally. name: Clang Format on: diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml index 37343c9d0..640c01a86 100644 --- a/.github/workflows/cppcheck.yml +++ b/.github/workflows/cppcheck.yml @@ -1,3 +1,8 @@ +# Runs cppcheck static analysis on the entire src/ tree. +# Builds cppcheck 2.9 from source (the Ubuntu package is too old) to ensure +# consistent results. Uses --enable=all --library=qt --std=c++20 --inconclusive +# and suppresses useStlAlgorithm. The qtwinmigrate directory is excluded. +# Output is colorized by ci/colorize_cppcheck_results.py and uploaded as an artifact. name: cppcheck on: diff --git a/.github/workflows/export_standards_data.yml b/.github/workflows/export_standards_data.yml index cd5a1809c..737c1790c 100644 --- a/.github/workflows/export_standards_data.yml +++ b/.github/workflows/export_standards_data.yml @@ -1,3 +1,11 @@ +# Manually triggered workflow that downloads the OpenStudio SDK, runs the Ruby script +# that generates OpenStudio Standards template .osm files, and commits the results back +# to the repository. This keeps src/openstudio_app/Resources/*.osm up to date. +# +# Run this workflow when: +# - A new OpenStudio SDK version is released +# - The check_osm_versions gate is failing on a master PR +# After the workflow completes, open a PR from the target branch to develop/master. name: Export OpenStudio Standards Data on: @@ -216,4 +224,3 @@ jobs: else echo "${Red}No logs to commit, that's very strange...${Color_Off}" fi - diff --git a/.github/workflows/manual_cli_test.yml b/.github/workflows/manual_cli_test.yml index 81c400662..f5730ed0a 100644 --- a/.github/workflows/manual_cli_test.yml +++ b/.github/workflows/manual_cli_test.yml @@ -1,3 +1,7 @@ +# Manually triggered smoke test that downloads a previously built installer archive +# and verifies the OpenStudio CLI works on all 5 platforms. Tests cover the classic +# Ruby CLI and the C++ (labs) CLI including EnergyPlus and Python scripting. +# Input: run_id - the numeric GitHub Actions run ID of the app_build workflow to test. name: Test OS SDK CLI from OpenStudio Application on: diff --git a/.github/workflows/release_notes.yml b/.github/workflows/release_notes.yml index cb53dde83..078a93b46 100644 --- a/.github/workflows/release_notes.yml +++ b/.github/workflows/release_notes.yml @@ -1,3 +1,7 @@ +# Automatically generates and appends a changelog to a GitHub Release when it is created. +# Runs developer/ruby/GitHubIssueStats.rb which queries the GitHub Issues API for all +# issues closed since the previous release tag, formats them as Markdown, and patches +# the release body via the GitHub API. name: Create release notes changelog on: release: diff --git a/CMakeLists.txt b/CMakeLists.txt index f8a7a1580..337de4cba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,9 +97,6 @@ find_package(cpprestsdk) find_package(websocketpp) find_package(Boost) find_package(geographiclib) -find_package(SWIG 4.1.1 EXACT REQUIRED CONFIG) -message("SWIG_EXECUTABLE=${SWIG_EXECUTABLE}") -message("SWIG_DIR=${SWIG_DIR}") find_package(TinyGLTF) find_package(minizip) find_package(OpenSSL) diff --git a/ci/clang-format.sh b/ci/clang-format.sh index 1f15b64d4..a6923cb47 100755 --- a/ci/clang-format.sh +++ b/ci/clang-format.sh @@ -33,14 +33,14 @@ then fi # first find if any files changed -num=$(git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|cxx\|cxx.in\|hpp\|h\|hxx\|hxx.in\)$' | wc -l | tr -d '[:space:]') +num=$(git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only --diff-filter=d | grep '.*\.\(cpp\|c\|cxx\|cxx.in\|hpp\|h\|hxx\|hxx.in\)$' | wc -l | tr -d '[:space:]') if [ $num -eq 0 ] then echo "No files of type (cpp, c, cxx, cxx.in, hpp, h, hxx, hxx.in) changed. Skipping clang-formatting" exit 0 fi -git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|cxx\|cxx.in\|hpp\|h\|hxx\|hxx.in\)$' | xargs clang-format -style=file -i -fallback-style=none +git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only --diff-filter=d | grep '.*\.\(cpp\|c\|cxx\|cxx.in\|hpp\|h\|hxx\|hxx.in\)$' | xargs clang-format -style=file -i -fallback-style=none # clang-format will auto correct files so prepare the diff and use this as artifact git diff > clang_format.patch @@ -58,4 +58,3 @@ else fi exit 0 - diff --git a/ci/install_script_qtifw.qs b/ci/install_script_qtifw.qs index bf63f6e5d..2480cbf72 100644 --- a/ci/install_script_qtifw.qs +++ b/ci/install_script_qtifw.qs @@ -1,3 +1,9 @@ +// QtIFW (Qt Installer Framework) controller script for unattended / silent installation in CI. +// Used by app_build.yml and manual_cli_test.yml to install the produced .exe/.dmg without +// any user interaction. Implements all installer page callbacks to auto-click through the +// wizard: Welcome -> License -> Component Selection -> Target Directory -> Install -> Finish. +// The "Launch after install" checkbox is explicitly disabled in FinishedPageCallback. + function Controller() { installer.autoRejectMessageBoxes(); diff --git a/conanfile.py b/conanfile.py index 8bf634981..e3dc690d1 100644 --- a/conanfile.py +++ b/conanfile.py @@ -41,7 +41,6 @@ def requirements(self): self.requires("cpprestsdk/2.10.19") # df2f6ac88e47cadd9c9e8e0971e00d89 self.requires("websocketpp/0.8.2") # 3fd704c4c5388d9c08b11af86f79f616 self.requires("geographiclib/1.52") # 76536a9315a003ef3511919310b2fe37 - self.requires("swig/4.1.1") # Pending https://github.com/conan-io/conan-center-index/pull/19058 self.requires("tinygltf/2.5.0") # c8b2aca9505e86312bb42aa0e1c639ec self.requires("termcap/1.3.1#479400c750a869f77b3d2d3a82e06f7d") # need version with updated minimum cmake # self.requires("cli11/2.3.2") # 8ccdf14fb1ad53532d498c16ae580b4b diff --git a/developer/doc/ci/jenkins.md b/developer/doc/ci/jenkins.md deleted file mode 100644 index 3601a931d..000000000 --- a/developer/doc/ci/jenkins.md +++ /dev/null @@ -1,60 +0,0 @@ -# CI: Jenkins Pipelines - -> **Back to:** [CI/CD Overview](overview.md) - -## Overview - -Three Jenkinsfiles provide integration with NREL's internal Jenkins infrastructure (`cbci`). Each file is minimal — it simply selects a function from the shared library `cbci_shared_libs` and calls it. All build logic lives in that external library. - ---- - -## Files - -| Jenkinsfile | Library Branch | Library Function | -|---|---|---| -| `Jenkinsfile_linux` | `@updateLibs` branch of `cbci_shared_libs` | `openstudio_app_incr_linux()` | -| `Jenkinsfile_osx` | default (`@cbci_shared_libs`) | `openstudio_app_incr_osx()` | -| `Jenkinsfile_windows` | default (`@cbci_shared_libs`) | `openstudio_app_incr_windows()` | - ---- - -## Trigger Condition - -All three pipelines share the same guard: - -```groovy -if (env.CHANGE_ID && env.CHANGE_TARGET) { - // Run — this is a PR build -} else { - // Skip — this is a branch push; handled by GitHub Actions -} -``` - -`CHANGE_ID` is set by the Jenkins GitHub plugin only when building a Pull Request. This means the Jenkins pipelines run **exclusively on PRs** and do not duplicate the push-triggered GitHub Actions builds. - ---- - -## Relationship to GitHub Actions - -| Metric | GitHub Actions (`app_build.yml`) | Jenkins | -|---|---|---| -| Trigger | PR + push + tags | PR only | -| Platforms | 5 (Ubuntu 22/24, Windows, macOS Intel/ARM) | Internal NREL runners | -| Code signing | Yes (on tags) | No | -| Release upload | Yes | No | -| Purpose | Official artifacts + release | Supplemental incremental check | - -Jenkins builds serve as an additional quality gate for NREL contributors without duplicating the official release workflow. - ---- - -## Shared Library - -The `cbci_shared_libs` library is hosted at `github.com/NREL/cbci_jenkins_libs` (internal). The `openstudio_app_incr_*` functions typically: -1. Check out the PR branch -2. Set up the build environment (Conan, CMake, compiler) -3. Run a build (`cmake --build`) -4. Run tests (`ctest`) -5. Report pass/fail back to the PR status check - -The exact steps are defined in the external shared library, not in this repository. diff --git a/developer/doc/ci/overview.md b/developer/doc/ci/overview.md deleted file mode 100644 index 074a2d805..000000000 --- a/developer/doc/ci/overview.md +++ /dev/null @@ -1,138 +0,0 @@ -# CI/CD Architecture Overview - -> **Back to:** [Architecture Overview](../architecture.md) - -## Contents - -1. [System Overview](#1-system-overview) -2. [End-to-End Pipeline](#2-end-to-end-pipeline) -3. [Build Matrix](#3-build-matrix) -4. [Workflow Index](#4-workflow-index) -5. [Jenkins Pipelines](#5-jenkins-pipelines) -6. [GitHub Secrets](#6-github-secrets) -7. [CI Helper Scripts](#7-ci-helper-scripts) -8. [CMake Code-Signing Modules](#8-cmake-code-signing-modules) - ---- - -## 1. System Overview - -The project uses **two parallel CI systems**: - -| System | Triggers | Purpose | -|---|---|---| -| **GitHub Actions** | PR (all), push to `master`/`develop`, `v*` tags, manual dispatch | Full 5-platform build matrix, static analysis, CLA, code style, release publishing | -| **Jenkins** (NREL internal, `cbci_shared_libs`) | PR builds only (`CHANGE_ID` set) | Incremental build checks on NREL infrastructure | - -GitHub Actions is the **primary** CI system. Jenkins provides supplemental incremental builds for NREL contributors. - ---- - -## 2. End-to-End Pipeline - -```mermaid -flowchart TD - PR["Pull Request opened / pushed"] --> CLA["cla.yml\nCLA signature check"] - PR --> FMT["clangformat.yml\nCode style check"] - PR --> CK["cppcheck.yml\nStatic analysis"] - PR --> OSM["check_osm_versions.yml\nOSM version gate (master only)"] - PR --> BUILD["app_build.yml\nFull 5-platform build matrix"] - - BUILD --> SIGN_WIN["Windows: SignPath\ncode signing"] - BUILD --> SIGN_MAC["macOS: Apple notarization\n(xcrun notarytool)"] - BUILD --> ARTIFACTS["Upload platform artifacts\n(installer + archive)"] - BUILD --> TEST_PKG["test_package_macos\nSignature & install verification"] - ARTIFACTS --> RELEASE["Tag push v*:\nupload to GitHub Release"] - - RELEASE --> RN["release_notes.yml\nAuto-generate changelog"] -``` - ---- - -## 3. Build Matrix - -```mermaid -flowchart LR - MATRIX["app_build.yml\nbuild job matrix"] - MATRIX --> U22["ubuntu-22.04\n→ .deb + .tar.gz"] - MATRIX --> U24["ubuntu-24.04\n→ .deb + .tar.gz"] - MATRIX --> WIN["windows-2022\n→ .exe (IFW) + .zip\n+ SignPath signing on tags"] - MATRIX --> MAC_INTEL["macos-15-intel x86_64\n→ .dmg (IFW) + .tar.gz\n+ Apple notarization"] - MATRIX --> MAC_ARM["macos-15 arm64\n→ .dmg (IFW) + .tar.gz\n+ Apple notarization"] -``` - ---- - -## 4. Workflow Index - -| Workflow | Trigger | Purpose | Doc | -|---|---|---|---| -| `app_build.yml` | Push master/develop, PR, tags | Main 5-platform build, sign, package, release | [workflows/app_build.md](workflows/app_build.md) | -| `check_osm_versions.yml` | PR → master | Validates OSM version translation | [workflows/check_osm_versions.md](workflows/check_osm_versions.md) | -| `cla.yml` | PR events + `issue_comment` | CLA signature enforcement | [workflows/cla.md](workflows/cla.md) | -| `clangformat.yml` | PR → master/develop | C++ code style enforcement | [workflows/clangformat.md](workflows/clangformat.md) | -| `cppcheck.yml` | Push master, PR | Static analysis | [workflows/cppcheck.md](workflows/cppcheck.md) | -| `export_standards_data.yml` | Manual dispatch | Export SDK standards data and commit OSMs | [workflows/export_standards_data.md](workflows/export_standards_data.md) | -| `manual_cli_test.yml` | Manual dispatch | 5-platform CLI smoke tests | [workflows/manual_cli_test.md](workflows/manual_cli_test.md) | -| `release_notes.yml` | Release `created` | Auto-generate changelog from GitHub issues | [workflows/release_notes.md](workflows/release_notes.md) | - ---- - -## 5. Jenkins Pipelines - -Three Jenkinsfiles are provided for NREL's internal Jenkins infrastructure. Each delegates entirely to a **shared library** at `github.com/NREL/cbci_jenkins_libs`: - -| File | Library function | -|---|---| -| `Jenkinsfile_linux` | `openstudio_app_incr_linux()` (branch: `@updateLibs`) | -| `Jenkinsfile_osx` | `openstudio_app_incr_osx()` | -| `Jenkinsfile_windows` | `openstudio_app_incr_windows()` | - -**Trigger condition:** all three pipelines run only when both `env.CHANGE_ID` and `env.CHANGE_TARGET` are set — meaning **PR builds only**. Pushes to branches are handled exclusively by GitHub Actions. - -See [jenkins.md](jenkins.md) for further details. - ---- - -## 6. GitHub Secrets - -| Secret | Used by | Purpose | -|---|---|---| -| `MACOS_DEVELOPER_ID_APPLICATION_CERTIFICATE_P12_BASE64` | `app_build.yml` | Base64-encoded P12 cert for macOS app bundle signing | -| `MACOS_DEVELOPER_ID_INSTALLER_CERTIFICATE_P12_PASSWORD` | `app_build.yml` | Password for the macOS installer signing P12 | -| `MACOS_KEYCHAIN_PASSWORD` | `app_build.yml` | Password for the temporary keychain created during macOS CI | -| `NOTARIZATION_API_KEY` | `app_build.yml` | Apple App Store Connect API key for `xcrun notarytool` | -| `NOTARIZATION_API_TEAM_ID` | `app_build.yml` | Apple Team ID for notarization | -| `NOTARIZATION_API_ISSUER_ID` | `app_build.yml` | Issuer ID for App Store Connect API | -| `SIGNPATH_CI_TOKEN` | `app_build.yml` | Windows code signing token via SignPath | -| `ANALYTICS_API_SECRET` | `app_build.yml` | Google Analytics Measurement Protocol secret embedded in the app binary | -| `ANALYTICS_MEASUREMENT_ID` | `app_build.yml` | Google Analytics measurement ID | -| `CLA_SECRET` | `cla.yml` | Personal access token for cla-assistant GitHub Action | -| `CACHE_KEY` | `app_build.yml` | Rotatable opaque key for invalidating all CI caches | - ---- - -## 7. CI Helper Scripts - -See [scripts.md](scripts.md) for full documentation of all scripts in `ci/`. - -| Script | Purpose | -|---|---| -| `ci/clang-format.sh` | Runs clang-format on PR-changed files; produces patch | -| `ci/pre-commit.sh` | Git pre-commit hook wrapping clang-format | -| `ci/colorize_cppcheck_results.py` | ANSI-colorizes cppcheck output by severity | -| `ci/install_script_qtifw.qs` | Silent QtIFW installer controller for CI | -| `ci/parse_cmake_versions.py` | Extracts version variables from CMake files | - ---- - -## 8. CMake Code-Signing Modules - -| File | Purpose | -|---|---| -| `CMake/CodeSigning.cmake` | `codesign` and `xcrun notarytool` helper CMake functions | -| `CMake/CPackSignAndNotarizeDmg.cmake` | CPack post-build hook: signs and notarizes the `.dmg` | -| `CMake/install_codesign_script.cmake` | CMake install-time signing (all components) | -| `CMake/install_codesign_script_OpenStudioApp.cmake` | Signing script scoped to the `OpenStudioApp` component | -| `CMake/install_codesign_script_Python.cmake` | Signing script scoped to the Python bundle component | -| `FindOpenStudioSDK.cmake` | Defines `OPENSTUDIO_VERSION_*` variables consumed by version parser script | diff --git a/developer/doc/ci/scripts.md b/developer/doc/ci/scripts.md deleted file mode 100644 index 2530dbbea..000000000 --- a/developer/doc/ci/scripts.md +++ /dev/null @@ -1,143 +0,0 @@ -# CI: Helper Scripts - -> **Back to:** [CI/CD Overview](overview.md) - -## Overview - -The `ci/` directory contains five helper scripts used by GitHub Actions workflows and the local development pre-commit hook. - ---- - -## `ci/clang-format.sh` - -**Used by:** [`clangformat.yml`](workflows/clangformat.md), [`ci/pre-commit.sh`](#cipre-commitsh) - -Runs `clang-format` on only the C/C++ files that differ between two git refs, then produces a unified diff patch. - -### Arguments - -```bash -ci/clang-format.sh -# e.g.: ci/clang-format.sh HEAD remotes/origin/develop -``` - -### Behavior - -1. Computes `git diff --name-only ref1 ref2` filtered to `*.cpp`, `*.hpp`, `*.cxx`, `*.h` -2. Runs `clang-format -style=file -i` on each changed file (uses the `.clang-format` in the repo root) -3. Runs `git diff` to detect any formatting changes -4. If changes exist: writes `clang_format.patch` and exits with code 1 -5. If no changes: exits with code 0 - -### Exit Codes - -| Code | Meaning | -|---|---| -| 0 | All changed files are correctly formatted | -| 1 | Formatting changes needed; `clang_format.patch` produced | - ---- - -## `ci/pre-commit.sh` - -**Used by:** Developer local setup (git pre-commit hook) - -A git pre-commit hook that runs `clang-format.sh` on staged changes before each commit. Prevents unformatted code from being committed. - -### Installation - -```bash -cd .git/hooks -ln -s ../../ci/pre-commit.sh pre-commit -``` - -### Behavior - -1. Stashes unstaged changes (`git stash -u`) to isolate staged content -2. Runs `ci/clang-format.sh HEAD origin/develop` -3. If exit code is 1: prints guidance and aborts the commit (exit 1) -4. Restores stashed changes (`git stash pop`) - ---- - -## `ci/colorize_cppcheck_results.py` - -**Used by:** [`cppcheck.yml`](workflows/cppcheck.md) - -Reads cppcheck output from stdin, applies ANSI colors by severity, and prints a summary counter. - -### Input Format - -Expects lines matching: -``` -[file.cpp:42]:(error),[missingOverride],Override has no matching virtual function -``` - -### Color Mapping - -| Severity | ANSI Color | -|---|---| -| `error` | Red | -| `warning` | Yellow | -| `style` | Blue | -| `performance` | Cyan | -| `portability` | Magenta | -| `information` | Green | - -### Usage - -```bash -cppcheck ... 2>&1 | python3 ci/colorize_cppcheck_results.py -``` - ---- - -## `ci/install_script_qtifw.qs` - -**Used by:** [`app_build.yml`](workflows/app_build.md) (Windows and macOS, silent install verification) - -A QtIFW (Qt Installer Framework) controller script for **unattended / silent installation** in CI environments. - -### Behavior - -Implements all QtIFW `Controller` callbacks: -- `WelcomePageCallback` — auto-clicks Next -- `LicenseAgreementPageCallback` — auto-accepts -- `ComponentSelectionPageCallback` — accepts defaults -- `TargetDirectoryPageCallback` — accepts default install path -- `ReadyForInstallationPageCallback` — clicks Install -- `FinishedPageCallback` — disables "Launch after install" checkbox, clicks Finish - -This allows automated installation of the produced `.exe`/`.dmg` installer as part of post-build verification. - ---- - -## `ci/parse_cmake_versions.py` - -**Used by:** [`app_build.yml`](workflows/app_build.md), [`export_standards_data.yml`](workflows/export_standards_data.md) - -Parses version numbers from `CMakeLists.txt` and `FindOpenStudioSDK.cmake` and writes them to `GITHUB_ENV` and `GITHUB_OUTPUT` for use by downstream workflow steps. - -### Variables Extracted - -From `CMakeLists.txt`: -- `OS_APP_VERSION` — e.g., `1.11.0` -- `OS_APP_VERSION_MAJOR`, `OS_APP_VERSION_MINOR`, `OS_APP_VERSION_PATCH` - -From `FindOpenStudioSDK.cmake`: -- `OS_SDK_VERSION` — assembled from major/minor/patch/prerelease components -- `OS_SDK_VERSION_MAJOR`, `OS_SDK_VERSION_MINOR`, `OS_SDK_VERSION_PATCH` -- `OS_SDK_VERSION_PRERELEASE`, `OS_SDK_SHA` (git SHA of the SDK) - -### Usage - -```bash -python3 ci/parse_cmake_versions.py -# Writes to $GITHUB_ENV and $GITHUB_OUTPUT automatically -``` - -After this step, any subsequent GitHub Actions step can use the variables: -```yaml -- name: Use version - run: echo "Building version ${{ env.OS_APP_VERSION }}" -``` diff --git a/developer/doc/ci/workflows/app_build.md b/developer/doc/ci/workflows/app_build.md deleted file mode 100644 index bbaaa2b12..000000000 --- a/developer/doc/ci/workflows/app_build.md +++ /dev/null @@ -1,139 +0,0 @@ -# Workflow: `app_build.yml` — Main Build Pipeline - -> **File:** `.github/workflows/app_build.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -The primary CI workflow. Builds the OpenStudio Application on 5 platforms, runs tests and benchmarks, applies code signing (on tags), and uploads installers to GitHub Releases. - ---- - -## Trigger - -```yaml -on: - push: - branches: [master, develop] - tags: ['v*'] - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - branches: [master, develop] -``` - -Draft PRs are skipped via an `if: github.event.pull_request.draft == false` guard. - ---- - -## Jobs - -```mermaid -flowchart TD - BUILD["build\n5-platform matrix"] - TEST_PKG["test_package_macos\nmacos-15-intel + macos-15 arm64"] - - BUILD --> TEST_PKG -``` - ---- - -## `build` Job — Step Sequence - -```mermaid -flowchart TD - CO["Checkout (actions/checkout@v4)"] --> PY["Setup Python 3.12"] - PY --> RB["Setup Ruby 3.2.2"] - RB --> VER["Parse versions\n(ci/parse_cmake_versions.py)"] - VER --> PLATFORM["Platform-specific setup\n(apt / choco / brew)"] - PLATFORM --> SIGN_SETUP["macOS: Code signing setup\n(P12 import, keychain, notarytool profile)"] - SIGN_SETUP --> CONAN["Install Conan 2\nSet profile: C++20, Release\nAdd NREL conan remote"] - CONAN --> CACHE["Restore 3 caches:\ncache1: ccache\ncache2: Conan packages\ncache3: Qt + OpenStudio SDK"] - CACHE --> QT["Install Qt 6.5.2 via aqtinstall\n(qtwebengine, qtcharts, etc.)"] - QT --> CMAKE["conan install → cmake --preset conan-release"] - CMAKE --> BUILD_PKG["cmake --build --target package"] - BUILD_PKG --> WIN_SIGN["Windows (tags only):\nSignPath signs .exe\nRepack with CPack\nSignPath signs installer .exe"] - WIN_SIGN --> UPLOAD["Upload artifact:\ninstaller + archive"] - UPLOAD --> MAC_VERIFY["macOS: verify_signature.py\non IFW + TGZ"] - MAC_VERIFY --> CTEST["CTest\n(xvfb-run on Linux,\nautomationmodetool on macOS)"] - CTEST --> BENCH["Benchmarks:\nSpacesSurfaces_Benchmark → CSV"] - BENCH --> RELEASE["Tag push v*:\nupload to GitHub Release\n(svenstaro/upload-release-action)"] - RELEASE --> KC["macOS: Always delete temp keychain"] -``` - ---- - -## `test_package_macos` Job - -Depends on `build` and runs on `macos-15-intel` and `macos-15` (arm64) only. - -**Steps:** -1. Download `.dmg` artifact from the `build` job -2. `spctl --assess --type install` — verify DMG signature -3. Mount DMG, verify installer app bundle signature with `codesign -dvvv` -4. Silent install via `installer -pkg` or QtIFW with `ci/install_script_qtifw.qs` -5. `codesign -dvvv` on all critical inner libs: `libopenstudiolib.dylib`, `libpythonengine.so`, `librubyengine.so`, `energyplus`, `libenergyplusapi.dylib` -6. Full deep signature check via `developer/python/verify_signature.py` -7. Run an EnergyPlus Python plugin simulation to verify end-to-end install -8. Upload `otool` JSON as artifact - ---- - -## Platform-Specific Setup Details - -### Linux (ubuntu-22.04, ubuntu-24.04) - -```bash -sudo apt-get install mesa-common-dev libxkbcommon-x11-dev \ - libxcb-util1 libxcb-keysyms1 libxcb-image0 libxcb-render-util0 \ - libxcb-randr0 libxcb-xinerama0 libxcb-icccm4 librsvg2-dev \ - chrpath ccache ninja-build patchelf -``` - -### Windows (windows-2022) - -- Downloads QtIFW 4.6.1 -- Installs `ninja` + `ccache` via Chocolatey -- Locates MSVC via `vswhere` - -### macOS (macos-15-intel, macos-15 arm64) - -- Sets `MACOSX_DEPLOYMENT_TARGET` and `SDKROOT` -- Selects Xcode 16.4 via `xcode-select` -- Installs `ccache` + `ninja` via Homebrew -- Removes conflicting system OpenSSL pkg-config files -- Downloads a patched QtIFW from `jmarrec/QtIFW-fixup` (for silent install) - ---- - -## Caching Strategy - -Three independent caches keyed to avoid stale data: - -| Cache | Key components | -|---|---| -| **CCache** | OS + build type + Conan profile hash + `CACHE_KEY` secret + `CMakeLists.txt` sha | -| **Conan packages** | OS + Conan profile hash + `conanfile.py` sha | -| **Qt + OpenStudio SDK** | OS + Qt version + Conan profile hash | - -Rotating the `CACHE_KEY` secret busts all caches immediately. - ---- - -## Artifacts - -| Artifact | Platforms | -|---|---| -| `OpenStudioApplication--.exe` | Windows | -| `OpenStudioApplication--.zip` | Windows | -| `OpenStudioApplication--.dmg` | macOS | -| `OpenStudioApplication--.tar.gz` | macOS, Linux | -| `OpenStudioApplication--.deb` | Linux | -| `otool-output.json` | macOS (test_package_macos job) | -| CTest XML results | all platforms | -| Benchmark CSV | all platforms | - ---- - -## Required Secrets - -All secrets from the [Secrets table](../overview.md#6-github-secrets) are consumed by this workflow. diff --git a/developer/doc/ci/workflows/check_osm_versions.md b/developer/doc/ci/workflows/check_osm_versions.md deleted file mode 100644 index dafbfc22b..000000000 --- a/developer/doc/ci/workflows/check_osm_versions.md +++ /dev/null @@ -1,64 +0,0 @@ -# Workflow: `check_osm_versions.yml` — OSM Version Gate - -> **File:** `.github/workflows/check_osm_versions.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Ensures that all `.osm` files bundled with the application have been version-translated to the current OpenStudio SDK version before a PR is merged to `master`. This prevents shipping stale template models that would trigger the version translation warning at startup. - ---- - -## Trigger - -```yaml -on: - pull_request: - branches: [master] -``` - -Runs only on PRs targeting `master` (not `develop`). - ---- - -## Jobs - -```mermaid -flowchart TD - A["osm-versions job\nubuntu-latest"] --> B["Checkout"] - B --> C["Setup Ruby 3.2"] - C --> D["Run developer/ruby/CheckOSMVersions.rb"] - D --> PASS{Exit 0?} - PASS -- yes --> OK["✓ Check passes"] - PASS -- no --> FAIL["✗ Check fails\nPrint guidance message"] -``` - ---- - -## Key Step - -```yaml -- name: Check OSM versions - run: ruby developer/ruby/CheckOSMVersions.rb -``` - -`CheckOSMVersions.rb` reads all `.osm` files in `src/openstudio_app/Resources/` and verifies that each file's `OS:Version` object matches the expected SDK version (extracted from `FindOpenStudioSDK.cmake`). - ---- - -## Failure Guidance - -On failure, the workflow prints: - -> Run the `export_standards_data` workflow (see [workflows/export_standards_data.md](export_standards_data.md)) to regenerate the OSM files, or run `developer/ruby/UpdateOSMVersions.rb` locally and commit the result. - ---- - -## Related Files - -| File | Role | -|---|---| -| `developer/ruby/CheckOSMVersions.rb` | The version-checking script | -| `developer/ruby/UpdateOSMVersions.rb` | Locally run script to translate OSM files | -| `src/openstudio_app/Resources/*.osm` | OSM template files that are checked | -| `FindOpenStudioSDK.cmake` | Source of the expected SDK version | diff --git a/developer/doc/ci/workflows/cla.md b/developer/doc/ci/workflows/cla.md deleted file mode 100644 index d05dc3ebe..000000000 --- a/developer/doc/ci/workflows/cla.md +++ /dev/null @@ -1,65 +0,0 @@ -# Workflow: `cla.yml` — CLA Enforcement - -> **File:** `.github/workflows/cla.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Enforces the Contributor License Agreement (CLA) for all external contributors. Any PR author who has not yet signed the CLA will see a blocking status check with instructions on how to sign. - ---- - -## Trigger - -```yaml -on: - issue_comment: - types: [created] - pull_request_target: - types: [opened, closed, synchronize] -``` - -`pull_request_target` runs in the context of the **base branch** (not the PR branch), which gives the workflow write access needed to post comments and update PR status even from fork PRs. - ---- - -## Job - -```mermaid -flowchart TD - PR["PR opened / synchronized / closed\nor comment created"] --> CLA_BOT["CLA Assistant\n(cla-assistant/github-action@v2.3.1)"] - CLA_BOT --> CHECK{Signature found\nin cla.json?} - CHECK -- yes --> PASS["✓ CLA signed - status check passes"] - CHECK -- no --> COMMENT["Bot posts comment with\nsigning instructions"] - COMMENT --> WAIT["Wait for magic comment"] - WAIT --> SIGN["Contributor comments:\n'I have read the CLA Document\nand I hereby sign the CLA'"] - SIGN --> UPDATE["Signature recorded in\nsignatures/version1/cla.json\non develop branch"] - UPDATE --> PASS -``` - ---- - -## Configuration - -| Setting | Value | -|---|---| -| CLA document | [CLA.md](../../../../CLA.md) | -| Signature storage | `signatures/version1/cla.json` on `develop` branch | -| Sign magic comment | `"I have read the CLA Document and I hereby sign the CLA"` | -| Re-check comment | `"recheck"` | - ---- - -## Required Secrets - -| Secret | Purpose | -|---|---| -| `CLA_SECRET` | GitHub personal access token with `repo` scope; allows the action to read/write `cla.json` on the `develop` branch | - ---- - -## Notes - -- Organization members are typically excluded from CLA requirements (configured in the action). -- Bots (`[bot]` suffix in username) are automatically excluded. -- Signatures persist across PRs; a contributor only needs to sign once. diff --git a/developer/doc/ci/workflows/clangformat.md b/developer/doc/ci/workflows/clangformat.md deleted file mode 100644 index d5f660f4f..000000000 --- a/developer/doc/ci/workflows/clangformat.md +++ /dev/null @@ -1,77 +0,0 @@ -# Workflow: `clangformat.yml` — Code Style Enforcement - -> **File:** `.github/workflows/clangformat.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Enforces that all C/C++ source files changed in a PR are formatted according to the project's `.clang-format` style. PRs with formatting violations produce a downloadable patch and a failing status check. - ---- - -## Trigger - -```yaml -on: - pull_request: - branches: [master, develop] -``` - ---- - -## Job - -```mermaid -flowchart TD - A["build job\nubuntu-latest"] --> B["Checkout\n(full fetch-depth: 0 to include all branches)"] - B --> C["ci/clang-format.sh HEAD remotes/origin/$GITHUB_BASE_REF"] - C --> RESULT{Exit code?} - RESULT -- 0 --> PASS["✓ Formatting correct"] - RESULT -- 1 --> PATCH["Upload clang_format.patch artifact\nas OpenStudioApplication-SHA-clang_format.patch"] - PATCH --> FAIL["✗ Check fails"] -``` - ---- - -## Key Step - -```bash -ci/clang-format.sh HEAD remotes/origin/$GITHUB_BASE_REF -``` - -This runs clang-format only on the files changed by the PR (diff between `HEAD` and the base branch). See [scripts.md](../scripts.md#ciclang-formatsh) for full script documentation. - ---- - -## Fixing Violations - -Download the `clang_format.patch` artifact and apply it: - -```bash -git apply clang_format.patch -git commit -am "Apply clang-format" -git push -``` - -Or run locally before committing: - -```bash -ci/clang-format.sh HEAD origin/develop -git diff # should be empty -``` - -Install the pre-commit hook to catch violations before pushing: - -```bash -cd .git/hooks && ln -s ../../ci/pre-commit.sh pre-commit -``` - ---- - -## Related Files - -| File | Role | -|---|---| -| `.clang-format` | Style configuration file | -| `ci/clang-format.sh` | Script invoked by this workflow | -| `ci/pre-commit.sh` | Local pre-commit hook equivalent | diff --git a/developer/doc/ci/workflows/cppcheck.md b/developer/doc/ci/workflows/cppcheck.md deleted file mode 100644 index e71dbd8fe..000000000 --- a/developer/doc/ci/workflows/cppcheck.md +++ /dev/null @@ -1,85 +0,0 @@ -# Workflow: `cppcheck.yml` — Static Analysis - -> **File:** `.github/workflows/cppcheck.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Runs `cppcheck` static analysis on the entire `src/` tree to detect potential bugs, style violations, and undefined behavior. Output is colorized by severity and stored as a build artifact. - ---- - -## Trigger - -```yaml -on: - push: - branches: [master] - pull_request: - branches: [master, develop] -``` - ---- - -## Job - -```mermaid -flowchart TD - A["build job\nubuntu-latest"] --> B["Checkout"] - B --> C["Build cppcheck 2.9 from source\n(cmake -DBUILD_TESTING=OFF .)"] - C --> D["Run cppcheck on ./src\n(excluding ./src/qtwinmigrate)"] - D --> E["Pipe through ci/colorize_cppcheck_results.py"] - E --> F["Always: upload cppcheck.txt artifact"] - D --> RESULT{Exit code?} - RESULT -- 0 --> PASS["✓ No errors"] - RESULT -- 1 --> FAIL["✗ Errors found"] -``` - ---- - -## Cppcheck Configuration - -```bash -cppcheck \ - --std=c++20 \ - --enable=all \ - --library=qt \ - --suppress=useStlAlgorithm \ - --inconclusive \ - --template='[{file}:{line}]:({severity}),[{id}],{message}' \ - -j $(nproc) \ - --output-file=cppcheck.txt \ - -i ./src/qtwinmigrate \ - ./src -``` - -| Option | Purpose | -|---|---| -| `--std=c++20` | Parse using C++20 standard | -| `--enable=all` | Enable all check categories | -| `--library=qt` | Use Qt-specific definitions to reduce false positives | -| `--suppress=useStlAlgorithm` | Suppress noisy "use `std::find` instead of loop" suggestions | -| `--inconclusive` | Include checks that may have false positives | -| `-i ./src/qtwinmigrate` | Exclude the third-party Qt/Win32 bridge | - ---- - -## Why Build cppcheck from Source? - -The Ubuntu system `cppcheck` package is typically several major versions behind. Building version 2.9 from source ensures consistent results across CI runs and access to newer checks. - ---- - -## Artifacts - -| Artifact | Contents | -|---|---| -| `cppcheck.txt` | Full cppcheck output (always uploaded, regardless of pass/fail) | - ---- - -## Related Files - -| File | Role | -|---|---| -| `ci/colorize_cppcheck_results.py` | Post-processes cppcheck output with ANSI colors | diff --git a/developer/doc/ci/workflows/export_standards_data.md b/developer/doc/ci/workflows/export_standards_data.md deleted file mode 100644 index c1b4a513b..000000000 --- a/developer/doc/ci/workflows/export_standards_data.md +++ /dev/null @@ -1,82 +0,0 @@ -# Workflow: `export_standards_data.yml` — Manual Standards Export - -> **File:** `.github/workflows/export_standards_data.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Manually triggered workflow that downloads the current OpenStudio SDK, runs the Ruby script that generates OpenStudio Standards template `.osm` files, and commits the results back to the repository. This is how the bundled template models in `src/openstudio_app/Resources/` are kept up to date with new SDK releases. - ---- - -## Trigger - -```yaml -on: - workflow_dispatch: - inputs: - os_installer_link: - description: 'URL of the OpenStudio SDK Linux .deb (optional override)' - required: false - branch_name: - description: 'Branch to commit results to (optional, defaults to current)' - required: false -``` - ---- - -## Job - -```mermaid -flowchart TD - A["export-os-standards job\nubuntu-latest"] --> B["Checkout"] - B --> C["Parse SDK version from FindOpenStudioSDK.cmake\n(inline Python)"] - C --> D{os_installer_link input set?} - D -- yes --> DIRECT["Use provided URL"] - D -- no --> DETECT["Try default URL\nFallback: S3 alternate URL\nFallback: latest GitHub release"] - DIRECT --> E["Download + install OpenStudio SDK .deb"] - DETECT --> E - E --> F[Setup target branch\n(create if not exists)] - F --> G["Run: N=$(nproc) openstudio export_openstudio_standards_libraries.rb\nin developer/ruby/"] - G --> H["Copy generated .osm files\nto src/openstudio_app/Resources/"] - H --> I["Copy export logs"] - I --> J["git add + git commit + git push\nto target branch"] -``` - ---- - -## When to Run - -Run this workflow when: -- A new OpenStudio SDK version is released and the template OSM files need to be regenerated -- The `check_osm_versions.yml` gate is failing on the `master` PR -- Structural changes to the standards data require a full regeneration - ---- - -## Inputs - -| Input | Required | Default | Description | -|---|---|---|---| -| `os_installer_link` | No | Auto-detected | Direct URL to an OpenStudio SDK `.deb` installer | -| `branch_name` | No | Current branch | Target branch to commit the generated OSM files to | - ---- - -## Outputs - -After the workflow runs, it commits to the target branch: -- Updated `.osm` files in `src/openstudio_app/Resources/` -- Export log files from the Ruby script - -Create a PR from the target branch to merge the updated OSMs into `develop` or `master`. - ---- - -## Related Files - -| File | Role | -|---|---| -| `developer/ruby/export_openstudio_standards_libraries.rb` | Ruby script that generates the OSM files | -| `FindOpenStudioSDK.cmake` | Source of the SDK version number for download URL construction | -| `src/openstudio_app/Resources/*.osm` | Generated template files committed by this workflow | diff --git a/developer/doc/ci/workflows/manual_cli_test.md b/developer/doc/ci/workflows/manual_cli_test.md deleted file mode 100644 index a48c17ba7..000000000 --- a/developer/doc/ci/workflows/manual_cli_test.md +++ /dev/null @@ -1,92 +0,0 @@ -# Workflow: `manual_cli_test.yml` — Manual CLI Integration Test - -> **File:** `.github/workflows/manual_cli_test.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Manually triggered smoke test workflow that downloads a previously built installer archive from a specific workflow run and verifies that the OpenStudio CLI works correctly on all 5 platforms. Tests cover both the classic Ruby CLI and the newer C++ (labs) CLI, including EnergyPlus and Python scripting. - ---- - -## Trigger - -```yaml -on: - workflow_dispatch: - inputs: - run_id: - description: 'Run ID of the app_build workflow to test' - required: true -``` - ---- - -## Matrix - -```mermaid -flowchart LR - MATRIX["5-platform matrix"] --> U20["ubuntu-20.04"] - MATRIX --> U22["ubuntu-22.04"] - MATRIX --> WIN["windows-2022"] - MATRIX --> M13["macos-13 x86_64"] - MATRIX --> MARM["macos arm64\n(self-hosted runner)"] -``` - ---- - -## Job Steps - -```mermaid -flowchart TD - A["Download archive artifact\nfrom run_id"] --> B["Extract archive"] - B --> C["Locate Examples/compact_osw/ directory"] - C --> D["Detect default CLI:\nRuby (classic) or C++ (labs)"] - D --> E["EnergyPlus smoke test:\n'energyplus --version'"] - E --> F["Classic Ruby CLI tests"] - F --> G["Labs C++ CLI tests"] - G --> H["'tree' output of install structure"] - H --> I["ldd / otool lib inspection"] -``` - ---- - -## Test Coverage - -### Classic Ruby CLI Tests - -| Test | Command | -|---|---| -| Help | `openstudio --help` | -| Version | `openstudio --version` | -| Ruby snippet | `openstudio -e "puts OpenStudio::openStudioVersion()"` | -| Gem require | `openstudio -e "require 'oga'; puts 'oga OK'"` | -| Execute script | `openstudio execute_ruby_script test.rb` | -| Run workflow | `openstudio run -w compact_ruby_only.osw` | - -### Labs C++ CLI Tests - -All Ruby tests above, plus: - -| Test | Command | -|---|---| -| Python version | `openstudio labs python --version` | -| Execute Python script | `openstudio labs execute_python_script test.py` | -| Mixed Ruby/Python OSW | `openstudio run -w compact_ruby_python.osw` | -| Multiple mixed workflows | Additional OSW permutations | - ---- - -## When to Run - -- After a successful `app_build.yml` run produces installer artifacts that you want to validate before releasing -- When investigating CLI regressions on a specific platform -- After updating Ruby or Python bindings - ---- - -## Required Inputs - -| Input | Description | -|---|---| -| `run_id` | The numeric ID of a prior `app_build.yml` workflow run (visible in the GitHub Actions URL) | diff --git a/developer/doc/ci/workflows/release_notes.md b/developer/doc/ci/workflows/release_notes.md deleted file mode 100644 index b36a66475..000000000 --- a/developer/doc/ci/workflows/release_notes.md +++ /dev/null @@ -1,76 +0,0 @@ -# Workflow: `release_notes.yml` — Automated Changelog - -> **File:** `.github/workflows/release_notes.yml` -> **Back to:** [CI/CD Overview](../overview.md) - -## Purpose - -Automatically generates and appends a changelog to a GitHub Release when the release is created. The changelog is built by querying the GitHub Issues API for all issues closed since the last release. - ---- - -## Trigger - -```yaml -on: - release: - types: [created] -``` - -Fires once when a new GitHub Release is created (not on draft creation). - ---- - -## Job - -```mermaid -flowchart TD - A["release-notes job\nubuntu-latest"] --> B["Checkout"] - B --> C["Setup Ruby 3.2"] - C --> D["Setup Python 3.8"] - D --> E["Install github_api gem\nInstall requests Python package"] - E --> F["Run developer/ruby/GitHubIssueStats.rb\n→ changelog.txt"] - F --> G["PATCH /repos/:owner/:repo/releases/:id\nAppend changelog to release body"] -``` - ---- - -## Key Step - -`developer/ruby/GitHubIssueStats.rb` queries the GitHub Issues API for issues closed between the previous release tag and the current one, formats them into a Markdown changelog, and writes `changelog.txt`. - -The changelog is then appended to the release body via: -```bash -curl -X PATCH \ - -H "Authorization: token $GITHUB_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"body\": \"$RELEASE_BODY\n\n$CHANGELOG\"}" \ - https://api.github.com/repos/openstudiocoalition/OpenStudioApplication/releases/$RELEASE_ID -``` - ---- - -## Outputs - -The GitHub Release body is updated to include a section like: - -```markdown -## Changes - -### Bug Fixes -- Fix crash when opening models with orphan spaces (#1234) - -### New Features -- Add support for EnergyPlus 24.1 output variables (#1198) - -### Improvements -- Improve geometry editor performance on large models (#1201) -``` - ---- - -## Related Files - -| File | Role | -|---|---| -| `developer/ruby/GitHubIssueStats.rb` | Generates the changelog from GitHub Issues API | diff --git a/developer/doc/classes/bimserver/BIMserverConnection.md b/developer/doc/classes/bimserver/BIMserverConnection.md deleted file mode 100644 index 5ec5945a2..000000000 --- a/developer/doc/classes/bimserver/BIMserverConnection.md +++ /dev/null @@ -1,111 +0,0 @@ -# Class: `BIMserverConnection` - -> **Module:** `bimserver` -> **Header:** [src/bimserver/BIMserverConnection.hpp](../../../../src/bimserver/BIMserverConnection.hpp) -> **Library doc:** [libraries/bimserver.md](../../libraries/bimserver.md) - -## Purpose - -`BIMserverConnection` is the HTTP client for the BIMserver REST API. It uses Qt's `QNetworkAccessManager` to send JSON-RPC style POST requests to a BIMserver instance and routes responses back to callers via Qt signals (async) or blocking return values (sync). - -A single `BIMserverConnection` is associated with one BIMserver address/port pair. All authentication state (session token) is maintained internally after a successful login. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QObject { - <> - } - class BIMserverConnection { - <> - -addr: QString - -port: QString - -token: QString - -manager: QNetworkAccessManager* - +BIMserverConnection(parent, addr, port) - +login(username, password) - +getAllProjects() - +download(revisionID) - +createProject(name) - +deleteProject(projectID) - +checkInIFCFile(projectID, path) - +getIFCRevisionList(projectID) - +loginBlocked(username, password, timeout) bool - +getAllProjectsBlocked(timeout) optional~QStringList~ - +downloadBlocked(projectID, timeout) optional~QString~ - +createProjectBlocked(name, timeout) bool - +deleteProjectBlocked(projectID, timeout) bool - +checkInIFCFileBlocked(projectID, path, timeout) bool - +getIFCRevisionListBlocked(projectID, timeout) optional~QStringList~ - signals: loginSuccess() - signals: loginFailed() - signals: allProjectsAvailable(QStringList) - signals: osmStringAvailable(QString) - signals: newProjectAdded() - signals: projectDeleted() - signals: ifcCheckedIn() - signals: ifcRevisionListAvailable(QStringList) - signals: errorOccured(QString) - signals: progressUpdated(int) - } - - QObject <|-- BIMserverConnection -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `parent` | `QObject*` | Qt parent (typically `ProjectImporter`) | -| `bimserverAddr` | `const QString&` | Hostname or IP of the BIMserver instance | -| `bimserverPort` | `const QString&` | Port number (e.g., `"8080"`) | - ---- - -## Non-Blocking API - -All non-blocking methods POST a JSON request and return immediately. The result is delivered asynchronously via the corresponding signal. - -| Method | Response signal | -|---|---| -| `login(username, password)` | `loginSuccess()` / `loginFailed()` | -| `getAllProjects()` | `allProjectsAvailable(QStringList)` | -| `download(revisionID)` | `osmStringAvailable(QString)` | -| `createProject(name)` | `newProjectAdded()` | -| `deleteProject(projectID)` | `projectDeleted()` | -| `checkInIFCFile(projectID, path)` | `ifcCheckedIn()` + `progressUpdated(int)` | -| `getIFCRevisionList(projectID)` | `ifcRevisionListAvailable(QStringList)` | - ---- - -## Blocking API - -Each blocking variant spins a `QEventLoop` with a `QTimer` timeout. Returns a result or `boost::none` on timeout/failure. - -| Method | Returns | -|---|---| -| `loginBlocked(username, password, timeout)` | `bool` | -| `getAllProjectsBlocked(timeout)` | `optional` | -| `downloadBlocked(projectID, timeout)` | `optional` (OSM string) | -| `createProjectBlocked(name, timeout)` | `bool` | -| `deleteProjectBlocked(projectID, timeout)` | `bool` | -| `checkInIFCFileBlocked(projectID, path, timeout)` | `bool` | -| `getIFCRevisionListBlocked(projectID, timeout)` | `optional` | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `loginSuccess` | — | Login POST succeeded and a session token was received | -| `loginFailed` | — | Login failed (wrong credentials or server unreachable) | -| `allProjectsAvailable` | `QStringList projects` | List of project names returned by the server | -| `osmStringAvailable` | `QString osmString` | Full OSM file content returned after download | -| `errorOccured` | `QString message` | Any network or protocol error | -| `progressUpdated` | `int percent` | IFC check-in progress (0–100) | diff --git a/developer/doc/classes/bimserver/ProjectImporter.md b/developer/doc/classes/bimserver/ProjectImporter.md deleted file mode 100644 index 795b18161..000000000 --- a/developer/doc/classes/bimserver/ProjectImporter.md +++ /dev/null @@ -1,100 +0,0 @@ -# Class: `ProjectImporter` - -> **Module:** `bimserver` -> **Header:** [src/bimserver/ProjectImporter.hpp](../../../../src/bimserver/ProjectImporter.hpp) -> **Library doc:** [libraries/bimserver.md](../../libraries/bimserver.md) - -## Purpose - -`ProjectImporter` is a dialog-based workflow that guides the user through connecting to a BIMserver, listing available projects, selecting one, and importing it as an OpenStudio Model. - -It owns a `BIMserverConnection` and orchestrates the multi-step process: -1. Show the BIMserver address/port/credentials form -2. Log in and retrieve the project list -3. Let the user select a project and revision -4. Download the OSM content and parse it into an `openstudio::model::Model` - ---- - -## Class Diagram - -```mermaid -classDiagram - class QDialog { - <> - } - class ProjectImporter { - <> - +ProjectImporter(parent) - +exec() int - +getModel() optional~Model~ - signals: modelImported(Model) - slots: onLoginClicked() - slots: onProjectSelected(QString) - slots: onDownloadClicked() - slots: onLoginSuccess() - slots: onLoginFailed() - slots: onAllProjectsAvailable(QStringList) - slots: onOsmStringAvailable(QString) - slots: onErrorOccured(QString) - } - class BIMserverConnection { - +loginBlocked(...) bool - +getAllProjects() - +download(revisionID) - signals: loginSuccess, allProjectsAvailable, osmStringAvailable, errorOccured - } - - QDialog <|-- ProjectImporter - ProjectImporter "1" *-- "1" BIMserverConnection : owns -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `parent` | `QWidget*` | Qt parent widget | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `exec()` | `int` | Shows the dialog modally; returns `QDialog::Accepted` if the user successfully imported a project | -| `getModel()` | `boost::optional` | Returns the imported model after `exec()` returns `Accepted` | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelImported` | `model::Model` | Emitted when the import is complete; callers can connect to this to receive the model without waiting for `exec()` | - ---- - -## Import Workflow - -```mermaid -sequenceDiagram - participant User - participant Dialog as ProjectImporter - participant Conn as BIMserverConnection - - User->>Dialog: Enter BIMserver URL, credentials - User->>Dialog: Click Login - Dialog->>Conn: login(username, password) - Conn-->>Dialog: loginSuccess() - Dialog->>Conn: getAllProjects() - Conn-->>Dialog: allProjectsAvailable(projectList) - Dialog-->>User: Show project list - User->>Dialog: Select project + revision - User->>Dialog: Click Import - Dialog->>Conn: download(revisionID) - Conn-->>Dialog: osmStringAvailable(osmString) - Dialog->>Dialog: parse OSM string into Model - Dialog-->>User: Close dialog (Accepted) -``` diff --git a/developer/doc/classes/model_editor/AccessPolicyStore.md b/developer/doc/classes/model_editor/AccessPolicyStore.md deleted file mode 100644 index cd76a1750..000000000 --- a/developer/doc/classes/model_editor/AccessPolicyStore.md +++ /dev/null @@ -1,69 +0,0 @@ -# Class: `AccessPolicyStore` - -> **Module:** `model_editor` -> **Header:** [src/model_editor/AccessPolicyStore.hpp](../../../../src/model_editor/AccessPolicyStore.hpp) -> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) - -## Purpose - -`AccessPolicyStore` is a singleton that controls which IDD fields `InspectorGadget` renders as editable, read-only, or hidden. It reads an XML policy file at startup and provides per-field `AccessPolicy` queries to `InspectorGadget` during widget construction. - -Without a loaded policy, all fields default to `FREE` (editable). - ---- - -## Class Diagram - -```mermaid -classDiagram - class AccessPolicyStore { - <> - +instance() AccessPolicyStore& - +loadFile(path) bool - +getPolicy(iddObjectType, fieldIndex) AccessPolicy - +setPolicy(iddObjectType, fieldIndex, policy) - } - class InspectorGadget { - # queries AccessPolicyStore per field - } - - AccessPolicyStore <-- InspectorGadget : queries -``` - ---- - -## `AccessPolicy` Enum - -| Value | Meaning | -|---|---| -| `FREE` | Field is editable; rendered as an input widget (spinbox, combobox, lineedit) | -| `LOCKED` | Field is read-only; rendered as a `QLabel` | -| `HIDDEN` | Field is not rendered at all | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `instance()` | `AccessPolicyStore&` | Returns the singleton instance | -| `loadFile(path)` | `bool` | Parses an XML policy file; returns `false` if the file cannot be opened or parsed | -| `getPolicy(iddObjectType, fieldIndex)` | `AccessPolicy` | Returns the policy for a specific IDD object type and field index | -| `setPolicy(iddObjectType, fieldIndex, policy)` | `void` | Programmatically overrides a policy at runtime | - ---- - -## Policy File Format - -The XML policy file specifies overrides from the `FREE` default: - -```xml - - - - - - -``` - -Fields not listed default to `FREE`. To lock all fields for an object type, specify policy `LOCKED` with `index="*"`. diff --git a/developer/doc/classes/model_editor/InspectorDialog.md b/developer/doc/classes/model_editor/InspectorDialog.md deleted file mode 100644 index 0c73bff27..000000000 --- a/developer/doc/classes/model_editor/InspectorDialog.md +++ /dev/null @@ -1,72 +0,0 @@ -# Class: `InspectorDialog` - -> **Module:** `model_editor` -> **Header:** [src/model_editor/InspectorDialog.hpp](../../../../src/model_editor/InspectorDialog.hpp) -> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) - -## Purpose - -`InspectorDialog` is a modal or modeless top-level dialog that hosts an `InspectorGadget`. It subscribes to a `Workspace` (or `Model`) to track object additions/removals and update the gadget whenever the selected object changes. - -It is primarily used as a standalone debugging tool and in the SketchUp plugin to inspect arbitrary model objects. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QDialog { - <> - } - class InspectorDialog { - +InspectorDialog(workspace, parent) - +setWorkspace(workspace) - +selectedObjectHandles() vector~Handle~ - +setSelectedObjectHandles(handles) - signals: workspaceChanged() - signals: workspaceObjectAdded(WorkspaceObject, IddObjectType, UUID) - signals: workspaceObjectRemoved(WorkspaceObject, IddObjectType, UUID) - signals: selectedObjectHandlesChanged(vector~Handle~) - } - class InspectorGadget { - +layoutModel(workspaceObj, ...) - } - class Workspace { - <> - } - - QDialog <|-- InspectorDialog - InspectorDialog "1" *-- "1" InspectorGadget : embeds - InspectorDialog --> Workspace : observes -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `workspace` | `openstudio::Workspace&` | The workspace to observe; the dialog subscribes to its object change signals | -| `parent` | `QWidget*` | Qt parent (can be nullptr for modeless usage) | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `setWorkspace(workspace)` | `void` | Detaches from old workspace, subscribes to new; clears and re-populates the gadget | -| `selectedObjectHandles()` | `vector` | Returns the handles of objects currently selected in the object type list | -| `setSelectedObjectHandles(handles)` | `void` | Programmatically selects objects to inspect | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `workspaceChanged` | — | Emitted when the workspace is replaced | -| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | -| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | -| `selectedObjectHandlesChanged` | `vector` | Emitted when selection changes | diff --git a/developer/doc/classes/model_editor/InspectorGadget.md b/developer/doc/classes/model_editor/InspectorGadget.md deleted file mode 100644 index c2d675c65..000000000 --- a/developer/doc/classes/model_editor/InspectorGadget.md +++ /dev/null @@ -1,96 +0,0 @@ -# Class: `InspectorGadget` - -> **Module:** `model_editor` -> **Header:** [src/model_editor/InspectorGadget.hpp](../../../../src/model_editor/InspectorGadget.hpp) -> **Library doc:** [libraries/model_editor.md](../../libraries/model_editor.md) - -## Purpose - -`InspectorGadget` is the core widget of the `model_editor` module. It accepts any `WorkspaceObject` or `ModelObject` and automatically generates a widget layout for all its IDD-defined fields, using `AccessPolicyStore` to determine which fields are editable, read-only, or hidden. - -This provides a "free" generic inspector for any OpenStudio object type without writing bespoke UI code. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class Nano_Observer { - <> - } - class IGWidget { - <> - +sizeHint() QSize - } - class InspectorGadget { - <> - +layoutModel(workspaceObj, recursive, hideChildren) - +layoutModelObj(modelObj, recursive, hideChildren, locked) - +clear() - +toggleGreenButton(isPushButton) - +setEnabled(enabled) - signals: nameChanged(QString) - signals: toggleUnitsClicked(bool) - signals: workspaceObjectAdded(WorkspaceObject, IddObjectType, UUID) - signals: workspaceObjectRemoved(WorkspaceObject, IddObjectType, UUID) - } - class AccessPolicyStore { - <> - +getPolicy(type, fieldIndex) AccessPolicy - } - - QWidget <|-- IGWidget - Nano_Observer <|.. IGWidget - QWidget <|-- InspectorGadget - Nano_Observer <|.. InspectorGadget - InspectorGadget --> AccessPolicyStore : queries per field - InspectorGadget *-- IGWidget : renders fields into -``` - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `layoutModel(wObj, recursive, hideChildren)` | `void` | Populates the widget from a `WorkspaceObject`; recursively follows references if `recursive = true` | -| `layoutModelObj(mObj, recursive, hideChildren, locked)` | `void` | Same, but starts from a `ModelObject`; `locked = true` forces all fields into read-only mode | -| `clear()` | `void` | Removes all generated widgets | -| `toggleGreenButton(isPushButton)` | `void` | Switches the "inspect object" button style | -| `setEnabled(bool)` | `void` | Enables/disables all child widgets | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `nameChanged` | `QString newName` | Emitted when the user edits the object's Name field | -| `toggleUnitsClicked` | `bool displayIP` | Emitted when the IP/SI toggle button is clicked | -| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace; keeps the inspector in sync | -| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the workspace | - ---- - -## Field Generation Rules - -| IDD Field Type | `FREE` policy | `LOCKED` policy | -|---|---|---| -| Real | `QDoubleSpinBox` | `QLabel` | -| Integer | `QSpinBox` | `QLabel` | -| Alpha / String | `QLineEdit` | `QLabel` | -| Choice | `IGComboBox` | `QLabel` | -| Boolean | `QCheckBox` | `QLabel` | -| Object reference | `QLineEdit` + lookup button | `QLabel` (hyperlink) | - -Fields with `AccessPolicy::HIDDEN` are not rendered at all. - ---- - -## `IGWidget` - -`IGWidget` is a thin `QWidget`/`Nano::Observer` subclass that serves as the scroll area content host for the generated controls. It overrides `sizeHint()` to correctly report its natural size after field generation. diff --git a/developer/doc/classes/openstudio_app/OpenStudioApp.md b/developer/doc/classes/openstudio_app/OpenStudioApp.md deleted file mode 100644 index 79f352910..000000000 --- a/developer/doc/classes/openstudio_app/OpenStudioApp.md +++ /dev/null @@ -1,115 +0,0 @@ -# Class: `OpenStudioApp` - -> **Module:** `openstudio_app` -> **Header:** [src/openstudio_app/OpenStudioApp.hpp](../../../../src/openstudio_app/OpenStudioApp.hpp) -> **Library doc:** [libraries/openstudio_app.md](../../libraries/openstudio_app.md) - -## Purpose - -`OpenStudioApp` is the concrete application object for the standalone OpenStudio Application. It extends `OSAppBase` (which extends `QApplication`) and is instantiated once in `main()`. - -Responsibilities: -- Constructs the initial `StartupView` and `StartupMenu` at launch -- Opens new or existing `.osm` files and wraps them in an `OSDocument` -- Runs `osversion::VersionTranslator` asynchronously (via `QFutureWatcher`) when opening older model files -- Provides access to the component library and HVAC template library models -- Manages translation (i18n) via `QTranslator` -- Handles the `dview` external tool path preference - ---- - -## Class Diagram - -```mermaid -classDiagram - class QApplication { - <> - } - class BaseApp { - <> - } - class OSAppBase { - <> - +instance() OSAppBase* - +measureManager() MeasureManager& - +currentDocument() OSDocument* = 0 - } - class OpenStudioApp { - +OpenStudioApp(argc, argv) - +currentDocument() OSDocument* - +instance() OpenStudioApp* - +componentLibrary() Model - +hvacComponentLibrary() Model - +resourcesPath() path - +openstudioCLIPath() path - +dviewPath() path - } - - QApplication <|-- OSAppBase - BaseApp <|.. OSAppBase - OSAppBase <|-- OpenStudioApp -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `argc` | `int&` | Standard C++ `argc` (passed through to `QApplication`) | -| `argv` | `char**` | Standard C++ `argv` (passed through to `QApplication`) | - -The constructor initialises the Qt application, registers `QMetaTypes`, installs the application icon, loads the QSS stylesheet (`resources/openstudio.qss`), instantiates `MeasureManager`, and shows the `StartupView`. - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `currentDocument()` | `shared_ptr` | Returns the currently open document, or `nullptr` if no document is open | -| `instance()` | `OpenStudioApp*` | Static method; returns the singleton application instance cast to `OpenStudioApp*` | -| `componentLibrary()` | `model::Model` | Returns the loaded component library model (for drag-and-drop from the right column library tab) | -| `hvacComponentLibrary()` | `model::Model` | Returns the HVAC template library containing pre-built loop templates | -| `resourcesPath()` | `openstudio::path` | Absolute path to the application's resources directory, resolved relative to the running executable | -| `openstudioCLIPath()` | `openstudio::path` | Absolute path to the `openstudio` CLI executable bundled with the application | -| `dviewPath()` | `openstudio::path` | Path to the DView results viewer, from settings or inferred from `PATH` | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `requestCloseAll` | — | Emitted when the application is about to quit; triggers document close | -| `newModelDropped` | — | Emitted when the user drops a new model file onto the application window | - ---- - -## Key Data Members - -| Member | Type | Description | -|---|---|---| -| `m_startupView` | `StartupView*` | Splash/welcome screen shown before a document is open | -| `m_startupMenu` | `StartupMenu*` | Minimal menu bar for the startup screen | -| `m_document` | `shared_ptr` | The currently open document | -| `m_versionTranslator` | `QFutureWatcher<...>` | Async watcher for version translation tasks | -| `m_translators` | `QList` | Loaded i18n translators | - ---- - -## Usage Pattern - -```cpp -// main.cpp -int main(int argc, char *argv[]) { - OpenStudioApp app(argc, argv); - return app.exec(); -} -``` - -All subsequent access to the application object is via the static accessor: -```cpp -OpenStudioApp* app = OpenStudioApp::instance(); -auto model = app->currentDocument()->model(); -``` diff --git a/developer/doc/classes/openstudio_app/StartupView.md b/developer/doc/classes/openstudio_app/StartupView.md deleted file mode 100644 index 651fc3ba2..000000000 --- a/developer/doc/classes/openstudio_app/StartupView.md +++ /dev/null @@ -1,60 +0,0 @@ -# Class: `StartupView` - -> **Module:** `openstudio_app` -> **Header:** [src/openstudio_app/StartupView.hpp](../../../../src/openstudio_app/StartupView.hpp) -> **Library doc:** [libraries/openstudio_app.md](../../libraries/openstudio_app.md) - -## Purpose - -`StartupView` is the welcome/splash screen displayed when the OpenStudio Application launches and no document is yet open. It presents the user with options to create a new model, open an existing file, or select a recently used file. - -It is shown and hidden by `OpenStudioApp` in response to document open/close events. When the user opens a document, `StartupView` is hidden; when they close the last document, it reappears. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class StartupView { - +StartupView(parent) - signals: newFromTemplateClicked(NewFromTemplateAction) - signals: openClicked() - signals: recentModelClicked(path) - } - class OpenStudioApp { - -m_startupView: StartupView* - } - - QWidget <|-- StartupView - OpenStudioApp "1" --> "1" StartupView : owns, shows/hides -``` - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `newFromTemplateClicked` | `NewFromTemplateAction` | User clicked one of the "New from template" buttons; the action enum identifies which template | -| `openClicked` | — | User clicked "Open..." — triggers a file dialog in `OpenStudioApp` | -| `recentModelClicked` | `openstudio::path` | User selected a recently used model from the list | - ---- - -## Key Data Members - -The view contains: -- A logo/banner area with the OpenStudio Coalition branding -- A list of "New from template" buttons for common starting points (empty model, residential, commercial) -- An "Open..." button -- A scrollable recent files list showing the last N opened `.osm` files with their paths - ---- - -## Relationship to `StartupMenu` - -`StartupMenu` provides a minimal menu bar (File → New, Open, Quit) that is installed on the application's main window while `StartupView` is visible. When a document is loaded, the full `MainMenu` replaces it. diff --git a/developer/doc/classes/openstudio_lib/ConstructionsController.md b/developer/doc/classes/openstudio_lib/ConstructionsController.md deleted file mode 100644 index 4f04dfebb..000000000 --- a/developer/doc/classes/openstudio_lib/ConstructionsController.md +++ /dev/null @@ -1,61 +0,0 @@ -# Class: `ConstructionsController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/ConstructionsController.hpp](../../../../src/openstudio_lib/ConstructionsController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`ConstructionsController` manages the Constructions sub-tab within the Constructions & Materials domain tab. It provides a list of all construction objects in the model, allows adding new constructions (by dropping from the component library or creating new ones), and drives the right-column inspector to show construction details when one is selected. - -It extends `OSVectorController` to supply the list of construction `OSItemId`s. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSVectorController { - <> - } - class ConstructionsController { - +ConstructionsController(model) - #makeVector() vector~OSItemId~ - #onDrop(itemId) - #onRemoveItem(item) - signals: modelObjectSelected(OptionalModelObject, bool) - } - class ConstructionsView { - <> - } - class ConstructionInspectorView { - +setConstruction(Construction) - } - - OSVectorController <|-- ConstructionsController - ConstructionsController --> ConstructionsView : populates - ConstructionsController --> ConstructionInspectorView : drives -``` - ---- - -## `makeVector()` Override - -Returns `OSItemId`s for all `openstudio::model::Construction`, `ConstructionWithInternalSource`, `ConstructionCfactorUndergroundWall`, `ConstructionFfactorGroundFloor`, and `ConstructionAirBoundary` objects in the model. - -## `onDrop()` Override - -Handles drops from the component library: if the dropped `OSItemId` references a BCL component or a component library construction, loads it into the model. - -## `onRemoveItem()` Override - -Removes the selected construction from the model after confirming there are no dependent surfaces still referencing it. - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelObjectSelected` | `OptionalModelObject, bool readOnly` | Emitted on selection; drives the inspector | diff --git a/developer/doc/classes/openstudio_lib/GeometryEditorController.md b/developer/doc/classes/openstudio_lib/GeometryEditorController.md deleted file mode 100644 index c0f0b64c3..000000000 --- a/developer/doc/classes/openstudio_lib/GeometryEditorController.md +++ /dev/null @@ -1,85 +0,0 @@ -# Class: `GeometryEditorController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/GeometryEditorController.hpp](../../../../src/openstudio_lib/GeometryEditorController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`GeometryEditorController` manages the Geometry tab's interactive 3D editor. The editor is implemented as a Qt WebEngine view hosting a JavaScript application that renders and edits OpenStudio geometry. The controller bridges the C++ model layer and the JavaScript geometry engine via `OSWebEnginePage`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class GeometryEditorController { - +GeometryEditorController(isIP, model) - +view() QWidget* - #m_view: QWidget* - } - class GeometryEditorView { - <> - +webEngineView() QWebEngineView* - } - class OSWebEnginePage { - <> - +setModel(model) - +getModel() Model - signals: modelChanged(Model) - } - - OSQObjectController <|-- GeometryEditorController - GeometryEditorController "1" *-- "1" GeometryEditorView : creates and stores as m_view - GeometryEditorView "1" *-- "1" OSWebEnginePage : hosts -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `isIP` | `bool` | Whether to display dimensions in imperial units | -| `model` | `const model::Model&` | The OpenStudio model whose geometry is displayed | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `view()` | `QWidget*` | The view widget (`GeometryEditorView`) to embed in the tab | - ---- - -## Architecture Note - -The geometry editor is built around a JS/C++ bridge: - -```mermaid -flowchart LR - CPP["C++ Model\n(openstudio::model::Model)"] - CTRL["GeometryEditorController"] - PAGE["OSWebEnginePage\n(QWebEnginePage)"] - WEB["Qt WebEngine\n(Chromium)"] - JS["JavaScript\nGeometry Engine\n(Three.js / custom)"] - GLTF["GLTF\n(TinyGLTF)"] - - CPP --"serialize to GLTF"--> GLTF - GLTF --> PAGE - PAGE --"postMessage / QWebChannel"--> WEB - WEB --> JS - JS --"user edits"--> WEB - WEB --"runJavaScript callback"--> PAGE - PAGE --"deserialize GLTF"--> CPP - CTRL --> PAGE -``` - -Model geometry is serialised to GLTF JSON and injected into the JavaScript engine; user edits in 3D are sent back as GLTF diffs, which `OSWebEnginePage` deserialises back into OpenStudio model objects. - -See [OSWebEnginePage](OSWebEnginePage.md) for the JS bridge API details. diff --git a/developer/doc/classes/openstudio_lib/HVACSystemsController.md b/developer/doc/classes/openstudio_lib/HVACSystemsController.md deleted file mode 100644 index daeb438b9..000000000 --- a/developer/doc/classes/openstudio_lib/HVACSystemsController.md +++ /dev/null @@ -1,124 +0,0 @@ -# Class: `HVACSystemsController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/HVACSystemsController.hpp](../../../../src/openstudio_lib/HVACSystemsController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`HVACSystemsController` manages the HVAC Systems tab, which is the most complex tab in the application. It displays a graphical scene of HVAC loops (air loops, plant loops, service water loops, VRF systems, refrigeration systems) and allows users to add, remove, and configure HVAC components by dragging them on the scene. - -The controller owns sub-controllers for different aspects of HVAC display: -- `HVACLayoutController` — manages the loop topology `QGraphicsScene` (component placement) -- `HVACControlsController` — manages the controls view (setpoint managers, availability managers, mechanical ventilation) -- `RefrigerationController` / `RefrigerationGridController` — dedicated refrigeration system view -- `VRFController` — dedicated VRF system view - ---- - -## Class Diagram - -```mermaid -classDiagram - class QObject { - <> - } - class Nano_Observer { - <> - } - class HVACSystemsController { - +HVACSystemsController(isIP, model) - +hvacSystemsView() HVACSystemsView* - +model() Model - +currentLoop() optional~Loop~ - +setCurrentLoop(loop) - signals: modelObjectSelected(OptionalModelObject, bool) - signals: itemRemoveClicked(OSItem*) - slots: addToModel(OSItemId) - slots: removeFromModel(OSItemId) - slots: toggleUnitsClicked(bool) - } - class HVACSystemsView { - +hvacGraphicsView() HVACGraphicsView* - signals: addSystemClicked, removeLoopClicked - } - class HVACLayoutController { - +loopScene() LoopScene* - } - class HVACControlsController { - +hvacControlsView() QWidget* - } - class VRFController { - +vrfView() QWidget* - } - class RefrigerationController { - +refrigerationView() QWidget* - } - class LoopListModel { - <> - +data(index, role) - } - - QObject <|-- HVACSystemsController - Nano_Observer <|.. HVACSystemsController - HVACSystemsController "1" *-- "1" HVACSystemsView : owns - HVACSystemsController "1" *-- "1" HVACLayoutController : owns - HVACSystemsController "1" *-- "1" HVACControlsController : owns - HVACSystemsController "1" *-- "1" VRFController : owns - HVACSystemsController "1" *-- "1" RefrigerationController : owns - HVACSystemsController --> LoopListModel : populates loop selector -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `isIP` | `bool` | Whether to display values in imperial units | -| `model` | `const model::Model&` | The OpenStudio model containing HVAC objects | - ---- - -## `SceneType` Enum - -| Value | Description | -|---|---| -| `TOPOLOGY` | Shows the graphical loop diagram (default) | -| `CONTROLS` | Shows the setpoint managers and controls configuration | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `hvacSystemsView()` | `HVACSystemsView*` | The main view widget for the HVAC tab | -| `model()` | `model::Model` | The current model | -| `currentLoop()` | `optional` | The currently selected loop (air, plant, or VRF) | -| `setCurrentLoop(loop)` | `void` | Switches the scene to display the given loop | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelObjectSelected` | `OptionalModelObject, bool readOnly` | Emitted when user clicks an HVAC component; drives the right-column inspector | -| `itemRemoveClicked` | `OSItem*` | Emitted when user removes a component | - ---- - -## Qt Slots - -| Slot | Arguments | Description | -|---|---|---| -| `addToModel` | `OSItemId` | Adds the identified HVAC component type to the current loop | -| `removeFromModel` | `OSItemId` | Removes the identified component from the current loop | -| `toggleUnitsClicked` | `bool displayIP` | Refreshes all numeric displays on units change | - ---- - -## HVAC Scenes - -The topology scene is built from `LoopScene` (for air/plant loops), `ServiceWaterScene` (for service hot water loops), and custom scenes for VRF and refrigeration. Each scene is a `QGraphicsScene` subclass containing `GridItem` and `SystemCenterItem` nodes connected by `TwoConnectorItem` edges, mirroring the loop topology in the model. diff --git a/developer/doc/classes/openstudio_lib/HVACSystemsView.md b/developer/doc/classes/openstudio_lib/HVACSystemsView.md deleted file mode 100644 index 1d07f7b34..000000000 --- a/developer/doc/classes/openstudio_lib/HVACSystemsView.md +++ /dev/null @@ -1,60 +0,0 @@ -# Class: `HVACSystemsView` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/HVACSystemsView.hpp](../../../../src/openstudio_lib/HVACSystemsView.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`HVACSystemsView` is the top-level view widget for the HVAC Systems tab. It contains: -- A **loop selector** combo box listing all HVAC loops in the model -- A **scene type toggle** (Topology / Controls) -- A `HVACGraphicsView` (`QGraphicsView`) displaying either the loop diagram or the controls panel -- Toolbar buttons for adding/removing loops and HVAC systems - -It delegates all display and interaction logic to `HVACSystemsController`, which calls into `HVACLayoutController` and `HVACControlsController`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class HVACSystemsView { - +hvacGraphicsView() HVACGraphicsView* - +loopComboBox() QComboBox* - +topologyViewButton() QPushButton* - +controlsViewButton() QPushButton* - signals: addSystemClicked() - signals: removeLoopClicked() - signals: systemComboBoxIndexChanged(int) - signals: topologyViewClicked() - signals: controlsViewClicked() - } - class HVACGraphicsView { - <> - +setScene(QGraphicsScene*) - } - class HVACSystemsController { - +hvacSystemsView() HVACSystemsView* - } - - QWidget <|-- HVACSystemsView - HVACSystemsView "1" *-- "1" HVACGraphicsView : contains - HVACSystemsController "1" *-- "1" HVACSystemsView : owns -``` - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `addSystemClicked` | — | User clicked the "Add System" button to add a new HVAC template | -| `removeLoopClicked` | — | User clicked the "Remove Loop" button | -| `systemComboBoxIndexChanged` | `int index` | User selected a different loop from the drop-down | -| `topologyViewClicked` | — | User switched to the loop topology diagram | -| `controlsViewClicked` | — | User switched to the loop controls view | diff --git a/developer/doc/classes/openstudio_lib/InspectorController.md b/developer/doc/classes/openstudio_lib/InspectorController.md deleted file mode 100644 index 059fc9876..000000000 --- a/developer/doc/classes/openstudio_lib/InspectorController.md +++ /dev/null @@ -1,66 +0,0 @@ -# Class: `InspectorController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/InspectorController.hpp](../../../../src/openstudio_lib/InspectorController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`InspectorController` manages the "Edit" tab of the right-column sidebar (`MainRightColumnController`). It receives `modelObjectSelected` signals from the active tab controller, determines the appropriate inspector view for the selected object type, and displays it. - -Each domain has its own set of `*InspectorView` classes. `InspectorController` acts as the dispatcher that selects and shows the correct view. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class InspectorController { - +inspectorView() InspectorView* - slots: selectItem(OSItem*) - slots: onClearSelection() - slots: onSelectModelObject(ModelObject) - } - class InspectorView { - <> - +selectModelObject(ModelObject) - +clearSelection() - signals: toggleUnitsClicked(bool) - } - class ScheduleDayView { - <> - } - class ConstructionInspectorView { - <> - } - - OSQObjectController <|-- InspectorController - InspectorController "1" *-- "1" InspectorView : owns - InspectorView <|-- ScheduleDayView - InspectorView <|-- ConstructionInspectorView -``` - ---- - -## Qt Slots - -| Slot | Arguments | Description | -|---|---|---| -| `selectItem(item)` | `OSItem*` | Called when an item is selected in any list or drop zone; looks up the model object and dispatches to `onSelectModelObject` | -| `onClearSelection()` | — | Clears the inspector (shows a blank/default pane) | -| `onSelectModelObject(obj)` | `model::ModelObject` | Determines the appropriate inspector view for `obj`'s IDD type and switches to it | - ---- - -## Inspector View Selection - -`InspectorController` maintains a `QStackedWidget` containing one inspector view per supported object type. On `onSelectModelObject()`, it: -1. Casts the `ModelObject` to the appropriate subtype -2. Calls `QStackedWidget::setCurrentWidget()` with the matching view -3. Calls `view->update(obj)` (or equivalent) to populate the fields - -Object types without a dedicated inspector view fall back to a generic `InspectorGadget`-based view from `model_editor`. diff --git a/developer/doc/classes/openstudio_lib/MainRightColumnController.md b/developer/doc/classes/openstudio_lib/MainRightColumnController.md deleted file mode 100644 index 5cac7c83d..000000000 --- a/developer/doc/classes/openstudio_lib/MainRightColumnController.md +++ /dev/null @@ -1,111 +0,0 @@ -# Class: `MainRightColumnController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/MainRightColumnController.hpp](../../../../src/openstudio_lib/MainRightColumnController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`MainRightColumnController` manages the right-column sidebar that appears alongside every tab. The sidebar has three tabs: - -| Tab | ID | Contents | -|---|---|---| -| **My Model** | `MY_MODEL` | A list of model objects relevant to the currently active domain tab (e.g., schedule types while on the Schedules tab) | -| **Library** | `LIBRARY` | The local measure/component library browser (`LocalLibraryController`) | -| **Edit** | `EDIT` | An inspector/editor for the currently selected model object | - -`OSDocument` calls the `configureFor*SubTab()` slots whenever the active domain tab or sub-tab changes, which switches the right column's content to match the current context. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class MainRightColumnController { - +MainRightColumnController(model, resourcesPath) - +mainRightColumnView() HorizontalTabWidget* - +measureLibraryController() QSharedPointer~LocalLibraryController~ - +inspectorController() shared_ptr~InspectorController~ - +hideMyModelTab(bool) - +isMyModelTabHidden() bool - +registerSystemItem(handle, item) - +unregisterSystemItem(handle) - +systemItem(handle) SystemItem* - slots: configureForSiteSubTab(int) - slots: configureForSchedulesSubTab(int) - slots: configureForConstructionsSubTab(int) - slots: configureForGeometrySubTab(int) - slots: configureForHVACSystemsSubTab(int) - signals: toggleUnitsClicked(bool) - signals: itemRemoveClicked(OSItem*) - } - class HorizontalTabWidget { - +addTab(widget, label) - +selectTab(int) - } - class InspectorController { - +inspectorView() InspectorView* - +selectItem(OSItem*) - } - class LocalLibraryController { - +localLibraryView() LocalLibraryView* - } - - OSQObjectController <|-- MainRightColumnController - MainRightColumnController "1" *-- "1" HorizontalTabWidget : owns view - MainRightColumnController "1" *-- "1" InspectorController : owns (Edit tab) - MainRightColumnController "1" *-- "1" LocalLibraryController : owns (Library tab) -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `model` | `model::Model` | The document's model; passed to the inspector controller | -| `resourcesPath` | `openstudio::path` | Path used to resolve icon and library resources | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `mainRightColumnView()` | `HorizontalTabWidget*` | The widget to embed in the main window's sidebar area | -| `measureLibraryController()` | `QSharedPointer` | The Library tab's measure browser controller | -| `inspectorController()` | `shared_ptr` | The Edit tab's inspector controller | -| `hideMyModelTab(bool)` | `void` | Hides the My Model tab when the active domain does not use it (e.g., Run tab) | -| `registerSystemItem(handle, item)` | `void` | Registers a `SystemItem` (HVAC loop) by handle for colour-coordination with the HVAC view | -| `systemItem(handle)` | `SystemItem*` | Returns the registered `SystemItem` for a given handle | - ---- - -## Qt Slots (configureFor* methods) - -Each of these is called by `OSDocument` when the user navigates to the corresponding domain: - -| Slot | Purpose | -|---|---| -| `configureForSiteSubTab(int)` | Sets up the My Model tab for the Site/Geometry domain | -| `configureForSchedulesSubTab(int)` | Shows relevant schedule types in My Model | -| `configureForConstructionsSubTab(int)` | Shows constructions/materials in My Model | -| `configureForGeometrySubTab(int)` | Hides My Model; shows geometry-specific edit panel | -| `configureForHVACSystemsSubTab(int)` | Shows HVAC component library | -| `configureForSpacesSubTab(int)` | Shows space-related objects | -| `configureForSimSettingsSubTab(int)` | Shows simulation settings objects | -| `configureForRunSubTab(int)` | Hides My Model tab | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `toggleUnitsClicked` | `bool displayIP` | Forwarded from the inspector view to the document | -| `toggleDisplayAdditionalPropsClicked` | `bool` | Forwarded from the inspector view | -| `itemRemoveClicked` | `OSItem*` | Forwarded when the user removes an item from the inspector | diff --git a/developer/doc/classes/openstudio_lib/MainTabController.md b/developer/doc/classes/openstudio_lib/MainTabController.md deleted file mode 100644 index 25e772150..000000000 --- a/developer/doc/classes/openstudio_lib/MainTabController.md +++ /dev/null @@ -1,105 +0,0 @@ -# Class: `MainTabController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/MainTabController.hpp](../../../../src/openstudio_lib/MainTabController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`MainTabController` is the abstract base class for every domain tab controller. A tab controller is responsible for: -- Creating and owning the domain's `MainTabView` (the central content widget) -- Implementing `setSubTab(int)` to switch between sub-tabs within the domain -- Forwarding model-object selection events, drag-and-drop zone interactions, and unit toggle signals up to `OSDocument` via signals - -Concrete sub-classes include `HVACSystemsTabController`, `ConstructionsTabController`, `SchedulesTabController`, `RunTabController`, etc. Each follows the pattern: construct the domain view in the constructor, populate it with sub-views, and emit signals when the user interacts with model objects. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class MainTabController { - <> - +MainTabController(mainContentWidget) - +mainContentWidget() MainTabView* - +setSubTab(int) = 0 - signals: modelObjectSelected(OptionalModelObject, bool) - signals: dropZoneItemSelected(OSItem*, bool) - signals: dropZoneItemClicked(OSItem*) - signals: toggleUnitsClicked(bool) - signals: toggleDisplayAdditionalPropsClicked(bool) - signals: itemRemoveClicked(OSItem*) - signals: downloadComponentsClicked() - signals: openLibDlgClicked() - } - class MainTabView { - +addTabWidget(QWidget*, QString label) - +setSubTab(int) - } - class HVACSystemsTabController { - +setSubTab(int) - } - class ConstructionsTabController { - +setSubTab(int) - } - class RunTabController { - +setSubTab(int) - signals: resultsGenerated(sqlPath, radianceOutputPath) - } - - OSQObjectController <|-- MainTabController - MainTabController "1" *-- "1" MainTabView : owns - MainTabController <|-- HVACSystemsTabController - MainTabController <|-- ConstructionsTabController - MainTabController <|-- RunTabController -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `mainContentWidget` | `MainTabView*` | The tab view owned by this controller | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `mainContentWidget()` | `MainTabView*` | The view managed by this controller | -| `setSubTab(int index)` | `void` | **Pure virtual** — switch to sub-tab at `index`. Implemented by each domain controller | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelObjectSelected` | `model::OptionalModelObject, bool readOnly` | Emitted when the user selects a model object; triggers the right-column inspector | -| `dropZoneItemSelected` | `OSItem*, bool readOnly` | Emitted when an item in a drop zone is selected | -| `dropZoneItemClicked` | `OSItem*` | Emitted on click (without necessarily selecting a different inspector) | -| `toggleUnitsClicked` | `bool displayIP` | Relays the IP/SI toggle from the view to the document | -| `toggleDisplayAdditionalPropsClicked` | `bool` | Relays the additional properties toggle | -| `itemRemoveClicked` | `OSItem*` | Emitted when the remove (×) button on an item is clicked | -| `downloadComponentsClicked` | — | Triggers opening the BCL component browser | -| `openLibDlgClicked` | — | Triggers opening the library selection dialog | - ---- - -## Implementing a New Tab Controller - -To add a new domain tab: - -1. Create a class that extends `MainTabController` -2. In the constructor, create the domain `MainTabView` and pass it to `MainTabController(view)` -3. Override `setSubTab(int)` to switch sub-views -4. Connect domain-specific interactions to the inherited signals above -5. Register the new tab in `OSDocument` by creating the controller and calling `MainWindow::addVerticalTabButton()` - -See [developer/doc/AddingHVACComponentsToGUI.md](../../AddingHVACComponentsToGUI.md) for a detailed walkthrough. diff --git a/developer/doc/classes/openstudio_lib/MainWindow.md b/developer/doc/classes/openstudio_lib/MainWindow.md deleted file mode 100644 index 7e1943b85..000000000 --- a/developer/doc/classes/openstudio_lib/MainWindow.md +++ /dev/null @@ -1,109 +0,0 @@ -# Class: `MainWindow` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/MainWindow.hpp](../../../../src/openstudio_lib/MainWindow.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`MainWindow` is the application's top-level `QMainWindow`. It owns the vertical tab bar on the left side (which switches between domains like Geometry, HVAC, Schedules, etc.), the central tab content area, and the right-column inspector/library sidebar. - -`OSDocument` creates and owns one `MainWindow`. The main window is shown when a document opens and closed when the document closes. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QMainWindow { - <> - } - class MainWindow { - +MainWindow(isPlugin, parent) - +addVerticalTabButton(id, toolTip, selectedImg, unselectedImg, disabledImg) - +setView(MainTabView*, id) - +view() MainTabView* - +setMainRightColumnView(QWidget*) - +selectVerticalTab(id) - +selectVerticalTabByIndex(index) - +verticalTabIndex() int - +displayIP() bool - +verboseOutput() bool - +useClassicCLI() bool - +displayAdditionalProps() bool - +enableRevertToSavedAction(bool) - +closeSidebar() - +openSidebar() - +geometryDiagnostics() bool - +lastPath() QString - signals: closeClicked, displayIPClicked, displayAdditionalPropsClicked - signals: newClicked, loadFileClicked, saveAsFileClicked - signals: importClicked, importSDDClicked, importIFCClicked - signals: revertFileClicked, preferencesClicked, quitClicked - } - class VerticalTabWidget { - +addTabButton(id, toolTip, selectedImg, unselectedImg) - +selectTab(id) - signals: tabSelected(int) - } - class MainMenu { - +MenuBar items - } - class AnalyticsHelper { - +sendMessage(event) - } - - QMainWindow <|-- MainWindow - MainWindow "1" *-- "1" VerticalTabWidget : left sidebar - MainWindow "1" *-- "1" MainMenu : menu bar - MainWindow "1" --> "1" AnalyticsHelper : sends usage events -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `isPlugin` | `bool` | When `true`, hides the menu bar and adjusts layout for embedding in SketchUp | -| `parent` | `QWidget*` | Optional Qt parent widget | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `addVerticalTabButton(id, toolTip, ...)` | `void` | Adds a domain tab button to the left vertical tab bar | -| `setView(view, id)` | `void` | Replaces the central content area with the given `MainTabView` | -| `view()` | `MainTabView*` | Returns the currently displayed tab view | -| `setMainRightColumnView(widget)` | `void` | Sets the widget displayed in the right-column sidebar | -| `selectVerticalTab(id)` | `void` | Programmatically switches to the tab with the given ID | -| `verticalTabIndex()` | `int` | Returns the index of the currently selected tab | -| `displayIP()` | `bool` | Returns the current unit display preference (true = imperial) | -| `verboseOutput()` | `bool` | Returns whether verbose EnergyPlus output is requested | -| `useClassicCLI()` | `bool` | Returns whether the Ruby CLI (classic) is preferred over the C++ labs CLI | -| `displayAdditionalProps()` | `bool` | Returns whether additional properties columns are shown in grid views | -| `enableRevertToSavedAction(bool)` | `void` | Enables/disables the Revert menu action | -| `closeSidebar()` / `openSidebar()` | `void` | Collapses or expands the right-column sidebar | -| `geometryDiagnostics()` | `bool` | Returns whether geometry diagnostics mode is active | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `closeClicked` | — | User clicked the window close button | -| `displayIPClicked` | `bool` | User toggled IP/SI unit display | -| `displayAdditionalPropsClicked` | `bool` | User toggled additional properties columns | -| `newClicked` | — | File → New | -| `loadFileClicked` | — | File → Open | -| `saveAsFileClicked` | — | File → Save As | -| `importClicked` | — | File → Import (OSM) | -| `importSDDClicked` | — | File → Import SDD | -| `importIFCClicked` | — | File → Import IFC | -| `revertFileClicked` | — | File → Revert to Saved | -| `preferencesClicked` | — | Edit → Preferences | -| `quitClicked` | — | File → Quit | diff --git a/developer/doc/classes/openstudio_lib/MaterialsController.md b/developer/doc/classes/openstudio_lib/MaterialsController.md deleted file mode 100644 index c11061d7a..000000000 --- a/developer/doc/classes/openstudio_lib/MaterialsController.md +++ /dev/null @@ -1,50 +0,0 @@ -# Class: `MaterialsController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/MaterialsController.hpp](../../../../src/openstudio_lib/MaterialsController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`MaterialsController` manages the Materials sub-tab, listing all material objects in the model (opaque layer materials, glazing, window gas layers, blinds, screens, shades, etc.). Selecting a material in the list opens its type-specific inspector view in the right column. - -Like `ConstructionsController`, it extends `OSVectorController` to supply its item list. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSVectorController { - <> - } - class MaterialsController { - +MaterialsController(model) - #makeVector() vector~OSItemId~ - #onDrop(itemId) - #onRemoveItem(item) - signals: modelObjectSelected(OptionalModelObject, bool) - } - - OSVectorController <|-- MaterialsController -``` - ---- - -## Material Types Covered - -`makeVector()` scans the model for all of the following IDD types and returns one `OSItemId` per object: - -| Category | IDD Types | -|---|---| -| Opaque | `StandardOpaqueMaterial`, `MasslessOpaqueMaterial`, `RoofVegetation`, `AirGap` | -| Glazing | `SimpleGlazing`, `StandardGlazing`, `RefractionExtinctionGlazing`, `ThermochromicGlazing` | -| Window controls | `Blind`, `Screen`, `Shade`, `DaylightRedirectionDevice` | -| Gas layers | `Gas`, `GasMixture`, `GasCustom`, `AirWall` | - ---- - -## Inspector View Pattern - -`OSDocument` (or the parent tab controller) connects `modelObjectSelected` to `InspectorController`. The inspector then casts the `ModelObject` to its specific subtype and shows the matching inspector view (e.g., `StandardOpaqueMaterialInspectorView`, `SimpleGlazingInspectorView`). diff --git a/developer/doc/classes/openstudio_lib/ModelObjectListView.md b/developer/doc/classes/openstudio_lib/ModelObjectListView.md deleted file mode 100644 index ca054ca91..000000000 --- a/developer/doc/classes/openstudio_lib/ModelObjectListView.md +++ /dev/null @@ -1,74 +0,0 @@ -# Class: `ModelObjectListView` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/ModelObjectListView.hpp](../../../../src/openstudio_lib/ModelObjectListView.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`ModelObjectListView` is a generic list view for displaying any collection of model objects as `OSItem` rows. It is used throughout the application for the "My Model" tab contents — e.g., showing all space types, all constructions, all schedules — providing a simple way to browse and select model objects without a full grid view. - -It wraps an `OSVectorController` to obtain its item list, and re-renders whenever the controller emits `itemIds`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class ModelObjectListView { - +ModelObjectListView(iddObjectType, model, addScrollArea, overrideLock, parent) - +selectedItem() optional~ModelObject~ - +setIddObjectType(IddObjectType) - signals: itemSelected(ModelObject) - signals: itemRemoveClicked(ModelObject) - signals: selectionCleared() - } - class OSVectorController { - <> - } - class OSItemList { - <> - } - class OSItem { - } - - QWidget <|-- ModelObjectListView - ModelObjectListView "1" *-- "1" OSVectorController : uses - ModelObjectListView "1" *-- "1" OSItemList : renders into - OSItemList "1..*" *-- "0..*" OSItem : contains -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `iddObjectType` | `IddObjectType` | The IDD type of objects to display (e.g., `IddObjectType::OS_SpaceType`) | -| `model` | `model::Model` | The model to scan | -| `addScrollArea` | `bool` | Wraps the list in a `QScrollArea` when true | -| `overrideLock` | `bool` | When true, ignores field-lock policies (used in plugin mode) | -| `parent` | `QWidget*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `selectedItem()` | `optional` | Returns the currently selected model object, if any | -| `setIddObjectType(type)` | `void` | Changes the object type being displayed; triggers a full refresh | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `itemSelected` | `model::ModelObject` | Emitted when the user clicks an item; drives the right-column inspector | -| `itemRemoveClicked` | `model::ModelObject` | Emitted when the × button is clicked; the controller above handles deletion from the model | -| `selectionCleared` | — | Emitted when the selection is cleared (e.g., user clicks empty space) | diff --git a/developer/doc/classes/openstudio_lib/OSAppBase.md b/developer/doc/classes/openstudio_lib/OSAppBase.md deleted file mode 100644 index 8103c9fa6..000000000 --- a/developer/doc/classes/openstudio_lib/OSAppBase.md +++ /dev/null @@ -1,112 +0,0 @@ -# Class: `OSAppBase` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSAppBase.hpp](../../../../src/openstudio_lib/OSAppBase.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`OSAppBase` is the abstract base class for the application object. It extends both `QApplication` and the `BaseApp` interface, providing a concrete implementation of measure management, workspace signal routing, and the static singleton accessor — while leaving `currentDocument()` abstract for the concrete subclass (`OpenStudioApp`) to implement. - -This split allows the SketchUp plugin and standalone application to share all `MeasureManager`, BCL dialog, and workspace notification logic without duplicating it. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QApplication { - <> - } - class BaseApp { - <> - +mainWidget() QWidget* = 0 - +measureManager() MeasureManager& = 0 - +currentModel() optional~Model~ = 0 - +tempDir() optional~path~ = 0 - } - class OSAppBase { - <> - +instance() OSAppBase* - +currentDocument() OSDocument* = 0 - +mainWidget() QWidget* - +measureManager() MeasureManager& - +tempDir() optional~path~ - +currentModel() optional~Model~ - +updateSelectedMeasureState() - +addMeasure() - +updateMyMeasures() - +updateBCLMeasures() - +openBclDlg() - +mouseOverInspectorView() bool - +notify(receiver, event) bool - slots: addWorkspaceObject, removeWorkspaceObject - signals: workspaceObjectAdded, workspaceObjectRemoved - } - class OpenStudioApp { - +currentDocument() OSDocument* - } - - QApplication <|-- OSAppBase - BaseApp <|.. OSAppBase - OSAppBase <|-- OpenStudioApp -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `argc` | `int&` | Passed through to `QApplication` | -| `argv` | `char**` | Passed through to `QApplication` | -| `t_measureManager` | `QSharedPointer` | Pre-constructed measure manager instance | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `instance()` | `OSAppBase*` | Returns the singleton application instance | -| `currentDocument()` | `shared_ptr` | **Pure virtual** — implemented by `OpenStudioApp` | -| `mainWidget()` | `QWidget*` | Returns the main window widget of the current document | -| `measureManager()` | `MeasureManager&` | Returns the application-wide measure manager | -| `tempDir()` | `optional` | Returns the path to a per-session temporary directory | -| `currentModel()` | `optional` | Returns the model from the current document, if one is open | -| `waitDialog()` | `shared_ptr` | Returns the shared "please wait" modal dialog | -| `mouseOverInspectorView()` | `bool` | Returns whether the mouse cursor is over the inspector view; used by `OSLineEdit2::focusOutEvent` to decide whether to keep focus | -| `dviewPath()` | `openstudio::path` | Returns the path to the DView results viewer | -| `notify(receiver, event)` | `bool` | Override of `QApplication::notify` — catches and logs C++ exceptions thrown inside Qt event handlers | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `workspaceObjectAdded` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the current document's model; allows global listeners to react to any model object addition | -| `workspaceObjectAddedPtr` | `shared_ptr, IddObjectType, UUID` | Pointer variant for performance-sensitive listeners | -| `workspaceObjectRemoved` | `WorkspaceObject, IddObjectType, UUID` | Forwarded from the current document's model | -| `workspaceObjectRemovedPtr` | `shared_ptr, IddObjectType, UUID` | Pointer variant | - ---- - -## Qt Slots - -| Slot | Arguments | Description | -|---|---|---| -| `addWorkspaceObject` | `WorkspaceObject, IddObjectType, UUID` | Connected to the model's object-added signal; re-emits as `workspaceObjectAdded` | -| `addWorkspaceObjectPtr` | `shared_ptr, ...` | Pointer variant | -| `removeWorkspaceObject` | `WorkspaceObject, IddObjectType, UUID` | Connected to the model's object-removed signal; re-emits as `workspaceObjectRemoved` | -| `removeWorkspaceObjectPtr` | `shared_ptr, ...` | Pointer variant | - ---- - -## Key Data Members - -| Member | Type | Description | -|---|---|---| -| `m_measureManager` | `QSharedPointer` | Shared measure management instance | -| `m_waitDialog` | `boost::shared_ptr` | Application-wide modal progress dialog | diff --git a/developer/doc/classes/openstudio_lib/OSDocument.md b/developer/doc/classes/openstudio_lib/OSDocument.md deleted file mode 100644 index 85366cedd..000000000 --- a/developer/doc/classes/openstudio_lib/OSDocument.md +++ /dev/null @@ -1,116 +0,0 @@ -# Class: `OSDocument` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSDocument.hpp](../../../../src/openstudio_lib/OSDocument.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`OSDocument` is the central document class of the application. It owns exactly one `openstudio::model::Model` and orchestrates the entire GUI around it: it creates the `MainWindow`, instantiates all tab controllers, and connects model change signals to view updates. - -It corresponds to an open `.osm` file. When the user creates a new model or opens an existing one, a new `OSDocument` is constructed; when they close it, the `OSDocument` is destroyed along with all tabs and views. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class OSDocument { - +OSDocument(library, resourcesPath, model, filePath, isPlugin, startTabIndex, startSubTabIndex) - +model() Model - +mainWindow() MainWindow* - +savePath() QString - +modelTempDir() QString - +modified() bool - +setModel(model, modified, saveCurrentTabs) - +fromModel(itemId) bool - +fromComponentLibrary(itemId) bool - +fromBCL(itemId) bool - +save() - +saveAs() - signals: modelSaved(path), modelClosed, fileNameChanged(QString) - signals: toggleUnitsClicked(bool), toggleDisplayAdditionalPropsClicked(bool) - } - class MainWindow { - <> - } - class MainTabController { - <> - } - class MainRightColumnController { - } - class model_Model { - <> - } - - OSQObjectController <|-- OSDocument - OSDocument "1" *-- "1" MainWindow : creates and owns - OSDocument "1" *-- "1" MainTabController : active tab controller - OSDocument "1" *-- "1" MainRightColumnController : right column - OSDocument "1" --> "1" model_Model : wraps -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `library` | `model::Model` | Component library model used for drag-and-drop into the document | -| `resourcesPath` | `openstudio::path` | Path to application resources (icons, default files) | -| `model` | `model::OptionalModel` | Initial model to display; if empty, a new blank model is created | -| `filePath` | `QString` | Path of the file on disk; empty for new unsaved models | -| `isPlugin` | `bool` | `true` when hosted inside the SketchUp plugin (modifies layout) | -| `startTabIndex` | `int` | Which tab to show initially (0 = Site / Geometry) | -| `startSubTabIndex` | `int` | Which sub-tab to select within the initial tab | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `mainWindow()` | `MainWindow*` | The top-level `QMainWindow` associated with this document | -| `model()` | `model::Model` | The current OpenStudio model | -| `setModel(model, modified, saveCurrentTabs)` | `void` | Replaces the model (used after version translation, format import); saves and restores tab index | -| `modified()` | `bool` | `true` if the model has unsaved changes | -| `savePath()` | `QString` | Absolute path to the saved `.osm` file; empty if unsaved | -| `modelTempDir()` | `QString` | Path to the temporary working directory for this document's resources | -| `componentLibrary()` | `model::Model` | The component library model | -| `setComponentLibrary(model)` | `void` | Replaces the component library | -| `fromModel(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to an object in the current model | -| `fromComponentLibrary(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to an object in the component library | -| `fromBCL(itemId)` | `bool` | Returns `true` if the `OSItemId` refers to a BCL component | -| `save()` | `bool` | Saves to the current `savePath()`; prompts "Save As" if unsaved | -| `saveAs()` | `bool` | Opens a file dialog for Save As | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelSaved` | `openstudio::path` | Emitted after a successful save, with the saved path | -| `modelClosed` | — | Emitted just before the document is destroyed | -| `fileNameChanged` | `QString` | Emitted when the save path changes (new save or Save As) | -| `toggleUnitsClicked` | `bool displayIP` | Relays the "Display IP/SI units" toggle from `MainWindow` to all tab views | -| `toggleDisplayAdditionalPropsClicked` | `bool` | Relays the "additional properties" visibility toggle | -| `treeChanged` | `openstudio::UUID` | Emitted when the model object hierarchy changes | - ---- - -## Key Data Members - -| Member | Type | Description | -|---|---|---| -| `m_model` | `model::Model` | The OpenStudio model being edited | -| `m_mainWindow` | `MainWindow*` | The document's top-level window | -| `m_mainTabController` | pointer to active controller | The currently displayed tab controller | -| `m_mainRightColumnController` | `MainRightColumnController*` | The right inspector/library column controller | -| `m_savePath` | `QString` | Current file path on disk | -| `m_modified` | `bool` | Dirty flag | -| `m_isPlugin` | `bool` | Whether hosted in SketchUp plugin mode | diff --git a/developer/doc/classes/openstudio_lib/OSDropZone.md b/developer/doc/classes/openstudio_lib/OSDropZone.md deleted file mode 100644 index 1deace1f0..000000000 --- a/developer/doc/classes/openstudio_lib/OSDropZone.md +++ /dev/null @@ -1,96 +0,0 @@ -# Class: `OSDropZone` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSDropZone.hpp](../../../../src/openstudio_lib/OSDropZone.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`OSDropZone` is a widget that displays a single `OSItem` (or a placeholder when empty) and accepts drag-and-drop of model objects onto it. It is the standard UI element for one-to-one model relationships — e.g., "the heating coil for this air loop terminal", or "the schedule for this lights definition". - -When a user drags an item from a list and drops it onto an `OSDropZone`, the drop zone routes the event through its associated `OSVectorController`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class OSDropZone { - +OSDropZone(vectorController, text, size, growsDown, parent) - +setItemsAcceptable(acceptable) - +setItemsRemoveable(removeable) - +setAcceptedMimeType(type) - +setMaxItems(max) - signals: itemDropped(OSItemId) - signals: itemSelected(OSItem*) - signals: itemRemoveClicked(OSItem*) - signals: inFocus(bool, bool) - } - class OSVectorController { - <> - +drop(OSItemId) - signals: itemIds(vector~OSItemId~) - } - class OSItem { - +setRemoveable(bool) - } - - QWidget <|-- OSDropZone - OSDropZone "1" --> "1" OSVectorController : delegates drops - OSDropZone "1" --> "0..1" OSItem : displays current item -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `vectorController` | `OSVectorController*` | The controller managing the underlying model relationship | -| `text` | `QString` | Placeholder text shown when the zone is empty | -| `size` | `QSize` | Preferred size | -| `growsDown` | `bool` | If true, multiple items can be stacked vertically (acts as a multi-item zone) | -| `parent` | `QWidget*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `setItemsAcceptable(bool)` | `void` | Whether drops are currently accepted (may be disabled e.g. when a field is locked) | -| `setItemsRemoveable(bool)` | `void` | Whether the remove button is shown on the displayed item | -| `setAcceptedMimeType(QString)` | `void` | Restricts accepted drops to items with the given MIME type (object type filter) | -| `setMaxItems(int)` | `void` | Caps the number of items when `growsDown` is true | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `itemDropped` | `OSItemId` | Emitted when a valid item is dropped; forwarded to the vector controller's `drop()` slot | -| `itemSelected` | `OSItem*` | Emitted when the displayed item is clicked | -| `itemRemoveClicked` | `OSItem*` | Emitted when the × button is clicked on the current item | -| `inFocus` | `bool focused, bool readOnly` | Emitted when the drop zone gains or loses focus (used to update the right-column inspector) | - ---- - -## Usage Pattern - -`OSDropZone` is typically used inside an inspector view for a single-object relationship: - -```cpp -// In some inspector constructor: -auto ctrl = new MyRelationshipVectorController(m_model); -auto dropZone = new OSDropZone(ctrl, "Drop Coil Here"); -connect(dropZone, &OSDropZone::itemSelected, - this, &MyInspectorView::onItemSelected); -layout->addWidget(dropZone); -``` - -For multi-item ordered lists, use `OSItemList` or `OSDropZone` with `growsDown = true`. diff --git a/developer/doc/classes/openstudio_lib/OSItem.md b/developer/doc/classes/openstudio_lib/OSItem.md deleted file mode 100644 index d26ad163a..000000000 --- a/developer/doc/classes/openstudio_lib/OSItem.md +++ /dev/null @@ -1,109 +0,0 @@ -# Class: `OSItem` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSItem.hpp](../../../../src/openstudio_lib/OSItem.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`OSItem` is the base class for all draggable, selectable model object items rendered in the application's lists, drop zones, and library panels. It wraps an `OSItemId` (a lightweight identifier for a model object or BCL component) and provides the visual representation plus drag-and-drop support. - -`OSItemId` is a companion value type that identifies an item by its model object UUID (or BCL identifier), its source (model, component library, or BCL), and optional positional information. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class Nano_Observer { - <> - } - class OSItemId { - +itemId() QString - +sourceId() QString - +isDefaulted() bool - +position() optional~int~ - +mimeDataText() QString - +operator==(other) bool - } - class OSItem { - +makeItem(itemId, itemType) OSItem* - +itemId() OSItemId - +isDefaulted() bool - +selected() bool - +removeable() bool - +draggable() bool - +inspector() bool - +setSelected(bool) - +setRemoveable(bool) - +setDraggable(bool) - signals: itemSelected(OSItem*) - signals: itemRemoveClicked(OSItem*) - signals: itemReplacementDropped(OSItem*, OSItemId) - } - class ModelObjectItem { - +modelObject() ModelObject - } - class BCLComponentItem { - +bclComponent() BCLComponent - } - - QWidget <|-- OSItem - Nano_Observer <|.. OSItem - OSItem "1" *-- "1" OSItemId : wraps - OSItem <|-- ModelObjectItem - OSItem <|-- BCLComponentItem -``` - ---- - -## `OSItemId` Value Type - -| Method | Returns | Description | -|---|---|---| -| `itemId()` | `QString` | The UUID string of the underlying model object, or BCL identifier | -| `sourceId()` | `QString` | Identifies the source: model, component library, or `BCL_SOURCE_ID` | -| `isDefaulted()` | `bool` | True if this item represents a default (inherited) value | -| `position()` | `optional` | Positional index within an ordered list (e.g., construction layer) | -| `mimeDataText()` | `QString` | Full serialized representation for Qt drag-and-drop MIME data | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `makeItem(itemId, itemType)` | `OSItem*` (static) | Factory: creates the appropriate `OSItem` subclass for the given item ID and display type | -| `itemId()` | `OSItemId` | The underlying item identifier | -| `selected()` | `bool` | Whether this item is currently selected (highlighted) | -| `setSelected(bool)` | `void` | Selects/deselects this item; triggers visual update | -| `removeable()` | `bool` | Whether the remove (×) button is visible | -| `setRemoveable(bool)` | `void` | Shows/hides the remove button | -| `draggable()` | `bool` | Whether the item can be dragged | -| `inspector()` | `bool` | Whether clicking this item opens the right-column inspector | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `itemSelected` | `OSItem*` | Emitted when the item is clicked/selected | -| `itemRemoveClicked` | `OSItem*` | Emitted when the × remove button is clicked | -| `itemReplacementDropped` | `OSItem* current, OSItemId replacement` | Emitted when another item is dropped onto this one, triggering a replace operation | - ---- - -## `OSItemType` Enum - -Controls which visual style is applied to the item: - -| Value | Appearance | -|---|---| -| `ListItem` | Full-width horizontal bar with label | -| `DropzoneSquare` | Square compact tile for drop zones | -| `CollapsibleListHeader` | Header row for collapsible sections | diff --git a/developer/doc/classes/openstudio_lib/OSWebEnginePage.md b/developer/doc/classes/openstudio_lib/OSWebEnginePage.md deleted file mode 100644 index 71b6edb4d..000000000 --- a/developer/doc/classes/openstudio_lib/OSWebEnginePage.md +++ /dev/null @@ -1,87 +0,0 @@ -# Class: `OSWebEnginePage` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/OSWebEnginePage.hpp](../../../../src/openstudio_lib/OSWebEnginePage.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`OSWebEnginePage` is a `QWebEnginePage` subclass that serves as the C++/JavaScript bridge for the geometry editor. It exposes a Qt-registered C++ object to the JavaScript engine so the web-based 3D geometry editor can read and write the OpenStudio model. - -The bridge is established via Qt WebChannel (`QWebChannel`), which makes the registered C++ object callable from JavaScript as if it were a native JS object. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWebEnginePage { - <> - } - class OSWebEnginePage { - +OSWebEnginePage(model, parent) - +setModel(model) - +getModel() Model - +translateModel(model) string - +javaScriptConsoleMessage(level, msg, lineNo, sourceID) - signals: modelChanged(Model) - } - class QWebChannel { - +registerObject(name, QObject*) - } - class GeometryEditorView { - <> - +webEngineView() QWebEngineView* - } - - QWebEnginePage <|-- OSWebEnginePage - OSWebEnginePage "1" *-- "1" QWebChannel : uses to expose self to JS - GeometryEditorView --> OSWebEnginePage : sets as page on QWebEngineView -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `model` | `const model::Model&` | Initial model whose geometry is serialised and sent to the JS engine | -| `parent` | `QObject*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `setModel(model)` | `void` | Serialises the model geometry to GLTF JSON and sends it to the JavaScript engine via `runJavaScript()` | -| `getModel()` | `model::Model` | Returns the current model maintained on the C++ side | -| `translateModel(model)` | `std::string` | Converts an `openstudio::model::Model` to a GLTF JSON string (uses TinyGLTF) | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelChanged` | `model::Model` | Emitted when the JavaScript editor sends back geometry changes; carries the updated model | - ---- - -## JavaScript Bridge API - -The following slots are exposed to JavaScript via `QWebChannel` under the registered object name `"openstudioApi"`: - -| JS-callable slot | C++ signature | Description | -|---|---|---| -| `getFloorplanJS()` | `Q_INVOKABLE QString getFloorplanJS()` | Returns the current model geometry as a floorplan JSON string | -| `setFloorplanJS(json)` | `Q_INVOKABLE void setFloorplanJS(QString)` | Receives updated floorplan JSON from the JS editor; deserialises into the model | -| `getGLTF()` | `Q_INVOKABLE QString getGLTF()` | Returns GLTF geometry JSON | -| `setGLTF(json)` | `Q_INVOKABLE void setGLTF(QString)` | Receives GLTF from the JS editor | - ---- - -## Console Message Logging - -`javaScriptConsoleMessage()` is overridden to forward JavaScript `console.log`/`console.error` messages to the C++ logger, making JavaScript errors visible in the application's debug output. diff --git a/developer/doc/classes/openstudio_lib/ResultsTabController.md b/developer/doc/classes/openstudio_lib/ResultsTabController.md deleted file mode 100644 index 6cc26b3c7..000000000 --- a/developer/doc/classes/openstudio_lib/ResultsTabController.md +++ /dev/null @@ -1,57 +0,0 @@ -# Class: `ResultsTabController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/ResultsTabController.hpp](../../../../src/openstudio_lib/ResultsTabController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`ResultsTabController` manages the Results tab. After a simulation completes, `RunTabController` emits `resultsGenerated(sqlPath)`, which this controller receives to load and display the SQL results database. - -The results view shows: -- Summary metrics (site energy use intensity, end-use breakdown) -- Time-series charts for user-selected output variables -- Optional links to DView for advanced charting - ---- - -## Class Diagram - -```mermaid -classDiagram - class MainTabController { - <> - } - class ResultsTabController { - +ResultsTabController(model, sqlPath, radiancePath) - +setSubTab(int) - slots: onResultsGenerated(sqlPath, radiancePath) - } - class ResultsTabView { - <> - +loadResults(sqlPath) - +showSummary() - +showTimeSeries() - } - - MainTabController <|-- ResultsTabController - ResultsTabController "1" *-- "1" ResultsTabView : owns - ResultsTabController <.. RunTabController : receives resultsGenerated signal -``` - ---- - -## Qt Slots - -| Slot | Arguments | Description | -|---|---|---| -| `onResultsGenerated` | `openstudio::path sqlFile, openstudio::path radianceOutputFile` | Loads the SQL results database and re-populates the results views. Connected to `RunTabController::resultsGenerated`. | - ---- - -## Results View Content - -The `ResultsTabView` uses `QtCharts` to render: -- **End-use bar chart** — energy by end use (heating, cooling, lighting, equipment, fans, pumps, etc.) -- **Time-series chart** — selectable EnergyPlus output variable over the run period -- **Utility summary table** — site EUI, source EUI, annual cost estimate diff --git a/developer/doc/classes/openstudio_lib/RunTabController.md b/developer/doc/classes/openstudio_lib/RunTabController.md deleted file mode 100644 index 6842fe1d9..000000000 --- a/developer/doc/classes/openstudio_lib/RunTabController.md +++ /dev/null @@ -1,76 +0,0 @@ -# Class: `RunTabController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/RunTabController.hpp](../../../../src/openstudio_lib/RunTabController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`RunTabController` manages the Run tab, which allows users to run an EnergyPlus simulation of the current model and monitor live output from the simulation process. When the simulation completes, it emits a signal with the path to the SQL results file, which triggers the Results tab to load them. - ---- - -## Class Diagram - -```mermaid -classDiagram - class MainTabController { - <> - } - class RunTabController { - +RunTabController(model, modelPath, tempFolder) - +setSubTab(int) - +updateToolsWarnings() - signals: resultsGenerated(sqlPath, radianceOutputPath) - signals: toolsUpdated() - } - class RunView { - +showSimulationControls() - +showOutputLog() - } - - MainTabController <|-- RunTabController - RunTabController "1" *-- "1" RunView : owns -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `model` | `const model::Model&` | Current model to simulate | -| `t_modelPath` | `const openstudio::path&` | Path to the saved `.osm` file | -| `t_tempFolder` | `const openstudio::path&` | Temporary working directory for simulation files | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `resultsGenerated` | `openstudio::path sqlFile, openstudio::path radianceOutputFile` | Emitted when the simulation completes successfully; drives the Results tab to load the SQL database | -| `toolsUpdated` | — | Emitted when EnergyPlus/Radiance tool paths change; may trigger warning banner updates | - ---- - -## Qt Slots - -| Slot | Description | -|---|---| -| `updateToolsWarnings()` | Checks whether EnergyPlus and Radiance are correctly located and updates any warning badges on the Run tab button | - ---- - -## Run Workflow - -```mermaid -flowchart TD - USER["User clicks Run"] --> SAVE["OSDocument saves model to temp dir"] - SAVE --> CLI["OpenStudio CLI spawned as QProcess\nwith the saved workflow file"] - CLI --> LOG["RunView streams stdout/stderr"] - LOG --> DONE{Exit code 0?} - DONE -- yes --> SIGNAL["emit resultsGenerated(sqlPath, ...)"] - DONE -- no --> ERR["Show error in output log"] - SIGNAL --> RESULTS["ResultsTabController loads SQL"] -``` diff --git a/developer/doc/classes/openstudio_lib/SchedulesController.md b/developer/doc/classes/openstudio_lib/SchedulesController.md deleted file mode 100644 index 6004003fd..000000000 --- a/developer/doc/classes/openstudio_lib/SchedulesController.md +++ /dev/null @@ -1,66 +0,0 @@ -# Class: `SchedulesController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/SchedulesController.hpp](../../../../src/openstudio_lib/SchedulesController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`SchedulesController` manages the Schedules domain tab. It displays a tree of schedule rule sets and schedule types, and provides a `ScheduleDayView` inspector that lets users graphically edit day-profile values with a chart-based editor. - ---- - -## Class Diagram - -```mermaid -classDiagram - class MainTabController { - <> - } - class SchedulesTabController { - +setSubTab(int) - } - class SchedulesController { - +SchedulesController(model, isIP) - #makeVector() vector~OSItemId~ - signals: modelObjectSelected(OptionalModelObject, bool) - } - class SchedulesDayView { - <> - +setScheduleDay(ScheduleDay) - signals: scheduleValueChanged(double time, double value) - } - class ScheduleDialog { - +exec() int - +schedule() ScheduleRuleset - } - - MainTabController <|-- SchedulesTabController - SchedulesTabController "1" *-- "1" SchedulesController : owns - SchedulesController --> SchedulesDayView : drives - SchedulesController ..> ScheduleDialog : opens for new schedules -``` - ---- - -## Day Schedule Editor - -The `SchedulesDayView` provides a graphical plot of a schedule day profile: -- X axis: time of day (00:00–24:00) -- Y axis: fractional value or absolute value (depending on schedule type limits) -- User can click and drag to set values at any time point -- Supports fractional interpolation and step profiles - ---- - -## Schedule Types Shown - -`makeVector()` returns all `ScheduleRuleset`, `ScheduleConstant`, `ScheduleCompact`, and `ScheduleFile` objects. - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelObjectSelected` | `OptionalModelObject, bool` | Emitted when a schedule is selected; drives the day-schedule editor | diff --git a/developer/doc/classes/openstudio_lib/SpaceTypesController.md b/developer/doc/classes/openstudio_lib/SpaceTypesController.md deleted file mode 100644 index b64f06d2c..000000000 --- a/developer/doc/classes/openstudio_lib/SpaceTypesController.md +++ /dev/null @@ -1,54 +0,0 @@ -# Class: `SpaceTypesController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/SpaceTypesController.hpp](../../../../src/openstudio_lib/SpaceTypesController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`SpaceTypesController` manages the Space Types tab, which shows all space type objects in the model in a grid view. Each row is a space type; columns show its name, default construction set, default schedule set, lighting power density, people density, equipment, outdoor air, and rendering color. - -It is a `MainTabController` subclass that owns a `SpaceTypesGridView` powered by a domain-specific `OSGridController`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class MainTabController { - <> - } - class SpaceTypesController { - +SpaceTypesController(isIP, model) - +setSubTab(int) - signals: modelObjectSelected(OptionalModelObject, bool) - } - class SpaceTypesGridView { - <> - } - class SpaceTypeInspectorView { - <> - +setSpaceType(SpaceType) - } - - MainTabController <|-- SpaceTypesController - SpaceTypesController "1" *-- "1" SpaceTypesGridView : owns - SpaceTypesController --> SpaceTypeInspectorView : drives on selection -``` - ---- - -## Grid Columns - -The `SpaceTypesGridController` defines these columns (not exhaustive): - -| Column | Field | -|---|---| -| Name | `SpaceType::name()` | -| Default Construction Set | `SpaceType::defaultConstructionSet()` | -| Default Schedule Set | `SpaceType::defaultScheduleSet()` | -| Space Type Color | `SpaceType::renderingColor()` | -| Lighting Power Density | `SpaceType::lightingPowerDensity()` | -| People Definition | `SpaceType::people()` | -| Outdoor Air | `SpaceType::designSpecificationOutdoorAir()` | diff --git a/developer/doc/classes/openstudio_lib/ThermalZonesController.md b/developer/doc/classes/openstudio_lib/ThermalZonesController.md deleted file mode 100644 index 5ca79c473..000000000 --- a/developer/doc/classes/openstudio_lib/ThermalZonesController.md +++ /dev/null @@ -1,46 +0,0 @@ -# Class: `ThermalZonesController` - -> **Module:** `openstudio_lib` -> **Header:** [src/openstudio_lib/ThermalZonesController.hpp](../../../../src/openstudio_lib/ThermalZonesController.hpp) -> **Library doc:** [libraries/openstudio_lib.md](../../libraries/openstudio_lib.md) - -## Purpose - -`ThermalZonesController` manages the Thermal Zones tab, showing all thermal zone objects in the model in a grid view. Each row represents one zone; columns expose thermostat types, humidistats, zone multipliers, cooling/heating ideal air loads, zone equipment, and DOAS connections. - ---- - -## Class Diagram - -```mermaid -classDiagram - class MainTabController { - <> - } - class ThermalZonesController { - +ThermalZonesController(isIP, model) - +setSubTab(int) - signals: modelObjectSelected(OptionalModelObject, bool) - } - class ThermalZonesGridView { - <> - } - - MainTabController <|-- ThermalZonesController - ThermalZonesController "1" *-- "1" ThermalZonesGridView : owns -``` - ---- - -## Grid Columns (representative) - -| Column | Field | -|---|---| -| Name | `ThermalZone::name()` | -| Thermostat | `ThermalZone::thermostat()` | -| Humidistat | `ThermalZone::zoneControlHumidistat()` | -| Multiplier | `ThermalZone::multiplier()` | -| Use Ideal Air Loads | `ThermalZone::useIdealAirLoads()` | -| DOAS Airloop | `ThermalZone::airLoopHVAC()` | -| Zone Conditioning Equip | `ThermalZone::equipment()` | -| Rendering Color | `ThermalZone::renderingColor()` | diff --git a/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md b/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md deleted file mode 100644 index 8d3f5d546..000000000 --- a/developer/doc/classes/shared_gui_components/BCLMeasureDialog.md +++ /dev/null @@ -1,60 +0,0 @@ -# Class: `BCLMeasureDialog` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/BCLMeasureDialog.hpp](../../../../src/shared_gui_components/BCLMeasureDialog.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`BCLMeasureDialog` is a modal dialog that lets users search and download OpenStudio Measures from the NREL Building Component Library (BCL). It queries the BCL REST API, displays results with taxonomy filtering and free-text search, and downloads selected measures to the local BCL cache. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QDialog { - <> - } - class BCLMeasureDialog { - +BCLMeasureDialog(app, parent) - +exec() int - +selectedMeasure() optional~BCLMeasure~ - slots: onSearchClicked() - slots: onDownloadClicked() - signals: measureDownloaded(BCLMeasure) - } - class MeasureManager { - +downloadMeasure(uid) - } - - QDialog <|-- BCLMeasureDialog - BCLMeasureDialog --> MeasureManager : triggers download via -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `app` | `BaseApp*` | Application interface for accessing `MeasureManager` | -| `parent` | `QWidget*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `exec()` | `int` | Shows the dialog modally; returns `QDialog::Accepted` if the user downloaded a measure | -| `selectedMeasure()` | `optional` | Returns the last downloaded/selected measure after `exec()` returns | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `measureDownloaded` | `BCLMeasure` | Emitted when a measure is successfully downloaded to the local cache | diff --git a/developer/doc/classes/shared_gui_components/BaseApp.md b/developer/doc/classes/shared_gui_components/BaseApp.md deleted file mode 100644 index 9b2d6e54f..000000000 --- a/developer/doc/classes/shared_gui_components/BaseApp.md +++ /dev/null @@ -1,65 +0,0 @@ -# Class: `BaseApp` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/BaseApp.hpp](../../../../src/shared_gui_components/BaseApp.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`BaseApp` is a pure abstract interface that decouples all shared GUI components from any specific application implementation. Widgets like `MeasureManager`, `LocalLibraryController`, and `BuildingComponentDialog` depend only on `BaseApp`, not on `OSAppBase` or `OpenStudioApp`. This isolation enables the shared components to be hosted inside the SketchUp plugin or any other Qt host without modification. - -`OSAppBase` implements `BaseApp`, satisfying the contract for both the standalone application and plugin contexts. - ---- - -## Class Diagram - -```mermaid -classDiagram - class BaseApp { - <> - +mainWidget() QWidget* = 0 - +measureManager() MeasureManager& = 0 - +updateSelectedMeasureState() = 0 - +addMeasure() = 0 - +duplicateSelectedMeasure() = 0 - +updateMyMeasures() = 0 - +updateBCLMeasures() = 0 - +openBclDlg() = 0 - +checkForRemoteBCLUpdates() = 0 - +chooseHorizontalEditTab() = 0 - +editController() QSharedPointer~EditController~ = 0 - +tempDir() optional~path~ = 0 - +currentModel() optional~Model~ = 0 - +mouseOverInspectorView() bool = 0 - } - class OSAppBase { - +mainWidget() QWidget* - +measureManager() MeasureManager& - +currentModel() optional~Model~ - ... - } - - BaseApp <|.. OSAppBase -``` - ---- - -## Abstract Methods - -| Method | Returns | Description | -|---|---|---| -| `mainWidget()` | `QWidget*` | The application's main window widget | -| `measureManager()` | `MeasureManager&` | Access to the application's measure manager | -| `updateSelectedMeasureState()` | `void` | Refresh the enable/disable state of measure-related actions | -| `addMeasure()` | `void` | Trigger the "Add Measure" workflow | -| `duplicateSelectedMeasure()` | `void` | Duplicate the currently selected measure | -| `updateMyMeasures()` | `void` | Re-scan the user's local measures directory | -| `updateBCLMeasures()` | `void` | Re-scan the BCL local cache | -| `openBclDlg()` | `void` | Open the BCL measure browser dialog | -| `checkForRemoteBCLUpdates()` | `void` | Query the BCL server for updated measures | -| `chooseHorizontalEditTab()` | `void` | Switch the right column to the Edit tab | -| `editController()` | `QSharedPointer` | The right-column edit controller | -| `tempDir()` | `optional` | Path to the session temporary directory | -| `currentModel()` | `optional` | The current model, if any | -| `mouseOverInspectorView()` | `bool` | Returns whether the mouse cursor is currently over the inspector view in the right column | diff --git a/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md b/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md deleted file mode 100644 index fe79dc573..000000000 --- a/developer/doc/classes/shared_gui_components/BuildingComponentDialog.md +++ /dev/null @@ -1,63 +0,0 @@ -# Class: `BuildingComponentDialog` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/BuildingComponentDialog.hpp](../../../../src/shared_gui_components/BuildingComponentDialog.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`BuildingComponentDialog` is a modal dialog for browsing and downloading building components (constructions, materials, schedules, etc.) from the NREL Building Component Library (BCL). Once downloaded, the component is available for drag-and-drop into the relevant model views. - -It is analogous to `BCLMeasureDialog` but targets BCL *components* rather than *measures*. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QDialog { - <> - } - class BCLSearchResult { - +uid() QString - +name() QString - +description() QString - } - class BuildingComponentDialog { - +BuildingComponentDialog(filterType, app, parent) - +exec() int - +selectedComponent() optional~BCLComponent~ - signals: componentDownloaded(BCLComponent) - } - - QDialog <|-- BuildingComponentDialog - BuildingComponentDialog --> BCLSearchResult : displays search results -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `filterType` | `QString` | BCL component type to filter results (e.g., `"Construction"`, `"Material"`) | -| `app` | `BaseApp*` | Application interface | -| `parent` | `QWidget*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `exec()` | `int` | Shows the dialog modally | -| `selectedComponent()` | `optional` | The downloaded component after `exec()` returns | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `componentDownloaded` | `BCLComponent` | Emitted after a successful component download | diff --git a/developer/doc/classes/shared_gui_components/LocalLibraryController.md b/developer/doc/classes/shared_gui_components/LocalLibraryController.md deleted file mode 100644 index 1208dc893..000000000 --- a/developer/doc/classes/shared_gui_components/LocalLibraryController.md +++ /dev/null @@ -1,93 +0,0 @@ -# Class: `LocalLibraryController` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/LocalLibraryController.hpp](../../../../src/shared_gui_components/LocalLibraryController.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`LocalLibraryController` manages the "Library" tab of the right-column sidebar. It provides a searchable, filterable browser of all locally available OpenStudio Measures (from both `myMeasures` and the BCL cache), organized by taxonomy category. - -Users can browse, search, and select measures from this list; the selected measure can then be dragged into the workflow or applied immediately via `ApplyMeasureNowDialog`. - ---- - -## Class Diagram - -```mermaid -classDiagram - class OSQObjectController { - <> - } - class LocalLibraryController { - +LocalLibraryController(app, parent) - +localLibraryView() LocalLibraryView* - signals: addMeasureClicked() - signals: duplicateMeasureClicked() - signals: removeMeasureClicked() - signals: applyMeasureClicked(BCLMeasure) - slots: onMeasureSelected(BCLMeasure) - slots: refresh() - } - class LocalLibraryView { - <> - +searchBox() QLineEdit* - +categoryTree() QTreeView* - +measureList() QListView* - } - class MeasureManager { - +combinedMeasures() vector~BCLMeasure~ - } - class TIDItemModel { - <> - # taxonomy tree data model - } - - OSQObjectController <|-- LocalLibraryController - LocalLibraryController "1" *-- "1" LocalLibraryView : owns - LocalLibraryController --> MeasureManager : queries - LocalLibraryController --> TIDItemModel : populates taxonomy tree -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `app` | `BaseApp*` | Application interface for accessing `MeasureManager` | -| `parent` | `QObject*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `localLibraryView()` | `LocalLibraryView*` | The view widget to embed in the right-column sidebar | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `addMeasureClicked` | — | User clicked the "Add Measure" button; opens the new measure wizard | -| `duplicateMeasureClicked` | — | User duplicated the selected measure | -| `removeMeasureClicked` | — | User deleted the selected measure from local disk | -| `applyMeasureClicked` | `BCLMeasure` | User pressed "Apply Now"; triggers `ApplyMeasureNowDialog` | - ---- - -## Qt Slots - -| Slot | Description | -|---|---| -| `onMeasureSelected(BCLMeasure)` | Updates the detail panel with the selected measure's metadata | -| `refresh()` | Rebuilds the taxonomy tree and measure list from `MeasureManager::combinedMeasures()` | - ---- - -## Taxonomy Browsing - -`LocalLibraryController` uses `TIDItemModel` to display measures in a hierarchical taxonomy tree (e.g., Whole Building > Space Types > Lighting > ...). The taxonomy IDs come from the BCL taxonomy metadata embedded in each `BCLMeasure`. diff --git a/developer/doc/classes/shared_gui_components/MeasureManager.md b/developer/doc/classes/shared_gui_components/MeasureManager.md deleted file mode 100644 index 5bca1af7b..000000000 --- a/developer/doc/classes/shared_gui_components/MeasureManager.md +++ /dev/null @@ -1,92 +0,0 @@ -# Class: `MeasureManager` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/MeasureManager.hpp](../../../../src/shared_gui_components/MeasureManager.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`MeasureManager` is the central manager for all OpenStudio Measures available to the application. It: -- Scans the user's `myMeasures` directory and the local BCL cache for available measures -- Deduplicates measures across both locations by UUID (preferring `myMeasures`) -- Checks for newer versions of measures in the project against the local library -- Provides the data source for the `LocalLibraryController` (measure browser) -- Manages the background update workflow for syncing project measures - ---- - -## Class Diagram - -```mermaid -classDiagram - class QObject { - <> - } - class MeasureManager { - +MeasureManager(app: BaseApp*) - +url() QUrl - +myMeasures() vector~BCLMeasure~ - +bclMeasures() vector~BCLMeasure~ - +combinedMeasures() vector~BCLMeasure~ - +getMeasureByUID(uid) optional~BCLMeasure~ - +checkForLocalUpdates() - +updateMeasures(app, measures, force) - +downloadMeasure(uid) - signals: measureUpdated(BCLMeasure) - signals: localLibraryChanged() - } - class BaseApp { - <> - } - class LocalLibraryController { - +localLibraryView() LocalLibraryView* - } - - QObject <|-- MeasureManager - MeasureManager --> BaseApp : uses - MeasureManager <-- LocalLibraryController : observes -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `t_app` | `BaseApp*` | The application interface; provides `tempDir()`, `currentModel()`, and UI hooks | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `myMeasures()` | `vector` | All measures found in the user's `myMeasures` directory | -| `bclMeasures()` | `vector` | All measures in the local BCL cache | -| `combinedMeasures()` | `vector` | Merged and deduplicated list (myMeasures preferred when UUID collides) | -| `getMeasureByUID(uid)` | `optional` | Looks up a measure by its UUID string | -| `checkForLocalUpdates()` | `void` | Re-scans both measure directories and emits `localLibraryChanged` if anything changed | -| `updateMeasures(app, measures, force)` | `void` | For each measure in the project workflow, checks if a newer version exists locally and optionally updates | -| `downloadMeasure(uid)` | `void` | Downloads a measure from the BCL to the local cache | -| `url()` | `QUrl` | The BCL API base URL | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `measureUpdated` | `BCLMeasure` | Emitted when a measure in the project has been updated to a newer local version | -| `localLibraryChanged` | — | Emitted after a rescan finds changes; triggers `LocalLibraryController` to refresh | - ---- - -## Thread Safety - -`MeasureManager` uses a `QMutex` to protect its internal measure index. BCL download network requests are performed on the Qt network thread; completion signals are delivered on the GUI thread via queued connections. - ---- - -## Measure Priority - -When the same UUID exists in both `myMeasures` and the BCL cache, `combinedMeasures()` always returns the `myMeasures` copy. This supports the workflow of: download from BCL → customise locally → `myMeasures` version takes precedence. diff --git a/developer/doc/classes/shared_gui_components/OSGridController.md b/developer/doc/classes/shared_gui_components/OSGridController.md deleted file mode 100644 index 380719a54..000000000 --- a/developer/doc/classes/shared_gui_components/OSGridController.md +++ /dev/null @@ -1,100 +0,0 @@ -# Class: `OSGridController` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/OSGridController.hpp](../../../../src/shared_gui_components/OSGridController.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`OSGridController` is the abstract base class for all multi-column tabular model views. It provides a declarative column-definition API (`add*Column()` methods) and manages row-object mapping, selection state, and cell widget creation on demand. - -Concrete subclasses declare their columns in their constructor by calling the `add*Column()` methods, which the base class uses to render each cell through an `OSCellWrapper`. Data is fetched lazily via `std::function` getters/setters rather than through Qt's model/view. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QObject { - <> - } - class OSGridController { - <> - +rowCount() int - +columnCount() int - +objectAt(row) ModelObject - +addCheckBoxColumn(heading, getter, setter) - +addComboBoxColumn(heading, choices, getter, setter) - +addDoubleEditColumn(heading, getter, setter, precision) - +addDropZoneColumn(heading, vectorController) - +addLineEditColumn(heading, getter, setter) - +addIntegerEditColumn(heading, getter, setter) - +addRenderingColorColumn(heading, getter) - +refreshAll() - signals: modelReset() - signals: itemSelected(OSItem*, bool) - } - class OSObjectSelector { - +selectRow(int) - +selectedRows() vector~int~ - +selectedObjects() vector~ModelObject~ - } - class OSCellWrapper { - <> - +setContent(QWidget*) - } - class ThermalZonesGridController { - +ThermalZonesGridController(isIP, model) - # defines columns in ctor - } - class SpaceTypesGridController { - +SpaceTypesGridController(isIP, model) - } - - QObject <|-- OSGridController - OSGridController "1" *-- "1" OSObjectSelector : owns - OSGridController "1" *-- "N" OSCellWrapper : creates lazily - OSGridController <|-- ThermalZonesGridController - OSGridController <|-- SpaceTypesGridController -``` - ---- - -## Column Definition API - -All `add*Column()` methods accept a heading string and typed getter/setter functions: - -| Method | Widget type | Getter | Setter | -|---|---|---|---| -| `addCheckBoxColumn` | `OSCheckBox2` | `function` | `function` | -| `addComboBoxColumn` | `OSComboBox2` | `function` | `function` | -| `addDoubleEditColumn` | `OSDoubleEdit2` | `function(ModelObject)>` | `function` | -| `addDropZoneColumn` | `OSDropZone` | `OSVectorController` subclass | — | -| `addLineEditColumn` | `OSLineEdit2` | `function` | `function` | -| `addIntegerEditColumn` | `OSIntegerEdit2` | `function(ModelObject)>` | `function` | -| `addRenderingColorColumn` | `RenderingColorWidget` | `function(ModelObject)>` | — | - -### `DataSource` Adapter - -Columns can optionally be wrapped in a `DataSource`, which maps a `ModelObject` to a `std::vector` of sub-objects, creating a stacked column to display multiple widgets per row cell (e.g., all space load instances for a space type). - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `rowCount()` | `int` | Number of data rows (model objects) | -| `columnCount()` | `int` | Number of defined columns | -| `objectAt(row)` | `model::ModelObject` | Returns the model object for the given row | -| `refreshAll()` | `void` | Forces a full re-render of all cells | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `modelReset` | — | Emitted when the underlying object list changes and all rows must be re-generated | -| `itemSelected` | `OSItem*, bool readOnly` | Emitted when a row object is selected; drives the right-column inspector | diff --git a/developer/doc/classes/shared_gui_components/OSGridView.md b/developer/doc/classes/shared_gui_components/OSGridView.md deleted file mode 100644 index 8e266b171..000000000 --- a/developer/doc/classes/shared_gui_components/OSGridView.md +++ /dev/null @@ -1,73 +0,0 @@ -# Class: `OSGridView` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/OSGridView.hpp](../../../../src/shared_gui_components/OSGridView.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`OSGridView` is the `QWidget` that hosts and renders an `OSGridController`. It manages a `QScrollArea` containing a grid of `OSCellWrapper` widgets arranged in rows and columns. It handles row selection highlighting and forwards keyboard navigation events to the controller. - -Domain views (e.g., `ThermalZonesGridView`, `SpaceTypesGridView`) typically subclass `OSGridView` or compose it into a larger layout with filter/search bars. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QWidget { - <> - } - class OSGridView { - +OSGridView(gridController, headerText, dropZoneText, isIP, parent) - +setGridController(OSGridController*) - +gridController() OSGridController* - +selectRow(int) - +selectedRows() vector~int~ - signals: rowSelected(int) - signals: dropZoneClicked() - } - class OSGridController { - <> - } - class OSCellWrapper { - <> - } - - QWidget <|-- OSGridView - OSGridView "1" --> "1" OSGridController : references - OSGridView "1..*" *-- "N" OSCellWrapper : renders -``` - ---- - -## Constructor - -| Parameter | Type | Description | -|---|---|---| -| `gridController` | `OSGridController*` | The controller providing row/column data | -| `headerText` | `QString` | Text shown in the column header row | -| `dropZoneText` | `QString` | Placeholder text for the "add new object" drop zone at the top or bottom | -| `isIP` | `bool` | IP/SI unit display preference | -| `parent` | `QWidget*` | Qt parent | - ---- - -## Key Public Methods - -| Method | Returns | Description | -|---|---|---| -| `setGridController(ctrl)` | `void` | Replaces the grid controller and re-renders all cells | -| `gridController()` | `OSGridController*` | The current controller | -| `selectRow(int)` | `void` | Programmatically selects a row and scrolls it into view | -| `selectedRows()` | `vector` | Returns indices of all currently selected rows | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `rowSelected` | `int rowIndex` | Emitted when the user clicks or keyboard-navigates to a row | -| `dropZoneClicked` | — | Emitted when the user clicks the "add new object" drop area | diff --git a/developer/doc/classes/shared_gui_components/OSVectorController.md b/developer/doc/classes/shared_gui_components/OSVectorController.md deleted file mode 100644 index 7a9a7e8ae..000000000 --- a/developer/doc/classes/shared_gui_components/OSVectorController.md +++ /dev/null @@ -1,111 +0,0 @@ -# Class: `OSVectorController` - -> **Module:** `shared_gui_components` -> **Header:** [src/shared_gui_components/OSVectorController.hpp](../../../../src/shared_gui_components/OSVectorController.hpp) -> **Library doc:** [libraries/shared_gui_components.md](../../libraries/shared_gui_components.md) - -## Purpose - -`OSVectorController` is the abstract base class for all list/vector controllers in the application. It provides the protocol for managing an ordered list of `OSItemId`s that represent model objects displayed in an `OSItemList` or `OSDropZone` widget. - -Concrete subclasses implement `makeVector()` to return the current set of item IDs from the model. The base class handles the scheduling of re-renders (deduped with a mutex) and the routing of user interactions (remove, replace, drop, create) through virtual dispatch. - ---- - -## Class Diagram - -```mermaid -classDiagram - class QObject { - <> - } - class Nano_Observer { - <> - } - class OSVectorController { - <> - +reportItems() - +removeItem(OSItem*) - +replaceItem(currentItem, replacementId) - +drop(OSItemId) - +makeNewItem() - #makeVector() vector~OSItemId~ = 0 - #onRemoveItem(item) - #onReplaceItem(item, replacementId) - #onDrop(itemId) - #onMakeNewItem() - signals: itemIds(vector~OSItemId~) - signals: selectedItemId(OSItemId) - } - class ConstructionObjectVectorController { - #makeVector() vector~OSItemId~ - #onDrop(itemId) - #onRemoveItem(item) - } - class DefaultConstructionSetsController { - #makeVector() vector~OSItemId~ - #onDrop(itemId) - } - - QObject <|-- OSVectorController - Nano_Observer <|.. OSVectorController - OSVectorController <|-- ConstructionObjectVectorController - OSVectorController <|-- DefaultConstructionSetsController -``` - ---- - -## Key Public Slots - -| Slot | Arguments | Description | -|---|---|---| -| `reportItems()` | — | Triggers `makeVector()` and emits `itemIds` with the result. Calls are deduplicated using a mutex so that rapid model changes only cause one repaint. | -| `removeItem(item)` | `OSItem*` | Called when the user removes an item (clicks the × button); dispatches to `onRemoveItem()` | -| `replaceItem(currentItem, replacementId)` | `OSItem*, OSItemId` | Called when an item is replaced by drag-and-drop; dispatches to `onReplaceItem()` | -| `drop(itemId)` | `OSItemId` | Called when an item is dropped into an associated `OSDropZone`; dispatches to `onDrop()` | -| `makeNewItem()` | — | Called when the user requests a new empty item; dispatches to `onMakeNewItem()` | - ---- - -## Qt Signals - -| Signal | Arguments | Description | -|---|---|---| -| `itemIds` | `vector` | Emitted by `reportItems()` with the current ordered list of item IDs | -| `selectedItemId` | `OSItemId` | Emitted when the controller wants to notify listeners of a newly selected item | - ---- - -## Protected Virtual Methods (override points) - -| Method | Description | -|---|---| -| `makeVector()` | **Must override.** Return the current ordered list of `OSItemId`s from the model. | -| `onRemoveItem(item)` | Called when the user removes an item. Default: no-op. Override to delete from model. | -| `onReplaceItem(item, replacementId)` | Called when an item is replaced. Default: removes old, drops new. | -| `onDrop(itemId)` | Called when an item is dropped. Default: no-op. Override to insert into model. | -| `onMakeNewItem()` | Called to create a new blank item. Default: no-op. | - ---- - -## Usage Pattern - -```cpp -class MyController : public OSVectorController { -protected: - std::vector makeVector() override { - // Return OSItemIds for all objects of interest in the model - std::vector ids; - for (auto& obj : m_model.getModelObjects()) { - ids.push_back(modelObjectToItemId(obj, false)); - } - return ids; - } - - void onDrop(const OSItemId& itemId) override { - // Handle drop: add the dropped object to the model collection - } -}; -``` - -The controller is paired with an `OSDropZone` or `OSItemList` widget, which connects to `itemIds` to re-render whenever the model changes. diff --git a/developer/doc/libraries/bimserver.md b/developer/doc/libraries/bimserver.md index 8e81dfca5..bbaa8ec31 100644 --- a/developer/doc/libraries/bimserver.md +++ b/developer/doc/libraries/bimserver.md @@ -125,7 +125,6 @@ Blocking variants spin a `QEventLoop` with a `QTimer` for the timeout, making th --- -## Class Documentation +## Key Classes -- [BIMserverConnection](../classes/bimserver/BIMserverConnection.md) -- [ProjectImporter](../classes/bimserver/ProjectImporter.md) +Class-level documentation is in the corresponding header files under [`src/bimserver/`](../../../src/bimserver/). diff --git a/developer/doc/libraries/model_editor.md b/developer/doc/libraries/model_editor.md index a4eded4db..5db1aa172 100644 --- a/developer/doc/libraries/model_editor.md +++ b/developer/doc/libraries/model_editor.md @@ -104,8 +104,6 @@ classDiagram --- -## Class Documentation +## Key Classes -- [InspectorGadget](../classes/model_editor/InspectorGadget.md) -- [InspectorDialog](../classes/model_editor/InspectorDialog.md) -- [AccessPolicyStore](../classes/model_editor/AccessPolicyStore.md) +Class-level documentation is in the corresponding header files under [`src/model_editor/`](../../../src/model_editor/). diff --git a/developer/doc/libraries/openstudio_app.md b/developer/doc/libraries/openstudio_app.md index fa16dde39..1341a9737 100644 --- a/developer/doc/libraries/openstudio_app.md +++ b/developer/doc/libraries/openstudio_app.md @@ -90,7 +90,6 @@ classDiagram --- -## Class Documentation +## Key Classes -- [OpenStudioApp](../classes/openstudio_app/OpenStudioApp.md) -- [StartupView](../classes/openstudio_app/StartupView.md) +Class-level documentation is in the corresponding header files under [`src/openstudio_app/`](../../../src/openstudio_app/). diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index 3257a79f8..32fd6932d 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -138,26 +138,6 @@ classDiagram --- -## Class Documentation - -- [OSAppBase](../classes/openstudio_lib/OSAppBase.md) -- [OSDocument](../classes/openstudio_lib/OSDocument.md) -- [MainWindow](../classes/openstudio_lib/MainWindow.md) -- [MainTabController](../classes/openstudio_lib/MainTabController.md) -- [MainRightColumnController](../classes/openstudio_lib/MainRightColumnController.md) -- [OSVectorController](../classes/shared_gui_components/OSVectorController.md) -- [InspectorController](../classes/openstudio_lib/InspectorController.md) -- [ModelObjectListView](../classes/openstudio_lib/ModelObjectListView.md) -- [OSItem](../classes/openstudio_lib/OSItem.md) -- [OSDropZone](../classes/openstudio_lib/OSDropZone.md) -- [HVACSystemsController](../classes/openstudio_lib/HVACSystemsController.md) -- [HVACSystemsView](../classes/openstudio_lib/HVACSystemsView.md) -- [GeometryEditorController](../classes/openstudio_lib/GeometryEditorController.md) -- [ConstructionsController](../classes/openstudio_lib/ConstructionsController.md) -- [MaterialsController](../classes/openstudio_lib/MaterialsController.md) -- [SchedulesController](../classes/openstudio_lib/SchedulesController.md) -- [SpaceTypesController](../classes/openstudio_lib/SpaceTypesController.md) -- [ThermalZonesController](../classes/openstudio_lib/ThermalZonesController.md) -- [RunTabController](../classes/openstudio_lib/RunTabController.md) -- [ResultsTabController](../classes/openstudio_lib/ResultsTabController.md) -- [OSWebEnginePage](../classes/openstudio_lib/OSWebEnginePage.md) +## Key Classes + +Class-level documentation is in the corresponding header files under [`src/openstudio_lib/`](../../../src/openstudio_lib/). diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 36276dbeb..3f126bdb7 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -167,13 +167,6 @@ flowchart TD --- -## Class Documentation - -- [BaseApp](../classes/shared_gui_components/BaseApp.md) -- [OSGridController](../classes/shared_gui_components/OSGridController.md) -- [OSGridView](../classes/shared_gui_components/OSGridView.md) -- [OSVectorController](../classes/shared_gui_components/OSVectorController.md) -- [MeasureManager](../classes/shared_gui_components/MeasureManager.md) -- [BCLMeasureDialog](../classes/shared_gui_components/BCLMeasureDialog.md) -- [LocalLibraryController](../classes/shared_gui_components/LocalLibraryController.md) -- [BuildingComponentDialog](../classes/shared_gui_components/BuildingComponentDialog.md) +## Key Classes + +Class-level documentation is in the corresponding header files under [`src/shared_gui_components/`](../../../src/shared_gui_components/). diff --git a/src/bimserver/BIMServer.i b/src/bimserver/BIMServer.i deleted file mode 100644 index b307ae846..000000000 --- a/src/bimserver/BIMServer.i +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BIMSERVER_I -#define BIMSERVER_I - -#ifdef SWIGPYTHON -%module openstudiobimserver -#endif - - -#define UTILITIES_API - -%include -%import -%import -%import - -%{ - #include - using namespace openstudio::bimserver; - using namespace openstudio; - - #include - #include - -%} - -// #ifdef SWIGCSHARP -%rename(BIMserverProjectImportation) openstudio::bimserver::ProjectImportation; -// #endif - -%include bimserver/ProjectImportation.hpp> - -#endif //BIMSERVER_I diff --git a/src/bimserver/BIMserverConnection.hpp b/src/bimserver/BIMserverConnection.hpp index b276fe0aa..0fafb0703 100644 --- a/src/bimserver/BIMserverConnection.hpp +++ b/src/bimserver/BIMserverConnection.hpp @@ -27,7 +27,11 @@ class Surface; namespace bimserver { -/// This provides utilities to connect to BIMserver +/** + * BIMServerConnection manages the HTTP/JSON communication with a BIMserver instance. It handles + * authentication, project listing, IFC export requests, and IFC-to-OpenStudio model import. + * All network calls are asynchronous; results are delivered via Qt signals. + */ class BIMserverConnection : public QObject { Q_OBJECT diff --git a/src/bimserver/CMakeLists.txt b/src/bimserver/CMakeLists.txt index 1cf776c07..89f126ec4 100644 --- a/src/bimserver/CMakeLists.txt +++ b/src/bimserver/CMakeLists.txt @@ -17,10 +17,6 @@ set(${target_name}_test_src Test/BIMserverFixture.cpp ) -set(${target_name}_swig_src - BIMserver.i -) - set(${target_name}_depends openstudio_qt_utils ) @@ -38,7 +34,6 @@ AddPCH(${target_name}) CREATE_SRC_GROUPS("${${target_name}_src}") CREATE_SRC_GROUPS("${${target_name}_test_src}") -CREATE_SRC_GROUPS("${${target_name}_swig_src}") CREATE_TEST_TARGETS(${target_name} "${${target_name}_test_src}" "${${target_name}_depends}") #if(BUILD_TESTING) diff --git a/src/model_editor/InspectorDialog.hpp b/src/model_editor/InspectorDialog.hpp index 5336e4d8f..f0087bbaf 100644 --- a/src/model_editor/InspectorDialog.hpp +++ b/src/model_editor/InspectorDialog.hpp @@ -39,6 +39,11 @@ class ModelObject; OPENSTUDIO_ENUM(InspectorDialogClient, ((AllOpenStudio))); #endif +/** + * InspectorDialog is a standalone QMainWindow that hosts an InspectorGadget for viewing and editing + * any ModelObject from the OpenStudio model. It is used in the Model Editor tool as the primary + * object inspector window. + */ class InspectorDialog : public QMainWindow , public Nano::Observer diff --git a/src/model_editor/ModelEditor.i b/src/model_editor/ModelEditor.i deleted file mode 100644 index 250aeb51f..000000000 --- a/src/model_editor/ModelEditor.i +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef MODELEDITOR_LIB_I -#define MODELEDITOR_LIB_I - -#ifdef SWIGPYTHON -%module openstudiomodeleditor -#endif - -#define UTILITIES_API -#define MODEL_API - -%include -%import -%import - -#if defined(SWIGCSHARP) || defined(SWIGJAVA) -%import -#else -%import(module="openstudiomodel") -%import(module="openstudiomodel") -#endif - -%{ - #include - #include - - #include - #include - - using namespace openstudio; - using namespace openstudio::model; - - // to be ignored - namespace openstudio{ - class ProgressBar; - class UpdateManager; - class IdfObjectWatcher; - class BCL; - class RemoteBCL; - class LocalBCL; - class WorkspaceObjectWatcher; - class WorkspaceWatcher; - } -%} - -%feature("director") OSSimpleProgressBar; -%include - -#endif //MODELEDITOR_LIB_I diff --git a/src/model_editor/Qt.i b/src/model_editor/Qt.i deleted file mode 100644 index ef6c34e5d..000000000 --- a/src/model_editor/Qt.i +++ /dev/null @@ -1,278 +0,0 @@ -#ifndef MODELEDITOR_QT_I -#define MODELEDITOR_QT_I - -// get rid of Q_OBJECT macros -#define Q_OBJECT - -// ignore these -#define Q_DECLARE_METATYPE(type) - -// slots remain public or private -#define slots - -// all signals are turned private -#define signals private - -// DLM commented out while still defined in Utilities Qt.i -// DLM@20091231: we need to generalize our plotting stuff -//namespace Qt{ -// enum GlobalColor { white, black, red, darkRed, green, darkGreen, blue, darkBlue, cyan, -// darkCyan, magenta, darkMagenta, yellow, darkYellow, gray, darkGray, -// lightGray, transparent, color0, color1 }; -// -// enum ConnectionType { AutoConnection=0, -// DirectConnection=1, -// QueuedConnection=2, -// BlockingQueuedConnection=3, -// UniqueConnection=0x80}; -//} // Qt - - -%{ - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -%} - -//class QObject -//{ -// QObject(); -// QObject(QObject* parent); -//}; - -//%rename(Color) QColor; -//class QColor -//{ -//public: -// enum Spec { Invalid, Rgb, Hsv, Cmyk }; -// -// QColor(); -// QColor(int r, int g, int b, int a = 255); -// QColor(QRgb rgb); -// QColor(const QString& name); -// QColor(const char *name); -// QColor(const QColor &color); -// QColor(Qt::GlobalColor color); -// bool isValid() const; -// QString name() const; -// void setNamedColor(const QString& name); -// static QStringList colorNames(); -// Spec spec() const; -// int alpha() const; -// void setAlpha(int alpha); -// double alphaF() const; -// void setAlphaF(qreal alpha); -// int red() const; -// int green() const; -// int blue() const; -// void setRed(int red); -// void setGreen(int green); -// void setBlue(int blue); -// void getRgb(int *r, int *g, int *b, int *a = 0) const; -// void setRgb(int r, int g, int b, int a = 255); -// int hue() const; // 0 <= hue < 360 -// int saturation() const; -// int value() const; -// void getHsv(int *h, int *s, int *v, int *a = 0) const; -// void setHsv(int h, int s, int v, int a = 255); -// int cyan() const; -// int magenta() const; -// int yellow() const; -// int black() const; -// void getCmyk(int *c, int *m, int *y, int *k, int *a = 0); -// void setCmyk(int c, int m, int y, int k, int a = 255); -// QColor toRgb() const; -// QColor toHsv() const; -// QColor toCmyk() const; -// QColor convertTo(Spec colorSpec) const; -// static QColor fromRgb(int r, int g, int b, int a = 255); -// static QColor fromHsv(int h, int s, int v, int a = 255); -// static QColor fromCmyk(int c, int m, int y, int k, int a = 255); -// QColor light(int f = 150) const; -// QColor lighter(int f = 150) const; -// QColor dark(int f = 200) const; -// QColor darker(int f = 200) const; -// QColor &operator=(const QColor &); -// QColor &operator=(Qt::GlobalColor color); -// bool operator==(const QColor &c) const; -// bool operator!=(const QColor &c) const; -//}; - -class QWidget -{ -public: - QWidget(); - QWidget(QWidget* parent); - void show(); - void hide(); - bool isWindow() const; - QString windowTitle() const; - void setWindowTitle(const QString &); - bool isActiveWindow() const; - void activateWindow(); - void raise(); - void lower(); - bool isAncestorOf(const QWidget* child) const; - bool isEnabled() const; - bool isEnabledTo(QWidget * ancestor) const; - void setEnabled(bool enabled); - bool isFullScreen() const; - bool isHidden() const; - bool isMaximized() const; - bool isMinimized() const; - bool isModal() const; - bool isVisible() const; - bool isVisibleTo(QWidget* ancestor) const; - void setVisible(bool visible); -}; - -class QMainWindow : public QWidget -{}; - -class QDialog : public QWidget -{}; - -class QComboBox : public QWidget -{}; - -//class QTextStream{}; - -//class QRgb{}; - -class QString{}; - -%extend QString{ - // to std::string - std::string __str__() const{ - return toString(*self); - } -} - -//class QModelIndex{}; - -//class QModelIndexList{}; - -%nodefaultctor QCoreApplication; -class QCoreApplication{}; - -%extend QCoreApplication{ - - void setApplicationName(const std::string& applicationName) const{ - self->setApplicationName(QString::fromStdString(applicationName)); - } - - void setOrganizationName(const std::string& organizationName) const{ - self->setOrganizationName(QString::fromStdString(organizationName)); - } - void setOrganizationDomain(const std::string& organizationDomain) const{ - self->setOrganizationDomain(QString::fromStdString(organizationDomain)); - } -} - -%nodefaultctor QApplication; -class QApplication : public QCoreApplication -{}; - -//class QFont{}; - -//class QDomNode{}; - -//class QDomElement : public QDomNode -//{}; - -//class QDomDocument : public QDomNode -//{}; - -class QUrl -{}; - -//%nodefaultctor QNetworkRequest; -//class QNetworkRequest -//{}; - -//%nodefaultctor QNetworkReply; -//class QNetworkReply -//{}; - -//%nodefaultctor QNetworkAccessManager; -//class QNetworkAccessManager : public QObject -//{}; - -//class QStandardItem -//{}; - - -// TODO: Check if actually needed... -#if defined SWIGJAVA -%rename(toQString) QVariant::toString; -#endif - -%template(QVariantVector) std::vector; -%template(QVariantVectorVector) std::vector >; -class QVariant { - public: - enum Type { Invalid = 0, - Bool = 1, - Int = 2, - UInt = 3, - LongLong = 4, - ULongLong = 5, - Double = 6, - String = 10, - Url = 17, - UserType = 127 }; - - QVariant(); - explicit QVariant( const QVariant& p); - explicit QVariant( int val ); - explicit QVariant( uint val ); - explicit QVariant( bool val ); - explicit QVariant( double val ); - explicit QVariant( const char* val ); - explicit QVariant( const QString& val ); - explicit QVariant( const QUrl& val ); - ~QVariant(); - - bool canConvert( Type t ) const; - void clear(); - bool convert( Type t ); - bool isNull() const; - bool isValid() const; - bool toBool() const; - double toDouble() const; - int toInt() const; - QString toString() const; - uint toUInt() const; - QUrl toUrl() const; - Type type() const; - const char * typeName() const; - - QVariant& operator=( const QVariant& variant); - - static Type nameToType( const char* name); - const char* typeToName( Type typ ); -}; - - -#endif // MODELEDITOR_QT_I - diff --git a/src/openstudio_app/OpenStudioApp.hpp b/src/openstudio_app/OpenStudioApp.hpp index 00c823f3e..3e4989a56 100644 --- a/src/openstudio_app/OpenStudioApp.hpp +++ b/src/openstudio_app/OpenStudioApp.hpp @@ -71,6 +71,11 @@ class TouchEater : public QObject bool eventFilter(QObject* obj, QEvent* event); }; +/** + * OpenStudioApp is the top-level QApplication subclass for the OpenStudio Application. It owns the + * OSDocument (model lifecycle), the main window, the measure manager, and coordinates between all + * top-level controllers. It implements OSAppBase and therefore BaseApp. + */ class OpenStudioApp : public OSAppBase { diff --git a/src/openstudio_app/StartupView.hpp b/src/openstudio_app/StartupView.hpp index 2338671c8..39236cfee 100644 --- a/src/openstudio_app/StartupView.hpp +++ b/src/openstudio_app/StartupView.hpp @@ -18,6 +18,11 @@ namespace openstudio { class TemplateListModel; +/** + * StartupView is the welcome/startup dialog shown when no project is open. It presents recent files, + * new-file and open-file buttons, and links to online resources. It is shown at launch and after a + * project is closed. + */ class StartupView : public QWidget { Q_OBJECT diff --git a/src/openstudio_lib/ConstructionsController.hpp b/src/openstudio_lib/ConstructionsController.hpp index e959f8590..002793a8b 100644 --- a/src/openstudio_lib/ConstructionsController.hpp +++ b/src/openstudio_lib/ConstructionsController.hpp @@ -10,6 +10,11 @@ namespace openstudio { +/** + * ConstructionsController manages the Constructions domain tab. It displays all construction objects + * in the model in a list, and provides a tabbed sub-tab layout for constructions, construction sets, + * and materials with an inspector that shows layers and thermal properties. + */ class ConstructionsController : public ModelSubTabController { Q_OBJECT diff --git a/src/openstudio_lib/GeometryEditorController.hpp b/src/openstudio_lib/GeometryEditorController.hpp index af0e174f7..050a9c41d 100644 --- a/src/openstudio_lib/GeometryEditorController.hpp +++ b/src/openstudio_lib/GeometryEditorController.hpp @@ -13,6 +13,11 @@ namespace model { class Model; } +/** + * GeometryEditorController manages the Geometry tab, which embeds a web-based 3D geometry editor + * (FloorspaceJS) via a QWebEngineView. It bridges JSON geometry edits from the web view back to + * the OpenStudio model and handles save/load of the floorplan JSON. + */ class GeometryEditorController : public OSQObjectController { Q_OBJECT diff --git a/src/openstudio_lib/HVACSystemsController.hpp b/src/openstudio_lib/HVACSystemsController.hpp index 6392d6825..13b400422 100644 --- a/src/openstudio_lib/HVACSystemsController.hpp +++ b/src/openstudio_lib/HVACSystemsController.hpp @@ -64,6 +64,11 @@ class RefrigerationGridController; class RefrigerationGridView; class VRFController; +/** + * HVACSystemsController manages the HVAC Systems tab. It maintains a set of scene controllers + * (one per HVAC system or loop in the model) and routes user interactions to the appropriate scene. + * It also manages the system selector dropdown and the "Add System" toolbar. + */ class HVACSystemsController : public QObject , public Nano::Observer diff --git a/src/openstudio_lib/HVACSystemsView.hpp b/src/openstudio_lib/HVACSystemsView.hpp index 3cd16ae13..e848deee1 100644 --- a/src/openstudio_lib/HVACSystemsView.hpp +++ b/src/openstudio_lib/HVACSystemsView.hpp @@ -39,6 +39,12 @@ class SetpointManagerWarmestTemperatureFlow; class SetpointManagerColdest; } // namespace model +/** + * HVACSystemsView is the top-level widget for the HVAC Systems tab. It hosts the system selector + * toolbar, the tabbed system scenes, and the mechanical ventilation/service water loops panels. + * The graphical system scenes are rendered by domain-specific scene widgets hosted in a + * QStackedWidget inside this view. + */ class HVACSystemsView : public QWidget { Q_OBJECT diff --git a/src/openstudio_lib/InspectorController.hpp b/src/openstudio_lib/InspectorController.hpp index 8c229ab27..20413c426 100644 --- a/src/openstudio_lib/InspectorController.hpp +++ b/src/openstudio_lib/InspectorController.hpp @@ -26,6 +26,11 @@ class WaterToAirComponent; class InspectorView; +/** + * InspectorController manages the right-column inspector panel. When an OSItem is selected anywhere + * in the application, InspectorController instantiates or updates the appropriate + * ModelObjectInspectorView subclass and displays it in the right column. + */ class InspectorController : public QObject { Q_OBJECT diff --git a/src/openstudio_lib/MainRightColumnController.hpp b/src/openstudio_lib/MainRightColumnController.hpp index 1cb9ee2dc..01ac2437d 100644 --- a/src/openstudio_lib/MainRightColumnController.hpp +++ b/src/openstudio_lib/MainRightColumnController.hpp @@ -26,6 +26,12 @@ class InspectorController; class LocalLibraryController; class SystemItem; +/** + * MainRightColumnController manages the right-column sidebar, which has three tabs: Inspector + * (shows properties of the selected model object), Library (the local BCL/measure browser), and + * Edit (apply-measure-now and workflow edit). It owns an InspectorController and a + * LocalLibraryController and routes switching between them. + */ class MainRightColumnController : public OSQObjectController { Q_OBJECT diff --git a/src/openstudio_lib/MainTabController.hpp b/src/openstudio_lib/MainTabController.hpp index 0ef86cae7..e7e31cf81 100644 --- a/src/openstudio_lib/MainTabController.hpp +++ b/src/openstudio_lib/MainTabController.hpp @@ -16,6 +16,11 @@ namespace openstudio { class MainTabView; class OSItem; +/** + * MainTabController is the abstract base class for all main-content-area tab controllers + * (Constructions, HVAC Systems, Schedules, etc.). Each subclass owns one or more MainTabView + * subclasses and handles the sub-tab switching logic for its domain. + */ class MainTabController : public OSQObjectController { Q_OBJECT diff --git a/src/openstudio_lib/MainWindow.hpp b/src/openstudio_lib/MainWindow.hpp index 84061a83d..8b891d2ea 100644 --- a/src/openstudio_lib/MainWindow.hpp +++ b/src/openstudio_lib/MainWindow.hpp @@ -24,6 +24,11 @@ class VerticalTabWidget; class MainMenu; +/** + * MainWindow is the application main window QMainWindow. It hosts the vertical tab bar (left side), + * the main content stack widget for each tab, the vertical toolbar, and the status bar. It routes + * tab-switching signals to OSDocument and wires up the menu bar. + */ class MainWindow : public QMainWindow { Q_OBJECT diff --git a/src/openstudio_lib/MaterialsController.hpp b/src/openstudio_lib/MaterialsController.hpp index d5f171edf..89943ba32 100644 --- a/src/openstudio_lib/MaterialsController.hpp +++ b/src/openstudio_lib/MaterialsController.hpp @@ -10,6 +10,11 @@ namespace openstudio { +/** + * MaterialsController manages the Materials sub-tab within the Constructions tab. It shows all + * material objects in the model in a list and provides an inspector for editing material thermal + * and optical properties. + */ class MaterialsController : public ModelSubTabController { Q_OBJECT diff --git a/src/openstudio_lib/ModelObjectListView.hpp b/src/openstudio_lib/ModelObjectListView.hpp index 633753d05..0c1e55272 100644 --- a/src/openstudio_lib/ModelObjectListView.hpp +++ b/src/openstudio_lib/ModelObjectListView.hpp @@ -46,6 +46,11 @@ class ModelObjectListController : public OSVectorController void reportItemsImpl(); }; +/** + * ModelObjectListView is a scrollable list widget that shows all model objects of a specific + * IddObjectType. It listens to model change signals via nano signals and updates the list + * incrementally. It emits itemSelected signals that drive the right-column inspector. + */ class ModelObjectListView : public OSItemList { Q_OBJECT diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index f0ee1d7b0..bf4612652 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -25,6 +25,11 @@ class OSDocument; class WaitDialog; +/** + * OSAppBase is the abstract base class for the OpenStudio application, implementing the BaseApp + * interface. It is subclassed by OpenStudioApp (standalone app) and provides common application + * services: the measure manager, document management, and the current model accessor. + */ class OSAppBase : public QApplication , public BaseApp diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index b7da327a1..743097fa4 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -42,6 +42,12 @@ class ApplyMeasureNowDialog; class Workspace; +/** + * OSDocument manages the full lifecycle of an OpenStudio model within the application: loading + * from disk, saving, reverting, and closing. It owns all the domain tab controllers and their + * views, constructs the complete tab bar layout, and coordinates undo/redo, units (IP/SI), and + * weather file management. + */ class OSDocument : public OSQObjectController { Q_OBJECT diff --git a/src/openstudio_lib/OSDropZone.hpp b/src/openstudio_lib/OSDropZone.hpp index e71ae2cda..1decf2a85 100644 --- a/src/openstudio_lib/OSDropZone.hpp +++ b/src/openstudio_lib/OSDropZone.hpp @@ -121,6 +121,12 @@ class OSDropZone2 QLabel* m_label; }; +/** + * OSDropZone is a QWidget that acts as a drop target for OSItems. It accepts drops from the + * left-column model object lists, forwards them to an OSVectorController, and visually indicates + * the valid/invalid drop state. It also shows the currently "dropped" item and provides a remove + * button. + */ class OSDropZone : public QWidget , public Nano::Observer diff --git a/src/openstudio_lib/OSItem.hpp b/src/openstudio_lib/OSItem.hpp index 024087608..d9ace0ad4 100644 --- a/src/openstudio_lib/OSItem.hpp +++ b/src/openstudio_lib/OSItem.hpp @@ -24,6 +24,11 @@ namespace openstudio { class MeasureBadge; +/** + * OSItem is the base class for all draggable/selectable items displayed in list views and drop + * zones throughout the application. Each OSItem wraps an OSItemId (module + handle pair) and + * provides consistent drag-and-drop support, selection highlighting, and remove-button behaviour. + */ class OSItem : public QWidget , public Nano::Observer diff --git a/src/openstudio_lib/OSWebEnginePage.hpp b/src/openstudio_lib/OSWebEnginePage.hpp index 2f82c5eaf..70361dbcf 100644 --- a/src/openstudio_lib/OSWebEnginePage.hpp +++ b/src/openstudio_lib/OSWebEnginePage.hpp @@ -26,6 +26,11 @@ class OSUrlRequestInterceptor : public QWebEngineUrlRequestInterceptor QByteArray m_userAgent; }; +/** + * OSWebEnginePage is a QWebEnginePage subclass that adds OpenStudio-specific URL interception and + * JavaScript bridge support. It is used by the Geometry tab's web view to communicate between the + * FloorspaceJS editor and the C++ model layer. + */ class OSWebEnginePage : public QWebEnginePage { Q_OBJECT diff --git a/src/openstudio_lib/ResultsTabController.hpp b/src/openstudio_lib/ResultsTabController.hpp index d5ff6d19e..c44f51f70 100644 --- a/src/openstudio_lib/ResultsTabController.hpp +++ b/src/openstudio_lib/ResultsTabController.hpp @@ -20,6 +20,11 @@ class Model; class ResultsTabView; +/** + * ResultsTabController manages the Results tab. After a simulation completes, it loads the + * EnergyPlus SQL output database and displays summary results tables and charts. It listens for + * the resultsGenerated signal from RunTabController to trigger the load. + */ class ResultsTabController : public MainTabController { Q_OBJECT diff --git a/src/openstudio_lib/RunTabController.hpp b/src/openstudio_lib/RunTabController.hpp index 96186d62b..b40be7d3b 100644 --- a/src/openstudio_lib/RunTabController.hpp +++ b/src/openstudio_lib/RunTabController.hpp @@ -22,6 +22,11 @@ class Model; class RunView; +/** + * RunTabController manages the Run/Simulation tab. It saves the model to a temporary directory, + * spawns the OpenStudio CLI as a QProcess with the saved workflow file, streams stdout/stderr to + * the RunView log pane, and emits resultsGenerated when the simulation succeeds. + */ class RunTabController : public MainTabController { Q_OBJECT diff --git a/src/openstudio_lib/SpaceTypesController.hpp b/src/openstudio_lib/SpaceTypesController.hpp index de2ef4890..8e59b812c 100644 --- a/src/openstudio_lib/SpaceTypesController.hpp +++ b/src/openstudio_lib/SpaceTypesController.hpp @@ -10,6 +10,12 @@ namespace openstudio { +/** + * SpaceTypesController manages the Space Types tab, which shows all space type objects in the + * model in a grid view. Each row is a space type; columns show its name, default construction set, + * default schedule set, lighting power density, people density, equipment, outdoor air, and + * rendering color. + */ class SpaceTypesController : public ModelSubTabController { Q_OBJECT diff --git a/src/openstudio_lib/ThermalZonesController.hpp b/src/openstudio_lib/ThermalZonesController.hpp index 520554357..4aee432c7 100644 --- a/src/openstudio_lib/ThermalZonesController.hpp +++ b/src/openstudio_lib/ThermalZonesController.hpp @@ -25,6 +25,12 @@ class ZoneHVACComponent; class ThermalZonesView; +/** + * ThermalZonesController manages the Thermal Zones tab, showing all thermal zone objects in the + * model in a grid view. Each row represents one zone; columns expose thermostat types, + * humidistats, zone multipliers, cooling/heating ideal air loads, zone equipment, and DOAS + * connections. + */ class ThermalZonesController : public ModelSubTabController { Q_OBJECT diff --git a/src/openstudio_qt_utils/QMetaTypes.cpp b/src/openstudio_qt_utils/QMetaTypes.cpp index 714d3be25..b05872056 100644 --- a/src/openstudio_qt_utils/QMetaTypes.cpp +++ b/src/openstudio_qt_utils/QMetaTypes.cpp @@ -11,23 +11,23 @@ namespace detail { // Note JM 2018-12-19: `Q_DECLARE_METATYPE` is enough to use a type inside a QVariant, but qRegisterMetaType is needed to use the type in // *queued* signals/slots and to dynamically create objects of these types at runtime -[[maybe_unused]] int __iddobjectype_type = qRegisterMetaType("openstudio::IddObjectType"); -[[maybe_unused]] int __iddfiletype_type = qRegisterMetaType("openstudio::IddFileType"); +[[maybe_unused]] int iddobjecttype_meta_type_id = qRegisterMetaType("openstudio::IddObjectType"); +[[maybe_unused]] int iddfiletype_meta_type_id = qRegisterMetaType("openstudio::IddFileType"); -[[maybe_unused]] int __uuid_type = qRegisterMetaType("openstudio::UUID"); +[[maybe_unused]] int uuid_meta_type_id = qRegisterMetaType("openstudio::UUID"); -[[maybe_unused]] int __string_type = qRegisterMetaType("std::string"); -[[maybe_unused]] int __string_vector_type = qRegisterMetaType>("std::vector"); +[[maybe_unused]] int string_meta_type_id = qRegisterMetaType("std::string"); +[[maybe_unused]] int string_vector_meta_type_id = qRegisterMetaType>("std::vector"); -[[maybe_unused]] int __optional_double_type = qRegisterMetaType>("boost::optional"); -[[maybe_unused]] int __optional_unsigned_type = qRegisterMetaType>("boost::optional"); -[[maybe_unused]] int __optional_int_type = qRegisterMetaType>("boost::optional"); -[[maybe_unused]] int __optional_string_type = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int optional_double_meta_type_id = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int optional_unsigned_meta_type_id = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int optional_int_meta_type_id = qRegisterMetaType>("boost::optional"); +[[maybe_unused]] int optional_string_meta_type_id = qRegisterMetaType>("boost::optional"); -[[maybe_unused]] int __quantity_type = qRegisterMetaType("openstudio::Quantity"); -[[maybe_unused]] int __optionalquantity_type = qRegisterMetaType("openstudio::OSOptionalQuantity"); +[[maybe_unused]] int quantity_meta_type_id = qRegisterMetaType("openstudio::Quantity"); +[[maybe_unused]] int optional_quantity_meta_type_id = qRegisterMetaType("openstudio::OSOptionalQuantity"); -[[maybe_unused]] int __workspaceobject_type = qRegisterMetaType>(); +[[maybe_unused]] int workspaceobject_impl_meta_type_id = qRegisterMetaType>(); } // namespace detail } // namespace openstudio diff --git a/src/shared_gui_components/BCLMeasureDialog.hpp b/src/shared_gui_components/BCLMeasureDialog.hpp index 380e2d733..0257ca028 100644 --- a/src/shared_gui_components/BCLMeasureDialog.hpp +++ b/src/shared_gui_components/BCLMeasureDialog.hpp @@ -19,6 +19,11 @@ class QListWidget; namespace openstudio { +/** + * BCLMeasureDialog is a modal dialog that lets users search and download OpenStudio Measures from + * the NREL Building Component Library (BCL). It queries the BCL REST API, displays results with + * taxonomy filtering and free-text search, and downloads selected measures to the local BCL cache. + */ class BCLMeasureDialog : public OSDialog { Q_OBJECT diff --git a/src/shared_gui_components/BaseApp.hpp b/src/shared_gui_components/BaseApp.hpp index 3539cf51b..c8081515e 100644 --- a/src/shared_gui_components/BaseApp.hpp +++ b/src/shared_gui_components/BaseApp.hpp @@ -26,6 +26,12 @@ namespace model { class Model; } +/** + * BaseApp is a pure abstract interface that decouples all shared GUI components from any specific + * application implementation. Widgets like MeasureManager, LocalLibraryController, and + * BuildingComponentDialog depend only on BaseApp, not on OSAppBase or OpenStudioApp. This isolation + * enables the shared components to be hosted in any Qt host without modification. + */ class BaseApp { public: diff --git a/src/shared_gui_components/BuildingComponentDialog.hpp b/src/shared_gui_components/BuildingComponentDialog.hpp index 9c4fe5f6e..1fd277dbb 100644 --- a/src/shared_gui_components/BuildingComponentDialog.hpp +++ b/src/shared_gui_components/BuildingComponentDialog.hpp @@ -26,6 +26,12 @@ namespace openstudio { class BuildingComponentDialogCentralWidget; class Component; +/** + * BuildingComponentDialog is a modal dialog for browsing and downloading building components + * (constructions, materials, schedules, etc.) from the NREL Building Component Library (BCL). + * Once downloaded, the component is available for drag-and-drop into the relevant model views. + * It is analogous to BCLMeasureDialog but targets BCL components rather than measures. + */ class BuildingComponentDialog : public QDialog { Q_OBJECT diff --git a/src/shared_gui_components/LocalLibraryController.hpp b/src/shared_gui_components/LocalLibraryController.hpp index 4fef7a260..71350feca 100644 --- a/src/shared_gui_components/LocalLibraryController.hpp +++ b/src/shared_gui_components/LocalLibraryController.hpp @@ -38,6 +38,13 @@ class LibraryItem; // TODO: Perhaps generalize LibraryGroupItem, LibrarySubGroupItem, LibraryItem and related classes into one tree like set of class. +/** + * LocalLibraryController manages the "Library" tab of the right-column sidebar. It provides a + * searchable, filterable browser of all locally available OpenStudio Measures (from both + * myMeasures and the BCL cache), organized by taxonomy category. Users can browse, search, and + * select measures; the selected measure can be dragged into the workflow or applied immediately + * via ApplyMeasureNowDialog. + */ class LocalLibraryController : public QObject { Q_OBJECT diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index b09cc9d81..32743df3c 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -6,10 +6,10 @@ #include "OSGridController.hpp" // Register OSItemId metatypes for queued signal/slot connections. -// Q_DECLARE_METATYPE is in OSGridController.hpp; qRegisterMetaType must run at startup. +// Q_DECLARE_METATYPE is in OSItemId.hpp; qRegisterMetaType must run at startup. namespace { -[[maybe_unused]] const int __ositemid_type = qRegisterMetaType("OSItemId"); -[[maybe_unused]] const int __ositemid_vector_type = qRegisterMetaType>("std::vector"); +[[maybe_unused]] const int ositemid_meta_type_id = qRegisterMetaType("OSItemId"); +[[maybe_unused]] const int ositemid_vector_meta_type_id = qRegisterMetaType>("std::vector"); } // namespace #include "OSCellWrapper.hpp" diff --git a/src/shared_gui_components/OSGridController.hpp b/src/shared_gui_components/OSGridController.hpp index 9bb1f80d0..5dd28c8d0 100644 --- a/src/shared_gui_components/OSGridController.hpp +++ b/src/shared_gui_components/OSGridController.hpp @@ -11,8 +11,6 @@ #include "OSItemId.hpp" #include "OSVectorController.hpp" #include "../openstudio_qt_utils/QMetaTypes.hpp" -Q_DECLARE_METATYPE(openstudio::OSItemId) -Q_DECLARE_METATYPE(std::vector) #include #include @@ -136,6 +134,15 @@ class DataSourceAdapter : public BaseConcept QSharedPointer m_inner; }; +/** + * OSGridController is the abstract base class for all multi-column tabular model views. It + * provides a declarative column-definition API (addCheckBoxColumn, addComboBoxColumn, + * addDoubleEditColumn, addDropZoneColumn, addLineEditColumn, addIntegerEditColumn, + * addRenderingColorColumn) and manages row-object mapping, selection state, and cell widget + * creation on demand. Concrete subclasses declare their columns in their constructor; data is + * fetched lazily via std::function getters/setters. Columns can optionally be wrapped in a + * DataSource to display stacked sub-object widgets per cell. + */ class OSGridController : public QObject { Q_OBJECT diff --git a/src/shared_gui_components/OSGridView.hpp b/src/shared_gui_components/OSGridView.hpp index a1083e78b..18dca4e71 100644 --- a/src/shared_gui_components/OSGridView.hpp +++ b/src/shared_gui_components/OSGridView.hpp @@ -32,6 +32,13 @@ class OSItem; class GridCellLocation; class GridCellInfo; +/** + * OSGridView is the QWidget that hosts and renders an OSGridController. It manages a QScrollArea + * containing a grid of OSCellWrapper widgets arranged in rows and columns. It handles row + * selection highlighting and forwards keyboard navigation events to the controller. Domain views + * (ThermalZonesGridView, SpaceTypesGridView, etc.) typically subclass OSGridView or compose it + * with filter/search bars. + */ class OSGridView : public QWidget { Q_OBJECT diff --git a/src/shared_gui_components/OSItemId.hpp b/src/shared_gui_components/OSItemId.hpp index c15e26178..55ec4ebbb 100644 --- a/src/shared_gui_components/OSItemId.hpp +++ b/src/shared_gui_components/OSItemId.hpp @@ -8,6 +8,7 @@ #include #include +#include class QMimeData; @@ -43,4 +44,7 @@ class OSItemId } // namespace openstudio +Q_DECLARE_METATYPE(openstudio::OSItemId) +Q_DECLARE_METATYPE(std::vector) + #endif // SHAREDGUICOMPONENTS_OSITEMID_HPP diff --git a/src/shared_gui_components/OSVectorController.hpp b/src/shared_gui_components/OSVectorController.hpp index b66a1e77d..72680c027 100644 --- a/src/shared_gui_components/OSVectorController.hpp +++ b/src/shared_gui_components/OSVectorController.hpp @@ -21,6 +21,13 @@ namespace openstudio { class OSItem; +/** + * OSVectorController is the abstract base class for all list/vector controllers in the + * application. It manages an ordered list of OSItemIds representing model objects displayed in an + * OSItemList or OSDropZone widget. Concrete subclasses implement makeVector() to return the + * current item IDs from the model. The base class handles deduplication of re-render requests via + * a mutex and routes user interactions (remove, replace, drop, create) through virtual dispatch. + */ class OSVectorController : public QObject , public Nano::Observer From b081f8ec5c273614e8f4c15fa0461050a9b4b96b Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 19:26:45 -0600 Subject: [PATCH 09/26] Address link errors on Ubuntu --- src/openstudio_lib/CMakeLists.txt | 3 - .../FacilityStoriesGridView.cpp | 2 +- src/shared_gui_components/CMakeLists.txt | 6 + .../LocalLibraryView.cpp | 2 - src/shared_gui_components/MeasureManager.cpp | 2 - src/shared_gui_components/OSCellWrapper.cpp | 2 +- .../OSGridController.cpp | 13 +-- src/shared_gui_components/OSGridView.cpp | 2 - src/shared_gui_components/OSLineEdit.cpp | 1 - .../OSLoadNamePixmapLineEdit.cpp | 1 - .../OSObjectSelector.cpp | 12 -- src/shared_gui_components/OSWidgetHolder.cpp | 1 - .../RenderingColorWidget.cpp | 108 ++++++++++++++++++ .../RenderingColorWidget.hpp | 50 ++++++++ .../RenderingColorWidget2.cpp} | 93 +-------------- .../RenderingColorWidget2.hpp} | 37 +----- 16 files changed, 175 insertions(+), 160 deletions(-) create mode 100644 src/shared_gui_components/RenderingColorWidget.cpp create mode 100644 src/shared_gui_components/RenderingColorWidget.hpp rename src/{openstudio_lib/RenderingColorWidget.cpp => shared_gui_components/RenderingColorWidget2.cpp} (75%) rename src/{openstudio_lib/RenderingColorWidget.hpp => shared_gui_components/RenderingColorWidget2.hpp} (65%) diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index fa7b167b8..6ab2c2878 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -225,8 +225,6 @@ set(${target_name}_SRC RefrigerationGridView.hpp RefrigerationScene.cpp RefrigerationScene.hpp - RenderingColorWidget.cpp - RenderingColorWidget.hpp ResultsTabController.cpp ResultsTabController.hpp ResultsTabView.cpp @@ -500,7 +498,6 @@ set(${target_name}_moc RefrigerationGridController.hpp RefrigerationGridView.hpp RefrigerationScene.hpp - RenderingColorWidget.hpp ResultsTabController.hpp ResultsTabView.hpp RunTabController.hpp diff --git a/src/openstudio_lib/FacilityStoriesGridView.cpp b/src/openstudio_lib/FacilityStoriesGridView.cpp index 4762527d9..239373575 100644 --- a/src/openstudio_lib/FacilityStoriesGridView.cpp +++ b/src/openstudio_lib/FacilityStoriesGridView.cpp @@ -7,7 +7,7 @@ #include "OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" -#include "RenderingColorWidget.hpp" +#include "../shared_gui_components/RenderingColorWidget.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index e41da293a..c9b1ff306 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -50,6 +50,10 @@ set(${target_name}_src MeasureManager.hpp NetworkProxyDialog.cpp NetworkProxyDialog.hpp + RenderingColorWidget.cpp + RenderingColorWidget.hpp + RenderingColorWidget2.cpp + RenderingColorWidget2.hpp OSCellWrapper.cpp OSCellWrapper.hpp OSCheckBox.cpp @@ -142,6 +146,8 @@ set(${target_name}_moc MeasureDragData.hpp MeasureManager.hpp NetworkProxyDialog.hpp + RenderingColorWidget.hpp + RenderingColorWidget2.hpp OSCellWrapper.hpp OSCheckBox.hpp OSCollapsibleView.hpp diff --git a/src/shared_gui_components/LocalLibraryView.cpp b/src/shared_gui_components/LocalLibraryView.cpp index 32933a851..01a94b8b5 100644 --- a/src/shared_gui_components/LocalLibraryView.cpp +++ b/src/shared_gui_components/LocalLibraryView.cpp @@ -8,8 +8,6 @@ #include "Buttons.hpp" #include "OSViewSwitcher.hpp" -#include "../openstudio_lib/OSItem.hpp" - #include "MeasureBadge.hpp" #include diff --git a/src/shared_gui_components/MeasureManager.cpp b/src/shared_gui_components/MeasureManager.cpp index 82055a7d5..1843aaf92 100644 --- a/src/shared_gui_components/MeasureManager.cpp +++ b/src/shared_gui_components/MeasureManager.cpp @@ -31,8 +31,6 @@ #include #include -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" #include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include diff --git a/src/shared_gui_components/OSCellWrapper.cpp b/src/shared_gui_components/OSCellWrapper.cpp index b315eae94..8adb8475e 100644 --- a/src/shared_gui_components/OSCellWrapper.cpp +++ b/src/shared_gui_components/OSCellWrapper.cpp @@ -18,7 +18,7 @@ #include "OSWidgetHolder.hpp" #include "../openstudio_lib/OSDropZone.hpp" -#include "../openstudio_lib/RenderingColorWidget.hpp" +#include "RenderingColorWidget2.hpp" #include #include diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index 32743df3c..8667d2c5c 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -16,16 +16,11 @@ namespace { #include "OSGridView.hpp" #include "OSObjectSelector.hpp" -#include "../openstudio_lib/HorizontalTabWidget.hpp" -#include "../openstudio_lib/MainRightColumnController.hpp" -#include "../openstudio_lib/ModelObjectInspectorView.hpp" #include "../openstudio_lib/ModelObjectItem.hpp" -//#include "../openstudio_lib/ModelSubTabView.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" -#include "../openstudio_lib/OSDropZone.hpp" -#include "../openstudio_lib/OSItemSelector.hpp" -#include "../openstudio_lib/RenderingColorWidget.hpp" +#include "../openstudio_lib/OSItem.hpp" + +#include +#include #include #include diff --git a/src/shared_gui_components/OSGridView.cpp b/src/shared_gui_components/OSGridView.cpp index 2545d3cf0..76580108c 100644 --- a/src/shared_gui_components/OSGridView.cpp +++ b/src/shared_gui_components/OSGridView.cpp @@ -23,9 +23,7 @@ #include "../openstudio_qt_utils/Application.hpp" -#include "../openstudio_lib/ModelObjectInspectorView.hpp" #include "../openstudio_lib/OSDropZone.hpp" -#include "../openstudio_lib/OSItem.hpp" #include #include diff --git a/src/shared_gui_components/OSLineEdit.cpp b/src/shared_gui_components/OSLineEdit.cpp index d8033eb86..5a647ada1 100644 --- a/src/shared_gui_components/OSLineEdit.cpp +++ b/src/shared_gui_components/OSLineEdit.cpp @@ -7,7 +7,6 @@ #include "../openstudio_lib/ModelObjectItem.hpp" #include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" #include "../openstudio_lib/OSItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" diff --git a/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp b/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp index cfc698278..3a3cc9bb5 100644 --- a/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp +++ b/src/shared_gui_components/OSLoadNamePixmapLineEdit.cpp @@ -8,7 +8,6 @@ #include "OSLineEdit.hpp" #include "IconLibrary.hpp" -#include "../openstudio_lib/OSItem.hpp" #include #include diff --git a/src/shared_gui_components/OSObjectSelector.cpp b/src/shared_gui_components/OSObjectSelector.cpp index f03588a0a..b4295ff6e 100644 --- a/src/shared_gui_components/OSObjectSelector.cpp +++ b/src/shared_gui_components/OSObjectSelector.cpp @@ -16,18 +16,6 @@ #include "OSUnsignedEdit.hpp" #include "OSWidgetHolder.hpp" -#include "../openstudio_lib/HorizontalTabWidget.hpp" -#include "../openstudio_lib/MainRightColumnController.hpp" -#include "../openstudio_lib/ModelObjectInspectorView.hpp" -#include "../openstudio_lib/ModelObjectItem.hpp" -//#include "../openstudio_lib/ModelSubTabView.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" -#include "../openstudio_lib/OSDropZone.hpp" -#include "../openstudio_lib/OSItemSelector.hpp" -#include "../openstudio_lib/RenderingColorWidget.hpp" -#include "../openstudio_lib/SchedulesView.hpp" - #include #include diff --git a/src/shared_gui_components/OSWidgetHolder.cpp b/src/shared_gui_components/OSWidgetHolder.cpp index e33d4377b..59a911e29 100644 --- a/src/shared_gui_components/OSWidgetHolder.cpp +++ b/src/shared_gui_components/OSWidgetHolder.cpp @@ -17,7 +17,6 @@ #include "OSUnsignedEdit.hpp" #include "../openstudio_lib/OSDropZone.hpp" -#include "../openstudio_lib/RenderingColorWidget.hpp" #include #include diff --git a/src/shared_gui_components/RenderingColorWidget.cpp b/src/shared_gui_components/RenderingColorWidget.cpp new file mode 100644 index 000000000..57f8ab1cd --- /dev/null +++ b/src/shared_gui_components/RenderingColorWidget.cpp @@ -0,0 +1,108 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#include "RenderingColorWidget.hpp" + +#include + +#include +#include +#include +#include +#include + +namespace openstudio { + +RenderingColorWidget::RenderingColorWidget(QWidget* parent) : QWidget(parent) { + this->setObjectName("GrayWidget"); + + auto* hLayout = new QHBoxLayout(); + hLayout->setContentsMargins(0, 0, 0, 0); + hLayout->setSpacing(10); + this->setLayout(hLayout); + + auto* renderingColorLabel = new QLabel(); + renderingColorLabel->setText("Rendering Color: "); + renderingColorLabel->setStyleSheet("QLabel { font: bold; }"); + hLayout->addWidget(renderingColorLabel); + + m_renderColorWidget = new QWidget(); + m_renderColorWidget->setFixedHeight(30); + m_renderColorWidget->setFixedWidth(30); + hLayout->addWidget(m_renderColorWidget); + + m_renderColorButton = new QPushButton(); + m_renderColorButton->setFlat(true); + m_renderColorButton->setText("Select Color"); + m_renderColorButton->setObjectName("StandardGrayButton"); + hLayout->addWidget(m_renderColorButton); + hLayout->addStretch(); + + connect(m_renderColorButton, &QPushButton::clicked, this, &RenderingColorWidget::renderColorButtonClicked); +} + +void RenderingColorWidget::attach(const openstudio::model::RenderingColor& renderingColor) { + detach(); + + m_renderingColor = renderingColor; + + m_renderingColor->getImpl()->onChange.connect(this); + + refresh(); +} + +void RenderingColorWidget::detach() { + clear(); + + if (m_renderingColor) { + m_renderingColor->getImpl()->onChange.disconnect(this); + m_renderingColor.reset(); + } +} + +void RenderingColorWidget::clear() { + QString style = "QWidget { background-color : rgba(255,255,255,255);}"; + m_renderColorWidget->setStyleSheet(style); + m_renderColorButton->setEnabled(false); +} + +void RenderingColorWidget::refresh() { + clear(); + + if (m_renderingColor) { + + int r = m_renderingColor->renderingRedValue(); + int g = m_renderingColor->renderingGreenValue(); + int b = m_renderingColor->renderingBlueValue(); + int a = m_renderingColor->renderingAlphaValue(); + QString style = "QWidget { background-color : rgba(" + QString::number(r) + "," + QString::number(g) + ", " + QString::number(b) + ", " + + QString::number(a) + ");}"; + m_renderColorWidget->setStyleSheet(style); + m_renderColorButton->setEnabled(true); + } +} + +void RenderingColorWidget::renderColorButtonClicked() { + if (m_renderingColor) { + int r = m_renderingColor->renderingRedValue(); + int g = m_renderingColor->renderingGreenValue(); + int b = m_renderingColor->renderingBlueValue(); + int a = m_renderingColor->renderingAlphaValue(); + QColor initialColor = QColor(r, g, b, a); + + QColor color = QColorDialog::getColor(initialColor, this, "Choose Rendering Color", QColorDialog::ShowAlphaChannel); + + if (color.isValid()) { + m_renderingColor->setRenderingRedValue(color.red()); + m_renderingColor->setRenderingGreenValue(color.green()); + m_renderingColor->setRenderingBlueValue(color.blue()); + m_renderingColor->setRenderingAlphaValue(color.alpha()); + + refresh(); + } + } +} + +} // namespace openstudio diff --git a/src/shared_gui_components/RenderingColorWidget.hpp b/src/shared_gui_components/RenderingColorWidget.hpp new file mode 100644 index 000000000..c8f9297f7 --- /dev/null +++ b/src/shared_gui_components/RenderingColorWidget.hpp @@ -0,0 +1,50 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef OPENSTUDIO_RENDERINGCOLORWIDGET_HPP +#define OPENSTUDIO_RENDERINGCOLORWIDGET_HPP + +#include // Signal-Slot replacement + +#include + +#include + +class QPushButton; + +namespace openstudio { + +class RenderingColorWidget + : public QWidget + , public Nano::Observer +{ + Q_OBJECT + + public: + explicit RenderingColorWidget(QWidget* parent = nullptr); + + virtual ~RenderingColorWidget() {} + + virtual void attach(const openstudio::model::RenderingColor& renderingColor); + + virtual void detach(); + + private slots: + + void clear(); + + void refresh(); + + void renderColorButtonClicked(); + + private: + QWidget* m_renderColorWidget; + QPushButton* m_renderColorButton; + boost::optional m_renderingColor; +}; + +} // namespace openstudio + +#endif // OPENSTUDIO_RENDERINGCOLORWIDGET_HPP diff --git a/src/openstudio_lib/RenderingColorWidget.cpp b/src/shared_gui_components/RenderingColorWidget2.cpp similarity index 75% rename from src/openstudio_lib/RenderingColorWidget.cpp rename to src/shared_gui_components/RenderingColorWidget2.cpp index 06ca54339..ca9ca7574 100644 --- a/src/openstudio_lib/RenderingColorWidget.cpp +++ b/src/shared_gui_components/RenderingColorWidget2.cpp @@ -3,7 +3,7 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "RenderingColorWidget.hpp" +#include "RenderingColorWidget2.hpp" #include @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -213,94 +212,4 @@ void RenderingColorWidget2::renderColorButtonClicked() { } } -RenderingColorWidget::RenderingColorWidget(QWidget* parent) : QWidget(parent) { - this->setObjectName("GrayWidget"); - - auto* hLayout = new QHBoxLayout(); - hLayout->setContentsMargins(0, 0, 0, 0); - hLayout->setSpacing(10); - this->setLayout(hLayout); - - auto* renderingColorLabel = new QLabel(); - renderingColorLabel->setText("Rendering Color: "); - renderingColorLabel->setStyleSheet("QLabel { font: bold; }"); - hLayout->addWidget(renderingColorLabel); - - m_renderColorWidget = new QWidget(); - m_renderColorWidget->setFixedHeight(30); - m_renderColorWidget->setFixedWidth(30); - hLayout->addWidget(m_renderColorWidget); - - m_renderColorButton = new QPushButton(); - m_renderColorButton->setFlat(true); - m_renderColorButton->setText("Select Color"); - m_renderColorButton->setObjectName("StandardGrayButton"); - hLayout->addWidget(m_renderColorButton); - hLayout->addStretch(); - - connect(m_renderColorButton, &QPushButton::clicked, this, &RenderingColorWidget::renderColorButtonClicked); -} - -void RenderingColorWidget::attach(const openstudio::model::RenderingColor& renderingColor) { - detach(); - - m_renderingColor = renderingColor; - - m_renderingColor->getImpl()->onChange.connect(this); - - refresh(); -} - -void RenderingColorWidget::detach() { - clear(); - - if (m_renderingColor) { - m_renderingColor->getImpl()->onChange.disconnect(this); - m_renderingColor.reset(); - } -} - -void RenderingColorWidget::clear() { - QString style = "QWidget { background-color : rgba(255,255,255,255);}"; - m_renderColorWidget->setStyleSheet(style); - m_renderColorButton->setEnabled(false); -} - -void RenderingColorWidget::refresh() { - clear(); - - if (m_renderingColor) { - - int r = m_renderingColor->renderingRedValue(); - int g = m_renderingColor->renderingGreenValue(); - int b = m_renderingColor->renderingBlueValue(); - int a = m_renderingColor->renderingAlphaValue(); - QString style = "QWidget { background-color : rgba(" + QString::number(r) + "," + QString::number(g) + ", " + QString::number(b) + ", " - + QString::number(a) + ");}"; - m_renderColorWidget->setStyleSheet(style); - m_renderColorButton->setEnabled(true); - } -} - -void RenderingColorWidget::renderColorButtonClicked() { - if (m_renderingColor) { - int r = m_renderingColor->renderingRedValue(); - int g = m_renderingColor->renderingGreenValue(); - int b = m_renderingColor->renderingBlueValue(); - int a = m_renderingColor->renderingAlphaValue(); - QColor initialColor = QColor(r, g, b, a); - - QColor color = QColorDialog::getColor(initialColor, this, "Choose Rendering Color", QColorDialog::ShowAlphaChannel); - - if (color.isValid()) { - m_renderingColor->setRenderingRedValue(color.red()); - m_renderingColor->setRenderingGreenValue(color.green()); - m_renderingColor->setRenderingBlueValue(color.blue()); - m_renderingColor->setRenderingAlphaValue(color.alpha()); - - refresh(); - } - } -} - } // namespace openstudio diff --git a/src/openstudio_lib/RenderingColorWidget.hpp b/src/shared_gui_components/RenderingColorWidget2.hpp similarity index 65% rename from src/openstudio_lib/RenderingColorWidget.hpp rename to src/shared_gui_components/RenderingColorWidget2.hpp index a844b8e00..fded7de70 100644 --- a/src/openstudio_lib/RenderingColorWidget.hpp +++ b/src/shared_gui_components/RenderingColorWidget2.hpp @@ -3,11 +3,11 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef OPENSTUDIO_RENDERINGCOLORWIDGET_HPP -#define OPENSTUDIO_RENDERINGCOLORWIDGET_HPP +#ifndef OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP +#define OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP #include // Signal-Slot replacement -#include "../shared_gui_components/FieldMethodTypedefs.hpp" +#include "FieldMethodTypedefs.hpp" #include @@ -56,35 +56,6 @@ class RenderingColorWidget2 boost::optional m_renderingColor; }; -class RenderingColorWidget - : public QWidget - , public Nano::Observer -{ - Q_OBJECT - - public: - explicit RenderingColorWidget(QWidget* parent = nullptr); - - virtual ~RenderingColorWidget() {} - - virtual void attach(const openstudio::model::RenderingColor& renderingColor); - - virtual void detach(); - - private slots: - - void clear(); - - void refresh(); - - void renderColorButtonClicked(); - - private: - QWidget* m_renderColorWidget; - QPushButton* m_renderColorButton; - boost::optional m_renderingColor; -}; - } // namespace openstudio -#endif // OPENSTUDIO_RENDERINGCOLORWIDGET_HPP +#endif // OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP From 94fe5c346892f5a83084e16224183605c3f9dca2 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 19:30:43 -0600 Subject: [PATCH 10/26] Remove unused class --- .../FacilityStoriesGridView.cpp | 1 - src/openstudio_lib/MainTabController.hpp | 2 +- src/shared_gui_components/CMakeLists.txt | 3 - .../RenderingColorWidget.cpp | 108 ------------------ .../RenderingColorWidget.hpp | 50 -------- 5 files changed, 1 insertion(+), 163 deletions(-) delete mode 100644 src/shared_gui_components/RenderingColorWidget.cpp delete mode 100644 src/shared_gui_components/RenderingColorWidget.hpp diff --git a/src/openstudio_lib/FacilityStoriesGridView.cpp b/src/openstudio_lib/FacilityStoriesGridView.cpp index 239373575..cc82a0309 100644 --- a/src/openstudio_lib/FacilityStoriesGridView.cpp +++ b/src/openstudio_lib/FacilityStoriesGridView.cpp @@ -7,7 +7,6 @@ #include "OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" -#include "../shared_gui_components/RenderingColorWidget.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" diff --git a/src/openstudio_lib/MainTabController.hpp b/src/openstudio_lib/MainTabController.hpp index e7e31cf81..b57d2d7c0 100644 --- a/src/openstudio_lib/MainTabController.hpp +++ b/src/openstudio_lib/MainTabController.hpp @@ -55,7 +55,7 @@ class MainTabController : public OSQObjectController public slots: - virtual void setSubTab(int index){}; + virtual void setSubTab(int index) {}; }; } // namespace openstudio diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index c9b1ff306..4e24db95c 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -50,8 +50,6 @@ set(${target_name}_src MeasureManager.hpp NetworkProxyDialog.cpp NetworkProxyDialog.hpp - RenderingColorWidget.cpp - RenderingColorWidget.hpp RenderingColorWidget2.cpp RenderingColorWidget2.hpp OSCellWrapper.cpp @@ -146,7 +144,6 @@ set(${target_name}_moc MeasureDragData.hpp MeasureManager.hpp NetworkProxyDialog.hpp - RenderingColorWidget.hpp RenderingColorWidget2.hpp OSCellWrapper.hpp OSCheckBox.hpp diff --git a/src/shared_gui_components/RenderingColorWidget.cpp b/src/shared_gui_components/RenderingColorWidget.cpp deleted file mode 100644 index 57f8ab1cd..000000000 --- a/src/shared_gui_components/RenderingColorWidget.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include "RenderingColorWidget.hpp" - -#include - -#include -#include -#include -#include -#include - -namespace openstudio { - -RenderingColorWidget::RenderingColorWidget(QWidget* parent) : QWidget(parent) { - this->setObjectName("GrayWidget"); - - auto* hLayout = new QHBoxLayout(); - hLayout->setContentsMargins(0, 0, 0, 0); - hLayout->setSpacing(10); - this->setLayout(hLayout); - - auto* renderingColorLabel = new QLabel(); - renderingColorLabel->setText("Rendering Color: "); - renderingColorLabel->setStyleSheet("QLabel { font: bold; }"); - hLayout->addWidget(renderingColorLabel); - - m_renderColorWidget = new QWidget(); - m_renderColorWidget->setFixedHeight(30); - m_renderColorWidget->setFixedWidth(30); - hLayout->addWidget(m_renderColorWidget); - - m_renderColorButton = new QPushButton(); - m_renderColorButton->setFlat(true); - m_renderColorButton->setText("Select Color"); - m_renderColorButton->setObjectName("StandardGrayButton"); - hLayout->addWidget(m_renderColorButton); - hLayout->addStretch(); - - connect(m_renderColorButton, &QPushButton::clicked, this, &RenderingColorWidget::renderColorButtonClicked); -} - -void RenderingColorWidget::attach(const openstudio::model::RenderingColor& renderingColor) { - detach(); - - m_renderingColor = renderingColor; - - m_renderingColor->getImpl()->onChange.connect(this); - - refresh(); -} - -void RenderingColorWidget::detach() { - clear(); - - if (m_renderingColor) { - m_renderingColor->getImpl()->onChange.disconnect(this); - m_renderingColor.reset(); - } -} - -void RenderingColorWidget::clear() { - QString style = "QWidget { background-color : rgba(255,255,255,255);}"; - m_renderColorWidget->setStyleSheet(style); - m_renderColorButton->setEnabled(false); -} - -void RenderingColorWidget::refresh() { - clear(); - - if (m_renderingColor) { - - int r = m_renderingColor->renderingRedValue(); - int g = m_renderingColor->renderingGreenValue(); - int b = m_renderingColor->renderingBlueValue(); - int a = m_renderingColor->renderingAlphaValue(); - QString style = "QWidget { background-color : rgba(" + QString::number(r) + "," + QString::number(g) + ", " + QString::number(b) + ", " - + QString::number(a) + ");}"; - m_renderColorWidget->setStyleSheet(style); - m_renderColorButton->setEnabled(true); - } -} - -void RenderingColorWidget::renderColorButtonClicked() { - if (m_renderingColor) { - int r = m_renderingColor->renderingRedValue(); - int g = m_renderingColor->renderingGreenValue(); - int b = m_renderingColor->renderingBlueValue(); - int a = m_renderingColor->renderingAlphaValue(); - QColor initialColor = QColor(r, g, b, a); - - QColor color = QColorDialog::getColor(initialColor, this, "Choose Rendering Color", QColorDialog::ShowAlphaChannel); - - if (color.isValid()) { - m_renderingColor->setRenderingRedValue(color.red()); - m_renderingColor->setRenderingGreenValue(color.green()); - m_renderingColor->setRenderingBlueValue(color.blue()); - m_renderingColor->setRenderingAlphaValue(color.alpha()); - - refresh(); - } - } -} - -} // namespace openstudio diff --git a/src/shared_gui_components/RenderingColorWidget.hpp b/src/shared_gui_components/RenderingColorWidget.hpp deleted file mode 100644 index c8f9297f7..000000000 --- a/src/shared_gui_components/RenderingColorWidget.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OPENSTUDIO_RENDERINGCOLORWIDGET_HPP -#define OPENSTUDIO_RENDERINGCOLORWIDGET_HPP - -#include // Signal-Slot replacement - -#include - -#include - -class QPushButton; - -namespace openstudio { - -class RenderingColorWidget - : public QWidget - , public Nano::Observer -{ - Q_OBJECT - - public: - explicit RenderingColorWidget(QWidget* parent = nullptr); - - virtual ~RenderingColorWidget() {} - - virtual void attach(const openstudio::model::RenderingColor& renderingColor); - - virtual void detach(); - - private slots: - - void clear(); - - void refresh(); - - void renderColorButtonClicked(); - - private: - QWidget* m_renderColorWidget; - QPushButton* m_renderColorButton; - boost::optional m_renderingColor; -}; - -} // namespace openstudio - -#endif // OPENSTUDIO_RENDERINGCOLORWIDGET_HPP From 3b2d037cf39432252698647f6ca85ec9131ab505 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 20:46:18 -0600 Subject: [PATCH 11/26] fix(linux): fix linker errors caused by shared_gui_components referencing openstudio_lib symbols Fix by extending the BaseApp interface (already in shared_gui_components) with the handful of methods that were being called through OSAppBase/OSDocument/MainWindow. OSAppBase overrides them as final, forwarding to the current document. Call sites in shared_gui_components now go through BaseApp::instance() (a dynamic_cast of qApp) instead of including openstudio_lib headers directly. --- src/openstudio_lib/OSAppBase.cpp | 48 +++++++++++++++ src/openstudio_lib/OSAppBase.hpp | 59 +++++++++++++------ .../BCLMeasureDialog.cpp | 11 ++-- src/shared_gui_components/BaseApp.hpp | 57 ++++++++++++++++-- .../BuildingComponentDialogCentralWidget.cpp | 9 +-- src/shared_gui_components/CMakeLists.txt | 1 + src/shared_gui_components/Component.cpp | 12 ++-- src/shared_gui_components/OSLineEdit.cpp | 4 +- src/shared_gui_components/UserSettings.cpp | 9 +-- 9 files changed, 159 insertions(+), 51 deletions(-) diff --git a/src/openstudio_lib/OSAppBase.cpp b/src/openstudio_lib/OSAppBase.cpp index c349382db..404675a12 100644 --- a/src/openstudio_lib/OSAppBase.cpp +++ b/src/openstudio_lib/OSAppBase.cpp @@ -261,4 +261,52 @@ openstudio::path OSAppBase::dviewPath() const { void OSAppBase::configureExternalTools() {} +bool OSAppBase::useClassicCLI() const { + auto doc = currentDocument(); + if (doc) { + return doc->mainWindow()->useClassicCLI(); + } + return false; +} + +boost::optional OSAppBase::getLocalComponent(const std::string& uid, const std::string& versionId) const { + auto doc = currentDocument(); + if (doc) { + return doc->getLocalComponent(uid, versionId); + } + return boost::none; +} + +boost::optional OSAppBase::getLocalMeasure(const std::string& uid, const std::string& versionId) const { + auto doc = currentDocument(); + if (doc) { + return doc->getLocalMeasure(uid, versionId); + } + return boost::none; +} + +std::vector OSAppBase::getLocalMeasures() const { + auto doc = currentDocument(); + if (doc) { + return doc->getLocalMeasures(); + } + return {}; +} + +std::size_t OSAppBase::removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const { + auto doc = currentDocument(); + if (doc) { + return doc->removeOutdatedLocalComponents(uid, currentVersionId); + } + return 0; +} + +std::size_t OSAppBase::removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const { + auto doc = currentDocument(); + if (doc) { + return doc->removeOutdatedLocalMeasures(uid, currentVersionId); + } + return 0; +} + } // namespace openstudio diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index bf4612652..70f1b5490 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -26,9 +26,25 @@ class OSDocument; class WaitDialog; /** - * OSAppBase is the abstract base class for the OpenStudio application, implementing the BaseApp - * interface. It is subclassed by OpenStudioApp (standalone app) and provides common application - * services: the measure manager, document management, and the current model accessor. + * OSAppBase is the abstract base class for the full OpenStudio application. It: + * + * 1. Owns the Qt event loop by inheriting QApplication — only one instance may exist + * per process, and it must outlive all widgets. + * + * 2. Implements the BaseApp interface — all virtual methods declared in BaseApp are + * overridden here as `final`, forwarding to the current OSDocument and MainWindow. + * Shared components reach this implementation via static_cast(qApp). + * + * 3. Leaves currentDocument() pure — concrete subclasses (e.g. OpenStudioApp) supply + * the document ownership strategy. + * + * Separation rationale: + * BaseApp lives in openstudio_shared_gui (lower-level static lib) and knows nothing + * about OSDocument or MainWindow. OSAppBase lives in openstudio_lib and bridges the + * two: it receives calls through the BaseApp interface and dispatches them to the + * real application objects. This one-way dependency prevents the linker errors that + * arise on Linux when a lower-level archive references symbols defined in a + * higher-level archive. */ class OSAppBase : public QApplication @@ -46,24 +62,31 @@ class OSAppBase static OSAppBase* instance(); - virtual QWidget* mainWidget() override; - virtual MeasureManager& measureManager() override; - virtual boost::optional tempDir() override; - virtual boost::optional currentModel() override; - //virtual boost::optional currentWorkspace() override; - virtual void updateSelectedMeasureState() override; - virtual void addMeasure() override; - virtual void duplicateSelectedMeasure() override; - virtual void updateMyMeasures() override; - virtual void updateBCLMeasures() override; - virtual void openBclDlg() override; - virtual void chooseHorizontalEditTab() override; - virtual void checkForRemoteBCLUpdates() override; - virtual QSharedPointer editController() override; + QWidget* mainWidget() final; + MeasureManager& measureManager() final; + boost::optional tempDir() final; + boost::optional currentModel() final; + //boost::optional currentWorkspace() final; + void updateSelectedMeasureState() final; + void addMeasure() final; + void duplicateSelectedMeasure() final; + void updateMyMeasures() final; + void updateBCLMeasures() final; + void openBclDlg() final; + void chooseHorizontalEditTab() final; + void checkForRemoteBCLUpdates() final; + QSharedPointer editController() final; boost::shared_ptr waitDialog() { return m_waitDialog; } - virtual bool mouseOverInspectorView() override; + bool mouseOverInspectorView() final; + + bool useClassicCLI() const final; + boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const final; + boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const final; + std::vector getLocalMeasures() const final; + std::size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const final; + std::size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const final; virtual openstudio::path dviewPath() const; virtual bool notify(QObject* receiver, QEvent* e) override; diff --git a/src/shared_gui_components/BCLMeasureDialog.cpp b/src/shared_gui_components/BCLMeasureDialog.cpp index 36121ea98..81c7201ba 100644 --- a/src/shared_gui_components/BCLMeasureDialog.cpp +++ b/src/shared_gui_components/BCLMeasureDialog.cpp @@ -8,10 +8,7 @@ #include "UserSettings.hpp" #include "../openstudio_qt_utils/Utilities.hpp" -// TODO: delete once the Labs CLI is the default -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" -#include "../openstudio_lib/MainWindow.hpp" +#include "BaseApp.hpp" #include #include @@ -164,7 +161,8 @@ boost::optional BCLMeasureDialog::createMeasure() { if (measureLanguageStr == "Python") { measureLanguage = MeasureLanguage::Python; - const bool useClassicCLI = OSAppBase::instance()->currentDocument()->mainWindow()->useClassicCLI(); + // TODO: remove once the Labs CLI is the default + const bool useClassicCLI = BaseApp::instance()->useClassicCLI(); if (useClassicCLI) { QMessageBox::information( this, "Python Measures not available in Classic CLI", @@ -398,7 +396,8 @@ void BCLMeasureDialog::init() { tempVLayout->addWidget(label); m_measureLanguageComboBox = new QComboBox(this); m_measureLanguageComboBox->addItem("Ruby"); - if (!OSAppBase::instance()->currentDocument()->mainWindow()->useClassicCLI()) { + // TODO: remove once the Labs CLI is the default + if (!BaseApp::instance()->useClassicCLI()) { m_measureLanguageComboBox->addItem("Python"); } m_measureLanguageComboBox->setCurrentIndex(0); diff --git a/src/shared_gui_components/BaseApp.hpp b/src/shared_gui_components/BaseApp.hpp index c8081515e..af0260e22 100644 --- a/src/shared_gui_components/BaseApp.hpp +++ b/src/shared_gui_components/BaseApp.hpp @@ -7,12 +7,19 @@ #define SHAREDGUICOMPONENTS_BASEAPP_HPP #include +#include +#include #include "../openstudio_qt_utils/QMetaTypes.hpp" #include +#include #include //#include "EditController.hpp" +#include +#include +#include + namespace openstudio { class MeasureManager; class EditController; @@ -27,16 +34,36 @@ class Model; } /** - * BaseApp is a pure abstract interface that decouples all shared GUI components from any specific - * application implementation. Widgets like MeasureManager, LocalLibraryController, and - * BuildingComponentDialog depend only on BaseApp, not on OSAppBase or OpenStudioApp. This isolation - * enables the shared components to be hosted in any Qt host without modification. + * BaseApp is the pure abstract interface through which all shared GUI components access + * application services. It lives in openstudio_shared_gui (a lower-level library) and + * deliberately has no dependency on OSAppBase, OSDocument, or any openstudio_lib symbol. + * + * Responsibilities: + * - Declare the polymorphic API that shared widgets require (measure manager, BCL + * queries, CLI mode flag, inspector focus state, etc.). + * - Be reachable process-wide via BaseApp::instance(), which down-casts qApp + * (safe because OSAppBase inherits both QApplication and BaseApp). + * - Provide safe default implementations for optional capabilities (BCL queries return + * empty/none; useClassicCLI returns false) so that lightweight hosts such as test + * fixtures do not need to implement every method. + * + * Dependency rule: + * shared_gui_components → BaseApp (this file, no openstudio_lib symbols) + * openstudio_lib → OSAppBase (implements BaseApp, owns QApplication) + * + * Never add includes from openstudio_lib to this header. */ class BaseApp { public: virtual ~BaseApp() {} + /// Returns the BaseApp singleton. Works because OSAppBase inherits both QApplication + /// and BaseApp, so qApp can be down-cast at runtime. + static BaseApp* instance() { + return dynamic_cast(qApp); + } + //virtual boost::optional project() = 0; virtual QWidget* mainWidget() = 0; virtual openstudio::MeasureManager& measureManager() = 0; @@ -56,6 +83,28 @@ class BaseApp //virtual boost::optional currentWorkspace() = 0; virtual bool mouseOverInspectorView() = 0; + + /// Whether the application is using the classic (legacy) CLI rather than the Labs CLI. + virtual bool useClassicCLI() const { + return false; + } + + /// BCL document queries — default implementations return empty/none for contexts without a document. + virtual boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const { + return boost::none; + } + virtual boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const { + return boost::none; + } + virtual std::vector getLocalMeasures() const { + return {}; + } + virtual std::size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const { + return 0; + } + virtual std::size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const { + return 0; + } }; } // namespace openstudio diff --git a/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp b/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp index a54b155a4..6ae046031 100644 --- a/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp +++ b/src/shared_gui_components/BuildingComponentDialogCentralWidget.cpp @@ -12,18 +12,13 @@ #include "ComponentList.hpp" #include "BaseApp.hpp" #include "MeasureManager.hpp" - -#include #include #include -#include #include #include #include "../openstudio_qt_utils/Application.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" #include #include @@ -263,7 +258,7 @@ void BuildingComponentDialogCentralWidget::comboBoxIndexChanged(const QString& t void BuildingComponentDialogCentralWidget::componentDownloadComplete(const std::string& uid, const boost::optional& component) { if (component) { // remove outdated components - OSAppBase::instance()->currentDocument()->removeOutdatedLocalComponents(component->uid(), component->versionId()); + BaseApp::instance()->removeOutdatedLocalComponents(component->uid(), component->versionId()); } else { // error downloading component downloadFailed(uid); @@ -277,7 +272,7 @@ void BuildingComponentDialogCentralWidget::componentDownloadComplete(const std:: void BuildingComponentDialogCentralWidget::measureDownloadComplete(const std::string& uid, const boost::optional& measure) { if (measure) { // remove outdated measures - OSAppBase::instance()->currentDocument()->removeOutdatedLocalMeasures(measure->uid(), measure->versionId()); + BaseApp::instance()->removeOutdatedLocalMeasures(measure->uid(), measure->versionId()); } else { // error downloading measure downloadFailed(uid); diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index 4e24db95c..f55155970 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${QT_INCLUDES}) set(${target_name}_src + BaseApp.hpp BCLMeasureDialog.cpp BCLMeasureDialog.hpp BuildingComponentDialog.cpp diff --git a/src/shared_gui_components/Component.cpp b/src/shared_gui_components/Component.cpp index 550366d18..b3f01362b 100644 --- a/src/shared_gui_components/Component.cpp +++ b/src/shared_gui_components/Component.cpp @@ -5,12 +5,10 @@ #include "Component.hpp" +#include "BaseApp.hpp" #include "../openstudio_qt_utils/Utilities.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" #include -#include #include #include #include @@ -98,14 +96,14 @@ Component::Component(const BCLSearchResult& bclSearchResult, bool showAbridgedVi if (bclSearchResult.componentType() == "component") { // This component has already been downloaded - if (OSAppBase::instance()->currentDocument()->getLocalComponent(this->uid(), this->versionId())) { + if (BaseApp::instance()->getLocalComponent(this->uid(), this->versionId())) { if (m_checkBox) { m_checkBox->setChecked(true); setCheckBoxEnabled(false); m_updateAvailable = false; } // This component has an update - } else if (OSAppBase::instance()->currentDocument()->getLocalComponent(this->uid())) { + } else if (BaseApp::instance()->getLocalComponent(this->uid())) { if (m_checkBox) { m_checkBox->setChecked(false); setCheckBoxUpdateAvailable(true); @@ -137,14 +135,14 @@ Component::Component(const BCLSearchResult& bclSearchResult, bool showAbridgedVi } } else { // This measure has already been downloaded - if (OSAppBase::instance()->currentDocument()->getLocalMeasure(this->uid(), this->versionId())) { + if (BaseApp::instance()->getLocalMeasure(this->uid(), this->versionId())) { if (m_checkBox) { m_checkBox->setChecked(true); setCheckBoxEnabled(false); m_updateAvailable = false; } // This measure has an update - } else if (OSAppBase::instance()->currentDocument()->getLocalMeasure(this->uid())) { + } else if (BaseApp::instance()->getLocalMeasure(this->uid())) { if (m_checkBox) { m_checkBox->setChecked(false); setCheckBoxUpdateAvailable(true); diff --git a/src/shared_gui_components/OSLineEdit.cpp b/src/shared_gui_components/OSLineEdit.cpp index 5a647ada1..3975cfdf4 100644 --- a/src/shared_gui_components/OSLineEdit.cpp +++ b/src/shared_gui_components/OSLineEdit.cpp @@ -6,7 +6,7 @@ #include "OSLineEdit.hpp" #include "../openstudio_lib/ModelObjectItem.hpp" -#include "../openstudio_lib/OSAppBase.hpp" +#include "BaseApp.hpp" #include "../openstudio_lib/OSItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" @@ -347,7 +347,7 @@ void OSLineEdit2::focusOutEvent(QFocusEvent* e) { emit inFocus(m_focused, false); - auto mouseOverInspectorView = OSAppBase::instance()->mouseOverInspectorView(); + auto mouseOverInspectorView = BaseApp::instance()->mouseOverInspectorView(); if (!mouseOverInspectorView) { emit itemClicked(nullptr); } diff --git a/src/shared_gui_components/UserSettings.cpp b/src/shared_gui_components/UserSettings.cpp index bf03798e7..11bf09f1f 100644 --- a/src/shared_gui_components/UserSettings.cpp +++ b/src/shared_gui_components/UserSettings.cpp @@ -5,12 +5,7 @@ #include "UserSettings.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" - -#include -#include -#include +#include "BaseApp.hpp" #include #include "../openstudio_qt_utils/Utilities.hpp" @@ -20,7 +15,7 @@ #include std::vector localBCLMeasures() { - return openstudio::OSAppBase::instance()->currentDocument()->getLocalMeasures(); + return openstudio::BaseApp::instance()->getLocalMeasures(); } std::vector userMeasures() { From 4048582bf5d6f05b55a92fca34b2ac0ec38e51c5 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 20:57:59 -0600 Subject: [PATCH 12/26] Remove references to Jenkins file and update docs --- .github/prompts/update-docs.prompt.md | 1 - .github/workflows/cppcheck.yml | 3 +- Jenkinsfile_linux | 14 -------- Jenkinsfile_osx | 10 ------ Jenkinsfile_windows | 10 ------ developer/doc/architecture.md | 1 - developer/doc/libraries/bimserver.md | 40 ++++++++++++++--------- developer/ruby/ApplyCopyright.rb | 4 +-- llms.txt | 3 +- src/openstudio_lib/split_os_app.sh | 4 +-- src/shared_gui_components/split_os_app.sh | 4 +-- 11 files changed, 32 insertions(+), 62 deletions(-) delete mode 100644 Jenkinsfile_linux delete mode 100644 Jenkinsfile_osx delete mode 100644 Jenkinsfile_windows diff --git a/.github/prompts/update-docs.prompt.md b/.github/prompts/update-docs.prompt.md index 99087e49f..85a19f1f4 100644 --- a/.github/prompts/update-docs.prompt.md +++ b/.github/prompts/update-docs.prompt.md @@ -14,7 +14,6 @@ applyTo: | src/**/*.hpp src/**/*.cpp .github/workflows/**/*.yml - Jenkinsfile_* ci/** CMakeLists.txt src/**/CMakeLists.txt diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml index 640c01a86..9d89f56dd 100644 --- a/.github/workflows/cppcheck.yml +++ b/.github/workflows/cppcheck.yml @@ -1,7 +1,7 @@ # Runs cppcheck static analysis on the entire src/ tree. # Builds cppcheck 2.9 from source (the Ubuntu package is too old) to ensure # consistent results. Uses --enable=all --library=qt --std=c++20 --inconclusive -# and suppresses useStlAlgorithm. The qtwinmigrate directory is excluded. +# and suppresses useStlAlgorithm. # Output is colorized by ci/colorize_cppcheck_results.py and uploaded as an artifact. name: cppcheck @@ -48,7 +48,6 @@ jobs: --library=qt \ --template='[{file}:{line}]:({severity}),[{id}],{message}' \ --force -q -j $(nproc) \ - -i ./src/qtwinmigrate \ ./src 2>&1 | tee cppcheck.txt - name: Parse and colorize cppcheck diff --git a/Jenkinsfile_linux b/Jenkinsfile_linux deleted file mode 100644 index fc9a69e94..000000000 --- a/Jenkinsfile_linux +++ /dev/null @@ -1,14 +0,0 @@ -//Jenkins pipelines are stored in shared libaries. Please see: https://github.com/NREL/cbci_jenkins_libs - -// To test you can target a branch in cbci_shared_libs. -// e.g. @Library('cbci_shared_libs@develop') _ - - -@Library('cbci_shared_libs@updateLibs') _ - -// Build for PR to develop branch only. -if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { - - openstudio_app_incr_linux() - -} diff --git a/Jenkinsfile_osx b/Jenkinsfile_osx deleted file mode 100644 index 67f9de6dc..000000000 --- a/Jenkinsfile_osx +++ /dev/null @@ -1,10 +0,0 @@ -//Jenkins pipelines are stored in shared libaries. Please see: https://github.com/NREL/cbci_jenkins_libs - -@Library('cbci_shared_libs') _ - -// Build for PR to develop branch only. -if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { - - openstudio_app_incr_osx() - -} diff --git a/Jenkinsfile_windows b/Jenkinsfile_windows deleted file mode 100644 index 2e8dd7489..000000000 --- a/Jenkinsfile_windows +++ /dev/null @@ -1,10 +0,0 @@ -//Jenkins pipelines are stored in shared libaries. Please see: https://github.com/NREL/cbci_jenkins_libs - -@Library('cbci_shared_libs') _ - -// Build for PR to develop branch only. -if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { - - openstudio_app_incr_windows() - -} diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index 07c40d030..835657fc0 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -252,7 +252,6 @@ Two parallel CI systems are used: | System | Trigger | Purpose | |---|---|---| | **GitHub Actions** | PR + push to master/develop + version tags | Full 5-platform build matrix, code signing, release publishing, static analysis, CLA enforcement | -| **Jenkins** (NREL internal) | PR builds only | Incremental build checks on NREL infrastructure via shared library `cbci_shared_libs` | See [ci/overview.md](ci/overview.md) for the full CI/CD architecture documentation, or browse individual workflow docs under [ci/workflows/](ci/workflows/). diff --git a/developer/doc/libraries/bimserver.md b/developer/doc/libraries/bimserver.md index bbaa8ec31..6a010b032 100644 --- a/developer/doc/libraries/bimserver.md +++ b/developer/doc/libraries/bimserver.md @@ -37,18 +37,22 @@ classDiagram +loginBlocked(username, password, timeout) bool +getAllProjectsBlocked(timeout) optional~QStringList~ +downloadBlocked(projectID, timeout) optional~QString~ - signals: loginSuccess, loginFailed - signals: allProjectsAvailable(QStringList) - signals: osmStringAvailable(QString) + +createProjectBlocked(name, timeout) bool + +deleteProjectBlocked(projectID, timeout) bool + +checkInIFCFileBlocked(projectID, path, timeout) bool + +getIFCRevisionListBlocked(projectID, timeout) optional~QStringList~ + signals: osmStringRetrieved(QString) + signals: listAllProjects(QStringList) + signals: listAllIFCRevisions(QStringList) + signals: operationSucceeded(QString) signals: errorOccured(QString) - signals: progressUpdated(int) + signals: bimserverError() } class ProjectImporter { <> -connection: BIMserverConnection* - +exec() int - +getModel() optional~Model~ - signals: modelImported(Model) + +run() optional~Model~ + signals: finished() } ProjectImporter "1" --> "1" BIMserverConnection : owns and drives @@ -72,17 +76,17 @@ sequenceDiagram NET->>BIM: HTTP request BIM-->>NET: JSON response (token) NET-->>CONN: QNetworkReply::finished - CONN-->>UI: emit loginSuccess / loginFailed + CONN-->>UI: emit operationSucceeded / errorOccured UI->>CONN: getAllProjects() CONN->>NET: POST /json [getAllProjects + token] BIM-->>NET: JSON project list - CONN-->>UI: emit allProjectsAvailable(QStringList) + CONN-->>UI: emit listAllProjects(QStringList) UI->>CONN: download(revisionID) CONN->>NET: POST /json [getFileFromRevision] BIM-->>NET: OSM string payload - CONN-->>UI: emit osmStringAvailable(osmString) + CONN-->>UI: emit osmStringRetrieved(osmString) ``` --- @@ -91,9 +95,13 @@ sequenceDiagram | Non-blocking (async) | Blocking | |---|---| -| `login(username, password)` → `loginSuccess`/`loginFailed` | `loginBlocked(username, password, timeout) → bool` | -| `getAllProjects()` → `allProjectsAvailable(QStringList)` | `getAllProjectsBlocked(timeout) → optional` | -| `download(revisionID)` → `osmStringAvailable(QString)` | `downloadBlocked(projectID, timeout) → optional` | +| `login(username, password)` → `operationSucceeded`/`errorOccured` | `loginBlocked(username, password, timeout) → bool` | +| `getAllProjects()` → `listAllProjects(QStringList)` | `getAllProjectsBlocked(timeout) → optional` | +| `download(revisionID)` → `osmStringRetrieved(QString)` | `downloadBlocked(projectID, timeout) → optional` | +| `createProject(name)` → `operationSucceeded`/`errorOccured` | `createProjectBlocked(name, timeout) → bool` | +| `deleteProject(projectID)` → `operationSucceeded`/`errorOccured` | `deleteProjectBlocked(projectID, timeout) → bool` | +| `checkInIFCFile(projectID, path)` → `operationSucceeded`/`errorOccured` | `checkInIFCFileBlocked(projectID, path, timeout) → bool` | +| `getIFCRevisionList(projectID)` → `listAllIFCRevisions(QStringList)` | `getIFCRevisionListBlocked(projectID, timeout) → optional` | Blocking variants spin a `QEventLoop` with a `QTimer` for the timeout, making them usable in non-GUI contexts. @@ -119,12 +127,12 @@ Blocking variants spin a `QEventLoop` with a `QTimer` for the timeout, making th ## Patterns & Conventions -- **Signal-based error handling** — errors from network operations surface via `errorOccured(QString)` rather than exceptions. -- **Progress reporting** — `progressUpdated(int)` (0–100) for long-running IFC check-in operations. +- **Signal-based error handling** — errors from network operations surface via `errorOccured(QString)` or `bimserverError()` (emitted when the server is unreachable or misconfigured) rather than exceptions. +- **Operation success reporting** — `operationSucceeded(QString)` carries a message identifying which operation completed (`"login"`, `"createProject"`, `"checkInIFC"`, etc.). - **`boost::optional` returns** — blocking APIs return `boost::none` on timeout/failure. --- -## Key Classes +## Source Reference Class-level documentation is in the corresponding header files under [`src/bimserver/`](../../../src/bimserver/). diff --git a/developer/ruby/ApplyCopyright.rb b/developer/ruby/ApplyCopyright.rb index 67ca36e57..d8be85359 100644 --- a/developer/ruby/ApplyCopyright.rb +++ b/developer/ruby/ApplyCopyright.rb @@ -33,9 +33,7 @@ # first do c++ # exclusions are files that are not part of OpenStudio -folder_exclusions = [ - ROOT_DIR / 'src/qtwinmigrate', -] +folder_exclusions = [] filename_exclusions = [ 'mainpage.hpp', ] diff --git a/llms.txt b/llms.txt index 05078caaa..a9c12d578 100644 --- a/llms.txt +++ b/llms.txt @@ -89,6 +89,7 @@ To use a class from library X in library Y, add X's CMake target to Y's `set(${t | `OSGridView.hpp/.cpp` | `openstudio::OSGridView` — renders the grid | | `OSObjectSelector.hpp/.cpp` | `openstudio::OSObjectSelector` — manages row selection in grids | | `OSLineEdit.hpp/.cpp` | `openstudio::OSLineEdit2` — line edit bound to a model object field | +| `OSItemId.hpp` | `openstudio::OSItemId` — identifies a draggable/droppable item by `itemId`, `sourceId`, and optional `position`; `Q_DECLARE_METATYPE` is in this header | | `MeasureManager.hpp/.cpp` | `openstudio::MeasureManager` — scans/runs OpenStudio Measures | | `UserSettings.hpp/.cpp` | `openstudio::UserSettings` — persistent user preferences | @@ -147,7 +148,7 @@ Example: `mouseOverInspectorView()` was added this way so `OSLineEdit.cpp` (in ` ## Qt metatype registration All SDK type metatype registrations live in `src/openstudio_qt_utils/QMetaTypes.hpp/.cpp`. -`OSItemId` registration is in `src/shared_gui_components/OSGridController.cpp` (requires the type definition from `openstudio_lib`). +`OSItemId` is defined in `src/shared_gui_components/OSItemId.hpp`, which also contains the `Q_DECLARE_METATYPE` declarations for `OSItemId` and `std::vector`. The corresponding `qRegisterMetaType` calls run at startup in `src/shared_gui_components/OSGridController.cpp`. --- diff --git a/src/openstudio_lib/split_os_app.sh b/src/openstudio_lib/split_os_app.sh index 27edd3cb2..02a8c7a74 100644 --- a/src/openstudio_lib/split_os_app.sh +++ b/src/openstudio_lib/split_os_app.sh @@ -1,5 +1,5 @@ -src/model_editor src/openstudio_app src/openstudio_lib src/qtwinmigrate src/shared_gui_components +src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components Source: https://stackoverflow.com/questions/2982055/detach-many-subdirectories-into-a-new-separate-git-repository - git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/qtwinmigrate src/shared_gui_components' --prune-empty -- --all + git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components' --prune-empty -- --all diff --git a/src/shared_gui_components/split_os_app.sh b/src/shared_gui_components/split_os_app.sh index 27edd3cb2..02a8c7a74 100644 --- a/src/shared_gui_components/split_os_app.sh +++ b/src/shared_gui_components/split_os_app.sh @@ -1,5 +1,5 @@ -src/model_editor src/openstudio_app src/openstudio_lib src/qtwinmigrate src/shared_gui_components +src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components Source: https://stackoverflow.com/questions/2982055/detach-many-subdirectories-into-a-new-separate-git-repository - git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/qtwinmigrate src/shared_gui_components' --prune-empty -- --all + git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components' --prune-empty -- --all From 969392a8192fc6ac7824411faee66812e941a99b Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 21:09:24 -0600 Subject: [PATCH 13/26] Remove InspectorDialog top level widget --- llms.txt | 1 - src/model_editor/CMakeLists.txt | 4 - src/model_editor/InspectorDialog.cpp | 908 ------------------ src/model_editor/InspectorDialog.hpp | 187 ---- .../test/InspectorDialog_GTest.cpp | 197 ---- translations/OpenStudioApp_ar.ts | 29 - translations/OpenStudioApp_ca.ts | 29 - translations/OpenStudioApp_de.ts | 29 - translations/OpenStudioApp_el.ts | 29 - translations/OpenStudioApp_es.ts | 30 - translations/OpenStudioApp_fa.ts | 29 - translations/OpenStudioApp_fr.ts | 29 - translations/OpenStudioApp_he.ts | 29 - translations/OpenStudioApp_hi.ts | 29 - translations/OpenStudioApp_it.ts | 29 - translations/OpenStudioApp_ja.ts | 29 - translations/OpenStudioApp_pl.ts | 29 - translations/OpenStudioApp_vi.ts | 29 - translations/OpenStudioApp_zh_CN.ts | 29 - 19 files changed, 1704 deletions(-) delete mode 100644 src/model_editor/InspectorDialog.cpp delete mode 100644 src/model_editor/InspectorDialog.hpp delete mode 100644 src/model_editor/test/InspectorDialog_GTest.cpp diff --git a/llms.txt b/llms.txt index a9c12d578..2cf3573c9 100644 --- a/llms.txt +++ b/llms.txt @@ -76,7 +76,6 @@ To use a class from library X in library Y, add X's CMake target to Y's `set(${t |---|---| | `AccessPolicyStore.hpp/.cpp` | `openstudio::model::AccessPolicy`, `AccessPolicyStore` — field-level access policies (FREE/LOCKED/HIDDEN) for IDD object types; used by InspectorGadget | | `InspectorGadget.hpp/.cpp` | `openstudio::InspectorGadget` — IDD-driven field editor widget | -| `InspectorDialog.hpp/.cpp` | `openstudio::InspectorDialog` — standalone dialog wrapping InspectorGadget | | `PathWatcher.hpp/.cpp` | `openstudio::PathWatcher` — filesystem path change notifications | | `GithubReleases.hpp/.cpp` | `openstudio::GithubReleases` — checks GitHub releases API for new versions | | `ModalDialogs.hpp/.cpp` | `openstudio::ModelObjectSelectorDialog` — generic model-object picker dialog | diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index 61b7c3df7..59451b018 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -15,8 +15,6 @@ set(${target_name}_src BridgeClasses.cpp GithubReleases.hpp GithubReleases.cpp - InspectorDialog.hpp - InspectorDialog.cpp InspectorGadget.hpp InspectorGadget.cpp ListWidget.hpp @@ -39,7 +37,6 @@ set(${target_name}_src # lib moc files set(${target_name}_moc - InspectorDialog.hpp InspectorGadget.hpp ListWidget.hpp ModalDialogs.hpp @@ -88,7 +85,6 @@ set(${target_name}_test_src test/ModelEditorFixture.hpp test/ModelEditorFixture.cpp test/IGLineEdit_GTest.cpp - test/InspectorDialog_GTest.cpp test/ModalDialogs_GTest.cpp test/PathWatcher_GTest.cpp test/QMetaTypes_GTest.cpp diff --git a/src/model_editor/InspectorDialog.cpp b/src/model_editor/InspectorDialog.cpp deleted file mode 100644 index 782d60384..000000000 --- a/src/model_editor/InspectorDialog.cpp +++ /dev/null @@ -1,908 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include "InspectorGadget.hpp" -#include "InspectorDialog.hpp" -#include "../openstudio_qt_utils/Application.hpp" -#include "AccessPolicyStore.hpp" -#include "../openstudio_qt_utils/Utilities.hpp" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace openstudio; -using namespace openstudio::model; - -InspectorDialog::InspectorDialog(InspectorDialogClient client, QWidget* parent) - : QMainWindow(parent), m_inspectorGadget(nullptr), m_workspaceChanged(false), m_workspaceObjectAdded(false), m_workspaceObjectRemoved(false) { - init(client); -} - -InspectorDialog::InspectorDialog(openstudio::model::Model& model, InspectorDialogClient client, QWidget* parent) - : QMainWindow(parent), - m_inspectorGadget(nullptr), - m_model(model), - m_workspaceChanged(false), - m_workspaceObjectAdded(false), - m_workspaceObjectRemoved(false) { - init(client); -} - -InspectorDialog::~InspectorDialog() = default; - -openstudio::IddObjectType InspectorDialog::iddObjectType() const { - return m_iddObjectType; -} - -bool InspectorDialog::setIddObjectType(const openstudio::IddObjectType& iddObjectType, bool force) { - if ((iddObjectType == m_iddObjectType) && !force) { - return true; - } - - if (m_typesToDisplay.find(iddObjectType) == m_typesToDisplay.end()) { - return false; - } - - m_iddObjectType = iddObjectType; - - // ensure that list widget has iddObjectType selected - m_listWidget->setUpdatesEnabled(false); - m_listWidget->blockSignals(true); - - m_listWidget->setSortingEnabled(false); - m_listWidget->clearSelection(); - - for (int i = 0; i < m_listWidget->count(); ++i) { - - QVariant data = m_listWidget->item(i)->data(Qt::UserRole); - if (!data.isValid()) { - continue; - } - - if (data.toInt() == iddObjectType.value()) { - //select this row - m_listWidget->setCurrentRow(i); - break; - } - } - - m_listWidget->blockSignals(false); - m_listWidget->setUpdatesEnabled(true); - - // update the object list in the table view - m_selectionLabel->setText(iddObjectType.valueDescription().c_str()); - loadTableWidgetData(); - - // set the selection - std::vector selectedObjectHandles; - if (!m_objectHandles.empty()) { - selectedObjectHandles.push_back(m_objectHandles[0]); - } - setSelectedObjectHandles(selectedObjectHandles, true); - - // determine if the selection widget should be hidden - bool disabledType = true; - if (m_disableSelectionTypes.find(iddObjectType) == m_disableSelectionTypes.end()) { - disabledType = false; - } - - hideSelectionWidget(disabledType); - - emit onIddObjectTypeChanged(m_iddObjectType); - - return true; -} - -std::vector InspectorDialog::selectedObjectHandles() const { - return m_selectedObjectHandles; -} - -bool InspectorDialog::setSelectedObjectHandles(const std::vector& selectedObjectHandles, bool force) { - // temporary disable multi select - if (selectedObjectHandles.size() > 1) { - return false; - } - - // see if same selection - if (m_selectedObjectHandles.size() == selectedObjectHandles.size()) { - bool allMatch = true; - for (unsigned i = 0; i < m_selectedObjectHandles.size(); ++i) { - if (m_selectedObjectHandles[i] != selectedObjectHandles[i]) { - allMatch = false; - break; - } - } - if (allMatch && !force) { - return true; - } - } - - // check if selection is ok - for (Handle handle : selectedObjectHandles) { - boost::optional object = m_model.getObject(handle); - if (!object || (object->iddObject().type() != m_iddObjectType)) { - return false; - } - } - - m_selectedObjectHandles = selectedObjectHandles; - - // update table widget - m_tableWidget->setUpdatesEnabled(false); - m_tableWidget->blockSignals(true); - - m_tableWidget->setSortingEnabled(false); - m_tableWidget->clearSelection(); - - for (int i = 0; i < m_tableWidget->rowCount(); ++i) { - - QString handleString = m_tableWidget->item(i, 0)->data(Qt::UserRole).toString(); - //std::string temp = toString(handleString); - Handle handle(toUUID(handleString)); - - auto it = std::find(m_selectedObjectHandles.begin(), m_selectedObjectHandles.end(), handle); - if (it != m_selectedObjectHandles.end()) { - //select this row - m_tableWidget->selectRow(i); - } - } - - m_tableWidget->setSortingEnabled(true); - - m_tableWidget->blockSignals(false); - m_tableWidget->setUpdatesEnabled(true); - - // update inspector gadget - if (m_selectedObjectHandles.empty()) { - m_inspectorGadget->clear(true); - } else if (m_selectedObjectHandles.size() == 1) { - boost::optional workspaceObject = m_model.getObject(m_selectedObjectHandles[0]); - OS_ASSERT(workspaceObject); - m_inspectorGadget->layoutModelObj(*workspaceObject, false, false, false, true); - m_inspectorGadget->createAllFields(); - } else { - // temporary do not allow multi select - OS_ASSERT(false); - } - - bool enableAdd = (m_disableAddTypes.find(m_iddObjectType) == m_disableAddTypes.end()); - bool enableCopy = (m_disableCopyTypes.find(m_iddObjectType) == m_disableCopyTypes.end()); - bool enableRemove = (m_disableRemoveTypes.find(m_iddObjectType) == m_disableRemoveTypes.end()); - bool enablePurge = (m_disablePurgeTypes.find(m_iddObjectType) == m_disablePurgeTypes.end()); - - boost::optional iddObject = IddFactory::instance().getObject(m_iddObjectType); - OS_ASSERT(iddObject); - - if (iddObject->properties().unique) { - enableCopy = false; - enablePurge = false; - if (m_objectHandles.empty()) { - enableRemove = false; - } else { - enableAdd = false; - if (iddObject->properties().required) { - enableRemove = false; - } - } - } else { - if (m_selectedObjectHandles.empty()) { - enableCopy = false; - enableRemove = false; - } else if (m_selectedObjectHandles.size() == 1) { - // no-op - } else { - enableCopy = false; - } - } - - std::vector objects = m_model.getObjectsByType(m_iddObjectType); - if (objects.empty()) { - enablePurge = false; - } else if (!objects[0].optionalCast()) { - enablePurge = false; - } - - // update push buttons - m_pushButtonNew->setEnabled(enableAdd); - m_pushButtonCopy->setEnabled(enableCopy); - m_pushButtonDelete->setEnabled(enableRemove); - m_pushButtonPurge->setEnabled(enablePurge); - - emit selectedObjectHandlesChanged(m_selectedObjectHandles); - - return true; -} - -openstudio::model::Model InspectorDialog::model() const { - return m_model; -} - -void InspectorDialog::setModel(const openstudio::model::Model& model, bool force) { - if ((model == m_model) && !force) { - return; - } - - // change model - m_model = model; - - // connect signals to the new model - this->connectModelSignalsAndSlots(); - - setIddObjectType(m_iddObjectType, true); - - updateListWidgetData(); - - emit modelChanged(m_model); - - /// \todo For some reason, after InspectorDialog::setModel is called the keyboard focus - /// gets "lost" on MacOS After several hours of trial and error, I found that setting the focus - /// programmatically in this out-of-band call consistently resolves the problem. - /// The "todo" is to reevaluate with a later version of Qt. - QTimer::singleShot(0, this, &InspectorDialog::onNeedsSetFocus); -} - -void InspectorDialog::rebuildInspectorGadget(bool recursive) { - m_inspectorGadget->rebuild(recursive); -} - -void InspectorDialog::saveState() { - QString organizationName = QCoreApplication::organizationName(); - QString applicationName("InspectorDialog"); - QSettings settings(organizationName, applicationName); - settings.setValue("Geometry", QMainWindow::saveGeometry()); - settings.setValue("State", QMainWindow::saveState()); -} - -void InspectorDialog::restoreState() { - QString organizationName("OpenStudio"); - QString applicationName("InspectorDialog"); - QSettings settings(organizationName, applicationName); - QMainWindow::restoreGeometry(settings.value("Geometry").toByteArray()); - QMainWindow::restoreState(settings.value("State").toByteArray()); -} - -void InspectorDialog::onIddObjectTypeChanged(const openstudio::IddObjectType& iddObjectType) {} - -void InspectorDialog::onSelectedObjectHandlesChanged(const std::vector& selectedObjectHandles) {} - -void InspectorDialog::onModelChanged(Model& /*unused*/) {} - -void InspectorDialog::showEvent(QShowEvent* event) { - //restoreState(); - QWidget::showEvent(event); -} - -void InspectorDialog::closeEvent(QCloseEvent* event) { - saveState(); - QWidget::closeEvent(event); -} - -void InspectorDialog::onPushButtonNew(bool /*unused*/) { - boost::optional object = m_model.addObject(IdfObject(m_iddObjectType)); - - if (object) { - m_selectedObjectHandles.clear(); - m_selectedObjectHandles.push_back(object->handle()); - //setSelectedObjectHandles(m_selectedObjectHandles, true); - } -} - -void InspectorDialog::onPushButtonCopy(bool /*unused*/) { - if (m_selectedObjectHandles.size() == 1) { - boost::optional workspaceObject = m_model.getObject(m_selectedObjectHandles[0]); - if (workspaceObject) { - ModelObject object = workspaceObject->cast().clone(m_model); - m_selectedObjectHandles.clear(); - m_selectedObjectHandles.push_back(object.handle()); - //setSelectedObjectHandles(m_selectedObjectHandles, true); - } - } -} - -void InspectorDialog::onPushButtonDelete(bool /*unused*/) { - std::vector handles = m_selectedObjectHandles; - for (Handle handle : handles) { - boost::optional object = m_model.getObject(handle); - if (object) { - // calls model object remove - object->remove(); - } - } -} - -void InspectorDialog::onPushButtonPurge(bool /*unused*/) { - m_model.purgeUnusedResourceObjects(m_iddObjectType); -} - -/* -void InspectorDialog::onCheckBox(bool checked) -{ - std::vector selectedObjects; - std::vector selectedHandles; - getTableWidgetSelected(selectedObjects,selectedHandles); - if(!selectedObjects.size()) return; - emit tableWidgetSelectionChanged(selectedHandles); - m_inspectorGadget->layoutModelObj(selectedObjects[0]); - // TODO use this call when IG multi-select completed - //m_inspectorGadget->layoutModelObjs(selectedObjects); -} -*/ - -void InspectorDialog::onListWidgetSelectionChanged() { - QList selectedItems = m_listWidget->selectedItems(); - - // One row must be selected - if (selectedItems.count() == 1) { - - //m_tableWidget->setSortingEnabled(false); - - QVariant data = selectedItems.at(0)->data(Qt::UserRole); - if (data.isValid()) { - IddObjectType iddObjectType(data.toInt()); - setIddObjectType(iddObjectType); - } - - // do not enable sorting - //m_tableWidget->setSortingEnabled(true); - } -} - -void InspectorDialog::onTableWidgetSelectionChanged() { - std::vector selectedObjectHandles; - getTableWidgetSelected(selectedObjectHandles); - setSelectedObjectHandles(selectedObjectHandles, true); -} - -void InspectorDialog::onAddWorkspaceObject(std::shared_ptr /* impl */, - const openstudio::IddObjectType& type, const openstudio::UUID& uuid) { - m_workspaceObjectAdded = true; - m_workspaceChanged = true; - - if (type == m_iddObjectType) { - - m_objectHandles.push_back(uuid); - - if (m_selectedObjectHandles.empty()) { - m_selectedObjectHandles.push_back(uuid); - } else { - // do we want to do this or preserve the current selection? - // this functionality is now in onPushButtonNew - //m_selectedObjectHandles.clear(); - //m_selectedObjectHandles.push_back(impl->handle()); - //setSelectedObjectHandles(m_selectedObjectHandles, true); - } - } - - QTimer::singleShot(0, this, &InspectorDialog::onTimeout); -} - -void InspectorDialog::onWorkspaceChange() { - m_workspaceChanged = true; - - QTimer::singleShot(0, this, &InspectorDialog::onTimeout); -} - -void InspectorDialog::onTimeout() { - if (m_workspaceObjectAdded) { - updateListWidgetData(); - m_workspaceObjectAdded = false; - } - - if (m_workspaceObjectRemoved) { - updateListWidgetData(); - m_workspaceObjectRemoved = false; - } - - if (m_workspaceChanged) { - loadTableWidgetData(); - setSelectedObjectHandles(m_selectedObjectHandles, true); - m_workspaceChanged = false; - } -} - -void InspectorDialog::onRemoveWorkspaceObject(std::shared_ptr /*impl*/, - const openstudio::IddObjectType& type, const openstudio::UUID& uuid) { - m_workspaceObjectRemoved = true; - m_workspaceChanged = true; - - // if removed object is of current type - if (type == m_iddObjectType) { - - auto it = std::remove(m_objectHandles.begin(), m_objectHandles.end(), uuid); - if (it != m_objectHandles.end()) { - m_objectHandles.erase(it, m_objectHandles.end()); - } - - it = std::remove(m_selectedObjectHandles.begin(), m_selectedObjectHandles.end(), uuid); - if (it != m_selectedObjectHandles.end()) { - m_selectedObjectHandles.erase(it, m_selectedObjectHandles.end()); - } - - if (m_selectedObjectHandles.empty()) { - if (!m_objectHandles.empty()) { - m_selectedObjectHandles.push_back(m_objectHandles[0]); - } - } - } - - QTimer::singleShot(0, this, &InspectorDialog::onTimeout); -} - -void InspectorDialog::onNeedsSetFocus() { - this->setFocus(); -} - -void InspectorDialog::init(InspectorDialogClient client) { - - switch (client.value()) { - case InspectorDialogClient::AllOpenStudio: - - m_iddFile = IddFactory::instance().getIddFile(IddFileType::OpenStudio); - - // everything is allowable - for (const IddObject& iddObject : m_iddFile.objects()) { - m_typesToDisplay.insert(iddObject.type()); - } - - m_iddObjectType = IddObjectType::OS_Building; - - break; - - default: - break; - } - - OS_ASSERT(!m_typesToDisplay.empty()); - - Qt::WindowFlags flags = Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint; // | Qt::WindowStaysOnTopHint; - this->setWindowFlags(flags); - - setWindowIcon(QIcon(":/images/me_16.png")); - setWindowIconText(tr("OpenStudio Inspector")); - setWindowTitle(tr("OpenStudio Inspector")); - createWidgets(); - loadStyleSheet(); - connectSelfSignalsAndSlots(); - loadListWidgetData(); - setModel(m_model, true); -} - -void InspectorDialog::createWidgets() { - /// The list widget - - QFont labelFont; - labelFont.setPixelSize(12); - //labelFont.setBold(true); - - QFont subLabelFont; - subLabelFont.setPixelSize(12); - subLabelFont.setBold(true); - - auto* listLabel = new QLabel(this); - listLabel->setObjectName("listLabel"); - listLabel->setText("Select Type"); - listLabel->setFont(labelFont); - listLabel->setMinimumHeight(40); - listLabel->setMaximumHeight(40); - - m_listWidget = new QListWidget(this); - m_listWidget->setObjectName("listWidget"); - //m_listWidget->setAlternatingRowColors(true); - m_listWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_listWidget->setSelectionMode(QAbstractItemView::SingleSelection); - m_listWidget->setAcceptDrops(false); - m_listWidget->setDragEnabled(false); - - auto* listHolderLayout = new QVBoxLayout; - listHolderLayout->addWidget(listLabel); - listHolderLayout->addWidget(m_listWidget); - - auto* listHolderWidget = new QWidget(this); - listHolderWidget->setLayout(listHolderLayout); - - /// The table widget - auto* tableLabel = new QLabel(this); - tableLabel->setObjectName("tableLabel"); - tableLabel->setText("Select Object"); - tableLabel->setFont(labelFont); - tableLabel->setMinimumHeight(40); - tableLabel->setMaximumHeight(40); - - m_selectionLabel = new QLabel(this); - //m_selectionLabel->setObjectName("selectionLabel"); - m_selectionLabel->setText(""); - m_selectionLabel->setFont(subLabelFont); - //m_selectionLabel->setMinimumHeight(40); - //m_selectionLabel->setMaximumHeight(40); - - QStringList headerLabels; - headerLabels.append("Name"); - headerLabels.append("Comment"); - - m_tableWidget = new QTableWidget(this); - m_tableWidget->setObjectName("tableWidget"); - m_tableWidget->setRowCount(0); - m_tableWidget->setColumnCount(2); - m_tableWidget->sortByColumn(0, Qt::AscendingOrder); - m_tableWidget->setSortingEnabled(false); - m_tableWidget->setAlternatingRowColors(true); - m_tableWidget->setShowGrid(false); - m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); - m_tableWidget->verticalHeader()->hide(); - m_tableWidget->setHorizontalHeaderLabels(headerLabels); - m_tableWidget->horizontalHeader()->setStretchLastSection(true); - m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - m_tableWidget->setAcceptDrops(false); - m_tableWidget->setDragEnabled(false); - - m_pushButtonNew = new QPushButton(this); - m_pushButtonNew->setObjectName("pushButtonNew"); - m_pushButtonNew->setToolTip(tr("Add new object")); - - m_pushButtonCopy = new QPushButton(this); - m_pushButtonCopy->setObjectName("pushButtonCopy"); - m_pushButtonCopy->setToolTip(tr("Copy selected object")); - - m_pushButtonDelete = new QPushButton(this); - m_pushButtonDelete->setObjectName("pushButtonDelete"); - m_pushButtonDelete->setToolTip(tr("Remove selected objects")); - - m_pushButtonPurge = new QPushButton(this); - m_pushButtonPurge->setObjectName("pushButtonPurge"); - m_pushButtonPurge->setToolTip(tr("Purge unused objects")); - - auto* buttonLayout = new QHBoxLayout; - buttonLayout->addSpacing(5); - buttonLayout->addWidget(m_pushButtonNew); - buttonLayout->addSpacing(5); - buttonLayout->addWidget(m_pushButtonCopy); - buttonLayout->addSpacing(5); - buttonLayout->addWidget(m_pushButtonDelete); - buttonLayout->addSpacing(5); - buttonLayout->addWidget(m_pushButtonPurge); - buttonLayout->addStretch(0); - - auto* buttonGroup = new QWidget(this); - buttonGroup->setLayout(buttonLayout); - - auto* tableVBoxLayout = new QVBoxLayout; - tableVBoxLayout->addWidget(m_tableWidget); - tableVBoxLayout->addWidget(buttonGroup); - - auto* tableWidgetHolder = new QWidget(this); - tableWidgetHolder->setLayout(tableVBoxLayout); - - auto* noSelectionImage = new QLabel(this); - noSelectionImage->setPixmap(QPixmap(":/images/alert_image.png")); - - auto* noSelectionLabel = new QLabel("Pick your selection.", this); - noSelectionLabel->setFont(labelFont); - noSelectionLabel->setMinimumHeight(40); - noSelectionLabel->setAlignment(Qt::AlignCenter); - noSelectionLabel->setWordWrap(true); - - auto* noSelectionLayout = new QVBoxLayout; - noSelectionLayout->addStretch(); - noSelectionLayout->addWidget(noSelectionImage, 0, Qt::AlignCenter); - noSelectionLayout->addWidget(noSelectionLabel, 0, Qt::AlignCenter); - noSelectionLayout->addStretch(); - - auto* noSelectionWidget = new QWidget(this); - noSelectionWidget->setLayout(noSelectionLayout); - - m_stackedWidget = new QStackedWidget(this); - m_stackedWidget->addWidget(tableWidgetHolder); - m_stackedWidget->addWidget(noSelectionWidget); - - auto* tableHolderLayout = new QVBoxLayout; - tableHolderLayout->addWidget(tableLabel); - tableHolderLayout->addWidget(m_selectionLabel); - tableHolderLayout->addWidget(m_stackedWidget); - - auto* tableHolderWidget = new QWidget(this); - tableHolderWidget->setLayout(tableHolderLayout); - - // The inspectorGadget widget - - auto* inspectorGadgetLabel = new QLabel(this); - inspectorGadgetLabel->setObjectName("igLabel"); - inspectorGadgetLabel->setText("Edit Object"); - inspectorGadgetLabel->setFont(labelFont); - inspectorGadgetLabel->setMinimumHeight(40); - inspectorGadgetLabel->setMaximumHeight(40); - - m_inspectorGadget = new InspectorGadget(this); - connect(this, &InspectorDialog::toggleUnitsClicked, m_inspectorGadget, &InspectorGadget::toggleUnitsClicked); - - auto* inspectorGadgetHolderLayout = new QVBoxLayout; - inspectorGadgetHolderLayout->addWidget(inspectorGadgetLabel); - inspectorGadgetHolderLayout->addWidget(m_inspectorGadget); - - auto* inspectorGadgetHolderWidget = new QWidget(this); - inspectorGadgetHolderWidget->setLayout(inspectorGadgetHolderLayout); - - // The left widget - - auto* leftSplitter = new QSplitter(this); - leftSplitter->setOrientation(Qt::Vertical); - leftSplitter->addWidget(listHolderWidget); - leftSplitter->addWidget(tableHolderWidget); - - // The right widget - /* - QSplitter* rightSplitter = new QSplitter(this); - rightSplitter->setOrientation(Qt::Vertical); - rightSplitter->addWidget(tableHolderWidget); - rightSplitter->addWidget(inspectorGadgetHolderWidget); -*/ - // The central widget - - auto* centralSplitter = new QSplitter(this); - centralSplitter->setOrientation(Qt::Horizontal); - centralSplitter->addWidget(leftSplitter); - centralSplitter->addWidget(inspectorGadgetHolderWidget); - - this->setCentralWidget(centralSplitter); - - hideSelectionWidget(true); -} - -void InspectorDialog::connectSelfSignalsAndSlots() { - connect(m_pushButtonNew, &QPushButton::clicked, this, &InspectorDialog::onPushButtonNew); - - connect(m_pushButtonCopy, &QPushButton::clicked, this, &InspectorDialog::onPushButtonCopy); - - connect(m_pushButtonDelete, &QPushButton::clicked, this, &InspectorDialog::onPushButtonDelete); - - connect(m_pushButtonPurge, &QPushButton::clicked, this, &InspectorDialog::onPushButtonPurge); - - connect(m_listWidget, &QListWidget::itemSelectionChanged, this, &InspectorDialog::onListWidgetSelectionChanged); - - connect(m_tableWidget, &QTableWidget::itemSelectionChanged, this, &InspectorDialog::onTableWidgetSelectionChanged); - - connect(this, &InspectorDialog::iddObjectTypeChanged, this, &InspectorDialog::onIddObjectTypeChanged); - - connect(this, &InspectorDialog::selectedObjectHandlesChanged, this, &InspectorDialog::onSelectedObjectHandlesChanged); - - connect(this, &InspectorDialog::modelChanged, this, &InspectorDialog::onModelChanged); -} - -void InspectorDialog::connectModelSignalsAndSlots() { - m_model.getImpl()->addWorkspaceObjectPtr.connect(this); - - m_model.getImpl()->onChange.connect(this); - - m_model.getImpl()->removeWorkspaceObjectPtr.connect(this); -} - -void InspectorDialog::hideSelectionWidget(bool hideSelectionWidget) { - /// \todo If the code in InspectorDialog::setModel does not properly reset the focus as desired, - /// this is the backup plan. After the user clicks on a new section, this hack makes sure - /// the keyboard focus is correct. Todo: reevaluate with a new version of Qt in the future. - /// \sa InspectorDialog::setModel - setFocus(); - - if (hideSelectionWidget) { - m_stackedWidget->setCurrentIndex(1); - } else { - m_stackedWidget->setCurrentIndex(0); - } -} - -void InspectorDialog::loadStyleSheet() { - QFile data(":/InspectorDialog.qss"); - if (data.open(QFile::ReadOnly)) { - QTextStream styleIn(&data); - QString style = styleIn.readAll(); - data.close(); - setStyleSheet(style); - } else { - LOG_FREE(LogLevel::Error, "InspectorDialog", "Failed to open InspectorDialog.qss"); - } -} - -void InspectorDialog::loadListWidgetData() { - QFont groupFont; - groupFont.setPixelSize(12); - groupFont.setBold(true); - - //backgroundGradient.setColorAt(0.66, QColor(208,212,215)); - //backgroundGradient.setColorAt(1, QColor(107,116,123)); - QBrush groupBackground(QColor(208, 212, 215)); - - QBrush groupForeground(QColor(0, 0, 0)); - - QBrush itemBackground(QColor(255, 255, 255)); - - QBrush itemAlternateBackground(QColor(238, 238, 238)); - - QListWidgetItem* listItem; - for (const std::string& group : m_iddFile.groups()) { - - // quick check if group is empty - bool empty = true; - for (const IddObject& iddObject : m_iddFile.getObjectsInGroup(group)) { - if (m_typesToDisplay.find(iddObject.type()) != m_typesToDisplay.end()) { - empty = false; - break; - } - } - - if (empty) { - continue; - } - - // add the group item - listItem = new QListWidgetItem(); - listItem->setText(group.c_str()); - listItem->setFlags(Qt::NoItemFlags); - listItem->setFont(groupFont); - listItem->setBackground(groupBackground); - listItem->setForeground(groupForeground); - m_listWidget->addItem(listItem); - - // add each object - bool alternate = false; - for (const IddObject& iddObject : m_iddFile.getObjectsInGroup(group)) { - - IddObjectType type = iddObject.type(); - if (m_typesToDisplay.find(type) == m_typesToDisplay.end()) { - continue; - } - - unsigned numObjects = m_model.numObjectsOfType(type); - QString text(type.valueDescription().c_str()); - text += QString(" (") + QString::number(numObjects) + QString(")"); - - listItem = new QListWidgetItem(); - listItem->setText(text); - listItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - listItem->setData(Qt::UserRole, type.value()); - - if (alternate) { - listItem->setBackground(itemAlternateBackground); - - } else { - listItem->setBackground(itemBackground); - } - - m_listWidget->addItem(listItem); - - alternate = !alternate; - } - } -} - -void InspectorDialog::updateListWidgetData() { - for (int i = 0; i < m_listWidget->count(); ++i) { - - QVariant data = m_listWidget->item(i)->data(Qt::UserRole); - if (!data.isValid()) { - continue; - } - - IddObjectType type(data.toInt()); - unsigned numObjects = m_model.numObjectsOfType(type); - - QString text(type.valueDescription().c_str()); - text += QString(" (") + QString::number(numObjects) + QString(")"); - m_listWidget->item(i)->setText(text); - } -} - -void InspectorDialog::loadTableWidgetData() { - m_tableWidget->setUpdatesEnabled(false); - m_tableWidget->blockSignals(true); - - m_tableWidget->clear(); - m_tableWidget->setRowCount(0); - m_tableWidget->setSortingEnabled(false); - - // clear removes header labels - QStringList headerLabels; - headerLabels.append("Name"); - headerLabels.append("Comment"); - m_tableWidget->setHorizontalHeaderLabels(headerLabels); - - // all object handles - m_objectHandles.clear(); - - int i = 0; - int j = 0; - //bool connected; - //QCheckBox * checkBox; - - std::vector objects = m_model.getObjectsByType(m_iddObjectType); - m_objectHandles.reserve(objects.size()); - for (const WorkspaceObject& object : objects) { - - m_objectHandles.push_back(object.handle()); - - m_tableWidget->insertRow(m_tableWidget->rowCount()); - - QString displayName("(No Name)"); - if (object.name()) { - displayName = object.name().get().c_str(); - } - unsigned numSources = object.numSources(); - displayName += QString(" (") + QString::number(numSources) + QString(")"); - - auto* tableItem = new QTableWidgetItem(displayName); - tableItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - QString handleString(toQString(object.handle())); - //std::string temp = toString(handleString); - tableItem->setData(Qt::UserRole, handleString); - m_tableWidget->setItem(i, j++, tableItem); - - QString description = object.comment().c_str(); - tableItem = new QTableWidgetItem(description); - tableItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - m_tableWidget->setItem(i, j++, tableItem); - - i++; - j = 0; - } - m_tableWidget->setSortingEnabled(true); - m_tableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); - m_tableWidget->horizontalHeader()->setStretchLastSection(true); - m_tableWidget->blockSignals(false); - m_tableWidget->setUpdatesEnabled(true); -} - -void InspectorDialog::getTableWidgetSelected(std::vector& selectedHandles) { - m_tableWidget->setSortingEnabled(false); - - selectedHandles.clear(); - - QList selectedItems = m_tableWidget->selectedItems(); - - for (auto* selectedItem : selectedItems) { - int column = m_tableWidget->column(selectedItem); - if (column == 0) { - QString handleString = selectedItem->data(Qt::UserRole).toString(); - //std::string temp = toString(handleString); - selectedHandles.push_back(Handle(toUUID(handleString))); - } - } - - m_tableWidget->setSortingEnabled(true); -} - -void InspectorDialog::displayIP(const bool displayIP) { - if (m_inspectorGadget) { - m_inspectorGadget->toggleUnits(displayIP); - } -} diff --git a/src/model_editor/InspectorDialog.hpp b/src/model_editor/InspectorDialog.hpp deleted file mode 100644 index f0087bbaf..000000000 --- a/src/model_editor/InspectorDialog.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef MODELEDITOR_INSPECTORDIALOG_HPP -#define MODELEDITOR_INSPECTORDIALOG_HPP - -#include - -#include -#include -#include -#include - -#include // Signal-Slot replacement - -#include -#include - -class QLabel; -class QListWidget; -class QStackedWidget; -class QTableWidget; -class QPushButton; -class QShowEvent; -class QCloseEvent; -class InspectorGadget; - -namespace openstudio { -class WorkspaceObject; - -namespace model { -class ModelObject; -} -} // namespace openstudio - -#ifndef Q_MOC_RUN -OPENSTUDIO_ENUM(InspectorDialogClient, ((AllOpenStudio))); -#endif - -/** - * InspectorDialog is a standalone QMainWindow that hosts an InspectorGadget for viewing and editing - * any ModelObject from the OpenStudio model. It is used in the Model Editor tool as the primary - * object inspector window. - */ -class InspectorDialog - : public QMainWindow - , public Nano::Observer -{ - Q_OBJECT; - - public: - /// create a new dialog with empty model - explicit InspectorDialog(InspectorDialogClient client = InspectorDialogClient::AllOpenStudio, QWidget* parent = nullptr); - - /// create a new dialog for existing model - explicit InspectorDialog(openstudio::model::Model& model, InspectorDialogClient client = InspectorDialogClient::AllOpenStudio, - QWidget* parent = nullptr); - - virtual ~InspectorDialog(); - - // get the idd object type - openstudio::IddObjectType iddObjectType() const; - - // set the idd object type, must be an allowable type - bool setIddObjectType(const openstudio::IddObjectType&, bool force = false); - - // get handles of the selected objects - std::vector selectedObjectHandles() const; - - // set the selected object handles, all handles must be found in current model and be of the - // same allowable idd object type - bool setSelectedObjectHandles(const std::vector&, bool force = false); - - // get the current model - openstudio::model::Model model() const; - - // point the dialog at a new model - void setModel(const openstudio::model::Model& model, bool force = false); - - // void rebuild inspector gadget - void rebuildInspectorGadget(bool recursive); - - // save the state - void saveState(); - - // restore the state - void restoreState(); - - void displayIP(const bool displayIP); - - public slots: - - virtual void onIddObjectTypeChanged(const openstudio::IddObjectType&); - - virtual void onSelectedObjectHandlesChanged(const std::vector&); - - virtual void onModelChanged(openstudio::model::Model&); - - virtual void onPushButtonNew(bool); - - virtual void onPushButtonCopy(bool); - - virtual void onPushButtonDelete(bool); - - virtual void onPushButtonPurge(bool); - - signals: - - // emitted when user selects a new idd object type, will be an allowable type - void iddObjectTypeChanged(const openstudio::IddObjectType&); - - // emitted when selected objects change, all handles will be in model and of the same allowable type - void selectedObjectHandlesChanged(const std::vector&); - - // emitted when inspected model changes - void modelChanged(openstudio::model::Model&); - - void toggleUnitsClicked(bool); - - protected: - // handle show event - virtual void showEvent(QShowEvent* event) override; - - // handle close event - virtual void closeEvent(QCloseEvent* event) override; - - private slots: - - // for testing - friend class ModelEditorFixture; - - //void onCheckBox(bool checked); - void onListWidgetSelectionChanged(); - void onTableWidgetSelectionChanged(); - void onAddWorkspaceObject(std::shared_ptr impl, const openstudio::IddObjectType& type, - const openstudio::UUID& uuid); - void onWorkspaceChange(); - void onTimeout(); - void onRemoveWorkspaceObject(std::shared_ptr impl, const openstudio::IddObjectType& type, - const openstudio::UUID& uuid); - - void onNeedsSetFocus(); - - private: - QListWidget* m_listWidget; - QStackedWidget* m_stackedWidget; - QLabel* m_selectionLabel; - QTableWidget* m_tableWidget; - QPushButton* m_pushButtonNew; - QPushButton* m_pushButtonCopy; - QPushButton* m_pushButtonDelete; - QPushButton* m_pushButtonPurge; - InspectorGadget* m_inspectorGadget; - - openstudio::IddFile m_iddFile; - std::set m_typesToDisplay; - std::set m_disableSelectionTypes; - std::set m_disableAddTypes; - std::set m_disableCopyTypes; - std::set m_disableRemoveTypes; - std::set m_disablePurgeTypes; - - openstudio::IddObjectType m_iddObjectType; - std::vector m_objectHandles; - std::vector m_selectedObjectHandles; - openstudio::model::Model m_model; - bool m_workspaceChanged; - bool m_workspaceObjectAdded; - bool m_workspaceObjectRemoved; - - void init(InspectorDialogClient client); - void createWidgets(); - void connectSelfSignalsAndSlots(); - void connectModelSignalsAndSlots(); - void hideSelectionWidget(bool hideSelectionWidget); - void loadStyleSheet(); - void loadListWidgetData(); - void updateListWidgetData(); - void loadTableWidgetData(); - void setTableWidgetHeader(); - void getTableWidgetSelected(std::vector& selectedHandles); - void loadModel(); -}; - -#endif // MODELEDITOR_INSPECTORDIALOG_HPP diff --git a/src/model_editor/test/InspectorDialog_GTest.cpp b/src/model_editor/test/InspectorDialog_GTest.cpp deleted file mode 100644 index 7b50b0786..000000000 --- a/src/model_editor/test/InspectorDialog_GTest.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include - -#include "ModelEditorFixture.hpp" - -#include "../InspectorDialog.hpp" -#include "../TestButton.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -using namespace openstudio::model; -using namespace openstudio; - -TEST_F(ModelEditorFixture, InspectorDialog_EmptyModel) { - std::shared_ptr inspectorDialog(new InspectorDialog()); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(Space::iddObjectType())); - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - - std::shared_ptr button(new TestButton); - - QObject::connect(button.get(), &TestButton::clicked, inspectorDialog.get(), &InspectorDialog::onPushButtonNew); - - Model model = inspectorDialog->model(); - EXPECT_EQ(0u, model.numObjects()); - - button->doClick(); - - ASSERT_EQ(1u, model.objects(true).size()); - EXPECT_TRUE(model.objects(true)[0].optionalCast()); -} - -TEST_F(ModelEditorFixture, InspectorDialog_Remove1Object) { - Model model; - Space space1(model); - Space space2(model); - EXPECT_EQ(2u, model.numObjects()); - - std::shared_ptr inspectorDialog(new InspectorDialog(model)); - - std::shared_ptr button(new TestButton); - - QObject::connect(button.get(), &TestButton::clicked, inspectorDialog.get(), &InspectorDialog::onPushButtonDelete); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(Space::iddObjectType())); - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - - std::vector handles; - handles.push_back(space1.handle()); - EXPECT_TRUE(inspectorDialog->setSelectedObjectHandles(handles)); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(space1.handle(), inspectorDialog->selectedObjectHandles()[0]); - - button->doClick(); - - ASSERT_EQ(1u, model.numObjects()); - EXPECT_EQ(space2.handle(), model.objects(true)[0].handle()); - - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(space2.handle(), inspectorDialog->selectedObjectHandles()[0]); -} - -TEST_F(ModelEditorFixture, InspectorDialog_Copy1Object) { - Model model; - Space space1(model); - Space space2(model); - ASSERT_EQ(2u, model.numObjects()); - EXPECT_EQ(space1.handle(), model.objects(true)[0].handle()); - EXPECT_EQ(space2.handle(), model.objects(true)[1].handle()); - - std::shared_ptr inspectorDialog(new InspectorDialog(model)); - - std::shared_ptr button(new TestButton); - - QObject::connect(button.get(), &TestButton::clicked, inspectorDialog.get(), &InspectorDialog::onPushButtonCopy); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(Space::iddObjectType())); - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - - std::vector handles; - handles.push_back(space1.handle()); - EXPECT_TRUE(inspectorDialog->setSelectedObjectHandles(handles)); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(space1.handle(), inspectorDialog->selectedObjectHandles()[0]); - - button->doClick(); - - ASSERT_EQ(3u, model.numObjects()); - EXPECT_EQ(space1.handle(), model.objects(true)[0].handle()); - EXPECT_EQ(space2.handle(), model.objects(true)[1].handle()); - EXPECT_TRUE(model.objects(true)[2].optionalCast()); - - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(model.objects(true)[2].handle(), inspectorDialog->selectedObjectHandles()[0]); -} - -TEST_F(ModelEditorFixture, InspectorDialog_ModelObjectRemove) { - Model model; - LightsDefinition definition(model); - Lights lights(definition); - ASSERT_EQ(2u, model.numObjects()); - EXPECT_EQ(definition.handle(), model.objects(true)[0].handle()); - EXPECT_EQ(lights.handle(), model.objects(true)[1].handle()); - - std::shared_ptr inspectorDialog(new InspectorDialog(model)); - - std::shared_ptr button(new TestButton); - - QObject::connect(button.get(), &TestButton::clicked, inspectorDialog.get(), &InspectorDialog::onPushButtonDelete); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(LightsDefinition::iddObjectType())); - EXPECT_EQ(LightsDefinition::iddObjectType(), inspectorDialog->iddObjectType()); - - std::vector handles; - handles.push_back(definition.handle()); - EXPECT_TRUE(inspectorDialog->setSelectedObjectHandles(handles)); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(definition.handle(), inspectorDialog->selectedObjectHandles()[0]); - - button->doClick(); - - ASSERT_EQ(0u, model.numObjects()); -} - -TEST_F(ModelEditorFixture, InspectorDialog_SignalsOnIddObjectTypeChange) { - Model model; - Space space(model); - ThermalZone thermalZone(model); - - ASSERT_TRUE(model.numObjects() >= 2); - EXPECT_EQ(space.handle(), model.objects(true)[0].handle()); - EXPECT_EQ(thermalZone.handle(), model.objects(true)[1].handle()); - - std::shared_ptr inspectorDialog(new InspectorDialog(model)); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(Space::iddObjectType())); - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(space.handle(), inspectorDialog->selectedObjectHandles()[0]); - - WorkspaceObjectWatcher spaceWatcher(space); - EXPECT_FALSE(spaceWatcher.dirty()); - - WorkspaceObjectWatcher thermalZoneWatcher(thermalZone); - EXPECT_FALSE(thermalZoneWatcher.dirty()); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(ThermalZone::iddObjectType())); - EXPECT_EQ(ThermalZone::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(thermalZone.handle(), inspectorDialog->selectedObjectHandles()[0]); - - EXPECT_FALSE(spaceWatcher.dirty()); - EXPECT_TRUE(thermalZoneWatcher.dirty()); // created new field for humidistat - - spaceWatcher.clearState(); - thermalZoneWatcher.clearState(); - - EXPECT_FALSE(spaceWatcher.dirty()); - EXPECT_FALSE(thermalZoneWatcher.dirty()); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(Space::iddObjectType())); - EXPECT_EQ(Space::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(space.handle(), inspectorDialog->selectedObjectHandles()[0]); - - EXPECT_FALSE(spaceWatcher.dirty()); - EXPECT_FALSE(thermalZoneWatcher.dirty()); - - EXPECT_TRUE(inspectorDialog->setIddObjectType(ThermalZone::iddObjectType())); - EXPECT_EQ(ThermalZone::iddObjectType(), inspectorDialog->iddObjectType()); - ASSERT_EQ(1u, inspectorDialog->selectedObjectHandles().size()); - EXPECT_EQ(thermalZone.handle(), inspectorDialog->selectedObjectHandles()[0]); - - EXPECT_FALSE(spaceWatcher.dirty()); - EXPECT_FALSE(thermalZoneWatcher.dirty()); -} diff --git a/translations/OpenStudioApp_ar.ts b/translations/OpenStudioApp_ar.ts index 5eee9d377..15213c0c7 100644 --- a/translations/OpenStudioApp_ar.ts +++ b/translations/OpenStudioApp_ar.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - - - - - Add new object - - - - - Copy selected object - - - - - Remove selected objects - - - - - Purge unused objects - - - InspectorGadget diff --git a/translations/OpenStudioApp_ca.ts b/translations/OpenStudioApp_ca.ts index 5deb95250..c545a3e28 100644 --- a/translations/OpenStudioApp_ca.ts +++ b/translations/OpenStudioApp_ca.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - Inspector d'OpenStudio - - - - Add new object - Afegir un objecte nou - - - - Copy selected object - Copiar l'objecte seleccionat - - - - Remove selected objects - Eliminar els objectes seleccionats - - - - Purge unused objects - Desfer-se dels objectes sense utilitzar - - InspectorGadget diff --git a/translations/OpenStudioApp_de.ts b/translations/OpenStudioApp_de.ts index ccd315816..9034d89be 100644 --- a/translations/OpenStudioApp_de.ts +++ b/translations/OpenStudioApp_de.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio Inspektor - - - - Add new object - Neues Objekt hinzufügen - - - - Copy selected object - Ausgewähltes Objekt kopieren - - - - Remove selected objects - Ausgewählte Objekte entfernen - - - - Purge unused objects - Ungenutzte Objekte löschen - - InspectorGadget diff --git a/translations/OpenStudioApp_el.ts b/translations/OpenStudioApp_el.ts index 77f97aa44..d384e531d 100644 --- a/translations/OpenStudioApp_el.ts +++ b/translations/OpenStudioApp_el.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio ελεγκτής - - - - Add new object - Προσθέστε ένα νέο αντικείμενο - - - - Copy selected object - Αντέγραψε επιλεγμένο αντικειμένο - - - - Remove selected objects - Αφαιρέσε επιλεγμένα αντικείμενα - - - - Purge unused objects - Εκκαθάριση αχρησιμοποίητων αντικειμένων - - InspectorGadget diff --git a/translations/OpenStudioApp_es.ts b/translations/OpenStudioApp_es.ts index 4dd761b6d..043c89745 100644 --- a/translations/OpenStudioApp_es.ts +++ b/translations/OpenStudioApp_es.ts @@ -1,36 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - Inspector de OpenStudio - - - - Add new object - Agregar nuevo objeto - - - - Copy selected object - Copiar objeto seleccionado - - - - Remove selected objects - Remover objetos seleccionados - - - - Purge unused objects - La palabra purgar no tiene el mismo contexto en Español. - Borrar todos los objetos sin usar - - InspectorGadget diff --git a/translations/OpenStudioApp_fa.ts b/translations/OpenStudioApp_fa.ts index 4ca3117b9..60b9aab85 100644 --- a/translations/OpenStudioApp_fa.ts +++ b/translations/OpenStudioApp_fa.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - پیمایشگر اپن استودیو - - - - Add new object - اضافه کردن شیء جدید - - - - Copy selected object - کپی اشیاء انتخاب شده - - - - Remove selected objects - حذف اشیاء انتخاب شده - - - - Purge unused objects - پاکسازی اشیاء استفاده نشده - - InspectorGadget diff --git a/translations/OpenStudioApp_fr.ts b/translations/OpenStudioApp_fr.ts index 95c26a8c5..93b1a87a2 100644 --- a/translations/OpenStudioApp_fr.ts +++ b/translations/OpenStudioApp_fr.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio Inspector - - - - Add new object - Ajouter un nouvel objet - - - - Copy selected object - Copier les objets sélectionnés - - - - Remove selected objects - Supprimer les objets selectionnés - - - - Purge unused objects - Purger les objets inutilisés - - InspectorGadget diff --git a/translations/OpenStudioApp_he.ts b/translations/OpenStudioApp_he.ts index e5a14c936..a0546f365 100644 --- a/translations/OpenStudioApp_he.ts +++ b/translations/OpenStudioApp_he.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - מפקח OPENSTUDIO - - - - Add new object - הוסף אובייקט חדש - - - - Copy selected object - העתק אובייקט חדש - - - - Remove selected objects - הסר אובייקטים נבחרים - - - - Purge unused objects - הסר אובייקטים לא בשימוש - - InspectorGadget diff --git a/translations/OpenStudioApp_hi.ts b/translations/OpenStudioApp_hi.ts index 187e395ed..ce2fc16f1 100644 --- a/translations/OpenStudioApp_hi.ts +++ b/translations/OpenStudioApp_hi.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - ओपेनस्टूडियो निरीक्षक - - - - Add new object - नया ऑब्जेक्ट जोड़ें - - - - Copy selected object - चयनित ऑब्जेक्ट की प्रतिलिपि बनाएँ - - - - Remove selected objects - चयनित ऑब्जेक्ट हटाएं - - - - Purge unused objects - अप्रयुक्त ऑब्जेक्ट को शुद्ध करें - - InspectorGadget diff --git a/translations/OpenStudioApp_it.ts b/translations/OpenStudioApp_it.ts index 71ce5c4b9..c12df8ceb 100644 --- a/translations/OpenStudioApp_it.ts +++ b/translations/OpenStudioApp_it.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio Revisore - - - - Add new object - Aggiungi Nuovo Oggetto - - - - Copy selected object - Copia Oggetto Selezionato - - - - Remove selected objects - Rimuovi Oggetti Selezionati - - - - Purge unused objects - Pulisci Oggetti Inutilizzati - - InspectorGadget diff --git a/translations/OpenStudioApp_ja.ts b/translations/OpenStudioApp_ja.ts index efde7ab0b..6683d5981 100644 --- a/translations/OpenStudioApp_ja.ts +++ b/translations/OpenStudioApp_ja.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio インスペクター - - - - Add new object - 新しいオブジェクトの追加 - - - - Copy selected object - 選択されたオブジェクトをコピー - - - - Remove selected objects - 選択されたオブジェクトを削除 - - - - Purge unused objects - 未使用オブジェクトをすべて削除 - - InspectorGadget diff --git a/translations/OpenStudioApp_pl.ts b/translations/OpenStudioApp_pl.ts index b41e18dc3..c5be88771 100644 --- a/translations/OpenStudioApp_pl.ts +++ b/translations/OpenStudioApp_pl.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio Inspektor - - - - Add new object - Dodaj nowy objekt - - - - Copy selected object - Kopiuj wybrany objekt - - - - Remove selected objects - Usuń wybrany objekt - - - - Purge unused objects - Wyczyść nieużywane objekty - - InspectorGadget diff --git a/translations/OpenStudioApp_vi.ts b/translations/OpenStudioApp_vi.ts index a12148104..ccdcdf648 100644 --- a/translations/OpenStudioApp_vi.ts +++ b/translations/OpenStudioApp_vi.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - Mở bảng kiểm thuộc tính - - - - Add new object - Thêm đối tượng mới - - - - Copy selected object - Copy những đối tượng được chọn - - - - Remove selected objects - Bỏ những đối tượng được chọn - - - - Purge unused objects - Dọn sạch những đối tượng không dùng - - InspectorGadget diff --git a/translations/OpenStudioApp_zh_CN.ts b/translations/OpenStudioApp_zh_CN.ts index 1cc9dd72b..70ae7e890 100644 --- a/translations/OpenStudioApp_zh_CN.ts +++ b/translations/OpenStudioApp_zh_CN.ts @@ -1,35 +1,6 @@ - - InspectorDialog - - - - OpenStudio Inspector - OpenStudio检测器 - - - - Add new object - 加入新物件 - - - - Copy selected object - 复制已选物件 - - - - Remove selected objects - 移除已选物件 - - - - Purge unused objects - 清楚未使用物件 - - InspectorGadget From bd12f80328cf21ec5abe3881a7168bf2a3e2f6fa Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 21:10:29 -0600 Subject: [PATCH 14/26] Fix include guard --- src/shared_gui_components/RenderingColorWidget2.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared_gui_components/RenderingColorWidget2.hpp b/src/shared_gui_components/RenderingColorWidget2.hpp index fded7de70..54d3b834c 100644 --- a/src/shared_gui_components/RenderingColorWidget2.hpp +++ b/src/shared_gui_components/RenderingColorWidget2.hpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#ifndef OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP -#define OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP +#ifndef SHAREDGUICOMPONENTS_RENDERINGCOLORWIDGET2_HPP +#define SHAREDGUICOMPONENTS_RENDERINGCOLORWIDGET2_HPP #include // Signal-Slot replacement #include "FieldMethodTypedefs.hpp" @@ -58,4 +58,4 @@ class RenderingColorWidget2 } // namespace openstudio -#endif // OPENSTUDIO_RENDERINGCOLORWIDGET2_HPP +#endif // SHAREDGUICOMPONENTS_RENDERINGCOLORWIDGET2_HPP From 3983c6b64d71a23735dbaaf9a1ab7ee52e8e72de Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 21:19:00 -0600 Subject: [PATCH 15/26] Apply review comments --- CMakeLists.txt | 1 + developer/doc/architecture.md | 6 ++++++ src/bimserver/CMakeLists.txt | 11 +++++++++-- src/openstudio_qt_utils/CMakeLists.txt | 1 - src/shared_gui_components/CMakeLists.txt | 1 + 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 337de4cba..a4b513832 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -744,6 +744,7 @@ add_subdirectory("translations") # E X P O R T T A R G E T S # ############################################################################### +list(APPEND all_lib_targets "openstudioapp_utilities ") list(APPEND all_lib_targets "openstudio_qt_utils") list(APPEND all_lib_targets "openstudio_modeleditor") list(APPEND all_lib_targets "openstudio_bimserver") diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index 835657fc0..0e9517172 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -68,11 +68,14 @@ C4Container Container(shared_gui, "shared_gui_components", "C++ static library", "Reusable widgets: grid system, form controls, measure manager, BCL dialogs, user settings. Target: openstudio_shared_gui") Container(model_editor, "model_editor", "C++ static library", "Generic IDD-driven model object inspector; AccessPolicyStore (field-level access policies for IDD objects). Target: openstudio_modeleditor") Container(qt_utils, "openstudio_qt_utils", "C++ static library", "Qt/OpenStudio primitives: string/UUID/path conversions, Application singleton, OSProgressBar, Qt metatype registration for SDK types. Target: openstudio_qt_utils") + Container(bimserver, "bimserver", "C++ static library", "BIMserver connection and project import via cpprestsdk/WebSocket. Target: openstudio_bimserver") Container(utilities, "utilities", "C++ static/header library", "Runtime path resolution for SDK CLI, EnergyPlus, Radiance. Target: openstudioapp_utilities") Rel(app_exe, openstudio_lib, "Links; creates OSDocument and MainWindow") + Rel(app_exe, bimserver, "Links; BIMserver import workflow") Rel(openstudio_lib, shared_gui, "Links; uses grid widgets, form controls, measure integration") Rel(openstudio_lib, model_editor, "Links; uses InspectorGadget, AccessPolicyStore") + Rel(bimserver, qt_utils, "Links; Qt string/UUID conversions, Application singleton") Rel(shared_gui, qt_utils, "Links; Qt string/UUID conversions, Application singleton, metatype registration") Rel(model_editor, qt_utils, "Links; Qt string/UUID conversions, Application singleton, OSProgressBar") Rel(qt_utils, utilities, "Links; runtime path resolution for SDK CLI, EnergyPlus, Radiance") @@ -88,6 +91,7 @@ flowchart TD LIB["openstudio_lib"] SHARED["shared_gui_components"] ME["model_editor"] + BIMSERVER["bimserver"] QTUTILS["openstudio_qt_utils"] UTIL["utilities"] QTWEB["QT_WEB_LIBS
(external)"] @@ -96,9 +100,11 @@ flowchart TD BOOST["Boost
(external)"] EXE --> LIB + EXE --> BIMSERVER LIB --> SHARED LIB --> ME LIB --> QTWEB + BIMSERVER --> QTUTILS SHARED --> QTUTILS ME --> QTUTILS QTUTILS --> UTIL diff --git a/src/bimserver/CMakeLists.txt b/src/bimserver/CMakeLists.txt index 89f126ec4..3184c50a3 100644 --- a/src/bimserver/CMakeLists.txt +++ b/src/bimserver/CMakeLists.txt @@ -1,5 +1,4 @@ set(target_name openstudio_bimserver) -set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${QT_INCLUDES}) @@ -17,11 +16,19 @@ set(${target_name}_test_src Test/BIMserverFixture.cpp ) +set(${target_name}_moc + BIMserverConnection.hpp + ProjectImporter.hpp +) + +## Qt MOC generation +qt6_wrap_cpp(${target_name}_moc_src ${${target_name}_moc}) + set(${target_name}_depends openstudio_qt_utils ) -add_library(${target_name} ${${target_name}_src}) +add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_moc_src}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) AddPCH(${target_name}) diff --git a/src/openstudio_qt_utils/CMakeLists.txt b/src/openstudio_qt_utils/CMakeLists.txt index 33f8428b5..c6fad6409 100644 --- a/src/openstudio_qt_utils/CMakeLists.txt +++ b/src/openstudio_qt_utils/CMakeLists.txt @@ -22,7 +22,6 @@ set(${target_name}_depends ${QT_LIBS} ) -add_dependencies(${target_name} ${${target_name}_depends}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) CREATE_SRC_GROUPS("${${target_name}_src}") diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index f55155970..bd440a324 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -72,6 +72,7 @@ set(${target_name}_src OSGridController.hpp OSGridView.cpp OSGridView.hpp + OSItemId.hpp OSIntegerEdit.cpp OSIntegerEdit.hpp OSLineEdit.cpp From 5113df658d558dcc5a5971f2966560b43195a213 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 21:31:51 -0600 Subject: [PATCH 16/26] Remove dead code and fix CI issues for Ubuntu --- CMakeLists.txt | 15 +++---- src/model_editor/CMakeLists.txt | 1 + src/model_editor/ModelEditor.rc | 1 - src/model_editor/ModelEditor.xml | 25 ------------ src/model_editor/TreeView.cpp | 48 ----------------------- src/model_editor/TreeView.hpp | 42 -------------------- src/model_editor/modeleditorlib.qrc | 1 + src/openstudio_lib/CMakeLists.txt | 1 + src/openstudio_lib/split_os_app.sh | 5 --- src/shared_gui_components/split_os_app.sh | 5 --- 10 files changed, 8 insertions(+), 136 deletions(-) delete mode 100644 src/model_editor/ModelEditor.rc delete mode 100644 src/model_editor/ModelEditor.xml delete mode 100644 src/model_editor/TreeView.cpp delete mode 100644 src/model_editor/TreeView.hpp delete mode 100644 src/openstudio_lib/split_os_app.sh delete mode 100644 src/shared_gui_components/split_os_app.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index a4b513832..757ac657e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -583,16 +583,11 @@ if(NOT APPLE) find_package(Qt6QmlModels ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) list(APPEND QT_WEB_LIBS Qt6::QmlModels) - # Qt 6.11+ splits QmlMeta and QmlWorkerScript into their own libraries (required by QtWebEngineProcess) - find_package(Qt6QmlMeta ${QT_VERSION} QUIET PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) - if(Qt6QmlMeta_FOUND) - list(APPEND QT_WEB_LIBS Qt6::QmlMeta) - endif() + find_package(Qt6QmlMeta ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) + list(APPEND QT_WEB_LIBS Qt6::QmlMeta) - find_package(Qt6QmlWorkerScript ${QT_VERSION} QUIET PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) - if(Qt6QmlWorkerScript_FOUND) - list(APPEND QT_WEB_LIBS Qt6::QmlWorkerScript) - endif() + find_package(Qt6QmlWorkerScript ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) + list(APPEND QT_WEB_LIBS Qt6::QmlWorkerScript) find_package(Qt6Positioning ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) list(APPEND QT_WEB_LIBS Qt6::Positioning) @@ -744,7 +739,7 @@ add_subdirectory("translations") # E X P O R T T A R G E T S # ############################################################################### -list(APPEND all_lib_targets "openstudioapp_utilities ") +list(APPEND all_lib_targets "openstudioapp_utilities") list(APPEND all_lib_targets "openstudio_qt_utils") list(APPEND all_lib_targets "openstudio_modeleditor") list(APPEND all_lib_targets "openstudio_bimserver") diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index 59451b018..e7197d3a1 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories(${QT_INCLUDES}) set(${target_name}_src AccessPolicyStore.hpp AccessPolicyStore.cpp + mainpage.hpp BridgeClasses.hpp BridgeClasses.cpp GithubReleases.hpp diff --git a/src/model_editor/ModelEditor.rc b/src/model_editor/ModelEditor.rc deleted file mode 100644 index 6419aad3c..000000000 --- a/src/model_editor/ModelEditor.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "../../icons/me.ico" diff --git a/src/model_editor/ModelEditor.xml b/src/model_editor/ModelEditor.xml deleted file mode 100644 index 824bf68cf..000000000 --- a/src/model_editor/ModelEditor.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/model_editor/TreeView.cpp b/src/model_editor/TreeView.cpp deleted file mode 100644 index e4c03da4a..000000000 --- a/src/model_editor/TreeView.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include -#include -#include - -#include "TreeView.hpp" - -namespace modeleditor { - -TreeView::TreeView(QWidget* parent) : QTreeView(parent) {} - -TreeView::~TreeView() {} - -void TreeView::enterEvent(QEvent* event) { - emit eventEnter(); -} - -void TreeView::leaveEvent(QEvent* event) { - emit eventLeave(); -} - -void TreeView::keyReleaseEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { - emit eventUpDnKeyRelease(); - } -} - -bool TreeView::getSelectedRows(QModelIndexList& rowList) { - //bool success = false; - QItemSelectionModel* selectionMod = nullptr; - selectionMod = selectionModel(); - if (selectionMod) { - //success = true; - rowList = selectionMod->selectedRows(); - } - return !rowList.empty(); -} - -bool TreeView::hasSelectedRows() { - QModelIndexList rowList; - return getSelectedRows(rowList); -} - -} // namespace modeleditor diff --git a/src/model_editor/TreeView.hpp b/src/model_editor/TreeView.hpp deleted file mode 100644 index ad8156518..000000000 --- a/src/model_editor/TreeView.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef MODELEDITOR_TREEVIEW_HPP -#define MODELEDITOR_TREEVIEW_HPP - -#include - -class QModelIndex; - -namespace modeleditor { - -class TreeView : public QTreeView -{ - Q_OBJECT - - public: - explicit TreeView(QWidget* parent = nullptr); - virtual ~TreeView(); - bool getSelectedRows(QModelIndexList& rowList); - bool hasSelectedRows(); - - public slots: - - signals: - void eventEnter(); - void eventLeave(); - void eventUpDnKeyRelease(); - - protected: - virtual void enterEvent(QEvent* event) override; - virtual void leaveEvent(QEvent* event) override; - virtual void keyReleaseEvent(QKeyEvent* event) override; - - private: -}; - -} // namespace modeleditor - -#endif // MODELEDITOR_TREEVIEW_HPP diff --git a/src/model_editor/modeleditorlib.qrc b/src/model_editor/modeleditorlib.qrc index 7bea150be..fb4dcf11b 100644 --- a/src/model_editor/modeleditorlib.qrc +++ b/src/model_editor/modeleditorlib.qrc @@ -13,6 +13,7 @@ images/me_16.png images/v_devider_dots.png InspectorDialog.qss + ModalDialogs.qss SketchUpPluginPolicy.xml ../../resources/openstudio.qss diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 6ab2c2878..56e0c2769 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -281,6 +281,7 @@ set(${target_name}_SRC SimSettingsTabView.hpp SimSettingsView.cpp SimSettingsView.hpp + SOConstants.hpp SpaceLoadInstancesWidget.cpp SpaceLoadInstancesWidget.hpp SpacesDaylightingGridView.cpp diff --git a/src/openstudio_lib/split_os_app.sh b/src/openstudio_lib/split_os_app.sh deleted file mode 100644 index 02a8c7a74..000000000 --- a/src/openstudio_lib/split_os_app.sh +++ /dev/null @@ -1,5 +0,0 @@ -src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components - -Source: https://stackoverflow.com/questions/2982055/detach-many-subdirectories-into-a-new-separate-git-repository - - git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components' --prune-empty -- --all diff --git a/src/shared_gui_components/split_os_app.sh b/src/shared_gui_components/split_os_app.sh deleted file mode 100644 index 02a8c7a74..000000000 --- a/src/shared_gui_components/split_os_app.sh +++ /dev/null @@ -1,5 +0,0 @@ -src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components - -Source: https://stackoverflow.com/questions/2982055/detach-many-subdirectories-into-a-new-separate-git-repository - - git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- src/model_editor src/openstudio_app src/openstudio_lib src/shared_gui_components' --prune-empty -- --all From 9792342483ec8327f35ef02d3f8d9678f36415f4 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sun, 26 Apr 2026 23:03:43 -0600 Subject: [PATCH 17/26] Fix tech debt issues identified --- developer/doc/architecture.md | 24 +++ developer/doc/libraries/openstudio_app.md | 1 + developer/doc/libraries/openstudio_lib.md | 3 +- .../doc/libraries/openstudio_qt_utils.md | 1 + .../doc/libraries/shared_gui_components.md | 19 +- src/model_editor/CMakeLists.txt | 7 - src/model_editor/InspectorDialog.qss | 127 -------------- src/model_editor/modeleditorlib.qrc | 1 - src/openstudio_app/CMakeLists.txt | 5 + .../GithubReleases.cpp | 0 .../GithubReleases.hpp | 0 src/openstudio_app/OpenStudioApp.cpp | 2 +- src/openstudio_app/main.cpp | 1 + .../test/GithubReleases_GTest.cpp | 8 +- .../test/OpenStudioAppFixture.cpp | 2 + src/openstudio_lib/OSAppBase.cpp | 14 ++ src/openstudio_lib/OSAppBase.hpp | 2 + src/openstudio_lib/openstudio.qrc | 162 +----------------- src/openstudio_lib/openstudiolib.qss | 40 +++++ .../test/OpenStudioLibFixture.cpp | 1 + .../test/SpacesSurfaces_Benchmark.cpp | 1 + src/openstudio_qt_utils/CMakeLists.txt | 22 ++- .../PathWatcher.cpp | 4 +- .../PathWatcher.hpp | 0 .../test/PathWatcher_GTest.cpp | 6 +- .../test/QtUtilsFixture.cpp | 28 +++ .../test/QtUtilsFixture.hpp | 27 +++ src/shared_gui_components/BaseApp.hpp | 6 + src/shared_gui_components/CMakeLists.txt | 5 +- .../LocalLibraryController.cpp | 8 +- .../WorkflowController.cpp | 30 ++-- .../openstudio_shared_gui.qrc | 160 +++++++++++++++++ 32 files changed, 390 insertions(+), 327 deletions(-) delete mode 100644 src/model_editor/InspectorDialog.qss rename src/{model_editor => openstudio_app}/GithubReleases.cpp (100%) rename src/{model_editor => openstudio_app}/GithubReleases.hpp (100%) rename src/{model_editor => openstudio_app}/test/GithubReleases_GTest.cpp (94%) rename src/{model_editor => openstudio_qt_utils}/PathWatcher.cpp (97%) rename src/{model_editor => openstudio_qt_utils}/PathWatcher.hpp (100%) rename src/{model_editor => openstudio_qt_utils}/test/PathWatcher_GTest.cpp (95%) create mode 100644 src/openstudio_qt_utils/test/QtUtilsFixture.cpp create mode 100644 src/openstudio_qt_utils/test/QtUtilsFixture.hpp create mode 100644 src/shared_gui_components/openstudio_shared_gui.qrc diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index 0e9517172..c26ef20f1 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -249,6 +249,30 @@ OpenStudio Measures (Ruby or Python scripts that transform models) are managed b - Runs measures via the OpenStudio CLI in a background process - The `ApplyMeasureNowDialog` provides a modal UI for running a single measure interactively +### 7.6 Library Boundary Rules + +The intended dependency order is strict and acyclic: + +``` +OpenStudioApp (exe) + → openstudio_lib + → shared_gui_components + → openstudio_qt_utils + → openstudioapp_utilities + → openstudio_bimserver + → openstudio_qt_utils + → openstudio_modeleditor + → openstudio_qt_utils +``` + +**The `BaseApp` interface** (`shared_gui_components/BaseApp.hpp`) is the key boundary between the lower-level `shared_gui_components` library and the upper-level `openstudio_lib` library. All `shared_gui_components` code that needs application-level services must go through `BaseApp`, never through `OSAppBase`, `OSDocument`, or `MainWindow` directly. + +**Known violations (tracked as tech debt):** + +| Violation | Location | Correct Fix | +|---|---|---| +| `OSItem`, `OSDropZone`, `ModelObjectItem` live in `openstudio_lib` but are included by `shared_gui_components` code (`OSCellWrapper`, `OSGridView`, `OSWidgetHolder`, `OSLineEdit`, `OSGridController`, `LocalLibraryController`) | `src/openstudio_lib/OSItem.hpp`, `OSDropZone.hpp`, `ModelObjectItem.hpp` | Move these three classes to `shared_gui_components`; they have no `openstudio_lib`-only dependencies. `OSItem` depends only on `OSItemId` and `LocalLibrary.hpp`, both already in `shared_gui_components`. | + --- ## 8. CI/CD Overview diff --git a/developer/doc/libraries/openstudio_app.md b/developer/doc/libraries/openstudio_app.md index 1341a9737..54aa43306 100644 --- a/developer/doc/libraries/openstudio_app.md +++ b/developer/doc/libraries/openstudio_app.md @@ -59,6 +59,7 @@ classDiagram | `StartupMenu` | [StartupMenu.hpp](../../../src/openstudio_app/StartupMenu.hpp) | Minimal menu bar shown during the startup screen (no document-specific items). | | `LibraryDialog` | [LibraryDialog.hpp](../../../src/openstudio_app/LibraryDialog.hpp) | Dialog allowing users to select component library `.osm` files to load alongside the project. | | `ExternalToolsDialog` | [ExternalToolsDialog.hpp](../../../src/openstudio_app/ExternalToolsDialog.hpp) | Dialog for configuring paths to external tools (EnergyPlus, Radiance, etc.). | +| `GithubReleases` / `GithubRelease` | [GithubReleases.hpp](../../../src/openstudio_app/GithubReleases.hpp) | Checks the GitHub releases API for new application versions. Called from `OpenStudioApp` at startup. | --- diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index 32fd6932d..c2dca3f16 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -103,9 +103,10 @@ classDiagram | `ModelObjectListView` | Generic list view displaying any collection of model objects | | `ModelObjectTreeWidget` | Generic tree view for hierarchical model data | | `OSWebEnginePage` | `QWebEnginePage` subclass for the geometry JS bridge | -| `RenderingColorWidget` | Color picker for object rendering colors | > **Note:** `OSVectorController`, `IconLibrary` have moved to `shared_gui_components`. +> +> **Boundary note:** `OSItem`, `OSDropZone`, and `ModelObjectItem` are currently in `openstudio_lib` for historical reasons, but `shared_gui_components` code (`OSCellWrapper`, `OSGridView`, `OSWidgetHolder`, `OSLineEdit`, `OSGridController`, `LocalLibraryController`) includes them via backward cross-library `#include` paths. These three classes should be moved to `shared_gui_components` in a future refactor — none of them have dependencies that would prevent the move. --- diff --git a/developer/doc/libraries/openstudio_qt_utils.md b/developer/doc/libraries/openstudio_qt_utils.md index 6f36c904c..39dadec7a 100644 --- a/developer/doc/libraries/openstudio_qt_utils.md +++ b/developer/doc/libraries/openstudio_qt_utils.md @@ -55,6 +55,7 @@ classDiagram | `Utilities.hpp/cpp` | Free functions for converting between `QString`, `std::string`, `std::wstring`, `openstudio::path`, and `openstudio::UUID` | | `QMetaTypes.hpp/cpp` | `Q_DECLARE_METATYPE` declarations and `qRegisterMetaType` calls for SDK types used in queued signal/slot connections | | `OSProgressBar.hpp/cpp` | `OSProgressBar` — wraps `QProgressBar` and implements the `openstudio::ProgressBar` interface | +| `PathWatcher.hpp/cpp` | `PathWatcher` — `QTimer`-based file-change watcher; polls a file path at a configurable interval and emits virtual callbacks when the file is added, changed, or removed | --- diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 3f126bdb7..253e6b662 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -159,9 +159,26 @@ flowchart TD --- +## Known Boundary Violations + +The following files in `shared_gui_components` currently include headers from `openstudio_lib`, which is a **higher-level** library and violates the intended dependency order. These are tracked as tech debt: + +| File | Bad include | Notes | +|---|---|---| +| `OSCellWrapper.cpp` | `../openstudio_lib/OSDropZone.hpp` | `OSDropZone` should move to `shared_gui_components` | +| `OSGridView.cpp` | `../openstudio_lib/OSDropZone.hpp` | Same as above | +| `OSWidgetHolder.cpp` | `../openstudio_lib/OSDropZone.hpp` | Same as above | +| `OSLineEdit.cpp` | `../openstudio_lib/OSItem.hpp`, `ModelObjectItem.hpp` | `OSItem` and `ModelObjectItem` should move to `shared_gui_components` | +| `OSGridController.cpp` | `../openstudio_lib/OSItem.hpp`, `ModelObjectItem.hpp` | Same as above | +| `LocalLibraryController.cpp` | `../openstudio_lib/OSItem.hpp` | Should use `OSItem` once it moves to `shared_gui_components` | + +The correct resolution is to move `OSItem`, `OSDropZone`, and `ModelObjectItem` to `shared_gui_components` (all three have no `openstudio_lib`-only dependencies). + +--- + ## Patterns & Conventions -- **`BaseApp` interface** — all components that need access to the application (e.g., `MeasureManager`) depend only on `BaseApp`, never on `OpenStudioApp` or `OSAppBase` directly. This enables reuse in plugin contexts. +- **`BaseApp` interface** — all components that need access to the application (e.g., `MeasureManager`, `LocalLibraryController`, `WorkflowController`) use only `BaseApp`, never `OSAppBase`, `OSDocument`, or `MainWindow` directly. `BaseApp` exposes `useClassicCLI()`, `disableDocument()`, and `enableDocument()` so that shared components can call these without depending on `openstudio_lib` types. This keeps the dependency order acyclic. - **`add*Column()` DSL** — `OSGridController` subclasses define their columns declaratively in their constructor, producing a clean, readable column specification without procedural layout code. - **Thread safety** — `MeasureManager` uses a `QMutex` to protect its measure index; BCL network requests are made on the Qt network thread. diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index e7197d3a1..83a54dc92 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -14,16 +14,12 @@ set(${target_name}_src mainpage.hpp BridgeClasses.hpp BridgeClasses.cpp - GithubReleases.hpp - GithubReleases.cpp InspectorGadget.hpp InspectorGadget.cpp ListWidget.hpp ListWidget.cpp ModalDialogs.hpp ModalDialogs.cpp - PathWatcher.hpp - PathWatcher.cpp TableView.hpp TableView.cpp TableWidget.hpp @@ -41,7 +37,6 @@ set(${target_name}_moc InspectorGadget.hpp ListWidget.hpp ModalDialogs.hpp - PathWatcher.hpp TableView.hpp TableWidget.hpp TestButton.hpp @@ -87,10 +82,8 @@ set(${target_name}_test_src test/ModelEditorFixture.cpp test/IGLineEdit_GTest.cpp test/ModalDialogs_GTest.cpp - test/PathWatcher_GTest.cpp test/QMetaTypes_GTest.cpp test/Utilities_GTest.cpp - test/GithubReleases_GTest.cpp ) set(${target_name}_test_depends diff --git a/src/model_editor/InspectorDialog.qss b/src/model_editor/InspectorDialog.qss deleted file mode 100644 index f02411eee..000000000 --- a/src/model_editor/InspectorDialog.qss +++ /dev/null @@ -1,127 +0,0 @@ -QListView { - show-decoration-selected: 1; /* make the selection span the entire width of the view */ -} - -QListView::item:alternate, QTableView::item:alternate { - background: #EEEEEE; -} - -QListView::item:selected, QTableView::item:selected { - border: 1px solid #6a6ea9; -} - -QListView::item:selected:!active, QTableView::item:selected:!active { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ABAFE5, stop: 1 #8588B2); -} - -QListView::item:selected:active, QTableView::item:selected:active { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6a6ea9, stop: 1 #888dd9); -} - -QListView::item:hover, QTableView::item:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FAFBFE, stop: 1 #DCDEF1); -} - -QHeaderView::section { - background-color: qlineargradient(x1:0,y1:0, - x2:0,y2:1, - stop: 0 #6B747B, - stop: 0.33 #D0D4D7, - stop: 0.66 #D0D4D7, - stop: 1 #6B747B); -} - -QWidget#listLabel { - background-color: qlineargradient(x1:0,y1:0, - x2:0,y2:1, - stop: 0 #6B747B, - stop: 0.33 #D0D4D7, - stop: 0.66 #D0D4D7, - stop: 1 #6B747B); -} - -QWidget#tableLabel { - background-color: qlineargradient(x1:0,y1:0, - x2:0,y2:1, - stop: 0 #6B747B, - stop: 0.33 #D0D4D7, - stop: 0.66 #D0D4D7, - stop: 1 #6B747B); -} - -QWidget#selectionLabel { - background-color: qlineargradient(x1:0,y1:0, - x2:0,y2:1, - stop: 0 #6B747B, - stop: 0.33 #D0D4D7, - stop: 0.66 #D0D4D7, - stop: 1 #6B747B); -} - -QWidget#igLabel{ - background-color: qlineargradient(x1:0,y1:0, - x2:0,y2:1, - stop: 0 #6B747B, - stop: 0.33 #D0D4D7, - stop: 0.66 #D0D4D7, - stop: 1 #6B747B); -} - -QSplitter::handle::horizontal { - width: 15px; - image: url(:/images/h_devider_dots.png); - background-color: #2C3233; -} - -QSplitter::handle::vertical { - height: 15px; - image: url(:/images/v_devider_dots.png); - background-color: #2C3233; -} - -QPushButton#pushButtonNew { - border: none; - image: url(:/images/edit_add.png); - width: 40px; - height: 40px; -} - -QPushButton#pushButtonNew:disabled { - image: url(:/images/edit_add_off.png); -} - -QPushButton#pushButtonCopy { - border: none; - image: url(:/images/copy.png); - width: 40px; - height: 40px; -} - -QPushButton#pushButtonCopy:disabled { - image: url(:/images/copy_off.png); -} - -QPushButton#pushButtonDelete { - border: none; - image: url(:/images/edit_remove.png); - width: 40px; - height: 40px; -} - -QPushButton#pushButtonDelete:disabled { - image: url(:/images/edit_remove_off.png); -} - -QPushButton#pushButtonPurge { - border: none; - image: url(:/images/edit_purge.png); - width: 40px; - height: 40px; -} - -QPushButton#pushButtonPurge:disabled { - image: url(:/images/edit_purge_off.png); -} diff --git a/src/model_editor/modeleditorlib.qrc b/src/model_editor/modeleditorlib.qrc index fb4dcf11b..b96ac6d40 100644 --- a/src/model_editor/modeleditorlib.qrc +++ b/src/model_editor/modeleditorlib.qrc @@ -12,7 +12,6 @@ images/h_devider_dots.png images/me_16.png images/v_devider_dots.png - InspectorDialog.qss ModalDialogs.qss SketchUpPluginPolicy.xml ../../resources/openstudio.qss diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index 7394740c7..3aff98063 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -8,6 +8,8 @@ set(${target_name}_SRC main.cpp OpenStudioApp.cpp OpenStudioApp.hpp + GithubReleases.hpp + GithubReleases.cpp StartupView.hpp StartupView.cpp StartupMenu.hpp @@ -519,6 +521,9 @@ set(${target_name}_test_src test/OpenStudioAppFixture.cpp test/Resources_GTest.cpp test/Units_GTest.cpp + test/GithubReleases_GTest.cpp + GithubReleases.hpp + GithubReleases.cpp ) CREATE_SRC_GROUPS("${${target_name}_test_src}") diff --git a/src/model_editor/GithubReleases.cpp b/src/openstudio_app/GithubReleases.cpp similarity index 100% rename from src/model_editor/GithubReleases.cpp rename to src/openstudio_app/GithubReleases.cpp diff --git a/src/model_editor/GithubReleases.hpp b/src/openstudio_app/GithubReleases.hpp similarity index 100% rename from src/model_editor/GithubReleases.hpp rename to src/openstudio_app/GithubReleases.hpp diff --git a/src/openstudio_app/OpenStudioApp.cpp b/src/openstudio_app/OpenStudioApp.cpp index ea602cf7e..8d6230dc9 100644 --- a/src/openstudio_app/OpenStudioApp.cpp +++ b/src/openstudio_app/OpenStudioApp.cpp @@ -13,7 +13,7 @@ #include "../openstudio_lib/OSDocument.hpp" #include "../model_editor/AccessPolicyStore.hpp" -#include "../model_editor/GithubReleases.hpp" +#include "GithubReleases.hpp" #include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/WaitDialog.hpp" diff --git a/src/openstudio_app/main.cpp b/src/openstudio_app/main.cpp index 8d6fb1a51..edbcd21fe 100644 --- a/src/openstudio_app/main.cpp +++ b/src/openstudio_app/main.cpp @@ -92,6 +92,7 @@ void qMessageHandler(QtMsgType type, const QMessageLogContext& context, const QS int main(int argc, char* argv[]) { Q_INIT_RESOURCE(openstudio); + Q_INIT_RESOURCE(openstudio_shared_gui); // DLM: on Windows run with 'OpenStudioApp.exe > out.log 2>&1' to capture all debug output // DLM: set env var 'QT_FATAL_WARNINGS' to error on qt warnings for debugging diff --git a/src/model_editor/test/GithubReleases_GTest.cpp b/src/openstudio_app/test/GithubReleases_GTest.cpp similarity index 94% rename from src/model_editor/test/GithubReleases_GTest.cpp rename to src/openstudio_app/test/GithubReleases_GTest.cpp index 181c636fa..cd8159059 100644 --- a/src/model_editor/test/GithubReleases_GTest.cpp +++ b/src/openstudio_app/test/GithubReleases_GTest.cpp @@ -5,7 +5,7 @@ #include -#include "ModelEditorFixture.hpp" +#include "OpenStudioAppFixture.hpp" #include "../GithubReleases.hpp" #include "../../openstudio_qt_utils/Application.hpp" @@ -18,7 +18,7 @@ using openstudio::Application; -TEST_F(ModelEditorFixture, GithubRelease_Release) { +TEST_F(OpenStudioAppFixture, GithubRelease_Release) { Application::instance().application(false); modeleditor::GithubRelease release("v1.0.1", false, 100, "https://github.com/openstudiocoalition/OpenStudioApplication/releases/tag/v1.0.1"); @@ -38,7 +38,7 @@ TEST_F(ModelEditorFixture, GithubRelease_Release) { EXPECT_EQ("https://github.com/openstudiocoalition/OpenStudioApplication/releases/tag/v1.0.1", root["url"].asString()); } -TEST_F(ModelEditorFixture, GithubRelease_Prerelease) { +TEST_F(OpenStudioAppFixture, GithubRelease_Prerelease) { Application::instance().application(false); modeleditor::GithubRelease release("v1.0.1-pre1", true, 100, @@ -59,7 +59,7 @@ TEST_F(ModelEditorFixture, GithubRelease_Prerelease) { EXPECT_EQ("https://github.com/openstudiocoalition/OpenStudioApplication/releases/tag/v1.0.1-pre1", root["url"].asString()); } -TEST_F(ModelEditorFixture, GithubReleases) { +TEST_F(OpenStudioAppFixture, GithubReleases) { modeleditor::GithubReleases releases("openstudiocoalition", "OpenStudioApplication"); releases.waitForFinished(); diff --git a/src/openstudio_app/test/OpenStudioAppFixture.cpp b/src/openstudio_app/test/OpenStudioAppFixture.cpp index 812de1394..43c8092e3 100644 --- a/src/openstudio_app/test/OpenStudioAppFixture.cpp +++ b/src/openstudio_app/test/OpenStudioAppFixture.cpp @@ -11,6 +11,8 @@ #include int main(int argc, char* argv[]) { + Q_INIT_RESOURCE(openstudio); + Q_INIT_RESOURCE(openstudio_shared_gui); auto app = openstudio::Application::instance().application(false); QTimer::singleShot(0, [&]() { diff --git a/src/openstudio_lib/OSAppBase.cpp b/src/openstudio_lib/OSAppBase.cpp index 404675a12..3678ad2d3 100644 --- a/src/openstudio_lib/OSAppBase.cpp +++ b/src/openstudio_lib/OSAppBase.cpp @@ -269,6 +269,20 @@ bool OSAppBase::useClassicCLI() const { return false; } +void OSAppBase::disableDocument() { + auto doc = currentDocument(); + if (doc) { + doc->disable(); + } +} + +void OSAppBase::enableDocument() { + auto doc = currentDocument(); + if (doc) { + doc->enable(); + } +} + boost::optional OSAppBase::getLocalComponent(const std::string& uid, const std::string& versionId) const { auto doc = currentDocument(); if (doc) { diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index 70f1b5490..23cb0016a 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -82,6 +82,8 @@ class OSAppBase bool mouseOverInspectorView() final; bool useClassicCLI() const final; + void disableDocument() final; + void enableDocument() final; boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const final; boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const final; std::vector getLocalMeasures() const final; diff --git a/src/openstudio_lib/openstudio.qrc b/src/openstudio_lib/openstudio.qrc index 2a984c23c..f4439b9f9 100644 --- a/src/openstudio_lib/openstudio.qrc +++ b/src/openstudio_lib/openstudio.qrc @@ -512,9 +512,14 @@ images/setpoint_singlezone_humidity_min_right@2x.png images/setpoint_singlezone_right.png images/setpoint_singlezone_right@2x.png + images/setpoint_systemnodereset_temperature.png + images/setpoint_systemnodereset_temperature@2x.png images/setpoint_systemnodereset_temperature_right.png + images/setpoint_systemnodereset_temperature_right@2x.png images/setpoint_systemnodereset_humidity.png + images/setpoint_systemnodereset_humidity@2x.png images/setpoint_systemnodereset_humidity_right.png + images/setpoint_systemnodereset_humidity_right@2x.png images/setpoint_warmest.png images/setpoint_warmest@2x.png images/setpoint_warmest_right.png @@ -1059,7 +1064,9 @@ images/mini_icons/setpoint_singlezone_humidity_min.png images/mini_icons/setpoint_singlezone_humidity_min@2x.png images/mini_icons/setpoint_systemnodereset_temperature.png + images/mini_icons/setpoint_systemnodereset_temperature@2x.png images/mini_icons/setpoint_systemnodereset_humidity.png + images/mini_icons/setpoint_systemnodereset_humidity@2x.png images/mini_icons/setpoint_warmest.png images/mini_icons/setpoint_warmest@2x.png images/mini_icons/setpoint_warmest_tempflow.png @@ -1147,161 +1154,6 @@ library/js/dat.gui.0.7.9.min.js library/js/TweenLite.2.1.3.min.js - ../shared_gui_components/images/add_script_icon.png - ../shared_gui_components/images/add_script_icon@2x.png - ../shared_gui_components/images/add_script_icon_over.png - ../shared_gui_components/images/add_script_icon_over@2x.png - ../shared_gui_components/images/add_script_icon_press.png - ../shared_gui_components/images/add_script_icon_press@2x.png - ../shared_gui_components/images/add_softer_off.png - ../shared_gui_components/images/add_softer_off@2x.png - ../shared_gui_components/images/add_softer_on.png - ../shared_gui_components/images/add_softer_on@2x.png - ../shared_gui_components/images/add_softer_press.png - ../shared_gui_components/images/add_softer_press@2x.png - ../shared_gui_components/images/arrow_down.png - ../shared_gui_components/images/arrow_down@2x.png - ../shared_gui_components/images/arrow_down_over.png - ../shared_gui_components/images/arrow_down_over@2x.png - ../shared_gui_components/images/arrow_down_press.png - ../shared_gui_components/images/arrow_down_press@2x.png - ../shared_gui_components/images/arrow_up.png - ../shared_gui_components/images/arrow_up@2x.png - ../shared_gui_components/images/arrow_up_over.png - ../shared_gui_components/images/arrow_up_over@2x.png - ../shared_gui_components/images/arrow_up_press.png - ../shared_gui_components/images/arrow_up_press@2x.png - ../shared_gui_components/images/broken_script.png - ../shared_gui_components/images/broken_script@2x.png - ../shared_gui_components/images/checked_checkbox.png - ../shared_gui_components/images/checked_checkbox@2x.png - ../shared_gui_components/images/checked_checkbox_focused.png - ../shared_gui_components/images/checked_checkbox_focused@2x.png - ../shared_gui_components/images/checked_checkbox_green.png - ../shared_gui_components/images/checked_checkbox_green@2x.png - ../shared_gui_components/images/checked_checkbox_locked.png - ../shared_gui_components/images/checked_checkbox_locked@2x.png - ../shared_gui_components/images/checked_checkbox_update_available.png - ../shared_gui_components/images/checked_checkbox_update_available@2x.png - ../shared_gui_components/images/delete_softer.png - ../shared_gui_components/images/delete_softer@2x.png - ../shared_gui_components/images/delete_softer_over.png - ../shared_gui_components/images/delete_softer_over@2x.png - ../shared_gui_components/images/delete_softer_press.png - ../shared_gui_components/images/delete_softer_press@2x.png - ../shared_gui_components/images/dir.png - ../shared_gui_components/images/dir@2x.png - ../shared_gui_components/images/dir_disabled.png - ../shared_gui_components/images/dir_disabled@2x.png - ../shared_gui_components/images/dir_press.png - ../shared_gui_components/images/dir_press@2x.png - ../shared_gui_components/images/duplicate_disabled.png - ../shared_gui_components/images/duplicate_disabled@2x.png - ../shared_gui_components/images/duplicate_off.png - ../shared_gui_components/images/duplicate_off@2x.png - ../shared_gui_components/images/duplicate_over.png - ../shared_gui_components/images/duplicate_over@2x.png - ../shared_gui_components/images/duplicate_press.png - ../shared_gui_components/images/duplicate_press@2x.png - ../shared_gui_components/images/duplicate_softer_disabled.png - ../shared_gui_components/images/duplicate_softer_disabled@2x.png - ../shared_gui_components/images/duplicate_softer_off.png - ../shared_gui_components/images/duplicate_softer_off@2x.png - ../shared_gui_components/images/duplicate_softer_over.png - ../shared_gui_components/images/duplicate_softer_over@2x.png - ../shared_gui_components/images/duplicate_softer_press.png - ../shared_gui_components/images/duplicate_softer_press@2x.png - ../shared_gui_components/images/energyplus_measure_icon.png - ../shared_gui_components/images/energyplus_measure_icon@2x.png - ../shared_gui_components/images/energyplus_measure_icon_Python.png - ../shared_gui_components/images/energyplus_measure_icon_Python@2x.png - ../shared_gui_components/images/energyplus_measure_icon_Ruby.png - ../shared_gui_components/images/energyplus_measure_icon_Ruby@2x.png - ../shared_gui_components/images/error-alert.png - ../shared_gui_components/images/error-alert@2x.png - ../shared_gui_components/images/fast_forward.png - ../shared_gui_components/images/fast_forward@2x.png - ../shared_gui_components/images/fast_reverse.png - ../shared_gui_components/images/fast_reverse@2x.png - ../shared_gui_components/images/forward.png - ../shared_gui_components/images/forward@2x.png - ../shared_gui_components/images/gray_add_icon.png - ../shared_gui_components/images/gray_add_icon@2x.png - ../shared_gui_components/images/launch_aws.png - ../shared_gui_components/images/launch_aws@2x.png - ../shared_gui_components/images/open_my_measures.png - ../shared_gui_components/images/open_my_measures@2x.png - ../shared_gui_components/images/open_my_measures_press.png - ../shared_gui_components/images/open_my_measures_press@2x.png - ../shared_gui_components/images/openstudio_measure_icon.png - ../shared_gui_components/images/openstudio_measure_icon@2x.png - ../shared_gui_components/images/openstudio_measure_icon_Python.png - ../shared_gui_components/images/openstudio_measure_icon_Python@2x.png - ../shared_gui_components/images/openstudio_measure_icon_Ruby.png - ../shared_gui_components/images/openstudio_measure_icon_Ruby@2x.png - ../shared_gui_components/images/partially_checked_checkbox.png - ../shared_gui_components/images/partially_checked_checkbox@2x.png - ../shared_gui_components/images/partially_checked_checkbox_locked.png - ../shared_gui_components/images/partially_checked_checkbox_locked@2x.png - ../shared_gui_components/images/partially_checked_checkbox_update_available.png - ../shared_gui_components/images/partially_checked_checkbox_update_available@2x.png - ../shared_gui_components/images/pause_over.png - ../shared_gui_components/images/pause_over@2x.png - ../shared_gui_components/images/pause_press.png - ../shared_gui_components/images/pause_press@2x.png - ../shared_gui_components/images/pause_regular.png - ../shared_gui_components/images/pause_regular@2x.png - ../shared_gui_components/images/report_measure_icon.png - ../shared_gui_components/images/report_measure_icon@2x.png - ../shared_gui_components/images/report_measure_icon_Python.png - ../shared_gui_components/images/report_measure_icon_Python@2x.png - ../shared_gui_components/images/report_measure_icon_Ruby.png - ../shared_gui_components/images/report_measure_icon_Ruby@2x.png - ../shared_gui_components/images/reverse.png - ../shared_gui_components/images/reverse@2x.png - ../shared_gui_components/images/rotating_arrow.png - ../shared_gui_components/images/rotating_arrow@2x.png - ../shared_gui_components/images/run_cancel.png - ../shared_gui_components/images/run_cancel@2x.png - ../shared_gui_components/images/run_cancel_over.png - ../shared_gui_components/images/run_cancel_over@2x.png - ../shared_gui_components/images/run_cancel_press.png - ../shared_gui_components/images/run_cancel_press@2x.png - ../shared_gui_components/images/run_simulation_button.png - ../shared_gui_components/images/run_simulation_button@2x.png - ../shared_gui_components/images/run_simulation_button_disabled.png - ../shared_gui_components/images/run_simulation_button_disabled@2x.png - ../shared_gui_components/images/run_simulation_over.png - ../shared_gui_components/images/run_simulation_over@2x.png - ../shared_gui_components/images/run_simulation_press.png - ../shared_gui_components/images/run_simulation_press@2x.png - ../shared_gui_components/images/searchbox_magnifyingglass.png - ../shared_gui_components/images/searchbox_magnifyingglass@2x.png - ../shared_gui_components/images/starting_simulation_button.png - ../shared_gui_components/images/starting_simulation_button@2x.png - ../shared_gui_components/images/stopping_simulation_button.png - ../shared_gui_components/images/stopping_simulation_button@2x.png - ../shared_gui_components/images/toggle_arrow.png - ../shared_gui_components/images/toggle_arrow@2x.png - ../shared_gui_components/images/toggle_arrow_closed.png - ../shared_gui_components/images/toggle_arrow_closed@2x.png - ../shared_gui_components/images/warning_icon.png - ../shared_gui_components/images/warning_icon@2x.png - ../shared_gui_components/images/unchecked_checkbox.png - ../shared_gui_components/images/unchecked_checkbox@2x.png - ../shared_gui_components/images/unchecked_checkbox_focused.png - ../shared_gui_components/images/unchecked_checkbox_focused@2x.png - ../shared_gui_components/images/unchecked_checkbox_green.png - ../shared_gui_components/images/unchecked_checkbox_green@2x.png - ../shared_gui_components/images/unchecked_checkbox_locked.png - ../shared_gui_components/images/unchecked_checkbox_locked@2x.png - ../shared_gui_components/images/unchecked_checkbox_update_available.png - ../shared_gui_components/images/unchecked_checkbox_update_available@2x.png - ../shared_gui_components/images/check_for_updates.png - ../shared_gui_components/images/check_for_updates@2x.png - - ../shared_gui_components/taxonomy.xml - fonts/Muli-Regular.ttf diff --git a/src/openstudio_lib/openstudiolib.qss b/src/openstudio_lib/openstudiolib.qss index fa0a5de45..172cb8464 100644 --- a/src/openstudio_lib/openstudiolib.qss +++ b/src/openstudio_lib/openstudiolib.qss @@ -3,6 +3,46 @@ QAbstractItemView { background: #E6E6E6; } +QMenuBar { + background-color: #F0F0F0; + color: #000000; +} + +QMenuBar::item { + background-color: transparent; + padding: 4px 8px; +} + +QMenuBar::item:selected { + background-color: #D0D0D0; +} + +QMenuBar::item:pressed { + background-color: #C0C0C0; +} + +QMenu { + background-color: #F0F0F0; + color: #000000; + border: 1px solid #B0B0B0; +} + +QMenu::item:selected { + background-color: #0078D4; + color: #FFFFFF; +} + +QMenu::item:disabled { + color: #808080; +} + +QMenu::separator { + height: 1px; + background: #C0C0C0; + margin: 2px 4px; +} + + QCheckBox::indicator { width: 15px; height: 15px; } diff --git a/src/openstudio_lib/test/OpenStudioLibFixture.cpp b/src/openstudio_lib/test/OpenStudioLibFixture.cpp index 9c6a928db..636906b79 100644 --- a/src/openstudio_lib/test/OpenStudioLibFixture.cpp +++ b/src/openstudio_lib/test/OpenStudioLibFixture.cpp @@ -28,6 +28,7 @@ boost::optional OpenStudioLibFixture::logFile; int main(int argc, char* argv[]) { Q_INIT_RESOURCE(openstudio); + Q_INIT_RESOURCE(openstudio_shared_gui); auto app = openstudio::Application::instance().application(true); QTimer::singleShot(0, [&]() { diff --git a/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp b/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp index c4a4f5f4f..91f4a5d5c 100644 --- a/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp +++ b/src/openstudio_lib/test/SpacesSurfaces_Benchmark.cpp @@ -22,6 +22,7 @@ using namespace openstudio::model; int main(int argc, char* argv[]) { Q_INIT_RESOURCE(openstudio); + Q_INIT_RESOURCE(openstudio_shared_gui); auto app = openstudio::Application::instance().application(true); QTimer::singleShot(0, [&]() { diff --git a/src/openstudio_qt_utils/CMakeLists.txt b/src/openstudio_qt_utils/CMakeLists.txt index c6fad6409..d93b040ca 100644 --- a/src/openstudio_qt_utils/CMakeLists.txt +++ b/src/openstudio_qt_utils/CMakeLists.txt @@ -9,13 +9,21 @@ set(${target_name}_src Application.cpp OSProgressBar.hpp OSProgressBar.cpp + PathWatcher.hpp + PathWatcher.cpp QMetaTypes.hpp QMetaTypes.cpp Utilities.hpp Utilities.cpp ) -add_library(${target_name} STATIC ${${target_name}_src}) +set(${target_name}_moc + PathWatcher.hpp +) + +qt6_wrap_cpp(${target_name}_mocs ${${target_name}_moc}) + +add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_mocs}) set(${target_name}_depends openstudioapp_utilities @@ -25,3 +33,15 @@ set(${target_name}_depends target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) CREATE_SRC_GROUPS("${${target_name}_src}") + +set(${target_name}_test_src + test/QtUtilsFixture.hpp + test/QtUtilsFixture.cpp + test/PathWatcher_GTest.cpp +) + +set(${target_name}_test_depends + ${${target_name}_depends} +) + +CREATE_TEST_TARGETS(${target_name} "${${target_name}_test_src}" "${${target_name}_test_depends}") diff --git a/src/model_editor/PathWatcher.cpp b/src/openstudio_qt_utils/PathWatcher.cpp similarity index 97% rename from src/model_editor/PathWatcher.cpp rename to src/openstudio_qt_utils/PathWatcher.cpp index 6cfc0a345..ec5f274a1 100644 --- a/src/model_editor/PathWatcher.cpp +++ b/src/openstudio_qt_utils/PathWatcher.cpp @@ -4,9 +4,9 @@ ***********************************************************************************************************************/ #include "PathWatcher.hpp" -#include "../openstudio_qt_utils/Application.hpp" +#include "Application.hpp" -#include "../openstudio_qt_utils/Utilities.hpp" +#include "Utilities.hpp" #include #include diff --git a/src/model_editor/PathWatcher.hpp b/src/openstudio_qt_utils/PathWatcher.hpp similarity index 100% rename from src/model_editor/PathWatcher.hpp rename to src/openstudio_qt_utils/PathWatcher.hpp diff --git a/src/model_editor/test/PathWatcher_GTest.cpp b/src/openstudio_qt_utils/test/PathWatcher_GTest.cpp similarity index 95% rename from src/model_editor/test/PathWatcher_GTest.cpp rename to src/openstudio_qt_utils/test/PathWatcher_GTest.cpp index 2573c094e..7ade56e09 100644 --- a/src/model_editor/test/PathWatcher_GTest.cpp +++ b/src/openstudio_qt_utils/test/PathWatcher_GTest.cpp @@ -7,10 +7,10 @@ #include -#include "ModelEditorFixture.hpp" +#include "QtUtilsFixture.hpp" #include "../PathWatcher.hpp" -#include "../../openstudio_qt_utils/Application.hpp" +#include "../Application.hpp" #include #include @@ -57,7 +57,7 @@ void remove_file(const openstudio::path& path) { openstudio::filesystem::remove(path); } -TEST_F(ModelEditorFixture, PathWatcher_File) { +TEST_F(QtUtilsFixture, PathWatcher_File) { Application::instance().application(false); openstudio::path path = toPath("./PathWatcher_File"); diff --git a/src/openstudio_qt_utils/test/QtUtilsFixture.cpp b/src/openstudio_qt_utils/test/QtUtilsFixture.cpp new file mode 100644 index 000000000..82d65ac1f --- /dev/null +++ b/src/openstudio_qt_utils/test/QtUtilsFixture.cpp @@ -0,0 +1,28 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#include "QtUtilsFixture.hpp" +#include "../Application.hpp" + +#include + +int main(int argc, char* argv[]) { + auto app = openstudio::Application::instance().application(true); + + QTimer::singleShot(0, [&]() { + ::testing::InitGoogleTest(&argc, argv); + auto testResult = RUN_ALL_TESTS(); + app->exit(testResult); + }); + + return app->exec(); +} + +void QtUtilsFixture::SetUp() {} +void QtUtilsFixture::TearDown() {} +void QtUtilsFixture::SetUpTestCase() {} +void QtUtilsFixture::TearDownTestCase() {} + +boost::optional QtUtilsFixture::logFile; diff --git a/src/openstudio_qt_utils/test/QtUtilsFixture.hpp b/src/openstudio_qt_utils/test/QtUtilsFixture.hpp new file mode 100644 index 000000000..48b1c83bb --- /dev/null +++ b/src/openstudio_qt_utils/test/QtUtilsFixture.hpp @@ -0,0 +1,27 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef OPENSTUDIO_QT_UTILS_TEST_QTUTILSFIXTURE_HPP +#define OPENSTUDIO_QT_UTILS_TEST_QTUTILSFIXTURE_HPP + +#include + +#include +#include + +class QtUtilsFixture : public ::testing::Test +{ + protected: + virtual void SetUp() override; + virtual void TearDown() override; + + static void SetUpTestCase(); + static void TearDownTestCase(); + + REGISTER_LOGGER("QtUtilsFixture"); + static boost::optional logFile; +}; + +#endif // OPENSTUDIO_QT_UTILS_TEST_QTUTILSFIXTURE_HPP diff --git a/src/shared_gui_components/BaseApp.hpp b/src/shared_gui_components/BaseApp.hpp index af0260e22..b5917c91e 100644 --- a/src/shared_gui_components/BaseApp.hpp +++ b/src/shared_gui_components/BaseApp.hpp @@ -89,6 +89,12 @@ class BaseApp return false; } + /// Disable the document UI (e.g. while a drop operation is in progress). + virtual void disableDocument() {} + + /// Re-enable the document UI after a disable call. + virtual void enableDocument() {} + /// BCL document queries — default implementations return empty/none for contexts without a document. virtual boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const { return boost::none; diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index bd440a324..60f35b292 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -183,11 +183,14 @@ set(${target_name}_moc ## Qt MOC generation qt6_wrap_cpp(${target_name}_moc_src ${${target_name}_moc}) +set(${target_name}_qrc openstudio_shared_gui.qrc) +qt6_add_resources(${target_name}_qrcs ${${target_name}_qrc}) + set(${target_name}_depends openstudio_qt_utils ) -add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_moc_src}) +add_library(${target_name} STATIC ${${target_name}_src} ${${target_name}_moc_src} ${${target_name}_qrcs}) target_link_libraries(${target_name} PUBLIC ${${target_name}_depends}) diff --git a/src/shared_gui_components/LocalLibraryController.cpp b/src/shared_gui_components/LocalLibraryController.cpp index dc67715ac..e6f0cae8e 100644 --- a/src/shared_gui_components/LocalLibraryController.cpp +++ b/src/shared_gui_components/LocalLibraryController.cpp @@ -13,10 +13,7 @@ #include "OSListView.hpp" #include "OSViewSwitcher.hpp" -#include "../openstudio_lib/MainWindow.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" -#include "../openstudio_lib/OSItem.hpp" + #include "MeasureBadge.hpp" @@ -497,8 +494,7 @@ QWidget* LibraryItemDelegate::view(QSharedPointer dataSource) { // Name widget->label->setText(libraryItem->displayName()); - const bool useClassicCLI = - OSAppBase::instance()->currentDocument() == nullptr ? false : OSAppBase::instance()->currentDocument()->mainWindow()->useClassicCLI(); + const bool useClassicCLI = BaseApp::instance() != nullptr && BaseApp::instance()->useClassicCLI(); if (useClassicCLI && (measureLanguage == MeasureLanguage::Python)) { widget->setToolTip("Python Measures are not supported in the Classic CLI.\nYou can change CLI version using 'Preferences->Use Classic CLI'."); widget->errorLabel->setVisible(true); diff --git a/src/shared_gui_components/WorkflowController.cpp b/src/shared_gui_components/WorkflowController.cpp index c8e62bea0..53a4e07d6 100644 --- a/src/shared_gui_components/WorkflowController.cpp +++ b/src/shared_gui_components/WorkflowController.cpp @@ -9,9 +9,7 @@ #include "MeasureManager.hpp" #include "EditController.hpp" #include "BaseApp.hpp" -#include "../openstudio_lib/OSAppBase.hpp" -#include "../openstudio_lib/OSDocument.hpp" -#include "../openstudio_lib/MainWindow.hpp" + #include "LocalLibraryController.hpp" #include "WorkflowTools.hpp" #include "../openstudio_qt_utils/Utilities.hpp" @@ -203,10 +201,9 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { UUID id = measureDragData.id(); - std::shared_ptr document = nullptr; - if (dynamic_cast(m_app)) { - document = dynamic_cast(m_app)->currentDocument(); - document->disable(); + const bool hasDocument = (m_app != nullptr); + if (hasDocument) { + m_app->disableDocument(); } boost::optional projectMeasure; @@ -221,8 +218,8 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { errorMessage += QString::fromStdString(e.what()); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (document) { - document->enable(); + if (hasDocument) { + m_app->enableDocument(); } return; } @@ -232,8 +229,8 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { QString errorMessage("Failed to add measure at this workflow location."); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (document) { - document->enable(); + if (hasDocument) { + m_app->enableDocument(); } return; } @@ -248,8 +245,8 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { errorMessage += QString::fromStdString(e.what()); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (document) { - document->enable(); + if (hasDocument) { + m_app->enableDocument(); } return; } @@ -277,8 +274,8 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { //workflowJSON.save(); - if (document) { - document->enable(); + if (hasDocument) { + m_app->enableDocument(); } emit modelReset(); @@ -573,8 +570,7 @@ QWidget* MeasureStepItemDelegate::view(QSharedPointer dataSource) { connect(measureStepItem.data(), &MeasureStepItem::selectedChanged, workflowStepView->workflowStepButton, &WorkflowStepButton::setHasEmphasis); - const bool useClassicCLI = - OSAppBase::instance()->currentDocument() == nullptr ? false : OSAppBase::instance()->currentDocument()->mainWindow()->useClassicCLI(); + const bool useClassicCLI = BaseApp::instance() != nullptr && BaseApp::instance()->useClassicCLI(); if (useClassicCLI && (measureLanguage == MeasureLanguage::Python)) { workflowStepView->workflowStepButton->errorLabel->setToolTip( "Python Measures are not supported in the Classic CLI.\nYou can change CLI version using 'Preferences->Use Classic CLI'."); diff --git a/src/shared_gui_components/openstudio_shared_gui.qrc b/src/shared_gui_components/openstudio_shared_gui.qrc new file mode 100644 index 000000000..6f399c1d1 --- /dev/null +++ b/src/shared_gui_components/openstudio_shared_gui.qrc @@ -0,0 +1,160 @@ + + + images/add_script_icon.png + images/add_script_icon@2x.png + images/add_script_icon_over.png + images/add_script_icon_over@2x.png + images/add_script_icon_press.png + images/add_script_icon_press@2x.png + images/add_softer_off.png + images/add_softer_off@2x.png + images/add_softer_on.png + images/add_softer_on@2x.png + images/add_softer_press.png + images/add_softer_press@2x.png + images/arrow_down.png + images/arrow_down@2x.png + images/arrow_down_over.png + images/arrow_down_over@2x.png + images/arrow_down_press.png + images/arrow_down_press@2x.png + images/arrow_up.png + images/arrow_up@2x.png + images/arrow_up_over.png + images/arrow_up_over@2x.png + images/arrow_up_press.png + images/arrow_up_press@2x.png + images/broken_script.png + images/broken_script@2x.png + images/check_for_updates.png + images/check_for_updates@2x.png + images/checked_checkbox.png + images/checked_checkbox@2x.png + images/checked_checkbox_focused.png + images/checked_checkbox_focused@2x.png + images/checked_checkbox_green.png + images/checked_checkbox_green@2x.png + images/checked_checkbox_locked.png + images/checked_checkbox_locked@2x.png + images/checked_checkbox_update_available.png + images/checked_checkbox_update_available@2x.png + images/delete_softer.png + images/delete_softer@2x.png + images/delete_softer_over.png + images/delete_softer_over@2x.png + images/delete_softer_press.png + images/delete_softer_press@2x.png + images/dir.png + images/dir@2x.png + images/dir_disabled.png + images/dir_disabled@2x.png + images/dir_press.png + images/dir_press@2x.png + images/duplicate_disabled.png + images/duplicate_disabled@2x.png + images/duplicate_off.png + images/duplicate_off@2x.png + images/duplicate_over.png + images/duplicate_over@2x.png + images/duplicate_press.png + images/duplicate_press@2x.png + images/duplicate_softer_disabled.png + images/duplicate_softer_disabled@2x.png + images/duplicate_softer_off.png + images/duplicate_softer_off@2x.png + images/duplicate_softer_over.png + images/duplicate_softer_over@2x.png + images/duplicate_softer_press.png + images/duplicate_softer_press@2x.png + images/energyplus_measure_icon.png + images/energyplus_measure_icon@2x.png + images/energyplus_measure_icon_Python.png + images/energyplus_measure_icon_Python@2x.png + images/energyplus_measure_icon_Ruby.png + images/energyplus_measure_icon_Ruby@2x.png + images/error-alert.png + images/error-alert@2x.png + images/fast_forward.png + images/fast_forward@2x.png + images/fast_reverse.png + images/fast_reverse@2x.png + images/forward.png + images/forward@2x.png + images/gray_add_icon.png + images/gray_add_icon@2x.png + images/launch_aws.png + images/launch_aws@2x.png + images/manage_all_button.png + images/manage_all_button@2x.png + images/open_my_measures.png + images/open_my_measures@2x.png + images/open_my_measures_press.png + images/open_my_measures_press@2x.png + images/openstudio_measure_icon.png + images/openstudio_measure_icon@2x.png + images/openstudio_measure_icon_Python.png + images/openstudio_measure_icon_Python@2x.png + images/openstudio_measure_icon_Ruby.png + images/openstudio_measure_icon_Ruby@2x.png + images/partially_checked_checkbox.png + images/partially_checked_checkbox@2x.png + images/partially_checked_checkbox_locked.png + images/partially_checked_checkbox_locked@2x.png + images/partially_checked_checkbox_update_available.png + images/partially_checked_checkbox_update_available@2x.png + images/pause_over.png + images/pause_over@2x.png + images/pause_press.png + images/pause_press@2x.png + images/pause_regular.png + images/pause_regular@2x.png + images/report_measure_icon.png + images/report_measure_icon@2x.png + images/report_measure_icon_Python.png + images/report_measure_icon_Python@2x.png + images/report_measure_icon_Ruby.png + images/report_measure_icon_Ruby@2x.png + images/reverse.png + images/reverse@2x.png + images/rotating_arrow.png + images/rotating_arrow@2x.png + images/run_cancel.png + images/run_cancel@2x.png + images/run_cancel_over.png + images/run_cancel_over@2x.png + images/run_cancel_press.png + images/run_cancel_press@2x.png + images/run_simulation_button.png + images/run_simulation_button@2x.png + images/run_simulation_button_disabled.png + images/run_simulation_button_disabled@2x.png + images/run_simulation_over.png + images/run_simulation_over@2x.png + images/run_simulation_press.png + images/run_simulation_press@2x.png + images/searchbox_magnifyingglass.png + images/searchbox_magnifyingglass@2x.png + images/starting_simulation_button.png + images/starting_simulation_button@2x.png + images/stopping_simulation_button.png + images/stopping_simulation_button@2x.png + images/toggle_arrow.png + images/toggle_arrow@2x.png + images/toggle_arrow_closed.png + images/toggle_arrow_closed@2x.png + images/unchecked_checkbox.png + images/unchecked_checkbox@2x.png + images/unchecked_checkbox_focused.png + images/unchecked_checkbox_focused@2x.png + images/unchecked_checkbox_green.png + images/unchecked_checkbox_green@2x.png + images/unchecked_checkbox_locked.png + images/unchecked_checkbox_locked@2x.png + images/unchecked_checkbox_update_available.png + images/unchecked_checkbox_update_available@2x.png + images/warning_icon.png + images/warning_icon@2x.png + + taxonomy.xml + + From 6b62156d5f106ad09b88652699be6abc2805e865 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 07:57:24 -0600 Subject: [PATCH 18/26] Introduce BaseDocument abstract interface in shared_gui_components and move OSItem, OSDropZone, and ModelObjectItem from openstudio_lib into that library, removing the upward dependency. Wire BaseApp::currentDocument() returning BaseDocument* through the hierarchy with a covariant OSDocument* override in OSAppBase/OpenStudioApp, replacing all shared_ptr local variables and member fields with raw pointers. --- .../cpp-refactoring.instructions.md | 41 ++++++ developer/doc/architecture.md | 6 +- developer/doc/libraries/openstudio_lib.md | 8 +- .../doc/libraries/shared_gui_components.md | 26 ++-- src/openstudio_app/OpenStudioApp.cpp | 8 +- src/openstudio_app/OpenStudioApp.hpp | 2 +- src/openstudio_lib/ApplyMeasureNowDialog.cpp | 2 +- src/openstudio_lib/BCLComponentItem.cpp | 2 +- src/openstudio_lib/BCLComponentItem.hpp | 2 +- src/openstudio_lib/BuildingInspectorView.cpp | 4 +- src/openstudio_lib/CMakeLists.txt | 9 -- .../ConstructionAirBoundaryInspectorView.cpp | 2 +- ...ionCfactorUndergroundWallInspectorView.cpp | 2 +- ...ructionFfactorGroundFloorInspectorView.cpp | 2 +- .../ConstructionInspectorView.cpp | 4 +- ...onstructionInternalSourceInspectorView.cpp | 4 +- .../ConstructionObjectVectorController.cpp | 2 +- .../DefaultConstructionSetInspectorView.cpp | 4 +- src/openstudio_lib/DesignDayGridView.cpp | 4 +- src/openstudio_lib/DesignDayGridView.hpp | 2 +- .../ElectricEquipmentInspectorView.cpp | 2 +- .../FacilityExteriorEquipmentGridView.hpp | 2 +- .../FacilityShadingGridView.cpp | 2 +- .../FacilityShadingGridView.hpp | 2 +- .../FacilityStoriesGridView.cpp | 2 +- .../FacilityStoriesGridView.hpp | 2 +- .../GasEquipmentInspectorView.cpp | 2 +- src/openstudio_lib/GeometryEditorView.cpp | 4 +- src/openstudio_lib/GeometryEditorView.hpp | 4 +- src/openstudio_lib/GeometryPreviewView.cpp | 2 +- src/openstudio_lib/GeometryPreviewView.hpp | 2 +- src/openstudio_lib/GridItem.cpp | 6 +- src/openstudio_lib/GridItem.hpp | 2 +- src/openstudio_lib/GridScene.hpp | 2 +- src/openstudio_lib/GridViewSubTab.cpp | 2 +- src/openstudio_lib/GridViewSubTab.hpp | 2 +- src/openstudio_lib/HVACSystemsController.hpp | 6 +- src/openstudio_lib/HVACSystemsView.cpp | 6 +- .../HotWaterEquipmentInspectorView.cpp | 2 +- src/openstudio_lib/InspectorView.cpp | 8 +- .../InternalMassInspectorView.cpp | 4 +- src/openstudio_lib/LightsInspectorView.cpp | 2 +- src/openstudio_lib/LocationTabView.cpp | 2 +- src/openstudio_lib/LoopScene.hpp | 2 +- src/openstudio_lib/LuminaireInspectorView.cpp | 2 +- .../MainRightColumnController.cpp | 34 ++--- .../MainRightColumnController.hpp | 2 +- src/openstudio_lib/MaterialInspectorView.cpp | 2 +- .../ModelObjectInspectorView.cpp | 2 +- src/openstudio_lib/ModelObjectListView.cpp | 2 +- src/openstudio_lib/ModelObjectTreeItems.cpp | 2 +- src/openstudio_lib/ModelObjectTreeItems.hpp | 2 +- .../ModelObjectTypeListView.cpp | 4 +- src/openstudio_lib/ModelSubTabController.cpp | 2 +- src/openstudio_lib/ModelSubTabView.cpp | 4 +- src/openstudio_lib/OSAppBase.cpp | 64 +++++--- src/openstudio_lib/OSAppBase.hpp | 20 ++- src/openstudio_lib/OSCollapsibleItem.hpp | 2 +- .../OSCollapsibleItemHeader.cpp | 2 +- .../OSCollapsibleItemHeader.hpp | 2 +- src/openstudio_lib/OSCollapsibleItemList.cpp | 2 +- src/openstudio_lib/OSCollapsibleItemList.hpp | 2 +- src/openstudio_lib/OSDocument.cpp | 2 +- src/openstudio_lib/OSDocument.hpp | 118 ++++++--------- src/openstudio_lib/OSInspectorView.cpp | 2 +- src/openstudio_lib/OSItemList.hpp | 2 +- src/openstudio_lib/OSItemSelector.cpp | 2 +- src/openstudio_lib/OSItemSelectorButtons.cpp | 4 +- .../OtherEquipmentInspectorView.cpp | 2 +- .../RefrigerationController.cpp | 26 ++-- .../RefrigerationGraphicsItems.cpp | 2 +- .../RefrigerationGraphicsItems.hpp | 4 +- src/openstudio_lib/RefrigerationGridView.cpp | 2 +- src/openstudio_lib/RefrigerationGridView.hpp | 2 +- src/openstudio_lib/RunTabView.cpp | 4 +- src/openstudio_lib/ScheduleDayView.cpp | 2 +- .../ScheduleSetInspectorView.cpp | 4 +- src/openstudio_lib/ScheduleSetsView.cpp | 2 +- src/openstudio_lib/SchedulesTabController.cpp | 2 +- src/openstudio_lib/SchedulesView.cpp | 2 +- src/openstudio_lib/ScriptItem.cpp | 2 +- src/openstudio_lib/ScriptItem.hpp | 2 +- src/openstudio_lib/ServiceWaterGridItems.hpp | 2 +- src/openstudio_lib/ServiceWaterScene.hpp | 2 +- .../SiteWaterMainsTemperatureWidget.cpp | 4 +- .../SpaceLoadInstancesWidget.cpp | 4 +- src/openstudio_lib/SpaceTypesGridView.cpp | 4 +- src/openstudio_lib/SpaceTypesGridView.hpp | 2 +- .../SpaceTypesTabController.cpp | 2 +- src/openstudio_lib/SpaceTypesView.cpp | 4 +- .../SpacesDaylightingGridView.cpp | 2 +- .../SpacesDaylightingGridView.hpp | 2 +- .../SpacesInteriorPartitionsGridView.cpp | 2 +- .../SpacesInteriorPartitionsGridView.hpp | 2 +- src/openstudio_lib/SpacesLoadsGridView.cpp | 2 +- src/openstudio_lib/SpacesLoadsGridView.hpp | 2 +- src/openstudio_lib/SpacesShadingGridView.cpp | 2 +- src/openstudio_lib/SpacesShadingGridView.hpp | 2 +- src/openstudio_lib/SpacesSpacesGridView.cpp | 2 +- src/openstudio_lib/SpacesSpacesGridView.hpp | 2 +- .../SpacesSubsurfacesGridView.cpp | 2 +- .../SpacesSubsurfacesGridView.hpp | 2 +- src/openstudio_lib/SpacesSubtabGridView.hpp | 2 +- src/openstudio_lib/SpacesSurfacesGridView.cpp | 2 +- src/openstudio_lib/SpacesSurfacesGridView.hpp | 2 +- ...StandardsInformationConstructionWidget.cpp | 2 +- .../StandardsInformationMaterialWidget.cpp | 2 +- .../SteamEquipmentInspectorView.cpp | 2 +- src/openstudio_lib/SubTabController.cpp | 2 +- src/openstudio_lib/SubTabView.cpp | 2 +- src/openstudio_lib/ThermalZonesController.cpp | 2 +- src/openstudio_lib/ThermalZonesGridView.cpp | 4 +- src/openstudio_lib/ThermalZonesGridView.hpp | 2 +- .../ThermalZonesTabController.cpp | 2 +- .../UtilityBillAllFuelTypesListView.cpp | 4 +- .../UtilityBillFuelTypeListView.cpp | 2 +- src/openstudio_lib/UtilityBillsView.cpp | 8 +- src/openstudio_lib/VRFController.cpp | 20 +-- src/openstudio_lib/VRFGraphicsItems.cpp | 4 +- src/openstudio_lib/VRFGraphicsItems.hpp | 4 +- .../WaterUseEquipmentInspectorView.cpp | 4 +- src/openstudio_lib/YearSettingsWidget.cpp | 2 +- src/openstudio_lib/test/OSDropZone_GTest.cpp | 4 +- .../test/OpenStudioLibFixture.cpp | 2 +- src/shared_gui_components/BaseApp.hpp | 67 ++++----- src/shared_gui_components/BaseDocument.hpp | 102 +++++++++++++ src/shared_gui_components/CMakeLists.txt | 11 ++ .../LocalLibraryController.cpp | 2 - .../ModelObjectItem.cpp | 12 +- .../ModelObjectItem.hpp | 0 src/shared_gui_components/OSCellWrapper.cpp | 2 +- .../OSDropZone.cpp | 35 +++-- .../OSDropZone.hpp | 2 +- .../OSGridController.cpp | 4 +- src/shared_gui_components/OSGridView.cpp | 2 +- .../OSItem.cpp | 138 +++--------------- .../OSItem.hpp | 4 +- src/shared_gui_components/OSItemId.cpp | 88 +++++++++++ src/shared_gui_components/OSLineEdit.cpp | 4 +- src/shared_gui_components/OSWidgetHolder.cpp | 2 +- 140 files changed, 638 insertions(+), 513 deletions(-) create mode 100644 .github/instructions/cpp-refactoring.instructions.md create mode 100644 src/shared_gui_components/BaseDocument.hpp rename src/{openstudio_lib => shared_gui_components}/ModelObjectItem.cpp (97%) rename src/{openstudio_lib => shared_gui_components}/ModelObjectItem.hpp (100%) rename src/{openstudio_lib => shared_gui_components}/OSDropZone.cpp (96%) rename src/{openstudio_lib => shared_gui_components}/OSDropZone.hpp (99%) rename src/{openstudio_lib => shared_gui_components}/OSItem.cpp (76%) rename src/{openstudio_lib => shared_gui_components}/OSItem.hpp (97%) create mode 100644 src/shared_gui_components/OSItemId.cpp diff --git a/.github/instructions/cpp-refactoring.instructions.md b/.github/instructions/cpp-refactoring.instructions.md new file mode 100644 index 000000000..700f6935b --- /dev/null +++ b/.github/instructions/cpp-refactoring.instructions.md @@ -0,0 +1,41 @@ +--- +description: "Use when moving, renaming, or refactoring C++ classes in src/. Covers include order, git mv, shared_ptr vs raw pointer, and C++ covariance rules." +applyTo: "src/**/*.cpp,src/**/*.hpp,src/**/CMakeLists.txt" +--- + +# C++ Refactoring Guidelines + +## Include Order + +Within every `.cpp` and `.hpp`, includes must appear in this order, with a blank line between each group: + +```cpp +// 1. Own header (in .cpp only — the header this .cpp implements) +#include "ThisClass.hpp" + +// 2. Same-directory relative includes +#include "Sibling.hpp" + +// 3. Cross-directory repo includes +#include "../other_module/Foo.hpp" + +// 4. OpenStudio SDK includes +#include + +// 5. Qt, Boost, and system includes +#include +#include +#include +``` + +Do not mix groups. When adding a new include, place it in the correct group in the same edit — not as a deferred cleanup. + +--- + +## Naming + +When introducing an interface method, choose its name before writing any code: + +- Prefer names that describe the *concept*, not the return type (`currentDocument`, not `currentBaseDocument`). +- Check for name collisions with existing virtuals in the inheritance chain before committing. +- A rename that touches 100+ files is expensive; settle the name at design time. diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index c26ef20f1..963481537 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -265,13 +265,11 @@ OpenStudioApp (exe) → openstudio_qt_utils ``` -**The `BaseApp` interface** (`shared_gui_components/BaseApp.hpp`) is the key boundary between the lower-level `shared_gui_components` library and the upper-level `openstudio_lib` library. All `shared_gui_components` code that needs application-level services must go through `BaseApp`, never through `OSAppBase`, `OSDocument`, or `MainWindow` directly. +**The `BaseApp` interface** (`shared_gui_components/BaseApp.hpp`) is the key boundary between the lower-level `shared_gui_components` library and the upper-level `openstudio_lib` library. All `shared_gui_components` code that needs application-level services must go through `BaseApp`, never through `OSAppBase`, `OSDocument`, or `MainWindow` directly. Code that needs document-level services (icon lookup, model-object resolution, drop handling) calls `BaseApp::currentDocument()`, which returns a `BaseDocument*` — another interface in `shared_gui_components` implemented by `OSDocument` in `openstudio_lib`. C++ raw pointer covariance means `OSAppBase::currentDocument()` can override `BaseApp::currentDocument()` while returning the more-derived `OSDocument*`, so a single virtual serves both caller audiences. **Known violations (tracked as tech debt):** -| Violation | Location | Correct Fix | -|---|---|---| -| `OSItem`, `OSDropZone`, `ModelObjectItem` live in `openstudio_lib` but are included by `shared_gui_components` code (`OSCellWrapper`, `OSGridView`, `OSWidgetHolder`, `OSLineEdit`, `OSGridController`, `LocalLibraryController`) | `src/openstudio_lib/OSItem.hpp`, `OSDropZone.hpp`, `ModelObjectItem.hpp` | Move these three classes to `shared_gui_components`; they have no `openstudio_lib`-only dependencies. `OSItem` depends only on `OSItemId` and `LocalLibrary.hpp`, both already in `shared_gui_components`. | +None. All boundary violations have been resolved. --- diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index c2dca3f16..0701b6919 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -18,7 +18,7 @@ The module follows a consistent **Controller / View / Inspector triad** per doma classDiagram class OSAppBase { <> - +currentDocument() OSDocument* = 0 + +currentDocument() OSDocument* +measureManager() MeasureManager& +instance() OSAppBase* signals: workspaceObjectAdded, workspaceObjectRemoved @@ -97,16 +97,12 @@ classDiagram | Class | Description | |---|---| -| `OSItem` | Base class for all draggable/selectable model object items | -| `OSDropZone` | Widget that accepts model object drops | | `OSItemList` / `OSCollapsibleItem` | Container widgets for ordered lists of `OSItem`s | | `ModelObjectListView` | Generic list view displaying any collection of model objects | | `ModelObjectTreeWidget` | Generic tree view for hierarchical model data | | `OSWebEnginePage` | `QWebEnginePage` subclass for the geometry JS bridge | -> **Note:** `OSVectorController`, `IconLibrary` have moved to `shared_gui_components`. -> -> **Boundary note:** `OSItem`, `OSDropZone`, and `ModelObjectItem` are currently in `openstudio_lib` for historical reasons, but `shared_gui_components` code (`OSCellWrapper`, `OSGridView`, `OSWidgetHolder`, `OSLineEdit`, `OSGridController`, `LocalLibraryController`) includes them via backward cross-library `#include` paths. These three classes should be moved to `shared_gui_components` in a future refactor — none of them have dependencies that would prevent the move. +> **Note:** `OSVectorController`, `IconLibrary`, `OSItem`, `OSDropZone`, `ModelObjectItem`, and `OSItemId` have all moved to `shared_gui_components`. --- diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 253e6b662..6297a3ef4 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -30,6 +30,16 @@ classDiagram +openBclDlg() = 0 +tempDir() optional~path~ = 0 +currentModel() optional~Model~ = 0 + +currentDocument() BaseDocument* + +makeItem(itemId, type) OSItem* + } + class BaseDocument { + <> + +fromBCL(itemId) bool = 0 + +fromComponentLibrary(itemId) bool = 0 + +getIddObjectType(itemId) optional~IddObjectType~ = 0 + +getModelObject(itemId) optional~ModelObject~ = 0 + +getComponent(itemId) optional~Component~ = 0 } class MeasureManager { +url() QUrl @@ -67,6 +77,7 @@ classDiagram } BaseApp <|.. OSAppBase : implements + BaseApp --> BaseDocument : currentDocument() MeasureManager --> BaseApp : uses OSGridView --> OSGridController : owned by LocalLibraryController --> MeasureManager : uses @@ -109,7 +120,7 @@ All typed input widgets follow the same pattern: they read from and write to a ` | `OSQuantityEdit` / `OSQuantityEdit2` | Dimensional quantity editor with SI/IP toggle | | `OSOptionalQuantityEdit` | Optional dimensional quantity (blank = unset) | -> **Note:** `OSVectorController`, `OSItemId`, `IconLibrary`, and `UserSettings` are now part of `shared_gui_components` (previously in `openstudio_lib` or `model_editor`). +> **Note:** `OSVectorController`, `OSItemId`, `IconLibrary`, `UserSettings`, `OSItem`, `OSDropZone`, and `ModelObjectItem` are now fully in `shared_gui_components` (previously in `openstudio_lib` or `model_editor`). All document/app operations are routed through `BaseApp` virtual methods. The `2` suffix variants use `std::function` callbacks instead of `QObject` signal/slot; they are preferred in newer code. @@ -161,18 +172,7 @@ flowchart TD ## Known Boundary Violations -The following files in `shared_gui_components` currently include headers from `openstudio_lib`, which is a **higher-level** library and violates the intended dependency order. These are tracked as tech debt: - -| File | Bad include | Notes | -|---|---|---| -| `OSCellWrapper.cpp` | `../openstudio_lib/OSDropZone.hpp` | `OSDropZone` should move to `shared_gui_components` | -| `OSGridView.cpp` | `../openstudio_lib/OSDropZone.hpp` | Same as above | -| `OSWidgetHolder.cpp` | `../openstudio_lib/OSDropZone.hpp` | Same as above | -| `OSLineEdit.cpp` | `../openstudio_lib/OSItem.hpp`, `ModelObjectItem.hpp` | `OSItem` and `ModelObjectItem` should move to `shared_gui_components` | -| `OSGridController.cpp` | `../openstudio_lib/OSItem.hpp`, `ModelObjectItem.hpp` | Same as above | -| `LocalLibraryController.cpp` | `../openstudio_lib/OSItem.hpp` | Should use `OSItem` once it moves to `shared_gui_components` | - -The correct resolution is to move `OSItem`, `OSDropZone`, and `ModelObjectItem` to `shared_gui_components` (all three have no `openstudio_lib`-only dependencies). +None. All cross-library includes have been resolved. `OSItem`, `OSDropZone`, and `ModelObjectItem` are fully in `shared_gui_components`; their former dependencies on `OSAppBase`/`OSDocument` are now routed through `BaseApp` virtual methods. --- diff --git a/src/openstudio_app/OpenStudioApp.cpp b/src/openstudio_app/OpenStudioApp.cpp index 8d6230dc9..9c7fdd47b 100644 --- a/src/openstudio_app/OpenStudioApp.cpp +++ b/src/openstudio_app/OpenStudioApp.cpp @@ -462,8 +462,8 @@ void OpenStudioApp::newFromTemplateSlot(NewFromTemplateEnum newFromTemplateEnum) waitDialog()->hide(); } -std::shared_ptr OpenStudioApp::currentDocument() const { - return m_osDocument; +OSDocument* OpenStudioApp::currentDocument() const { + return m_osDocument.get(); } void OpenStudioApp::importIdf() { @@ -979,7 +979,9 @@ void OpenStudioApp::showAbout() { } QString details = tr("Measure Manager Server: ") + measureManager().url().toString() + "\n"; details += tr("Chrome Debugger: http://localhost:") + qgetenv("QTWEBENGINE_REMOTE_DEBUGGING") + "\n"; - details += tr("Temp Directory: ") + currentDocument()->modelTempDir(); + if (currentDocument()) { + details += tr("Temp Directory: ") + currentDocument()->modelTempDir(); + } QMessageBox about(parent); about.setText(OPENSTUDIOAPP_ABOUTBOX); about.setDetailedText(details); diff --git a/src/openstudio_app/OpenStudioApp.hpp b/src/openstudio_app/OpenStudioApp.hpp index 3e4989a56..da87d057d 100644 --- a/src/openstudio_app/OpenStudioApp.hpp +++ b/src/openstudio_app/OpenStudioApp.hpp @@ -86,7 +86,7 @@ class OpenStudioApp : public OSAppBase virtual ~OpenStudioApp(); - virtual std::shared_ptr currentDocument() const override; + virtual OSDocument* currentDocument() const override; static OpenStudioApp* instance(); diff --git a/src/openstudio_lib/ApplyMeasureNowDialog.cpp b/src/openstudio_lib/ApplyMeasureNowDialog.cpp index 23014e022..2e94814cd 100644 --- a/src/openstudio_lib/ApplyMeasureNowDialog.cpp +++ b/src/openstudio_lib/ApplyMeasureNowDialog.cpp @@ -19,7 +19,7 @@ #include "OSAppBase.hpp" #include "OSDocument.hpp" #include "MainWindow.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/openstudio_lib/BCLComponentItem.cpp b/src/openstudio_lib/BCLComponentItem.cpp index 3724c0bff..9d28b5dbe 100644 --- a/src/openstudio_lib/BCLComponentItem.cpp +++ b/src/openstudio_lib/BCLComponentItem.cpp @@ -5,7 +5,7 @@ #include "BCLComponentItem.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/MeasureBadge.hpp" diff --git a/src/openstudio_lib/BCLComponentItem.hpp b/src/openstudio_lib/BCLComponentItem.hpp index 6e2c7dc1a..3171c4bab 100644 --- a/src/openstudio_lib/BCLComponentItem.hpp +++ b/src/openstudio_lib/BCLComponentItem.hpp @@ -6,7 +6,7 @@ #ifndef OPENSTUDIO_BCLCOMPONENTITEM_HPP #define OPENSTUDIO_BCLCOMPONENTITEM_HPP -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include namespace openstudio { diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index 402d090b4..5e39db7ed 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -11,8 +11,8 @@ #include "../shared_gui_components/OSQuantityEdit.hpp" #include "../shared_gui_components/OSSwitch.hpp" -#include "ModelObjectItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSVectorController.hpp" #include "../openstudio_qt_utils/Utilities.hpp" diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 56e0c2769..a01c81dd5 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -163,8 +163,6 @@ set(${target_name}_SRC MaterialsView.hpp ModelObjectInspectorView.cpp ModelObjectInspectorView.hpp - ModelObjectItem.cpp - ModelObjectItem.hpp ModelObjectListView.cpp ModelObjectListView.hpp ModelObjectTreeItems.cpp @@ -193,12 +191,8 @@ set(${target_name}_SRC OSCollapsibleItemList.hpp OSDocument.cpp OSDocument.hpp - OSDropZone.cpp - OSDropZone.hpp OSInspectorView.cpp OSInspectorView.hpp - OSItem.cpp - OSItem.hpp OSItemList.cpp OSItemList.hpp OSItemSelector.cpp @@ -468,7 +462,6 @@ set(${target_name}_moc MaterialsController.hpp MaterialsView.hpp ModelObjectInspectorView.hpp - ModelObjectItem.hpp ModelObjectListView.hpp ModelObjectTreeItems.hpp ModelObjectTreeWidget.hpp @@ -483,9 +476,7 @@ set(${target_name}_moc OSCollapsibleItemHeader.hpp OSCollapsibleItemList.hpp OSDocument.hpp - OSDropZone.hpp OSInspectorView.hpp - OSItem.hpp OSItemList.hpp OSItemSelector.hpp OSItemSelectorButtons.hpp diff --git a/src/openstudio_lib/ConstructionAirBoundaryInspectorView.cpp b/src/openstudio_lib/ConstructionAirBoundaryInspectorView.cpp index e1addd08d..da80f1b3d 100644 --- a/src/openstudio_lib/ConstructionAirBoundaryInspectorView.cpp +++ b/src/openstudio_lib/ConstructionAirBoundaryInspectorView.cpp @@ -6,7 +6,7 @@ #include "ConstructionAirBoundaryInspectorView.hpp" #include "StandardsInformationConstructionWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" diff --git a/src/openstudio_lib/ConstructionCfactorUndergroundWallInspectorView.cpp b/src/openstudio_lib/ConstructionCfactorUndergroundWallInspectorView.cpp index c5053bfc2..7f85bf5de 100644 --- a/src/openstudio_lib/ConstructionCfactorUndergroundWallInspectorView.cpp +++ b/src/openstudio_lib/ConstructionCfactorUndergroundWallInspectorView.cpp @@ -6,7 +6,7 @@ #include "ConstructionCfactorUndergroundWallInspectorView.hpp" #include "StandardsInformationConstructionWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" diff --git a/src/openstudio_lib/ConstructionFfactorGroundFloorInspectorView.cpp b/src/openstudio_lib/ConstructionFfactorGroundFloorInspectorView.cpp index 7a6203510..649dc2ee5 100644 --- a/src/openstudio_lib/ConstructionFfactorGroundFloorInspectorView.cpp +++ b/src/openstudio_lib/ConstructionFfactorGroundFloorInspectorView.cpp @@ -5,7 +5,7 @@ #include "ConstructionFfactorGroundFloorInspectorView.hpp" #include "StandardsInformationConstructionWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" diff --git a/src/openstudio_lib/ConstructionInspectorView.cpp b/src/openstudio_lib/ConstructionInspectorView.cpp index db77796dc..c1a1a8d33 100644 --- a/src/openstudio_lib/ConstructionInspectorView.cpp +++ b/src/openstudio_lib/ConstructionInspectorView.cpp @@ -7,10 +7,10 @@ #include "StandardsInformationConstructionWidget.hpp" #include "ConstructionObjectVectorController.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSLineEdit.hpp" diff --git a/src/openstudio_lib/ConstructionInternalSourceInspectorView.cpp b/src/openstudio_lib/ConstructionInternalSourceInspectorView.cpp index 940af71d8..b3eba5801 100644 --- a/src/openstudio_lib/ConstructionInternalSourceInspectorView.cpp +++ b/src/openstudio_lib/ConstructionInternalSourceInspectorView.cpp @@ -6,10 +6,10 @@ #include "ConstructionInternalSourceInspectorView.hpp" #include "StandardsInformationConstructionWidget.hpp" #include "ConstructionObjectVectorController.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSIntegerEdit.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" diff --git a/src/openstudio_lib/ConstructionObjectVectorController.cpp b/src/openstudio_lib/ConstructionObjectVectorController.cpp index 1b8f6a11d..04abb9d1b 100644 --- a/src/openstudio_lib/ConstructionObjectVectorController.cpp +++ b/src/openstudio_lib/ConstructionObjectVectorController.cpp @@ -5,7 +5,7 @@ #include "ConstructionObjectVectorController.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" diff --git a/src/openstudio_lib/DefaultConstructionSetInspectorView.cpp b/src/openstudio_lib/DefaultConstructionSetInspectorView.cpp index 644330116..88ea83567 100644 --- a/src/openstudio_lib/DefaultConstructionSetInspectorView.cpp +++ b/src/openstudio_lib/DefaultConstructionSetInspectorView.cpp @@ -4,9 +4,9 @@ ***********************************************************************************************************************/ #include "DefaultConstructionSetInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectTypeListView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" diff --git a/src/openstudio_lib/DesignDayGridView.cpp b/src/openstudio_lib/DesignDayGridView.cpp index ab0616c65..4c0c5bb62 100644 --- a/src/openstudio_lib/DesignDayGridView.cpp +++ b/src/openstudio_lib/DesignDayGridView.cpp @@ -9,10 +9,10 @@ #include "../shared_gui_components/OSGridView.hpp" #include "../shared_gui_components/OSObjectSelector.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include diff --git a/src/openstudio_lib/DesignDayGridView.hpp b/src/openstudio_lib/DesignDayGridView.hpp index 31591a2db..5c3ca1a39 100644 --- a/src/openstudio_lib/DesignDayGridView.hpp +++ b/src/openstudio_lib/DesignDayGridView.hpp @@ -8,7 +8,7 @@ #include "../shared_gui_components/OSGridController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/ElectricEquipmentInspectorView.cpp b/src/openstudio_lib/ElectricEquipmentInspectorView.cpp index 34b0ee379..89597fb6e 100644 --- a/src/openstudio_lib/ElectricEquipmentInspectorView.cpp +++ b/src/openstudio_lib/ElectricEquipmentInspectorView.cpp @@ -6,7 +6,7 @@ #include "ElectricEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/FacilityExteriorEquipmentGridView.hpp b/src/openstudio_lib/FacilityExteriorEquipmentGridView.hpp index bc16ce0f6..643f0a7e8 100644 --- a/src/openstudio_lib/FacilityExteriorEquipmentGridView.hpp +++ b/src/openstudio_lib/FacilityExteriorEquipmentGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "GridViewSubTab.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/FacilityShadingGridView.cpp b/src/openstudio_lib/FacilityShadingGridView.cpp index b925d4688..dd4e195e2 100644 --- a/src/openstudio_lib/FacilityShadingGridView.cpp +++ b/src/openstudio_lib/FacilityShadingGridView.cpp @@ -5,7 +5,7 @@ #include "FacilityShadingGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/FacilityShadingGridView.hpp b/src/openstudio_lib/FacilityShadingGridView.hpp index 74b29aab6..7c43183e5 100644 --- a/src/openstudio_lib/FacilityShadingGridView.hpp +++ b/src/openstudio_lib/FacilityShadingGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "GridViewSubTab.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/FacilityStoriesGridView.cpp b/src/openstudio_lib/FacilityStoriesGridView.cpp index cc82a0309..adf43fec5 100644 --- a/src/openstudio_lib/FacilityStoriesGridView.cpp +++ b/src/openstudio_lib/FacilityStoriesGridView.cpp @@ -5,7 +5,7 @@ #include "FacilityStoriesGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/FacilityStoriesGridView.hpp b/src/openstudio_lib/FacilityStoriesGridView.hpp index 5689b4789..353c39fb4 100644 --- a/src/openstudio_lib/FacilityStoriesGridView.hpp +++ b/src/openstudio_lib/FacilityStoriesGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "GridViewSubTab.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/GasEquipmentInspectorView.cpp b/src/openstudio_lib/GasEquipmentInspectorView.cpp index 27f53a6a5..705766630 100644 --- a/src/openstudio_lib/GasEquipmentInspectorView.cpp +++ b/src/openstudio_lib/GasEquipmentInspectorView.cpp @@ -6,7 +6,7 @@ #include "GasEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/GeometryEditorView.cpp b/src/openstudio_lib/GeometryEditorView.cpp index a9f9ba6db..4315e86a0 100644 --- a/src/openstudio_lib/GeometryEditorView.cpp +++ b/src/openstudio_lib/GeometryEditorView.cpp @@ -1098,7 +1098,7 @@ EditorWebView::EditorWebView(bool isIP, const openstudio::model::Model& model, Q auto* mainLayout = new QVBoxLayout; setLayout(mainLayout); - connect(m_document.get(), &OSDocument::toggleUnitsClicked, this, &EditorWebView::onUnitSystemChange); + connect(m_document, &OSDocument::toggleUnitsClicked, this, &EditorWebView::onUnitSystemChange); connect(m_geometrySourceComboBox, &QComboBox::currentTextChanged, this, &EditorWebView::geometrySourceChanged); connect(m_newImportGeometry, &QPushButton::clicked, this, &EditorWebView::newImportClicked); connect(m_refreshBtn, &QPushButton::clicked, this, &EditorWebView::refreshClicked); @@ -1168,7 +1168,7 @@ EditorWebView::EditorWebView(bool isIP, const openstudio::model::Model& model, Q //mainLayout->addWidget(m_view, 10, Qt::AlignTop); mainLayout->addWidget(m_view); - connect(m_document.get(), &OSDocument::modelSaving, this, &EditorWebView::saveClickedBlocking); + connect(m_document, &OSDocument::modelSaving, this, &EditorWebView::saveClickedBlocking); // check if floorplan exists openstudio::path p = floorplanPath(); diff --git a/src/openstudio_lib/GeometryEditorView.hpp b/src/openstudio_lib/GeometryEditorView.hpp index 0fe0664a7..061b6b5c6 100644 --- a/src/openstudio_lib/GeometryEditorView.hpp +++ b/src/openstudio_lib/GeometryEditorView.hpp @@ -96,7 +96,7 @@ class BaseEditor : public QObject model::Model m_exportModel; std::map m_exportModelHandleMapping; - std::shared_ptr m_document; + OSDocument* m_document = nullptr; QTimer* m_checkForUpdateTimer; }; @@ -244,7 +244,7 @@ class EditorWebView : public QWidget QWebEngineView* m_view; OSWebEnginePage* m_page; - std::shared_ptr m_document; + OSDocument* m_document = nullptr; }; } // namespace openstudio diff --git a/src/openstudio_lib/GeometryPreviewView.cpp b/src/openstudio_lib/GeometryPreviewView.cpp index 4a2e2f49d..f06ca87a4 100644 --- a/src/openstudio_lib/GeometryPreviewView.cpp +++ b/src/openstudio_lib/GeometryPreviewView.cpp @@ -179,7 +179,7 @@ PreviewWebView::PreviewWebView(bool isIP, const model::Model& model, QWidget* t_ auto* mainLayout = new QVBoxLayout; setLayout(mainLayout); - connect(m_document.get(), &OSDocument::toggleUnitsClicked, this, &PreviewWebView::onUnitSystemChange); + connect(m_document, &OSDocument::toggleUnitsClicked, this, &PreviewWebView::onUnitSystemChange); connect(m_refreshBtn, &QPushButton::clicked, this, &PreviewWebView::refreshClicked); auto* hLayout = new QHBoxLayout(); diff --git a/src/openstudio_lib/GeometryPreviewView.hpp b/src/openstudio_lib/GeometryPreviewView.hpp index 6ff8fd452..3727034a0 100644 --- a/src/openstudio_lib/GeometryPreviewView.hpp +++ b/src/openstudio_lib/GeometryPreviewView.hpp @@ -100,7 +100,7 @@ class PreviewWebView : public QWidget QWebEngineView* m_view; OSWebEnginePage* m_page; - std::shared_ptr m_document; + OSDocument* m_document = nullptr; GeometryBridge* m_bridge; QString m_json; diff --git a/src/openstudio_lib/GridItem.cpp b/src/openstudio_lib/GridItem.cpp index e2a8bace8..92b268fd7 100644 --- a/src/openstudio_lib/GridItem.cpp +++ b/src/openstudio_lib/GridItem.cpp @@ -10,7 +10,7 @@ #include "OSDocument.hpp" #include "OSAppBase.hpp" #include "MainRightColumnController.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../shared_gui_components/ColorPalettes.hpp" #include @@ -1248,7 +1248,7 @@ void HorizontalBranchGroupItem::layout() { void HorizontalBranchGroupItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {} SystemItem::SystemItem(const model::Loop& loop, LoopScene* loopScene) : m_loop(loop), m_loopScene(loopScene) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); std::shared_ptr mrc = doc->mainRightColumnController(); mrc->registerSystemItem(m_loop.handle(), this); @@ -1333,7 +1333,7 @@ SystemItem::SystemItem(const model::Loop& loop, LoopScene* loopScene) : m_loop(l } SystemItem::~SystemItem() { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); std::shared_ptr mrc = doc->mainRightColumnController(); mrc->unregisterSystemItem(m_loop.handle()); } diff --git a/src/openstudio_lib/GridItem.hpp b/src/openstudio_lib/GridItem.hpp index 9d4b0507e..a5564428e 100644 --- a/src/openstudio_lib/GridItem.hpp +++ b/src/openstudio_lib/GridItem.hpp @@ -18,7 +18,7 @@ #include #include #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "shared_gui_components/GraphicsItems.hpp" class QMenu; diff --git a/src/openstudio_lib/GridScene.hpp b/src/openstudio_lib/GridScene.hpp index 8068d390a..edf6df724 100644 --- a/src/openstudio_lib/GridScene.hpp +++ b/src/openstudio_lib/GridScene.hpp @@ -9,7 +9,7 @@ #include #include // Signal-Slot replacement #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" namespace openstudio { diff --git a/src/openstudio_lib/GridViewSubTab.cpp b/src/openstudio_lib/GridViewSubTab.cpp index 76831ae98..dfc2903d1 100644 --- a/src/openstudio_lib/GridViewSubTab.cpp +++ b/src/openstudio_lib/GridViewSubTab.cpp @@ -146,7 +146,7 @@ std::set GridViewSubTab::selectedObjects() const { } void GridViewSubTab::onDropZoneItemClicked(OSItem* item) { - std::shared_ptr currentDocument = OSAppBase::instance()->currentDocument(); + OSDocument* currentDocument = OSAppBase::instance()->currentDocument(); if (currentDocument) { if (!item) { emit dropZoneItemSelected(item, false); diff --git a/src/openstudio_lib/GridViewSubTab.hpp b/src/openstudio_lib/GridViewSubTab.hpp index aa78dec32..cd79c58f8 100644 --- a/src/openstudio_lib/GridViewSubTab.hpp +++ b/src/openstudio_lib/GridViewSubTab.hpp @@ -12,7 +12,7 @@ #include #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/HVACSystemsController.hpp b/src/openstudio_lib/HVACSystemsController.hpp index 13b400422..636793241 100644 --- a/src/openstudio_lib/HVACSystemsController.hpp +++ b/src/openstudio_lib/HVACSystemsController.hpp @@ -9,13 +9,13 @@ #include #include #include -#include "OSDropZone.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectVectorController.hpp" #include #include "SOConstants.hpp" #include "../shared_gui_components/OSQObjectController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include #include diff --git a/src/openstudio_lib/HVACSystemsView.cpp b/src/openstudio_lib/HVACSystemsView.cpp index 2ff14535f..6ca319935 100644 --- a/src/openstudio_lib/HVACSystemsView.cpp +++ b/src/openstudio_lib/HVACSystemsView.cpp @@ -5,10 +5,10 @@ #include "HVACSystemsView.hpp" #include "../shared_gui_components/OSComboBox.hpp" -#include "OSItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSSwitch.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../shared_gui_components/OSViewSwitcher.hpp" #include "../shared_gui_components/Buttons.hpp" #include diff --git a/src/openstudio_lib/HotWaterEquipmentInspectorView.cpp b/src/openstudio_lib/HotWaterEquipmentInspectorView.cpp index 53129d0c6..7aa141681 100644 --- a/src/openstudio_lib/HotWaterEquipmentInspectorView.cpp +++ b/src/openstudio_lib/HotWaterEquipmentInspectorView.cpp @@ -6,7 +6,7 @@ #include "HotWaterEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/InspectorView.cpp b/src/openstudio_lib/InspectorView.cpp index a188ef63e..c5f7219e6 100644 --- a/src/openstudio_lib/InspectorView.cpp +++ b/src/openstudio_lib/InspectorView.cpp @@ -10,9 +10,9 @@ #include "LibraryTabWidget.hpp" #include "LoopChooserView.hpp" #include "MainRightColumnController.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSDocument.hpp" #include "ZoneChooserView.hpp" #include "EMSInspectorView.hpp" @@ -929,7 +929,7 @@ NewPlenumDialog::NewPlenumDialog(QWidget* parent) : QDialog(parent) { mainVLayout->addSpacing(20); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); model::Model model = doc->model(); std::vector allZones = model.getModelObjects(); @@ -1180,7 +1180,7 @@ void ThermalZoneInspectorView::update() { return; } - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); std::shared_ptr mrc = doc->mainRightColumnController(); SystemItem* systemItem = mrc->systemItem(t_airLoopHVAC->handle()); // if there is t_airLoopHVAC but no systemItem then we are probably showing this view from the grid. diff --git a/src/openstudio_lib/InternalMassInspectorView.cpp b/src/openstudio_lib/InternalMassInspectorView.cpp index a098cb6f1..005866e00 100644 --- a/src/openstudio_lib/InternalMassInspectorView.cpp +++ b/src/openstudio_lib/InternalMassInspectorView.cpp @@ -6,8 +6,8 @@ #include "InternalMassInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include #include #include diff --git a/src/openstudio_lib/LightsInspectorView.cpp b/src/openstudio_lib/LightsInspectorView.cpp index 8131187ab..0ba30b0e4 100644 --- a/src/openstudio_lib/LightsInspectorView.cpp +++ b/src/openstudio_lib/LightsInspectorView.cpp @@ -6,7 +6,7 @@ #include "LightsInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index 87349756d..2763e70fa 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -9,7 +9,7 @@ #include "ModelObjectListView.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "SchedulesTabController.hpp" diff --git a/src/openstudio_lib/LoopScene.hpp b/src/openstudio_lib/LoopScene.hpp index 8f0e8dceb..4429c4113 100644 --- a/src/openstudio_lib/LoopScene.hpp +++ b/src/openstudio_lib/LoopScene.hpp @@ -10,7 +10,7 @@ #include #include #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "GridScene.hpp" #include "../openstudio_qt_utils/QMetaTypes.hpp" diff --git a/src/openstudio_lib/LuminaireInspectorView.cpp b/src/openstudio_lib/LuminaireInspectorView.cpp index de1bdfd4a..8eef3d4b9 100644 --- a/src/openstudio_lib/LuminaireInspectorView.cpp +++ b/src/openstudio_lib/LuminaireInspectorView.cpp @@ -6,7 +6,7 @@ #include "LuminaireInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/MainRightColumnController.cpp b/src/openstudio_lib/MainRightColumnController.cpp index f19e3b4d1..b4308f53b 100644 --- a/src/openstudio_lib/MainRightColumnController.cpp +++ b/src/openstudio_lib/MainRightColumnController.cpp @@ -17,7 +17,7 @@ #include "OSCollapsibleItem.hpp" #include "OSCollapsibleItemHeader.hpp" #include "OSDocument.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSItemList.hpp" #include "SchedulesTabController.hpp" #include "SpaceTypeInspectorView.hpp" @@ -123,7 +123,7 @@ void MainRightColumnController::inspectModelObjectByItem(OSItem* item, bool read m_item = item; if (m_item) { boost::optional modelObject; - std::shared_ptr currentDocument = OSAppBase::instance()->currentDocument(); + OSDocument* currentDocument = OSAppBase::instance()->currentDocument(); if (currentDocument) { modelObject = currentDocument->getModelObject(item->itemId()); } @@ -212,7 +212,7 @@ void MainRightColumnController::setLibraryView(QWidget* widget) { } void MainRightColumnController::configureForSiteSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -264,7 +264,7 @@ void MainRightColumnController::configureForSiteSubTab(int subTabID) { } void MainRightColumnController::configureForSchedulesSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -360,7 +360,7 @@ void MainRightColumnController::configureForSchedulesSubTab(int subTabID) { } void MainRightColumnController::configureForConstructionsSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -530,7 +530,7 @@ void MainRightColumnController::configureForConstructionsSubTab(int subTabID) { } void MainRightColumnController::configureForGeometrySubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -551,7 +551,7 @@ void MainRightColumnController::configureForGeometrySubTab(int subTabID) { } void MainRightColumnController::configureForLoadsSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); model::Model lib = doc->componentLibrary(); @@ -627,7 +627,7 @@ void MainRightColumnController::configureForSpaceTypesSubTab(int subTabID) { setEditView(nullptr); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); // my model auto* myModelList = new ModelObjectTypeListView(m_model, true, OSItemType::CollapsibleListHeader, false); @@ -707,7 +707,7 @@ void MainRightColumnController::configureForSpaceTypesSubTab(int subTabID) { void MainRightColumnController::configureForFacilitySubTab(int subTabID) { setEditView(nullptr); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); // my model auto* myModelList = new ModelObjectTypeListView(m_model, true, OSItemType::CollapsibleListHeader, false); @@ -816,7 +816,7 @@ void MainRightColumnController::configureForFacilitySubTab(int subTabID) { void MainRightColumnController::configureForSpacesSubTab(int subTabID) { setEditView(nullptr); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); // my model auto* myModelList = new ModelObjectTypeListView(m_model, true, OSItemType::CollapsibleListHeader, false); @@ -929,7 +929,7 @@ void MainRightColumnController::configureForSpacesSubTab(int subTabID) { void MainRightColumnController::configureForThermalZonesSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -1005,7 +1005,7 @@ void MainRightColumnController::configureForThermalZonesSubTab(int subTabID) { void MainRightColumnController::configureForHVACSystemsSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -1272,7 +1272,7 @@ void MainRightColumnController::configureForHVACSystemsSubTab(int subTabID) { } void MainRightColumnController::configureForOutputVariablesSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -1283,7 +1283,7 @@ void MainRightColumnController::configureForOutputVariablesSubTab(int subTabID) } void MainRightColumnController::configureForSimulationSettingsSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -1294,7 +1294,7 @@ void MainRightColumnController::configureForSimulationSettingsSubTab(int subTabI } void MainRightColumnController::configureForScriptsSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(m_measureLibraryController->localLibraryView.data()); setMyModelView(nullptr); @@ -1305,7 +1305,7 @@ void MainRightColumnController::configureForScriptsSubTab(int subTabID) { } void MainRightColumnController::configureForRunSimulationSubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); @@ -1316,7 +1316,7 @@ void MainRightColumnController::configureForRunSimulationSubTab(int subTabID) { } void MainRightColumnController::configureForResultsSummarySubTab(int subTabID) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); setLibraryView(nullptr); setMyModelView(nullptr); diff --git a/src/openstudio_lib/MainRightColumnController.hpp b/src/openstudio_lib/MainRightColumnController.hpp index 01ac2437d..4f4f23b3b 100644 --- a/src/openstudio_lib/MainRightColumnController.hpp +++ b/src/openstudio_lib/MainRightColumnController.hpp @@ -14,7 +14,7 @@ #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" class QStackedWidget; diff --git a/src/openstudio_lib/MaterialInspectorView.cpp b/src/openstudio_lib/MaterialInspectorView.cpp index d62105a9e..5fb369451 100644 --- a/src/openstudio_lib/MaterialInspectorView.cpp +++ b/src/openstudio_lib/MaterialInspectorView.cpp @@ -7,7 +7,7 @@ #include "StandardsInformationMaterialWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSLineEdit.hpp" diff --git a/src/openstudio_lib/ModelObjectInspectorView.cpp b/src/openstudio_lib/ModelObjectInspectorView.cpp index 9825cc294..3858690bc 100644 --- a/src/openstudio_lib/ModelObjectInspectorView.cpp +++ b/src/openstudio_lib/ModelObjectInspectorView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" diff --git a/src/openstudio_lib/ModelObjectListView.cpp b/src/openstudio_lib/ModelObjectListView.cpp index 2652892d2..f3d765584 100644 --- a/src/openstudio_lib/ModelObjectListView.cpp +++ b/src/openstudio_lib/ModelObjectListView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "ModelObjectListView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" #include "BCLComponentItem.hpp" diff --git a/src/openstudio_lib/ModelObjectTreeItems.cpp b/src/openstudio_lib/ModelObjectTreeItems.cpp index cdf0e96f4..59a3cf955 100644 --- a/src/openstudio_lib/ModelObjectTreeItems.cpp +++ b/src/openstudio_lib/ModelObjectTreeItems.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "ModelObjectTreeItems.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../shared_gui_components/IconLibrary.hpp" #include diff --git a/src/openstudio_lib/ModelObjectTreeItems.hpp b/src/openstudio_lib/ModelObjectTreeItems.hpp index a77ef72c7..f5c5571ce 100644 --- a/src/openstudio_lib/ModelObjectTreeItems.hpp +++ b/src/openstudio_lib/ModelObjectTreeItems.hpp @@ -9,7 +9,7 @@ #include #include #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include #include diff --git a/src/openstudio_lib/ModelObjectTypeListView.cpp b/src/openstudio_lib/ModelObjectTypeListView.cpp index 0132115ef..61d29e073 100644 --- a/src/openstudio_lib/ModelObjectTypeListView.cpp +++ b/src/openstudio_lib/ModelObjectTypeListView.cpp @@ -5,11 +5,11 @@ #include "ModelObjectTypeListView.hpp" #include "ModelObjectTypeItem.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectListView.hpp" #include "OSCollapsibleItemHeader.hpp" #include "OSCategoryPlaceholder.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include #include diff --git a/src/openstudio_lib/ModelSubTabController.cpp b/src/openstudio_lib/ModelSubTabController.cpp index 880a048e6..8225d993c 100644 --- a/src/openstudio_lib/ModelSubTabController.cpp +++ b/src/openstudio_lib/ModelSubTabController.cpp @@ -6,7 +6,7 @@ #include "ModelSubTabController.hpp" #include "ModelSubTabView.hpp" #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectListView.hpp" #include "ModelObjectTypeListView.hpp" #include "OSItemSelector.hpp" diff --git a/src/openstudio_lib/ModelSubTabView.cpp b/src/openstudio_lib/ModelSubTabView.cpp index aa2c3e5ae..cb74ac88f 100644 --- a/src/openstudio_lib/ModelSubTabView.cpp +++ b/src/openstudio_lib/ModelSubTabView.cpp @@ -6,7 +6,7 @@ #include "ModelSubTabView.hpp" #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectListView.hpp" #include "ModelObjectTypeListView.hpp" #include "OSAppBase.hpp" @@ -51,7 +51,7 @@ ModelObjectInspectorView* ModelSubTabView::modelObjectInspectorView() { } void ModelSubTabView::onDropZoneItemClicked(OSItem* item) { - std::shared_ptr currentDocument = OSAppBase::instance()->currentDocument(); + OSDocument* currentDocument = OSAppBase::instance()->currentDocument(); if (currentDocument) { if (!item) { emit dropZoneItemSelected(item, false); diff --git a/src/openstudio_lib/OSAppBase.cpp b/src/openstudio_lib/OSAppBase.cpp index 3678ad2d3..5db07acd3 100644 --- a/src/openstudio_lib/OSAppBase.cpp +++ b/src/openstudio_lib/OSAppBase.cpp @@ -6,20 +6,22 @@ #include "OSAppBase.hpp" #include "ApplyMeasureNowDialog.hpp" +#include "BCLComponentItem.hpp" #include "InspectorController.hpp" #include "InspectorView.hpp" #include "MainRightColumnController.hpp" #include "MainWindow.hpp" #include "OSDocument.hpp" -#include "../openstudio_qt_utils/Utilities.hpp" +#include "ScriptItem.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/EditController.hpp" -#include "../shared_gui_components/MeasureManager.hpp" -#include "../shared_gui_components/LocalLibraryView.hpp" #include "../shared_gui_components/LocalLibraryController.hpp" -#include "../shared_gui_components/WaitDialog.hpp" - +#include "../shared_gui_components/LocalLibraryView.hpp" +#include "../shared_gui_components/MeasureManager.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../shared_gui_components/UserSettings.hpp" +#include "../shared_gui_components/WaitDialog.hpp" #include #include @@ -77,7 +79,7 @@ void OSAppBase::showMeasureUpdateDlg() { //boost::optional OSAppBase::project() //{ -// std::shared_ptr document = currentDocument(); +// OSDocument* document = currentDocument(); // // if (document) // { @@ -108,7 +110,7 @@ void OSAppBase::removeWorkspaceObjectPtr(std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { return document->mainWindow(); @@ -118,7 +120,7 @@ QWidget* OSAppBase::mainWidget() { } boost::optional OSAppBase::tempDir() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { return toPath(document->modelTempDir()); } @@ -126,7 +128,7 @@ boost::optional OSAppBase::tempDir() { } boost::optional OSAppBase::currentModel() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { return document->model(); } else { @@ -135,7 +137,7 @@ boost::optional OSAppBase::currentModel() { } bool OSAppBase::mouseOverInspectorView() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { return document->mainRightColumnController()->inspectorController()->inspectorView()->mouseOverInspectorView(); } @@ -144,7 +146,7 @@ bool OSAppBase::mouseOverInspectorView() { //boost::optional OSAppBase::currentWorkspace() //{ -// std::shared_ptr document = currentDocument(); +// OSDocument* document = currentDocument(); // if (document) // { // return document->workspace(); @@ -160,7 +162,7 @@ MeasureManager& OSAppBase::measureManager() { void OSAppBase::updateSelectedMeasureState() { // DLM: this slot seems out of place here, seems like the connection from the measure list to enabling duplicate buttons, etc // should be tighter - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { std::shared_ptr mainRightColumnController = document->mainRightColumnController(); @@ -194,7 +196,7 @@ void OSAppBase::duplicateSelectedMeasure() { } void OSAppBase::updateMyMeasures() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { //boost::optional project = document->project(); @@ -210,7 +212,7 @@ void OSAppBase::updateMyMeasures() { } void OSAppBase::updateBCLMeasures() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { //boost::optional project = document->project(); @@ -230,7 +232,7 @@ void OSAppBase::checkForRemoteBCLUpdates() { } void OSAppBase::openBclDlg() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { document->openMeasuresBclDlg(); @@ -238,7 +240,7 @@ void OSAppBase::openBclDlg() { } void OSAppBase::chooseHorizontalEditTab() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { document->mainRightColumnController()->chooseEditTab(); @@ -246,7 +248,7 @@ void OSAppBase::chooseHorizontalEditTab() { } QSharedPointer OSAppBase::editController() { - std::shared_ptr document = currentDocument(); + OSDocument* document = currentDocument(); if (document) { return document->mainRightColumnController()->measuresEditController(); @@ -323,4 +325,32 @@ std::size_t OSAppBase::removeOutdatedLocalMeasures(const std::string& uid, const return 0; } +OSItem* OSAppBase::makeItem(const OSItemId& itemId, OSItemType osItemType) { + auto doc = currentDocument(); + if (!doc) { + return nullptr; + } + + if (itemId.sourceId() == OSItemId::BCL_SOURCE_ID) { + boost::optional comp = doc->getLocalComponent(itemId.itemId().toStdString()); + if (comp) { + return new BCLComponentItem(comp.get(), osItemType); + } + return nullptr; + } + + boost::optional modelObject = doc->getModelObject(itemId); + if (modelObject) { + return new ModelObjectItem(*modelObject, itemId.isDefaulted(), osItemType); + } + + openstudio::path p = openstudio::toPath(itemId.itemId()); + boost::system::error_code ec; + if (openstudio::filesystem::exists(p, ec)) { + return new ScriptItem(p, osItemType); + } + + return nullptr; +} + } // namespace openstudio diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index 23cb0016a..282aff416 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -6,11 +6,12 @@ #ifndef OPENSTUDIO_OSAPPBASE_HPP #define OPENSTUDIO_OSAPPBASE_HPP -#include "../shared_gui_components/BaseApp.hpp" +#include "OSDocument.hpp" -#include #include "../openstudio_qt_utils/QMetaTypes.hpp" +#include "../shared_gui_components/BaseApp.hpp" +#include #include #include @@ -21,7 +22,6 @@ class QEvent; namespace openstudio { -class OSDocument; class WaitDialog; @@ -32,8 +32,9 @@ class WaitDialog; * per process, and it must outlive all widgets. * * 2. Implements the BaseApp interface — all virtual methods declared in BaseApp are - * overridden here as `final`, forwarding to the current OSDocument and MainWindow. - * Shared components reach this implementation via static_cast(qApp). + * overridden here as `final`, except currentDocument() which is left pure virtual + * for the concrete subclass (e.g. OpenStudioApp) to supply. + * Shared components reach this implementation via dynamic_cast(qApp). * * 3. Leaves currentDocument() pure — concrete subclasses (e.g. OpenStudioApp) supply * the document ownership strategy. @@ -58,7 +59,12 @@ class OSAppBase virtual ~OSAppBase(); - virtual std::shared_ptr currentDocument() const = 0; + /// Returns the current document as a concrete OSDocument. Covariant override of + /// BaseApp::currentDocument() — C++ allows raw pointer covariance, so a single virtual + /// serves both openstudio_lib callers (which get OSDocument*) and shared_gui_components + /// callers (which receive the BaseDocument* base pointer). Pure virtual — OpenStudioApp + /// owns the document and provides the implementation. + virtual OSDocument* currentDocument() const = 0; static OSAppBase* instance(); @@ -90,6 +96,8 @@ class OSAppBase std::size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const final; std::size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const final; + OSItem* makeItem(const OSItemId& itemId, OSItemType osItemType) final; + virtual openstudio::path dviewPath() const; virtual bool notify(QObject* receiver, QEvent* e) override; diff --git a/src/openstudio_lib/OSCollapsibleItem.hpp b/src/openstudio_lib/OSCollapsibleItem.hpp index 1d842f299..2ad94a2eb 100644 --- a/src/openstudio_lib/OSCollapsibleItem.hpp +++ b/src/openstudio_lib/OSCollapsibleItem.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_OSCOLLAPSIBLEITEM_HPP #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" class QButtonGroup; class QComboBox; diff --git a/src/openstudio_lib/OSCollapsibleItemHeader.cpp b/src/openstudio_lib/OSCollapsibleItemHeader.cpp index 462250aab..7e6a4d55f 100644 --- a/src/openstudio_lib/OSCollapsibleItemHeader.cpp +++ b/src/openstudio_lib/OSCollapsibleItemHeader.cpp @@ -5,7 +5,7 @@ #include "OSCollapsibleItemHeader.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include #include diff --git a/src/openstudio_lib/OSCollapsibleItemHeader.hpp b/src/openstudio_lib/OSCollapsibleItemHeader.hpp index 14cafa455..978a18f99 100644 --- a/src/openstudio_lib/OSCollapsibleItemHeader.hpp +++ b/src/openstudio_lib/OSCollapsibleItemHeader.hpp @@ -6,7 +6,7 @@ #ifndef OPENSTUDIO_OSCOLLAPSIBLEITEMHEADER_HPP #define OPENSTUDIO_OSCOLLAPSIBLEITEMHEADER_HPP -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" class QLabel; class QVBoxLayout; diff --git a/src/openstudio_lib/OSCollapsibleItemList.cpp b/src/openstudio_lib/OSCollapsibleItemList.cpp index 35e66eb21..2e5eec6eb 100644 --- a/src/openstudio_lib/OSCollapsibleItemList.cpp +++ b/src/openstudio_lib/OSCollapsibleItemList.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "OSCollapsibleItemList.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSItemList.hpp" #include "OSCollapsibleItem.hpp" #include "OSCollapsibleItemHeader.hpp" diff --git a/src/openstudio_lib/OSCollapsibleItemList.hpp b/src/openstudio_lib/OSCollapsibleItemList.hpp index f1de26a99..c310a7d7e 100644 --- a/src/openstudio_lib/OSCollapsibleItemList.hpp +++ b/src/openstudio_lib/OSCollapsibleItemList.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_OSCOLLAPSIBLEITEMLIST_HPP #include "OSItemSelector.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSCategoryPlaceholder.hpp" class QVBoxLayout; diff --git a/src/openstudio_lib/OSDocument.cpp b/src/openstudio_lib/OSDocument.cpp index 79001b096..72a2d3c94 100644 --- a/src/openstudio_lib/OSDocument.cpp +++ b/src/openstudio_lib/OSDocument.cpp @@ -19,7 +19,7 @@ #include "LocationTabView.hpp" #include "MainRightColumnController.hpp" #include "MainWindow.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectTypeListView.hpp" #include "OSAppBase.hpp" #include "ResultsTabController.hpp" diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index 743097fa4..bfd25a100 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -7,6 +7,7 @@ #define OPENSTUDIO_OSDOCUMENT_HPP #include "../shared_gui_components/OSQObjectController.hpp" +#include "../shared_gui_components/BaseDocument.hpp" #include "../openstudio_qt_utils/QMetaTypes.hpp" #include @@ -48,7 +49,9 @@ class Workspace; * views, constructs the complete tab bar layout, and coordinates undo/redo, units (IP/SI), and * weather file management. */ -class OSDocument : public OSQObjectController +class OSDocument + : public OSQObjectController + , public BaseDocument { Q_OBJECT @@ -58,81 +61,55 @@ class OSDocument : public OSQObjectController virtual ~OSDocument(); - // Returns the main window associated with this document. + // ------------------------------------------------------------------------- + // BaseDocument interface — pure virtual overrides + // ------------------------------------------------------------------------- + + model::Model model() override; + bool modified() const override; + QString savePath() const override; + QString modelTempDir() const override; + model::Model componentLibrary() const override; + bool fromModel(const OSItemId& itemId) const override; + bool fromComponentLibrary(const OSItemId& itemId) const override; + bool fromBCL(const OSItemId& itemId) const override; + std::vector componentAttributeSearch(const std::vector>& pairs) const override; + boost::optional getIddObjectType(const OSItemId& itemId) const override; + boost::optional getModelObject(const OSItemId& itemId) const override; + boost::optional getComponent(const OSItemId& itemId) const override; + + // ------------------------------------------------------------------------- + // OSDocument-specific API + // ------------------------------------------------------------------------- + + // TODO: promote to BaseDocument once MainWindow is extracted into an IMainWindow interface + // that lives in shared_gui_components or openstudio_qt_utils (no openstudio_lib dependency). MainWindow* mainWindow(); - // Returns the model associated with this document. - model::Model model(); - - // Sets the model associated with this document. - // This will close all current windows, make sure to call app->setQuitOnLastWindowClosed(false) before calling this + // Sets the model — closes all current windows. + // Call app->setQuitOnLastWindowClosed(false) before calling this. void setModel(const model::Model& model, bool modified, bool saveCurrentTabs); - // Returns the Workspace associated with this document's model - //boost::optional workspace(); - - // Set the Workspace associated with this document's model. - // Workspace is created by idf translator when the scripts tab is shown. - // This is used to populate idf measure arguments. - //void setWorkspace(const boost::optional& workspace); - - // Returns true if the document has unsaved changes. - bool modified() const; - - // Returns the string path to the location where the document is saved. - // If the document is unsaved an empty string will be returned. - QString savePath() const; - - // Returns the path to the directory where model resources are stored - QString modelTempDir() const; - - // Returns the component library associated with this document. - openstudio::model::Model componentLibrary() const; - // Sets the component library associated with this document. void setComponentLibrary(const openstudio::model::Model& model); - // Returns true if OSItemId's source is the model - bool fromModel(const OSItemId& itemId) const; - - // Returns true if OSItemId's source is the componentLibrary - bool fromComponentLibrary(const OSItemId& itemId) const; - - // Returns true if OSItemId's source is the BCL - bool fromBCL(const OSItemId& itemId) const; - - // returns false if the LocalBCL cannot be accessed + // Returns false if the LocalBCL cannot be accessed. bool haveLocalBCL() const; boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const; boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const; - std::vector getLocalComponents() const; std::vector getLocalMeasures() const; - // Removes all components with uid but NOT currentVersionId + // Removes all components with uid but NOT currentVersionId. size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const; - // Removes all measures with uid but NOT currentVersionId + // Removes all measures with uid but NOT currentVersionId. size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const; - std::vector componentAttributeSearch(const std::vector>& pairs) const; - - // Returns IddObjectType from either model, componentLibrary, or BCL - boost::optional getIddObjectType(const OSItemId& itemId) const; - - // Returns the model object from either model or componentLibrary if possible - // does not return model object from BCL - boost::optional getModelObject(const OSItemId& itemId) const; - - // Retrieves the Component identified by itemId from the local bcl library, - // updates it to the current version and returns it. - boost::optional getComponent(const OSItemId& itemId) const; - // Returns the index of the current tab. int verticalTabIndex(); - // Returns the index of the current sub tab. - // Returns -1 if there are no sub tabs. + // Returns the index of the current sub tab, or -1 if there are no sub tabs. int subTabIndex() const; enum VerticalTabID @@ -161,6 +138,8 @@ class OSDocument : public OSQObjectController EDIT }; + // TODO: promote to BaseDocument once MainRightColumnController is extracted into an + // IMainRightColumnController interface with no openstudio_lib dependency. std::shared_ptr mainRightColumnController() const; // DLM: would like for this to not be a member variable since it is only used as a modal dialog with a well defined lifetime @@ -225,36 +204,29 @@ class OSDocument : public OSQObjectController public slots: - void markAsModified(); - - void markAsUnmodified(); + // BaseDocument interface — pure virtual overrides + void markAsModified() override; + void markAsUnmodified() override; + void enable() override; + void disable() override; + void openSidebar() override; + // OSDocument-specific slots void exportIdf(); - void exportgbXML(); - void exportSDD(); // returns if a file was saved bool save(); - // returns if a file was saved bool saveAs(); void showRunManagerPreferences(); - void scanForTools(); - void closeSidebar(); - - void openSidebar(); - void openBclDlg(); - void openMeasuresBclDlg(); - void openMeasuresDlg(); - void openChangeMeasuresDirDlg(); private slots: @@ -283,14 +255,8 @@ class OSDocument : public OSQObjectController public slots: - void enable(); - - void disable(); - void enableTabsAfterRun(); - void disableTabsDuringRun(); - void weatherFileReset(); private: diff --git a/src/openstudio_lib/OSInspectorView.cpp b/src/openstudio_lib/OSInspectorView.cpp index 9e80ad680..9de0640dc 100644 --- a/src/openstudio_lib/OSInspectorView.cpp +++ b/src/openstudio_lib/OSInspectorView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "OSInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include #include diff --git a/src/openstudio_lib/OSItemList.hpp b/src/openstudio_lib/OSItemList.hpp index 55d3e2146..733a43642 100644 --- a/src/openstudio_lib/OSItemList.hpp +++ b/src/openstudio_lib/OSItemList.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_OSITEMLIST_HPP #include "OSItemSelector.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" class QVBoxLayout; diff --git a/src/openstudio_lib/OSItemSelector.cpp b/src/openstudio_lib/OSItemSelector.cpp index c7cd20ec3..8d5fea342 100644 --- a/src/openstudio_lib/OSItemSelector.cpp +++ b/src/openstudio_lib/OSItemSelector.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "OSItemSelector.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" namespace openstudio { diff --git a/src/openstudio_lib/OSItemSelectorButtons.cpp b/src/openstudio_lib/OSItemSelectorButtons.cpp index 6f094d5d1..c890b1e05 100644 --- a/src/openstudio_lib/OSItemSelectorButtons.cpp +++ b/src/openstudio_lib/OSItemSelectorButtons.cpp @@ -4,8 +4,8 @@ ***********************************************************************************************************************/ #include "OSItemSelectorButtons.hpp" -#include "OSDropZone.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSVectorController.hpp" #include diff --git a/src/openstudio_lib/OtherEquipmentInspectorView.cpp b/src/openstudio_lib/OtherEquipmentInspectorView.cpp index 865b8086b..0c57a9ff6 100644 --- a/src/openstudio_lib/OtherEquipmentInspectorView.cpp +++ b/src/openstudio_lib/OtherEquipmentInspectorView.cpp @@ -6,7 +6,7 @@ #include "OtherEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/RefrigerationController.cpp b/src/openstudio_lib/RefrigerationController.cpp index 48d3c11eb..9e446980c 100644 --- a/src/openstudio_lib/RefrigerationController.cpp +++ b/src/openstudio_lib/RefrigerationController.cpp @@ -7,7 +7,7 @@ #include "RefrigerationGraphicsItems.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "MainWindow.hpp" #include "MainRightColumnController.hpp" #include "../shared_gui_components/IconLibrary.hpp" @@ -229,7 +229,7 @@ boost::optional RefrigerationController::cascadeSyst } void RefrigerationController::zoomInOnSystem(const Handle& handle) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); model::Model t_model = doc->model(); if (boost::optional system = t_model.getModelObject(handle)) { @@ -240,7 +240,7 @@ void RefrigerationController::zoomInOnSystem(const Handle& handle) { void RefrigerationController::zoomInOnSystem(const model::RefrigerationSystem& refrigerationSystem) { model::OptionalModelObject mo; - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); doc->mainRightColumnController()->inspectModelObject(mo, false); @@ -298,7 +298,7 @@ void RefrigerationController::zoomOutToSystemGridView() { m_currentSystem = boost::none; model::OptionalModelObject mo; - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); doc->mainRightColumnController()->inspectModelObject(mo, false); m_refrigerationSystemListController->reset(); @@ -314,7 +314,7 @@ void RefrigerationController::zoomOutToSystemGridView() { void RefrigerationController::onCondenserViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -369,7 +369,7 @@ void RefrigerationController::onCondenserViewDrop(const OSItemId& itemid) { void RefrigerationController::onCompressorViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -390,7 +390,7 @@ void RefrigerationController::onSecondaryViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); model::Model t_model = m_currentSystem->model(); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); OS_ASSERT(mo); @@ -447,7 +447,7 @@ void RefrigerationController::onSecondaryViewDrop(const OSItemId& itemid) { void RefrigerationController::onCasesViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -474,7 +474,7 @@ void RefrigerationController::onCasesViewDrop(const OSItemId& itemid) { void RefrigerationController::onSubCoolerViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -523,7 +523,7 @@ void RefrigerationController::removeLoad(const Handle& handle) { void RefrigerationController::onSHXViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -577,7 +577,7 @@ NoRefrigerationView* RefrigerationController::noRefrigerationView() const { } void RefrigerationController::inspectOSItem(const OSItemId& itemid) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); OS_ASSERT(doc); @@ -626,7 +626,7 @@ QSharedPointer RefrigerationController::refri RefrigerationSystemListController::RefrigerationSystemListController(RefrigerationController* refrigerationController) : m_refrigerationController(refrigerationController) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); model::Model t_model = doc->model(); t_model.getImpl() ->addWorkspaceObject.connect(this); @@ -688,7 +688,7 @@ void RefrigerationSystemListController::onModelObjectAdd(const WorkspaceObject& } void RefrigerationSystemListController::addSystem(const OSItemId& itemid) { - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { boost::optional mo = doc->getModelObject(itemid); diff --git a/src/openstudio_lib/RefrigerationGraphicsItems.cpp b/src/openstudio_lib/RefrigerationGraphicsItems.cpp index 0833c65c4..6789dae2e 100644 --- a/src/openstudio_lib/RefrigerationGraphicsItems.cpp +++ b/src/openstudio_lib/RefrigerationGraphicsItems.cpp @@ -3,7 +3,7 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "RefrigerationGraphicsItems.hpp" #include #include "../shared_gui_components/Buttons.hpp" diff --git a/src/openstudio_lib/RefrigerationGraphicsItems.hpp b/src/openstudio_lib/RefrigerationGraphicsItems.hpp index 84de064aa..9163bf21e 100644 --- a/src/openstudio_lib/RefrigerationGraphicsItems.hpp +++ b/src/openstudio_lib/RefrigerationGraphicsItems.hpp @@ -7,8 +7,8 @@ #define OPENSTUDIO_REFRIGERATIONGRAPHICSITEMS_HPP #include -#include "OSItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSListController.hpp" #include "../shared_gui_components/GraphicsItems.hpp" #include diff --git a/src/openstudio_lib/RefrigerationGridView.cpp b/src/openstudio_lib/RefrigerationGridView.cpp index d9861e427..600f70e08 100644 --- a/src/openstudio_lib/RefrigerationGridView.cpp +++ b/src/openstudio_lib/RefrigerationGridView.cpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridView.hpp" #include "../shared_gui_components/OSObjectSelector.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" diff --git a/src/openstudio_lib/RefrigerationGridView.hpp b/src/openstudio_lib/RefrigerationGridView.hpp index bd34f5f8c..aa2b9e9d9 100644 --- a/src/openstudio_lib/RefrigerationGridView.hpp +++ b/src/openstudio_lib/RefrigerationGridView.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_REFRIGERATIONGRIDVIEW_HPP #include "../shared_gui_components/OSGridController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/RunTabView.cpp b/src/openstudio_lib/RunTabView.cpp index 6cba47bb8..9882cc174 100644 --- a/src/openstudio_lib/RunTabView.cpp +++ b/src/openstudio_lib/RunTabView.cpp @@ -216,7 +216,7 @@ void RunView::onRunProcessFinished(int exitCode, QProcess::ExitStatus status) { m_progressBar->setMaximum(State::complete); m_progressBar->setValue(State::complete); - const std::shared_ptr osdocument = OSAppBase::instance()->currentDocument(); + OSDocument* osdocument = OSAppBase::instance()->currentDocument(); osdocument->save(); osdocument->enableTabsAfterRun(); m_openSimDirButton->setEnabled(true); @@ -228,7 +228,7 @@ void RunView::onRunProcessFinished(int exitCode, QProcess::ExitStatus status) { void RunView::playButtonClicked(bool t_checked) { LOG(Debug, "playButtonClicked " << t_checked); - const std::shared_ptr osdocument = OSAppBase::instance()->currentDocument(); + OSDocument* osdocument = OSAppBase::instance()->currentDocument(); if (t_checked) { // run diff --git a/src/openstudio_lib/ScheduleDayView.cpp b/src/openstudio_lib/ScheduleDayView.cpp index 593cde17b..cdc439c6d 100644 --- a/src/openstudio_lib/ScheduleDayView.cpp +++ b/src/openstudio_lib/ScheduleDayView.cpp @@ -8,7 +8,7 @@ #include "../openstudio_qt_utils/Utilities.hpp" #include "../shared_gui_components/OSCheckBox.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSLineEdit.hpp" diff --git a/src/openstudio_lib/ScheduleSetInspectorView.cpp b/src/openstudio_lib/ScheduleSetInspectorView.cpp index 801d55c12..e687a8a82 100644 --- a/src/openstudio_lib/ScheduleSetInspectorView.cpp +++ b/src/openstudio_lib/ScheduleSetInspectorView.cpp @@ -5,9 +5,9 @@ #include "ScheduleSetInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectTypeListView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include diff --git a/src/openstudio_lib/ScheduleSetsView.cpp b/src/openstudio_lib/ScheduleSetsView.cpp index 76a733e0f..af0cecc7e 100644 --- a/src/openstudio_lib/ScheduleSetsView.cpp +++ b/src/openstudio_lib/ScheduleSetsView.cpp @@ -5,7 +5,7 @@ #include "ScheduleSetsView.hpp" #include "ModelObjectListView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "ScheduleSetInspectorView.hpp" #include diff --git a/src/openstudio_lib/SchedulesTabController.cpp b/src/openstudio_lib/SchedulesTabController.cpp index 371b8522f..8faf77c03 100644 --- a/src/openstudio_lib/SchedulesTabController.cpp +++ b/src/openstudio_lib/SchedulesTabController.cpp @@ -8,7 +8,7 @@ #include "MainTabView.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "ScheduleDialog.hpp" #include "ScheduleSetsController.hpp" #include "ScheduleSetsView.hpp" diff --git a/src/openstudio_lib/SchedulesView.cpp b/src/openstudio_lib/SchedulesView.cpp index 1a3b81b53..4c7f93468 100644 --- a/src/openstudio_lib/SchedulesView.cpp +++ b/src/openstudio_lib/SchedulesView.cpp @@ -8,7 +8,7 @@ #include "OSAppBase.hpp" #include "../shared_gui_components/OSCheckBox.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/ColorPalettes.hpp" diff --git a/src/openstudio_lib/ScriptItem.cpp b/src/openstudio_lib/ScriptItem.cpp index 34b515e6e..0da2dd11c 100644 --- a/src/openstudio_lib/ScriptItem.cpp +++ b/src/openstudio_lib/ScriptItem.cpp @@ -42,7 +42,7 @@ ScriptItem::ScriptItem(const openstudio::path& t_path, OSItemType type, QWidget* // } //} - //std::shared_ptr osDoc = OSAppBase::instance()->currentDocument(); + //OSDocument* osDoc = OSAppBase::instance()->currentDocument(); //connect(this, &ScriptItem::argChanged, osDoc.get(), &OSDocument::markAsModified); } diff --git a/src/openstudio_lib/ScriptItem.hpp b/src/openstudio_lib/ScriptItem.hpp index 317282246..a38edb551 100644 --- a/src/openstudio_lib/ScriptItem.hpp +++ b/src/openstudio_lib/ScriptItem.hpp @@ -6,7 +6,7 @@ #ifndef OPENSTUDIO_SCRIPTITEM_HPP #define OPENSTUDIO_SCRIPTITEM_HPP -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include #include diff --git a/src/openstudio_lib/ServiceWaterGridItems.hpp b/src/openstudio_lib/ServiceWaterGridItems.hpp index 143411673..d46c92c2e 100644 --- a/src/openstudio_lib/ServiceWaterGridItems.hpp +++ b/src/openstudio_lib/ServiceWaterGridItems.hpp @@ -10,7 +10,7 @@ #include #include #include -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "GridItem.hpp" namespace openstudio { diff --git a/src/openstudio_lib/ServiceWaterScene.hpp b/src/openstudio_lib/ServiceWaterScene.hpp index 25e55f445..d1a427bcd 100644 --- a/src/openstudio_lib/ServiceWaterScene.hpp +++ b/src/openstudio_lib/ServiceWaterScene.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_SERVICEWATERSCENE_HPP #include "GridScene.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../openstudio_qt_utils/QMetaTypes.hpp" #include #include diff --git a/src/openstudio_lib/SiteWaterMainsTemperatureWidget.cpp b/src/openstudio_lib/SiteWaterMainsTemperatureWidget.cpp index 597e908a5..200ddd167 100644 --- a/src/openstudio_lib/SiteWaterMainsTemperatureWidget.cpp +++ b/src/openstudio_lib/SiteWaterMainsTemperatureWidget.cpp @@ -5,8 +5,8 @@ #include "SiteWaterMainsTemperatureWidget.hpp" -#include "OSDropZone.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" diff --git a/src/openstudio_lib/SpaceLoadInstancesWidget.cpp b/src/openstudio_lib/SpaceLoadInstancesWidget.cpp index 26635f099..75f08af6a 100644 --- a/src/openstudio_lib/SpaceLoadInstancesWidget.cpp +++ b/src/openstudio_lib/SpaceLoadInstancesWidget.cpp @@ -8,8 +8,8 @@ #include "OSAppBase.hpp" #include "../shared_gui_components/IconLibrary.hpp" -#include "ModelObjectItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSVectorController.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" diff --git a/src/openstudio_lib/SpaceTypesGridView.cpp b/src/openstudio_lib/SpaceTypesGridView.cpp index 916d5cf97..170d41658 100644 --- a/src/openstudio_lib/SpaceTypesGridView.cpp +++ b/src/openstudio_lib/SpaceTypesGridView.cpp @@ -6,11 +6,11 @@ #include "SpaceTypesGridView.hpp" #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelSubTabView.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "../shared_gui_components/OSComboBox.hpp" diff --git a/src/openstudio_lib/SpaceTypesGridView.hpp b/src/openstudio_lib/SpaceTypesGridView.hpp index 4142b8e15..cf7de21ed 100644 --- a/src/openstudio_lib/SpaceTypesGridView.hpp +++ b/src/openstudio_lib/SpaceTypesGridView.hpp @@ -8,7 +8,7 @@ #include "../shared_gui_components/OSGridController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpaceTypesTabController.cpp b/src/openstudio_lib/SpaceTypesTabController.cpp index c4c8702ff..fba0fa16c 100644 --- a/src/openstudio_lib/SpaceTypesTabController.cpp +++ b/src/openstudio_lib/SpaceTypesTabController.cpp @@ -5,7 +5,7 @@ #include "SpaceTypesTabController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "SpaceTypeInspectorView.hpp" #include "SpaceTypesController.hpp" #include "SpaceTypesTabView.hpp" diff --git a/src/openstudio_lib/SpaceTypesView.cpp b/src/openstudio_lib/SpaceTypesView.cpp index 1bac2cd7d..a40473ca1 100644 --- a/src/openstudio_lib/SpaceTypesView.cpp +++ b/src/openstudio_lib/SpaceTypesView.cpp @@ -4,12 +4,10 @@ ***********************************************************************************************************************/ #include "SpaceTypesView.hpp" - #include "ModelObjectListView.hpp" -#include "OSItem.hpp" #include "SpaceTypeInspectorView.hpp" -#include "../openstudio_lib/OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesDaylightingGridView.cpp b/src/openstudio_lib/SpacesDaylightingGridView.cpp index 72cecc94f..99aac4db9 100644 --- a/src/openstudio_lib/SpacesDaylightingGridView.cpp +++ b/src/openstudio_lib/SpacesDaylightingGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesDaylightingGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "../shared_gui_components/OSGridView.hpp" diff --git a/src/openstudio_lib/SpacesDaylightingGridView.hpp b/src/openstudio_lib/SpacesDaylightingGridView.hpp index 6af30ba2d..4830780c8 100644 --- a/src/openstudio_lib/SpacesDaylightingGridView.hpp +++ b/src/openstudio_lib/SpacesDaylightingGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesInteriorPartitionsGridView.cpp b/src/openstudio_lib/SpacesInteriorPartitionsGridView.cpp index a7637bb2e..b3388c200 100644 --- a/src/openstudio_lib/SpacesInteriorPartitionsGridView.cpp +++ b/src/openstudio_lib/SpacesInteriorPartitionsGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesInteriorPartitionsGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesInteriorPartitionsGridView.hpp b/src/openstudio_lib/SpacesInteriorPartitionsGridView.hpp index 351b99615..79cb2ed60 100644 --- a/src/openstudio_lib/SpacesInteriorPartitionsGridView.hpp +++ b/src/openstudio_lib/SpacesInteriorPartitionsGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesLoadsGridView.cpp b/src/openstudio_lib/SpacesLoadsGridView.cpp index 7f74266be..f9b0f7a4b 100644 --- a/src/openstudio_lib/SpacesLoadsGridView.cpp +++ b/src/openstudio_lib/SpacesLoadsGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesLoadsGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesLoadsGridView.hpp b/src/openstudio_lib/SpacesLoadsGridView.hpp index 9b537746b..2d1654f15 100644 --- a/src/openstudio_lib/SpacesLoadsGridView.hpp +++ b/src/openstudio_lib/SpacesLoadsGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesShadingGridView.cpp b/src/openstudio_lib/SpacesShadingGridView.cpp index be3c267a0..582932a7c 100644 --- a/src/openstudio_lib/SpacesShadingGridView.cpp +++ b/src/openstudio_lib/SpacesShadingGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesShadingGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesShadingGridView.hpp b/src/openstudio_lib/SpacesShadingGridView.hpp index b776aadea..85344bc6a 100644 --- a/src/openstudio_lib/SpacesShadingGridView.hpp +++ b/src/openstudio_lib/SpacesShadingGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesSpacesGridView.cpp b/src/openstudio_lib/SpacesSpacesGridView.cpp index 2e9ae6ab7..4bf68b649 100644 --- a/src/openstudio_lib/SpacesSpacesGridView.cpp +++ b/src/openstudio_lib/SpacesSpacesGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesSpacesGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesSpacesGridView.hpp b/src/openstudio_lib/SpacesSpacesGridView.hpp index 79d6e2a47..04a2ba0bb 100644 --- a/src/openstudio_lib/SpacesSpacesGridView.hpp +++ b/src/openstudio_lib/SpacesSpacesGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesSubsurfacesGridView.cpp b/src/openstudio_lib/SpacesSubsurfacesGridView.cpp index 769578210..0358dc69c 100644 --- a/src/openstudio_lib/SpacesSubsurfacesGridView.cpp +++ b/src/openstudio_lib/SpacesSubsurfacesGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesSubsurfacesGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesSubsurfacesGridView.hpp b/src/openstudio_lib/SpacesSubsurfacesGridView.hpp index 2a2aab5ff..9a688f35f 100644 --- a/src/openstudio_lib/SpacesSubsurfacesGridView.hpp +++ b/src/openstudio_lib/SpacesSubsurfacesGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesSubtabGridView.hpp b/src/openstudio_lib/SpacesSubtabGridView.hpp index 9540ba030..d958ba667 100644 --- a/src/openstudio_lib/SpacesSubtabGridView.hpp +++ b/src/openstudio_lib/SpacesSubtabGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "GridViewSubTab.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/SpacesSurfacesGridView.cpp b/src/openstudio_lib/SpacesSurfacesGridView.cpp index 1f6d68ddb..00476f25d 100644 --- a/src/openstudio_lib/SpacesSurfacesGridView.cpp +++ b/src/openstudio_lib/SpacesSurfacesGridView.cpp @@ -5,7 +5,7 @@ #include "SpacesSurfacesGridView.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "OSItemSelectorButtons.hpp" #include "../shared_gui_components/OSCheckBox.hpp" diff --git a/src/openstudio_lib/SpacesSurfacesGridView.hpp b/src/openstudio_lib/SpacesSurfacesGridView.hpp index 08bec340d..31f70d99d 100644 --- a/src/openstudio_lib/SpacesSurfacesGridView.hpp +++ b/src/openstudio_lib/SpacesSurfacesGridView.hpp @@ -9,7 +9,7 @@ #include "../shared_gui_components/OSGridController.hpp" #include "SpacesSubtabGridView.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/StandardsInformationConstructionWidget.cpp b/src/openstudio_lib/StandardsInformationConstructionWidget.cpp index bfbd39bbb..edf3e2c46 100644 --- a/src/openstudio_lib/StandardsInformationConstructionWidget.cpp +++ b/src/openstudio_lib/StandardsInformationConstructionWidget.cpp @@ -5,7 +5,7 @@ #include "StandardsInformationConstructionWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" diff --git a/src/openstudio_lib/StandardsInformationMaterialWidget.cpp b/src/openstudio_lib/StandardsInformationMaterialWidget.cpp index 2d6b4b4c4..9d33f12c4 100644 --- a/src/openstudio_lib/StandardsInformationMaterialWidget.cpp +++ b/src/openstudio_lib/StandardsInformationMaterialWidget.cpp @@ -5,7 +5,7 @@ #include "StandardsInformationMaterialWidget.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSLineEdit.hpp" diff --git a/src/openstudio_lib/SteamEquipmentInspectorView.cpp b/src/openstudio_lib/SteamEquipmentInspectorView.cpp index 33df9a30e..ba1ab9f7b 100644 --- a/src/openstudio_lib/SteamEquipmentInspectorView.cpp +++ b/src/openstudio_lib/SteamEquipmentInspectorView.cpp @@ -6,7 +6,7 @@ #include "SteamEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include #include #include diff --git a/src/openstudio_lib/SubTabController.cpp b/src/openstudio_lib/SubTabController.cpp index 6f3f73303..44732aa65 100644 --- a/src/openstudio_lib/SubTabController.cpp +++ b/src/openstudio_lib/SubTabController.cpp @@ -6,7 +6,7 @@ #include "SubTabController.hpp" #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectListView.hpp" #include "ModelObjectTypeListView.hpp" #include "OSAppBase.hpp" diff --git a/src/openstudio_lib/SubTabView.cpp b/src/openstudio_lib/SubTabView.cpp index 2d8dd1f8f..d51c50c77 100644 --- a/src/openstudio_lib/SubTabView.cpp +++ b/src/openstudio_lib/SubTabView.cpp @@ -8,7 +8,7 @@ #include "OSItemSelectorButtons.hpp" #include "ModelObjectListView.hpp" #include "ModelObjectTypeListView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectInspectorView.hpp" #include diff --git a/src/openstudio_lib/ThermalZonesController.cpp b/src/openstudio_lib/ThermalZonesController.cpp index 150ce6b3d..d2b7c39bc 100644 --- a/src/openstudio_lib/ThermalZonesController.cpp +++ b/src/openstudio_lib/ThermalZonesController.cpp @@ -8,7 +8,7 @@ #include "OSAppBase.hpp" #include "OSDocument.hpp" #include "OSItemSelectorButtons.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "ThermalZonesView.hpp" #include diff --git a/src/openstudio_lib/ThermalZonesGridView.cpp b/src/openstudio_lib/ThermalZonesGridView.cpp index c692d3123..ff7e37a60 100644 --- a/src/openstudio_lib/ThermalZonesGridView.cpp +++ b/src/openstudio_lib/ThermalZonesGridView.cpp @@ -6,11 +6,11 @@ #include "ThermalZonesGridView.hpp" #include "ModelObjectInspectorView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelSubTabView.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSCheckBox.hpp" #include "../shared_gui_components/OSGridView.hpp" diff --git a/src/openstudio_lib/ThermalZonesGridView.hpp b/src/openstudio_lib/ThermalZonesGridView.hpp index fc7e9a7aa..e9c9d6afb 100644 --- a/src/openstudio_lib/ThermalZonesGridView.hpp +++ b/src/openstudio_lib/ThermalZonesGridView.hpp @@ -7,7 +7,7 @@ #define OPENSTUDIO_THERMALZONESGRIDVIEW_HPP #include "../shared_gui_components/OSGridController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include diff --git a/src/openstudio_lib/ThermalZonesTabController.cpp b/src/openstudio_lib/ThermalZonesTabController.cpp index 6c0d2aa6e..2200c2913 100644 --- a/src/openstudio_lib/ThermalZonesTabController.cpp +++ b/src/openstudio_lib/ThermalZonesTabController.cpp @@ -5,7 +5,7 @@ #include "ThermalZonesTabController.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "ThermalZonesController.hpp" #include "ThermalZonesTabView.hpp" #include "ThermalZonesView.hpp" diff --git a/src/openstudio_lib/UtilityBillAllFuelTypesListView.cpp b/src/openstudio_lib/UtilityBillAllFuelTypesListView.cpp index c43cbc0a9..e7461e87b 100644 --- a/src/openstudio_lib/UtilityBillAllFuelTypesListView.cpp +++ b/src/openstudio_lib/UtilityBillAllFuelTypesListView.cpp @@ -6,10 +6,10 @@ #include "UtilityBillAllFuelTypesListView.hpp" #include "ModelObjectTypeItem.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "ModelObjectListView.hpp" #include "OSCollapsibleItemHeader.hpp" -#include "OSItem.hpp" +#include "../shared_gui_components/OSItem.hpp" #include "UtilityBillFuelTypeItem.hpp" #include "UtilityBillFuelTypeListView.hpp" diff --git a/src/openstudio_lib/UtilityBillFuelTypeListView.cpp b/src/openstudio_lib/UtilityBillFuelTypeListView.cpp index 615db288b..1aeb9e6e6 100644 --- a/src/openstudio_lib/UtilityBillFuelTypeListView.cpp +++ b/src/openstudio_lib/UtilityBillFuelTypeListView.cpp @@ -5,7 +5,7 @@ #include "UtilityBillFuelTypeListView.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "OSItemList.hpp" #include "OSAppBase.hpp" diff --git a/src/openstudio_lib/UtilityBillsView.cpp b/src/openstudio_lib/UtilityBillsView.cpp index c66db582c..006ad22e3 100644 --- a/src/openstudio_lib/UtilityBillsView.cpp +++ b/src/openstudio_lib/UtilityBillsView.cpp @@ -5,8 +5,8 @@ #include "UtilityBillsView.hpp" -#include "OSItem.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include "UtilityBillFuelTypeListView.hpp" #include "UtilityBillAllFuelTypesListView.hpp" @@ -48,8 +48,8 @@ namespace openstudio { UtilityBillsView::UtilityBillsView(const openstudio::model::Model& model, QWidget* parent) : ModelSubTabView( - new UtilityBillAllFuelTypesListView(UtilityBillsView::utilityBillFuelTypesAndNames(), model, true, OSItemType::CollapsibleListHeader, parent), - new UtilityBillsInspectorView(model, parent), false, parent) { + new UtilityBillAllFuelTypesListView(UtilityBillsView::utilityBillFuelTypesAndNames(), model, true, OSItemType::CollapsibleListHeader, parent), + new UtilityBillsInspectorView(model, parent), false, parent) { connect(dynamic_cast(modelObjectInspectorView()), &UtilityBillsInspectorView::enableAddNewObjectButton, this, &UtilityBillsView::enableAddNewObjectButton); } diff --git a/src/openstudio_lib/VRFController.cpp b/src/openstudio_lib/VRFController.cpp index 46e272e40..3ba315e4b 100644 --- a/src/openstudio_lib/VRFController.cpp +++ b/src/openstudio_lib/VRFController.cpp @@ -7,9 +7,9 @@ #include "VRFGraphicsItems.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" -#include "OSItem.hpp" -#include "ModelObjectItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "MainWindow.hpp" #include "MainRightColumnController.hpp" #include @@ -120,7 +120,7 @@ void VRFController::refreshNow() { void VRFController::onVRFSystemViewDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromComponentLibrary(itemid)) { if (boost::optional mo = doc->getModelObject(itemid)) { @@ -161,7 +161,7 @@ void VRFController::onVRFSystemViewDrop(const OSItemId& itemid) { void VRFController::onVRFSystemViewZoneDrop(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); if (doc->fromModel(itemid)) { boost::optional mo = doc->getModelObject(itemid); @@ -220,7 +220,7 @@ void VRFController::onVRFTerminalViewDrop(const OSItemId& terminalId, const OSIt void VRFController::onRemoveZoneClicked(const OSItemId& terminalId) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); boost::optional mo = doc->getModelObject(terminalId); OS_ASSERT(mo); @@ -234,7 +234,7 @@ void VRFController::onRemoveZoneClicked(const OSItemId& terminalId) { void VRFController::onRemoveTerminalClicked(const OSItemId& terminalId) { OS_ASSERT(m_currentSystem); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); boost::optional mo = doc->getModelObject(terminalId); OS_ASSERT(mo); @@ -249,7 +249,7 @@ void VRFController::onRemoveTerminalClicked(const OSItemId& terminalId) { void VRFController::zoomInOnSystem(const model::AirConditionerVariableRefrigerantFlow& system) { m_currentSystem = system; - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); model::OptionalModelObject mo; doc->mainRightColumnController()->inspectModelObject(mo, false); @@ -271,7 +271,7 @@ void VRFController::zoomOutToSystemGridView() { m_currentSystem = boost::none; model::OptionalModelObject mo; - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); doc->mainRightColumnController()->inspectModelObject(mo, false); m_vrfSystemListController->reset(); @@ -288,7 +288,7 @@ void VRFController::inspectOSItem(const OSItemId& itemid) { OS_ASSERT(m_currentSystem); boost::optional mo = m_currentSystem->model().getModelObject(toUUID(itemid.itemId())); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + OSDocument* doc = OSAppBase::instance()->currentDocument(); OS_ASSERT(doc); doc->mainRightColumnController()->inspectModelObject(mo, false); } diff --git a/src/openstudio_lib/VRFGraphicsItems.cpp b/src/openstudio_lib/VRFGraphicsItems.cpp index dcb59b3e8..c8d4eb699 100644 --- a/src/openstudio_lib/VRFGraphicsItems.cpp +++ b/src/openstudio_lib/VRFGraphicsItems.cpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "OSItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "VRFGraphicsItems.hpp" #include #include "../shared_gui_components/Buttons.hpp" diff --git a/src/openstudio_lib/VRFGraphicsItems.hpp b/src/openstudio_lib/VRFGraphicsItems.hpp index b94f7400a..a3c59a24d 100644 --- a/src/openstudio_lib/VRFGraphicsItems.hpp +++ b/src/openstudio_lib/VRFGraphicsItems.hpp @@ -7,8 +7,8 @@ #define OPENSTUDIO_VRFGRAPHICSITEMS_HPP #include -#include "OSItem.hpp" -#include "OSDropZone.hpp" +#include "../shared_gui_components/OSItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" #include "../shared_gui_components/OSListController.hpp" #include "../shared_gui_components/GraphicsItems.hpp" diff --git a/src/openstudio_lib/WaterUseEquipmentInspectorView.cpp b/src/openstudio_lib/WaterUseEquipmentInspectorView.cpp index 0ab53ac02..51e78fa83 100644 --- a/src/openstudio_lib/WaterUseEquipmentInspectorView.cpp +++ b/src/openstudio_lib/WaterUseEquipmentInspectorView.cpp @@ -6,8 +6,8 @@ #include "WaterUseEquipmentInspectorView.hpp" #include "../shared_gui_components/OSLineEdit.hpp" #include "../shared_gui_components/OSQuantityEdit.hpp" -#include "OSDropZone.hpp" -#include "ModelObjectItem.hpp" +#include "../shared_gui_components/OSDropZone.hpp" +#include "../shared_gui_components/ModelObjectItem.hpp" #include #include #include diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index a78df6f8d..db3d1c52e 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -316,7 +316,7 @@ void YearSettingsWidget::refresh() { //boost::optional epwFile; //boost::optional weatherFile = m_model.getOptionalUniqueModelObject(); //if (weatherFile) { - //std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + //OSDocument* doc = OSAppBase::instance()->currentDocument(); //openstudio::path resourcesPath = openstudio::toPath(doc->modelTempDir()) / openstudio::toPath("resources"); //epwFile = weatherFile->file(resourcesPath); //} diff --git a/src/openstudio_lib/test/OSDropZone_GTest.cpp b/src/openstudio_lib/test/OSDropZone_GTest.cpp index c2be7412e..115c17445 100644 --- a/src/openstudio_lib/test/OSDropZone_GTest.cpp +++ b/src/openstudio_lib/test/OSDropZone_GTest.cpp @@ -7,7 +7,7 @@ #include "OpenStudioLibFixture.hpp" -#include "../OSDropZone.hpp" +#include "../../shared_gui_components/OSDropZone.hpp" #include "../../shared_gui_components/OSConcepts.hpp" #include @@ -49,4 +49,4 @@ TEST_F(OpenStudioLibFixture, OSDropZone) { ModelObjectIsDefaulted(std::bind(&DropZoneConcept::isDefaulted, dropZoneConcept.data(), space1))); processEvents(); -} \ No newline at end of file +} diff --git a/src/openstudio_lib/test/OpenStudioLibFixture.cpp b/src/openstudio_lib/test/OpenStudioLibFixture.cpp index 636906b79..4d563d0a5 100644 --- a/src/openstudio_lib/test/OpenStudioLibFixture.cpp +++ b/src/openstudio_lib/test/OpenStudioLibFixture.cpp @@ -9,7 +9,7 @@ #include "../DesignDayGridView.hpp" #include "../GridViewSubTab.hpp" -#include "../OSDropZone.hpp" +#include "../../shared_gui_components/OSDropZone.hpp" #include "../../shared_gui_components/OSCellWrapper.hpp" #include "../../shared_gui_components/OSGridController.hpp" #include "../../shared_gui_components/OSGridView.hpp" diff --git a/src/shared_gui_components/BaseApp.hpp b/src/shared_gui_components/BaseApp.hpp index b5917c91e..08330fc92 100644 --- a/src/shared_gui_components/BaseApp.hpp +++ b/src/shared_gui_components/BaseApp.hpp @@ -6,35 +6,34 @@ #ifndef SHAREDGUICOMPONENTS_BASEAPP_HPP #define SHAREDGUICOMPONENTS_BASEAPP_HPP -#include +#include "BaseDocument.hpp" +#include "LocalLibrary.hpp" +#include "OSItemId.hpp" + +#include "../openstudio_qt_utils/QMetaTypes.hpp" + #include #include -#include "../openstudio_qt_utils/QMetaTypes.hpp" +#include -#include #include +#include #include //#include "EditController.hpp" +#include +#include #include #include -#include namespace openstudio { class MeasureManager; class EditController; +class OSItem; class Workspace; -//namespace analysisdriver { -// class SimpleProject; -//} - -namespace model { -class Model; -} - /** - * BaseApp is the pure abstract interface through which all shared GUI components access + * BaseApp is the **pure virtual interface** through which all shared GUI components access * application services. It lives in openstudio_shared_gui (a lower-level library) and * deliberately has no dependency on OSAppBase, OSDocument, or any openstudio_lib symbol. * @@ -43,9 +42,9 @@ class Model; * queries, CLI mode flag, inspector focus state, etc.). * - Be reachable process-wide via BaseApp::instance(), which down-casts qApp * (safe because OSAppBase inherits both QApplication and BaseApp). - * - Provide safe default implementations for optional capabilities (BCL queries return - * empty/none; useClassicCLI returns false) so that lightweight hosts such as test - * fixtures do not need to implement every method. + * + * Every method is pure virtual — OSAppBase (in openstudio_lib) provides all implementations, + * each marked `final`. * * Dependency rule: * shared_gui_components → BaseApp (this file, no openstudio_lib symbols) @@ -85,32 +84,26 @@ class BaseApp virtual bool mouseOverInspectorView() = 0; /// Whether the application is using the classic (legacy) CLI rather than the Labs CLI. - virtual bool useClassicCLI() const { - return false; - } + virtual bool useClassicCLI() const = 0; /// Disable the document UI (e.g. while a drop operation is in progress). - virtual void disableDocument() {} + virtual void disableDocument() = 0; /// Re-enable the document UI after a disable call. - virtual void enableDocument() {} + virtual void enableDocument() = 0; - /// BCL document queries — default implementations return empty/none for contexts without a document. - virtual boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const { - return boost::none; - } - virtual boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const { - return boost::none; - } - virtual std::vector getLocalMeasures() const { - return {}; - } - virtual std::size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const { - return 0; - } - virtual std::size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const { - return 0; - } + /// BCL document queries. + virtual boost::optional getLocalComponent(const std::string& uid, const std::string& versionId = "") const = 0; + virtual boost::optional getLocalMeasure(const std::string& uid, const std::string& versionId = "") const = 0; + virtual std::vector getLocalMeasures() const = 0; + virtual std::size_t removeOutdatedLocalComponents(const std::string& uid, const std::string& currentVersionId) const = 0; + virtual std::size_t removeOutdatedLocalMeasures(const std::string& uid, const std::string& currentVersionId) const = 0; + + /// Returns the current document, or nullptr if no document is open. + virtual BaseDocument* currentDocument() const = 0; + + /// Factory: create the correct OSItem subclass for a given id. + virtual OSItem* makeItem(const OSItemId& itemId, OSItemType osItemType) = 0; }; } // namespace openstudio diff --git a/src/shared_gui_components/BaseDocument.hpp b/src/shared_gui_components/BaseDocument.hpp new file mode 100644 index 000000000..0770cbe71 --- /dev/null +++ b/src/shared_gui_components/BaseDocument.hpp @@ -0,0 +1,102 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef SHAREDGUICOMPONENTS_BASEDOCUMENT_HPP +#define SHAREDGUICOMPONENTS_BASEDOCUMENT_HPP + +#include "OSItemId.hpp" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace openstudio { + +/** + * BaseDocument is the **pure virtual interface** through which shared_gui_components code accesses + * the current open document. It lives in openstudio_shared_gui and has no dependency on + * OSDocument or any other openstudio_lib symbol. + * + * OSDocument (in openstudio_lib) inherits from BaseDocument and provides the real + * implementations. Every method is pure virtual — there are no default implementations. + * + * Dependency rule: + * shared_gui_components → BaseDocument (this file, no openstudio_lib symbols) + * openstudio_lib → OSDocument (implements BaseDocument) + */ +class BaseDocument +{ + public: + virtual ~BaseDocument() {} + + /// Returns true if the item originated from the BCL (Building Component Library). + virtual bool fromBCL(const OSItemId& itemId) const = 0; + + /// Returns true if the item originated from the component library. + virtual bool fromComponentLibrary(const OSItemId& itemId) const = 0; + + /// Look up the IDD object type for an item (used to find the correct icon). + virtual boost::optional getIddObjectType(const OSItemId& itemId) const = 0; + + /// Resolve an OSItemId to a model object in the current document. + virtual boost::optional getModelObject(const OSItemId& itemId) const = 0; + + /// Retrieve the BCL component identified by an OSItemId. + virtual boost::optional getComponent(const OSItemId& itemId) const = 0; + + // ------------------------------------------------------------------------- + // Document state — safe SDK/Qt return types, no openstudio_lib dependency. + // ------------------------------------------------------------------------- + + /// Returns true if the document has unsaved changes. + virtual bool modified() const = 0; + + /// Returns the string path to the location where the document is saved. + /// Returns an empty string if the document has never been saved. + virtual QString savePath() const = 0; + + /// Returns the path to the directory where model resources are stored. + virtual QString modelTempDir() const = 0; + + /// Returns the live model associated with this document. + virtual model::Model model() = 0; + + /// Returns the component library associated with this document. + virtual model::Model componentLibrary() const = 0; + + /// Returns true if the OSItemId refers to an object in the live model. + virtual bool fromModel(const OSItemId& itemId) const = 0; + + /// Search BCL components by attribute key/value pairs. + virtual std::vector componentAttributeSearch(const std::vector>& pairs) const = 0; + + /// Mark the document as modified (unsaved changes). + virtual void markAsModified() = 0; + + /// Mark the document as unmodified (no unsaved changes). + virtual void markAsUnmodified() = 0; + + /// Disable the document UI (e.g. while a drop or run operation is in progress). + virtual void disable() = 0; + + /// Re-enable the document UI. + virtual void enable() = 0; + + /// Open the inspector sidebar panel. + virtual void openSidebar() = 0; +}; + +} // namespace openstudio + +#endif // SHAREDGUICOMPONENTS_BASEDOCUMENT_HPP diff --git a/src/shared_gui_components/CMakeLists.txt b/src/shared_gui_components/CMakeLists.txt index 60f35b292..d164eb6d1 100644 --- a/src/shared_gui_components/CMakeLists.txt +++ b/src/shared_gui_components/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${QT_INCLUDES}) set(${target_name}_src BaseApp.hpp + BaseDocument.hpp BCLMeasureDialog.cpp BCLMeasureDialog.hpp BuildingComponentDialog.cpp @@ -72,7 +73,14 @@ set(${target_name}_src OSGridController.hpp OSGridView.cpp OSGridView.hpp + OSItem.cpp + OSItem.hpp + OSItemId.cpp OSItemId.hpp + OSDropZone.cpp + OSDropZone.hpp + ModelObjectItem.cpp + ModelObjectItem.hpp OSIntegerEdit.cpp OSIntegerEdit.hpp OSLineEdit.cpp @@ -156,6 +164,9 @@ set(${target_name}_moc OSDragableView.hpp OSGridController.hpp OSGridView.hpp + OSItem.hpp + OSDropZone.hpp + ModelObjectItem.hpp OSIntegerEdit.hpp OSLineEdit.hpp OSListController.hpp diff --git a/src/shared_gui_components/LocalLibraryController.cpp b/src/shared_gui_components/LocalLibraryController.cpp index e6f0cae8e..e55a18c79 100644 --- a/src/shared_gui_components/LocalLibraryController.cpp +++ b/src/shared_gui_components/LocalLibraryController.cpp @@ -13,8 +13,6 @@ #include "OSListView.hpp" #include "OSViewSwitcher.hpp" - - #include "MeasureBadge.hpp" #include "UserSettings.hpp" diff --git a/src/openstudio_lib/ModelObjectItem.cpp b/src/shared_gui_components/ModelObjectItem.cpp similarity index 97% rename from src/openstudio_lib/ModelObjectItem.cpp rename to src/shared_gui_components/ModelObjectItem.cpp index 0cfdec76c..8c417a9d1 100644 --- a/src/openstudio_lib/ModelObjectItem.cpp +++ b/src/shared_gui_components/ModelObjectItem.cpp @@ -5,21 +5,19 @@ #include "ModelObjectItem.hpp" +#include "MeasureBadge.hpp" #include "OSItem.hpp" -#include "../shared_gui_components/MeasureBadge.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" -#include -#include #include #include - -#include "../openstudio_qt_utils/Utilities.hpp" +#include +#include +#include #include -#include - namespace openstudio { OSItemId modelObjectToItemId(const openstudio::model::ModelObject& modelObject, bool isDefaulted) { diff --git a/src/openstudio_lib/ModelObjectItem.hpp b/src/shared_gui_components/ModelObjectItem.hpp similarity index 100% rename from src/openstudio_lib/ModelObjectItem.hpp rename to src/shared_gui_components/ModelObjectItem.hpp diff --git a/src/shared_gui_components/OSCellWrapper.cpp b/src/shared_gui_components/OSCellWrapper.cpp index 8adb8475e..c85559fb1 100644 --- a/src/shared_gui_components/OSCellWrapper.cpp +++ b/src/shared_gui_components/OSCellWrapper.cpp @@ -17,7 +17,7 @@ #include "OSUnsignedEdit.hpp" #include "OSWidgetHolder.hpp" -#include "../openstudio_lib/OSDropZone.hpp" +#include "OSDropZone.hpp" #include "RenderingColorWidget2.hpp" #include diff --git a/src/openstudio_lib/OSDropZone.cpp b/src/shared_gui_components/OSDropZone.cpp similarity index 96% rename from src/openstudio_lib/OSDropZone.cpp rename to src/shared_gui_components/OSDropZone.cpp index cdf429d31..50060c02b 100644 --- a/src/openstudio_lib/OSDropZone.cpp +++ b/src/shared_gui_components/OSDropZone.cpp @@ -5,15 +5,11 @@ #include "OSDropZone.hpp" -#include "../shared_gui_components/IconLibrary.hpp" -#include "InspectorController.hpp" -#include "InspectorView.hpp" -#include "MainRightColumnController.hpp" +#include "BaseApp.hpp" +#include "IconLibrary.hpp" #include "ModelObjectItem.hpp" -#include "OSAppBase.hpp" -#include "OSDocument.hpp" #include "OSItem.hpp" -#include "../shared_gui_components/OSVectorController.hpp" +#include "OSVectorController.hpp" #include #include @@ -655,7 +651,14 @@ void OSDropZone2::dragEnterEvent(QDragEnterEvent* event) { void OSDropZone2::dropEvent(QDropEvent* event) { event->accept(); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); + BaseApp* app = BaseApp::instance(); + if (!app) { + return; + } + BaseDocument* doc = app->currentDocument(); + if (!doc) { + return; + } if ((event->proposedAction() == Qt::CopyAction) && m_modelObject && m_set) { @@ -668,15 +671,16 @@ void OSDropZone2::dropEvent(QDropEvent* event) { boost::optional componentData; // If what you dragged is from the BCL, then VT it and insert it in model - // TODO: should we modify OSDocument::getModelObject instead? - // DLM: initially thought so but we also want to keep track of the component data as well if (doc->fromBCL(itemId)) { component = doc->getComponent(itemId); if (component) { if (component->primaryObject().optionalCast()) { - componentData = doc->model().insertComponent(*component); - if (componentData) { - modelObject = componentData->primaryComponentObject(); + boost::optional currentModel = app->currentModel(); + if (currentModel) { + componentData = currentModel->insertComponent(*component); + if (componentData) { + modelObject = componentData->primaryComponentObject(); + } } } } @@ -696,7 +700,7 @@ void OSDropZone2::dropEvent(QDropEvent* event) { for (const auto& object : componentData->componentObjects()) { handlesToRemove.push_back(object.handle()); } - doc->model().removeObjects(handlesToRemove); + modelObject->model().removeObjects(handlesToRemove); // removing objects in component will remove component data object via component watcher //componentData->remove(); OS_ASSERT(componentData->handle().isNull()); @@ -757,8 +761,7 @@ void OSDropZone2::focusOutEvent(QFocusEvent* e) { emit inFocus(m_focused, false); - auto mouseOverInspectorView = - OSAppBase::instance()->currentDocument()->mainRightColumnController()->inspectorController()->inspectorView()->mouseOverInspectorView(); + auto mouseOverInspectorView = BaseApp::instance() && BaseApp::instance()->mouseOverInspectorView(); if (!mouseOverInspectorView) { emit itemClicked(nullptr); } diff --git a/src/openstudio_lib/OSDropZone.hpp b/src/shared_gui_components/OSDropZone.hpp similarity index 99% rename from src/openstudio_lib/OSDropZone.hpp rename to src/shared_gui_components/OSDropZone.hpp index 1decf2a85..08334b40c 100644 --- a/src/openstudio_lib/OSDropZone.hpp +++ b/src/shared_gui_components/OSDropZone.hpp @@ -9,7 +9,7 @@ #include "OSItem.hpp" #include // Signal-Slot replacement -#include "../shared_gui_components/FieldMethodTypedefs.hpp" +#include "FieldMethodTypedefs.hpp" #include #include diff --git a/src/shared_gui_components/OSGridController.cpp b/src/shared_gui_components/OSGridController.cpp index 8667d2c5c..ca372d2ee 100644 --- a/src/shared_gui_components/OSGridController.cpp +++ b/src/shared_gui_components/OSGridController.cpp @@ -16,8 +16,8 @@ namespace { #include "OSGridView.hpp" #include "OSObjectSelector.hpp" -#include "../openstudio_lib/ModelObjectItem.hpp" -#include "../openstudio_lib/OSItem.hpp" +#include "ModelObjectItem.hpp" +#include "OSItem.hpp" #include #include diff --git a/src/shared_gui_components/OSGridView.cpp b/src/shared_gui_components/OSGridView.cpp index 76580108c..d17c198f0 100644 --- a/src/shared_gui_components/OSGridView.cpp +++ b/src/shared_gui_components/OSGridView.cpp @@ -23,7 +23,7 @@ #include "../openstudio_qt_utils/Application.hpp" -#include "../openstudio_lib/OSDropZone.hpp" +#include "OSDropZone.hpp" #include #include diff --git a/src/openstudio_lib/OSItem.cpp b/src/shared_gui_components/OSItem.cpp similarity index 76% rename from src/openstudio_lib/OSItem.cpp rename to src/shared_gui_components/OSItem.cpp index dcc8975a4..10d2a181c 100644 --- a/src/openstudio_lib/OSItem.cpp +++ b/src/shared_gui_components/OSItem.cpp @@ -5,21 +5,16 @@ #include "OSItem.hpp" -#include "BCLComponentItem.hpp" -#include "../shared_gui_components/IconLibrary.hpp" +#include "BaseApp.hpp" +#include "IconLibrary.hpp" +#include "MeasureBadge.hpp" #include "ModelObjectItem.hpp" -#include "OSAppBase.hpp" -#include "OSDocument.hpp" -#include "OSDropZone.hpp" -#include "ScriptItem.hpp" -#include "../shared_gui_components/MeasureBadge.hpp" +#include "../openstudio_qt_utils/Utilities.hpp" #include #include -#include "../openstudio_qt_utils/Utilities.hpp" - #include #include #include @@ -34,82 +29,6 @@ namespace openstudio { -const QString OSItemId::BCL_SOURCE_ID = QString("BCL"); - -OSItemId::OSItemId() : m_isDefaulted(false) {} - -OSItemId::OSItemId(const QString& itemId, const QString& sourceId, bool isDefaulted, const QString& otherData) - : m_itemId(itemId), m_sourceId(sourceId), m_otherData(otherData), m_isDefaulted(isDefaulted) {} - -OSItemId::OSItemId(const QMimeData* mimeData) : m_isDefaulted(false) { - QStringList strings = mimeData->text().split(","); - if (!strings.empty()) { - m_itemId = strings[0]; - } - if (strings.size() > 1) { - m_sourceId = strings[1]; - } - if (strings.size() > 2) { - m_isDefaulted = (strings[2] == "True"); - } - if (strings.size() > 3) { - if (strings[3] == "None") { - m_position_.reset(); - } else { - m_position_ = strings[3].toInt(); - } - } - for (int i = 4; i < strings.size(); ++i) { - m_otherData += strings[i]; - if (i < strings.size() - 1) { - m_otherData += ","; - } - } -} - -QString OSItemId::itemId() const { - return m_itemId; -} - -QString OSItemId::sourceId() const { - return m_sourceId; -} - -QString OSItemId::otherData() const { - return m_otherData; -} - -QString OSItemId::mimeDataText() const { - QString isDefaultedString((m_isDefaulted ? "True" : "False")); - QString positonString((m_position_ ? QString::number(m_position_.get()) : "None")); - QString result = m_itemId + "," + m_sourceId + "," + isDefaultedString + "," + positonString + "," + m_otherData; - return result; -} - -bool OSItemId::isDefaulted() const { - return m_isDefaulted; -} - -void OSItemId::setIsDefaulted(bool isDefaulted) { - m_isDefaulted = isDefaulted; -} - -boost::optional OSItemId::position() const { - return m_position_; -} - -void OSItemId::setPosition(int position) { - m_position_ = position; -} - -bool OSItemId::operator==(const OSItemId& other) const { - bool result = false; - if (!this->mimeDataText().isEmpty()) { - result = (this->mimeDataText() == other.mimeDataText()); - } - return result; -} - OSItem::OSItem(const OSItemId& itemId, OSItemType osItemType, QWidget* parent) : QWidget(parent), m_measureBadge(nullptr), @@ -137,28 +56,10 @@ OSItem::OSItem(const OSItemId& itemId, OSItemType osItemType, QWidget* parent) } OSItem* OSItem::makeItem(const OSItemId& itemId, OSItemType osItemType) { - OSItem* result = nullptr; - - OSAppBase* app = OSAppBase::instance(); - - if (itemId.sourceId() == OSItemId::BCL_SOURCE_ID) { - boost::optional comp = OSAppBase::instance()->currentDocument()->getLocalComponent(itemId.itemId().toStdString()); - if (comp) { - result = new BCLComponentItem(comp.get(), osItemType); - } - } else { - boost::optional modelObject = app->currentDocument()->getModelObject(itemId); - if (modelObject) { - result = new ModelObjectItem(*modelObject, itemId.isDefaulted(), osItemType); - } else { - openstudio::path p = openstudio::toPath(itemId.itemId()); - boost::system::error_code ec; - if (openstudio::filesystem::exists(p, ec)) { - result = new ScriptItem(p, osItemType); - } - } + if (BaseApp* app = BaseApp::instance()) { + return app->makeItem(itemId, osItemType); } - return result; + return nullptr; } void OSItem::createLayout() { @@ -179,18 +80,19 @@ void OSItem::createLayout() { mainHLayout->addLayout(leftVBoxLayout); - std::shared_ptr doc = OSAppBase::instance()->currentDocument(); - if (doc) { - boost::optional iddObjectType = doc->getIddObjectType(m_itemId); - if (iddObjectType) { - const QPixmap* pixmap = IconLibrary::Instance().findMiniIcon(iddObjectType->value()); - if (pixmap) { - setLeftPixmap(*pixmap); - } - - pixmap = IconLibrary::Instance().findIcon(iddObjectType->value()); - if (pixmap) { - m_largePixmap = *pixmap; + if (BaseApp* app = BaseApp::instance()) { + if (BaseDocument* doc = app->currentDocument()) { + boost::optional iddObjectType = doc->getIddObjectType(m_itemId); + if (iddObjectType) { + const QPixmap* pixmap = IconLibrary::Instance().findMiniIcon(iddObjectType->value()); + if (pixmap) { + setLeftPixmap(*pixmap); + } + + pixmap = IconLibrary::Instance().findIcon(iddObjectType->value()); + if (pixmap) { + m_largePixmap = *pixmap; + } } } } diff --git a/src/openstudio_lib/OSItem.hpp b/src/shared_gui_components/OSItem.hpp similarity index 97% rename from src/openstudio_lib/OSItem.hpp rename to src/shared_gui_components/OSItem.hpp index d9ace0ad4..6ed4f41bc 100644 --- a/src/openstudio_lib/OSItem.hpp +++ b/src/shared_gui_components/OSItem.hpp @@ -6,8 +6,8 @@ #ifndef OPENSTUDIO_OSITEM_HPP #define OPENSTUDIO_OSITEM_HPP -#include "../shared_gui_components/LocalLibrary.hpp" -#include "../shared_gui_components/OSItemId.hpp" +#include "LocalLibrary.hpp" +#include "OSItemId.hpp" #include #include diff --git a/src/shared_gui_components/OSItemId.cpp b/src/shared_gui_components/OSItemId.cpp new file mode 100644 index 000000000..a0b2f9685 --- /dev/null +++ b/src/shared_gui_components/OSItemId.cpp @@ -0,0 +1,88 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#include "OSItemId.hpp" + +#include + +namespace openstudio { + +const QString OSItemId::BCL_SOURCE_ID = QString("BCL"); + +OSItemId::OSItemId() : m_isDefaulted(false) {} + +OSItemId::OSItemId(const QString& itemId, const QString& sourceId, bool isDefaulted, const QString& otherData) + : m_itemId(itemId), m_sourceId(sourceId), m_otherData(otherData), m_isDefaulted(isDefaulted) {} + +OSItemId::OSItemId(const QMimeData* mimeData) : m_isDefaulted(false) { + QStringList strings = mimeData->text().split(","); + if (!strings.empty()) { + m_itemId = strings[0]; + } + if (strings.size() > 1) { + m_sourceId = strings[1]; + } + if (strings.size() > 2) { + m_isDefaulted = (strings[2] == "True"); + } + if (strings.size() > 3) { + if (strings[3] == "None") { + m_position_.reset(); + } else { + m_position_ = strings[3].toInt(); + } + } + for (int i = 4; i < strings.size(); ++i) { + m_otherData += strings[i]; + if (i < strings.size() - 1) { + m_otherData += ","; + } + } +} + +QString OSItemId::itemId() const { + return m_itemId; +} + +QString OSItemId::sourceId() const { + return m_sourceId; +} + +QString OSItemId::otherData() const { + return m_otherData; +} + +QString OSItemId::mimeDataText() const { + QString isDefaultedString((m_isDefaulted ? "True" : "False")); + QString positonString((m_position_ ? QString::number(m_position_.get()) : "None")); + QString result = m_itemId + "," + m_sourceId + "," + isDefaultedString + "," + positonString + "," + m_otherData; + return result; +} + +bool OSItemId::isDefaulted() const { + return m_isDefaulted; +} + +void OSItemId::setIsDefaulted(bool isDefaulted) { + m_isDefaulted = isDefaulted; +} + +boost::optional OSItemId::position() const { + return m_position_; +} + +void OSItemId::setPosition(int position) { + m_position_ = position; +} + +bool OSItemId::operator==(const OSItemId& other) const { + bool result = false; + if (!this->mimeDataText().isEmpty()) { + result = (this->mimeDataText() == other.mimeDataText()); + } + return result; +} + +} // namespace openstudio diff --git a/src/shared_gui_components/OSLineEdit.cpp b/src/shared_gui_components/OSLineEdit.cpp index 3975cfdf4..090987ba3 100644 --- a/src/shared_gui_components/OSLineEdit.cpp +++ b/src/shared_gui_components/OSLineEdit.cpp @@ -5,9 +5,9 @@ #include "OSLineEdit.hpp" -#include "../openstudio_lib/ModelObjectItem.hpp" +#include "ModelObjectItem.hpp" #include "BaseApp.hpp" -#include "../openstudio_lib/OSItem.hpp" +#include "OSItem.hpp" #include "../openstudio_qt_utils/Utilities.hpp" #include diff --git a/src/shared_gui_components/OSWidgetHolder.cpp b/src/shared_gui_components/OSWidgetHolder.cpp index 59a911e29..b1f6d3e19 100644 --- a/src/shared_gui_components/OSWidgetHolder.cpp +++ b/src/shared_gui_components/OSWidgetHolder.cpp @@ -16,7 +16,7 @@ #include "OSQuantityEdit.hpp" #include "OSUnsignedEdit.hpp" -#include "../openstudio_lib/OSDropZone.hpp" +#include "OSDropZone.hpp" #include #include From 989a66841ed8ce8386b31f0221e1a0a1440eb98d Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 07:58:31 -0600 Subject: [PATCH 19/26] Clang format --- src/openstudio_lib/OSAppBase.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index 282aff416..31d973e53 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -22,7 +22,6 @@ class QEvent; namespace openstudio { - class WaitDialog; /** From fd9565c51d9208b0242e071f67416074f2133085 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 18:15:56 -0600 Subject: [PATCH 20/26] Fix review issues --- src/openstudio_lib/OSAppBase.cpp | 4 ++++ src/shared_gui_components/OSDropZone.cpp | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/openstudio_lib/OSAppBase.cpp b/src/openstudio_lib/OSAppBase.cpp index 5db07acd3..afbb74f5b 100644 --- a/src/openstudio_lib/OSAppBase.cpp +++ b/src/openstudio_lib/OSAppBase.cpp @@ -332,6 +332,10 @@ OSItem* OSAppBase::makeItem(const OSItemId& itemId, OSItemType osItemType) { } if (itemId.sourceId() == OSItemId::BCL_SOURCE_ID) { + // TODO: OSItemId does not carry a versionId — only the uid is stored in itemId.itemId(). + // If multiple versions of the same component are locally installed, getLocalComponent will + // return whichever the BCL finds first. To fix properly, OSItemId should be extended with + // a versionId field and BCLComponentItem should populate it on construction. boost::optional comp = doc->getLocalComponent(itemId.itemId().toStdString()); if (comp) { return new BCLComponentItem(comp.get(), osItemType); diff --git a/src/shared_gui_components/OSDropZone.cpp b/src/shared_gui_components/OSDropZone.cpp index 50060c02b..e197a801b 100644 --- a/src/shared_gui_components/OSDropZone.cpp +++ b/src/shared_gui_components/OSDropZone.cpp @@ -688,12 +688,22 @@ void OSDropZone2::dropEvent(QDropEvent* event) { modelObject = doc->getModelObject(itemId); } - OS_ASSERT(modelObject); + if (!modelObject) { + // BCL component lookup failed (getComponent returned none, insertComponent failed, + // or the item is no longer in the model). Silently ignore the drop — refreshing the + // zone without crashing is the safest fallback. + refresh(); + return; + } bool success = false; if (doc->fromBCL(itemId)) { // model object already cloned above - OS_ASSERT(componentData); + if (!componentData) { + // insertComponent failed — nothing was inserted, nothing to clean up. + refresh(); + return; + } success = (*m_set)(modelObject.get()); if (!success) { std::vector handlesToRemove; From 0fa88b111c482d4adddcd993b12bae96f350e49c Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 18:44:46 -0600 Subject: [PATCH 21/26] Normalize includes and fix Mac warning treated as error --- src/openstudio_lib/CMakeLists.txt | 2 -- src/openstudio_lib/OSAppBase.hpp | 2 +- .../BuildingComponentDialogCentralWidget.hpp | 2 +- src/shared_gui_components/GraphicsItems.cpp | 4 ++-- src/shared_gui_components/SyncMeasuresDialog.cpp | 8 ++++---- .../SyncMeasuresDialogCentralWidget.cpp | 14 +++++++------- .../SyncMeasuresDialogCentralWidget.hpp | 2 +- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index a01c81dd5..d4f06a7a6 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -574,8 +574,6 @@ set(${target_name}_moc ) -#include_directories(SYSTEM ${Ruby_INCLUDE_DIRS}) - # resource files set(${target_name}_qrc openstudio.qrc diff --git a/src/openstudio_lib/OSAppBase.hpp b/src/openstudio_lib/OSAppBase.hpp index 31d973e53..b38d6842e 100644 --- a/src/openstudio_lib/OSAppBase.hpp +++ b/src/openstudio_lib/OSAppBase.hpp @@ -63,7 +63,7 @@ class OSAppBase /// serves both openstudio_lib callers (which get OSDocument*) and shared_gui_components /// callers (which receive the BaseDocument* base pointer). Pure virtual — OpenStudioApp /// owns the document and provides the implementation. - virtual OSDocument* currentDocument() const = 0; + virtual OSDocument* currentDocument() const override = 0; static OSAppBase* instance(); diff --git a/src/shared_gui_components/BuildingComponentDialogCentralWidget.hpp b/src/shared_gui_components/BuildingComponentDialogCentralWidget.hpp index b1e1cc2d5..8a9ce90a9 100644 --- a/src/shared_gui_components/BuildingComponentDialogCentralWidget.hpp +++ b/src/shared_gui_components/BuildingComponentDialogCentralWidget.hpp @@ -17,7 +17,7 @@ #include #include -#include "../shared_gui_components/ProgressBarWithError.hpp" +#include "ProgressBarWithError.hpp" #include diff --git a/src/shared_gui_components/GraphicsItems.cpp b/src/shared_gui_components/GraphicsItems.cpp index 4b0d8983f..bd73d5d2e 100644 --- a/src/shared_gui_components/GraphicsItems.cpp +++ b/src/shared_gui_components/GraphicsItems.cpp @@ -3,8 +3,8 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "../shared_gui_components/GraphicsItems.hpp" -#include "../shared_gui_components/OSListController.hpp" +#include "GraphicsItems.hpp" +#include "OSListController.hpp" #include #include #include diff --git a/src/shared_gui_components/SyncMeasuresDialog.cpp b/src/shared_gui_components/SyncMeasuresDialog.cpp index 568bcc3a5..aa8eb34d4 100644 --- a/src/shared_gui_components/SyncMeasuresDialog.cpp +++ b/src/shared_gui_components/SyncMeasuresDialog.cpp @@ -3,11 +3,11 @@ * See also https://openstudiocoalition.org/about/software_license/ ***********************************************************************************************************************/ -#include "../shared_gui_components/SyncMeasuresDialog.hpp" +#include "SyncMeasuresDialog.hpp" -#include "../shared_gui_components/Component.hpp" -#include "../shared_gui_components/MeasureManager.hpp" -#include "../shared_gui_components/SyncMeasuresDialogCentralWidget.hpp" +#include "Component.hpp" +#include "MeasureManager.hpp" +#include "SyncMeasuresDialogCentralWidget.hpp" #include #include diff --git a/src/shared_gui_components/SyncMeasuresDialogCentralWidget.cpp b/src/shared_gui_components/SyncMeasuresDialogCentralWidget.cpp index ff27076c6..5b8734cb0 100644 --- a/src/shared_gui_components/SyncMeasuresDialogCentralWidget.cpp +++ b/src/shared_gui_components/SyncMeasuresDialogCentralWidget.cpp @@ -5,13 +5,13 @@ #include "SyncMeasuresDialogCentralWidget.hpp" -#include "../shared_gui_components/CollapsibleComponent.hpp" -#include "../shared_gui_components/CollapsibleComponentHeader.hpp" -#include "../shared_gui_components/CollapsibleComponentList.hpp" -#include "../shared_gui_components/Component.hpp" -#include "../shared_gui_components/ComponentList.hpp" -#include "../shared_gui_components/MeasureManager.hpp" -#include "../shared_gui_components/SyncMeasuresDialog.hpp" +#include "CollapsibleComponent.hpp" +#include "CollapsibleComponentHeader.hpp" +#include "CollapsibleComponentList.hpp" +#include "Component.hpp" +#include "ComponentList.hpp" +#include "MeasureManager.hpp" +#include "SyncMeasuresDialog.hpp" #include diff --git a/src/shared_gui_components/SyncMeasuresDialogCentralWidget.hpp b/src/shared_gui_components/SyncMeasuresDialogCentralWidget.hpp index b363f2823..808905150 100644 --- a/src/shared_gui_components/SyncMeasuresDialogCentralWidget.hpp +++ b/src/shared_gui_components/SyncMeasuresDialogCentralWidget.hpp @@ -11,7 +11,7 @@ #include #include -#include "../shared_gui_components/ProgressBarWithError.hpp" +#include "ProgressBarWithError.hpp" class QPushButton; From 7868a041f6c5dff829e20c69866e4be7556142b1 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 21:53:25 -0600 Subject: [PATCH 22/26] Fix issues found on manual review --- .../cpp-refactoring.instructions.md | 2 +- BUILDING.md | 2 +- CMakeLists.txt | 2 +- developer/doc/AddingHVACComponentsToGUI.md | 2 +- developer/doc/architecture.md | 20 +- developer/doc/libraries/bimserver.md | 21 - developer/doc/libraries/model_editor.md | 14 - developer/doc/libraries/openstudio_lib.md | 63 +- .../doc/libraries/openstudio_qt_utils.md | 5 +- .../doc/libraries/shared_gui_components.md | 10 +- developer/ruby/OSMVersionsLib.rb | 2 +- src/model_editor/SketchUpPluginPolicy.xml | 71 - src/model_editor/modeleditorlib.qrc | 1 - src/openstudio_app/OpenStudioApp.cpp | 12 +- src/openstudio_app/OpenStudioApp.hpp | 14 +- src/openstudio_lib/CMakeLists.txt | 7 - src/openstudio_lib/ModelObjectTreeItems.cpp | 1335 ----------------- src/openstudio_lib/ModelObjectTreeItems.hpp | 455 ------ src/openstudio_lib/ModelObjectTreeWidget.cpp | 84 -- src/openstudio_lib/ModelObjectTreeWidget.hpp | 67 - src/openstudio_lib/test/IconLibrary_GTest.cpp | 4 + src/openstudio_lib/test/OSDropZone_GTest.cpp | 4 + src/openstudio_lib/test/OSLineEdit_GTest.cpp | 5 +- .../WorkflowController.cpp | 21 +- 24 files changed, 75 insertions(+), 2148 deletions(-) delete mode 100644 src/model_editor/SketchUpPluginPolicy.xml delete mode 100644 src/openstudio_lib/ModelObjectTreeItems.cpp delete mode 100644 src/openstudio_lib/ModelObjectTreeItems.hpp delete mode 100644 src/openstudio_lib/ModelObjectTreeWidget.cpp delete mode 100644 src/openstudio_lib/ModelObjectTreeWidget.hpp diff --git a/.github/instructions/cpp-refactoring.instructions.md b/.github/instructions/cpp-refactoring.instructions.md index 700f6935b..15b7da6cf 100644 --- a/.github/instructions/cpp-refactoring.instructions.md +++ b/.github/instructions/cpp-refactoring.instructions.md @@ -28,7 +28,7 @@ Within every `.cpp` and `.hpp`, includes must appear in this order, with a blank #include ``` -Do not mix groups. When adding a new include, place it in the correct group in the same edit — not as a deferred cleanup. +Do not mix groups. When adding a new include, place it in the correct group in the same edit — not as a deferred cleanup. Within each group, sort includes alphabetically by filename. --- diff --git a/BUILDING.md b/BUILDING.md index ca476c508..7aa6b240d 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,6 +1,6 @@ # Building with conan v2 -Check you have `conan >= 2`, and add the `nrel-v2` remote to grab `ruby` and `swig/4.1.1`. +Check you have `conan >= 2`, and add the `nrel-v2` remote to grab `ruby`. ```shell conan --version diff --git a/CMakeLists.txt b/CMakeLists.txt index 757ac657e..53f36c60b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1045,7 +1045,7 @@ cpack_add_component(Python cpack_add_component(RubyAPI DISPLAY_NAME "Ruby API" - DESCRIPTION "The Ruby openstudio modeleditor for Sketchup" + DESCRIPTION "The Ruby openstudio modeleditor stub for Sketchup" ) cpack_add_component( diff --git a/developer/doc/AddingHVACComponentsToGUI.md b/developer/doc/AddingHVACComponentsToGUI.md index 038f211d9..c75af3f66 100644 --- a/developer/doc/AddingHVACComponentsToGUI.md +++ b/developer/doc/AddingHVACComponentsToGUI.md @@ -17,7 +17,7 @@ Add two entries to the file `./src/openstudio_lib/openstudio.qrc`. This file registers the image files so that they become resources in the executable. Add one entry for the full size icon and one for the mini icon. -Add two entries to the file `./src/openstudio_lib/IconLibrary.cpp`. +Add two entries to the file `./src/shared_gui_components/IconLibrary.cpp`. This file contains a big map of the new OS type to the proper icon. ## Make the library aware of the new type: diff --git a/developer/doc/architecture.md b/developer/doc/architecture.md index 963481537..193f98519 100644 --- a/developer/doc/architecture.md +++ b/developer/doc/architecture.md @@ -1,6 +1,5 @@ # OpenStudio Application — Architecture Overview -> **Version:** 1.11.0 > **Audience:** Internal team (C++/Qt familiarity assumed) > **Last updated:** See git log @@ -133,7 +132,6 @@ flowchart TD | Formatting | **fmt** | 9.1.0 | String formatting | | Database | **SQLite3** | system | Local results database | | 3D geometry | **TinyGLTF** | — | GLTF import/export | -| Language bindings | **SWIG** | 4.1.1 | Ruby/Python binding generation | | Compiler cache | **ccache / sccache** | any | CI build acceleration | --- @@ -189,7 +187,7 @@ See [BUILDING.md](../../BUILDING.md) for the complete, platform-specific instruc ### 7.1 Tab-Based Master-Detail Pattern -Each major domain (HVAC, Schedules, Constructions, Geometry, etc.) follows a three-class pattern. The **Model** role is played by the OpenStudio SDK model objects (`openstudio::model::Model` and its children); the controller mediates between those objects and two views: +Each major domain (HVAC, Schedules, Constructions, Geometry, etc.) follows a three-class pattern. The **Model** is the OpenStudio SDK — specifically `openstudio::model::Model` and its `ModelObject` subclasses. Controllers read from and mutate these SDK objects directly. Each controller mediates between the SDK model and two views: ```mermaid classDiagram @@ -259,29 +257,21 @@ OpenStudioApp (exe) → shared_gui_components → openstudio_qt_utils → openstudioapp_utilities + → openstudio_modeleditor + → openstudio_qt_utils → openstudio_bimserver → openstudio_qt_utils - → openstudio_modeleditor - → openstudio_qt_utils ``` **The `BaseApp` interface** (`shared_gui_components/BaseApp.hpp`) is the key boundary between the lower-level `shared_gui_components` library and the upper-level `openstudio_lib` library. All `shared_gui_components` code that needs application-level services must go through `BaseApp`, never through `OSAppBase`, `OSDocument`, or `MainWindow` directly. Code that needs document-level services (icon lookup, model-object resolution, drop handling) calls `BaseApp::currentDocument()`, which returns a `BaseDocument*` — another interface in `shared_gui_components` implemented by `OSDocument` in `openstudio_lib`. C++ raw pointer covariance means `OSAppBase::currentDocument()` can override `BaseApp::currentDocument()` while returning the more-derived `OSDocument*`, so a single virtual serves both caller audiences. -**Known violations (tracked as tech debt):** - -None. All boundary violations have been resolved. - --- ## 8. CI/CD Overview -Two parallel CI systems are used: - -| System | Trigger | Purpose | -|---|---|---| -| **GitHub Actions** | PR + push to master/develop + version tags | Full 5-platform build matrix, code signing, release publishing, static analysis, CLA enforcement | +**GitHub Actions** is the sole CI system. It triggers on PRs, pushes to `master`/`develop`, and version tags, running a full 5-platform build matrix (Windows, macOS, Ubuntu 22.04, Ubuntu 24.04, and a packaging pass). It also handles code signing, release publishing, static analysis, and CLA enforcement. -See [ci/overview.md](ci/overview.md) for the full CI/CD architecture documentation, or browse individual workflow docs under [ci/workflows/](ci/workflows/). +Individual workflow files are in [`.github/workflows/`](../../.github/workflows/). --- diff --git a/developer/doc/libraries/bimserver.md b/developer/doc/libraries/bimserver.md index 6a010b032..6d565e7bf 100644 --- a/developer/doc/libraries/bimserver.md +++ b/developer/doc/libraries/bimserver.md @@ -24,35 +24,14 @@ The module offers both **non-blocking (async)** and **blocking** APIs for all op classDiagram class BIMserverConnection { <> - -addr: QString - -port: QString - -manager: QNetworkAccessManager +login(username, password) - +getAllProjects() +download(revisionID) - +createProject(name) - +deleteProject(projectID) - +checkInIFCFile(projectID, path) - +getIFCRevisionList(projectID) +loginBlocked(username, password, timeout) bool - +getAllProjectsBlocked(timeout) optional~QStringList~ +downloadBlocked(projectID, timeout) optional~QString~ - +createProjectBlocked(name, timeout) bool - +deleteProjectBlocked(projectID, timeout) bool - +checkInIFCFileBlocked(projectID, path, timeout) bool - +getIFCRevisionListBlocked(projectID, timeout) optional~QStringList~ - signals: osmStringRetrieved(QString) - signals: listAllProjects(QStringList) - signals: listAllIFCRevisions(QStringList) - signals: operationSucceeded(QString) - signals: errorOccured(QString) - signals: bimserverError() } class ProjectImporter { <> - -connection: BIMserverConnection* +run() optional~Model~ - signals: finished() } ProjectImporter "1" --> "1" BIMserverConnection : owns and drives diff --git a/developer/doc/libraries/model_editor.md b/developer/doc/libraries/model_editor.md index 5db1aa172..ddf99baeb 100644 --- a/developer/doc/libraries/model_editor.md +++ b/developer/doc/libraries/model_editor.md @@ -9,9 +9,7 @@ `model_editor` provides a generic, IDD schema-driven inspector for any OpenStudio `ModelObject` or `WorkspaceObject`. Rather than hand-coding a bespoke widget for every object type, it interrogates the object's IDD definition at runtime and generates the appropriate input controls (spinboxes, comboboxes, labels) automatically. It is used: -- By the SketchUp plugin as a standalone model inspector window - By `openstudio_lib` for the right-column object inspector -- As a debugging tool to inspect arbitrary model objects without domain-specific views --- @@ -32,19 +30,12 @@ classDiagram <> +sizeHint() QSize } - class InspectorDialog { - <> - +setWorkspace(workspace) - +selectedObjectHandles() vector~Handle~ - signals: workspaceChanged, workspaceObjectAdded, workspaceObjectRemoved - } class AccessPolicyStore { <> +loadFile(path) bool +getPolicy(iddObjectType, fieldIndex) AccessPolicy } - InspectorDialog "1" *-- "1" InspectorGadget : embeds InspectorGadget --> AccessPolicyStore : consults for field visibility InspectorGadget *-- IGWidget : renders fields into ``` @@ -53,9 +44,7 @@ classDiagram |---|---|---| | `InspectorGadget` | [InspectorGadget.hpp](../../../src/model_editor/InspectorGadget.hpp) | Core widget. Accepts any `WorkspaceObject` or `ModelObject` and auto-generates input controls from the IDD field definitions. | | `IGWidget` | [InspectorGadget.hpp](../../../src/model_editor/InspectorGadget.hpp) | Lightweight `QWidget` / `Nano::Observer` base used as the scroll area content for the generated controls. | -| `InspectorDialog` | [InspectorDialog.hpp](../../../src/model_editor/InspectorDialog.hpp) | Modal or modeless dialog that hosts an `InspectorGadget`. Can observe a `Workspace` and keeps the display in sync as objects change. | | `AccessPolicyStore` | [AccessPolicyStore.hpp](../../../src/model_editor/AccessPolicyStore.hpp) | Singleton that reads an XML policy file to determine whether each IDD field is `FREE` (editable), `LOCKED` (read-only), or hidden. | -| `GithubReleases` | [GithubReleases.hpp](../../../src/model_editor/GithubReleases.hpp) | Checks GitHub releases API for newer application versions. | | `BridgeClasses` | [BridgeClasses.hpp](../../../src/model_editor/BridgeClasses.hpp) | Adapts OpenStudio nano signals to Qt slots so workspace change notifications reach Qt-connected widgets. | --- @@ -91,8 +80,6 @@ classDiagram |---|---| | `openstudio_qt_utils` | `Application` singleton, `Utilities` (string/UUID/path conversions), `QMetaTypes` (SDK metatype registration), `OSProgressBar` | -> **Note:** `Application`, `OSProgressBar`, `QMetaTypes`, `Utilities`, and `UserSettings` were previously in `model_editor` and have been moved to `openstudio_qt_utils` and `shared_gui_components` respectively. - --- ## Patterns & Conventions @@ -100,7 +87,6 @@ classDiagram - **IDD-driven layout** — the widget layout is entirely data-driven from the OpenStudio IDD schema, requiring no code changes when new object types are added to the SDK. - **Policy file** — `AccessPolicyStore` reads an XML file at startup. To lock or hide a field for a specific object type, edit the policy file rather than the widget code. - **Nano signals (not Qt signals)** — `InspectorGadget` and `IGWidget` use `Nano::Observer` (a lightweight signal-slot system that does not require `QObject`) for model change notifications, minimising MOC overhead. -- **SWIG interface** — `ModelEditor.i` and `Qt.i` are SWIG interface files used to generate Ruby and Python bindings for the model editor library (used by the SketchUp plugin). --- diff --git a/developer/doc/libraries/openstudio_lib.md b/developer/doc/libraries/openstudio_lib.md index 0701b6919..fc6f1adc8 100644 --- a/developer/doc/libraries/openstudio_lib.md +++ b/developer/doc/libraries/openstudio_lib.md @@ -6,9 +6,9 @@ ## Purpose -`openstudio_lib` is the largest module (~200+ source files). It implements the complete building model editing GUI: every tab, every inspector view, every drag-and-drop list, and the geometry editor. It also defines the shared base types (`OSAppBase`, `OSDocument`, `MainWindow`) that the executable and the SketchUp plugin both build upon. +`openstudio_lib` is the largest module (~200+ source files). It implements the complete building model editing GUI: every tab, every inspector view, every drag-and-drop list, and the geometry editor. It also defines the shared base types (`OSAppBase`, `OSDocument`, `MainWindow`) that the OpenStudioApp executable builds upon. -The module follows a consistent **Controller / View / Inspector triad** per domain: a controller manages data access and inter-widget coordination, a tab view provides the domain's layout, and inspector widgets display the selected object's properties. +The module follows a consistent **Controller / View / Inspector triad** per domain. The **Model** layer is the OpenStudio SDK (`openstudio::model::Model` and its `ModelObject` children) — controllers read from and mutate these SDK objects directly, never through an intermediate layer. The controller manages data access and inter-widget coordination, the tab view provides the domain's primary layout, and inspector widgets display the selected object's editable properties. --- @@ -55,41 +55,47 @@ classDiagram OSDocument "1" *-- "1" MainWindow : owns OSDocument "1" *-- "1" MainTabController : owns active OSDocument "1" *-- "1" MainRightColumnController : owns - MainTabController <|-- HVACSystemsTabController - MainTabController <|-- ConstructionsTabController + MainTabController <|-- LocationTabController MainTabController <|-- SchedulesTabController + MainTabController <|-- ConstructionsTabController + MainTabController <|-- LoadsTabController MainTabController <|-- SpaceTypesTabController + MainTabController <|-- GeometryTabController MainTabController <|-- FacilityTabController + MainTabController <|-- SpacesTabController + MainTabController <|-- ThermalZonesTabController + MainTabController <|-- HVACSystemsTabController + MainTabController <|-- VariablesTabController + MainTabController <|-- SimSettingsTabController + MainTabController <|-- ScriptsTabController MainTabController <|-- RunTabController + MainTabController <|-- ResultsTabController ``` --- ## Domain Modules Within `openstudio_lib` -| Domain | Key Controller | Key View | Notes | +| Domain (VerticalTabID) | Key Controller | Key View | Sub-tabs | |---|---|---|---| -| Application shell | `OSAppBase`, `OSDocument` | `MainWindow` | Foundation for all tabs | -| Geometry editor | `GeometryEditorController` | `GeometryEditorView` | Qt WebEngine + JS bridge | -| Geometry preview | `GeometryPreviewController` | `GeometryPreviewView` | Read-only 3D preview | -| HVAC Systems | `HVACSystemsTabController`, `HVACSystemsController` | `HVACSystemsTabView`, `HVACSystemsView` | Loop/service water/VRF scenes | -| Refrigeration | `RefrigerationController`, `RefrigerationGridController` | `RefrigerationView`, `RefrigerationScene` | Custom QGraphicsScene | -| Constructions | `ConstructionsTabController`, `ConstructionsController` | `ConstructionsTabView`, `ConstructionsView` | Many derived inspector views | -| Materials | `MaterialsController` | `MaterialsView` | Per-material inspector views | -| Loads | `LoadsController` | `LoadsView` | Equipment, people, lights inspectors | -| Schedules | `SchedulesTabController`, `SchedulesController` | `SchedulesTabView`, `SchedulesDayView` | Day schedule chart editor | -| Space Types | `SpaceTypesController` | `SpaceTypesGridView`, `SpaceTypeInspectorView` | Grid view | -| Thermal Zones | `ThermalZonesController` | `ThermalZonesGridView` | Grid view | -| Spaces | `SpacesTabController` | Multiple `Spaces*GridView` | Surfaces, loads, shading sub-tabs | -| Facility | `FacilityTabController` | `FacilityStoriesGridView`, `FacilityShadingGridView` | Building stories, shading | -| Simulation Settings | `SimSettingsTabController` | `SimSettingsTabView`, `DesignDayGridView` | Run period, design days | -| Run | `RunTabController` | `RunTabView` | Triggers EnergyPlus | -| Results | `ResultsTabController` | `ResultsTabView` | Post-run output charts | -| Variables | `VariablesTabController` | `VariablesTabView` | EnergyPlus output variables | -| Measures/Scripts | `ScriptsTabController` | `ScriptsTabView` | Measure workflow | -| Utility Bills | `UtilityBillsController` | `UtilityBillsView` | Calibration data | -| Inspector (generic) | `InspectorController` | `InspectorView` | Right-column inspector | -| BCL | — | — | `BCLComponentItem` | +| Application shell | `OSAppBase`, `OSDocument` | `MainWindow` | — | +| Site / Location (0) | `LocationTabController` | `LocationTabView` | Weather File & Design Days · Life Cycle Costs · Utility Bills · Ground Temperatures | +| Schedules (1) | `SchedulesTabController`, `SchedulesController` | `SchedulesTabView`, `SchedulesDayView` | Schedule Sets · Schedules · Other Schedules | +| Constructions (2) | `ConstructionsTabController`, `ConstructionsController` | `ConstructionsTabView`, `ConstructionsView` | Construction Sets · Constructions · Materials | +| Loads (3) | `LoadsTabController`, `LoadsController` | `LoadsView` | *(single grid view)* | +| Space Types (4) | `SpaceTypesTabController`, `SpaceTypesController` | `SpaceTypesGridView`, `SpaceTypeInspectorView` | *(single grid view)* | +| Geometry (5) | `GeometryTabController` | — | 3D View · Editor | +| Facility (6) | `FacilityTabController` | `FacilityTabView` | Building · Stories · Shading · Exterior Equipment | +| Spaces (7) | `SpacesTabController` | Multiple `Spaces*GridView` | Properties · Loads · Surfaces · Subsurfaces · Interior Partitions · Shading | +| Thermal Zones (8) | `ThermalZonesTabController`, `ThermalZonesController` | `ThermalZonesGridView` | *(single grid view)* | +| HVAC Systems (9) | `HVACSystemsTabController`, `HVACSystemsController` | `HVACSystemsTabView`, `HVACSystemsView` | *(single view; `RefrigerationController` accessible via HVAC scene)* | +| Output Variables (10) | `VariablesTabController` | `VariablesTabView` | *(single view)* | +| Simulation Settings (11) | `SimSettingsTabController` | `SimSettingsTabView`, `DesignDayGridView` | *(single view)* | +| Measures/Scripts (12) | `ScriptsTabController` | `ScriptsTabView` | *(single view)* | +| Run (13) | `RunTabController` | `RunTabView` | *(single view)* | +| Results (14) | `ResultsTabController` | `ResultsTabView` | *(single view)* | +| Inspector (generic) | `InspectorController` | `InspectorView` | — | +| BCL | — | — | — | --- @@ -99,11 +105,8 @@ classDiagram |---|---| | `OSItemList` / `OSCollapsibleItem` | Container widgets for ordered lists of `OSItem`s | | `ModelObjectListView` | Generic list view displaying any collection of model objects | -| `ModelObjectTreeWidget` | Generic tree view for hierarchical model data | | `OSWebEnginePage` | `QWebEnginePage` subclass for the geometry JS bridge | -> **Note:** `OSVectorController`, `IconLibrary`, `OSItem`, `OSDropZone`, `ModelObjectItem`, and `OSItemId` have all moved to `shared_gui_components`. - --- ## External Dependencies @@ -128,7 +131,7 @@ classDiagram ## Patterns & Conventions -- **MVC triad** — every domain has a `*TabController`, a `*TabView`, and one or more `*InspectorView` classes. +- **Master-detail MVC** — every domain has a `*TabController` (controller), a `*TabView` (master), and one or more `*InspectorView` classes (detail). - **`OSQObjectController`** — `OSDocument` and most controllers extend `OSQObjectController`, which provides a thread-safe `QObject` parent management pattern. - **Static linking** — all internal libraries are built `STATIC`; no DLL export macros are needed. - **Analytics** — `AnalyticsHelper` sends anonymized usage pings (configurable via `ANALYTICS_API_SECRET`/`ANALYTICS_MEASUREMENT_ID` build-time secrets). diff --git a/developer/doc/libraries/openstudio_qt_utils.md b/developer/doc/libraries/openstudio_qt_utils.md index 39dadec7a..c9a22154e 100644 --- a/developer/doc/libraries/openstudio_qt_utils.md +++ b/developer/doc/libraries/openstudio_qt_utils.md @@ -83,9 +83,6 @@ namespace openstudio { // Retrieve (or lazily create) the QApplication/QCoreApplication QCoreApplication* Application::instance().application(bool gui = true); - // Wrap an existing QApplication created by a host (e.g. SketchUp) - Application::instance().setApplication(QCoreApplication*); - // Cross-module QSettings access Application::hasSetting(const std::string& key); Application::getSettingValueAsBool(const std::string& key); // → boost::optional @@ -136,4 +133,4 @@ namespace openstudio { - **Singleton via local static** — `Application::instance()` uses a function-local `static Application` for thread-safe lazy initialisation (C++11 magic statics). - **Lazy `QApplication` creation** — `application(bool gui)` creates a headless `QCoreApplication` or full `QApplication` only if no `QCoreApplication::instance()` already exists, making it safe to call from both GUI and CLI contexts. -- **Global metatype registration via namespace-scope statics** — the `int __xxx_type = qRegisterMetaType(...)` variables in `QMetaTypes.cpp` run at shared library load time, ensuring types are registered before any signal/slot connection is made. +- **Global metatype registration via namespace-scope statics** — the `int __xxx_type = qRegisterMetaType(...)` variables in `QMetaTypes.cpp` are namespace-scope statics that run at executable start-up (before `main()`), ensuring types are registered before any signal/slot connection is made. diff --git a/developer/doc/libraries/shared_gui_components.md b/developer/doc/libraries/shared_gui_components.md index 6297a3ef4..704b3c733 100644 --- a/developer/doc/libraries/shared_gui_components.md +++ b/developer/doc/libraries/shared_gui_components.md @@ -6,7 +6,7 @@ ## Purpose -`shared_gui_components` provides the reusable Qt widgets and controllers that are shared between the standalone OpenStudio Application and any plugin host (e.g., the SketchUp plugin). It is designed to be independent of the specific application shell, conforming only to the `BaseApp` interface. +`shared_gui_components` provides the reusable Qt widgets and controllers that are used by the standalone OpenStudio Application. It is designed to be independent of the specific application shell, conforming only to the `BaseApp` interface. Key responsibilities: - **Grid system** — a generic multi-column tabular view for OpenStudio model objects @@ -120,8 +120,6 @@ All typed input widgets follow the same pattern: they read from and write to a ` | `OSQuantityEdit` / `OSQuantityEdit2` | Dimensional quantity editor with SI/IP toggle | | `OSOptionalQuantityEdit` | Optional dimensional quantity (blank = unset) | -> **Note:** `OSVectorController`, `OSItemId`, `IconLibrary`, `UserSettings`, `OSItem`, `OSDropZone`, and `ModelObjectItem` are now fully in `shared_gui_components` (previously in `openstudio_lib` or `model_editor`). All document/app operations are routed through `BaseApp` virtual methods. - The `2` suffix variants use `std::function` callbacks instead of `QObject` signal/slot; they are preferred in newer code. --- @@ -170,12 +168,6 @@ flowchart TD --- -## Known Boundary Violations - -None. All cross-library includes have been resolved. `OSItem`, `OSDropZone`, and `ModelObjectItem` are fully in `shared_gui_components`; their former dependencies on `OSAppBase`/`OSDocument` are now routed through `BaseApp` virtual methods. - ---- - ## Patterns & Conventions - **`BaseApp` interface** — all components that need access to the application (e.g., `MeasureManager`, `LocalLibraryController`, `WorkflowController`) use only `BaseApp`, never `OSAppBase`, `OSDocument`, or `MainWindow` directly. `BaseApp` exposes `useClassicCLI()`, `disableDocument()`, and `enableDocument()` so that shared components can call these without depending on `openstudio_lib` types. This keeps the dependency order acyclic. diff --git a/developer/ruby/OSMVersionsLib.rb b/developer/ruby/OSMVersionsLib.rb index 3cda501b1..ffd6f915d 100644 --- a/developer/ruby/OSMVersionsLib.rb +++ b/developer/ruby/OSMVersionsLib.rb @@ -63,7 +63,7 @@ def find_resource_osms() path = File.join(ROOT_DIR, 'src/**/*.osm') files = Dir.glob(path) # Only keep the one we're interested in - files = files.grep(/openstudio_app\/Resources|sketchup_plugin\/resources\/templates|sketchup_plugin\/user_scripts/) + files = files.grep(/openstudio_app\/Resources/) return files end diff --git a/src/model_editor/SketchUpPluginPolicy.xml b/src/model_editor/SketchUpPluginPolicy.xml deleted file mode 100644 index 753a5ccc3..000000000 --- a/src/model_editor/SketchUpPluginPolicy.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/model_editor/modeleditorlib.qrc b/src/model_editor/modeleditorlib.qrc index b96ac6d40..e0c869ec2 100644 --- a/src/model_editor/modeleditorlib.qrc +++ b/src/model_editor/modeleditorlib.qrc @@ -13,7 +13,6 @@ images/me_16.png images/v_devider_dots.png ModalDialogs.qss - SketchUpPluginPolicy.xml ../../resources/openstudio.qss diff --git a/src/openstudio_app/OpenStudioApp.cpp b/src/openstudio_app/OpenStudioApp.cpp index 9c7fdd47b..9567b963b 100644 --- a/src/openstudio_app/OpenStudioApp.cpp +++ b/src/openstudio_app/OpenStudioApp.cpp @@ -931,8 +931,8 @@ void OpenStudioApp::showHelp() { void OpenStudioApp::checkForUpdate() { QWidget* parent = nullptr; - if (currentDocument()) { - parent = currentDocument()->mainWindow(); + if (auto* doc = currentDocument()) { + parent = doc->mainWindow(); } modeleditor::GithubReleases releases("openstudiocoalition", "OpenStudioApplication"); @@ -974,13 +974,13 @@ void OpenStudioApp::debugWebgl() { void OpenStudioApp::showAbout() { QWidget* parent = nullptr; - if (currentDocument()) { - parent = currentDocument()->mainWindow(); + if (auto* doc = currentDocument()) { + parent = doc->mainWindow(); } QString details = tr("Measure Manager Server: ") + measureManager().url().toString() + "\n"; details += tr("Chrome Debugger: http://localhost:") + qgetenv("QTWEBENGINE_REMOTE_DEBUGGING") + "\n"; - if (currentDocument()) { - details += tr("Temp Directory: ") + currentDocument()->modelTempDir(); + if (auto* doc = currentDocument()) { + details += tr("Temp Directory: ") + doc->modelTempDir(); } QMessageBox about(parent); about.setText(OPENSTUDIOAPP_ABOUTBOX); diff --git a/src/openstudio_app/OpenStudioApp.hpp b/src/openstudio_app/OpenStudioApp.hpp index da87d057d..3df934ad1 100644 --- a/src/openstudio_app/OpenStudioApp.hpp +++ b/src/openstudio_app/OpenStudioApp.hpp @@ -86,7 +86,7 @@ class OpenStudioApp : public OSAppBase virtual ~OpenStudioApp(); - virtual OSDocument* currentDocument() const override; + virtual OSDocument* currentDocument() const final; static OpenStudioApp* instance(); @@ -101,14 +101,14 @@ class OpenStudioApp : public OSAppBase // Returns the hard set path (in settings), and or if not set will try to infer it by looking into the current PATH // If all fails, ends up returning an empty path (no need to wrap into a boost::optional (with overhead) for this) - virtual openstudio::path dviewPath() const override; + virtual openstudio::path dviewPath() const final; - virtual bool notify(QObject* receiver, QEvent* event) override; + virtual bool notify(QObject* receiver, QEvent* event) final; protected: - virtual bool event(QEvent* event) override; + virtual bool event(QEvent* event) final; - virtual void childEvent(QChildEvent* event) override; + virtual void childEvent(QChildEvent* event) final; signals: @@ -140,7 +140,7 @@ class OpenStudioApp : public OSAppBase void showAbout(); - virtual void reloadFile(const QString& osmPath, bool modified, bool saveCurrentTabs) override; + virtual void reloadFile(const QString& osmPath, bool modified, bool saveCurrentTabs) final; void revertToSaved(); @@ -159,7 +159,7 @@ class OpenStudioApp : public OSAppBase void changeLanguage(const QString& rLanguage); // Checks what happened in the ExternalToolsDialog preference pane - virtual void configureExternalTools() override; + virtual void configureExternalTools() final; private slots: diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index d4f06a7a6..b2c0313ad 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -165,10 +165,6 @@ set(${target_name}_SRC ModelObjectInspectorView.hpp ModelObjectListView.cpp ModelObjectListView.hpp - ModelObjectTreeItems.cpp - ModelObjectTreeItems.hpp - ModelObjectTreeWidget.cpp - ModelObjectTreeWidget.hpp ModelObjectTypeItem.cpp ModelObjectTypeItem.hpp ModelObjectTypeListView.cpp @@ -383,7 +379,6 @@ set(${target_name}_SRC ZoneChooserView.cpp ZoneChooserView.hpp - #"${CMAKE_CURRENT_BINARY_DIR}/SWIGRubyRuntime.h" ) # moc files @@ -463,8 +458,6 @@ set(${target_name}_moc MaterialsView.hpp ModelObjectInspectorView.hpp ModelObjectListView.hpp - ModelObjectTreeItems.hpp - ModelObjectTreeWidget.hpp ModelObjectTypeItem.hpp ModelObjectTypeListView.hpp ModelObjectVectorController.hpp diff --git a/src/openstudio_lib/ModelObjectTreeItems.cpp b/src/openstudio_lib/ModelObjectTreeItems.cpp deleted file mode 100644 index 59a3cf955..000000000 --- a/src/openstudio_lib/ModelObjectTreeItems.cpp +++ /dev/null @@ -1,1335 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include "ModelObjectTreeItems.hpp" -#include "../shared_gui_components/ModelObjectItem.hpp" -#include "../shared_gui_components/IconLibrary.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../openstudio_qt_utils/Utilities.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace openstudio { - -const OSItemType ModelObjectTreeItem::m_type = ModelObjectTreeItem::initializeOSItemType(); - -OSItemType ModelObjectTreeItem::initializeOSItemType() { - return OSItemType::ListItem; -} - -OSItemType initializeOSItemType(); - -ModelObjectTreeItem::ModelObjectTreeItem(const openstudio::model::ModelObject& modelObject, bool isDefaulted, OSItemType type, - QTreeWidgetItem* parent) - : QTreeWidgetItem(parent), - m_handle(modelObject.handle()), - m_modelObject(modelObject), - m_model(modelObject.model()), - m_item(new ModelObjectItem(modelObject, isDefaulted, type)), - m_dirty(false) { - - m_item->setVisible(false); - - this->setText(0, toQString(modelObject.nameString())); - this->setStyle(0, ""); - - m_modelObject->getImpl()->onNameChange.connect(this); - - m_modelObject->getImpl()->onChange.connect(this); - - m_modelObject->getImpl() - ->onRelationshipChange.connect(this); -} - -ModelObjectTreeItem::ModelObjectTreeItem(const std::string& name, const openstudio::model::Model& model, QTreeWidgetItem* parent) - : QTreeWidgetItem(parent), m_model(model), m_name(name), m_item(nullptr), m_dirty(false) { - - this->setText(0, toQString(name)); - this->setStyle(0, ""); -} - -ModelObjectTreeItem::~ModelObjectTreeItem() { - delete m_item; -} - -boost::optional ModelObjectTreeItem::handle() const { - return m_handle; -} - -boost::optional ModelObjectTreeItem::modelObject() const { - return m_modelObject; -} - -openstudio::model::Model ModelObjectTreeItem::model() const { - return m_model; -} - -std::string ModelObjectTreeItem::name() const { - if (m_modelObject) { - return m_modelObject->nameString(); - } - return m_name; -} - -OSItem* ModelObjectTreeItem::item() const { - return m_item; -} - -std::vector ModelObjectTreeItem::children() const { - std::vector result; - - int n = this->childCount(); - for (int i = 0; i < n; ++i) { - QTreeWidgetItem* child = this->child(i); - auto* modelObjectTreeItem = dynamic_cast(child); - OS_ASSERT(modelObjectTreeItem); - result.push_back(modelObjectTreeItem); - } - - return result; -} - -std::vector ModelObjectTreeItem::recursiveChildren() const { - std::vector result; - - int n = this->childCount(); - for (int i = 0; i < n; ++i) { - QTreeWidgetItem* child = this->child(i); - auto* modelObjectTreeItem = dynamic_cast(child); - OS_ASSERT(modelObjectTreeItem); - result.push_back(modelObjectTreeItem); - - std::vector childChildren = modelObjectTreeItem->recursiveChildren(); - result.insert(result.end(), childChildren.begin(), childChildren.end()); - } - - return result; -} - -void ModelObjectTreeItem::setStyle(int headerLevel, const QString& color) { - if (this->modelObject()) { - //this->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); - this->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled); - - static QIcon defaultIcon(":/images/bug.png"); - - QIcon icon(defaultIcon); - const QPixmap* pixMap = IconLibrary::Instance().findMiniIcon(this->modelObject()->iddObjectType().value()); - if (pixMap) { - icon = QIcon(*pixMap); - } - this->setIcon(0, icon); - - } else { - this->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); - this->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled); - - static QIcon icon(":/images/mini_icons/folder.png"); - this->setIcon(0, icon); - } - - QFont font; - if (headerLevel == 1) { - font.setBold(true); - font.setPixelSize(14); - } else if (headerLevel == 2) { - font.setBold(true); - font.setPixelSize(12); - } else { - font.setPixelSize(12); - } - this->setFont(0, font); - - QBrush brush(Qt::black, Qt::SolidPattern); - if (!color.isEmpty()) { - brush = QBrush(color, Qt::SolidPattern); - } - this->setForeground(0, brush); -} - -bool ModelObjectTreeItem::isDirty() const { - return m_dirty; -} - -void ModelObjectTreeItem::makeDirty() { - m_dirty = true; -} - -void ModelObjectTreeItem::refresh() { - m_dirty = false; - - std::vector nonModelObjectChildrenVec = this->nonModelObjectChildren(); - std::vector defaultedModelObjectChildrenVec = this->defaultedModelObjectChildren(); - std::vector modelObjectChildrenVec = this->modelObjectChildren(); - std::vector childrenToRemove; - - std::set nonModelObjectChildrenSet(nonModelObjectChildrenVec.begin(), nonModelObjectChildrenVec.end()); - - std::set allModelObjectChildrenHandleSet; - for (const model::ModelObject& child : defaultedModelObjectChildrenVec) { - allModelObjectChildrenHandleSet.insert(child.handle()); - } - for (const model::ModelObject& child : modelObjectChildrenVec) { - allModelObjectChildrenHandleSet.insert(child.handle()); - } - - int n = this->childCount(); - for (int i = 0; i < n; ++i) { - QTreeWidgetItem* child = this->child(i); - auto* modelObjectTreeItem = dynamic_cast(child); - OS_ASSERT(modelObjectTreeItem); - - boost::optional modelObject_ = modelObjectTreeItem->modelObject(); - if (modelObject_) { - if (allModelObjectChildrenHandleSet.find(modelObject_->handle()) != allModelObjectChildrenHandleSet.end()) { - // this item's model object is for a model object we should have - modelObjectTreeItem->refresh(); - - // erase from set so we don't add later - allModelObjectChildrenHandleSet.erase(modelObject_->handle()); - } else { - // this item's model object is for a model object we should not have - - // add it to list to remove - childrenToRemove.push_back(child); - } - } else { - if (nonModelObjectChildrenSet.find(modelObjectTreeItem->name()) != nonModelObjectChildrenSet.end()) { - // this item's name is a name we should have - modelObjectTreeItem->refresh(); - - // erase from set so we don't add later - nonModelObjectChildrenSet.erase(modelObjectTreeItem->name()); - } else { - // this item's name is not a name we should not have - - // add it to list to remove - childrenToRemove.push_back(child); - } - } - } - - for (QTreeWidgetItem* child : childrenToRemove) { - this->removeChild(child); - delete child; - } - - // todo: insert in correct order - - for (const std::string& child : nonModelObjectChildrenVec) { - // still need this object - // cppcheck-suppress redundantIfRemove - if (nonModelObjectChildrenSet.find(child) != nonModelObjectChildrenSet.end()) { - nonModelObjectChildrenSet.erase(child); - this->addNonModelObjectChild(child); - } - } - for (const model::ModelObject& child : defaultedModelObjectChildrenVec) { - // still need this object - if (allModelObjectChildrenHandleSet.find(child.handle()) != allModelObjectChildrenHandleSet.end()) { - allModelObjectChildrenHandleSet.erase(child.handle()); - this->addModelObjectChild(child, true); - } - } - for (const model::ModelObject& child : modelObjectChildrenVec) { - // still need this object - if (allModelObjectChildrenHandleSet.find(child.handle()) != allModelObjectChildrenHandleSet.end()) { - allModelObjectChildrenHandleSet.erase(child.handle()); - this->addModelObjectChild(child, false); - } - } - - finalize(); -} - -void ModelObjectTreeItem::refreshTree() { - // refresh each top level object - QTreeWidget* treeWidget = this->treeWidget(); - - int N = treeWidget->topLevelItemCount(); - for (int i = 0; i < N; ++i) { - QTreeWidgetItem* treeItem = treeWidget->topLevelItem(i); - auto* modelObjectTreeItem = dynamic_cast(treeItem); - OS_ASSERT(modelObjectTreeItem); - - if (!modelObjectTreeItem->isDirty()) { - modelObjectTreeItem->makeDirty(); - QTimer::singleShot(0, modelObjectTreeItem, &ModelObjectTreeItem::refresh); - } - } -} - -void ModelObjectTreeItem::change() { - boost::optional modelObject_ = this->modelObject(); - OS_ASSERT(modelObject_); - - auto type = modelObject_->iddObjectType(); - if (type == IddObjectType::OS_ShadingSurfaceGroup || type == IddObjectType::OS_InteriorPartitionSurfaceGroup || type == IddObjectType::OS_Surface - || type == IddObjectType::OS_SubSurface) { - // these objects have 'type' fields that are not relationships but change tree structure - refreshTree(); - } -} - -void ModelObjectTreeItem::changeRelationship(int index, Handle newHandle, Handle oldHandle) { - if (newHandle == oldHandle) { - return; - } - - boost::optional modelObject_ = this->modelObject(); - OS_ASSERT(modelObject_); - - switch (modelObject_->iddObjectType().value()) { - case IddObjectType::OS_Building: - if (index == OS_BuildingFields::SpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_BuildingStory: - break; - case IddObjectType::OS_ThermalZone: - break; - case IddObjectType::OS_SpaceType: - if (index == OS_SpaceTypeFields::DesignSpecificationOutdoorAirObjectName) { - refreshTree(); - } - break; - case IddObjectType::OS_Space: - if (index == OS_SpaceFields::BuildingStoryName || index == OS_SpaceFields::SpaceTypeName || index == OS_SpaceFields::ThermalZoneName - || index == OS_SpaceFields::DesignSpecificationOutdoorAirObjectName) { - refreshTree(); - } - break; - case IddObjectType::OS_ShadingSurfaceGroup: - // handle in onChange - break; - case IddObjectType::OS_ShadingSurface: - if (index == OS_ShadingSurfaceFields::ShadingSurfaceGroupName) { - refreshTree(); - } - break; - case IddObjectType::OS_InteriorPartitionSurfaceGroup: - // handle in onChange - break; - case IddObjectType::OS_InteriorPartitionSurface: - if (index == OS_InteriorPartitionSurfaceFields::InteriorPartitionSurfaceGroupName) { - refreshTree(); - } - break; - case IddObjectType::OS_Surface: - // handle in onChange - if (index == OS_SurfaceFields::SpaceName) { - refreshTree(); - } - break; - case IddObjectType::OS_SubSurface: - // handle in onChange - break; - case IddObjectType::OS_Daylighting_Control: - if (index == OS_Daylighting_ControlFields::SpaceName) { - refreshTree(); - } - break; - case IddObjectType::OS_IlluminanceMap: - if (index == OS_IlluminanceMapFields::SpaceName) { - refreshTree(); - } - break; - case IddObjectType::OS_InternalMass: - if (index == OS_InternalMassFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_People: - if (index == OS_PeopleFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_Lights: - if (index == OS_LightsFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_Luminaire: - if (index == OS_LuminaireFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_ElectricEquipment: - if (index == OS_ElectricEquipmentFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_GasEquipment: - if (index == OS_GasEquipmentFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_HotWaterEquipment: - if (index == OS_HotWaterEquipmentFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_SteamEquipment: - if (index == OS_SteamEquipmentFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_OtherEquipment: - if (index == OS_OtherEquipmentFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_SpaceInfiltration_DesignFlowRate: - if (index == OS_SpaceInfiltration_DesignFlowRateFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_SpaceInfiltration_EffectiveLeakageArea: - if (index == OS_SpaceInfiltration_EffectiveLeakageAreaFields::SpaceorSpaceTypeName) { - refreshTree(); - } - break; - case IddObjectType::OS_DesignSpecification_OutdoorAir: - break; - default: - refreshTree(); - } -} - -void ModelObjectTreeItem::makeChildren() { - for (const std::string& child : this->nonModelObjectChildren()) { - this->addNonModelObjectChild(child); - } - for (const model::ModelObject& child : this->defaultedModelObjectChildren()) { - this->addModelObjectChild(child, true); - } - for (const model::ModelObject& child : this->modelObjectChildren()) { - this->addModelObjectChild(child, false); - } - - finalize(); -} - -std::vector ModelObjectTreeItem::nonModelObjectChildren() const { - return {}; -} - -std::vector ModelObjectTreeItem::modelObjectChildren() const { - return {}; -} - -std::vector ModelObjectTreeItem::defaultedModelObjectChildren() const { - return {}; -} - -void ModelObjectTreeItem::addNonModelObjectChild(const std::string& child) { - auto* treeItem = new ModelObjectTreeItem(child, this->model(), this); - this->addChild(treeItem); -} - -void ModelObjectTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - auto* treeItem = new ModelObjectTreeItem(child, isDefaulted, m_type, this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } -} - -void ModelObjectTreeItem::finalize() {} - -void ModelObjectTreeItem::changeName() { - boost::optional modelObject_ = this->modelObject(); - if (modelObject_) { - this->setText(0, toQString(modelObject_->nameString())); - } -} - -///////////////////// SiteShading //////////////////////////////////////////////// - -SiteShadingTreeItem::SiteShadingTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent) - : ModelObjectTreeItem(SiteShadingTreeItem::itemName(), model, parent) { - this->setStyle(1, ""); - this->makeChildren(); -} - -std::string SiteShadingTreeItem::itemName() { - return "Site Shading"; -} - -std::vector SiteShadingTreeItem::modelObjectChildren() const { - std::vector result; - for (const model::ShadingSurfaceGroup& shadingSurfaceGroup : this->model().getConcreteModelObjects()) { - if (openstudio::istringEqual("Site", shadingSurfaceGroup.shadingSurfaceType())) { - result.push_back(shadingSurfaceGroup); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void SiteShadingTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new ShadingSurfaceGroupTreeItem(child.cast(), this); - this->addChild(treeItem); - treeItem->setStyle(2, ""); - } else { - OS_ASSERT(false); - } -} - -///////////////////// ShadingSurfaceGroup //////////////////////////////////////////////// - -ShadingSurfaceGroupTreeItem::ShadingSurfaceGroupTreeItem(const openstudio::model::ShadingSurfaceGroup& shadingSurfaceGroup, QTreeWidgetItem* parent) - : ModelObjectTreeItem(shadingSurfaceGroup, false, m_type, parent) { - this->makeChildren(); -} - -std::vector ShadingSurfaceGroupTreeItem::modelObjectChildren() const { - auto shadingSurfaceGroup = this->modelObject()->cast(); - std::vector shadingSurfaces = shadingSurfaceGroup.shadingSurfaces(); - - std::vector result(shadingSurfaces.begin(), shadingSurfaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - - return result; -} - -void ShadingSurfaceGroupTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new ModelObjectTreeItem(child, false, m_type, this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// Building //////////////////////////////////////////////// - -BuildingTreeItem::BuildingTreeItem(const openstudio::model::Building& building, const openstudio::IddObjectType& sortByType, QTreeWidgetItem* parent) - : ModelObjectTreeItem(building, false, m_type, parent), m_sortByType(sortByType) { - this->setStyle(1, ""); - this->makeChildren(); -} - -std::vector BuildingTreeItem::modelObjectChildren() const { - openstudio::model::Model model = this->model(); - std::vector result; - - if (m_sortByType == IddObjectType::OS_BuildingStory) { - std::vector buildingStories = model.getConcreteModelObjects(); - result.insert(result.end(), buildingStories.begin(), buildingStories.end()); - } else if (m_sortByType == IddObjectType::OS_ThermalZone) { - std::vector thermalZones = model.getConcreteModelObjects(); - result.insert(result.end(), thermalZones.begin(), thermalZones.end()); - } else if (m_sortByType == IddObjectType::OS_SpaceType) { - std::vector spaceTypes = model.getConcreteModelObjects(); - result.insert(result.end(), spaceTypes.begin(), spaceTypes.end()); - } - - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - - return result; -} - -void BuildingTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new BuildingStoryTreeItem(child.cast(), this); - this->addChild(treeItem); - } else if (child.optionalCast()) { - auto* treeItem = new ThermalZoneTreeItem(child.cast(), this); - this->addChild(treeItem); - } else if (child.optionalCast()) { - auto* treeItem = new SpaceTypeTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -std::vector BuildingTreeItem::nonModelObjectChildren() const { - std::vector result; - result.push_back(BuildingShadingTreeItem::itemName()); - - if (m_sortByType == IddObjectType::OS_BuildingStory) { - result.push_back(NoBuildingStoryTreeItem::itemName()); - } else if (m_sortByType == IddObjectType::OS_ThermalZone) { - result.push_back(NoThermalZoneTreeItem::itemName()); - } else if (m_sortByType == IddObjectType::OS_SpaceType) { - result.push_back(NoSpaceTypeTreeItem::itemName()); - } - - return result; -} - -void BuildingTreeItem::addNonModelObjectChild(const std::string& child) { - if (child == BuildingShadingTreeItem::itemName()) { - auto* treeItem = new BuildingShadingTreeItem(this->model(), this); - this->addChild(treeItem); - } else if (child == NoBuildingStoryTreeItem::itemName()) { - auto* treeItem = new NoBuildingStoryTreeItem(this->model(), this); - this->addChild(treeItem); - } else if (child == NoThermalZoneTreeItem::itemName()) { - auto* treeItem = new NoThermalZoneTreeItem(this->model(), this); - this->addChild(treeItem); - } else if (child == NoSpaceTypeTreeItem::itemName()) { - auto* treeItem = new NoSpaceTypeTreeItem(this->model(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// BuildingShading //////////////////////////////////////////////// - -BuildingShadingTreeItem::BuildingShadingTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent) - : ModelObjectTreeItem(BuildingShadingTreeItem::itemName(), model, parent) { - this->setStyle(2, ""); - this->makeChildren(); -} - -std::string BuildingShadingTreeItem::itemName() { - return "Building Shading"; -} - -std::vector BuildingShadingTreeItem::modelObjectChildren() const { - std::vector result; - for (const model::ShadingSurfaceGroup& shadingSurfaceGroup : this->model().getConcreteModelObjects()) { - if (openstudio::istringEqual("Building", shadingSurfaceGroup.shadingSurfaceType())) { - result.push_back(shadingSurfaceGroup); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void BuildingShadingTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new ShadingSurfaceGroupTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// BuildingStory //////////////////////////////////////////////// - -BuildingStoryTreeItem::BuildingStoryTreeItem(const openstudio::model::BuildingStory& buildingStory, QTreeWidgetItem* parent) - : ModelObjectTreeItem(buildingStory, false, m_type, parent) { - this->setStyle(2, ""); - this->makeChildren(); -} - -std::vector BuildingStoryTreeItem::modelObjectChildren() const { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - std::vector spaces = modelObject->getModelObjectSources(); - std::vector result(spaces.begin(), spaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void BuildingStoryTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -NoBuildingStoryTreeItem::NoBuildingStoryTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent) - : ModelObjectTreeItem(NoBuildingStoryTreeItem::itemName(), model, parent) { - this->makeChildren(); -} - -std::string NoBuildingStoryTreeItem::itemName() { - return "Unassigned Building Story"; -} - -std::vector NoBuildingStoryTreeItem::modelObjectChildren() const { - model::Model model = this->model(); - std::vector result; - for (const model::Space& space : model.getConcreteModelObjects()) { - if (!space.buildingStory()) { - result.push_back(space); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void NoBuildingStoryTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -void NoBuildingStoryTreeItem::finalize() { - if (this->childCount() == 0) { - this->setDisabled(true); - this->setStyle(2, ""); - } else { - this->setDisabled(false); - this->setStyle(2, "#F15A24"); - } -} - -///////////////////// ThermalZone //////////////////////////////////////////////// - -ThermalZoneTreeItem::ThermalZoneTreeItem(const openstudio::model::ThermalZone& thermalZone, QTreeWidgetItem* parent) - : ModelObjectTreeItem(thermalZone, false, m_type, parent) { - this->setStyle(2, ""); - this->makeChildren(); -} - -std::vector ThermalZoneTreeItem::modelObjectChildren() const { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - std::vector spaces = modelObject->getModelObjectSources(); - std::vector result(spaces.begin(), spaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void ThermalZoneTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -NoThermalZoneTreeItem::NoThermalZoneTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent) - : ModelObjectTreeItem(NoThermalZoneTreeItem::itemName(), model, parent) { - this->setStyle(2, "#F15A24"); - this->makeChildren(); -} - -std::string NoThermalZoneTreeItem::itemName() { - return "Unassigned Thermal Zone"; -} - -std::vector NoThermalZoneTreeItem::modelObjectChildren() const { - model::Model model = this->model(); - std::vector result; - for (const model::Space& space : model.getConcreteModelObjects()) { - if (!space.thermalZone()) { - result.push_back(space); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void NoThermalZoneTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -void NoThermalZoneTreeItem::finalize() { - if (this->childCount() == 0) { - this->setDisabled(true); - this->setStyle(2, ""); - } else { - this->setDisabled(false); - this->setStyle(2, "#F15A24"); - } -} - -///////////////////// SpaceType //////////////////////////////////////////////// - -SpaceTypeTreeItem::SpaceTypeTreeItem(const openstudio::model::SpaceType& spaceType, QTreeWidgetItem* parent) - : ModelObjectTreeItem(spaceType, false, m_type, parent) { - this->setStyle(2, ""); - this->makeChildren(); -} - -std::vector SpaceTypeTreeItem::modelObjectChildren() const { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - std::vector spaces = modelObject->getModelObjectSources(); - std::vector result(spaces.begin(), spaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -std::vector SpaceTypeTreeItem::defaultedModelObjectChildren() const { - std::vector result; - - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - auto spaceType = modelObject->cast(); - - // get spaces that inherit this space type as default - for (const model::Space& space : spaceType.spaces()) { - if (space.isSpaceTypeDefaulted()) { - result.push_back(space); - } - } - - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void SpaceTypeTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -NoSpaceTypeTreeItem::NoSpaceTypeTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent) - : ModelObjectTreeItem(NoSpaceTypeTreeItem::itemName(), model, parent) { - this->makeChildren(); -} - -std::string NoSpaceTypeTreeItem::itemName() { - return "Unassigned Space Type"; -} - -std::vector NoSpaceTypeTreeItem::modelObjectChildren() const { - model::Model model = this->model(); - std::vector result; - for (const model::Space& space : model.getConcreteModelObjects()) { - if (!space.spaceType()) { - result.push_back(space); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void NoSpaceTypeTreeItem::addModelObjectChild(const model::ModelObject& child, bool isDefaulted) { - if (child.optionalCast()) { - auto* treeItem = new SpaceTreeItem(child.cast(), this); - this->addChild(treeItem); - if (isDefaulted) { - treeItem->setStyle(0, "#006837"); - } - } else { - OS_ASSERT(false); - } -} - -void NoSpaceTypeTreeItem::finalize() { - if (this->childCount() == 0) { - this->setDisabled(true); - this->setStyle(2, ""); - } else { - this->setDisabled(false); - this->setStyle(2, "#F15A24"); - } -} - -///////////////////// Space //////////////////////////////////////////////// - -SpaceTreeItem::SpaceTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) : ModelObjectTreeItem(space, false, m_type, parent) { - this->makeChildren(); -} - -std::vector SpaceTreeItem::nonModelObjectChildren() const { - std::vector result; - result.push_back(RoofsTreeItem::itemName()); - result.push_back(WallsTreeItem::itemName()); - result.push_back(FloorsTreeItem::itemName()); - result.push_back(SpaceShadingTreeItem::itemName()); - result.push_back(InteriorPartitionsTreeItem::itemName()); - result.push_back(DaylightingObjectsTreeItem::itemName()); - result.push_back(LoadsTreeItem::itemName()); - return result; -} - -void SpaceTreeItem::addNonModelObjectChild(const std::string& child) { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - auto space = modelObject->cast(); - - if (child == RoofsTreeItem::itemName()) { - auto* treeItem = new RoofsTreeItem(space, this); - this->addChild(treeItem); - } else if (child == WallsTreeItem::itemName()) { - auto* treeItem = new WallsTreeItem(space, this); - this->addChild(treeItem); - } else if (child == FloorsTreeItem::itemName()) { - auto* treeItem = new FloorsTreeItem(space, this); - this->addChild(treeItem); - } else if (child == SpaceShadingTreeItem::itemName()) { - auto* treeItem = new SpaceShadingTreeItem(space, this); - this->addChild(treeItem); - } else if (child == InteriorPartitionsTreeItem::itemName()) { - auto* treeItem = new InteriorPartitionsTreeItem(space, this); - this->addChild(treeItem); - } else if (child == DaylightingObjectsTreeItem::itemName()) { - auto* treeItem = new DaylightingObjectsTreeItem(space, this); - this->addChild(treeItem); - } else if (child == LoadsTreeItem::itemName()) { - auto* treeItem = new LoadsTreeItem(space, this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// Roofs //////////////////////////////////////////////// - -RoofsTreeItem::RoofsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(RoofsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string RoofsTreeItem::itemName() { - return "Roof/Ceilings"; -} - -std::vector RoofsTreeItem::modelObjectChildren() const { - std::vector result; - for (const model::Surface& surface : m_space.surfaces()) { - if (istringEqual("RoofCeiling", surface.surfaceType())) { - result.push_back(surface); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void RoofsTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new SurfaceTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// Walls //////////////////////////////////////////////// - -WallsTreeItem::WallsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(WallsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string WallsTreeItem::itemName() { - return "Walls"; -} - -std::vector WallsTreeItem::modelObjectChildren() const { - std::vector result; - for (const model::Surface& surface : m_space.surfaces()) { - if (istringEqual("Wall", surface.surfaceType())) { - result.push_back(surface); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void WallsTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new SurfaceTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// Floors //////////////////////////////////////////////// - -FloorsTreeItem::FloorsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(FloorsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string FloorsTreeItem::itemName() { - return "Floors"; -} - -std::vector FloorsTreeItem::modelObjectChildren() const { - std::vector result; - for (const model::Surface& surface : m_space.surfaces()) { - if (istringEqual("Floor", surface.surfaceType())) { - result.push_back(surface); - } - } - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void FloorsTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new SurfaceTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// Surface //////////////////////////////////////////////// - -SurfaceTreeItem::SurfaceTreeItem(const openstudio::model::Surface& surface, QTreeWidgetItem* parent) - : ModelObjectTreeItem(surface, false, m_type, parent) { - this->makeChildren(); -} - -std::vector SurfaceTreeItem::modelObjectChildren() const { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - auto surface = modelObject->cast(); - - std::vector subSurfaces = surface.subSurfaces(); - std::vector result(subSurfaces.begin(), subSurfaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -///////////////////// SpaceShading //////////////////////////////////////////////// - -SpaceShadingTreeItem::SpaceShadingTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(SpaceShadingTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string SpaceShadingTreeItem::itemName() { - return "Space Shading"; -} - -std::vector SpaceShadingTreeItem::modelObjectChildren() const { - std::vector shadingSurfaceGroups = m_space.shadingSurfaceGroups(); - std::vector result(shadingSurfaceGroups.begin(), shadingSurfaceGroups.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void SpaceShadingTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new ShadingSurfaceGroupTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// InteriorPartitions //////////////////////////////////////////////// - -InteriorPartitionsTreeItem::InteriorPartitionsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(InteriorPartitionsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string InteriorPartitionsTreeItem::itemName() { - return "Interior Partitions"; -} - -std::vector InteriorPartitionsTreeItem::modelObjectChildren() const { - std::vector interiorPartitionSurfaceGroups = m_space.interiorPartitionSurfaceGroups(); - std::vector result(interiorPartitionSurfaceGroups.begin(), interiorPartitionSurfaceGroups.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -void InteriorPartitionsTreeItem::addModelObjectChild(const model::ModelObject& child, bool /*isDefaulted*/) { - if (child.optionalCast()) { - auto* treeItem = new InteriorPartitionSurfaceGroupTreeItem(child.cast(), this); - this->addChild(treeItem); - } else { - OS_ASSERT(false); - } -} - -///////////////////// InteriorPartitionSurfaceGroup //////////////////////////////////////////////// - -InteriorPartitionSurfaceGroupTreeItem::InteriorPartitionSurfaceGroupTreeItem( - const openstudio::model::InteriorPartitionSurfaceGroup& interiorPartitionSurfaceGroup, QTreeWidgetItem* parent) - : ModelObjectTreeItem(interiorPartitionSurfaceGroup, false, m_type, parent) { - this->makeChildren(); -} - -std::vector InteriorPartitionSurfaceGroupTreeItem::modelObjectChildren() const { - boost::optional modelObject = this->modelObject(); - OS_ASSERT(modelObject); - auto interiorPartitionSurfaceGroup = modelObject->cast(); - - std::vector interiorPartitionSurfaces = interiorPartitionSurfaceGroup.interiorPartitionSurfaces(); - std::vector result(interiorPartitionSurfaces.begin(), interiorPartitionSurfaces.end()); - std::sort(result.begin(), result.end(), WorkspaceObjectNameLess()); - return result; -} - -///////////////////// DaylightingControls //////////////////////////////////////////////// - -DaylightingObjectsTreeItem::DaylightingObjectsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(DaylightingObjectsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string DaylightingObjectsTreeItem::itemName() { - return "Daylighting Objects"; -} - -std::vector DaylightingObjectsTreeItem::modelObjectChildren() const { - std::vector daylightingControls = m_space.daylightingControls(); - std::sort(daylightingControls.begin(), daylightingControls.end(), WorkspaceObjectNameLess()); - std::vector result(daylightingControls.begin(), daylightingControls.end()); - - std::vector glareSensors = m_space.glareSensors(); - result.insert(result.end(), glareSensors.begin(), glareSensors.end()); - - std::vector illuminanceMaps = m_space.illuminanceMaps(); - std::sort(illuminanceMaps.begin(), illuminanceMaps.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), illuminanceMaps.begin(), illuminanceMaps.end()); - - return result; -} - -///////////////////// Loads //////////////////////////////////////////////// - -LoadsTreeItem::LoadsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent) - : ModelObjectTreeItem(LoadsTreeItem::itemName(), space.model(), parent), m_space(space) { - this->makeChildren(); -} - -std::string LoadsTreeItem::itemName() { - return "Loads"; -} - -std::vector LoadsTreeItem::modelObjectChildren() const { - std::vector result; - - boost::optional designSpecificationOutdoorAir = m_space.designSpecificationOutdoorAir(); - if (designSpecificationOutdoorAir) { - if (!m_space.isDesignSpecificationOutdoorAirDefaulted()) { - result.push_back(*designSpecificationOutdoorAir); - } - } - - std::vector spaceInfiltrationDesignFlowRates = m_space.spaceInfiltrationDesignFlowRates(); - std::sort(spaceInfiltrationDesignFlowRates.begin(), spaceInfiltrationDesignFlowRates.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), spaceInfiltrationDesignFlowRates.begin(), spaceInfiltrationDesignFlowRates.end()); - - std::vector spaceInfiltrationEffectiveLeakageAreas = m_space.spaceInfiltrationEffectiveLeakageAreas(); - std::sort(spaceInfiltrationEffectiveLeakageAreas.begin(), spaceInfiltrationEffectiveLeakageAreas.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), spaceInfiltrationEffectiveLeakageAreas.begin(), spaceInfiltrationEffectiveLeakageAreas.end()); - - std::vector people = m_space.people(); - std::sort(people.begin(), people.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), people.begin(), people.end()); - - std::vector lights = m_space.lights(); - std::sort(lights.begin(), lights.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), lights.begin(), lights.end()); - - std::vector luminaires = m_space.luminaires(); - std::sort(luminaires.begin(), luminaires.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), luminaires.begin(), luminaires.end()); - - std::vector electricEquipment = m_space.electricEquipment(); - std::sort(electricEquipment.begin(), electricEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), electricEquipment.begin(), electricEquipment.end()); - - std::vector gasEquipment = m_space.gasEquipment(); - std::sort(gasEquipment.begin(), gasEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), gasEquipment.begin(), gasEquipment.end()); - - std::vector steamEquipment = m_space.steamEquipment(); - std::sort(steamEquipment.begin(), steamEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), steamEquipment.begin(), steamEquipment.end()); - - std::vector otherEquipment = m_space.otherEquipment(); - std::sort(otherEquipment.begin(), otherEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), otherEquipment.begin(), otherEquipment.end()); - - std::vector internalMass = m_space.internalMass(); - std::sort(internalMass.begin(), internalMass.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), internalMass.begin(), internalMass.end()); - - return result; -} - -std::vector LoadsTreeItem::defaultedModelObjectChildren() const { - std::vector result; - - boost::optional spaceType = m_space.spaceType(); - if (spaceType) { - - boost::optional designSpecificationOutdoorAir = m_space.designSpecificationOutdoorAir(); - if (designSpecificationOutdoorAir) { - if (m_space.isDesignSpecificationOutdoorAirDefaulted()) { - result.push_back(*designSpecificationOutdoorAir); - } - } - - std::vector spaceInfiltrationDesignFlowRates = spaceType->spaceInfiltrationDesignFlowRates(); - std::sort(spaceInfiltrationDesignFlowRates.begin(), spaceInfiltrationDesignFlowRates.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), spaceInfiltrationDesignFlowRates.begin(), spaceInfiltrationDesignFlowRates.end()); - - std::vector spaceInfiltrationEffectiveLeakageAreas = - spaceType->spaceInfiltrationEffectiveLeakageAreas(); - std::sort(spaceInfiltrationEffectiveLeakageAreas.begin(), spaceInfiltrationEffectiveLeakageAreas.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), spaceInfiltrationEffectiveLeakageAreas.begin(), spaceInfiltrationEffectiveLeakageAreas.end()); - - std::vector people = spaceType->people(); - std::sort(people.begin(), people.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), people.begin(), people.end()); - - std::vector lights = spaceType->lights(); - std::sort(lights.begin(), lights.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), lights.begin(), lights.end()); - - std::vector luminaires = spaceType->luminaires(); - std::sort(luminaires.begin(), luminaires.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), luminaires.begin(), luminaires.end()); - - std::vector electricEquipment = spaceType->electricEquipment(); - std::sort(electricEquipment.begin(), electricEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), electricEquipment.begin(), electricEquipment.end()); - - std::vector gasEquipment = spaceType->gasEquipment(); - std::sort(gasEquipment.begin(), gasEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), gasEquipment.begin(), gasEquipment.end()); - - std::vector steamEquipment = spaceType->steamEquipment(); - std::sort(steamEquipment.begin(), steamEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), steamEquipment.begin(), steamEquipment.end()); - - std::vector otherEquipment = spaceType->otherEquipment(); - std::sort(otherEquipment.begin(), otherEquipment.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), otherEquipment.begin(), otherEquipment.end()); - - std::vector internalMass = spaceType->internalMass(); - std::sort(internalMass.begin(), internalMass.end(), WorkspaceObjectNameLess()); - result.insert(result.end(), internalMass.begin(), internalMass.end()); - } - return result; -} - -} // namespace openstudio diff --git a/src/openstudio_lib/ModelObjectTreeItems.hpp b/src/openstudio_lib/ModelObjectTreeItems.hpp deleted file mode 100644 index f5c5571ce..000000000 --- a/src/openstudio_lib/ModelObjectTreeItems.hpp +++ /dev/null @@ -1,455 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OPENSTUDIO_MODELOBJECTTREEITEMS_HPP -#define OPENSTUDIO_MODELOBJECTTREEITEMS_HPP - -#include -#include -#include -#include "../shared_gui_components/OSItem.hpp" - -#include -#include -#include // Signal-Slot replacement - -class QPushButton; -class QLabel; - -namespace openstudio { - -class OSItem; - -namespace model { -class ShadingSurfaceGroup; -class Building; -class BuildingStory; -class ThermalZone; -class SpaceType; -class Space; -} // namespace model - -class ModelObjectTreeItem - : public QObject - , public QTreeWidgetItem - , public Nano::Observer -{ - Q_OBJECT - - public: - /// Constructed with a modelObject this tree item represents that object - ModelObjectTreeItem(const openstudio::model::ModelObject& modelObject, bool isDefaulted, OSItemType type, QTreeWidgetItem* parent = nullptr); - - /// Constructed with no modelObject this tree item represents a container - ModelObjectTreeItem(const std::string& name, const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - - virtual ~ModelObjectTreeItem(); - - boost::optional handle() const; - - boost::optional modelObject() const; - - openstudio::model::Model model() const; - - std::string name() const; - - OSItem* item() const; - - std::vector children() const; - - std::vector recursiveChildren() const; - - void setStyle(int headerLevel, const QString& color); - - bool isDirty() const; - - void makeDirty(); - - public slots: - - void refresh(); - - void refreshTree(); - - void change(); - - void changeRelationship(int index, Handle newHandle, Handle oldHandle); - - protected: - // make all child items - void makeChildren(); - - // get any non-model object children that this item should have - virtual std::vector nonModelObjectChildren() const; - - // get any model object children that this item should have - virtual std::vector modelObjectChildren() const; - - // get any defaulted model object children that this item should have - virtual std::vector defaultedModelObjectChildren() const; - - // add a non-model object as a child - virtual void addNonModelObjectChild(const std::string& child); - - // add a model object as a child - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted); - - // called after makeChildren or refresh - virtual void finalize(); - - static const OSItemType m_type; - - static OSItemType initializeOSItemType(); - - private slots: - - void changeName(); - - private: - boost::optional m_handle; - boost::optional m_modelObject; - openstudio::model::Model m_model; - std::string m_name; - OSItem* m_item; - bool m_dirty; -}; - -///////////////////// SiteShading //////////////////////////////////////////////// - -class SiteShadingTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit SiteShadingTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - virtual ~SiteShadingTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -///////////////////// ShadingSurfaceGroup //////////////////////////////////////////////// - -class ShadingSurfaceGroupTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit ShadingSurfaceGroupTreeItem(const openstudio::model::ShadingSurfaceGroup& shadingSurfaceGroup, QTreeWidgetItem* parent = nullptr); - virtual ~ShadingSurfaceGroupTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -///////////////////// Building //////////////////////////////////////////////// - -class BuildingTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - BuildingTreeItem(const openstudio::model::Building& building, const openstudio::IddObjectType& sortByType, QTreeWidgetItem* parent = nullptr); - virtual ~BuildingTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - virtual std::vector nonModelObjectChildren() const override; - virtual void addNonModelObjectChild(const std::string& child) override; - - private: - openstudio::IddObjectType m_sortByType; -}; - -///////////////////// BuildingShading //////////////////////////////////////////////// - -class BuildingShadingTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit BuildingShadingTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - virtual ~BuildingShadingTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -///////////////////// BuildingStory //////////////////////////////////////////////// - -class BuildingStoryTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit BuildingStoryTreeItem(const openstudio::model::BuildingStory& buildingStory, QTreeWidgetItem* parent = nullptr); - virtual ~BuildingStoryTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -class NoBuildingStoryTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit NoBuildingStoryTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - virtual ~NoBuildingStoryTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - virtual void finalize() override; -}; - -///////////////////// ThermalZone //////////////////////////////////////////////// - -class ThermalZoneTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit ThermalZoneTreeItem(const openstudio::model::ThermalZone& thermalZone, QTreeWidgetItem* parent = nullptr); - virtual ~ThermalZoneTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -class NoThermalZoneTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit NoThermalZoneTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - virtual ~NoThermalZoneTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - virtual void finalize() override; -}; - -///////////////////// SpaceType //////////////////////////////////////////////// - -class SpaceTypeTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit SpaceTypeTreeItem(const openstudio::model::SpaceType& spaceType, QTreeWidgetItem* parent = nullptr); - virtual ~SpaceTypeTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; - virtual std::vector defaultedModelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; -}; - -class NoSpaceTypeTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit NoSpaceTypeTreeItem(const openstudio::model::Model& model, QTreeWidgetItem* parent = nullptr); - virtual ~NoSpaceTypeTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - virtual void finalize() override; -}; - -///////////////////// Space //////////////////////////////////////////////// - -class SpaceTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit SpaceTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~SpaceTreeItem() {} - - protected: - virtual std::vector nonModelObjectChildren() const override; - virtual void addNonModelObjectChild(const std::string& child) override; -}; - -///////////////////// Roofs //////////////////////////////////////////////// - -class RoofsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit RoofsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~RoofsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// Walls //////////////////////////////////////////////// - -class WallsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit WallsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~WallsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// Floors //////////////////////////////////////////////// - -class FloorsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit FloorsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~FloorsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// Surface //////////////////////////////////////////////// - -class SurfaceTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit SurfaceTreeItem(const openstudio::model::Surface& surface, QTreeWidgetItem* parent = nullptr); - virtual ~SurfaceTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; -}; - -///////////////////// SpaceShading //////////////////////////////////////////////// - -class SpaceShadingTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit SpaceShadingTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~SpaceShadingTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// InteriorPartitions //////////////////////////////////////////////// - -class InteriorPartitionsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit InteriorPartitionsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~InteriorPartitionsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual void addModelObjectChild(const model::ModelObject& child, bool isDefaulted) override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// InteriorPartitionSurfaceGroup //////////////////////////////////////////////// - -class InteriorPartitionSurfaceGroupTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit InteriorPartitionSurfaceGroupTreeItem(const openstudio::model::InteriorPartitionSurfaceGroup& interiorPartitionSurfaceGroup, - QTreeWidgetItem* parent = nullptr); - virtual ~InteriorPartitionSurfaceGroupTreeItem() {} - - protected: - virtual std::vector modelObjectChildren() const override; -}; - -///////////////////// DaylightingObjects //////////////////////////////////////////////// - -class DaylightingObjectsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit DaylightingObjectsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~DaylightingObjectsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - - private: - openstudio::model::Space m_space; -}; - -///////////////////// Loads //////////////////////////////////////////////// - -class LoadsTreeItem : public ModelObjectTreeItem -{ - Q_OBJECT - - public: - explicit LoadsTreeItem(const openstudio::model::Space& space, QTreeWidgetItem* parent = nullptr); - virtual ~LoadsTreeItem() {} - static std::string itemName(); - - protected: - virtual std::vector modelObjectChildren() const override; - virtual std::vector defaultedModelObjectChildren() const override; - - private: - openstudio::model::Space m_space; -}; - -} // namespace openstudio - -#endif // OPENSTUDIO_MODELOBJECTTREEITEMS_HPP diff --git a/src/openstudio_lib/ModelObjectTreeWidget.cpp b/src/openstudio_lib/ModelObjectTreeWidget.cpp deleted file mode 100644 index 109b1b450..000000000 --- a/src/openstudio_lib/ModelObjectTreeWidget.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#include "ModelObjectTreeWidget.hpp" -#include "ModelObjectTreeItems.hpp" -#include "OSAppBase.hpp" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -namespace openstudio { - -ModelObjectTreeWidget::ModelObjectTreeWidget(const model::Model& model, QWidget* parent) : OSItemSelector(parent), m_model(model) { - m_vLayout = new QVBoxLayout(); - m_vLayout->setContentsMargins(0, 7, 0, 0); - m_vLayout->setSpacing(7); - setLayout(m_vLayout); - - m_treeWidget = new QTreeWidget(parent); - m_treeWidget->setStyleSheet("QTreeWidget { border: none; border-top: 1px solid black; }"); - m_treeWidget->setAttribute(Qt::WA_MacShowFocusRect, 0); - - m_vLayout->addWidget(m_treeWidget); - - // model.getImpl().get()->addWorkspaceObjectPtr.connect(this); - connect(OSAppBase::instance(), &OSAppBase::workspaceObjectAddedPtr, this, &ModelObjectTreeWidget::objectAdded, Qt::QueuedConnection); - - //model.getImpl().get()->removeWorkspaceObjectPtr.connect(this); - connect(OSAppBase::instance(), &OSAppBase::workspaceObjectRemovedPtr, this, &ModelObjectTreeWidget::objectRemoved, Qt::QueuedConnection); -} - -OSItem* ModelObjectTreeWidget::selectedItem() const { - // todo: something - return nullptr; -} - -QTreeWidget* ModelObjectTreeWidget::treeWidget() const { - return m_treeWidget; -} - -QVBoxLayout* ModelObjectTreeWidget::vLayout() const { - return m_vLayout; -} - -openstudio::model::Model ModelObjectTreeWidget::model() const { - return m_model; -} - -void ModelObjectTreeWidget::objectAdded(std::shared_ptr impl, - const openstudio::IddObjectType& iddObjectType, const openstudio::UUID& handle) { - onObjectAdded(impl->getObject(), iddObjectType, handle); -} - -void ModelObjectTreeWidget::objectRemoved(std::shared_ptr impl, - const openstudio::IddObjectType& iddObjectType, const openstudio::UUID& handle) { - onObjectRemoved(impl->getObject(), iddObjectType, handle); -} - -void ModelObjectTreeWidget::refresh() { - int N = m_treeWidget->topLevelItemCount(); - for (int i = 0; i < N; ++i) { - QTreeWidgetItem* treeItem = m_treeWidget->topLevelItem(i); - auto* modelObjectTreeItem = dynamic_cast(treeItem); - if (modelObjectTreeItem) { - if (!modelObjectTreeItem->isDirty()) { - modelObjectTreeItem->makeDirty(); - QTimer::singleShot(0, modelObjectTreeItem, &ModelObjectTreeItem::refresh); - } - } - } -} - -} // namespace openstudio diff --git a/src/openstudio_lib/ModelObjectTreeWidget.hpp b/src/openstudio_lib/ModelObjectTreeWidget.hpp deleted file mode 100644 index d853705ea..000000000 --- a/src/openstudio_lib/ModelObjectTreeWidget.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/*********************************************************************************************************************** -* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. -* See also https://openstudiocoalition.org/about/software_license/ -***********************************************************************************************************************/ - -#ifndef OPENSTUDIO_MODELOBJECTTREEWIDGET_HPP -#define OPENSTUDIO_MODELOBJECTTREEWIDGET_HPP - -#include "OSItemSelector.hpp" -#include // Signal-Slot replacement - -#include -#include "../openstudio_qt_utils/QMetaTypes.hpp" - -class QTreeWidget; - -class QVBoxLayout; - -namespace openstudio { - -class ModelObjectTreeWidget - : public OSItemSelector - , public Nano::Observer -{ - Q_OBJECT - - public: - explicit ModelObjectTreeWidget(const model::Model& model, QWidget* parent = nullptr); - - virtual ~ModelObjectTreeWidget() {} - - virtual OSItem* selectedItem() const override; - - QTreeWidget* treeWidget() const; - - QVBoxLayout* vLayout() const; - - openstudio::model::Model model() const; - - protected: - virtual void onObjectAdded(const openstudio::model::ModelObject& modelObject, const openstudio::IddObjectType& iddObjectType, - const openstudio::UUID& handle) = 0; - - virtual void onObjectRemoved(const openstudio::model::ModelObject& modelObject, const openstudio::IddObjectType& iddObjectType, - const openstudio::UUID& handle) = 0; - - void refresh(); - - private slots: - - void objectAdded(std::shared_ptr impl, const openstudio::IddObjectType& iddObjectType, - const openstudio::UUID& handle); - - void objectRemoved(std::shared_ptr impl, const openstudio::IddObjectType& iddObjectType, - const openstudio::UUID& handle); - - private: - QTreeWidget* m_treeWidget; - - QVBoxLayout* m_vLayout; - - openstudio::model::Model m_model; -}; - -} // namespace openstudio - -#endif // OPENSTUDIO_MODELOBJECTTREEWIDGET_HPP diff --git a/src/openstudio_lib/test/IconLibrary_GTest.cpp b/src/openstudio_lib/test/IconLibrary_GTest.cpp index f4b9503a6..46f46f3cb 100644 --- a/src/openstudio_lib/test/IconLibrary_GTest.cpp +++ b/src/openstudio_lib/test/IconLibrary_GTest.cpp @@ -5,6 +5,10 @@ #include +// IconLibrary is defined in shared_gui_components, but this test lives in openstudio_lib/test/ +// because it reuses OpenStudioLibFixture for QApplication setup and Qt resource initialisation. +// shared_gui_components has no test target of its own; a lightweight QApplication-only fixture +// there would suffice if one is ever added. #include "OpenStudioLibFixture.hpp" #include "../../shared_gui_components/IconLibrary.hpp" diff --git a/src/openstudio_lib/test/OSDropZone_GTest.cpp b/src/openstudio_lib/test/OSDropZone_GTest.cpp index 115c17445..8c2101547 100644 --- a/src/openstudio_lib/test/OSDropZone_GTest.cpp +++ b/src/openstudio_lib/test/OSDropZone_GTest.cpp @@ -5,6 +5,10 @@ #include +// OSDropZone is defined in shared_gui_components, but this test lives in openstudio_lib/test/ +// because it requires OpenStudioLibFixture, which sets up a live OSAppBase and OSDocument. +// OSDropZone connects to OSAppBase::workspaceObjectAddedPtr/workspaceObjectRemovedPtr at +// runtime; a BaseApp mock would be needed to host it in shared_gui_components tests. #include "OpenStudioLibFixture.hpp" #include "../../shared_gui_components/OSDropZone.hpp" diff --git a/src/openstudio_lib/test/OSLineEdit_GTest.cpp b/src/openstudio_lib/test/OSLineEdit_GTest.cpp index 76badd68a..cc6d7ef47 100644 --- a/src/openstudio_lib/test/OSLineEdit_GTest.cpp +++ b/src/openstudio_lib/test/OSLineEdit_GTest.cpp @@ -5,6 +5,9 @@ #include +// OSLineEdit is defined in shared_gui_components, but this test lives in openstudio_lib/test/ +// because it requires OpenStudioLibFixture, which provides a live OSAppBase, OSDocument, and +// model::Model. A BaseApp mock would be needed to host it in shared_gui_components tests. #include "OpenStudioLibFixture.hpp" #include "../../shared_gui_components/OSLineEdit.hpp" @@ -33,4 +36,4 @@ TEST_F(OpenStudioLibFixture, OSLineEdit) { ASSERT_EQ(1u, spaceTypes.size()); processEvents(); -} \ No newline at end of file +} diff --git a/src/shared_gui_components/WorkflowController.cpp b/src/shared_gui_components/WorkflowController.cpp index 53a4e07d6..32a36926b 100644 --- a/src/shared_gui_components/WorkflowController.cpp +++ b/src/shared_gui_components/WorkflowController.cpp @@ -201,10 +201,7 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { UUID id = measureDragData.id(); - const bool hasDocument = (m_app != nullptr); - if (hasDocument) { - m_app->disableDocument(); - } + m_app->disableDocument(); boost::optional projectMeasure; try { @@ -218,9 +215,7 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { errorMessage += QString::fromStdString(e.what()); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (hasDocument) { - m_app->enableDocument(); - } + m_app->enableDocument(); return; } OS_ASSERT(projectMeasure); @@ -229,9 +224,7 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { QString errorMessage("Failed to add measure at this workflow location."); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (hasDocument) { - m_app->enableDocument(); - } + m_app->enableDocument(); return; } @@ -245,9 +238,7 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { errorMessage += QString::fromStdString(e.what()); QMessageBox::information(m_app->mainWidget(), QString("Failed to add measure"), errorMessage); - if (hasDocument) { - m_app->enableDocument(); - } + m_app->enableDocument(); return; } @@ -274,9 +265,7 @@ void MeasureStepController::addItemForDroppedMeasure(QDropEvent* event) { //workflowJSON.save(); - if (hasDocument) { - m_app->enableDocument(); - } + m_app->enableDocument(); emit modelReset(); } From 5707722982ca55c4028d1cda9eaa2f68cc73c233 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 22:04:23 -0600 Subject: [PATCH 23/26] Add script to sort includes, will run this on a separate pr --- .gitignore | 4 +- developer/python/sort_includes.py | 254 ++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 developer/python/sort_includes.py diff --git a/.gitignore b/.gitignore index c59e93fe6..5a07d9260 100644 --- a/.gitignore +++ b/.gitignore @@ -25,12 +25,9 @@ relwithdebinfo/ profile/ /super-build-shared/ /super-build-static/ - *.sublime-workspace - *.sublime-project cmake-build-debug - developer/msvc/Visualizers/all_concat.natvis .vscode/ .vs/ @@ -42,3 +39,4 @@ clang_format.patch conan-cache .ccache CMakeUserPresets.json +__pycache__ \ No newline at end of file diff --git a/developer/python/sort_includes.py b/developer/python/sort_includes.py new file mode 100644 index 000000000..c646b25c8 --- /dev/null +++ b/developer/python/sort_includes.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python3 +""" +sort_includes.py +================ +Applies the include-order rule from + .github/instructions/cpp-refactoring.instructions.md +to every .cpp and .hpp file under src/. + +Groups (blank line between non-empty groups, alphabetical within group): + 1. Own header (.cpp only) — #include "ThisClass.hpp" matching the file stem + 2. Same-dir — #include "Sibling.hpp" (quoted, no path separator) + 3. Cross-dir — #include "../other/Foo.hpp" (quoted, contains '/') + 4. OpenStudio SDK — #include + 5. Qt / Boost / system — #include <...> (all other angle-bracket includes) + +Scope: only the contiguous top-level include block is touched. + - Includes inside #if / #ifdef / #ifndef / #else / #elif / #endif are never moved. + - Any line that is not '#include ...' or blank terminates the block. + +Usage (run from the repo root, i.e. the directory that contains src/): + python developer/python/sort_includes.py # rewrite files in-place + python developer/python/sort_includes.py --dry-run # report what would change, no writes + python developer/python/sort_includes.py --check # exit 1 if any file is out of order (CI mode) +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +# --------------------------------------------------------------------------- +# Classification helpers +# --------------------------------------------------------------------------- + +INCLUDE_RE = re.compile(r'^#include\s*([<"])(.*?)([>"])\s*(?://.*)?$') + + +def classify(line: str, stem: str, is_cpp: bool) -> int: + """Return group number 1-5, or 0 if not a recognisable #include line.""" + m = INCLUDE_RE.match(line.strip()) + if not m: + return 0 + bracket, path = m.group(1), m.group(2) + + if bracket == '"': + # Group 1: own header (.cpp only) — stem of included file matches this file's stem + if is_cpp and Path(path).stem == stem: + return 1 + # Group 3: cross-directory — path contains a directory separator + if '/' in path or '\\' in path: + return 3 + # Group 2: same-directory + return 2 + else: # angle-bracket + # Group 4: OpenStudio SDK + if path.startswith('openstudio/'): + return 4 + # Group 5: Qt, Boost, system, gtest, etc. + return 5 + + +def sort_key(line: str) -> str: + """Alphabetical sort key: lowercase basename of the included path.""" + m = INCLUDE_RE.match(line.strip()) + if not m: + return line.lower() + return Path(m.group(2)).name.lower() + + +# --------------------------------------------------------------------------- +# Reorder a flat list of #include lines into the canonical group order +# --------------------------------------------------------------------------- + +def reorder_includes(includes: list[str], stem: str, is_cpp: bool) -> list[str]: + """ + Given a flat list of #include lines (no blank lines between them), + return them reordered into groups separated by single blank lines. + """ + groups: dict[int, list[str]] = {1: [], 2: [], 3: [], 4: [], 5: []} + unclassified: list[str] = [] + + for line in includes: + g = classify(line, stem, is_cpp) + if g: + groups[g].append(line) + else: + # Should not happen in a well-formed include block; keep as-is in group 5 + unclassified.append(line) + + if unclassified: + groups[5].extend(unclassified) + + for g in groups: + groups[g].sort(key=sort_key) + + result: list[str] = [] + first_group = True + for g in (1, 2, 3, 4, 5): + if groups[g]: + if not first_group: + result.append('') + result.extend(groups[g]) + first_group = False + + return result + + +# --------------------------------------------------------------------------- +# File transformation +# --------------------------------------------------------------------------- + +def transform(filepath: Path) -> tuple[bool, str]: + """ + Parse *filepath*, reorder its top-level include block according to the + five-group rule, and return (changed, new_content). + + Returns (False, original_text) if no change is needed or the file has no + top-level include block. + """ + text = filepath.read_text(encoding='utf-8', errors='replace') + original = text + lines = text.splitlines() + n = len(lines) + + stem = filepath.stem + is_cpp = filepath.suffix == '.cpp' + + # ── Step 1: skip to the first non-blank line ───────────────────────────── + i = 0 + while i < n and lines[i].strip() == '': + i += 1 + + # ── Step 2: skip the file-top block comment /* ... */ ─────────────────── + if i < n and lines[i].strip().startswith('/*'): + while i < n and '*/' not in lines[i]: + i += 1 + i += 1 # skip the closing '*/' line + + # skip blank lines after the license comment + while i < n and lines[i].strip() == '': + i += 1 + + # ── Step 3: skip include guards or #pragma once ────────────────────────── + # Pattern A: #pragma once + if i < n and lines[i].strip().startswith('#pragma once'): + i += 1 + # Pattern B: #ifndef FOO_HPP / #define FOO_HPP + elif i < n and lines[i].strip().startswith('#ifndef'): + if i + 1 < n and lines[i + 1].strip().startswith('#define'): + i += 2 + + # skip blank lines after guard + while i < n and lines[i].strip() == '': + i += 1 + + include_start = i + + # ── Step 4: collect the contiguous top-level include block ─────────────── + # Rules: + # - '#include ...' lines and blank lines between them are included. + # - The first line that is neither '#include' nor blank terminates the block. + # - Lines starting with '#if', '#ifdef', etc. also terminate the block + # (conditional includes are never reordered). + include_lines_raw: list[str] = [] + pending_blanks = 0 + j = include_start + + while j < n: + stripped = lines[j].strip() + + if stripped == '': + pending_blanks += 1 + j += 1 + continue + + if stripped.startswith('#include'): + # Commit any pending blanks only if we already have some includes + if include_lines_raw: + include_lines_raw.extend([''] * pending_blanks) + pending_blanks = 0 + include_lines_raw.append(lines[j]) + j += 1 + continue + + # Anything else (code, comment, preprocessor conditional) → stop + break + + include_end = j # first line *after* the block (trailing blanks not consumed) + + if not include_lines_raw: + return False, original + + # ── Step 5: reorder ─────────────────────────────────────────────────────── + flat_includes = [ln for ln in include_lines_raw if ln.strip() != ''] + reordered = reorder_includes(flat_includes, stem, is_cpp) + + # ── Step 6: rebuild file ────────────────────────────────────────────────── + new_lines = lines[:include_start] + reordered + lines[include_end:] + new_text = '\n'.join(new_lines) + if text.endswith('\n'): + new_text += '\n' + + changed = new_text != original + return changed, new_text + + +# --------------------------------------------------------------------------- +# Entry point +# --------------------------------------------------------------------------- + +def main() -> int: + dry_run = '--dry-run' in sys.argv + check_mode = '--check' in sys.argv # CI: exit 1 if any file needs changes + + root = Path(__file__).resolve().parent.parent.parent / 'src' + if not root.is_dir(): + print(f"ERROR: src/ directory not found at {root}", file=sys.stderr) + return 1 + + files = sorted(root.rglob('*.cpp')) + sorted(root.rglob('*.hpp')) + + changed_files: list[Path] = [] + error_files: list[tuple[Path, str]] = [] + + for fp in files: + try: + changed, new_content = transform(fp) + except Exception as exc: + error_files.append((fp, str(exc))) + continue + + if changed: + changed_files.append(fp) + rel = fp.relative_to(root.parent) + if check_mode or dry_run: + print(f"{'[CHECK]' if check_mode else '[DRY-RUN]'} needs reorder: {rel}") + else: + fp.write_text(new_content, encoding='utf-8') + print(f"reordered: {rel}") + + for fp, err in error_files: + print(f"ERROR: {fp.relative_to(root.parent)}: {err}", file=sys.stderr) + + mode_label = 'would change' if (dry_run or check_mode) else 'reordered' + print(f"\nDone. {len(changed_files)} file(s) {mode_label}, {len(error_files)} error(s).") + + if check_mode and (changed_files or error_files): + return 1 + return 0 + + +if __name__ == '__main__': + sys.exit(main()) From fe41f159e537ecd7fa07f62116813eea0624873b Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 27 Apr 2026 22:11:30 -0600 Subject: [PATCH 24/26] Revert changes to this file --- developer/ruby/OSMVersionsLib.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/ruby/OSMVersionsLib.rb b/developer/ruby/OSMVersionsLib.rb index ffd6f915d..3cda501b1 100644 --- a/developer/ruby/OSMVersionsLib.rb +++ b/developer/ruby/OSMVersionsLib.rb @@ -63,7 +63,7 @@ def find_resource_osms() path = File.join(ROOT_DIR, 'src/**/*.osm') files = Dir.glob(path) # Only keep the one we're interested in - files = files.grep(/openstudio_app\/Resources/) + files = files.grep(/openstudio_app\/Resources|sketchup_plugin\/resources\/templates|sketchup_plugin\/user_scripts/) return files end From 66b708722e06dbdf31c57c29be08c0dde9239bfe Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sat, 2 May 2026 11:58:37 -0600 Subject: [PATCH 25/26] Add removed doc strings and improve TODO comment --- src/openstudio_lib/OSDocument.hpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index bfd25a100..2fa767ad3 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -65,25 +65,40 @@ class OSDocument // BaseDocument interface — pure virtual overrides // ------------------------------------------------------------------------- + // Returns the model associated with this document. model::Model model() override; + // Returns true if the document has unsaved changes. bool modified() const override; + // Returns the string path to the location where the document is saved. + // If the document is unsaved an empty string will be returned. QString savePath() const override; + // Returns the path to the directory where model resources are stored. QString modelTempDir() const override; + // Returns the component library associated with this document. model::Model componentLibrary() const override; + // Returns true if OSItemId's source is the model. bool fromModel(const OSItemId& itemId) const override; + // Returns true if OSItemId's source is the componentLibrary. bool fromComponentLibrary(const OSItemId& itemId) const override; + // Returns true if OSItemId's source is the BCL. bool fromBCL(const OSItemId& itemId) const override; std::vector componentAttributeSearch(const std::vector>& pairs) const override; + // Returns IddObjectType from either model, componentLibrary, or BCL. boost::optional getIddObjectType(const OSItemId& itemId) const override; + // Returns the model object from either model or componentLibrary if possible. + // Does not return model object from BCL. boost::optional getModelObject(const OSItemId& itemId) const override; + // Returns the component from BCL identified by itemId. boost::optional getComponent(const OSItemId& itemId) const override; // ------------------------------------------------------------------------- // OSDocument-specific API // ------------------------------------------------------------------------- - // TODO: promote to BaseDocument once MainWindow is extracted into an IMainWindow interface - // that lives in shared_gui_components or openstudio_qt_utils (no openstudio_lib dependency). + // TODO: create a BaseMainWindow interface in shared_gui_components and change this + // to a virtual method `BaseMainWindow* mainWindow()` in BaseDocument. + // This will allow us to split up openstudio_lib into domain-specific libraries + // (e.g. constructions_gui, hvac_gui, etc.) which need to call mainWindow(). MainWindow* mainWindow(); // Sets the model — closes all current windows. From 4cf35d9d96f7812e8f9f482485e851d7057289b3 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Sat, 2 May 2026 11:59:12 -0600 Subject: [PATCH 26/26] Clang format --- src/openstudio_lib/OSDocument.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openstudio_lib/OSDocument.hpp b/src/openstudio_lib/OSDocument.hpp index 2fa767ad3..ac696acdc 100644 --- a/src/openstudio_lib/OSDocument.hpp +++ b/src/openstudio_lib/OSDocument.hpp @@ -95,7 +95,7 @@ class OSDocument // OSDocument-specific API // ------------------------------------------------------------------------- - // TODO: create a BaseMainWindow interface in shared_gui_components and change this + // TODO: create a BaseMainWindow interface in shared_gui_components and change this // to a virtual method `BaseMainWindow* mainWindow()` in BaseDocument. // This will allow us to split up openstudio_lib into domain-specific libraries // (e.g. constructions_gui, hvac_gui, etc.) which need to call mainWindow().