141 lines
5.6 KiB
C++
141 lines
5.6 KiB
C++
#include "panels/chart/ExceptionDetailDialog.hpp"
|
||
|
||
#include <QColorDialog>
|
||
#include <QComboBox>
|
||
#include <QDoubleSpinBox>
|
||
#include <QFormLayout>
|
||
#include <QHBoxLayout>
|
||
#include <QHeaderView>
|
||
#include <QJsonObject>
|
||
#include <QLabel>
|
||
#include <QLineEdit>
|
||
#include <QMessageBox>
|
||
#include <QPlainTextEdit>
|
||
#include <QPointer>
|
||
#include <QPushButton>
|
||
#include <QTableWidget>
|
||
#include <QVBoxLayout>
|
||
|
||
#include "FormKit.hpp"
|
||
#include "Theme.hpp"
|
||
#include "repo/IDatasetCommandRepository.hpp"
|
||
|
||
namespace geopro::app {
|
||
|
||
ExceptionDetailDialog::ExceptionDetailDialog(geopro::data::IDatasetCommandRepository* repo,
|
||
const geopro::core::Anomaly& anomaly, QWidget* parent)
|
||
: QDialog(parent), repo_(repo), anomaly_(anomaly) {
|
||
setWindowTitle(QStringLiteral("异常详情"));
|
||
setModal(true);
|
||
resize(420, 460);
|
||
|
||
lineColor_ = QString::fromStdString(anomaly_.lineColor);
|
||
if (lineColor_.isEmpty()) lineColor_ = QStringLiteral("#000000");
|
||
|
||
auto* root = formkit::dialogRoot(this);
|
||
|
||
auto* card = formkit::formCard(this);
|
||
auto* cardLay = formkit::cardBody(card);
|
||
auto* form = formkit::makeEditForm();
|
||
|
||
nameEdit_ = new QLineEdit(QString::fromStdString(anomaly_.name), this);
|
||
formkit::capField(nameEdit_);
|
||
form->addRow(formkit::editLabel(QStringLiteral("名称")), nameEdit_);
|
||
|
||
auto* typeLabel = new QLabel(QString::fromStdString(anomaly_.typeName), this);
|
||
form->addRow(formkit::editLabel(QStringLiteral("异常类型")), typeLabel);
|
||
|
||
// 图例:线色 / 线宽 / 线型(对照原版 legend.polyline*)。
|
||
colorBtn_ = new QPushButton(lineColor_, this);
|
||
colorBtn_->setStyleSheet(QStringLiteral("background:%1;").arg(lineColor_));
|
||
connect(colorBtn_, &QPushButton::clicked, this, [this]() {
|
||
const QColor c = QColorDialog::getColor(QColor(lineColor_), this, QStringLiteral("线色"));
|
||
if (c.isValid()) {
|
||
lineColor_ = c.name();
|
||
colorBtn_->setText(lineColor_);
|
||
colorBtn_->setStyleSheet(QStringLiteral("background:%1;").arg(lineColor_));
|
||
}
|
||
});
|
||
formkit::capField(colorBtn_);
|
||
form->addRow(formkit::editLabel(QStringLiteral("线色")), colorBtn_);
|
||
|
||
widthSpin_ = new QDoubleSpinBox(this);
|
||
widthSpin_->setRange(0.1, 20.0);
|
||
widthSpin_->setSingleStep(0.5);
|
||
widthSpin_->setValue(anomaly_.lineWidth > 0 ? anomaly_.lineWidth : 1.0);
|
||
formkit::capField(widthSpin_);
|
||
form->addRow(formkit::editLabel(QStringLiteral("线宽")), widthSpin_);
|
||
|
||
shapeCombo_ = new QComboBox(this);
|
||
shapeCombo_->addItem(QStringLiteral("实线"), QStringLiteral("solid"));
|
||
shapeCombo_->addItem(QStringLiteral("虚线"), QStringLiteral("dash"));
|
||
shapeCombo_->setCurrentIndex(anomaly_.dashed ? 1 : 0);
|
||
formkit::capField(shapeCombo_);
|
||
form->addRow(formkit::editLabel(QStringLiteral("线型")), shapeCombo_);
|
||
|
||
remarkEdit_ = new QPlainTextEdit(QString::fromStdString(anomaly_.remark), this);
|
||
remarkEdit_->setFixedHeight(geopro::app::scaledPx(60));
|
||
formkit::capField(remarkEdit_);
|
||
form->addRow(formkit::editLabel(QStringLiteral("备注")), remarkEdit_);
|
||
cardLay->addLayout(form);
|
||
root->addWidget(card);
|
||
|
||
// 坐标(只读展示,对照原版坐标信息 tab)。
|
||
root->addWidget(new QLabel(QStringLiteral("坐标:"), this));
|
||
auto* coordTable = new QTableWidget(static_cast<int>(anomaly_.localPts.size()), 2, this);
|
||
coordTable->setHorizontalHeaderLabels({QStringLiteral("x"), QStringLiteral("y")});
|
||
coordTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||
coordTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||
for (int r = 0; r < static_cast<int>(anomaly_.localPts.size()); ++r) {
|
||
coordTable->setItem(r, 0,
|
||
new QTableWidgetItem(QString::number(anomaly_.localPts[r].x, 'f', 7)));
|
||
coordTable->setItem(r, 1,
|
||
new QTableWidgetItem(QString::number(anomaly_.localPts[r].y, 'f', 7)));
|
||
}
|
||
root->addWidget(coordTable, 1);
|
||
|
||
auto* btnLay = new QHBoxLayout();
|
||
btnLay->addStretch();
|
||
auto* cancelBtn = new QPushButton(QStringLiteral("取消"), this);
|
||
okBtn_ = new QPushButton(QStringLiteral("确定"), this);
|
||
okBtn_->setDefault(true);
|
||
btnLay->addWidget(cancelBtn);
|
||
btnLay->addWidget(okBtn_);
|
||
root->addLayout(btnLay);
|
||
|
||
connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject);
|
||
connect(okBtn_, &QPushButton::clicked, this, &ExceptionDetailDialog::onConfirm);
|
||
}
|
||
|
||
void ExceptionDetailDialog::onConfirm() {
|
||
if (!repo_ || anomaly_.id.empty()) { reject(); return; }
|
||
const QString name = nameEdit_->text().trimmed();
|
||
if (name.isEmpty()) {
|
||
QMessageBox::warning(this, windowTitle(), QStringLiteral("请输入名称"));
|
||
return;
|
||
}
|
||
// 原版详情抽屉「改名称/备注」走 PUT /business/exception 的局部更新,
|
||
// 仅发 {id, exceptionName, remark}(线样式是另一条独立 PUT,且抽屉里样式控件 disabled)。
|
||
// 对齐原版 contourPage.vue onOk:不合并/不重发 legend。
|
||
QJsonObject body{
|
||
{QStringLiteral("id"), QString::fromStdString(anomaly_.id)},
|
||
{QStringLiteral("exceptionName"), name},
|
||
{QStringLiteral("remark"), remarkEdit_->toPlainText()},
|
||
};
|
||
|
||
okBtn_->setEnabled(false);
|
||
QPointer<ExceptionDetailDialog> self(this);
|
||
repo_->updateException(body, [self](bool ok, QString msg) {
|
||
if (!self) return;
|
||
self->okBtn_->setEnabled(true);
|
||
if (ok) {
|
||
self->accept();
|
||
} else {
|
||
QMessageBox::warning(self, self->windowTitle(),
|
||
msg.isEmpty() ? QStringLiteral("更新失败") : msg);
|
||
}
|
||
});
|
||
}
|
||
|
||
} // namespace geopro::app
|