mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 23:50:05 +00:00 
			
		
		
		
	Add county selection dialog
This commit is contained in:
		
							parent
							
								
									bcc7391a19
								
							
						
					
					
						commit
						769ce896e7
					
				
					 6 changed files with 325 additions and 0 deletions
				
			
		|  | @ -203,6 +203,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | ||||||
|            source/scwx/qt/ui/alert_dock_widget.hpp |            source/scwx/qt/ui/alert_dock_widget.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/flow_layout.hpp |            source/scwx/qt/ui/flow_layout.hpp | ||||||
|            source/scwx/qt/ui/imgui_debug_dialog.hpp |            source/scwx/qt/ui/imgui_debug_dialog.hpp | ||||||
|            source/scwx/qt/ui/imgui_debug_widget.hpp |            source/scwx/qt/ui/imgui_debug_widget.hpp | ||||||
|  | @ -222,6 +223,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp | ||||||
|            source/scwx/qt/ui/alert_dock_widget.cpp |            source/scwx/qt/ui/alert_dock_widget.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/flow_layout.cpp |            source/scwx/qt/ui/flow_layout.cpp | ||||||
|            source/scwx/qt/ui/imgui_debug_dialog.cpp |            source/scwx/qt/ui/imgui_debug_dialog.cpp | ||||||
|            source/scwx/qt/ui/imgui_debug_widget.cpp |            source/scwx/qt/ui/imgui_debug_widget.cpp | ||||||
|  | @ -241,6 +243,7 @@ set(UI_UI  source/scwx/qt/ui/about_dialog.ui | ||||||
|            source/scwx/qt/ui/alert_dock_widget.ui |            source/scwx/qt/ui/alert_dock_widget.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/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 | ||||||
|            source/scwx/qt/ui/open_url_dialog.ui |            source/scwx/qt/ui/open_url_dialog.ui | ||||||
|  |  | ||||||
|  | @ -225,6 +225,11 @@ GetCounties(const std::string& state) | ||||||
|    return counties; |    return counties; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const std::unordered_map<std::string, std::string>& GetStates() | ||||||
|  | { | ||||||
|  |    return stateMap_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace CountyDatabase
 | } // namespace CountyDatabase
 | ||||||
| } // namespace config
 | } // namespace config
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ void        Initialize(); | ||||||
| std::string GetCountyName(const std::string& id); | 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(); | ||||||
| 
 | 
 | ||||||
| } // namespace CountyDatabase
 | } // namespace CountyDatabase
 | ||||||
| } // namespace config
 | } // namespace config
 | ||||||
|  |  | ||||||
							
								
								
									
										175
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,175 @@ | ||||||
|  | #include "county_dialog.hpp" | ||||||
|  | #include "ui_county_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::county_dialog"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | class CountyDialog::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(CountyDialog* self) : | ||||||
|  |        self_ {self}, | ||||||
|  |        model_ {new QStandardItemModel(self)}, | ||||||
|  |        proxyModel_ {new QSortFilterProxyModel(self)}, | ||||||
|  |        states_ {config::CountyDatabase::GetStates()} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|  |    ~Impl() = default; | ||||||
|  | 
 | ||||||
|  |    void UpdateModel(const std::string& stateName); | ||||||
|  | 
 | ||||||
|  |    CountyDialog*          self_; | ||||||
|  |    QStandardItemModel*    model_; | ||||||
|  |    QSortFilterProxyModel* proxyModel_; | ||||||
|  | 
 | ||||||
|  |    std::string selectedCounty_ {"?"}; | ||||||
|  | 
 | ||||||
|  |    const std::unordered_map<std::string, std::string>& states_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | CountyDialog::CountyDialog(QWidget* parent) : | ||||||
|  |     QDialog(parent), p {std::make_unique<Impl>(this)}, ui(new Ui::CountyDialog) | ||||||
|  | { | ||||||
|  |    ui->setupUi(this); | ||||||
|  | 
 | ||||||
|  |    for (auto& state : p->states_) | ||||||
|  |    { | ||||||
|  |       ui->stateComboBox->addItem(QString::fromStdString(state.second)); | ||||||
|  |    } | ||||||
|  |    ui->stateComboBox->model()->sort(0); | ||||||
|  |    ui->stateComboBox->setCurrentIndex(0); | ||||||
|  | 
 | ||||||
|  |    p->proxyModel_->setSourceModel(p->model_); | ||||||
|  |    ui->countyView->setModel(p->proxyModel_); | ||||||
|  |    ui->countyView->setEditTriggers( | ||||||
|  |       QAbstractItemView::EditTrigger::NoEditTriggers); | ||||||
|  |    ui->countyView->sortByColumn(0, Qt::SortOrder::AscendingOrder); | ||||||
|  |    ui->countyView->header()->setSectionResizeMode( | ||||||
|  |       QHeaderView::ResizeMode::Stretch); | ||||||
|  | 
 | ||||||
|  |    connect(ui->stateComboBox, | ||||||
|  |            &QComboBox::currentTextChanged, | ||||||
|  |            this, | ||||||
|  |            [this](const QString& text) { p->UpdateModel(text.toStdString()); }); | ||||||
|  |    p->UpdateModel(ui->stateComboBox->currentText().toStdString()); | ||||||
|  | 
 | ||||||
|  |    // Button Box
 | ||||||
|  |    ui->buttonBox->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setEnabled(false); | ||||||
|  | 
 | ||||||
|  |    connect(ui->countyView, | ||||||
|  |            &QTreeView::doubleClicked, | ||||||
|  |            this, | ||||||
|  |            [this]() { Q_EMIT accept(); }); | ||||||
|  |    connect( | ||||||
|  |       ui->countyView->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->selectedCounty_ = variantData.toString().toStdString(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                logger_->warn("Unexpected selection data type"); | ||||||
|  |                p->selectedCounty_ = std::string {"?"}; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             p->selectedCounty_ = std::string {"?"}; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          logger_->debug("Selected: {}", p->selectedCounty_); | ||||||
|  |       }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | CountyDialog::~CountyDialog() | ||||||
|  | { | ||||||
|  |    delete ui; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string CountyDialog::county_fips_id() | ||||||
|  | { | ||||||
|  |    return p->selectedCounty_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CountyDialog::SelectState(const std::string& state) | ||||||
|  | { | ||||||
|  |    auto it = p->states_.find(state); | ||||||
|  |    if (it != p->states_.cend()) | ||||||
|  |    { | ||||||
|  |       ui->stateComboBox->setCurrentText(QString::fromStdString(it->second)); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CountyDialog::Impl::UpdateModel(const std::string& stateName) | ||||||
|  | { | ||||||
|  |    // Clear existing counties
 | ||||||
|  |    model_->clear(); | ||||||
|  | 
 | ||||||
|  |    // Reset selected county and disable OK button
 | ||||||
|  |    selectedCounty_ = std::string {"?"}; | ||||||
|  |    self_->ui->buttonBox->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setEnabled(false); | ||||||
|  | 
 | ||||||
|  |    // Reset headers
 | ||||||
|  |    model_->setHorizontalHeaderLabels({tr("County / Area"), tr("FIPS ID")}); | ||||||
|  | 
 | ||||||
|  |    // Find the state ID from the statename
 | ||||||
|  |    auto it = std::find_if(states_.cbegin(), | ||||||
|  |                           states_.cend(), | ||||||
|  |                           [&](const std::pair<std::string, std::string>& record) | ||||||
|  |                           { return record.second == stateName; }); | ||||||
|  | 
 | ||||||
|  |    if (it != states_.cend()) | ||||||
|  |    { | ||||||
|  |       QStandardItem* root = model_->invisibleRootItem(); | ||||||
|  | 
 | ||||||
|  |       // Add each county to the model
 | ||||||
|  |       for (auto& county : config::CountyDatabase::GetCounties(it->first)) | ||||||
|  |       { | ||||||
|  |          root->appendRow( | ||||||
|  |             {new QStandardItem(QString::fromStdString(county.second)), | ||||||
|  |              new QStandardItem(QString::fromStdString(county.first))}); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										37
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <QDialog> | ||||||
|  | 
 | ||||||
|  | namespace Ui | ||||||
|  | { | ||||||
|  | class CountyDialog; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | class CountyDialog : public QDialog | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  |    Q_DISABLE_COPY_MOVE(CountyDialog) | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |    explicit CountyDialog(QWidget* parent = nullptr); | ||||||
|  |    ~CountyDialog(); | ||||||
|  | 
 | ||||||
|  |    std::string county_fips_id(); | ||||||
|  | 
 | ||||||
|  |    void SelectState(const std::string& state); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  |    Ui::CountyDialog*     ui; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										104
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								scwx-qt/source/scwx/qt/ui/county_dialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,104 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>CountyDialog</class> | ||||||
|  |  <widget class="QDialog" name="CountyDialog"> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>400</width> | ||||||
|  |     <height>400</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Select County</string> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QTreeView" name="countyView"> | ||||||
|  |      <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::StyledPanel</enum> | ||||||
|  |      </property> | ||||||
|  |      <property name="frameShadow"> | ||||||
|  |       <enum>QFrame::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="QComboBox" name="stateComboBox"/> | ||||||
|  |       </item> | ||||||
|  |       <item> | ||||||
|  |        <widget class="QDialogButtonBox" name="buttonBox"> | ||||||
|  |         <property name="orientation"> | ||||||
|  |          <enum>Qt::Horizontal</enum> | ||||||
|  |         </property> | ||||||
|  |         <property name="standardButtons"> | ||||||
|  |          <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||||||
|  |         </property> | ||||||
|  |        </widget> | ||||||
|  |       </item> | ||||||
|  |      </layout> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <resources/> | ||||||
|  |  <connections> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>accepted()</signal> | ||||||
|  |    <receiver>CountyDialog</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>CountyDialog</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> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat