#include "storychainspresent.h" #include "DocsManager.h" #include "command_list.h" #include "manager_docs.h" #include #include 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( model_base, [](DesNode *const &d, QStandardItem *it) -> bool { return static_cast(d)->name().first() == it->text(); }, [](DesNode *const &d, QStandardItem *it) { it->setText(static_cast(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 { if (p) { QList 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 &chain_path) { QStandardItem *item = nullptr; // 迭代路径获取故事链节点 for (auto &it : chain_path) { auto result = OpStream([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 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 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)); }