supercell-wx/scwx-qt/source/scwx/qt/ui/alert_dock_widget.cpp
2024-09-12 11:46:39 -04:00

235 lines
7.1 KiB
C++

#include "alert_dock_widget.hpp"
#include "ui_alert_dock_widget.h"
#include <scwx/qt/manager/text_event_manager.hpp>
#include <scwx/qt/model/alert_model.hpp>
#include <scwx/qt/model/alert_proxy_model.hpp>
#include <scwx/qt/settings/general_settings.hpp>
#include <scwx/qt/types/alert_types.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/qt/ui/alert_dialog.hpp>
#include <scwx/util/logger.hpp>
namespace scwx
{
namespace qt
{
namespace ui
{
static const std::string logPrefix_ = "scwx::qt::ui::alert_dock_widget";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class AlertDockWidgetImpl : QObject
{
Q_OBJECT
public:
explicit AlertDockWidgetImpl(AlertDockWidget* self) :
self_ {self},
textEventManager_ {manager::TextEventManager::Instance()},
alertModel_ {std::make_unique<model::AlertModel>()},
proxyModel_ {std::make_unique<model::AlertProxyModel>()},
alertDialog_ {new AlertDialog(self)},
mapPosition_ {},
mapUpdateDeferred_ {false},
selectedAlertKey_ {},
selectedAlertCentroid_ {}
{
proxyModel_->setSourceModel(alertModel_.get());
proxyModel_->setSortRole(types::SortRole);
proxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxyModel_->setFilterKeyColumn(-1);
}
~AlertDockWidgetImpl() = default;
void ConnectSignals();
AlertDockWidget* self_;
std::shared_ptr<manager::TextEventManager> textEventManager_;
std::unique_ptr<model::AlertModel> alertModel_;
std::unique_ptr<model::AlertProxyModel> proxyModel_;
AlertDialog* alertDialog_;
scwx::common::Coordinate mapPosition_;
bool mapUpdateDeferred_;
types::TextEventKey selectedAlertKey_;
common::Coordinate selectedAlertCentroid_;
};
AlertDockWidget::AlertDockWidget(QWidget* parent) :
QDockWidget(parent),
p {std::make_unique<AlertDockWidgetImpl>(this)},
ui(new Ui::AlertDockWidget)
{
ui->setupUi(this);
ui->alertView->setModel(p->proxyModel_.get());
ui->alertView->header()->setSortIndicator(
static_cast<int>(model::AlertModel::Column::Distance),
Qt::AscendingOrder);
ui->alertView->header()->resizeSections(
QHeaderView::ResizeMode::ResizeToContents);
ui->alertSettings->addAction(ui->actionActiveAlerts);
ui->alertViewButton->setEnabled(false);
ui->alertGoButton->setEnabled(false);
p->ConnectSignals();
// Check Active Alerts and trigger signal
ui->actionActiveAlerts->setChecked(true);
}
AlertDockWidget::~AlertDockWidget()
{
delete ui;
}
void AlertDockWidget::showEvent(QShowEvent* event)
{
if (p->mapUpdateDeferred_)
{
p->alertModel_->HandleMapUpdate(p->mapPosition_.latitude_,
p->mapPosition_.longitude_);
p->mapUpdateDeferred_ = false;
}
QDockWidget::showEvent(event);
}
void AlertDockWidget::HandleMapUpdate(double latitude, double longitude)
{
p->mapPosition_ = {latitude, longitude};
if (isVisible())
{
p->alertModel_->HandleMapUpdate(latitude, longitude);
}
else
{
p->mapUpdateDeferred_ = true;
}
}
void AlertDockWidget::SelectAlert(const types::TextEventKey& key)
{
// View alert
p->alertDialog_->SelectAlert(key);
p->alertDialog_->show();
}
void AlertDockWidgetImpl::ConnectSignals()
{
connect(self_->ui->alertFilter,
&QLineEdit::textChanged,
proxyModel_.get(),
&QSortFilterProxyModel::setFilterWildcard);
connect(self_->ui->actionActiveAlerts,
&QAction::toggled,
proxyModel_.get(),
&model::AlertProxyModel::SetAlertActiveFilter);
connect(textEventManager_.get(),
&manager::TextEventManager::AlertUpdated,
alertModel_.get(),
&model::AlertModel::HandleAlert,
Qt::QueuedConnection);
connect(
self_->ui->alertView->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;
}
bool itemSelected = selected.size() > 0;
bool itemHasCoordinates = false;
if (itemSelected)
{
QModelIndex selectedIndex =
proxyModel_->mapToSource(selected[0].indexes()[0]);
selectedAlertKey_ = alertModel_->key(selectedIndex);
selectedAlertCentroid_ = alertModel_->centroid(selectedAlertKey_);
itemHasCoordinates =
selectedAlertCentroid_ != common::Coordinate {};
}
else
{
selectedAlertKey_ = {};
selectedAlertCentroid_ = {};
}
self_->ui->alertViewButton->setEnabled(itemSelected);
self_->ui->alertGoButton->setEnabled(itemHasCoordinates);
logger_->debug("Selected: {}", selectedAlertKey_.ToString());
});
connect(self_->ui->alertView,
&QTreeView::doubleClicked,
this,
[this](const QModelIndex& /* index */)
{
// If an item is selected
if (selectedAlertKey_ != types::TextEventKey {})
{
types::AlertAction alertAction =
types::GetAlertAction(settings::GeneralSettings::Instance()
.default_alert_action()
.GetValue());
switch (alertAction)
{
case types::AlertAction::Go:
// Move map
Q_EMIT self_->MoveMap(selectedAlertCentroid_.latitude_,
selectedAlertCentroid_.longitude_);
break;
case types::AlertAction::View:
// View alert
alertDialog_->SelectAlert(selectedAlertKey_);
alertDialog_->show();
break;
default:
// Do nothing
break;
}
}
});
connect(self_->ui->alertViewButton,
&QPushButton::clicked,
this,
[this]()
{
// View alert
alertDialog_->SelectAlert(selectedAlertKey_);
alertDialog_->show();
});
connect(self_->ui->alertGoButton,
&QPushButton::clicked,
this,
[this]()
{
Q_EMIT self_->MoveMap(selectedAlertCentroid_.latitude_,
selectedAlertCentroid_.longitude_);
});
connect(
alertDialog_, &AlertDialog::MoveMap, self_, &AlertDockWidget::MoveMap);
}
#include "alert_dock_widget.moc"
} // namespace ui
} // namespace qt
} // namespace scwx