diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index a9051b6e8..cf9dcd884 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -13,7 +13,10 @@ #include "OSItemSelectorButtons.hpp" #include "SchedulesTabController.hpp" +#include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSGridView.hpp" +#include "../shared_gui_components/OSQuantityEdit.hpp" +#include "../shared_gui_components/OSSwitch.hpp" #include "../openstudio_app/OpenStudioApp.hpp" @@ -70,6 +73,7 @@ #include #include #include +#include static constexpr auto NAME("Name: "); static constexpr auto LATITUDE("Latitude: "); @@ -174,6 +178,11 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& weatherFileGridLayout->setContentsMargins(7, 3, 7, 7); weatherFileGridLayout->setSpacing(7); + // ***** Measure Tags GridLayout ***** + auto* siteInfoGridLayout = new QGridLayout(); + siteInfoGridLayout->setContentsMargins(7, 7, 7, 7); + siteInfoGridLayout->setSpacing(7); + // ***** Measure Tags GridLayout ***** auto* measureTagsGridLayout = new QGridLayout(); measureTagsGridLayout->setContentsMargins(7, 7, 7, 7); @@ -236,16 +245,13 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& weatherFileGridLayout->addLayout(hLayout, i++, 0); - m_latitudeLbl = new QLabel(tr("Latitude: ")); + m_latitudeLbl = new QLabel(tr(LATITUDE)); weatherFileGridLayout->addWidget(m_latitudeLbl, i++, 0); - m_longitudeLbl = new QLabel(tr("Longitude: ")); + m_longitudeLbl = new QLabel(tr(LONGITUDE)); weatherFileGridLayout->addWidget(m_longitudeLbl, i++, 0); - m_elevationLbl = new QLabel(tr("Elevation: ")); - weatherFileGridLayout->addWidget(m_elevationLbl, i++, 0); - - m_timeZoneLbl = new QLabel(tr("Time Zone: ")); + m_timeZoneLbl = new QLabel(tr(TIME_ZONE)); weatherFileGridLayout->addWidget(m_timeZoneLbl, i++, 0); // ***** Weather File Download Location ***** @@ -258,6 +264,91 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& leftVLayout->addLayout(weatherFileGridLayout); leftVLayout->addStretch(); + // Site Information + { + label = new QLabel(tr("Site Information:")); + label->setObjectName("H2"); + leftVLayout->addWidget(label); + + i = 0; + + { + label = new QLabel(tr("Keep Site Location Information")); + label->setToolTip(tr("If enabled, this will write the Site:Location object that will keep the Elevation change for example.")); + + m_keepSiteLocationInfo = new OSSwitch2(); + + m_keepSiteLocationInfo->bind(*m_site, BoolGetter([this] { return m_site->keepSiteLocationInformation(); }), + boost::optional([this](bool b) { + bool result = m_site->setKeepSiteLocationInformation(b); + + if (result) { + + // force the style to update + m_elevation->clearCachedText(); + + if (b) { + // set elevation if turning on + if (m_site->isElevationDefaulted()) { + m_site->setElevation(m_weatherFileElevation); + } else { + m_site->setElevation(m_site->elevation()); + } + } else { + // reset elevation if turning off + if (std::abs(m_weatherFileElevation) > 0.01) { + m_site->setElevation(m_weatherFileElevation); + } else { + m_site->resetElevation(); + } + } + } + return result; + }), + boost::optional([this] { m_site->resetKeepSiteLocationInformation(); }), + boost::optional([this] { return m_site->isKeepSiteLocationInformationDefaulted(); })); + + siteInfoGridLayout->addWidget(label, i, 0); + siteInfoGridLayout->addWidget(m_keepSiteLocationInfo, i++, 1); + } + { + label = new QLabel(tr(ELEVATION)); + label->setToolTip(tr("Elevation affects the wind speed at the site, and is defaulted to the Weather File's elevation")); + + m_elevation = new OSQuantityEdit2("m", "m", "ft", m_isIP); + connect(this, &LocationView::toggleUnitsClicked, m_elevation, &OSQuantityEdit2::onUnitSystemChange); + + // Bind is delayed until after update() is called, so that the weatherFileElevation is set correctly. + + m_elevation->setFixedWidth(200); + + siteInfoGridLayout->addWidget(label, i, 0); + siteInfoGridLayout->addWidget(m_elevation, i++, 1); + } + // Terrain + { + label = new QLabel(tr("Terrain")); + label->setToolTip(tr("Terrain affects the wind speed at the site.")); + + m_terrain = new OSComboBox2(); + m_terrain->bind(*m_site, static_cast(&openstudio::toString), &model::Site::validTerrainValues, + std::bind(&model::Site::terrain, m_site.get_ptr()), + std::bind(&model::Site::setTerrain, m_site.get_ptr(), std::placeholders::_1), + boost::optional(std::bind(&model::Site::resetTerrain, m_site.get_ptr())), + boost::optional(std::bind(&model::Site::isTerrainDefaulted, m_site.get_ptr()))); + + m_terrain->setFixedWidth(200); + + siteInfoGridLayout->addWidget(label, i, 0); + siteInfoGridLayout->addWidget(m_terrain, i++, 1); + } + + // ***** Site Info GridLayout ***** + siteInfoGridLayout->setColumnStretch(++i, 10); + leftVLayout->addLayout(siteInfoGridLayout); + leftVLayout->addStretch(); + } + // ***** Climate Zones ***** label = new QLabel(tr("Measure Tags (Optional):")); label->setObjectName("H2"); @@ -400,11 +491,37 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& connect(m_itemSelectorButtons, &OSItemSelectorButtons::purgeClicked, m_designDaysGridView, &DesignDayGridView::onPurgeClicked); update(); + { + m_elevation->bind(m_isIP, *m_site, DoubleGetter([this] { return m_site->elevation(); }), boost::optional([this](double d) { + // turn keep site info on + m_site->setKeepSiteLocationInformation(true); + return m_site->setElevation(d); + }), + boost::optional([this] { + // turn keep site info off + m_site->setKeepSiteLocationInformation(false); + + // force the style to update + m_elevation->clearCachedText(); + + if (std::abs(m_weatherFileElevation) > 0.01) { + m_site->setElevation(m_weatherFileElevation); + } else { + m_site->resetElevation(); + } + }), + boost::none, // autosize + boost::none, // autocalculate + boost::optional([this] { // + return (m_site->isElevationDefaulted() || !m_site->keepSiteLocationInformation()); + })); + } onSelectItem(); } LocationView::~LocationView() { + // m_terrain->unbind(); // NOTE: I don't think this is necessary saveQSettings(); } @@ -496,6 +613,7 @@ void LocationView::update() { if (fileExists) { m_weatherFileBtn->setText(tr("Change Weather File")); + m_weatherFileElevation = weatherFile->elevation(); setSiteInfo(); } else { m_weatherFileBtn->setText(tr("Set Weather File")); @@ -526,11 +644,6 @@ void LocationView::setSiteInfo() { info += temp; m_longitudeLbl->setText(info); - info = tr(ELEVATION); - temp.setNum(m_site->elevation()); - info += temp; - m_elevationLbl->setText(info); - info = tr(TIME_ZONE); temp.setNum(m_site->timeZone()); info += temp; @@ -544,9 +657,9 @@ void LocationView::clearSiteInfo() { m_longitudeLbl->setText(tr(LONGITUDE)); - m_elevationLbl->setText(tr(ELEVATION)); - m_timeZoneLbl->setText(tr(TIME_ZONE)); + + m_weatherFileElevation = 0.0; } // ***** SLOTS ***** @@ -637,7 +750,10 @@ void LocationView::onWeatherFileBtnClicked() { m_site->setName(weatherFile->city()); m_site->setLatitude(weatherFile->latitude()); m_site->setLongitude(weatherFile->longitude()); + m_weatherFileElevation = weatherFile->elevation(); + m_site->setKeepSiteLocationInformation(false); m_site->setElevation(weatherFile->elevation()); + m_site->resetTerrain(); m_site->setTimeZone(weatherFile->timeZone()); m_lastEpwPathOpened = QFileInfo(fileName).absoluteFilePath(); diff --git a/src/openstudio_lib/LocationTabView.hpp b/src/openstudio_lib/LocationTabView.hpp index 4aea184d8..5df69a75c 100644 --- a/src/openstudio_lib/LocationTabView.hpp +++ b/src/openstudio_lib/LocationTabView.hpp @@ -23,7 +23,10 @@ namespace openstudio { class EpwFile; class DesignDayGridView; +class OSComboBox2; class OSItemSelectorButtons; +class OSQuantityEdit2; +class OSSwitch2; namespace model { class Model; @@ -97,17 +100,23 @@ class LocationView : public QWidget YearSettingsWidget* m_yearSettingsWidget = nullptr; DesignDayGridView* m_designDaysGridView = nullptr; OSItemSelectorButtons* m_itemSelectorButtons = nullptr; - QString m_modelTempDir = QString(); - QString m_lastEpwPathOpened = QString(); - QString m_lastDdyPathOpened = QString(); - QComboBox* m_ashraeClimateZone = nullptr; - QComboBox* m_cecClimateZone = nullptr; + QString m_modelTempDir; + QString m_lastEpwPathOpened; + QString m_lastDdyPathOpened; + + QPushButton* m_weatherFileBtn = nullptr; QLineEdit* m_siteName = nullptr; QLabel* m_latitudeLbl = nullptr; QLabel* m_longitudeLbl = nullptr; - QLabel* m_elevationLbl = nullptr; QLabel* m_timeZoneLbl = nullptr; - QPushButton* m_weatherFileBtn = nullptr; + + OSComboBox2* m_terrain = nullptr; + OSSwitch2* m_keepSiteLocationInfo = nullptr; + OSQuantityEdit2* m_elevation = nullptr; + double m_weatherFileElevation = 0.0; + QComboBox* m_ashraeClimateZone = nullptr; + QComboBox* m_cecClimateZone = nullptr; + bool m_isIP; signals: diff --git a/src/shared_gui_components/Component.cpp b/src/shared_gui_components/Component.cpp index a97bc061f..c5283782c 100644 --- a/src/shared_gui_components/Component.cpp +++ b/src/shared_gui_components/Component.cpp @@ -430,17 +430,20 @@ void Component::createAbridgedLayout() { label = new QLabel(string); leftLayout->addWidget(label); + QString labelString; + QString typeString = "Unknown"; + if (m_componentType == "component") { + labelString = "Type: "; + } else if (m_componentType == "measure" || m_componentType == "MeasureType") { + labelString = "Measure Type: "; + } for (const Attribute& attribute : m_attributes) { string = attribute.name().c_str(); if (m_componentType == "component") { if (string.toStdString() == OPENSTUDIO_TYPE) { openstudio::AttributeValueType type = attribute.valueType(); if (type == AttributeValueType::String) { - string = attribute.valueAsString().c_str(); - QString temp("Type: "); - temp += string; - label = new QLabel(temp); - leftLayout->addWidget(label); + typeString = attribute.valueAsString().c_str(); break; } } @@ -448,16 +451,16 @@ void Component::createAbridgedLayout() { if (string.toStdString() == "Measure Type") { openstudio::AttributeValueType type = attribute.valueType(); if (type == AttributeValueType::String) { - string = attribute.valueAsString().c_str(); - QString temp("Measure Type: "); - temp += string; - label = new QLabel(temp); - leftLayout->addWidget(label); + typeString = attribute.valueAsString().c_str(); } } } } + labelString += typeString; + label = new QLabel(labelString); + leftLayout->addWidget(label); + m_msg = new QLabel(this); if (m_error) { m_msg->setStyleSheet("color:#F00;font-style:italic;"); diff --git a/src/shared_gui_components/OSComboBox.cpp b/src/shared_gui_components/OSComboBox.cpp index fa3de7d53..a5c58e87e 100644 --- a/src/shared_gui_components/OSComboBox.cpp +++ b/src/shared_gui_components/OSComboBox.cpp @@ -250,6 +250,14 @@ void OSComboBox2::onModelObjectRemoved(const Handle& handle) { unbind(); } +void OSComboBox2::onActivated(int index) { + if (m_choiceConcept) { + if (index == this->currentIndex() && m_choiceConcept->isDefaulted()) { + this->onCurrentIndexChanged(this->currentText()); + } + } +} + void OSComboBox2::onCurrentIndexChanged(const QString& text) { emit inFocus(m_focused, hasData()); @@ -347,6 +355,7 @@ void OSComboBox2::completeBind() { m_modelObject->getImpl() ->onRemoveFromWorkspace.connect(this); + connect(this, static_cast(&OSComboBox2::activated), this, &OSComboBox2::onActivated); connect(this, static_cast(&OSComboBox2::currentTextChanged), this, &OSComboBox2::onCurrentIndexChanged); if (isEditable()) { diff --git a/src/shared_gui_components/OSComboBox.hpp b/src/shared_gui_components/OSComboBox.hpp index 7f13c6751..2549b5090 100644 --- a/src/shared_gui_components/OSComboBox.hpp +++ b/src/shared_gui_components/OSComboBox.hpp @@ -180,6 +180,8 @@ class OSComboBox2 void onModelObjectRemoved(const Handle& handle); + void onActivated(int index); + void onCurrentIndexChanged(const QString& text); void onEditTextChanged(const QString& text); diff --git a/src/shared_gui_components/OSQuantityEdit.cpp b/src/shared_gui_components/OSQuantityEdit.cpp index d480dc84c..6b705b65a 100644 --- a/src/shared_gui_components/OSQuantityEdit.cpp +++ b/src/shared_gui_components/OSQuantityEdit.cpp @@ -82,6 +82,10 @@ void OSQuantityEdit2::setLocked(bool locked) { m_lineEdit->setLocked(locked); } +void OSQuantityEdit2::clearCachedText() { + m_text = "UNINITIALIZED"; +} + QDoubleValidator* OSQuantityEdit2::doubleValidator() { return m_doubleValidator; } diff --git a/src/shared_gui_components/OSQuantityEdit.hpp b/src/shared_gui_components/OSQuantityEdit.hpp index 43267575a..fbd8c53a8 100644 --- a/src/shared_gui_components/OSQuantityEdit.hpp +++ b/src/shared_gui_components/OSQuantityEdit.hpp @@ -84,6 +84,8 @@ class OSQuantityEdit2 void setLocked(bool locked); + void clearCachedText(); + QDoubleValidator* doubleValidator(); void bind(bool isIP, const model::ModelObject& modelObject, DoubleGetter get, boost::optional set = boost::none,