From 48466620442c8bad89e6d7b9e5aca5d32c22bab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E5=AE=87=E6=B8=85=E9=9F=B3?= <2422523675@qq.com> Date: Fri, 10 Mar 2023 21:01:19 +0800 Subject: [PATCH] save --- GenericConsole/commandsdispatcher.cpp | 2 +- GenericConsole/commandsdispatcher.h | 4 +- QtNovelDesc.pro.user | 2 +- Testpad/opstream.h | 7 +- WordsIDE/DocsManager.cpp | 218 +++++++++--------- WordsIDE/DocsManager.h | 113 +++++----- WordsIDE/WordsIDE.pro | 4 + WordsIDE/appcore.cpp | 11 +- WordsIDE/appcore.h | 10 +- WordsIDE/command_list.cpp | 304 ++++++++++++++++++++++++- WordsIDE/command_list.h | 146 +++++++++++- WordsIDE/fragmentsorderview.cpp | 10 + WordsIDE/fragmentsorderview.h | 7 +- WordsIDE/mainwindow.cpp | 308 ++++++++++---------------- WordsIDE/mainwindow.h | 13 +- WordsIDE/manager_docs.cpp | 178 +++++++++------ WordsIDE/manager_docs.h | 48 ++-- WordsIDE/opstream.h | 9 + WordsIDE/storychainspresent.cpp | 200 ++++++++++++----- WordsIDE/storychainspresent.h | 46 +++- WordsIDE/storyunitspresent.cpp | 118 +++++----- WordsIDE/storyunitspresent.h | 46 ++-- WordsIDE/tools.cpp | 4 +- WordsIDE/tools.h | 4 +- 24 files changed, 1200 insertions(+), 612 deletions(-) diff --git a/GenericConsole/commandsdispatcher.cpp b/GenericConsole/commandsdispatcher.cpp index c157512..ee4152a 100644 --- a/GenericConsole/commandsdispatcher.cpp +++ b/GenericConsole/commandsdispatcher.cpp @@ -100,7 +100,7 @@ QList CommandsDispatcher::listCommands() const return command_types.values(); } -void CommandsDispatcher::postCommand(GeCommand &c) +void CommandsDispatcher::postCommand(const GeCommand &c) { if(!command_types.contains(c.name())) throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + c.name()); diff --git a/GenericConsole/commandsdispatcher.h b/GenericConsole/commandsdispatcher.h index c7ef1ab..a3488c1 100644 --- a/GenericConsole/commandsdispatcher.h +++ b/GenericConsole/commandsdispatcher.h @@ -48,7 +48,7 @@ namespace Schedule { * @brief 执行命令逻辑 * @param core 核心实例 */ - virtual void run(CommandsDispatcher *core) = 0; + virtual void run(CommandsDispatcher *core) const = 0; /** * @brief 转换成文本 @@ -140,7 +140,7 @@ namespace Schedule { * @brief 接收命令并执行,不接收内存管理责任,调用者自行管理命令内存 * @param c 命令实体 */ - virtual void postCommand(GeCommand &c); + virtual void postCommand(const GeCommand &c); /** * @brief 接收文本形势的命令并执行,主要应用对象是控制台 diff --git a/QtNovelDesc.pro.user b/QtNovelDesc.pro.user index b64ba9f..ac0b4f1 100644 --- a/QtNovelDesc.pro.user +++ b/QtNovelDesc.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/Testpad/opstream.h b/Testpad/opstream.h index 5b9f9eb..b922a8b 100644 --- a/Testpad/opstream.h +++ b/Testpad/opstream.h @@ -72,9 +72,10 @@ namespace Operate { public: OpStream(std::function peak_proc) { - int count = 0, index = 0; - ValueType one = peak_proc(count, index); - for(; index < count; ++index) + int count = 0; + peak_proc(count, -1); + + for(int index = 0; index < count; ++index) source_store << peak_proc(count, index); } OpStream(QList source) diff --git a/WordsIDE/DocsManager.cpp b/WordsIDE/DocsManager.cpp index f316b97..3b0f7ea 100644 --- a/WordsIDE/DocsManager.cpp +++ b/WordsIDE/DocsManager.cpp @@ -10,138 +10,138 @@ using namespace MakeTools; using namespace Core; -DocsManager::DocsManager(StoryTool *tool, AppCore *host, MainWindow *views) - : host_core(host), views_holder(views), make_core(tool) -{ +//DocsManager::DocsManager(StoryTool *tool, AppCore *host, MainWindow *views) +// : host_core(host), views_holder(views), make_core(tool) +//{ -} +//} -void DocsManager::saveAll() const -{ - for(auto &it : sourcecode_map) - it->saveAs(); - for(auto &it : plaintext_map) - it->saveAs(); -} +//void DocsManager::saveAll() const +//{ +// for(auto &it : sourcecode_map) +// it->saveAs(); +// for(auto &it : plaintext_map) +// it->saveAs(); +//} -void DocsManager::closeAll() -{ - for(auto &it : sourcecode_map.keys()) - closeTextComponent(QFileInfo(it)); +//void DocsManager::closeAll() +//{ +// for(auto &it : sourcecode_map.keys()) +// closeTextComponent(QFileInfo(it)); - for(auto &it : plaintext_map.keys()) - closeTextComponent(QFileInfo(it)); +// for(auto &it : plaintext_map.keys()) +// closeTextComponent(QFileInfo(it)); - host_core->getMakeCore()->getCore()->clear(); -} +// host_core->getMakeCore()->getCore()->clear(); +//} -bool DocsManager::activedContains(const QFileInfo &target) const -{ - for(auto &it : sourcecode_map.keys()) - if(it == target.absoluteFilePath()) - return true; - for(auto &it : plaintext_map.keys()) - if(it == target.absoluteFilePath()) - return true; +//bool DocsManager::activedContains(const QFileInfo &target) const +//{ +// for(auto &it : sourcecode_map.keys()) +// if(it == target.absoluteFilePath()) +// return true; +// for(auto &it : plaintext_map.keys()) +// if(it == target.absoluteFilePath()) +// return true; - return false; -} +// return false; +//} -MakeTools::ContentPresent *DocsManager::queryTextComponent(const QWidget *child_view) const -{ - for(auto ins : sourcecode_map) - if(ins->widget() == child_view) - return ins; - for(auto ins : plaintext_map) - if(ins->widget() == child_view) - return ins; +//MakeTools::ContentPresent *DocsManager::queryTextComponent(const QWidget *child_view) const +//{ +// for(auto ins : sourcecode_map) +// if(ins->widget() == child_view) +// return ins; +// for(auto ins : plaintext_map) +// if(ins->widget() == child_view) +// return ins; - return nullptr; -} +// return nullptr; +//} -MakeTools::ContentPresent *DocsManager::queryTextComponent(const QFileInfo &target) const -{ - for(auto &it : sourcecode_map.keys()) - if(it == target.absoluteFilePath()) - return sourcecode_map[it]; - for(auto &it : plaintext_map.keys()) - if(it == target.absoluteFilePath()) - return plaintext_map[it]; +//MakeTools::ContentPresent *DocsManager::queryTextComponent(const QFileInfo &target) const +//{ +// for(auto &it : sourcecode_map.keys()) +// if(it == target.absoluteFilePath()) +// return sourcecode_map[it]; +// for(auto &it : plaintext_map.keys()) +// if(it == target.absoluteFilePath()) +// return plaintext_map[it]; - return nullptr; -} +// return nullptr; +//} -void DocsManager::closeTextComponent(const QFileInfo &target) -{ - auto key = target.absoluteFilePath(); +//void DocsManager::closeTextComponent(const QFileInfo &target) +//{ +// auto key = target.absoluteFilePath(); - if(sourcecode_map.contains(key)){ - sourcecode_map[key]->saveAs(); - delete sourcecode_map[key]; - sourcecode_map.remove(key); - } - else if(plaintext_map.contains(key)){ - plaintext_map[key]->saveAs(); - delete plaintext_map[key]; - plaintext_map.remove(key); - } -} +// if(sourcecode_map.contains(key)){ +// sourcecode_map[key]->saveAs(); +// delete sourcecode_map[key]; +// sourcecode_map.remove(key); +// } +// else if(plaintext_map.contains(key)){ +// plaintext_map[key]->saveAs(); +// delete plaintext_map[key]; +// plaintext_map.remove(key); +// } +//} -void DocsManager::openTextDocument(const QString &src, const QString &name) -{ - // 获取匹配的处理类型 - auto xfactorys = host_core->extensions(QFileInfo(src).suffix()); +//void DocsManager::openTextDocument(const QString &src, const QString &name) +//{ +// // 获取匹配的处理类型 +// auto xfactorys = host_core->extensions(QFileInfo(src).suffix()); - // 如果已经打开 - if(activedContains(src)){ - auto ins = queryTextComponent(QFileInfo(src)); - if(ins == nullptr) - throw new SimpleException("逻辑错误,不应出现空指针"); - views_holder->contentViewAppend(ins->widget(), name); - return; - } +// // 如果已经打开 +// if(activedContains(src)){ +// auto ins = queryTextComponent(QFileInfo(src)); +// if(ins == nullptr) +// throw new SimpleException("逻辑错误,不应出现空指针"); +// views_holder->contentViewAppend(ins->widget(), name); +// return; +// } - make_core->compile(QFileInfo(src), name); +// make_core->compile(QFileInfo(src), name); - auto tins = xfactorys[0]->newInst(); - tins->applySetting(name, host_core); - tins->load(QFileInfo(src)); - addPerceptionList(tins); +// auto tins = xfactorys[0]->newInst(); +// tins->applySetting(name, host_core); +// tins->load(QFileInfo(src)); +// addPerceptionList(tins); - views_holder->contentViewAppend(tins->widget(), name); -} +// views_holder->contentViewAppend(tins->widget(), name); +//} -void DocsManager::addPerceptionList(ContentPresent *ins, SensitiveType type) -{ - auto cins = dynamic_cast(ins); - if(type == SensitiveType::CompileAtChanged && cins != nullptr){ - connect(cins, &CompileFeature::dataChanged, [ins, this](const QString &path){ - this->recompile(path, ins->name()); - }); - this->sourcecode_map[ins->absoluteTargetPath()] = ins; - } - else{ - this->plaintext_map[ins->absoluteTargetPath()] = ins; - } -} +//void DocsManager::addPerceptionList(ContentPresent *ins, SensitiveType type) +//{ +// auto cins = dynamic_cast(ins); +// if(type == SensitiveType::CompileAtChanged && cins != nullptr){ +// connect(cins, &CompileFeature::dataChanged, [ins, this](const QString &path){ +// this->recompile(path, ins->name()); +// }); +// this->sourcecode_map[ins->absoluteTargetPath()] = ins; +// } +// else{ +// this->plaintext_map[ins->absoluteTargetPath()] = ins; +// } +//} -void DocsManager::addProcTrigger(std::function exc) -{ - this->trigger_list << exc; -} +//void DocsManager::addProcTrigger(std::function exc) +//{ +// this->trigger_list << exc; +//} -void DocsManager::recompile(const QString &file_path, const QString &doc_name) -{ - if(!sourcecode_map.contains(file_path)) - return; +//void DocsManager::recompile(const QString &file_path, const QString &doc_name) +//{ +// if(!sourcecode_map.contains(file_path)) +// return; - auto view = this->sourcecode_map[file_path]; - auto cins = dynamic_cast(view); - make_core->compileSource(QFileInfo(file_path), cins->getText(), doc_name); +// auto view = this->sourcecode_map[file_path]; +// auto cins = dynamic_cast(view); +// make_core->compileSource(QFileInfo(file_path), cins->getText(), doc_name); - for(auto &ex : trigger_list) - ex(); -} +// for(auto &ex : trigger_list) +// ex(); +//} CompileFeature::CompileFeature(QObject *parent) diff --git a/WordsIDE/DocsManager.h b/WordsIDE/DocsManager.h index f28a93f..9f488c5 100644 --- a/WordsIDE/DocsManager.h +++ b/WordsIDE/DocsManager.h @@ -86,11 +86,6 @@ namespace MakeTools { * @return */ virtual QString name() const = 0; - /** - * @brief 重置实例别名 - * @param name - */ - virtual void rename(const QString &name) = 0; /** * @brief 使用此实例打开指定的路径文件,冲刷掉所有状态 * @param target_file 指定文件的info @@ -135,67 +130,67 @@ namespace MakeTools { /** * @brief 自动编译管理框架 */ - class DocsManager : public QObject - { - Q_OBJECT - public: - /** - * @brief 内容自动构建和管理核心 - * @param tool - */ - DocsManager(StoryTool *tool, Core::AppCore *host, MainWindow *views); +// class DocsManager : public QObject +// { +// Q_OBJECT +// public: +// /** +// * @brief 内容自动构建和管理核心 +// * @param tool +// */ +// DocsManager(StoryTool *tool, Core::AppCore *host, MainWindow *views); - /** - * @brief 保存当前所有文档内容 - */ - void saveAll() const; +// /** +// * @brief 保存当前所有文档内容 +// */ +// void saveAll() const; - void closeAll(); +// void closeAll(); - /** - * @brief 文档打开状态查询 - * @param target - * @return - */ - bool activedContains(const QFileInfo &target) const; - /** - * @brief 获取文档内存实例 - * @param child_view - * @return - */ - ContentPresent *queryTextComponent(const QWidget *child_view) const; - /** - * @brief 获取文档内存实例 - * @param target - * @return - */ - ContentPresent *queryTextComponent(const QFileInfo &target) const; - /** - * @brief 关闭文档内存实例,关闭之前保存内容 - * @param target - */ - void closeTextComponent(const QFileInfo &target); +// /** +// * @brief 文档打开状态查询 +// * @param target +// * @return +// */ +// bool activedContains(const QFileInfo &target) const; +// /** +// * @brief 获取文档内存实例 +// * @param child_view +// * @return +// */ +// ContentPresent *queryTextComponent(const QWidget *child_view) const; +// /** +// * @brief 获取文档内存实例 +// * @param target +// * @return +// */ +// ContentPresent *queryTextComponent(const QFileInfo &target) const; +// /** +// * @brief 关闭文档内存实例,关闭之前保存内容 +// * @param target +// */ +// void closeTextComponent(const QFileInfo &target); - /** - * @brief 打开指定路径的文档 - * @param src - * @param name - */ - void openTextDocument(const QString &src, const QString &name); +// /** +// * @brief 打开指定路径的文档 +// * @param src +// * @param name +// */ +// void openTextDocument(const QString &src, const QString &name); - void addPerceptionList(ContentPresent *ins, SensitiveType type = SensitiveType::CompileAtChanged); - void addProcTrigger(std::function exc); +// void addPerceptionList(ContentPresent *ins, SensitiveType type = SensitiveType::CompileAtChanged); +// void addProcTrigger(std::function exc); - private: - Core::AppCore *const host_core; - MainWindow *const views_holder; - StoryTool *const make_core; - QHash sourcecode_map; - QHash plaintext_map; - QList> trigger_list; +// private: +// Core::AppCore *const host_core; +// MainWindow *const views_holder; +// StoryTool *const make_core; +// QHash sourcecode_map; +// QHash plaintext_map; +// QList> trigger_list; - void recompile(const QString &file_path, const QString &doc_name); - }; +// void recompile(const QString &file_path, const QString &doc_name); +// }; } #endif // DOCSMANAGER_H diff --git a/WordsIDE/WordsIDE.pro b/WordsIDE/WordsIDE.pro index 683b734..8c11d7f 100644 --- a/WordsIDE/WordsIDE.pro +++ b/WordsIDE/WordsIDE.pro @@ -29,6 +29,8 @@ SOURCES += \ mainwindow.cpp \ manager_docs.cpp \ messagepresent.cpp \ + projectpresent.cpp \ + route.cpp \ srcedit_defaulttext.cpp \ srcedit_storyboard.cpp \ srcedit_storychain.cpp \ @@ -54,6 +56,8 @@ HEADERS += \ manager_docs.h \ messagepresent.h \ opstream.h \ + projectpresent.h \ + route.h \ srcedit_defaulttext.h \ srcedit_storyboard.h \ srcedit_storychain.h \ diff --git a/WordsIDE/appcore.cpp b/WordsIDE/appcore.cpp index 7eab0d4..ac015e9 100644 --- a/WordsIDE/appcore.cpp +++ b/WordsIDE/appcore.cpp @@ -21,7 +21,7 @@ using namespace MakeTools; AppCore::AppCore(MainWindow *win, bool record, QObject *parent) : QObject(parent), disp_core(new Schedule::CommandsDispatcher(QDir::home(), record)), views_holder(win), global_config(new Config::XMLConfig(this)), - makes_core(new StoryTool()), docs_manager(new DocsManager(makes_core, this, win)) + makes_core(new StoryTool())//, docs_manager(new DocsManager(makes_core, this, win)) { global_config->loadFile(QDir(QApplication::applicationDirPath()).filePath(".software.xml")); @@ -118,11 +118,16 @@ MakeTools::StoryTool *AppCore::getMakeCore() const return makes_core; } -MakeTools::DocsManager *AppCore::getDocsManager() const +QString AppCore::name() const { - return docs_manager; + return NAME(AppCore); } +//MakeTools::DocsManager *AppCore::getDocsManager() const +//{ +// return docs_manager; +//} + diff --git a/WordsIDE/appcore.h b/WordsIDE/appcore.h index 5082512..e0ebfe6 100644 --- a/WordsIDE/appcore.h +++ b/WordsIDE/appcore.h @@ -46,7 +46,7 @@ namespace Core { /** * @brief 软件内核类型 */ - class AppCore : public QObject + class AppCore : public QObject, public Schedule::AccessibleObject { public: Schedule::CommandsDispatcher *const disp_core; @@ -79,8 +79,6 @@ namespace Core { MakeTools::StoryTool *getMakeCore() const; - MakeTools::DocsManager *getDocsManager() const; - private: MainWindow *const views_holder; Config::Configration *const global_config; @@ -90,7 +88,11 @@ namespace Core { MakeTools::StoryTool *const makes_core; - MakeTools::DocsManager *const docs_manager; +// MakeTools::DocsManager *const docs_manager; + + // AccessibleObject interface + public: + virtual QString name() const override; }; } diff --git a/WordsIDE/command_list.cpp b/WordsIDE/command_list.cpp index afd2db5..be408c9 100644 --- a/WordsIDE/command_list.cpp +++ b/WordsIDE/command_list.cpp @@ -1,13 +1,16 @@ #include "command_list.h" #include "manager_docs.h" +#include "route.h" +#include "DocsManager.h" using namespace CommandList; using namespace Components; +using namespace Core; +using namespace MakeTools; -NewPackage::NewPackage(const QList &names) - : sequence(names) +NewPackage::NewPackage(const QString &path_string) { - + sequence = path_string.split("/"); } QString NewPackage::name() const @@ -15,20 +18,303 @@ QString NewPackage::name() const return NAME(NewPackage); } -void NewPackage::run(Schedule::CommandsDispatcher *core) +void NewPackage::run(Schedule::CommandsDispatcher *core) const { - auto vmgr = core->get - (NAME(DocumentManager)); - - vmgr->newPackage(sequence); + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->newPackage(Route::collect(sequence)); } QString NewPackage::toText() const { - return QStringList(sequence).join(":"); + return QStringList(sequence).join("/"); } void NewPackage::fromText(const QString &line) +{ + sequence = line.split("/"); +} + +NewFile::NewFile(const Route &group, const QString &name, const QString &suffix) + : name_val(name), suffix(suffix) { group_val = group.links(); } + +QString NewFile::name() const +{ + return NAME(NewFile); +} + +void NewFile::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->newFile(Route::collect(group_val), name_val, suffix); +} + +QString NewFile::toText() const +{ + return (QStringList() << QStringList(group_val).join("/") << name_val << suffix).join(":"); +} + +void NewFile::fromText(const QString &line) +{ + auto list = line.split(":", QString::SkipEmptyParts); + group_val = list[0].split("/"); + name_val = list[1]; + suffix = list[2]; +} + +SaveAll::SaveAll() { } + +QString SaveAll::name() const +{ + return NAME(SaveAll); +} + +void SaveAll::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(SaveAll)); + vmgr->projectManager()->save(); + vmgr->save(); +} + +QString SaveAll::toText() const +{ + return ""; +} + +void SaveAll::fromText(const QString &line) +{ + +} + +OpenProject::OpenProject(const QString &path) + : project_path(path) +{ + +} + +QString OpenProject::name() const +{ + return NAME(OpenProject); +} + +void OpenProject::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->projectManager()->openProject(project_path); +} + +QString OpenProject::toText() const +{ + return project_path; +} + +void OpenProject::fromText(const QString &line) +{ + project_path = line; +} + +CloseProject::CloseProject() +{ + +} + +QString CloseProject::name() const +{ + return NAME(CloseProject); +} + +void CloseProject::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->save(); + vmgr->close(); + vmgr->projectManager()->save(); + vmgr->projectManager()->closeProject(); +} + +NewProject::NewProject(const QDir &dir, const QString &name) + : dir_symbo(dir), name_val(name) +{ + +} + +QString NewProject::name() const +{ + return NAME(NewProject); +} + +void NewProject::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->projectManager()->newProject(dir_symbo.absolutePath(), name_val); +} + +QString NewProject::toText() const +{ + return QString("%1:%2").arg(dir_symbo.absolutePath(), name_val); +} + +void NewProject::fromText(const QString &line) +{ + auto list = line.split(":"); + dir_symbo = QDir(list[0]); + name_val = list[1]; +} + +Build::Build(bool fromdisk) + :all_from_disk(fromdisk) +{ + +} + +QString Build::name() const +{ + return NAME(Build); +} + +void Build::run(Schedule::CommandsDispatcher *core) const +{ + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->build(all_from_disk); +} + +QString Build::toText() const +{ + return QString("%1").arg(all_from_disk); +} + +void Build::fromText(const QString &line) +{ + all_from_disk = line.toUInt(); +} + +OpenFile::OpenFile(const Core::Route &path_node) +{ + path_store = path_node.links(); +} + +OpenFile::OpenFile(const QFileInfo &file_path) +{ + final_file = file_path; +} + +QString OpenFile::name() const +{ + return NAME(OpenFile); +} + +void OpenFile::run(Schedule::CommandsDispatcher *core) const +{ + auto mgr = core->get(NAME(DocumentsManager)); + if(path_store.size()){ + mgr->openFile(Route::collect(path_store)); + } + else{ + auto index = mgr->projectManager()->queryIndex(final_file); + auto route = mgr->pathOf(index); + + mgr->openFile(route); + } +} + +QString OpenFile::toText() const +{ + return path_store.join("/"); +} + +void OpenFile::fromText(const QString &line) +{ + path_store = line.split("/"); +} + + +StorychainJumpTo::StorychainJumpTo(const QList &node_path) +{ + jump_path.append(node_path); +} + +QString StorychainJumpTo::name() const +{ + return NAME(StorychainJumpTo); +} + +void StorychainJumpTo::run(Schedule::CommandsDispatcher *core) const +{ + auto core_ins = core->get(NAME(AppCore)); + auto chain_ins = core_ins->parseCore()->queryStoryChain(jump_path[0]).first(); + + auto vmgr = core->get(NAME(DocumentsManager)); + auto index = vmgr->projectManager()->queryIndex(chain_ins->doc()->filePath()); + auto route = vmgr->pathOf(index); + + vmgr->openFile(route); + vmgr->activePresentOf(route)->jumpTo(jump_path); +} + +QString StorychainJumpTo::toText() const +{ + return jump_path.join("/"); +} + +void StorychainJumpTo::fromText(const QString &line) +{ + jump_path=line.split("/"); +} + + +#include "storychainspresent.h" +using namespace Components; + +StorychainDetailShow::StorychainDetailShow(const QList &chain_path) + : chain_path(chain_path) +{ + +} + +QString StorychainDetailShow::name() const +{ + return NAME(StorychainDetailShow); +} + +void StorychainDetailShow::run(Schedule::CommandsDispatcher *core) const +{ + auto backend = core->get(NAME(StorychainsPresentModel)); + backend->showDetails(chain_path); +} + +QString StorychainDetailShow::toText() const +{ + return chain_path.join("/"); +} + +void StorychainDetailShow::fromText(const QString &line) +{ + chain_path = line.split("/"); +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WordsIDE/command_list.h b/WordsIDE/command_list.h index cace70e..e6433d1 100644 --- a/WordsIDE/command_list.h +++ b/WordsIDE/command_list.h @@ -1,25 +1,155 @@ #ifndef COMMAND_LIST_H #define COMMAND_LIST_H +#include "route.h" + #include namespace CommandList { - class NewPackage : public Schedule::GeCommand - { - public: - NewPackage(const QList &names); + class NewProject : public Schedule::GeCommand { + public: + NewProject(const QDir &dir, const QString &name); // GeCommand interface - public: + public: virtual QString name() const override; - virtual void run(Schedule::CommandsDispatcher *core) override; + virtual void run(Schedule::CommandsDispatcher *core) const override; virtual QString toText() const override; virtual void fromText(const QString &line) override; - private: + private: + QDir dir_symbo; + QString name_val; + }; + class OpenProject : public Schedule::GeCommand { + public: + OpenProject(const QString &path); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + + private: + QString project_path; + }; + class CloseProject : public Schedule::GeCommand { + public: + CloseProject(); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + }; + + class NewPackage : public Schedule::GeCommand { + public: + NewPackage(const QString &path_string); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + + private: QList sequence; }; -} + class NewFile : public Schedule::GeCommand { + public: + NewFile(const Core::Route &group, const QString &name, + const QString &suffix); + + private: + QList group_val; + QString name_val, suffix; + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + }; + class OpenFile : public Schedule::GeCommand { + public: + OpenFile(const Core::Route &path_node); + OpenFile(const QFileInfo &f); + + private: + QList path_store; + QFileInfo final_file; + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + }; + class SaveAll : public Schedule::GeCommand { + public: + SaveAll(); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + }; + + class Build : public Schedule::GeCommand { + public: + Build(bool fromdisk); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + + private: + bool all_from_disk; + }; + + class StorychainDetailShow : public Schedule::GeCommand { + public: + StorychainDetailShow(const QList &chain_path); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + + private: + QList chain_path; + }; + class StorychainJumpTo : public Schedule::GeCommand { + public: + StorychainJumpTo(const QList &node_path); + + // GeCommand interface + public: + virtual QString name() const override; + virtual void run(Schedule::CommandsDispatcher *core) const override; + virtual QString toText() const override; + virtual void fromText(const QString &line) override; + + private: + QList jump_path; + }; + +} // namespace CommandList #endif // COMMAND_LIST_H diff --git a/WordsIDE/fragmentsorderview.cpp b/WordsIDE/fragmentsorderview.cpp index a5ef934..7ee4e09 100644 --- a/WordsIDE/fragmentsorderview.cpp +++ b/WordsIDE/fragmentsorderview.cpp @@ -1,5 +1,6 @@ #include "fragmentsorderview.h" #include "DocsManager.h" +#include "manager_docs.h" #include #include #include @@ -52,6 +53,10 @@ void FragmentsOrderView::double_click(const QModelIndex &index) auto unit_ins = this->core_ins->parseCore()->queryStoryUnit(path[0]).first(); auto unit_doc = unit_ins->doc(); + + auto vmgr = this->core_ins->disp_core->get(NAME(DocumentsManager)); + index = vmgr->converter(QFileInfo()) + this->core_ins->getDocsManager()->openTextDocument(unit_doc->filePath(), unit_doc->docName()); auto present = this->core_ins->getDocsManager()->queryTextComponent(QFileInfo(unit_doc->filePath())); @@ -60,6 +65,11 @@ void FragmentsOrderView::double_click(const QModelIndex &index) } } +QString FragmentsOrderView::name() const +{ + return NAME(FragmentsOrderView); +} + diff --git a/WordsIDE/fragmentsorderview.h b/WordsIDE/fragmentsorderview.h index c7d49f6..53bd590 100644 --- a/WordsIDE/fragmentsorderview.h +++ b/WordsIDE/fragmentsorderview.h @@ -6,10 +6,11 @@ #include #include #include "appcore.h" +#include namespace Components { - class FragmentsOrderView : public QWidget + class FragmentsOrderView : public QWidget, public Schedule::AccessibleObject { Q_OBJECT public: @@ -24,6 +25,10 @@ namespace Components { QTableView *const table_view; QStandardItemModel *const table_base; + + // AccessibleObject interface + public: + virtual QString name() const override; }; } diff --git a/WordsIDE/mainwindow.cpp b/WordsIDE/mainwindow.cpp index fa7cedb..cf2292e 100644 --- a/WordsIDE/mainwindow.cpp +++ b/WordsIDE/mainwindow.cpp @@ -21,12 +21,15 @@ #include #include +#include "command_list.h" + using namespace Project; using namespace MakeTools; using namespace Parse::Result; using namespace Components; using namespace Core; using namespace Tools; +using namespace CommandList; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -39,11 +42,11 @@ MainWindow::MainWindow(QWidget *parent) center_funcs(new QTabWidget(this)), bottom_funcs(new QTabWidget(this)), project_manager(new XMLProjectManager(this)), - current_projects(new QListView(this)), - project_view(new QTreeView(this)), - project_structure(new DocumentManager(app_core, project_manager, this)), - chains_view(new StoryChainsPresent(app_core, this)), - units_view(new StoryUnitsPresent(app_core, this)), + welcome_list(new QListView(this)), + project_present(new ProjectPresent(app_core, this)), + docs_container(new DocumentsManager(app_core, project_manager, this)), + chains_view(new StorychainsPresent(app_core, this)), + units_view(new StoryunitsPresent(app_core, this)), errors_present(new MessagePresent(app_core->getMakeCore(), this)), boards_view(new StoryBoardsPresent(app_core, this)), concept_view(new StoryConceptsPresent(app_core, this)), @@ -51,7 +54,9 @@ MainWindow::MainWindow(QWidget *parent) { QApplication::instance()->installEventFilter(this); this->app_core->setCurrentProject(project_manager); - this->app_core->disp_core->registerMember(project_structure); + this->app_core->disp_core->registerMember(docs_container); + this->app_core->disp_core->registerMember(project_present); + this->app_core->disp_core->registerMember(this->app_core); setMinimumSize(1000, 600); setWindowTitle("提线木偶"); @@ -62,8 +67,6 @@ MainWindow::MainWindow(QWidget *parent) boards_view->setVisible(false); concept_view->setVisible(false); fragments_order->setVisible(false); - project_view->setVisible(false); - project_view->setModel(project_manager->model()); left_funcs->setVisible(false); right_funcs->setVisible(false); bottom_funcs->setVisible(false); @@ -75,56 +78,71 @@ MainWindow::MainWindow(QWidget *parent) statusBar()->addWidget(new QLabel("文本消息", this)); auto mbar = menuBar(); + initial_menubar(mbar); + + + setCentralWidget(this->vertical_split); + this->vertical_split->addWidget(this->horizontal_split); + this->vertical_split->addWidget(bottom_funcs); + + this->horizontal_split->addWidget(left_funcs); + this->horizontal_split->addWidget(center_funcs); + this->horizontal_split->addWidget(right_funcs); + + left_funcs->setTabsClosable(true); + connect(left_funcs, &QTabWidget::tabCloseRequested, + [this](int index){ toggle_widget_visible(false, left_funcs, left_funcs->widget(index)); }); + bottom_funcs->setTabsClosable(true); + connect(bottom_funcs, &QTabWidget::tabCloseRequested, + [this](int index){ toggle_widget_visible(false, bottom_funcs, bottom_funcs->widget(index)); }); + right_funcs->setTabsClosable(true); + connect(right_funcs, &QTabWidget::tabCloseRequested, + [this](int index){ toggle_widget_visible(false, right_funcs, right_funcs->widget(index)); }); + center_funcs->setTabsClosable(true); + connect(center_funcs, &QTabWidget::tabCloseRequested, + [this](int index){ + auto view = center_funcs->widget(index); + toggle_widget_visible(false, center_funcs, view); + auto comp = app_core->getDocsManager()->queryTextComponent(view); + if(comp) + app_core->getDocsManager()->closeTextComponent(QFileInfo(comp->absoluteTargetPath())); + }); + + this->app_core->getDocsManager()->addProcTrigger([this](){ + this->refresh_views(); + }); + + + center_funcs->addTab(welcome_list, "欢迎界面"); + + uilayout_load(); + + connect(horizontal_split, &QSplitter::splitterMoved, [this](){ + splitter_layout_save({"uilayout","split-policy-h","lens"}, horizontal_split->sizes()); + }); + connect(vertical_split, &QSplitter::splitterMoved, [this](){ + splitter_layout_save({"uilayout", "split-policy-v", "lens"}, vertical_split->sizes()); + }); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::initial_menubar(QMenuBar *mbar) +{ // 项目菜单树 auto project = mbar->addMenu("项目"); - auto pnew = project->addAction("新建路径", [this](){ - auto packages = QInputDialog::getText(this, "输入包路径名称", "packagea#packageb#packagec"); - if(packages == "") - return; - - QList names; - QRegExp exp("([^#]+)"); - auto idx=0; - while ((idx = exp.indexIn(packages, idx)) != -1) { - names << exp.capturedTexts()[1]; - idx += names.last().length(); - } - - project_manager->newPackage(names); - }); - sync_kernel->registerActionSync(pnew, [this]()->bool{return project_manager->isOpen();}); - - auto _xnew = project->addMenu("最后卷新建文件"); - _xnew->addAction("小说章节"); - _xnew->addSeparator(); - _xnew->addAction("发展脉络"); - _xnew->addAction("故事单元"); - _xnew->addAction("故事大纲"); - _xnew->addAction("叙事大纲"); - sync_kernel->registerWidgetSync(_xnew, [this]()->bool{return project_manager->isOpen();}); - - project->addSeparator(); - auto sav = project->addAction("保存"); - sav->setShortcut(QKeySequence::StandardKey::Save); - sync_kernel->registerActionSync(sav, [this]()->bool{return project_manager->isOpen();}); - connect(sav, &QAction::triggered, [this](){ - this->project_manager->save(); - app_core->getDocsManager()->saveAll(); - }); - project->addSeparator(); - auto opnp = project->addAction("打开项目"); - sync_kernel->registerActionSync(opnp, [this]()->bool{return !project_manager->isOpen();}); - connect(opnp, &QAction::triggered, [this](){ + auto opnp = project->addAction("打开项目", [this](){ auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)"); if(file == "") return; - project_manager->openProject(file); - build_internal(true); - }); - auto newp = project->addAction("新建项目"); - sync_kernel->registerActionSync(newp, [this]()->bool{return !project_manager->isOpen();}); - connect(newp, &QAction::triggered, [this](){ + this->app_core->disp_core->postCommand(OpenProject(file)); + build_internal(true);}); + sync_kernel->actionSync(opnp, [this]()->bool{return !project_manager->isOpen();}); + + auto newp = project->addAction("新建项目", [this](){ auto name = QInputDialog::getText(this, "输入项目名称", "项目名称"); if(name == "") return; @@ -132,53 +150,51 @@ MainWindow::MainWindow(QWidget *parent) if(dir_path == "") return; - this->project_manager->newProject(dir_path, name); - }); - auto clsp = project->addAction("关闭项目"); - sync_kernel->registerActionSync(clsp, [this]()->bool{return project_manager->isOpen();}); - connect(clsp, &QAction::triggered, [this](){ - this->project_manager->closeProject(); - this->app_core->getDocsManager()->closeAll(); - this->refresh_views(); - }); + this->app_core->disp_core->postCommand(NewProject(QDir(dir_path), name));}); + sync_kernel->actionSync(newp, [this]()->bool{return !project_manager->isOpen();}); + + auto clsp = project->addAction("关闭项目", [this](){ + this->app_core->disp_core->postCommand(CloseProject()); + this->refresh_views();}); + sync_kernel->actionSync(clsp, [this]()->bool{return project_manager->isOpen();}); project->addSeparator(); - auto pcfg = project->addAction("项目配置"); - connect(pcfg, &QAction::triggered, [this](){ - QDialog x(this); - auto layout = new QVBoxLayout(&x); - auto widget = new QTabWidget(&x); - widget->setTabPosition(QTabWidget::West); - layout->addWidget(widget); + auto pnew = project->addAction("新建路径", [this](){ + auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:"); + if(packages != "") + this->app_core->disp_core->postCommand(NewPackage(packages));}); + sync_kernel->actionSync(pnew, [this]()->bool{return project_manager->isOpen();}); -// auto exts = app_core->extensions(); -// for(auto &es : exts){ -// auto cp = es->getNewPanel(app_core->currentProject()->configraions()); -// if(cp) -// widget->addTab(cp, es->extensionName()); -// } - x.exec(); - }); - sync_kernel->registerActionSync(pcfg, [this]()->bool{ return app_core->currentProject()->isOpen();}); - auto scfg = project->addAction("软件配置"); - connect(scfg, &QAction::triggered, [this](){ - QDialog x(this); - auto layout = new QVBoxLayout(&x); + auto _xnew = project->addMenu("新建文件"); + auto types = docs_container->fileTypes(); + for(auto &t : types){ + _xnew->addAction(t, [this, &t](){ + auto name = QInputDialog::getText(this, "输入名称", "名称:"); + if(name == "") + return; - auto widget = new QTabWidget(&x); - widget->setTabPosition(QTabWidget::West); - layout->addWidget(widget); + auto idx = project_view->currentIndex(); + if(!idx.isValid()) + idx = project_manager->model()->item(0)->index(); - auto exts = app_core->extensions(); -// for(auto &es : exts){ -// auto cp = es->getNewPanel(app_core->globalConfig()); -// if(cp) -// widget->addTab(cp, es->extensionName()); -// } - x.exec(); - }); + auto group_path = docs_container->converter(idx); + this->app_core->disp_core->postCommand(NewFile(group_path, name, t)); + }); + } + sync_kernel->widgetSync(_xnew, [this]()->bool{return project_manager->isOpen();}); project->addSeparator(); - project->addAction("退出", [](){ QApplication::exit(0); }); + + auto sav = project->addAction("保存全部", [this](){ + this->app_core->disp_core->postCommand(SaveAll());}); + sav->setShortcut(QKeySequence::StandardKey::Save); + sync_kernel->actionSync(sav, [this]()->bool{return project_manager->isOpen();}); + project->addSeparator(); + + project->addAction("退出", [this](){ + this->app_core->disp_core->postCommand(SaveAll()); + QApplication::exit(0);}); + + // 编辑菜单 auto edit = mbar->addMenu("编辑"); @@ -228,15 +244,15 @@ MainWindow::MainWindow(QWidget *parent) change->addAction("编辑视图"); view->addSeparator(); auto func = view->addMenu("功能视图"); - // 项目管理 - { - auto project_v = func->addAction("项目管理", [this](bool v){ - toggle_widget_visible(v, left_funcs, project_structure, "项目管理"); - }); - project_v->setCheckable(true); - sync_kernel->registerAutoRun([this]()->bool{return this->project_structure->isVisible();}, - [project_v](bool v){ if(v != project_v->isChecked()) project_v->setChecked(v); }); - } +// // 项目管理 +// { +// auto project_v = func->addAction("项目管理", [this](bool v){ +// toggle_widget_visible(v, left_funcs, project_structure, "项目管理"); +// }); +// project_v->setCheckable(true); +// sync_kernel->registerAutoRun([this]()->bool{return this->project_structure->isVisible();}, +// [project_v](bool v){ if(v != project_v->isChecked()) project_v->setChecked(v); }); +// } func->addAction("引用统计"); func->addAction("脉络分蘖"); // 编译信息 @@ -313,7 +329,7 @@ MainWindow::MainWindow(QWidget *parent) auto build = tool->addAction("编译", [this](){ this->build_internal(); }); - sync_kernel->registerActionSync(build, [this]()->bool{ return project_manager->isOpen(); }); + sync_kernel->actionSync(build, [this]()->bool{ return project_manager->isOpen(); }); // 窗口菜单 auto window = mbar->addMenu("窗口"); @@ -330,67 +346,6 @@ MainWindow::MainWindow(QWidget *parent) sys->addAction("系统信息"); sys->addSeparator(); sys->addAction("关于……"); - - setCentralWidget(this->vertical_split); - this->vertical_split->addWidget(this->horizontal_split); - this->vertical_split->addWidget(bottom_funcs); - - this->horizontal_split->addWidget(left_funcs); - this->horizontal_split->addWidget(center_funcs); - this->horizontal_split->addWidget(right_funcs); - - left_funcs->setTabsClosable(true); - connect(left_funcs, &QTabWidget::tabCloseRequested, - [this](int index){ toggle_widget_visible(false, left_funcs, left_funcs->widget(index)); }); - bottom_funcs->setTabsClosable(true); - connect(bottom_funcs, &QTabWidget::tabCloseRequested, - [this](int index){ toggle_widget_visible(false, bottom_funcs, bottom_funcs->widget(index)); }); - right_funcs->setTabsClosable(true); - connect(right_funcs, &QTabWidget::tabCloseRequested, - [this](int index){ toggle_widget_visible(false, right_funcs, right_funcs->widget(index)); }); - center_funcs->setTabsClosable(true); - connect(center_funcs, &QTabWidget::tabCloseRequested, - [this](int index){ - auto view = center_funcs->widget(index); - toggle_widget_visible(false, center_funcs, view); - auto comp = app_core->getDocsManager()->queryTextComponent(view); - if(comp) - app_core->getDocsManager()->closeTextComponent(QFileInfo(comp->absoluteTargetPath())); - }); - - connect(project_structure, &DocumentManager::aboutToBoDelete, - [this](QList infos){ - for(auto &key : infos){ - auto comp = app_core->getDocsManager()->queryTextComponent(key); - if(comp){ - toggle_widget_visible(false, center_funcs, comp->widget()); - app_core->getDocsManager()->closeTextComponent(key); - } - } - }); - - this->app_core->getDocsManager()->addProcTrigger([this](){ - this->refresh_views(); - }); - - - center_funcs->addTab(current_projects, "欢迎界面"); - - connect(project_structure, &DocumentManager::activeDocument, - app_core->getDocsManager(), &MakeTools::DocsManager::openTextDocument); - - uilayout_load(); - - connect(horizontal_split, &QSplitter::splitterMoved, [this](){ - splitter_layout_save({"uilayout","split-policy-h","lens"}, horizontal_split->sizes()); - }); - connect(vertical_split, &QSplitter::splitterMoved, [this](){ - splitter_layout_save({"uilayout", "split-policy-v", "lens"}, vertical_split->sizes()); - }); -} - -MainWindow::~MainWindow() -{ } void MainWindow::contentViewAppend(QWidget *widget, const QString &name) @@ -426,30 +381,7 @@ void MainWindow::refresh_views() void MainWindow::build_internal(bool all_from_disk) { - if(!all_from_disk) - app_core->getDocsManager()->saveAll(); - - auto chains = project_manager->filesWithEnds("storychain"); - for(auto &it : chains){ - app_core->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); - } - - auto units = project_manager->filesWithEnds("storyunit"); - for(auto &it : units) - app_core->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); - - auto storys = project_manager->filesWithEnds("storyboard"); - for(auto &it : storys) - app_core->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); - - auto volumes = project_manager->filesWithEnds("storyvolume"); - for(auto &it : volumes) - app_core->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); - - auto concepts = project_manager->filesWithEnds("storyconcept"); - for(auto &it : concepts) - app_core->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); - + app_core->disp_core->postCommand(Build(all_from_disk)); refresh_views(); } diff --git a/WordsIDE/mainwindow.h b/WordsIDE/mainwindow.h index 918da71..5166fb1 100644 --- a/WordsIDE/mainwindow.h +++ b/WordsIDE/mainwindow.h @@ -18,6 +18,7 @@ #include "storyconceptspresent.h" #include "fragmentsorderview.h" #include "tools.h" +#include "projectpresent.h" class MainWindow : public QMainWindow, public Components::PresentContainer { @@ -42,17 +43,19 @@ private: Project::ProjectManager *const project_manager; - QListView *const current_projects; - QTreeView *const project_view; - Components::DocumentManager *const project_structure; - Components::StoryChainsPresent *const chains_view; - Components::StoryUnitsPresent *const units_view; + QListView *const welcome_list; + Components::ProjectPresent *const project_present; + Components::DocumentsManager *const docs_container; + Components::StorychainsPresent *const chains_view; + Components::StoryunitsPresent *const units_view; Components::MessagePresent *const errors_present; Components::StoryBoardsPresent *const boards_view; Components::StoryConceptsPresent *const concept_view; Components::FragmentsOrderView *const fragments_order; // 内部逻辑 =========================================== + void initial_menubar(QMenuBar *mbar); + void refresh_views(); void build_internal(bool all_from_disk = false); diff --git a/WordsIDE/manager_docs.cpp b/WordsIDE/manager_docs.cpp index 97c3e07..243031a 100644 --- a/WordsIDE/manager_docs.cpp +++ b/WordsIDE/manager_docs.cpp @@ -2,30 +2,27 @@ #include "DocsManager.h" using namespace Components; +using namespace Core; -DocumentManager::DocumentManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con) - : rtcore(src), pjtins(project), front_end(con) {} +DocumentsManager::DocumentsManager(AppCore *src, Project::ProjectManager *project, PresentContainer *con) + : rtcore(src), pjtins(project), present_ui(con) {} -void DocumentManager::newPackage(const QString &path_str) +Project::ProjectManager *DocumentsManager::projectManager() const { - QList path_list; - - QRegExp exp("/([^/]+)"); - auto offset = -1; - while ((offset = exp.indexIn(path_str, offset + 1)) != -1) { - path_list << exp.capturedTexts()[1].trimmed(); - } - - pjtins->newPackage(path_list); + return pjtins; } -void DocumentManager::newPackage(const QString &group_path, const QString &name) +void DocumentsManager::newPackage(const Route &link) { - QString path = group_path + "/" + name; - newPackage(path); + pjtins->newPackage(link.links()); } -QList DocumentManager::fileTypes() const +void DocumentsManager::newPackage(const Route &group, const QString &name) +{ + newPackage(group|name); +} + +QList DocumentsManager::fileTypes() const { QList all_types; for(auto &it : rtcore->allViews()) @@ -33,7 +30,7 @@ QList DocumentManager::fileTypes() const return all_types; } -void DocumentManager::newFile(const QString &group_path, const QString &name, const QString &suffix) +void DocumentsManager::newFile(const Route &group_path, const QString &name, const QString &suffix) { auto list = rtcore->extensions(suffix); QDir root = pjtins->projectDir(); @@ -49,16 +46,9 @@ void DocumentManager::newFile(const QString &group_path, const QString &name, co } } -QModelIndex DocumentManager::converter(const QString &path) +QModelIndex DocumentsManager::converter(const Route &path) { - QList path_list; - - QRegExp exp("/([^/]+)"); - auto offset = -1; - while ((offset = exp.indexIn(path, offset + 1)) != -1) { - path_list << exp.capturedTexts()[1].trimmed(); - } - + auto path_list = path.links(); auto itor_node = pjtins->model()->item(0); while (path_list.size()) { auto item = path_list.takeAt(0); @@ -71,108 +61,170 @@ QModelIndex DocumentManager::converter(const QString &path) } if(idx == itor_node->rowCount()) - throw new SimpleException("指定的path非法:"+path); + throw new SimpleException("指定的path非法:/"+ path.links().join("/")); } return itor_node->index(); } -QString DocumentManager::converter(const QModelIndex &index) +Route DocumentsManager::converter(const QModelIndex &index) { - QString path = ""; + Route path; auto item = pjtins->model()->itemFromIndex(index); auto pjt_node = pjtins->model()->item(0); while (item != pjt_node) { - path.prepend("/" + item->text().trimmed()); + path = path | item->text().trimmed(); item = item->parent(); } return path; } -void DocumentManager::removeNode(const QString &node_path) +//QModelIndex DocumentsManager::converter(const QFileInfo &file) +//{ +// for(auto &key : doc_openning.keys()){ +// if(file == QFileInfo(doc_openning[key]->absoluteTargetPath())) +// return converter(key); +// } +// return QModelIndex(); +//} + +void DocumentsManager::removeNode(const Route &node_path) { - auto node = converter(node_path); + auto node_mindex = converter(node_path); auto activie_file_nodes = actives(); - auto file_nodes = pjtins->filesGather(node); + auto file_nodes = pjtins->filesGather(node_mindex); - for(auto &n : file_nodes) - if(activie_file_nodes.contains(converter(n))) - close(QList()< path_buff; + for(auto &n : file_nodes){ + auto target = converter(n); + if(activie_file_nodes.contains(target)) + path_buff << target; + } - pjtins->deleteTarget(node); + close(path_buff); + pjtins->deleteTarget(node_mindex); } -void DocumentManager::renameNode(const QString &node_path, const QString &name) +void DocumentsManager::renameNode(const Route &node_path, const QString &name) { pjtins->rename(converter(node_path), name); auto activie_file_nodes = actives(); if(activie_file_nodes.contains(node_path)){ auto inst = activePresentOf(node_path); - inst->rename(name); - front_end->active(inst); + inst->applySetting(name, rtcore); + present_ui->active(inst); } } -void DocumentManager::openFile(const QString &file_node) +void DocumentsManager::openFile(const Route &path_node) { - auto info = pjtins->queryInfo(converter(file_node)); + auto info = pjtins->queryInfo(converter(path_node)); if(!info.isFile()) throw new SimpleException("打开的节点不是文件节点"); - if(actives().contains(file_node)){ - front_end->active(doc_openning[file_node]); + auto path_union = path_node.links().join("/"); + if(actives().contains(path_node)){ + present_ui->active(doc_openning[path_union]); return; } auto list = rtcore->extensions(info.suffix()); auto nview = list.first()->newInst(); nview->load(info); - doc_openning[file_node] = nview; - front_end->append(nview); - front_end->active(nview); + doc_openning[path_union] = nview; + present_ui->append(nview); + present_ui->active(nview); } -QList DocumentManager::actives() const +QList DocumentsManager::actives() const { - return doc_openning.keys(); + QList retv; + for(auto x : doc_openning.keys()) + retv << Route::collect(x.split("/")); + + return retv; } -MakeTools::ContentPresent *DocumentManager::activePresentOf(const QString &node_path) +MakeTools::ContentPresent *DocumentsManager::activePresentOf(const Route &node_path) { - return doc_openning[node_path]; + return doc_openning[node_path.links().join("/")]; } -void DocumentManager::save(const QList &docs) +void DocumentsManager::save(const QList &docs_path) { - auto actives = this->actives(); - for(auto &idx : docs) - if(actives.contains(idx)) - activePresentOf(idx)->saveAs(); + auto actives_paths = this->actives(); + for(auto &idx_path : docs_path) + if(actives_paths.contains(idx_path)) + activePresentOf(idx_path)->saveAs(); } -void DocumentManager::close(const QList &doc_paths) +void DocumentsManager::close(const QList &doc_paths) { auto actives = this->actives(); for(auto &idx : doc_paths) if(actives.contains(idx)){ auto inst = activePresentOf(idx); inst->saveAs(); - front_end->remove(inst); + present_ui->remove(inst); delete inst; - doc_openning.remove(idx); + doc_openning.remove(idx.links().join("/")); } } -QString DocumentManager::pathOf(MakeTools::ContentPresent *ins) const +Route DocumentsManager::pathOf(MakeTools::ContentPresent *ins) const { - return doc_openning.key(ins); + return Route::collect(doc_openning.key(ins).split("/")); } -QString DocumentManager::name() const +Route DocumentsManager::pathOf(const QModelIndex &p) const { - return NAME(DocumentManager); + if(!p.isValid()) + throw new SimpleException("传入非法QModelIndex"); + + auto item = projectManager()->model()->itemFromIndex(p); + auto proot = projectManager()->model()->item(0); + + Route retv; + while(proot != item){ + retv = retv|item->text(); + item = item->parent(); + } + + return retv; +} + +void DocumentsManager::build(bool all_from_disk) +{ + if(!all_from_disk) + save(); + + auto chains = pjtins->filesWithEnds("storychain"); + for(auto &it : chains){ + rtcore->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); + } + + auto units = pjtins->filesWithEnds("storyunit"); + for(auto &it : units) + rtcore->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); + + auto storys = pjtins->filesWithEnds("storyboard"); + for(auto &it : storys) + rtcore->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); + + auto volumes = pjtins->filesWithEnds("storyvolume"); + for(auto &it : volumes) + rtcore->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); + + auto concepts = pjtins->filesWithEnds("storyconcept"); + for(auto &it : concepts) + rtcore->getMakeCore()->compile(std::get<1>(it), std::get<0>(it)); +} + +QString DocumentsManager::name() const +{ + return NAME(DocumentsManager); } diff --git a/WordsIDE/manager_docs.h b/WordsIDE/manager_docs.h index 3dbad09..6086965 100644 --- a/WordsIDE/manager_docs.h +++ b/WordsIDE/manager_docs.h @@ -2,6 +2,7 @@ #define VISUABLE_PROJECT_CONTROLLER #include "appcore.h" +#include "route.h" #include #include @@ -36,25 +37,26 @@ namespace Components { /** * @brief 文档管理器,根据项目配置文件,打开、查询、关闭文档实例 */ - class DocumentManager : public Schedule::AccessibleObject + class DocumentsManager : public Schedule::AccessibleObject { - Q_OBJECT public: - DocumentManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con); - virtual ~DocumentManager() = default; + DocumentsManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con); + virtual ~DocumentsManager() = default; + + Project::ProjectManager* projectManager() const; /** * @brief 提供完整路径创建新包 * @param path [/x_name]+ */ - void newPackage(const QString &path_str); + void newPackage(const Core::Route &link); /** * @brief 提供父节点Index,创建新包 * @param group * @param name * @throw SimpleException */ - void newPackage(const QString &group_path, const QString &name); + void newPackage(const Core::Route &group, const QString &name); /** * @brief 获取支持的文件类型 @@ -68,17 +70,17 @@ namespace Components { * @param suffix 通过后缀名,指定文件类型 * @throw SimpleException */ - void newFile(const QString &group_path, const QString &name, const QString &suffix); + void newFile(const Core::Route &group_path, const QString &name, const QString &suffix); - QModelIndex converter(const QString &path); - QString converter(const QModelIndex &index); + QModelIndex converter(const Core::Route &path); + Core::Route converter(const QModelIndex &index); /** * @brief 移除指定节点(必须非根节点) * @param node 文件节点或者包节点 * @throw SimpleException */ - void removeNode(const QString &node_path); + void removeNode(const Core::Route &node_path); /** * @brief 修改指定节点的名称 @@ -86,52 +88,52 @@ namespace Components { * @param name 新名称 * @throw SimpleException */ - void renameNode(const QString &node_path, const QString &name); + void renameNode(const Core::Route &node_path, const QString &name); /** * @brief 打开文件节点 - * @param file_node + * @param path_node * @throw SimpleException */ - void openFile(const QString &file_node); + void openFile(const Core::Route &path_node); /** * @brief 获取打开的活跃文档 * @return */ - QList actives() const; + QList actives() const; /** * @brief 获取打开的内容展示实例,如果指向未打开的节点或无效文件节点,返回null * @param node * @return null或打开的展示实例 */ - MakeTools::ContentPresent* activePresentOf(const QString &node_path); + MakeTools::ContentPresent* activePresentOf(const Core::Route &node_path); /** * @brief 保存指定的文档节点集合 * @param docs */ - void save(const QList &docs = QList()); + void save(const QList &docs = QList()); /** * @brief 关闭定制的文档节点集合 * @param docs */ - void close(const QList &doc_paths = QList()); + void close(const QList &doc_paths = QList()); /** * @brief 查询指定实例(打开的)关联的ModelIndex * @param ins */ - QString pathOf(MakeTools::ContentPresent *ins) const; + Core::Route pathOf(MakeTools::ContentPresent *ins) const; + Core::Route pathOf(const QModelIndex &p) const; /** - * @brief 查询指定实例(打开的) - * @param target - * @return + * @brief 构建所有源代码 + * @param disk */ - QModelIndex pathOf(const QFileInfo &target) const; + void build(bool disk); // AccessibleObject interface public: @@ -140,7 +142,7 @@ namespace Components { private: Core::AppCore *const rtcore; Project::ProjectManager *pjtins; - PresentContainer *front_end; + PresentContainer *present_ui; QHash doc_openning; }; diff --git a/WordsIDE/opstream.h b/WordsIDE/opstream.h index 5b9f9eb..1c958a3 100644 --- a/WordsIDE/opstream.h +++ b/WordsIDE/opstream.h @@ -70,13 +70,22 @@ namespace Operate { class OpStream { public: + /** + * @brief 通过迭代函数建立操作流 + * @param peak_proc function + */ OpStream(std::function peak_proc) { int count = 0, index = 0; ValueType one = peak_proc(count, index); + for(; index < count; ++index) source_store << peak_proc(count, index); } + /** + * @brief 通过集合建立操作流 + * @param source + */ OpStream(QList source) : source_store(source){} diff --git a/WordsIDE/storychainspresent.cpp b/WordsIDE/storychainspresent.cpp index 9cfa8c5..734ae92 100644 --- a/WordsIDE/storychainspresent.cpp +++ b/WordsIDE/storychainspresent.cpp @@ -1,5 +1,7 @@ #include "storychainspresent.h" #include "DocsManager.h" +#include "manager_docs.h" +#include "command_list.h" #include #include @@ -8,63 +10,103 @@ using namespace Components; using namespace Parse; using namespace Parse::Result; using namespace Tools; +using namespace CommandList; -StoryChainsPresent::StoryChainsPresent(Core::AppCore *core, QWidget *parent) - : QWidget(parent), core_ins(core), model_base(new QStandardItemModel(this)), - tree_view(new QTreeView(this)), details_show(new QPlainTextEdit(this)), - sync_tools(new ModelSyncs( - 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(Core::AppCore *core) + :core_ins(core), + model_base(new QStandardItemModel), + details_base(new QTextDocument) { -tree_view->setModel(model_base); -tree_view->setHeaderHidden(true); - -auto layoutx = new QVBoxLayout(this); -layoutx->setMargin(0); -auto split = new QSplitter(Qt::Vertical, this); -layoutx->addWidget(split); -split->addWidget(tree_view); -split->addWidget(details_show); -details_show->setReadOnly(true); - -connect(tree_view, &QTreeView::clicked, this, &StoryChainsPresent::action_details_show); -connect(tree_view, &QTreeView::doubleClicked, this,&StoryChainsPresent::click_to); + sync_tools = new ModelSyncs( + 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()); }); } -void StoryChainsPresent::refresh() +StorychainsPresentModel::~StorychainsPresentModel() { - sync_tools->presentSync([this](DesNode *p)->QList{ - if(p){ - QList retv; - for(auto &point : p->children()){ - if(point->typeValue() == NODE_STORYPOINT){ - retv << point; + 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; } - return retv; - } - else - return this->core_ins->parseCore()->allStoryChains(); - }); + else + return this->core_ins->parseCore()->allStoryChains(); + }); } -void StoryChainsPresent::action_details_show(const QModelIndex &curr) +using namespace Operate; +void StorychainsPresentModel::showDetails(const QList &chain_path) { - if(!curr.isValid()) - return; + // 获取第一级初始集合 + QList item_list = \ + OpStream([this](int &cnt, int idx)->QStandardItem* + { + cnt = model_base->rowCount(); + if(cnt <= 0) + return nullptr; + return model_base->item(idx); + }).select().toList(); - details_show->clear(); - auto item = model_base->itemFromIndex(curr); + // 迭代路径获取故事链节点 + for(auto it : chain_path){ + auto result = \ + OpStream(item_list) + .filter([it](QStandardItem *const &xit) + {return it == xit->text();}) + .toList(); + + if(!result.size()){ + throw new SimpleException("指定的Storychain路径无效:" + chain_path.join("/")); + } + + item_list = \ + OpStream([&result](int &cnt, int idx)->QStandardItem* + { + cnt = result[0]->rowCount(); + if(cnt <= 0) + return nullptr; + return result[0]->child(idx); + }).select().toList(); + } + + // 填充详细内容 + auto item = item_list[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){ - details_show->appendPlainText(it->toString()); + text_lines += it->toString() + "\n"; } } } @@ -74,31 +116,84 @@ void StoryChainsPresent::action_details_show(const QModelIndex &curr) auto children = point.first()->children(); for(auto &it : children){ - details_show->appendPlainText(it->toString()); + text_lines += it->toString() + "\n"; } } + + details_base->setPlainText(text_lines); } -void StoryChainsPresent::click_to(const QModelIndex &curr) +QString StorychainsPresentModel::name() const +{ + return NAME(StorychainsPresentModel); +} + + + +StorychainsPresent::StorychainsPresent(Schedule::CommandsDispatcher *disp, QWidget *parent) + : QWidget(parent), disp_core(disp), + tree_view(new QTreeView(this)), details_show(new QPlainTextEdit) +{ + auto backend = disp->get(NAME(StorychainsPresentModel)); + + 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::details_show); + connect(tree_view, &QTreeView::doubleClicked, + this, &StorychainsPresent::jump_to); +} + +QString StorychainsPresent::name() const +{ + return NAME(StorychainsPresent); +} + +void StorychainsPresent::jump_to(const QModelIndex &curr) { if(!curr.isValid()) return; - auto pnode = this->model_base->itemFromIndex(curr); QList path; - while (pnode) { - path.insert(0, pnode->text()); - pnode = pnode->parent(); + while (true) { + auto node = curr.data().toString(); + + if(node.isEmpty()) + break; + else + path << node; } - auto chain_ins = this->core_ins->parseCore()->queryStoryChain(path[0]).first(); - auto chain_doc = chain_ins->doc(); - this->core_ins->getDocsManager()->openTextDocument(chain_doc->filePath(), chain_doc->docName()); - auto present = this->core_ins->getDocsManager()->queryTextComponent(QFileInfo(chain_doc->filePath())); + disp_core->postCommand(StorychainJumpTo(path)); +} - if(path.size()){ - present->jumpTo(path); +void StorychainsPresent::detail_show(const QModelIndex &curr) +{ + if(!curr.isValid()) + return; + + QList path; + while (true) { + auto node = curr.data().toString(); + + if(node.isEmpty()) + break; + else + path << node; } + + disp_core->postCommand(StorychainDetailShow(path)); } @@ -113,4 +208,3 @@ void StoryChainsPresent::click_to(const QModelIndex &curr) - diff --git a/WordsIDE/storychainspresent.h b/WordsIDE/storychainspresent.h index 426fbab..b9cffec 100644 --- a/WordsIDE/storychainspresent.h +++ b/WordsIDE/storychainspresent.h @@ -12,26 +12,54 @@ namespace Components { - class StoryChainsPresent : public QWidget + /** + * @brief 情节链展示后端 + */ + class StorychainsPresentModel : public Schedule::AccessibleObject { - Q_OBJECT public: - explicit StoryChainsPresent(Core::AppCore *core, QWidget *parent = nullptr); + StorychainsPresentModel(Core::AppCore *core); + virtual ~StorychainsPresentModel(); - void refresh(); + QStandardItemModel* treeModel() const; + QTextDocument *const detailsBackend() const; - signals: + void refreshTree(); + void showDetails(const QList &chain_path); + + // AccessibleObject interface + public: + virtual QString name() const override; private: Core::AppCore *const core_ins; QStandardItemModel *const model_base; + QTextDocument *const details_base; + Tools::ModelSyncs *sync_tools; + + }; + + /** + * @brief 情节链展示视图 + */ + class StorychainsPresent : public QWidget, + public Schedule::AccessibleObject { + Q_OBJECT + public: + explicit StorychainsPresent(Schedule::CommandsDispatcher *disp, + QWidget *parent = nullptr); + + // AccessibleObject interface + public: + virtual QString name() const override; + + private: + Schedule::CommandsDispatcher *disp_core; QTreeView *const tree_view; QPlainTextEdit *const details_show; - Tools::ModelSyncs *const sync_tools; - void action_details_show(const QModelIndex &curr); - - void click_to(const QModelIndex &curr); + void jump_to(const QModelIndex &curr); + void detail_show(const QModelIndex &curr); }; } diff --git a/WordsIDE/storyunitspresent.cpp b/WordsIDE/storyunitspresent.cpp index 6798797..36cdd95 100644 --- a/WordsIDE/storyunitspresent.cpp +++ b/WordsIDE/storyunitspresent.cpp @@ -7,43 +7,37 @@ using namespace Components; using namespace Parse::Result; -StoryUnitsPresent::StoryUnitsPresent(Core::AppCore *core, QWidget *parent) - : QWidget(parent), core_ins(core), - model_ins(new QStandardItemModel(this)), - units_view(new QTreeView(this)), - details_show(new QPlainTextEdit(this)) -{ - units_view->setHeaderHidden(true); +StoryunitsPresentModel::StoryunitsPresentModel(Core::AppCore *core) + : core_ins(core), model_ins(new QStandardItemModel), + details_backend(new QTextDocument) {} - auto layout = new QVBoxLayout(this); - layout->setMargin(0); - - auto splitter = new QSplitter(Qt::Vertical, this); - layout->addWidget(splitter); - - splitter->addWidget(units_view); - splitter->addWidget(details_show); - - units_view->setModel(model_ins); - details_show->setReadOnly(true); - - connect(units_view, &QTreeView::clicked, this, &StoryUnitsPresent::show_node_description); - connect(units_view, &QTreeView::doubleClicked, this, &StoryUnitsPresent::click_to); +StoryunitsPresentModel::~StoryunitsPresentModel() { + delete model_ins; + delete details_backend; } -void StoryUnitsPresent::refresh() -{ +QStandardItemModel *StoryunitsPresentModel::treeModel() const { + return model_ins; +} + +QTextDocument *StoryunitsPresentModel::detailsBackend() const { + return details_backend; +} + +void StoryunitsPresentModel::refresh() { model_ins->clear(); auto units = core_ins->parseCore()->allStoryUnits(); - for(auto &unit : units){ - auto unit_node = new QStandardItem(static_cast(unit)->name()[0]); + for (auto &unit : units) { + auto unit_node = + new QStandardItem(static_cast(unit)->name()[0]); unit_node->setEditable(false); model_ins->appendRow(unit_node); auto children = unit->children(); - for(auto &frag : children){ - if(frag->typeValue() == NODE_STORYFRAGMENT){ - auto frag_node = new QStandardItem(static_cast(frag)->name()[0]); + for (auto &frag : children) { + if (frag->typeValue() == NODE_STORYFRAGMENT) { + auto frag_node = new QStandardItem( + static_cast(frag)->name()[0]); frag_node->setEditable(false); unit_node->appendRow(frag_node); } @@ -51,37 +45,36 @@ void StoryUnitsPresent::refresh() } } -void StoryUnitsPresent::show_node_description(const QModelIndex &curr) -{ - if(!curr.isValid()) +void StoryunitsPresentModel::show_node_description(const QModelIndex &curr) { + if (!curr.isValid()) return; details_show->clear(); auto item = model_ins->itemFromIndex(curr); - if(item->parent() == nullptr){ + if (item->parent() == nullptr) { auto node = core_ins->parseCore()->queryStoryUnit(item->text()); auto children = node.first()->children(); - for(auto &it : children){ - if(it->typeValue() != NODE_STORYFRAGMENT){ + for (auto &it : children) { + if (it->typeValue() != NODE_STORYFRAGMENT) { details_show->appendPlainText(it->toString()); } } - } - else{ - auto node = core_ins->parseCore()->queryStoryUnit(item->parent()->text()); - auto point = core_ins->parseCore()->queryStoryFragment(node.first(), item->text()); + } else { + auto node = + core_ins->parseCore()->queryStoryUnit(item->parent()->text()); + auto point = core_ins->parseCore()->queryStoryFragment(node.first(), + item->text()); auto children = point.first()->children(); - for(auto &it : children){ + for (auto &it : children) { details_show->appendPlainText(it->toString()); } } } -void StoryUnitsPresent::click_to(const QModelIndex &curr) -{ - if(!curr.isValid()) +void StoryunitsPresentModel::click_to(const QModelIndex &curr) { + if (!curr.isValid()) return; auto pnode = this->model_ins->itemFromIndex(curr); @@ -91,25 +84,42 @@ void StoryUnitsPresent::click_to(const QModelIndex &curr) pnode = pnode->parent(); } - auto unit_ins = this->core_ins->parseCore()->queryStoryUnit(path[0]).first(); + auto unit_ins = + this->core_ins->parseCore()->queryStoryUnit(path[0]).first(); auto chain_doc = unit_ins->doc(); - this->core_ins->getDocsManager()->openTextDocument(chain_doc->filePath(), chain_doc->docName()); - auto present = this->core_ins->getDocsManager()->queryTextComponent(QFileInfo(chain_doc->filePath())); + this->core_ins->getDocsManager()->openTextDocument(chain_doc->filePath(), + chain_doc->docName()); + auto present = this->core_ins->getDocsManager()->queryTextComponent( + QFileInfo(chain_doc->filePath())); - if(path.size()){ + if (path.size()) { present->jumpTo(path); } } +StoryunitsPresent::StoryunitsPresent(Schedule::CommandsDispatcher *core, + QWidget *parent) + : QWidget(parent), core_ins(core), units_view(new QTreeView(this)), + details_show(new QTextEdit(this)) { + auto backend = + core->get(NAME(StoryunitsPresentModel)); + units_view->setHeaderHidden(true); + units_view->setModel(backend->treeModel()); + details_show->setReadOnly(true); + details_show->setDocument(backend->detailsBackend()); + auto layout = new QVBoxLayout(this); + auto splitter = new QSplitter(Qt::Vertical, this); + layout->addWidget(splitter); + splitter->addWidget(units_view); + splitter->addWidget(details_show); + layout->setMargin(0); + connect(units_view, &QTreeView::clicked, this, + &StoryunitsPresent::show_details); + connect(units_view, &QTreeView::doubleClicked, this, + &StoryunitsPresent::jump_to); +} - - - - - - - - +QString StoryunitsPresent::name() const { return NAME(StoryunitsPresent); } diff --git a/WordsIDE/storyunitspresent.h b/WordsIDE/storyunitspresent.h index 4d031d0..929f80c 100644 --- a/WordsIDE/storyunitspresent.h +++ b/WordsIDE/storyunitspresent.h @@ -12,26 +12,46 @@ namespace Components { - class StoryUnitsPresent : public QWidget - { - Q_OBJECT - public: - explicit StoryUnitsPresent(Core::AppCore *core, QWidget *parent = nullptr); + class StoryunitsPresentModel : public Schedule::AccessibleObject { + public: + StoryunitsPresentModel(Core::AppCore *core); + virtual ~StoryunitsPresentModel(); + + QStandardItemModel *treeModel() const; + QTextDocument *detailsBackend() const; void refresh(); + void show_node_description(const QModelIndex &curr); - signals: + // AccessibleObject interface + public: + virtual QString name() const override; - private: + private: Core::AppCore *const core_ins; QStandardItemModel *const model_ins; - QTreeView *const units_view; - QPlainTextEdit *const details_show; - - void show_node_description(const QModelIndex &curr); - void click_to(const QModelIndex &curr); + QTextDocument *const details_backend; }; -} + class StoryunitsPresent : public QWidget, + public Schedule::AccessibleObject { + Q_OBJECT + public: + explicit StoryunitsPresent(Schedule::CommandsDispatcher *core, + QWidget *parent = nullptr); + + // AccessibleObject interface + public: + virtual QString name() const override; + + private: + Schedule::CommandsDispatcher *const core_ins; + QTreeView *const units_view; + QTextEdit *const details_show; + + void jump_to(const QModelIndex &curr); + void show_details(const QModelIndex &curr); + }; +} // namespace Components #endif // STORYUNITSPRESENT_H diff --git a/WordsIDE/tools.cpp b/WordsIDE/tools.cpp index c0f4cc7..0c2edea 100644 --- a/WordsIDE/tools.cpp +++ b/WordsIDE/tools.cpp @@ -18,12 +18,12 @@ void Run::exec() StatusSyncCore::StatusSyncCore(QObject *p) : QObject(p){} -void StatusSyncCore::registerWidgetSync(QWidget *tar, std::function proc) +void StatusSyncCore::widgetSync(QWidget *tar, std::function proc) { widget_trigger_map[tar] = proc; } -void StatusSyncCore::registerActionSync(QAction *tar, std::function proc) +void StatusSyncCore::actionSync(QAction *tar, std::function proc) { action_trigger_map[tar] = proc; } diff --git a/WordsIDE/tools.h b/WordsIDE/tools.h index 3c29635..ed6a50a 100644 --- a/WordsIDE/tools.h +++ b/WordsIDE/tools.h @@ -27,8 +27,8 @@ namespace Tools { virtual ~StatusSyncCore() = default; - void registerWidgetSync(QWidget* tar, std::function proc); - void registerActionSync(QAction* tar, std::function proc); + void widgetSync(QWidget* tar, std::function proc); + void actionSync(QAction* tar, std::function proc); void registerAutoRun(std::function judge, std::function exec); Run* registerManualRun(std::function judge, std::function exec); void sync();