154 lines
5.2 KiB
C++
154 lines
5.2 KiB
C++
#include "WorkbenchNavController.hpp"
|
||
|
||
namespace geopro::controller {
|
||
|
||
using data::ProjectSummary;
|
||
using data::Workspace;
|
||
|
||
WorkbenchNavController::WorkbenchNavController(data::IProjectRepository& repo, QObject* parent)
|
||
: QObject(parent), repo_(repo) {}
|
||
|
||
namespace {
|
||
// RAII:进入公共导航操作时置忙(驱动等待光标),任何返回路径都复位——保证 busyChanged 配平。
|
||
struct BusyGuard {
|
||
WorkbenchNavController* self;
|
||
bool* busy;
|
||
BusyGuard(WorkbenchNavController* s, bool* b) : self(s), busy(b) {
|
||
*busy = true;
|
||
emit self->busyChanged(true);
|
||
}
|
||
~BusyGuard() {
|
||
*busy = false;
|
||
emit self->busyChanged(false);
|
||
}
|
||
};
|
||
} // namespace
|
||
|
||
void WorkbenchNavController::start() {
|
||
if (busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
const auto ws = repo_.listWorkspaces();
|
||
if (!ws.ok) {
|
||
emit loadFailed(QStringLiteral("workspaces"), QString::fromStdString(ws.error));
|
||
return;
|
||
}
|
||
QString cur;
|
||
for (const auto& w : ws.value)
|
||
if (w.isCurrent) cur = QString::fromStdString(w.id);
|
||
if (cur.isEmpty() && !ws.value.empty()) cur = QString::fromStdString(ws.value.front().id);
|
||
currentWorkspaceId_ = cur.toStdString();
|
||
emit workspacesLoaded(ws.value, cur);
|
||
loadProjectsAndStructure();
|
||
}
|
||
|
||
void WorkbenchNavController::loadProjectsAndStructure() {
|
||
const auto ps = repo_.listProjects(std::string());
|
||
if (!ps.ok) {
|
||
emit loadFailed(QStringLiteral("projects"), QString::fromStdString(ps.error));
|
||
return;
|
||
}
|
||
lastProjects_ = ps.value;
|
||
QString curP;
|
||
if (!ps.value.empty()) {
|
||
const auto& first = ps.value.front();
|
||
curP = QString::fromStdString(first.id);
|
||
currentProjectId_ = first.id;
|
||
currentProjectName_ = first.name;
|
||
currentCrsCode_ = first.crsCode;
|
||
} else {
|
||
currentProjectId_.clear();
|
||
currentProjectName_.clear();
|
||
currentCrsCode_.clear();
|
||
}
|
||
emit projectsLoaded(ps.value, curP);
|
||
|
||
if (curP.isEmpty()) {
|
||
emit structureLoaded(QString(), {}); // 暂无项目 → 空树
|
||
return;
|
||
}
|
||
const auto st = repo_.loadStructure(currentProjectId_);
|
||
if (!st.ok) {
|
||
emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error));
|
||
return;
|
||
}
|
||
emit structureLoaded(QString::fromStdString(currentProjectName_), st.value);
|
||
}
|
||
|
||
void WorkbenchNavController::switchWorkspace(const QString& tenantId) {
|
||
if (tenantId.isEmpty() || busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
const auto r = repo_.switchWorkspace(tenantId.toStdString());
|
||
if (!r.ok) {
|
||
emit loadFailed(QStringLiteral("switchWorkspace"), QString::fromStdString(r.error));
|
||
return;
|
||
}
|
||
currentWorkspaceId_ = tenantId.toStdString();
|
||
loadProjectsAndStructure();
|
||
}
|
||
|
||
void WorkbenchNavController::switchProject(const QString& projectId) {
|
||
if (projectId.isEmpty() || busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
currentProjectId_ = projectId.toStdString();
|
||
for (const auto& p : lastProjects_)
|
||
if (p.id == currentProjectId_) {
|
||
currentProjectName_ = p.name;
|
||
currentCrsCode_ = p.crsCode;
|
||
}
|
||
const auto st = repo_.loadStructure(currentProjectId_);
|
||
if (!st.ok) {
|
||
emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error));
|
||
return;
|
||
}
|
||
emit structureLoaded(QString::fromStdString(currentProjectName_), st.value);
|
||
}
|
||
|
||
void WorkbenchNavController::selectTm(const QString& tmObjectId) {
|
||
if (tmObjectId.isEmpty() || busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
currentTmId_ = tmObjectId.toStdString();
|
||
const std::string pid = currentProjectId_;
|
||
dataPageNo_ = 1;
|
||
filePageNo_ = 1;
|
||
const auto d = repo_.loadTmRows(pid, currentTmId_, 3, dataPageNo_);
|
||
if (!d.ok) {
|
||
emit loadFailed(QStringLiteral("datasets"), QString::fromStdString(d.error));
|
||
return;
|
||
}
|
||
dataTotal_ = d.value.total;
|
||
emit datasetsLoaded(tmObjectId, d.value.rows, d.value.total, false);
|
||
const auto f = repo_.loadTmRows(pid, currentTmId_, 1, filePageNo_);
|
||
if (!f.ok) {
|
||
emit loadFailed(QStringLiteral("files"), QString::fromStdString(f.error));
|
||
return;
|
||
}
|
||
fileTotal_ = f.value.total;
|
||
emit filesLoaded(tmObjectId, f.value.rows, f.value.total, false);
|
||
}
|
||
|
||
void WorkbenchNavController::loadMoreData() {
|
||
if (currentTmId_.empty() || busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
const auto d = repo_.loadTmRows(currentProjectId_, currentTmId_, 3, ++dataPageNo_);
|
||
if (!d.ok) {
|
||
emit loadFailed(QStringLiteral("datasets"), QString::fromStdString(d.error));
|
||
return;
|
||
}
|
||
dataTotal_ = d.value.total;
|
||
emit datasetsLoaded(QString::fromStdString(currentTmId_), d.value.rows, d.value.total, true);
|
||
}
|
||
|
||
void WorkbenchNavController::loadMoreFiles() {
|
||
if (currentTmId_.empty() || busy_) return;
|
||
BusyGuard guard(this, &busy_);
|
||
const auto f = repo_.loadTmRows(currentProjectId_, currentTmId_, 1, ++filePageNo_);
|
||
if (!f.ok) {
|
||
emit loadFailed(QStringLiteral("files"), QString::fromStdString(f.error));
|
||
return;
|
||
}
|
||
fileTotal_ = f.value.total;
|
||
emit filesLoaded(QString::fromStdString(currentTmId_), f.value.rows, f.value.total, true);
|
||
}
|
||
|
||
} // namespace geopro::controller
|