feat/vtk-merged-dataset-column #10
|
|
@ -1300,6 +1300,25 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
|||
if (!applyFittedAxes(dsId)) sceneView->showSceneAxes();
|
||||
renderWindowPtr->Render();
|
||||
});
|
||||
// 双击 DS(决策6/T4):(a) 相机适配到该 ds 子树空间范围(复用 T2 subtreeDsIds + T1
|
||||
// datasetBounds/fitToBounds,与选中贴合轴同一子树盒);(b) 有详情页的类型联动打开中下方详情面板,
|
||||
// 三维体等无详情页类型静默——gate 在联动入口(detailCtrl.supports),不走 openDataset→loadFailed
|
||||
// 的状态栏提示。属性弹窗改由右键「详情」(detailRequested) 触发,双击不再弹属性框。
|
||||
QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::datasetActivated, &window,
|
||||
[sceneView, renderWindowPtr, analysisTab, &detailCtrl](
|
||||
const QString& dsId, const QString& ddCode, const QString& name) {
|
||||
const QStringList sub = analysisTab->subtreeDsIds(dsId);
|
||||
std::vector<std::string> ids;
|
||||
ids.reserve(static_cast<size_t>(sub.size()));
|
||||
for (const QString& s : sub) ids.push_back(s.toStdString());
|
||||
double box[6];
|
||||
if (!ids.empty() && sceneView->datasetBounds(ids, box)) { // 未渲染/无盒 → 跳过适配(静默)
|
||||
sceneView->fitToBounds(box);
|
||||
renderWindowPtr->Render();
|
||||
}
|
||||
if (detailCtrl.supports(ddCode)) // 无详情页策略(三维体等)→ 只适配、不开面板(静默)
|
||||
detailCtrl.openDataset(dsId, ddCode, name, QString());
|
||||
});
|
||||
// 2D 段「z 值」滑块 → 整体升降该 2D 类型平面(Plane2DRenderStrategy 重摆其全部足迹)。
|
||||
QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::planeZChanged, sceneCtrl,
|
||||
&geopro::controller::VtkSceneController::setPlaneZ);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
|||
// 注:「导入雷达测线」入口已迁至 TopBar「设备」菜单(Task D1);CategorySection 段头按钮与
|
||||
// CategoryAnalysisTab::radarImportRequested 信号均已移除。
|
||||
connect(sec, &CategorySection::detailRequested, this, &CategoryAnalysisTab::detailRequested);
|
||||
connect(sec, &CategorySection::datasetActivated, this, &CategoryAnalysisTab::datasetActivated);
|
||||
connect(sec, &CategorySection::deleteDatasetRequested, this,
|
||||
&CategoryAnalysisTab::deleteDatasetRequested);
|
||||
connect(sec, &CategorySection::sliceRequested, this, &CategoryAnalysisTab::sliceRequested);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ public:
|
|||
signals:
|
||||
void checkedDatasetsChanged(const QStringList& dsIds); // 5 段勾选并集
|
||||
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds);
|
||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name);
|
||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 右键「详情」=属性弹窗
|
||||
void datasetActivated(const QString& dsId, const QString& ddCode, const QString& name); // 双击=适配+图表联动(T4)
|
||||
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除切片/异常
|
||||
// ── 三维体段操作转发(迁自旧 Column3DAnalysis,全接)──
|
||||
void sliceRequested(geopro::render::interact::SliceAxis axis, const QString& volumeDsId);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,9 @@ CategorySection::CategorySection(const geopro::data::CategoryDescriptor& desc,
|
|||
connect(list_, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem* it, int) {
|
||||
const QString id = it->data(0, kDsIdRole).toString();
|
||||
if (id.isEmpty()) return;
|
||||
emit detailRequested(id, it->data(0, kDsDdCodeRole).toString(), it->data(0, kDsNameRole).toString());
|
||||
// 双击=适配相机到该 ds 子树盒 + 联动中下方图表详情页(无图表页类型静默,见 main.cpp T4 接线)。
|
||||
// 属性弹窗改由右键「详情」触发(detailRequested),双击不再弹属性框(决策6:三维体只适配、静默)。
|
||||
emit datasetActivated(id, it->data(0, kDsDdCodeRole).toString(), it->data(0, kDsNameRole).toString());
|
||||
});
|
||||
if (desc_.id == "voxel") { // 仅三维体段提供右键操作菜单(体/切片/异常)
|
||||
list_->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,10 @@ signals:
|
|||
void planeZChanged(const QString& typeId, double z); // PlaneZ 滑块:整体升降该 2D 类型平面(z=绝对高程,米)
|
||||
void basemapKindChanged(const QString& typeId, int kind); // 底图弹窗:矢量平面(0)/无(1)
|
||||
void basemapOpacityChanged(const QString& typeId, double o); // 底图弹窗透明度滑块[0,1](防抖发射)
|
||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情
|
||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 右键「详情」=属性弹窗
|
||||
// 双击某行(决策6/T4):适配相机到该 ds 子树空间范围 + 联动中下方详情面板(无详情页类型静默)。
|
||||
// 与 detailRequested(右键属性弹窗)分开,使双击「只适配 + 图表联动」,三维体等无图表页时静默。
|
||||
void datasetActivated(const QString& dsId, const QString& ddCode, const QString& name);
|
||||
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
||||
// ── 三维体段右键操作(迁自旧 Column3DAnalysis,全接)──
|
||||
void sliceRequested(geopro::render::interact::SliceAxis axis, const QString& volumeDsId); // 体→生成切片(轴+目标体)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ public slots:
|
|||
void loadTabPaged(const QString& dsId, const QString& ddCode, int tabIndex, int pageNo,
|
||||
int pageSize);
|
||||
void focusDataset(const QString& dsId);
|
||||
public:
|
||||
// 该 ddCode 是否有已注册的详情页策略(=有中下方图表详情页)。供联动入口 gate:
|
||||
// 无策略的类型(如 dd_voxel/dd_radar_3d 三维体)不走 openDataset,避免 loadFailed 的状态栏提示,静默。
|
||||
bool supports(const QString& ddCode) const { return registry_.supports(ddCode.toStdString()); }
|
||||
signals:
|
||||
void datasetOpened(const QString& dsId, const QString& ddCode, const QString& dsName,
|
||||
const QString& tmObjectId, const std::vector<controller::TabSpec>& tabs);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include "DatasetDetailTab.hpp"
|
||||
#include "IDatasetChartStrategy.hpp" // geopro::controller(控制器层)
|
||||
#include "panels/chart/ErtInversionStrategy.hpp"
|
||||
#include "panels/chart/MeasurementStrategy.hpp"
|
||||
#include "panels/chart/GrMeasurementStrategy.hpp"
|
||||
#include "panels/chart/TrajectoryStrategy.hpp"
|
||||
|
|
@ -39,6 +40,29 @@ TEST(ChartStrategyRegistry, ExposesTabSpecsFromStrategy) {
|
|||
EXPECT_EQ(tabs[1].kind, ViewKind::FilledContour);
|
||||
}
|
||||
|
||||
// T4 双击详情联动 gate 契约(决策6):DatasetDetailController::supports() 直接委托本注册表的 supports()。
|
||||
// 三维体(dd_voxel/dd_radar_3d)等无详情页策略 → supports()=false → 双击只适配、静默不开面板;
|
||||
// 5 种已注册类型 supports()=true → 双击联动打开中下方详情页。此测锁定这条 gate 的真实注册集行为。
|
||||
TEST(ChartStrategyRegistry, T4GateSilentForVolumeTypesSupportsRegistered) {
|
||||
ChartStrategyRegistry reg;
|
||||
reg.add(std::make_unique<geopro::app::ErtInversionStrategy>());
|
||||
reg.add(std::make_unique<geopro::app::MeasurementStrategy>());
|
||||
reg.add(std::make_unique<geopro::app::GrMeasurementStrategy>());
|
||||
reg.add(std::make_unique<geopro::app::TrajectoryStrategy>());
|
||||
reg.add(std::make_unique<geopro::app::GridStrategy>());
|
||||
// 有详情页 → 双击联动打开中下方详情面板。
|
||||
EXPECT_TRUE(reg.supports("dd_inversion_data"));
|
||||
EXPECT_TRUE(reg.supports("dd_ert_measurement_data"));
|
||||
EXPECT_TRUE(reg.supports("dd_ert_measurement_gr_data"));
|
||||
EXPECT_TRUE(reg.supports("dd_trajectory_data"));
|
||||
EXPECT_TRUE(reg.supports("dd_grid"));
|
||||
// 无详情页(三维体/切片/异常)→ 静默:双击只适配、不开面板、不弹状态栏。
|
||||
EXPECT_FALSE(reg.supports("dd_voxel"));
|
||||
EXPECT_FALSE(reg.supports("dd_radar_3d"));
|
||||
EXPECT_FALSE(reg.supports("dd_slice"));
|
||||
EXPECT_FALSE(reg.supports("dd_anomaly"));
|
||||
}
|
||||
|
||||
TEST(MeasurementStrategy, DrivesTwoTabsScatterAndTable) {
|
||||
geopro::app::MeasurementStrategy s;
|
||||
EXPECT_EQ(s.ddCode(), "dd_ert_measurement_data");
|
||||
|
|
|
|||
Loading…
Reference in New Issue