mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 17:30: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/animation_dock_widget.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/imgui_debug_dialog.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/animation_dock_widget.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/imgui_debug_dialog.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/animation_dock_widget.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/layer_dialog.ui
|
||||
source/scwx/qt/ui/open_url_dialog.ui
|
||||
|
|
|
|||
|
|
@ -225,6 +225,11 @@ GetCounties(const std::string& state)
|
|||
return counties;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, std::string>& GetStates()
|
||||
{
|
||||
return stateMap_;
|
||||
}
|
||||
|
||||
} // namespace CountyDatabase
|
||||
} // namespace config
|
||||
} // namespace qt
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ void Initialize();
|
|||
std::string GetCountyName(const std::string& id);
|
||||
std::unordered_map<std::string, std::string>
|
||||
GetCounties(const std::string& state);
|
||||
const std::unordered_map<std::string, std::string>& GetStates();
|
||||
|
||||
} // namespace CountyDatabase
|
||||
} // 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