geopro/src/app/panels/columns/Column2DDataset.cpp

130 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "panels/columns/Column2DDataset.hpp"
#include <set>
#include <string>
#include <QComboBox>
#include "EmptyAwareComboBox.hpp"
#include <QDoubleSpinBox>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSignalBlocker>
#include <QTreeWidget>
#include <QTreeWidgetItemIterator>
#include <QVBoxLayout>
#include "Theme.hpp"
#include "panels/DatasetListPanel.hpp"
namespace geopro::app {
Column2DDataset::Column2DDataset(QWidget* parent) : QWidget(parent) {
auto* root = new QVBoxLayout(this);
root->setContentsMargins(space::kMd, space::kMd, space::kMd, space::kMd);
root->setSpacing(space::kMd);
// 地图
{
auto* form = new QFormLayout();
auto* basemap = new EmptyAwareComboBox();
basemap->addItem(QStringLiteral("天地图"));
basemap->addItem(QStringLiteral("Google Map"));
basemap->addItem(QStringLiteral("隐藏"));
basemap->setCurrentIndex(0); // 默认天地图:数据重锚后由 onFrameReanchored 在数据位置加载
connect(basemap, qOverload<int>(&QComboBox::currentIndexChanged), this,
[this](int index) { emit basemapChanged(index); });
form->addRow(QStringLiteral("底图源"), basemap);
root->addWidget(new QLabel(QStringLiteral("地图")));
root->addLayout(form);
}
// 2D视图
{
auto* form = new QFormLayout();
auto* view2d = new EmptyAwareComboBox();
view2d->addItem(QStringLiteral("关闭"));
view2d->addItem(QStringLiteral("Z=0"));
view2d->addItem(QStringLiteral("顶部"));
view2d->addItem(QStringLiteral("底部"));
view2d->addItem(QStringLiteral("自定义"));
view2d->setCurrentIndex(1);
auto* zSpin = new QDoubleSpinBox();
zSpin->setRange(-1000000, 1000000);
zSpin->setSuffix(QStringLiteral(" m"));
zSpin->setValue(0);
connect(view2d, qOverload<int>(&QComboBox::currentIndexChanged), this,
[this, form, zSpin](int idx) {
form->setRowVisible(zSpin, idx == 4); // 整行隐藏(含"Z 值"标签),非自定义时不留孤标签
emit view2DModeChanged(idx);
});
connect(zSpin, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
[this](double z) { emit customZChanged(z); });
form->addRow(QStringLiteral("位置"), view2d);
form->addRow(QStringLiteral("Z 值"), zSpin);
form->setRowVisible(zSpin, false); // 默认非自定义→隐藏整行
root->addWidget(new QLabel(QStringLiteral("2D视图")));
root->addLayout(form);
}
// 数据集列表(可勾选)
list_ = new QTreeWidget();
list_->setHeaderHidden(true);
list_->setRootIsDecorated(true);
list_->setSelectionMode(QAbstractItemView::ExtendedSelection); // 多选行(与 VTK 多选拖动联动)
applyDatasetCardDelegate(list_);
connect(list_, &QTreeWidget::itemChanged, this, [this](QTreeWidgetItem*, int) {
QStringList ids;
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
if ((*it)->checkState(0) == Qt::Checked)
ids << (*it)->data(0, kDsIdRole).toString();
}
emit checkedDatasetsChanged(ids);
});
// 行选中变化 → 上抛选中 dsId(高亮联动 VTK与勾选/渲染独立)。
connect(list_, &QTreeWidget::itemSelectionChanged, this, [this]() {
QStringList ids;
for (QTreeWidgetItem* it : list_->selectedItems())
ids << it->data(0, kDsIdRole).toString();
emit selectedDatasetsChanged(ids);
});
root->addWidget(list_, 1);
}
void Column2DDataset::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
// 增量保留:记住当前已勾选的足迹 ds重建后复原仍存在的项保持勾选。否则对象树每次增删勾选都触发
// 本刷新 → 清空全部勾选 + 上抛空集 → 已渲染足迹被移除、列表选中丢失(用户反馈:必须增量更新,
// 与三维分析段 CategorySection::rebuildList 同一处理)。
std::set<std::string> wasChecked;
for (QTreeWidgetItemIterator it(list_); *it; ++it)
if ((*it)->checkState(0) == Qt::Checked)
wasChecked.insert((*it)->data(0, kDsIdRole).toString().toStdString());
{
QSignalBlocker blocker(list_);
populateDatasetList(list_, rows, /*append=*/false);
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
const std::string id = (*it)->data(0, kDsIdRole).toString().toStdString();
// 复原勾选:仍存在的曾勾选项保持勾选;新项默认不勾。
(*it)->setCheckState(0, wasChecked.count(id) ? Qt::Checked : Qt::Unchecked);
}
} // blocker released here
// 上抛复原后的勾选集(保持渲染,不再清空 → 控制器据 diff 增量保留已渲染足迹,集合不变则不增删)。
QStringList ids;
for (QTreeWidgetItemIterator it(list_); *it; ++it)
if ((*it)->checkState(0) == Qt::Checked)
ids << (*it)->data(0, kDsIdRole).toString();
emit checkedDatasetsChanged(ids);
}
void Column2DDataset::setSelectedDsIds(const QStringList& dsIds) {
QSignalBlocker blocker(list_); // 防回环VTK→列表 设置选中不再上抛 selectedDatasetsChanged
list_->clearSelection();
for (QTreeWidgetItemIterator it(list_); *it; ++it)
if (dsIds.contains((*it)->data(0, kDsIdRole).toString())) (*it)->setSelected(true);
}
} // namespace geopro::app