mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 06:30:05 +00:00 
			
		
		
		
	Merge pull request #267 from AdenKoperczak/wfo-audio-location-method
Add WFO audio location method
This commit is contained in:
		
						commit
						21cb6859a2
					
				
					 16 changed files with 623 additions and 147 deletions
				
			
		
							
								
								
									
										2
									
								
								data
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								data
									
										
									
									
									
								
							|  | @ -1 +1 @@ | ||||||
| Subproject commit 1d93f4106761cabbe61e1265bb1d2b8501600177 | Subproject commit 8eb89b19fdd1c78e896cc6cb47e07425bb473699 | ||||||
|  | @ -240,6 +240,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | ||||||
|            source/scwx/qt/ui/animation_dock_widget.hpp |            source/scwx/qt/ui/animation_dock_widget.hpp | ||||||
|            source/scwx/qt/ui/collapsible_group.hpp |            source/scwx/qt/ui/collapsible_group.hpp | ||||||
|            source/scwx/qt/ui/county_dialog.hpp |            source/scwx/qt/ui/county_dialog.hpp | ||||||
|  |            source/scwx/qt/ui/wfo_dialog.hpp | ||||||
|            source/scwx/qt/ui/download_dialog.hpp |            source/scwx/qt/ui/download_dialog.hpp | ||||||
|            source/scwx/qt/ui/flow_layout.hpp |            source/scwx/qt/ui/flow_layout.hpp | ||||||
|            source/scwx/qt/ui/gps_info_dialog.hpp |            source/scwx/qt/ui/gps_info_dialog.hpp | ||||||
|  | @ -265,6 +266,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp | ||||||
|            source/scwx/qt/ui/animation_dock_widget.cpp |            source/scwx/qt/ui/animation_dock_widget.cpp | ||||||
|            source/scwx/qt/ui/collapsible_group.cpp |            source/scwx/qt/ui/collapsible_group.cpp | ||||||
|            source/scwx/qt/ui/county_dialog.cpp |            source/scwx/qt/ui/county_dialog.cpp | ||||||
|  |            source/scwx/qt/ui/wfo_dialog.cpp | ||||||
|            source/scwx/qt/ui/download_dialog.cpp |            source/scwx/qt/ui/download_dialog.cpp | ||||||
|            source/scwx/qt/ui/flow_layout.cpp |            source/scwx/qt/ui/flow_layout.cpp | ||||||
|            source/scwx/qt/ui/gps_info_dialog.cpp |            source/scwx/qt/ui/gps_info_dialog.cpp | ||||||
|  | @ -290,6 +292,7 @@ set(UI_UI  source/scwx/qt/ui/about_dialog.ui | ||||||
|            source/scwx/qt/ui/animation_dock_widget.ui |            source/scwx/qt/ui/animation_dock_widget.ui | ||||||
|            source/scwx/qt/ui/collapsible_group.ui |            source/scwx/qt/ui/collapsible_group.ui | ||||||
|            source/scwx/qt/ui/county_dialog.ui |            source/scwx/qt/ui/county_dialog.ui | ||||||
|  |            source/scwx/qt/ui/wfo_dialog.ui | ||||||
|            source/scwx/qt/ui/gps_info_dialog.ui |            source/scwx/qt/ui/gps_info_dialog.ui | ||||||
|            source/scwx/qt/ui/imgui_debug_dialog.ui |            source/scwx/qt/ui/imgui_debug_dialog.ui | ||||||
|            source/scwx/qt/ui/layer_dialog.ui |            source/scwx/qt/ui/layer_dialog.ui | ||||||
|  | @ -388,6 +391,7 @@ set(ZONE_DBF_FILES   ${SCWX_DIR}/data/db/fz05mr24.dbf | ||||||
|                      ${SCWX_DIR}/data/db/oz05mr24.dbf |                      ${SCWX_DIR}/data/db/oz05mr24.dbf | ||||||
|                      ${SCWX_DIR}/data/db/z_05mr24.dbf) |                      ${SCWX_DIR}/data/db/z_05mr24.dbf) | ||||||
| set(STATE_DBF_FILES  ${SCWX_DIR}/data/db/s_05mr24.dbf) | set(STATE_DBF_FILES  ${SCWX_DIR}/data/db/s_05mr24.dbf) | ||||||
|  | set(WFO_DBF_FILES    ${SCWX_DIR}/data/db/w_05mr24.dbf) | ||||||
| set(COUNTIES_SQLITE_DB ${scwx-qt_BINARY_DIR}/res/db/counties.db) | set(COUNTIES_SQLITE_DB ${scwx-qt_BINARY_DIR}/res/db/counties.db) | ||||||
| 
 | 
 | ||||||
| set(RESOURCE_INPUT  ${scwx-qt_SOURCE_DIR}/res/scwx-qt.rc.in) | set(RESOURCE_INPUT  ${scwx-qt_SOURCE_DIR}/res/scwx-qt.rc.in) | ||||||
|  | @ -483,11 +487,13 @@ add_custom_command(OUTPUT  ${COUNTIES_SQLITE_DB} | ||||||
|                            -c ${COUNTY_DBF_FILES} |                            -c ${COUNTY_DBF_FILES} | ||||||
|                            -z ${ZONE_DBF_FILES} |                            -z ${ZONE_DBF_FILES} | ||||||
|                            -s ${STATE_DBF_FILES} |                            -s ${STATE_DBF_FILES} | ||||||
|  |                            -w ${WFO_DBF_FILES} | ||||||
|                            -o ${COUNTIES_SQLITE_DB} |                            -o ${COUNTIES_SQLITE_DB} | ||||||
|                    DEPENDS ${scwx-qt_SOURCE_DIR}/tools/generate_counties_db.py |                    DEPENDS ${scwx-qt_SOURCE_DIR}/tools/generate_counties_db.py | ||||||
|                            ${COUNTY_DB_FILES} |                            ${COUNTY_DB_FILES} | ||||||
|                            ${STATE_DBF_FILES} |                            ${STATE_DBF_FILES} | ||||||
|                            ${ZONE_DBF_FILES}) |                            ${ZONE_DBF_FILES} | ||||||
|  |                            ${WFO_DBF_FILES}) | ||||||
| 
 | 
 | ||||||
| add_custom_target(scwx-qt_generate_counties_db ALL | add_custom_target(scwx-qt_generate_counties_db ALL | ||||||
|                   DEPENDS ${COUNTIES_SQLITE_DB}) |                   DEPENDS ${COUNTIES_SQLITE_DB}) | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ typedef std::unordered_map<char, StateMap>           FormatMap; | ||||||
| static bool                                         initialized_ {false}; | static bool                                         initialized_ {false}; | ||||||
| static FormatMap                                    countyDatabase_; | static FormatMap                                    countyDatabase_; | ||||||
| static std::unordered_map<std::string, std::string> stateMap_; | static std::unordered_map<std::string, std::string> stateMap_; | ||||||
|  | static std::unordered_map<std::string, std::string> wfoMap_; | ||||||
| 
 | 
 | ||||||
| void Initialize() | void Initialize() | ||||||
| { | { | ||||||
|  | @ -168,6 +169,39 @@ void Initialize() | ||||||
|       sqlite3_free(errorMessage); |       sqlite3_free(errorMessage); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // Query database for WFOs
 | ||||||
|  |    rc = sqlite3_exec( | ||||||
|  |       db, | ||||||
|  |       "SELECT id, city_state FROM wfos", | ||||||
|  |       [](void* /* param */, | ||||||
|  |          int    columns, | ||||||
|  |          char** columnText, | ||||||
|  |          char** /* columnName */) -> int | ||||||
|  |       { | ||||||
|  |          int status = 0; | ||||||
|  | 
 | ||||||
|  |          if (columns == 2) | ||||||
|  |          { | ||||||
|  |             wfoMap_.emplace(columnText[0], columnText[1]); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             logger_->error( | ||||||
|  |                "WFO database format error, invalid number of columns: {}", | ||||||
|  |                columns); | ||||||
|  |             status = -1; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          return status; | ||||||
|  |       }, | ||||||
|  |       nullptr, | ||||||
|  |       &errorMessage); | ||||||
|  |    if (rc != SQLITE_OK) | ||||||
|  |    { | ||||||
|  |       logger_->error("SQL error: {}", errorMessage); | ||||||
|  |       sqlite3_free(errorMessage); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|    // Close database
 |    // Close database
 | ||||||
|    sqlite3_close(db); |    sqlite3_close(db); | ||||||
| 
 | 
 | ||||||
|  | @ -230,6 +264,22 @@ const std::unordered_map<std::string, std::string>& GetStates() | ||||||
|    return stateMap_; |    return stateMap_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const std::unordered_map<std::string, std::string>& GetWFOs() | ||||||
|  | { | ||||||
|  |    return wfoMap_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const std::string& GetWFOName(const std::string& wfoId) | ||||||
|  | { | ||||||
|  |    auto wfo = wfoMap_.find(wfoId); | ||||||
|  |    if (wfo == wfoMap_.end()) | ||||||
|  |    { | ||||||
|  |       return wfoId; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return wfo->second; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace CountyDatabase
 | } // namespace CountyDatabase
 | ||||||
| } // namespace config
 | } // namespace config
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
|  |  | ||||||
|  | @ -19,6 +19,8 @@ std::string GetCountyName(const std::string& id); | ||||||
| std::unordered_map<std::string, std::string> | std::unordered_map<std::string, std::string> | ||||||
| GetCounties(const std::string& state); | GetCounties(const std::string& state); | ||||||
| const std::unordered_map<std::string, std::string>& GetStates(); | const std::unordered_map<std::string, std::string>& GetStates(); | ||||||
|  | const std::unordered_map<std::string, std::string>& GetWFOs(); | ||||||
|  | const std::string& GetWFOName(const std::string& wfoId); | ||||||
| 
 | 
 | ||||||
| } // namespace CountyDatabase
 | } // namespace CountyDatabase
 | ||||||
| } // namespace config
 | } // namespace config
 | ||||||
|  |  | ||||||
|  | @ -151,6 +151,7 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, | ||||||
|    std::string        alertCounty = audioSettings.alert_county().GetValue(); |    std::string        alertCounty = audioSettings.alert_county().GetValue(); | ||||||
|    auto               alertRadius = units::length::kilometers<double>( |    auto               alertRadius = units::length::kilometers<double>( | ||||||
|       audioSettings.alert_radius().GetValue()); |       audioSettings.alert_radius().GetValue()); | ||||||
|  |    std::string alertWFO = audioSettings.alert_wfo().GetValue(); | ||||||
| 
 | 
 | ||||||
|    auto message = textEventManager_->message_list(key).at(messageIndex); |    auto message = textEventManager_->message_list(key).at(messageIndex); | ||||||
| 
 | 
 | ||||||
|  | @ -185,9 +186,7 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, | ||||||
|          auto alertCoordinates = segment->codedLocation_->coordinates(); |          auto alertCoordinates = segment->codedLocation_->coordinates(); | ||||||
| 
 | 
 | ||||||
|          activeAtLocation = util::GeographicLib::AreaInRangeOfPoint( |          activeAtLocation = util::GeographicLib::AreaInRangeOfPoint( | ||||||
|                alertCoordinates, |             alertCoordinates, currentCoordinate, alertRadius); | ||||||
|                currentCoordinate, |  | ||||||
|                alertRadius); |  | ||||||
|       } |       } | ||||||
|       else if (locationMethod == types::LocationMethod::County) |       else if (locationMethod == types::LocationMethod::County) | ||||||
|       { |       { | ||||||
|  | @ -196,6 +195,12 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, | ||||||
|          auto it = std::find(fipsIds.cbegin(), fipsIds.cend(), alertCounty); |          auto it = std::find(fipsIds.cbegin(), fipsIds.cend(), alertCounty); | ||||||
|          activeAtLocation = it != fipsIds.cend(); |          activeAtLocation = it != fipsIds.cend(); | ||||||
|       } |       } | ||||||
|  |       else if (locationMethod == types::LocationMethod::WFO) | ||||||
|  |       { | ||||||
|  |          std::string wfoId = vtec.pVtec_.office_id(); | ||||||
|  | 
 | ||||||
|  |          activeAtLocation = wfoId == alertWFO; | ||||||
|  |       } | ||||||
| 
 | 
 | ||||||
|       if (activeAtLocation) |       if (activeAtLocation) | ||||||
|       { |       { | ||||||
|  |  | ||||||
|  | @ -39,6 +39,7 @@ public: | ||||||
|       alertLongitude_.SetDefault(0.0); |       alertLongitude_.SetDefault(0.0); | ||||||
|       alertRadius_.SetDefault(0.0); |       alertRadius_.SetDefault(0.0); | ||||||
|       alertRadarSite_.SetDefault("default"); |       alertRadarSite_.SetDefault("default"); | ||||||
|  |       alertWFO_.SetDefault(""); | ||||||
|       ignoreMissingCodecs_.SetDefault(false); |       ignoreMissingCodecs_.SetDefault(false); | ||||||
| 
 | 
 | ||||||
|       alertLatitude_.SetMinimum(-90.0); |       alertLatitude_.SetMinimum(-90.0); | ||||||
|  | @ -62,6 +63,14 @@ public: | ||||||
|                    config::CountyDatabase::GetCountyName(value) != value; |                    config::CountyDatabase::GetCountyName(value) != value; | ||||||
|          }); |          }); | ||||||
| 
 | 
 | ||||||
|  |       alertWFO_.SetValidator( | ||||||
|  |          [](const std::string& value) | ||||||
|  |          { | ||||||
|  |             return value.empty() || | ||||||
|  |                    config::CountyDatabase::GetWFOs().count(value) != 0; | ||||||
|  |          }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|       auto& alertAudioPhenomena = types::GetAlertAudioPhenomena(); |       auto& alertAudioPhenomena = types::GetAlertAudioPhenomena(); | ||||||
|       alertEnabled_.reserve(alertAudioPhenomena.size() + 1); |       alertEnabled_.reserve(alertAudioPhenomena.size() + 1); | ||||||
| 
 | 
 | ||||||
|  | @ -94,6 +103,7 @@ public: | ||||||
|    SettingsVariable<std::string> alertRadarSite_ {"alert_radar_site"}; |    SettingsVariable<std::string> alertRadarSite_ {"alert_radar_site"}; | ||||||
|    SettingsVariable<double>      alertRadius_ {"alert_radius"}; |    SettingsVariable<double>      alertRadius_ {"alert_radius"}; | ||||||
|    SettingsVariable<std::string> alertCounty_ {"alert_county"}; |    SettingsVariable<std::string> alertCounty_ {"alert_county"}; | ||||||
|  |    SettingsVariable<std::string> alertWFO_ {"alert_wfo"}; | ||||||
|    SettingsVariable<bool>        ignoreMissingCodecs_ {"ignore_missing_codecs"}; |    SettingsVariable<bool>        ignoreMissingCodecs_ {"ignore_missing_codecs"}; | ||||||
| 
 | 
 | ||||||
|    std::unordered_map<awips::Phenomenon, SettingsVariable<bool>> |    std::unordered_map<awips::Phenomenon, SettingsVariable<bool>> | ||||||
|  | @ -111,6 +121,7 @@ AudioSettings::AudioSettings() : | ||||||
|                       &p->alertRadarSite_, |                       &p->alertRadarSite_, | ||||||
|                       &p->alertRadius_, |                       &p->alertRadius_, | ||||||
|                       &p->alertCounty_, |                       &p->alertCounty_, | ||||||
|  |                       &p->alertWFO_, | ||||||
|                       &p->ignoreMissingCodecs_}); |                       &p->ignoreMissingCodecs_}); | ||||||
|    RegisterVariables(p->variables_); |    RegisterVariables(p->variables_); | ||||||
|    SetDefaults(); |    SetDefaults(); | ||||||
|  | @ -157,6 +168,11 @@ SettingsVariable<std::string>& AudioSettings::alert_county() const | ||||||
|    return p->alertCounty_; |    return p->alertCounty_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SettingsVariable<std::string>& AudioSettings::alert_wfo() const | ||||||
|  | { | ||||||
|  |    return p->alertWFO_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| SettingsVariable<bool>& | SettingsVariable<bool>& | ||||||
| AudioSettings::alert_enabled(awips::Phenomenon phenomenon) const | AudioSettings::alert_enabled(awips::Phenomenon phenomenon) const | ||||||
| { | { | ||||||
|  | @ -188,6 +204,7 @@ bool operator==(const AudioSettings& lhs, const AudioSettings& rhs) | ||||||
|            lhs.p->alertRadarSite_ == rhs.p->alertRadarSite_ && |            lhs.p->alertRadarSite_ == rhs.p->alertRadarSite_ && | ||||||
|            lhs.p->alertRadius_ == rhs.p->alertRadius_ && |            lhs.p->alertRadius_ == rhs.p->alertRadius_ && | ||||||
|            lhs.p->alertCounty_ == rhs.p->alertCounty_ && |            lhs.p->alertCounty_ == rhs.p->alertCounty_ && | ||||||
|  |            lhs.p->alertWFO_ == rhs.p->alertWFO_ && | ||||||
|            lhs.p->alertEnabled_ == rhs.p->alertEnabled_); |            lhs.p->alertEnabled_ == rhs.p->alertEnabled_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ public: | ||||||
|    SettingsVariable<double>&      alert_radius() const; |    SettingsVariable<double>&      alert_radius() const; | ||||||
|    SettingsVariable<std::string>& alert_radar_site() const; |    SettingsVariable<std::string>& alert_radar_site() const; | ||||||
|    SettingsVariable<std::string>& alert_county() const; |    SettingsVariable<std::string>& alert_county() const; | ||||||
|  |    SettingsVariable<std::string>& alert_wfo() const; | ||||||
|    SettingsVariable<bool>& alert_enabled(awips::Phenomenon phenomenon) const; |    SettingsVariable<bool>& alert_enabled(awips::Phenomenon phenomenon) const; | ||||||
|    SettingsVariable<bool>& ignore_missing_codecs() const; |    SettingsVariable<bool>& ignore_missing_codecs() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ static const std::unordered_map<LocationMethod, std::string> | ||||||
|                         {LocationMethod::Track, "Track"}, |                         {LocationMethod::Track, "Track"}, | ||||||
|                         {LocationMethod::RadarSite, "Radar Site"}, |                         {LocationMethod::RadarSite, "Radar Site"}, | ||||||
|                         {LocationMethod::County, "County"}, |                         {LocationMethod::County, "County"}, | ||||||
|  |                         {LocationMethod::WFO, "WFO"}, | ||||||
|                         {LocationMethod::All, "All"}, |                         {LocationMethod::All, "All"}, | ||||||
|                         {LocationMethod::Unknown, "?"}}; |                         {LocationMethod::Unknown, "?"}}; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ enum class LocationMethod | ||||||
|    Track, |    Track, | ||||||
|    RadarSite, |    RadarSite, | ||||||
|    County, |    County, | ||||||
|  |    WFO, | ||||||
|    All, |    All, | ||||||
|    Unknown |    Unknown | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| #include <scwx/qt/types/time_types.hpp> | #include <scwx/qt/types/time_types.hpp> | ||||||
| #include <scwx/qt/types/unit_types.hpp> | #include <scwx/qt/types/unit_types.hpp> | ||||||
| #include <scwx/qt/ui/county_dialog.hpp> | #include <scwx/qt/ui/county_dialog.hpp> | ||||||
|  | #include <scwx/qt/ui/wfo_dialog.hpp> | ||||||
| #include <scwx/qt/ui/radar_site_dialog.hpp> | #include <scwx/qt/ui/radar_site_dialog.hpp> | ||||||
| #include <scwx/qt/ui/serial_port_dialog.hpp> | #include <scwx/qt/ui/serial_port_dialog.hpp> | ||||||
| #include <scwx/qt/ui/settings/hotkey_settings_widget.hpp> | #include <scwx/qt/ui/settings/hotkey_settings_widget.hpp> | ||||||
|  | @ -108,6 +109,7 @@ public: | ||||||
|        alertAudioRadarSiteDialog_ {new RadarSiteDialog(self)}, |        alertAudioRadarSiteDialog_ {new RadarSiteDialog(self)}, | ||||||
|        gpsSourceDialog_ {new SerialPortDialog(self)}, |        gpsSourceDialog_ {new SerialPortDialog(self)}, | ||||||
|        countyDialog_ {new CountyDialog(self)}, |        countyDialog_ {new CountyDialog(self)}, | ||||||
|  |        wfoDialog_ {new WFODialog(self)}, | ||||||
|        fontDialog_ {new QFontDialog(self)}, |        fontDialog_ {new QFontDialog(self)}, | ||||||
|        fontCategoryModel_ {new QStandardItemModel(self)}, |        fontCategoryModel_ {new QStandardItemModel(self)}, | ||||||
|        settings_ {std::initializer_list<settings::SettingsInterfaceBase*> { |        settings_ {std::initializer_list<settings::SettingsInterfaceBase*> { | ||||||
|  | @ -140,6 +142,7 @@ public: | ||||||
|           &alertAudioRadarSite_, |           &alertAudioRadarSite_, | ||||||
|           &alertAudioRadius_, |           &alertAudioRadius_, | ||||||
|           &alertAudioCounty_, |           &alertAudioCounty_, | ||||||
|  |           &alertAudioWFO_, | ||||||
|           &hoverTextWrap_, |           &hoverTextWrap_, | ||||||
|           &tooltipMethod_, |           &tooltipMethod_, | ||||||
|           &placefileTextDropShadowEnabled_, |           &placefileTextDropShadowEnabled_, | ||||||
|  | @ -208,6 +211,7 @@ public: | ||||||
|    RadarSiteDialog*  alertAudioRadarSiteDialog_; |    RadarSiteDialog*  alertAudioRadarSiteDialog_; | ||||||
|    SerialPortDialog* gpsSourceDialog_; |    SerialPortDialog* gpsSourceDialog_; | ||||||
|    CountyDialog*     countyDialog_; |    CountyDialog*     countyDialog_; | ||||||
|  |    WFODialog*        wfoDialog_; | ||||||
|    QFontDialog*      fontDialog_; |    QFontDialog*      fontDialog_; | ||||||
| 
 | 
 | ||||||
|    QStandardItemModel* fontCategoryModel_; |    QStandardItemModel* fontCategoryModel_; | ||||||
|  | @ -262,6 +266,7 @@ public: | ||||||
|    settings::SettingsInterface<std::string> alertAudioRadarSite_ {}; |    settings::SettingsInterface<std::string> alertAudioRadarSite_ {}; | ||||||
|    settings::SettingsInterface<double>      alertAudioRadius_ {}; |    settings::SettingsInterface<double>      alertAudioRadius_ {}; | ||||||
|    settings::SettingsInterface<std::string> alertAudioCounty_ {}; |    settings::SettingsInterface<std::string> alertAudioCounty_ {}; | ||||||
|  |    settings::SettingsInterface<std::string> alertAudioWFO_ {}; | ||||||
| 
 | 
 | ||||||
|    std::unordered_map<awips::Phenomenon, settings::SettingsInterface<bool>> |    std::unordered_map<awips::Phenomenon, settings::SettingsInterface<bool>> | ||||||
|       alertAudioEnabled_ {}; |       alertAudioEnabled_ {}; | ||||||
|  | @ -948,6 +953,8 @@ void SettingsDialogImpl::SetupAudioTab() | ||||||
|             locationMethod == types::LocationMethod::RadarSite; |             locationMethod == types::LocationMethod::RadarSite; | ||||||
|          bool countyEntryEnabled = |          bool countyEntryEnabled = | ||||||
|             locationMethod == types::LocationMethod::County; |             locationMethod == types::LocationMethod::County; | ||||||
|  |          bool wfoEntryEnabled = | ||||||
|  |             locationMethod == types::LocationMethod::WFO; | ||||||
| 
 | 
 | ||||||
|          self_->ui->alertAudioLatitudeSpinBox->setEnabled( |          self_->ui->alertAudioLatitudeSpinBox->setEnabled( | ||||||
|             coordinateEntryEnabled); |             coordinateEntryEnabled); | ||||||
|  | @ -974,6 +981,10 @@ void SettingsDialogImpl::SetupAudioTab() | ||||||
|          self_->ui->alertAudioCountySelectButton->setEnabled( |          self_->ui->alertAudioCountySelectButton->setEnabled( | ||||||
|             countyEntryEnabled); |             countyEntryEnabled); | ||||||
|          self_->ui->resetAlertAudioCountyButton->setEnabled(countyEntryEnabled); |          self_->ui->resetAlertAudioCountyButton->setEnabled(countyEntryEnabled); | ||||||
|  | 
 | ||||||
|  |          self_->ui->alertAudioWFOLineEdit->setEnabled(wfoEntryEnabled); | ||||||
|  |          self_->ui->alertAudioWFOSelectButton->setEnabled(wfoEntryEnabled); | ||||||
|  |          self_->ui->resetAlertAudioWFOButton->setEnabled(wfoEntryEnabled); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|    settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); |    settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); | ||||||
|  | @ -1194,6 +1205,44 @@ void SettingsDialogImpl::SetupAudioTab() | ||||||
|    alertAudioCounty_.SetSettingsVariable(audioSettings.alert_county()); |    alertAudioCounty_.SetSettingsVariable(audioSettings.alert_county()); | ||||||
|    alertAudioCounty_.SetEditWidget(self_->ui->alertAudioCountyLineEdit); |    alertAudioCounty_.SetEditWidget(self_->ui->alertAudioCountyLineEdit); | ||||||
|    alertAudioCounty_.SetResetButton(self_->ui->resetAlertAudioCountyButton); |    alertAudioCounty_.SetResetButton(self_->ui->resetAlertAudioCountyButton); | ||||||
|  | 
 | ||||||
|  |    QObject::connect( | ||||||
|  |       self_->ui->alertAudioWFOSelectButton, | ||||||
|  |       &QAbstractButton::clicked, | ||||||
|  |       self_, | ||||||
|  |       [this]() | ||||||
|  |       { | ||||||
|  |          wfoDialog_->show(); | ||||||
|  |       }); | ||||||
|  |    QObject::connect(wfoDialog_, | ||||||
|  |                     &WFODialog::accepted, | ||||||
|  |                     self_, | ||||||
|  |                     [this]() | ||||||
|  |                     { | ||||||
|  |                        std::string wfoId  = wfoDialog_->wfo_id(); | ||||||
|  |                        QString     qWFOId = QString::fromStdString(wfoId); | ||||||
|  |                        self_->ui->alertAudioWFOLineEdit->setText(qWFOId); | ||||||
|  | 
 | ||||||
|  |                        // setText does not emit the textEdited signal
 | ||||||
|  |                        Q_EMIT self_->ui->alertAudioWFOLineEdit->textEdited( | ||||||
|  |                           qWFOId); | ||||||
|  |                     }); | ||||||
|  |    QObject::connect(self_->ui->alertAudioWFOLineEdit, | ||||||
|  |                     &QLineEdit::textChanged, | ||||||
|  |                     self_, | ||||||
|  |                     [this](const QString& text) | ||||||
|  |                     { | ||||||
|  |                        std::string wfoName = | ||||||
|  |                           config::CountyDatabase::GetWFOName( | ||||||
|  |                              text.toStdString()); | ||||||
|  |                        self_->ui->alertAudioWFOLabel->setText( | ||||||
|  |                           QString::fromStdString(wfoName)); | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |    alertAudioWFO_.SetSettingsVariable(audioSettings.alert_wfo()); | ||||||
|  |    alertAudioWFO_.SetEditWidget(self_->ui->alertAudioWFOLineEdit); | ||||||
|  |    alertAudioWFO_.SetResetButton(self_->ui->resetAlertAudioWFOButton); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SettingsDialogImpl::SetupTextTab() | void SettingsDialogImpl::SetupTextTab() | ||||||
|  |  | ||||||
|  | @ -136,8 +136,8 @@ | ||||||
|                <rect> |                <rect> | ||||||
|                 <x>0</x> |                 <x>0</x> | ||||||
|                 <y>0</y> |                 <y>0</y> | ||||||
|                 <width>511</width> |                 <width>274</width> | ||||||
|                 <height>647</height> |                 <height>691</height> | ||||||
|                </rect> |                </rect> | ||||||
|               </property> |               </property> | ||||||
|               <layout class="QVBoxLayout" name="verticalLayout"> |               <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  | @ -610,8 +610,8 @@ | ||||||
|                    <rect> |                    <rect> | ||||||
|                     <x>0</x> |                     <x>0</x> | ||||||
|                     <y>0</y> |                     <y>0</y> | ||||||
|                     <width>66</width> |                     <width>98</width> | ||||||
|                     <height>18</height> |                     <height>28</height> | ||||||
|                    </rect> |                    </rect> | ||||||
|                   </property> |                   </property> | ||||||
|                   <layout class="QGridLayout" name="gridLayout_3"> |                   <layout class="QGridLayout" name="gridLayout_3"> | ||||||
|  | @ -691,8 +691,15 @@ | ||||||
|               <string>Alerts</string> |               <string>Alerts</string> | ||||||
|              </property> |              </property> | ||||||
|              <layout class="QGridLayout" name="gridLayout_10"> |              <layout class="QGridLayout" name="gridLayout_10"> | ||||||
|               <item row="3" column="6"> |               <item row="7" column="0"> | ||||||
|                <widget class="QToolButton" name="resetAlertAudioLongitudeButton"> |                <widget class="QLabel" name="label_19"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>County</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="4" column="6"> | ||||||
|  |                <widget class="QToolButton" name="resetAlertAudioRadarSiteButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -702,6 +709,71 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  |               <item row="1" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_12"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Location Method</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="0" column="1" colspan="2"> | ||||||
|  |                <widget class="QLineEdit" name="alertAudioSoundLineEdit"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="2" column="6"> | ||||||
|  |                <widget class="QToolButton" name="resetAlertAudioLatitudeButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="3" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_16"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Longitude</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="4" column="3"> | ||||||
|  |                <widget class="QToolButton" name="alertAudioRadarSiteSelectButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="5" column="3"> | ||||||
|  |                <widget class="QLabel" name="alertAudioRadiusUnitsLabel"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string/> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="2" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_14"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Latitude</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="2" column="1" colspan="2"> | ||||||
|  |                <widget class="QDoubleSpinBox" name="alertAudioLatitudeSpinBox"> | ||||||
|  |                 <property name="decimals"> | ||||||
|  |                  <number>4</number> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="minimum"> | ||||||
|  |                  <double>-90.000000000000000</double> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="maximum"> | ||||||
|  |                  <double>90.000000000000000</double> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="singleStep"> | ||||||
|  |                  <double>0.000100000000000</double> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|               <item row="5" column="1" colspan="2"> |               <item row="5" column="1" colspan="2"> | ||||||
|                <widget class="QDoubleSpinBox" name="alertAudioRadiusSpinBox"> |                <widget class="QDoubleSpinBox" name="alertAudioRadiusSpinBox"> | ||||||
|                 <property name="decimals"> |                 <property name="decimals"> | ||||||
|  | @ -718,8 +790,8 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="2" column="6"> |               <item row="7" column="6"> | ||||||
|                <widget class="QToolButton" name="resetAlertAudioLatitudeButton"> |                <widget class="QToolButton" name="resetAlertAudioCountyButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -729,38 +801,25 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="1" column="1" colspan="2"> |               <item row="0" column="4"> | ||||||
|                <widget class="QComboBox" name="alertAudioLocationMethodComboBox"> |                <widget class="QToolButton" name="alertAudioSoundTestButton"> | ||||||
|                 <property name="sizePolicy"> |                 <property name="icon"> | ||||||
|                  <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|                   <horstretch>0</horstretch> |                   <normaloff>:/res/icons/font-awesome-6/play-solid.svg</normaloff>:/res/icons/font-awesome-6/play-solid.svg</iconset> | ||||||
|                   <verstretch>0</verstretch> |  | ||||||
|                  </sizepolicy> |  | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="7" column="0"> |               <item row="7" column="3"> | ||||||
|                <widget class="QLabel" name="label_19"> |                <widget class="QToolButton" name="alertAudioCountySelectButton"> | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>County</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="0" column="6"> |  | ||||||
|                <widget class="QToolButton" name="resetAlertAudioSoundButton"> |  | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="5" column="3"> |               <item row="5" column="0"> | ||||||
|                <widget class="QLabel" name="alertAudioRadiusUnitsLabel"> |                <widget class="QLabel" name="alertAudioRadiusLabel"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string/> |                  <string>Radius</string> | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  | @ -780,14 +839,10 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="1" column="6"> |               <item row="4" column="0"> | ||||||
|                <widget class="QToolButton" name="resetAlertAudioLocationMethodButton"> |                <widget class="QLabel" name="label_28"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>Radar Site</string> | ||||||
|                 </property> |  | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  | @ -798,32 +853,6 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="7" column="3"> |  | ||||||
|                <widget class="QToolButton" name="alertAudioCountySelectButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="0" column="1" colspan="2"> |  | ||||||
|                <widget class="QLineEdit" name="alertAudioSoundLineEdit"/> |  | ||||||
|               </item> |  | ||||||
|               <item row="2" column="1" colspan="2"> |  | ||||||
|                <widget class="QDoubleSpinBox" name="alertAudioLatitudeSpinBox"> |  | ||||||
|                 <property name="decimals"> |  | ||||||
|                  <number>4</number> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="minimum"> |  | ||||||
|                  <double>-90.000000000000000</double> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="maximum"> |  | ||||||
|                  <double>90.000000000000000</double> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="singleStep"> |  | ||||||
|                  <double>0.000100000000000</double> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="0" column="5"> |               <item row="0" column="5"> | ||||||
|                <widget class="QToolButton" name="alertAudioSoundStopButton"> |                <widget class="QToolButton" name="alertAudioSoundStopButton"> | ||||||
|                 <property name="icon"> |                 <property name="icon"> | ||||||
|  | @ -832,8 +861,8 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="5" column="6"> |               <item row="1" column="6"> | ||||||
|                <widget class="QToolButton" name="resetAlertAudioRadiusButton"> |                <widget class="QToolButton" name="resetAlertAudioLocationMethodButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -843,20 +872,6 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="2" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_14"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Latitude</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="0" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_17"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Sound</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="7" column="2"> |               <item row="7" column="2"> | ||||||
|                <widget class="QLabel" name="alertAudioCountyLabel"> |                <widget class="QLabel" name="alertAudioCountyLabel"> | ||||||
|                 <property name="sizePolicy"> |                 <property name="sizePolicy"> | ||||||
|  | @ -870,11 +885,25 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="0" column="4"> |               <item row="5" column="6"> | ||||||
|                <widget class="QToolButton" name="alertAudioSoundTestButton"> |                <widget class="QToolButton" name="resetAlertAudioRadiusButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|                 <property name="icon"> |                 <property name="icon"> | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/play-solid.svg</normaloff>:/res/icons/font-awesome-6/play-solid.svg</iconset> |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="0" column="6"> | ||||||
|  |                <widget class="QToolButton" name="resetAlertAudioSoundButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  | @ -891,66 +920,72 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="1" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_12"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Location Method</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="7" column="6"> |  | ||||||
|                <widget class="QToolButton" name="resetAlertAudioCountyButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="5" column="0"> |  | ||||||
|                <widget class="QLabel" name="alertAudioRadiusLabel"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Radius</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="3" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_16"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Longitude</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="4" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_28"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Radar Site</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="4" column="3"> |  | ||||||
|                <widget class="QToolButton" name="alertAudioRadarSiteSelectButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="4" column="6"> |  | ||||||
|                <widget class="QToolButton" name="resetAlertAudioRadarSiteButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="4" column="1" colspan="2"> |               <item row="4" column="1" colspan="2"> | ||||||
|                <widget class="QComboBox" name="alertAudioRadarSiteComboBox"/> |                <widget class="QComboBox" name="alertAudioRadarSiteComboBox"/> | ||||||
|               </item> |               </item> | ||||||
|  |               <item row="1" column="1" colspan="2"> | ||||||
|  |                <widget class="QComboBox" name="alertAudioLocationMethodComboBox"> | ||||||
|  |                 <property name="sizePolicy"> | ||||||
|  |                  <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |                   <horstretch>0</horstretch> | ||||||
|  |                   <verstretch>0</verstretch> | ||||||
|  |                  </sizepolicy> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="3" column="6"> | ||||||
|  |                <widget class="QToolButton" name="resetAlertAudioLongitudeButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="0" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_17"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Sound</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="8" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_29"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>WFO</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="8" column="6"> | ||||||
|  |                <widget class="QToolButton" name="resetAlertAudioWFOButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="8" column="1"> | ||||||
|  |                <widget class="QLineEdit" name="alertAudioWFOLineEdit"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="8" column="2"> | ||||||
|  |                <widget class="QLabel" name="alertAudioWFOLabel"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string/> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="8" column="3"> | ||||||
|  |                <widget class="QToolButton" name="alertAudioWFOSelectButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|              </layout> |              </layout> | ||||||
|             </widget> |             </widget> | ||||||
|            </item> |            </item> | ||||||
|  |  | ||||||
							
								
								
									
										142
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,142 @@ | ||||||
|  | #include "wfo_dialog.hpp" | ||||||
|  | #include "ui_wfo_dialog.h" | ||||||
|  | 
 | ||||||
|  | #include <scwx/qt/config/county_database.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #include <QPushButton> | ||||||
|  | #include <QSortFilterProxyModel> | ||||||
|  | #include <QStandardItemModel> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::ui::wfo_dialog"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | class WFODialog::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(WFODialog* self) : | ||||||
|  |        self_ {self}, | ||||||
|  |        model_ {new QStandardItemModel(self)}, | ||||||
|  |        proxyModel_ {new QSortFilterProxyModel(self)} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|  |    ~Impl() = default; | ||||||
|  | 
 | ||||||
|  |    void UpdateModel(); | ||||||
|  | 
 | ||||||
|  |    WFODialog*             self_; | ||||||
|  |    QStandardItemModel*    model_; | ||||||
|  |    QSortFilterProxyModel* proxyModel_; | ||||||
|  | 
 | ||||||
|  |    std::string selectedWFO_ {"?"}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | WFODialog::WFODialog(QWidget* parent) : | ||||||
|  |     QDialog(parent), p {std::make_unique<Impl>(this)}, ui(new Ui::WFODialog) | ||||||
|  | { | ||||||
|  |    ui->setupUi(this); | ||||||
|  | 
 | ||||||
|  |    p->proxyModel_->setSourceModel(p->model_); | ||||||
|  |    ui->wfoView->setModel(p->proxyModel_); | ||||||
|  |    ui->wfoView->setEditTriggers( | ||||||
|  |       QAbstractItemView::EditTrigger::NoEditTriggers); | ||||||
|  |    ui->wfoView->sortByColumn(0, Qt::SortOrder::AscendingOrder); | ||||||
|  |    ui->wfoView->header()->setSectionResizeMode( | ||||||
|  |       QHeaderView::ResizeMode::Stretch); | ||||||
|  | 
 | ||||||
|  |    p->UpdateModel(); | ||||||
|  | 
 | ||||||
|  |    // Button Box
 | ||||||
|  |    ui->buttonBox->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setEnabled(false); | ||||||
|  | 
 | ||||||
|  |    connect(ui->wfoView, | ||||||
|  |            &QTreeView::doubleClicked, | ||||||
|  |            this, | ||||||
|  |            [this]() { Q_EMIT accept(); }); | ||||||
|  |    connect( | ||||||
|  |       ui->wfoView->selectionModel(), | ||||||
|  |       &QItemSelectionModel::selectionChanged, | ||||||
|  |       this, | ||||||
|  |       [this](const QItemSelection& selected, const QItemSelection& deselected) | ||||||
|  |       { | ||||||
|  |          if (selected.size() == 0 && deselected.size() == 0) | ||||||
|  |          { | ||||||
|  |             // Items which stay selected but change their index are not
 | ||||||
|  |             // included in selected and deselected. Thus, this signal might
 | ||||||
|  |             // be emitted with both selected and deselected empty, if only
 | ||||||
|  |             // the indices of selected items change.
 | ||||||
|  |             return; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          ui->buttonBox->button(QDialogButtonBox::Ok) | ||||||
|  |             ->setEnabled(selected.size() > 0); | ||||||
|  | 
 | ||||||
|  |          if (selected.size() > 0) | ||||||
|  |          { | ||||||
|  |             QModelIndex selectedIndex = | ||||||
|  |                p->proxyModel_->mapToSource(selected[0].indexes()[0]); | ||||||
|  |             selectedIndex        = p->model_->index(selectedIndex.row(), 1); | ||||||
|  |             QVariant variantData = p->model_->data(selectedIndex); | ||||||
|  |             if (variantData.typeId() == QMetaType::QString) | ||||||
|  |             { | ||||||
|  |                p->selectedWFO_ = variantData.toString().toStdString(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                logger_->warn("Unexpected selection data type"); | ||||||
|  |                p->selectedWFO_ = std::string {"?"}; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             p->selectedWFO_ = std::string {"?"}; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          logger_->debug("Selected: {}", p->selectedWFO_); | ||||||
|  |       }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WFODialog::~WFODialog() | ||||||
|  | { | ||||||
|  |    delete ui; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string WFODialog::wfo_id() | ||||||
|  | { | ||||||
|  |    return p->selectedWFO_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WFODialog::Impl::UpdateModel() | ||||||
|  | { | ||||||
|  |    // Clear existing WFOs
 | ||||||
|  |    model_->clear(); | ||||||
|  | 
 | ||||||
|  |    // Disable OK button
 | ||||||
|  |    self_->ui->buttonBox->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setEnabled(false); | ||||||
|  | 
 | ||||||
|  |    // Reset headers
 | ||||||
|  |    model_->setHorizontalHeaderLabels({tr("State and City"), tr("ID")}); | ||||||
|  | 
 | ||||||
|  |    QStandardItem* root = model_->invisibleRootItem(); | ||||||
|  | 
 | ||||||
|  |    // Add each wfo to the model
 | ||||||
|  |    for (auto& wfo : config::CountyDatabase::GetWFOs()) | ||||||
|  |    { | ||||||
|  |       root->appendRow( | ||||||
|  |          {new QStandardItem(QString::fromStdString(wfo.second)), | ||||||
|  |           new QStandardItem(QString::fromStdString(wfo.first))}); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										34
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <QDialog> | ||||||
|  | 
 | ||||||
|  | namespace Ui | ||||||
|  | { | ||||||
|  | class WFODialog; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | class WFODialog : public QDialog | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  |    Q_DISABLE_COPY_MOVE(WFODialog) | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |    explicit WFODialog(QWidget* parent = nullptr); | ||||||
|  |    ~WFODialog(); | ||||||
|  | 
 | ||||||
|  |    std::string wfo_id(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  |    Ui::WFODialog*     ui; | ||||||
|  | }; | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										101
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								scwx-qt/source/scwx/qt/ui/wfo_dialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,101 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>WFODialog</class> | ||||||
|  |  <widget class="QDialog" name="WFODialog"> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>400</width> | ||||||
|  |     <height>400</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Select WFO</string> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QTreeView" name="wfoView"> | ||||||
|  |      <property name="alternatingRowColors"> | ||||||
|  |       <bool>true</bool> | ||||||
|  |      </property> | ||||||
|  |      <property name="indentation"> | ||||||
|  |       <number>0</number> | ||||||
|  |      </property> | ||||||
|  |      <property name="sortingEnabled"> | ||||||
|  |       <bool>true</bool> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QFrame" name="frame"> | ||||||
|  |      <property name="frameShape"> | ||||||
|  |       <enum>QFrame::Shape::StyledPanel</enum> | ||||||
|  |      </property> | ||||||
|  |      <property name="frameShadow"> | ||||||
|  |       <enum>QFrame::Shadow::Raised</enum> | ||||||
|  |      </property> | ||||||
|  |      <layout class="QHBoxLayout" name="horizontalLayout"> | ||||||
|  |       <property name="leftMargin"> | ||||||
|  |        <number>0</number> | ||||||
|  |       </property> | ||||||
|  |       <property name="topMargin"> | ||||||
|  |        <number>0</number> | ||||||
|  |       </property> | ||||||
|  |       <property name="rightMargin"> | ||||||
|  |        <number>0</number> | ||||||
|  |       </property> | ||||||
|  |       <property name="bottomMargin"> | ||||||
|  |        <number>0</number> | ||||||
|  |       </property> | ||||||
|  |       <item> | ||||||
|  |        <widget class="QDialogButtonBox" name="buttonBox"> | ||||||
|  |         <property name="orientation"> | ||||||
|  |          <enum>Qt::Orientation::Horizontal</enum> | ||||||
|  |         </property> | ||||||
|  |         <property name="standardButtons"> | ||||||
|  |          <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> | ||||||
|  |         </property> | ||||||
|  |        </widget> | ||||||
|  |       </item> | ||||||
|  |      </layout> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <resources/> | ||||||
|  |  <connections> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>accepted()</signal> | ||||||
|  |    <receiver>WFODialog</receiver> | ||||||
|  |    <slot>accept()</slot> | ||||||
|  |    <hints> | ||||||
|  |     <hint type="sourcelabel"> | ||||||
|  |      <x>248</x> | ||||||
|  |      <y>254</y> | ||||||
|  |     </hint> | ||||||
|  |     <hint type="destinationlabel"> | ||||||
|  |      <x>157</x> | ||||||
|  |      <y>274</y> | ||||||
|  |     </hint> | ||||||
|  |    </hints> | ||||||
|  |   </connection> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>rejected()</signal> | ||||||
|  |    <receiver>WFODialog</receiver> | ||||||
|  |    <slot>reject()</slot> | ||||||
|  |    <hints> | ||||||
|  |     <hint type="sourcelabel"> | ||||||
|  |      <x>316</x> | ||||||
|  |      <y>260</y> | ||||||
|  |     </hint> | ||||||
|  |     <hint type="destinationlabel"> | ||||||
|  |      <x>286</x> | ||||||
|  |      <y>274</y> | ||||||
|  |     </hint> | ||||||
|  |    </hints> | ||||||
|  |   </connection> | ||||||
|  |  </connections> | ||||||
|  | </ui> | ||||||
|  | @ -34,6 +34,14 @@ def ParseArguments(): | ||||||
|                         nargs   = "+", |                         nargs   = "+", | ||||||
|                         default = [], |                         default = [], | ||||||
|                         type    = pathlib.Path) |                         type    = pathlib.Path) | ||||||
|  |     parser.add_argument("-w", "--wfo_dbf", | ||||||
|  |                         metavar = "filename", | ||||||
|  |                         help    = "input wfo database", | ||||||
|  |                         dest    = "inputWfoDbs_", | ||||||
|  |                         action  = "extend", | ||||||
|  |                         nargs   = "+", | ||||||
|  |                         default = [], | ||||||
|  |                         type    = pathlib.Path) | ||||||
|     parser.add_argument("-o", "--output_db", |     parser.add_argument("-o", "--output_db", | ||||||
|                         metavar  = "filename", |                         metavar  = "filename", | ||||||
|                         help     = "output sqlite database", |                         help     = "output sqlite database", | ||||||
|  | @ -62,6 +70,11 @@ def Prepare(dbInfo, outputDb): | ||||||
|     dbInfo.sqlCursor_.execute("""CREATE TABLE states( |     dbInfo.sqlCursor_.execute("""CREATE TABLE states( | ||||||
|         state TEXT NOT NULL PRIMARY KEY, |         state TEXT NOT NULL PRIMARY KEY, | ||||||
|         name  TEXT NOT NULL)""") |         name  TEXT NOT NULL)""") | ||||||
|  |     dbInfo.sqlCursor_.execute("""CREATE TABLE wfos( | ||||||
|  |         id TEXT NOT NULL PRIMARY KEY, | ||||||
|  |         city       TEXT NOT NULL, | ||||||
|  |         state      TEXT NOT NULL, | ||||||
|  |         city_state TEXT NOT NULL)""") | ||||||
| 
 | 
 | ||||||
| def ProcessCountiesDbf(dbInfo, dbfFilename): | def ProcessCountiesDbf(dbInfo, dbfFilename): | ||||||
|     # County area type |     # County area type | ||||||
|  | @ -130,6 +143,22 @@ def ProcessZoneDbf(dbInfo, dbfFilename): | ||||||
|                 if resultRow["name"] != row.NAME: |                 if resultRow["name"] != row.NAME: | ||||||
|                     print("Skipping duplicate zone:", fipsId, row.NAME) |                     print("Skipping duplicate zone:", fipsId, row.NAME) | ||||||
| 
 | 
 | ||||||
|  | def ProcessWfoDbf(dbInfo, dbfFilename): | ||||||
|  |     print("Processing WFO file:", dbfFilename) | ||||||
|  | 
 | ||||||
|  |     # Read dataframe | ||||||
|  |     dbfTable = gpd.read_file(filename        = dbfFilename, | ||||||
|  |                              columns         = ["FULLSTAID", "CITY", "STATE", "CITYSTATE"], | ||||||
|  |                              ignore_geometry = True) | ||||||
|  |     dbfTable.drop_duplicates(inplace = True) | ||||||
|  | 
 | ||||||
|  |     for row in dbfTable.itertuples(): | ||||||
|  |         try: | ||||||
|  |             dbInfo.sqlCursor_.execute("INSERT INTO wfos VALUES (?, ?, ?, ?)", | ||||||
|  |                                       (row.FULLSTAID, row.CITY, row.STATE, row.CITYSTATE)) | ||||||
|  |         except: | ||||||
|  |             print("Error inserting WFO:", row.FULLSTAID, row.CITYSTATE) | ||||||
|  | 
 | ||||||
| def PostProcess(dbInfo): | def PostProcess(dbInfo): | ||||||
|     # Commit changes and close database |     # Commit changes and close database | ||||||
|     dbInfo.sqlConnection_.commit() |     dbInfo.sqlConnection_.commit() | ||||||
|  | @ -148,4 +177,7 @@ for zoneDb in args.inputZoneDbs_: | ||||||
| for stateDb in args.inputStateDbs_: | for stateDb in args.inputStateDbs_: | ||||||
|     ProcessStateDbf(dbInfo, stateDb) |     ProcessStateDbf(dbInfo, stateDb) | ||||||
| 
 | 
 | ||||||
|  | for wfoDb in args.inputWfoDbs_: | ||||||
|  |     ProcessWfoDbf(dbInfo, wfoDb) | ||||||
|  | 
 | ||||||
| PostProcess(dbInfo) | PostProcess(dbInfo) | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| Subproject commit 5115993596cfe6528b7a07c0b16dbd1ae16ce4df | Subproject commit 5a91ded677d4032b0de9370ed767a16708c0ecff | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat