feat/vtk-3d-view #7
|
|
@ -83,6 +83,7 @@ add_executable(geopro_desktop WIN32
|
||||||
panels/columns/Column3DAnalysis.cpp
|
panels/columns/Column3DAnalysis.cpp
|
||||||
panels/columns/CategorySection.cpp
|
panels/columns/CategorySection.cpp
|
||||||
panels/columns/CategoryAnalysisTab.cpp
|
panels/columns/CategoryAnalysisTab.cpp
|
||||||
|
panels/columns/DateRangeEdit.cpp
|
||||||
panels/columns/ColumnDrawer.cpp
|
panels/columns/ColumnDrawer.cpp
|
||||||
panels/AnomalyTablePanel.cpp
|
panels/AnomalyTablePanel.cpp
|
||||||
panels/LoadingOverlay.cpp
|
panels/LoadingOverlay.cpp
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QDateEdit>
|
#include "panels/columns/DateRangeEdit.hpp"
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
@ -68,21 +68,10 @@ CategorySection::CategorySection(const CategorySpec& spec, geopro::data::Dataset
|
||||||
[this](int) { rebuildList(); });
|
[this](int) { rebuildList(); });
|
||||||
filterRow->addWidget(arrayCombo_);
|
filterRow->addWidget(arrayCombo_);
|
||||||
}
|
}
|
||||||
auto makeDate = [this]() {
|
|
||||||
auto* d = new QDateEdit(body_);
|
|
||||||
d->setCalendarPopup(true);
|
|
||||||
d->setDisplayFormat(QStringLiteral("yyyy-MM-dd"));
|
|
||||||
d->setSpecialValueText(QStringLiteral("不限")); // 最小日期→显示"不限"
|
|
||||||
d->setDate(d->minimumDate());
|
|
||||||
connect(d, &QDateEdit::dateChanged, this, [this](const QDate&) { rebuildList(); });
|
|
||||||
return d;
|
|
||||||
};
|
|
||||||
fromDate_ = makeDate();
|
|
||||||
toDate_ = makeDate();
|
|
||||||
filterRow->addWidget(new QLabel(QStringLiteral("采集"), body_));
|
filterRow->addWidget(new QLabel(QStringLiteral("采集"), body_));
|
||||||
filterRow->addWidget(fromDate_, 1);
|
dateRange_ = new DateRangeEdit(body_);
|
||||||
filterRow->addWidget(new QLabel(QStringLiteral("至"), body_));
|
connect(dateRange_, &DateRangeEdit::rangeChanged, this, [this] { rebuildList(); });
|
||||||
filterRow->addWidget(toDate_, 1);
|
filterRow->addWidget(dateRange_, 1);
|
||||||
body->addLayout(filterRow);
|
body->addLayout(filterRow);
|
||||||
|
|
||||||
// 段体:可勾选数据树(勾选=渲染)。复用数据列表卡片委托与 populateDatasetList。
|
// 段体:可勾选数据树(勾选=渲染)。复用数据列表卡片委托与 populateDatasetList。
|
||||||
|
|
@ -152,17 +141,17 @@ bool CategorySection::passesFilters(const DsRow& row) const {
|
||||||
if (!hit) return false;
|
if (!hit) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 采集时间段(collectTime 经 dict 取;缺则回退 createTime;最小日期="不限"不约束)。
|
// 采集时间范围(collectTime 经 dict 取;缺则回退 createTime;空范围不约束)。
|
||||||
const bool hasFrom = fromDate_ && fromDate_->date() > fromDate_->minimumDate();
|
const QDate from = dateRange_ ? dateRange_->from() : QDate();
|
||||||
const bool hasTo = toDate_ && toDate_->date() > toDate_->minimumDate();
|
const QDate to = dateRange_ ? dateRange_->to() : QDate();
|
||||||
if (hasFrom || hasTo) {
|
if (from.isValid() || to.isValid()) {
|
||||||
const DsTypeFields* f = dict_ ? dict_->fields(spec_.dsTypeCode) : nullptr;
|
const DsTypeFields* f = dict_ ? dict_->fields(spec_.dsTypeCode) : nullptr;
|
||||||
std::string ts = f ? collectTimeOf(row, *f) : std::string();
|
std::string ts = f ? collectTimeOf(row, *f) : std::string();
|
||||||
if (ts.empty()) ts = row.createTime;
|
if (ts.empty()) ts = row.createTime;
|
||||||
const QDate d = QDate::fromString(QString::fromStdString(ts).left(10), QStringLiteral("yyyy-MM-dd"));
|
const QDate d = QDate::fromString(QString::fromStdString(ts).left(10), QStringLiteral("yyyy-MM-dd"));
|
||||||
if (d.isValid()) {
|
if (d.isValid()) {
|
||||||
if (hasFrom && d < fromDate_->date()) return false;
|
if (from.isValid() && d < from) return false;
|
||||||
if (hasTo && d > toDate_->date()) return false;
|
if (to.isValid() && d > to) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ class DatasetFieldDictionary;
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
||||||
|
class DateRangeEdit;
|
||||||
|
|
||||||
// 单个数据类型大类段(spec §7):段头(标题/折叠 + 装置类型/日期筛选 + 「+新增三维体」)+ 段体(可勾选数据树)。
|
// 单个数据类型大类段(spec §7):段头(标题/折叠 + 装置类型/日期筛选 + 「+新增三维体」)+ 段体(可勾选数据树)。
|
||||||
// 勾选数据行 = 渲染(帘面/体素/切片);段头生成按钮据当前勾选源发 generateVolumeRequested。
|
// 勾选数据行 = 渲染(帘面/体素/切片);段头生成按钮据当前勾选源发 generateVolumeRequested。
|
||||||
class CategorySection : public QWidget {
|
class CategorySection : public QWidget {
|
||||||
|
|
@ -51,8 +53,7 @@ private:
|
||||||
QToolButton* header_ = nullptr; // 折叠头(标题 + 箭头)
|
QToolButton* header_ = nullptr; // 折叠头(标题 + 箭头)
|
||||||
QWidget* body_ = nullptr; // 段体容器(折叠时隐藏)
|
QWidget* body_ = nullptr; // 段体容器(折叠时隐藏)
|
||||||
QComboBox* arrayCombo_ = nullptr; // 装置类型筛选(仅 hasArrayTypeFilter)
|
QComboBox* arrayCombo_ = nullptr; // 装置类型筛选(仅 hasArrayTypeFilter)
|
||||||
QDateEdit* fromDate_ = nullptr; // 采集时间段·起
|
DateRangeEdit* dateRange_ = nullptr; // 采集时间范围筛选(起止双日历,可清空)
|
||||||
QDateEdit* toDate_ = nullptr; // 采集时间段·止
|
|
||||||
QTreeWidget* list_ = nullptr;
|
QTreeWidget* list_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include "panels/columns/DateRangeEdit.hpp"
|
||||||
|
|
||||||
|
#include <QCalendarWidget>
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Theme.hpp"
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
DateRangeEdit::DateRangeEdit(QWidget* parent) : QWidget(parent) {
|
||||||
|
auto* lay = new QHBoxLayout(this);
|
||||||
|
lay->setContentsMargins(0, 0, 0, 0);
|
||||||
|
lay->setSpacing(0);
|
||||||
|
btn_ = new QToolButton(this);
|
||||||
|
btn_->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||||
|
btn_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
btn_->setPopupMode(QToolButton::InstantPopup);
|
||||||
|
btn_->setToolTip(QStringLiteral("按采集时间筛选(起 ~ 止),可清空"));
|
||||||
|
connect(btn_, &QToolButton::clicked, this, &DateRangeEdit::openPopup);
|
||||||
|
lay->addWidget(btn_);
|
||||||
|
updateText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateRangeEdit::openPopup() {
|
||||||
|
if (!popup_) {
|
||||||
|
popup_ = new QFrame(this, Qt::Popup);
|
||||||
|
popup_->setFrameShape(QFrame::StyledPanel);
|
||||||
|
applyTokenizedStyleSheet(
|
||||||
|
popup_, QStringLiteral("QFrame{background:{{bg/panel}};border:1px solid {{border/default}};"
|
||||||
|
"border-radius:8px;}"));
|
||||||
|
auto* v = new QVBoxLayout(popup_);
|
||||||
|
v->setContentsMargins(space::kSm, space::kSm, space::kSm, space::kSm);
|
||||||
|
|
||||||
|
auto* cals = new QHBoxLayout();
|
||||||
|
auto* fromCol = new QVBoxLayout();
|
||||||
|
fromCol->addWidget(new QLabel(QStringLiteral("起始"), popup_));
|
||||||
|
fromCal_ = new QCalendarWidget(popup_);
|
||||||
|
fromCol->addWidget(fromCal_);
|
||||||
|
cals->addLayout(fromCol);
|
||||||
|
auto* toCol = new QVBoxLayout();
|
||||||
|
toCol->addWidget(new QLabel(QStringLiteral("结束"), popup_));
|
||||||
|
toCal_ = new QCalendarWidget(popup_);
|
||||||
|
toCol->addWidget(toCal_);
|
||||||
|
cals->addLayout(toCol);
|
||||||
|
v->addLayout(cals);
|
||||||
|
|
||||||
|
auto* btns = new QHBoxLayout();
|
||||||
|
auto* clr = new QPushButton(QStringLiteral("清空"), popup_);
|
||||||
|
auto* ok = new QPushButton(QStringLiteral("确定"), popup_);
|
||||||
|
connect(clr, &QPushButton::clicked, this, &DateRangeEdit::clearAndClose);
|
||||||
|
connect(ok, &QPushButton::clicked, this, &DateRangeEdit::applyAndClose);
|
||||||
|
btns->addWidget(clr);
|
||||||
|
btns->addStretch(1);
|
||||||
|
btns->addWidget(ok);
|
||||||
|
v->addLayout(btns);
|
||||||
|
}
|
||||||
|
// 已有范围则定位到当前值,否则日历默认今天(不再 1752)。
|
||||||
|
if (from_.isValid()) fromCal_->setSelectedDate(from_);
|
||||||
|
if (to_.isValid()) toCal_->setSelectedDate(to_);
|
||||||
|
popup_->adjustSize();
|
||||||
|
popup_->move(mapToGlobal(QPoint(0, height())));
|
||||||
|
popup_->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateRangeEdit::applyAndClose() {
|
||||||
|
from_ = fromCal_->selectedDate();
|
||||||
|
to_ = toCal_->selectedDate();
|
||||||
|
if (from_.isValid() && to_.isValid() && from_ > to_) std::swap(from_, to_); // 起>止则交换
|
||||||
|
if (popup_) popup_->hide();
|
||||||
|
updateText();
|
||||||
|
emit rangeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateRangeEdit::clearAndClose() {
|
||||||
|
from_ = QDate();
|
||||||
|
to_ = QDate();
|
||||||
|
if (popup_) popup_->hide();
|
||||||
|
updateText();
|
||||||
|
emit rangeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateRangeEdit::updateText() {
|
||||||
|
if (!from_.isValid() && !to_.isValid()) {
|
||||||
|
btn_->setText(QStringLiteral("全部时间 ▾"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QString f = from_.isValid() ? from_.toString(QStringLiteral("yyyy-MM-dd")) : QStringLiteral("不限");
|
||||||
|
const QString t = to_.isValid() ? to_.toString(QStringLiteral("yyyy-MM-dd")) : QStringLiteral("不限");
|
||||||
|
btn_->setText(QStringLiteral("%1 ~ %2 ▾").arg(f, t));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
#include <QDate>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QToolButton;
|
||||||
|
class QCalendarWidget;
|
||||||
|
class QFrame;
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
// 日期范围选择器(spec 采集时间筛选):一个按钮显示「起 ~ 止」,点开弹双日历面板选起止;
|
||||||
|
// 可清空(回到"全部时间");默认不限,日历定位今天(不再停在 1752)。
|
||||||
|
class DateRangeEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DateRangeEdit(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
QDate from() const { return from_; } // 无效 QDate = 不限下限
|
||||||
|
QDate to() const { return to_; } // 无效 QDate = 不限上限
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void rangeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void openPopup();
|
||||||
|
void applyAndClose();
|
||||||
|
void clearAndClose();
|
||||||
|
void updateText();
|
||||||
|
|
||||||
|
QToolButton* btn_ = nullptr;
|
||||||
|
QFrame* popup_ = nullptr;
|
||||||
|
QCalendarWidget* fromCal_ = nullptr;
|
||||||
|
QCalendarWidget* toCal_ = nullptr;
|
||||||
|
QDate from_;
|
||||||
|
QDate to_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
Loading…
Reference in New Issue