177 lines
5.4 KiB
C++
177 lines
5.4 KiB
C++
#include "storychainspresent.h"
|
||
#include "DocsManager.h"
|
||
#include "command_list.h"
|
||
#include "manager_docs.h"
|
||
|
||
#include <QSplitter>
|
||
#include <QVBoxLayout>
|
||
|
||
using namespace Components;
|
||
using namespace Parse;
|
||
using namespace Parse::Result;
|
||
using namespace Tools;
|
||
using namespace CommandList;
|
||
using namespace DataModel;
|
||
|
||
StorychainsPresentModel::StorychainsPresentModel(Core::AppCore *core)
|
||
: core_ins(core), model_base(new QStandardItemModel),
|
||
details_base(new QTextDocument) {
|
||
sync_tools = new TreeSyncs<DesNode *>(
|
||
model_base,
|
||
[](DesNode *const &d, QStandardItem *it) -> bool {
|
||
return static_cast<NamedNode *>(d)->name().first() == it->text();
|
||
},
|
||
[](DesNode *const &d, QStandardItem *it) {
|
||
it->setText(static_cast<NamedNode *>(d)->name().first());
|
||
});
|
||
}
|
||
|
||
StorychainsPresentModel::~StorychainsPresentModel() {
|
||
delete model_base;
|
||
delete details_base;
|
||
delete sync_tools;
|
||
}
|
||
|
||
QStandardItemModel *StorychainsPresentModel::treeModel() const {
|
||
return model_base;
|
||
}
|
||
|
||
QTextDocument *const StorychainsPresentModel::detailsBackend() const {
|
||
return details_base;
|
||
}
|
||
|
||
void StorychainsPresentModel::refreshTree() {
|
||
sync_tools->presentSync([this](DesNode *p) -> QList<DesNode *> {
|
||
if (p) {
|
||
QList<DesNode *> retv;
|
||
for (auto &point : p->children()) {
|
||
if (point->typeValue() == NODE_STORYPOINT) {
|
||
retv << point;
|
||
}
|
||
}
|
||
return retv;
|
||
} else
|
||
return this->core_ins->parseCore()->allStoryChains();
|
||
});
|
||
}
|
||
|
||
using namespace Operate;
|
||
void StorychainsPresentModel::showDetails(const QList<QString> &chain_path) {
|
||
QStandardItem *item = nullptr;
|
||
// 迭代路径获取故事链节点
|
||
for (auto &it : chain_path) {
|
||
auto result = OpStream<QStandardItem *>([this, &item](int &cnt, int idx) -> QStandardItem * {
|
||
if (!item) {
|
||
cnt = model_base->rowCount();
|
||
if (cnt <= 0)
|
||
return nullptr;
|
||
return model_base->item(idx);
|
||
} else {
|
||
cnt = item->rowCount();
|
||
if (cnt <= 0)
|
||
return nullptr;
|
||
return item->child(idx);
|
||
}
|
||
}).filter([it](QStandardItem *const &xit) {
|
||
return it == xit->text();
|
||
}).toList();
|
||
|
||
if (!result.size()) {
|
||
throw new SimpleException("指定的Storychain路径无效:" +
|
||
chain_path.join("/"));
|
||
} else {
|
||
item = result.at(0);
|
||
}
|
||
}
|
||
|
||
// 填充详细内容
|
||
QString text_lines;
|
||
if (item->parent() == nullptr) {
|
||
auto node = core_ins->parseCore()->queryStoryChain(item->text());
|
||
|
||
auto children = node.first()->children();
|
||
for (auto &it : children) {
|
||
if (it->typeValue() != NODE_STORYPOINT) {
|
||
text_lines += it->toString() + "\n";
|
||
}
|
||
}
|
||
} else {
|
||
auto node =
|
||
core_ins->parseCore()->queryStoryChain(item->parent()->text());
|
||
auto point =
|
||
core_ins->parseCore()->queryStoryPoint(node.first(), item->text());
|
||
|
||
auto children = point.first()->children();
|
||
for (auto &it : children) {
|
||
text_lines += it->toString() + "\n";
|
||
}
|
||
}
|
||
|
||
details_base->setPlainText(text_lines);
|
||
}
|
||
|
||
QString StorychainsPresentModel::name() const {
|
||
return NAME(StorychainsPresentModel);
|
||
}
|
||
|
||
StorychainsPresent::StorychainsPresent(Schedule::CommandsDispatcher *disp, StorychainsPresentModel *backend, QWidget *parent)
|
||
: QWidget(parent), disp_core(disp), tree_view(new QTreeView(this)), details_show(new QTextEdit) {
|
||
|
||
tree_view->setModel(backend->treeModel());
|
||
tree_view->setHeaderHidden(true);
|
||
details_show->setDocument(backend->detailsBackend());
|
||
details_show->setReadOnly(true);
|
||
|
||
auto layoutx = new QVBoxLayout(this);
|
||
auto split = new QSplitter(Qt::Vertical, this);
|
||
layoutx->addWidget(split);
|
||
split->addWidget(tree_view);
|
||
split->addWidget(details_show);
|
||
layoutx->setMargin(0);
|
||
|
||
connect(tree_view, &QTreeView::clicked, this,
|
||
&StorychainsPresent::detail_show);
|
||
connect(tree_view, &QTreeView::doubleClicked, this,
|
||
&StorychainsPresent::jump_to);
|
||
}
|
||
|
||
QString StorychainsPresent::name() const { return NAME(StorychainsPresent); }
|
||
|
||
QWidget *StorychainsPresent::widget() const { return (QWidget *)this; }
|
||
|
||
void StorychainsPresent::jump_to(const QModelIndex &curr) {
|
||
if (!curr.isValid())
|
||
return;
|
||
|
||
QList<QString> path;
|
||
auto node = curr;
|
||
while (true) {
|
||
auto node_name = node.data().toString();
|
||
|
||
if (node_name.isEmpty())
|
||
break;
|
||
path.insert(0, node_name);
|
||
node = node.parent();
|
||
}
|
||
|
||
disp_core->postCommand(StorychainJumpTo(path));
|
||
}
|
||
|
||
void StorychainsPresent::detail_show(const QModelIndex &curr) {
|
||
if (!curr.isValid())
|
||
return;
|
||
|
||
QList<QString> path;
|
||
auto node = curr;
|
||
while (true) {
|
||
auto node_name = node.data().toString();
|
||
|
||
if (node_name.isEmpty())
|
||
break;
|
||
path.insert(0, node_name);
|
||
node = node.parent();
|
||
}
|
||
|
||
disp_core->postCommand(StorychainDetailShow(path));
|
||
}
|