feat/vtk-3d-view #7
|
|
@ -97,14 +97,16 @@ ColorScaleConfigDialog::ColorScaleConfigDialog(const geopro::core::ColorScale& i
|
||||||
double vmax, std::vector<double> samples,
|
double vmax, std::vector<double> samples,
|
||||||
const ContourLineConfig& lineInit,
|
const ContourLineConfig& lineInit,
|
||||||
geopro::data::IColorTemplateRepository* tplRepo,
|
geopro::data::IColorTemplateRepository* tplRepo,
|
||||||
QString projectId, QWidget* parent)
|
QString projectId, QString lvlTemplateId,
|
||||||
|
QWidget* parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
vmin_(vmin),
|
vmin_(vmin),
|
||||||
vmax_(vmax),
|
vmax_(vmax),
|
||||||
samples_(std::move(samples)),
|
samples_(std::move(samples)),
|
||||||
lineCfg_(lineInit),
|
lineCfg_(lineInit),
|
||||||
tplRepo_(tplRepo),
|
tplRepo_(tplRepo),
|
||||||
projectId_(std::move(projectId)) {
|
projectId_(std::move(projectId)),
|
||||||
|
lvlTemplateId_(std::move(lvlTemplateId)) {
|
||||||
setWindowTitle(QStringLiteral("色阶配置"));
|
setWindowTitle(QStringLiteral("色阶配置"));
|
||||||
setModal(true);
|
setModal(true);
|
||||||
resize(560, 420);
|
resize(560, 420);
|
||||||
|
|
@ -433,11 +435,31 @@ void ColorScaleConfigDialog::loadColorBar(
|
||||||
|
|
||||||
void ColorScaleConfigDialog::onSaveOther() {
|
void ColorScaleConfigDialog::onSaveOther() {
|
||||||
if (tplRepo_ == nullptr || projectId_.isEmpty()) return;
|
if (tplRepo_ == nullptr || projectId_.isEmpty()) return;
|
||||||
bool ok = false;
|
|
||||||
const QString name = QInputDialog::getText(this, QStringLiteral("另存模板配置"),
|
// 自定义另存为弹窗(复刻 handleSaveOther):名称输入 + 覆盖复选框。
|
||||||
QStringLiteral("模板名称:"), QLineEdit::Normal,
|
// 「覆盖」仅当有来源模板 id(lvlTemplateId_ 非空)时可勾选,对照原版 props.data.lvlTemplateId。
|
||||||
QStringLiteral("等值线配置.lvl"), &ok);
|
QDialog askDlg(this);
|
||||||
if (!ok || name.trimmed().isEmpty()) return;
|
askDlg.setWindowTitle(QStringLiteral("另存模板配置"));
|
||||||
|
askDlg.setModal(true);
|
||||||
|
auto* askRoot = new QVBoxLayout(&askDlg);
|
||||||
|
auto* nameRow = new QHBoxLayout();
|
||||||
|
nameRow->addWidget(new QLabel(QStringLiteral("模板名称:"), &askDlg));
|
||||||
|
auto* nameEdit = new QLineEdit(QStringLiteral("等值线配置.lvl"), &askDlg);
|
||||||
|
nameRow->addWidget(nameEdit, 1);
|
||||||
|
askRoot->addLayout(nameRow);
|
||||||
|
auto* overwriteCheck = new QCheckBox(QStringLiteral("覆盖原模板"), &askDlg);
|
||||||
|
overwriteCheck->setEnabled(!lvlTemplateId_.isEmpty()); // 无来源模板 → 禁用覆盖
|
||||||
|
askRoot->addWidget(overwriteCheck);
|
||||||
|
auto* askBtns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &askDlg);
|
||||||
|
askBtns->button(QDialogButtonBox::Ok)->setText(QStringLiteral("应用"));
|
||||||
|
askBtns->button(QDialogButtonBox::Cancel)->setText(QStringLiteral("取消"));
|
||||||
|
connect(askBtns, &QDialogButtonBox::accepted, &askDlg, &QDialog::accept);
|
||||||
|
connect(askBtns, &QDialogButtonBox::rejected, &askDlg, &QDialog::reject);
|
||||||
|
askRoot->addWidget(askBtns);
|
||||||
|
if (askDlg.exec() != QDialog::Accepted) return;
|
||||||
|
const QString name = nameEdit->text().trimmed();
|
||||||
|
if (name.isEmpty()) return;
|
||||||
|
const bool overwrite = overwriteCheck->isChecked() && !lvlTemplateId_.isEmpty();
|
||||||
|
|
||||||
// 组装 properties(复刻 handleSaveOther)。
|
// 组装 properties(复刻 handleSaveOther)。
|
||||||
QJsonArray colorBar;
|
QJsonArray colorBar;
|
||||||
|
|
@ -457,18 +479,22 @@ void ColorScaleConfigDialog::onSaveOther() {
|
||||||
{QStringLiteral("colorBar"), colorBar}};
|
{QStringLiteral("colorBar"), colorBar}};
|
||||||
|
|
||||||
// 走仓储传输;回调里用 QPointer 守卫 this(模态对话框可能已关)。
|
// 走仓储传输;回调里用 QPointer 守卫 this(模态对话框可能已关)。
|
||||||
|
// 勾选覆盖 → PUT 更新来源模板(updateLvlTemplate);否则 → POST 新建(saveLvlTemplate)。
|
||||||
QPointer<ColorScaleConfigDialog> self(this);
|
QPointer<ColorScaleConfigDialog> self(this);
|
||||||
tplRepo_->saveLvlTemplate(projectId_, name.trimmed(), properties,
|
auto onDone = [self, overwrite](bool ok, QString msg) {
|
||||||
[self](bool ok, QString msg) {
|
if (!self) return;
|
||||||
if (!self) return;
|
if (ok)
|
||||||
if (ok)
|
QMessageBox::information(
|
||||||
QMessageBox::information(self, QStringLiteral("另存"),
|
self, QStringLiteral("另存"),
|
||||||
QStringLiteral("另存成功。"));
|
overwrite ? QStringLiteral("更新成功。") : QStringLiteral("另存成功。"));
|
||||||
else
|
else
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(self, QStringLiteral("另存"),
|
||||||
self, QStringLiteral("另存"),
|
QStringLiteral("另存失败:%1").arg(msg));
|
||||||
QStringLiteral("另存失败:%1").arg(msg));
|
};
|
||||||
});
|
if (overwrite)
|
||||||
|
tplRepo_->updateLvlTemplate(lvlTemplateId_, name, properties, std::move(onDone));
|
||||||
|
else
|
||||||
|
tplRepo_->saveLvlTemplate(projectId_, name, properties, std::move(onDone));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorScaleConfigDialog::onOpen() {
|
void ColorScaleConfigDialog::onOpen() {
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,15 @@ public:
|
||||||
// init:当前色阶(升序断点填表);vmin/vmax:数据原始范围(层级/颜色子对话框 + 新增外推用);
|
// init:当前色阶(升序断点填表);vmin/vmax:数据原始范围(层级/颜色子对话框 + 新增外推用);
|
||||||
// samples:数据原始标量(等积分层 + 颜色编辑器直方图用,空则等积退化为线性);
|
// samples:数据原始标量(等积分层 + 颜色编辑器直方图用,空则等积退化为线性);
|
||||||
// lineInit:线形/标注初值(2D 传当前态,3D 用默认);
|
// lineInit:线形/标注初值(2D 传当前态,3D 用默认);
|
||||||
// tplRepo/projectId:lvl 模板库仓储句柄(可空 → 另存为/打开 禁用)。
|
// tplRepo/projectId:lvl 模板库仓储句柄(可空 → 另存为/打开 禁用);
|
||||||
|
// lvlTemplateId:当前色阶来源模板 id(可空,对照原版 props.data.lvlTemplateId)。
|
||||||
|
// 非空时「另存为」弹窗的「覆盖」复选框可勾选 → 走 PUT 更新该模板;3D/无模板场景不传即可。
|
||||||
ColorScaleConfigDialog(const geopro::core::ColorScale& init, double vmin, double vmax,
|
ColorScaleConfigDialog(const geopro::core::ColorScale& init, double vmin, double vmax,
|
||||||
std::vector<double> samples = {},
|
std::vector<double> samples = {},
|
||||||
const ContourLineConfig& lineInit = {},
|
const ContourLineConfig& lineInit = {},
|
||||||
geopro::data::IColorTemplateRepository* tplRepo = nullptr,
|
geopro::data::IColorTemplateRepository* tplRepo = nullptr,
|
||||||
QString projectId = {}, QWidget* parent = nullptr);
|
QString projectId = {}, QString lvlTemplateId = {},
|
||||||
|
QWidget* parent = nullptr);
|
||||||
|
|
||||||
// 由表格当前断点装配的新色阶(按层级升序 addStop)。
|
// 由表格当前断点装配的新色阶(按层级升序 addStop)。
|
||||||
geopro::core::ColorScale colorScale() const;
|
geopro::core::ColorScale colorScale() const;
|
||||||
|
|
@ -74,6 +77,7 @@ private:
|
||||||
|
|
||||||
geopro::data::IColorTemplateRepository* tplRepo_ = nullptr; // lvl 模板库仓储(可空)
|
geopro::data::IColorTemplateRepository* tplRepo_ = nullptr; // lvl 模板库仓储(可空)
|
||||||
QString projectId_;
|
QString projectId_;
|
||||||
|
QString lvlTemplateId_; // 当前色阶来源模板 id(可空 → 另存为弹窗禁用「覆盖」)
|
||||||
// 随子对话框更新、写入另存为 properties(复刻原版透传字段)。
|
// 随子对话框更新、写入另存为 properties(复刻原版透传字段)。
|
||||||
QString lvlSchemeType_ = QStringLiteral("normal");
|
QString lvlSchemeType_ = QStringLiteral("normal");
|
||||||
int logLinesCount_ = 8;
|
int logLinesCount_ = 8;
|
||||||
|
|
|
||||||
|
|
@ -807,10 +807,11 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
}
|
}
|
||||||
// 3D 无等值线,线形/标注配置忽略(用默认);仅取色阶应用。
|
// 3D 无等值线,线形/标注配置忽略(用默认);仅取色阶应用。
|
||||||
// 「另存为/打开」与「新建色阶/配色方案」走色阶模板仓储,projectId 取当前项目。
|
// 「另存为/打开」与「新建色阶/配色方案」走色阶模板仓储,projectId 取当前项目。
|
||||||
|
// 3D 体无来源 lvl 模板 → lvlTemplateId 传空(覆盖复选框禁用,行为不变)。
|
||||||
geopro::app::ColorScaleConfigDialog dlg(
|
geopro::app::ColorScaleConfigDialog dlg(
|
||||||
sceneView->currentColorScale(), sceneView->currentVmin(),
|
sceneView->currentColorScale(), sceneView->currentVmin(),
|
||||||
sceneView->currentVmax(), std::move(samples), {}, &colorTplRepo,
|
sceneView->currentVmax(), std::move(samples), {}, &colorTplRepo,
|
||||||
nav.currentProjectId(), &window);
|
nav.currentProjectId(), QString(), &window);
|
||||||
if (dlg.exec() == QDialog::Accepted)
|
if (dlg.exec() == QDialog::Accepted)
|
||||||
sceneCtrl->setVolumeColorScale(dsId, dlg.colorScale());
|
sceneCtrl->setVolumeColorScale(dsId, dlg.colorScale());
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ std::unique_ptr<IDetailView> makeDetailView(controller::ViewKind kind, QWidget*
|
||||||
auto* raw = new RawDataChartView(parent);
|
auto* raw = new RawDataChartView(parent);
|
||||||
// 注入反演命令仓储 + dsId/projectId 取值回调(measurement 反演运算/生成视电阻率)。
|
// 注入反演命令仓储 + dsId/projectId 取值回调(measurement 反演运算/生成视电阻率)。
|
||||||
raw->setCommandRepo(cmdRepo, dsIdGetter, projectIdGetter);
|
raw->setCommandRepo(cmdRepo, dsIdGetter, projectIdGetter);
|
||||||
|
// 注入色阶模板仓储(散点「色阶配置」编辑器另存为/打开/覆盖用;projectId 复用上面的 getter)。
|
||||||
|
raw->setColorTemplateRepo(colorTplRepo);
|
||||||
return std::unique_ptr<IDetailView>(raw);
|
return std::unique_ptr<IDetailView>(raw);
|
||||||
}
|
}
|
||||||
case controller::ViewKind::FilledContour: {
|
case controller::ViewKind::FilledContour: {
|
||||||
|
|
|
||||||
|
|
@ -318,8 +318,9 @@ void GridDataChartView::openColorScaleEditor() {
|
||||||
|
|
||||||
// projectId 在打开时取一次(随项目切换生效);无 getter 退化为空 → 后端按钮禁用。
|
// projectId 在打开时取一次(随项目切换生效);无 getter 退化为空 → 后端按钮禁用。
|
||||||
const QString projectId = projectIdGetter_ ? projectIdGetter_() : QString();
|
const QString projectId = projectIdGetter_ ? projectIdGetter_() : QString();
|
||||||
|
// 网格剖面载荷(ContourPayload)无 templateId 字段 → lvlTemplateId 传空(覆盖复选框禁用)。
|
||||||
ColorScaleConfigDialog dlg(gridScale_, grid_.vmin, grid_.vmax, std::move(samples), lineCfg_,
|
ColorScaleConfigDialog dlg(gridScale_, grid_.vmin, grid_.vmax, std::move(samples), lineCfg_,
|
||||||
tplRepo_, projectId, this);
|
tplRepo_, projectId, QString(), this);
|
||||||
if (dlg.exec() != QDialog::Accepted) return;
|
if (dlg.exec() != QDialog::Accepted) return;
|
||||||
|
|
||||||
gridScale_ = dlg.colorScale();
|
gridScale_ = dlg.colorScale();
|
||||||
|
|
|
||||||
|
|
@ -352,6 +352,10 @@ void RawDataChartView::setCommandRepo(geopro::data::IDatasetCommandRepository* r
|
||||||
projectIdGetter_ = std::move(projectIdGetter);
|
projectIdGetter_ = std::move(projectIdGetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RawDataChartView::setColorTemplateRepo(geopro::data::IColorTemplateRepository* repo) {
|
||||||
|
colorTplRepo_ = repo;
|
||||||
|
}
|
||||||
|
|
||||||
void RawDataChartView::openInversionDialog(bool apparentResistivity, QWidget* anchor) {
|
void RawDataChartView::openInversionDialog(bool apparentResistivity, QWidget* anchor) {
|
||||||
// 无仓储/无 dsId 取值回调 → 退化占位(与未注入时一致)。
|
// 无仓储/无 dsId 取值回调 → 退化占位(与未注入时一致)。
|
||||||
const QString dsId = dsIdGetter_ ? dsIdGetter_() : QString();
|
const QString dsId = dsIdGetter_ ? dsIdGetter_() : QString();
|
||||||
|
|
@ -388,7 +392,10 @@ void RawDataChartView::openInversionColorScale(QWidget* anchor) {
|
||||||
}
|
}
|
||||||
if (vMin > vMax) { vMin = 0.0; vMax = 1.0; }
|
if (vMin > vMax) { vMin = 0.0; vMax = 1.0; }
|
||||||
std::vector<double> samples = data_.scatter.v;
|
std::vector<double> samples = data_.scatter.v;
|
||||||
ColorScaleConfigDialog dlg(data_.scale, vMin, vMax, std::move(samples), {}, nullptr, {}, this);
|
// 接通色阶模板库:注入仓储 + 当前 projectId + 载荷 templateId(另存为/打开/覆盖 可用)。
|
||||||
|
ColorScaleConfigDialog dlg(data_.scale, vMin, vMax, std::move(samples), {}, colorTplRepo_,
|
||||||
|
projectIdGetter_ ? projectIdGetter_() : QString(), data_.templateId,
|
||||||
|
this);
|
||||||
if (dlg.exec() != QDialog::Accepted) return;
|
if (dlg.exec() != QDialog::Accepted) return;
|
||||||
|
|
||||||
// 本地重建上色重绘。
|
// 本地重建上色重绘。
|
||||||
|
|
@ -565,8 +572,10 @@ void RawDataChartView::openScatterColorScale(QWidget* anchor) {
|
||||||
if (vMin > vMax) { vMin = 0.0; vMax = 1.0; }
|
if (vMin > vMax) { vMin = 0.0; vMax = 1.0; }
|
||||||
std::vector<double> samples = data_.scatter.v; // 直方图/等积分层用原始标量
|
std::vector<double> samples = data_.scatter.v; // 直方图/等积分层用原始标量
|
||||||
|
|
||||||
// 散点无独立 lvl 模板仓储(视图只持命令仓储)→ tplRepo 传空(另存为/打开 禁用)。
|
// 接通色阶模板库:注入仓储 + 当前 projectId + 载荷 templateId(另存为/打开/覆盖 可用)。
|
||||||
ColorScaleConfigDialog dlg(data_.scale, vMin, vMax, std::move(samples), {}, nullptr, {}, this);
|
ColorScaleConfigDialog dlg(data_.scale, vMin, vMax, std::move(samples), {}, colorTplRepo_,
|
||||||
|
projectIdGetter_ ? projectIdGetter_() : QString(), data_.templateId,
|
||||||
|
this);
|
||||||
if (dlg.exec() != QDialog::Accepted) return;
|
if (dlg.exec() != QDialog::Accepted) return;
|
||||||
|
|
||||||
// 本地重建 colorSvc_ 重绘散点(M8 即时生效)。
|
// 本地重建 colorSvc_ 重绘散点(M8 即时生效)。
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class QwtPlotRescaler;
|
||||||
|
|
||||||
namespace geopro::data {
|
namespace geopro::data {
|
||||||
class IDatasetCommandRepository;
|
class IDatasetCommandRepository;
|
||||||
|
class IColorTemplateRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
@ -47,6 +48,10 @@ public:
|
||||||
std::function<QString()> dsIdGetter,
|
std::function<QString()> dsIdGetter,
|
||||||
std::function<QString()> projectIdGetter);
|
std::function<QString()> projectIdGetter);
|
||||||
|
|
||||||
|
// 注入色阶模板仓储(散点「色阶配置」编辑器「另存为/打开/覆盖」用;projectId 复用
|
||||||
|
// setCommandRepo 注入的 projectIdGetter_)。可传空 → 编辑器后端按钮禁用。
|
||||||
|
void setColorTemplateRepo(geopro::data::IColorTemplateRepository* repo);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// 信息模式(M13)下捕获画布点击:找最近散点显示属性。其余事件不消费。
|
// 信息模式(M13)下捕获画布点击:找最近散点显示属性。其余事件不消费。
|
||||||
bool eventFilter(QObject* obj, QEvent* ev) override;
|
bool eventFilter(QObject* obj, QEvent* ev) override;
|
||||||
|
|
@ -123,6 +128,8 @@ private:
|
||||||
geopro::data::IDatasetCommandRepository* cmdRepo_ = nullptr;
|
geopro::data::IDatasetCommandRepository* cmdRepo_ = nullptr;
|
||||||
std::function<QString()> dsIdGetter_;
|
std::function<QString()> dsIdGetter_;
|
||||||
std::function<QString()> projectIdGetter_;
|
std::function<QString()> projectIdGetter_;
|
||||||
|
// 色阶模板仓储(注入;空则编辑器「另存为/打开」禁用)。
|
||||||
|
geopro::data::IColorTemplateRepository* colorTplRepo_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,24 @@ void ApiColorTemplateRepository::saveLvlTemplate(const QString& projectId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiColorTemplateRepository::updateLvlTemplate(const QString& id,
|
||||||
|
const QString& templateName,
|
||||||
|
const QJsonObject& properties,
|
||||||
|
std::function<void(bool, QString)> cb) {
|
||||||
|
QJsonObject body{{QStringLiteral("id"), id},
|
||||||
|
{QStringLiteral("templateName"), templateName},
|
||||||
|
{QStringLiteral("properties"), properties}};
|
||||||
|
auto* call = api_.putJsonAsync(QStringLiteral("/business/lvlTemplate"), body);
|
||||||
|
if (call == nullptr) {
|
||||||
|
if (cb) cb(false, QStringLiteral("请求创建失败"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QObject::connect(call, &net::IApiCall::finished, call,
|
||||||
|
[cb = std::move(cb)](const net::ApiResponse& resp) {
|
||||||
|
if (cb) cb(isOk(resp), resp.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ApiColorTemplateRepository::listLvlTemplates(
|
void ApiColorTemplateRepository::listLvlTemplates(
|
||||||
const QString& projectId, std::function<void(bool, QJsonArray, QString)> cb) {
|
const QString& projectId, std::function<void(bool, QJsonArray, QString)> cb) {
|
||||||
QJsonObject body{{QStringLiteral("projectId"), projectId},
|
QJsonObject body{{QStringLiteral("projectId"), projectId},
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ public:
|
||||||
void saveLvlTemplate(const QString& projectId, const QString& templateName,
|
void saveLvlTemplate(const QString& projectId, const QString& templateName,
|
||||||
const QJsonObject& properties,
|
const QJsonObject& properties,
|
||||||
std::function<void(bool ok, QString msg)> cb) override;
|
std::function<void(bool ok, QString msg)> cb) override;
|
||||||
|
void updateLvlTemplate(const QString& id, const QString& templateName,
|
||||||
|
const QJsonObject& properties,
|
||||||
|
std::function<void(bool ok, QString msg)> cb) override;
|
||||||
void listLvlTemplates(const QString& projectId,
|
void listLvlTemplates(const QString& projectId,
|
||||||
std::function<void(bool ok, QJsonArray list, QString msg)> cb) override;
|
std::function<void(bool ok, QJsonArray list, QString msg)> cb) override;
|
||||||
void newClrScheme(const QString& projectId, const QJsonObject& properties,
|
void newClrScheme(const QString& projectId, const QJsonObject& properties,
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,12 @@ public:
|
||||||
const QJsonObject& properties,
|
const QJsonObject& properties,
|
||||||
std::function<void(bool ok, QString msg)> cb) = 0;
|
std::function<void(bool ok, QString msg)> cb) = 0;
|
||||||
|
|
||||||
|
// 覆盖更新 lvl 模板:PUT /business/lvlTemplate(body {id, templateName, properties})。
|
||||||
|
// 复刻原版 updateLvlTemplate(另存为弹窗勾选「覆盖」时调用,id=当前模板 lvlTemplateId)。
|
||||||
|
virtual void updateLvlTemplate(const QString& id, const QString& templateName,
|
||||||
|
const QJsonObject& properties,
|
||||||
|
std::function<void(bool ok, QString msg)> cb) = 0;
|
||||||
|
|
||||||
// 列 lvl 模板:POST /business/lvlTemplate/page(pageNo=1,pageSize=1000)。
|
// 列 lvl 模板:POST /business/lvlTemplate/page(pageNo=1,pageSize=1000)。
|
||||||
// 回调 list = 响应 data.list 数组(每项含 templateName/properties)。
|
// 回调 list = 响应 data.list 数组(每项含 templateName/properties)。
|
||||||
virtual void listLvlTemplates(const QString& projectId,
|
virtual void listLvlTemplates(const QString& projectId,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue