This commit is contained in:
玉宇清音 2023-03-10 21:01:19 +08:00
parent 0b764bf30a
commit 4846662044
24 changed files with 1200 additions and 612 deletions

View File

@ -100,7 +100,7 @@ QList<GeCommand *> CommandsDispatcher::listCommands() const
return command_types.values(); return command_types.values();
} }
void CommandsDispatcher::postCommand(GeCommand &c) void CommandsDispatcher::postCommand(const GeCommand &c)
{ {
if(!command_types.contains(c.name())) if(!command_types.contains(c.name()))
throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + c.name()); throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + c.name());

View File

@ -48,7 +48,7 @@ namespace Schedule {
* @brief * @brief
* @param core * @param core
*/ */
virtual void run(CommandsDispatcher *core) = 0; virtual void run(CommandsDispatcher *core) const = 0;
/** /**
* @brief * @brief
@ -140,7 +140,7 @@ namespace Schedule {
* @brief * @brief
* @param c * @param c
*/ */
virtual void postCommand(GeCommand &c); virtual void postCommand(const GeCommand &c);
/** /**
* @brief * @brief

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.0, 2023-03-04T10:25:52. --> <!-- Written by QtCreator 4.15.0, 2023-03-09T23:20:26. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@ -72,9 +72,10 @@ namespace Operate {
public: public:
OpStream(std::function<ValueType(int &cnt, int idx)> peak_proc) OpStream(std::function<ValueType(int &cnt, int idx)> peak_proc)
{ {
int count = 0, index = 0; int count = 0;
ValueType one = peak_proc(count, index); peak_proc(count, -1);
for(; index < count; ++index)
for(int index = 0; index < count; ++index)
source_store << peak_proc(count, index); source_store << peak_proc(count, index);
} }
OpStream(QList<ValueType> source) OpStream(QList<ValueType> source)

View File

@ -10,138 +10,138 @@ using namespace MakeTools;
using namespace Core; using namespace Core;
DocsManager::DocsManager(StoryTool *tool, AppCore *host, MainWindow *views) //DocsManager::DocsManager(StoryTool *tool, AppCore *host, MainWindow *views)
: host_core(host), views_holder(views), make_core(tool) // : host_core(host), views_holder(views), make_core(tool)
{ //{
} //}
void DocsManager::saveAll() const //void DocsManager::saveAll() const
{ //{
for(auto &it : sourcecode_map) // for(auto &it : sourcecode_map)
it->saveAs(); // it->saveAs();
for(auto &it : plaintext_map) // for(auto &it : plaintext_map)
it->saveAs(); // it->saveAs();
} //}
void DocsManager::closeAll() //void DocsManager::closeAll()
{ //{
for(auto &it : sourcecode_map.keys()) // for(auto &it : sourcecode_map.keys())
closeTextComponent(QFileInfo(it)); // closeTextComponent(QFileInfo(it));
for(auto &it : plaintext_map.keys()) // for(auto &it : plaintext_map.keys())
closeTextComponent(QFileInfo(it)); // closeTextComponent(QFileInfo(it));
host_core->getMakeCore()->getCore()->clear(); // host_core->getMakeCore()->getCore()->clear();
} //}
bool DocsManager::activedContains(const QFileInfo &target) const //bool DocsManager::activedContains(const QFileInfo &target) const
{ //{
for(auto &it : sourcecode_map.keys()) // for(auto &it : sourcecode_map.keys())
if(it == target.absoluteFilePath()) // if(it == target.absoluteFilePath())
return true; // return true;
for(auto &it : plaintext_map.keys()) // for(auto &it : plaintext_map.keys())
if(it == target.absoluteFilePath()) // if(it == target.absoluteFilePath())
return true; // return true;
return false; // return false;
} //}
MakeTools::ContentPresent *DocsManager::queryTextComponent(const QWidget *child_view) const //MakeTools::ContentPresent *DocsManager::queryTextComponent(const QWidget *child_view) const
{ //{
for(auto ins : sourcecode_map) // for(auto ins : sourcecode_map)
if(ins->widget() == child_view) // if(ins->widget() == child_view)
return ins; // return ins;
for(auto ins : plaintext_map) // for(auto ins : plaintext_map)
if(ins->widget() == child_view) // if(ins->widget() == child_view)
return ins; // return ins;
return nullptr; // return nullptr;
} //}
MakeTools::ContentPresent *DocsManager::queryTextComponent(const QFileInfo &target) const //MakeTools::ContentPresent *DocsManager::queryTextComponent(const QFileInfo &target) const
{ //{
for(auto &it : sourcecode_map.keys()) // for(auto &it : sourcecode_map.keys())
if(it == target.absoluteFilePath()) // if(it == target.absoluteFilePath())
return sourcecode_map[it]; // return sourcecode_map[it];
for(auto &it : plaintext_map.keys()) // for(auto &it : plaintext_map.keys())
if(it == target.absoluteFilePath()) // if(it == target.absoluteFilePath())
return plaintext_map[it]; // return plaintext_map[it];
return nullptr; // return nullptr;
} //}
void DocsManager::closeTextComponent(const QFileInfo &target) //void DocsManager::closeTextComponent(const QFileInfo &target)
{ //{
auto key = target.absoluteFilePath(); // auto key = target.absoluteFilePath();
if(sourcecode_map.contains(key)){ // if(sourcecode_map.contains(key)){
sourcecode_map[key]->saveAs(); // sourcecode_map[key]->saveAs();
delete sourcecode_map[key]; // delete sourcecode_map[key];
sourcecode_map.remove(key); // sourcecode_map.remove(key);
} // }
else if(plaintext_map.contains(key)){ // else if(plaintext_map.contains(key)){
plaintext_map[key]->saveAs(); // plaintext_map[key]->saveAs();
delete plaintext_map[key]; // delete plaintext_map[key];
plaintext_map.remove(key); // plaintext_map.remove(key);
} // }
} //}
void DocsManager::openTextDocument(const QString &src, const QString &name) //void DocsManager::openTextDocument(const QString &src, const QString &name)
{ //{
// 获取匹配的处理类型 // // 获取匹配的处理类型
auto xfactorys = host_core->extensions(QFileInfo(src).suffix()); // auto xfactorys = host_core->extensions(QFileInfo(src).suffix());
// 如果已经打开 // // 如果已经打开
if(activedContains(src)){ // if(activedContains(src)){
auto ins = queryTextComponent(QFileInfo(src)); // auto ins = queryTextComponent(QFileInfo(src));
if(ins == nullptr) // if(ins == nullptr)
throw new SimpleException("逻辑错误,不应出现空指针"); // throw new SimpleException("逻辑错误,不应出现空指针");
views_holder->contentViewAppend(ins->widget(), name); // views_holder->contentViewAppend(ins->widget(), name);
return; // return;
} // }
make_core->compile(QFileInfo(src), name); // make_core->compile(QFileInfo(src), name);
auto tins = xfactorys[0]->newInst(); // auto tins = xfactorys[0]->newInst();
tins->applySetting(name, host_core); // tins->applySetting(name, host_core);
tins->load(QFileInfo(src)); // tins->load(QFileInfo(src));
addPerceptionList(tins); // addPerceptionList(tins);
views_holder->contentViewAppend(tins->widget(), name); // views_holder->contentViewAppend(tins->widget(), name);
} //}
void DocsManager::addPerceptionList(ContentPresent *ins, SensitiveType type) //void DocsManager::addPerceptionList(ContentPresent *ins, SensitiveType type)
{ //{
auto cins = dynamic_cast<CompileFeature*>(ins); // auto cins = dynamic_cast<CompileFeature*>(ins);
if(type == SensitiveType::CompileAtChanged && cins != nullptr){ // if(type == SensitiveType::CompileAtChanged && cins != nullptr){
connect(cins, &CompileFeature::dataChanged, [ins, this](const QString &path){ // connect(cins, &CompileFeature::dataChanged, [ins, this](const QString &path){
this->recompile(path, ins->name()); // this->recompile(path, ins->name());
}); // });
this->sourcecode_map[ins->absoluteTargetPath()] = ins; // this->sourcecode_map[ins->absoluteTargetPath()] = ins;
} // }
else{ // else{
this->plaintext_map[ins->absoluteTargetPath()] = ins; // this->plaintext_map[ins->absoluteTargetPath()] = ins;
} // }
} //}
void DocsManager::addProcTrigger(std::function<void ()> exc) //void DocsManager::addProcTrigger(std::function<void ()> exc)
{ //{
this->trigger_list << exc; // this->trigger_list << exc;
} //}
void DocsManager::recompile(const QString &file_path, const QString &doc_name) //void DocsManager::recompile(const QString &file_path, const QString &doc_name)
{ //{
if(!sourcecode_map.contains(file_path)) // if(!sourcecode_map.contains(file_path))
return; // return;
auto view = this->sourcecode_map[file_path]; // auto view = this->sourcecode_map[file_path];
auto cins = dynamic_cast<CompileFeature*>(view); // auto cins = dynamic_cast<CompileFeature*>(view);
make_core->compileSource(QFileInfo(file_path), cins->getText(), doc_name); // make_core->compileSource(QFileInfo(file_path), cins->getText(), doc_name);
for(auto &ex : trigger_list) // for(auto &ex : trigger_list)
ex(); // ex();
} //}
CompileFeature::CompileFeature(QObject *parent) CompileFeature::CompileFeature(QObject *parent)

View File

@ -86,11 +86,6 @@ namespace MakeTools {
* @return * @return
*/ */
virtual QString name() const = 0; virtual QString name() const = 0;
/**
* @brief
* @param name
*/
virtual void rename(const QString &name) = 0;
/** /**
* @brief 使 * @brief 使
* @param target_file info * @param target_file info
@ -135,67 +130,67 @@ namespace MakeTools {
/** /**
* @brief * @brief
*/ */
class DocsManager : public QObject // class DocsManager : public QObject
{ // {
Q_OBJECT // Q_OBJECT
public: // public:
/** // /**
* @brief // * @brief 内容自动构建和管理核心
* @param tool // * @param tool
*/ // */
DocsManager(StoryTool *tool, Core::AppCore *host, MainWindow *views); // DocsManager(StoryTool *tool, Core::AppCore *host, MainWindow *views);
/** // /**
* @brief // * @brief 保存当前所有文档内容
*/ // */
void saveAll() const; // void saveAll() const;
void closeAll(); // void closeAll();
/** // /**
* @brief // * @brief 文档打开状态查询
* @param target // * @param target
* @return // * @return
*/ // */
bool activedContains(const QFileInfo &target) const; // bool activedContains(const QFileInfo &target) const;
/** // /**
* @brief // * @brief 获取文档内存实例
* @param child_view // * @param child_view
* @return // * @return
*/ // */
ContentPresent *queryTextComponent(const QWidget *child_view) const; // ContentPresent *queryTextComponent(const QWidget *child_view) const;
/** // /**
* @brief // * @brief 获取文档内存实例
* @param target // * @param target
* @return // * @return
*/ // */
ContentPresent *queryTextComponent(const QFileInfo &target) const; // ContentPresent *queryTextComponent(const QFileInfo &target) const;
/** // /**
* @brief // * @brief 关闭文档内存实例,关闭之前保存内容
* @param target // * @param target
*/ // */
void closeTextComponent(const QFileInfo &target); // void closeTextComponent(const QFileInfo &target);
/** // /**
* @brief // * @brief 打开指定路径的文档
* @param src // * @param src
* @param name // * @param name
*/ // */
void openTextDocument(const QString &src, const QString &name); // void openTextDocument(const QString &src, const QString &name);
void addPerceptionList(ContentPresent *ins, SensitiveType type = SensitiveType::CompileAtChanged); // void addPerceptionList(ContentPresent *ins, SensitiveType type = SensitiveType::CompileAtChanged);
void addProcTrigger(std::function<void()> exc); // void addProcTrigger(std::function<void()> exc);
private: // private:
Core::AppCore *const host_core; // Core::AppCore *const host_core;
MainWindow *const views_holder; // MainWindow *const views_holder;
StoryTool *const make_core; // StoryTool *const make_core;
QHash<QString, ContentPresent*> sourcecode_map; // QHash<QString, ContentPresent*> sourcecode_map;
QHash<QString, ContentPresent*> plaintext_map; // QHash<QString, ContentPresent*> plaintext_map;
QList<std::function<void()>> trigger_list; // QList<std::function<void()>> 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 #endif // DOCSMANAGER_H

View File

@ -29,6 +29,8 @@ SOURCES += \
mainwindow.cpp \ mainwindow.cpp \
manager_docs.cpp \ manager_docs.cpp \
messagepresent.cpp \ messagepresent.cpp \
projectpresent.cpp \
route.cpp \
srcedit_defaulttext.cpp \ srcedit_defaulttext.cpp \
srcedit_storyboard.cpp \ srcedit_storyboard.cpp \
srcedit_storychain.cpp \ srcedit_storychain.cpp \
@ -54,6 +56,8 @@ HEADERS += \
manager_docs.h \ manager_docs.h \
messagepresent.h \ messagepresent.h \
opstream.h \ opstream.h \
projectpresent.h \
route.h \
srcedit_defaulttext.h \ srcedit_defaulttext.h \
srcedit_storyboard.h \ srcedit_storyboard.h \
srcedit_storychain.h \ srcedit_storychain.h \

View File

@ -21,7 +21,7 @@ using namespace MakeTools;
AppCore::AppCore(MainWindow *win, bool record, QObject *parent) AppCore::AppCore(MainWindow *win, bool record, QObject *parent)
: QObject(parent), disp_core(new Schedule::CommandsDispatcher(QDir::home(), record)), : QObject(parent), disp_core(new Schedule::CommandsDispatcher(QDir::home(), record)),
views_holder(win), global_config(new Config::XMLConfig(this)), 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")); global_config->loadFile(QDir(QApplication::applicationDirPath()).filePath(".software.xml"));
@ -118,11 +118,16 @@ MakeTools::StoryTool *AppCore::getMakeCore() const
return makes_core; 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;
//}

View File

@ -46,7 +46,7 @@ namespace Core {
/** /**
* @brief * @brief
*/ */
class AppCore : public QObject class AppCore : public QObject, public Schedule::AccessibleObject
{ {
public: public:
Schedule::CommandsDispatcher *const disp_core; Schedule::CommandsDispatcher *const disp_core;
@ -79,8 +79,6 @@ namespace Core {
MakeTools::StoryTool *getMakeCore() const; MakeTools::StoryTool *getMakeCore() const;
MakeTools::DocsManager *getDocsManager() const;
private: private:
MainWindow *const views_holder; MainWindow *const views_holder;
Config::Configration *const global_config; Config::Configration *const global_config;
@ -90,7 +88,11 @@ namespace Core {
MakeTools::StoryTool *const makes_core; MakeTools::StoryTool *const makes_core;
MakeTools::DocsManager *const docs_manager; // MakeTools::DocsManager *const docs_manager;
// AccessibleObject interface
public:
virtual QString name() const override;
}; };
} }

View File

@ -1,13 +1,16 @@
#include "command_list.h" #include "command_list.h"
#include "manager_docs.h" #include "manager_docs.h"
#include "route.h"
#include "DocsManager.h"
using namespace CommandList; using namespace CommandList;
using namespace Components; using namespace Components;
using namespace Core;
using namespace MakeTools;
NewPackage::NewPackage(const QList<QString> &names) NewPackage::NewPackage(const QString &path_string)
: sequence(names)
{ {
sequence = path_string.split("/");
} }
QString NewPackage::name() const QString NewPackage::name() const
@ -15,20 +18,303 @@ QString NewPackage::name() const
return NAME(NewPackage); return NAME(NewPackage);
} }
void NewPackage::run(Schedule::CommandsDispatcher *core) void NewPackage::run(Schedule::CommandsDispatcher *core) const
{ {
auto vmgr = core->get<DocumentManager> auto vmgr = core->get<DocumentsManager>(NAME(DocumentsManager));
(NAME(DocumentManager)); vmgr->newPackage(Route::collect(sequence));
vmgr->newPackage(sequence);
} }
QString NewPackage::toText() const QString NewPackage::toText() const
{ {
return QStringList(sequence).join(":"); return QStringList(sequence).join("/");
} }
void NewPackage::fromText(const QString &line) 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<DocumentsManager>(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<DocumentsManager>(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<DocumentsManager>(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<DocumentsManager>(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<DocumentsManager>(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<DocumentsManager>(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<DocumentsManager>(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<QString> &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<AppCore>(NAME(AppCore));
auto chain_ins = core_ins->parseCore()->queryStoryChain(jump_path[0]).first();
auto vmgr = core->get<DocumentsManager>(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<QString> &chain_path)
: chain_path(chain_path)
{
}
QString StorychainDetailShow::name() const
{
return NAME(StorychainDetailShow);
}
void StorychainDetailShow::run(Schedule::CommandsDispatcher *core) const
{
auto backend = core->get<StorychainsPresentModel>(NAME(StorychainsPresentModel));
backend->showDetails(chain_path);
}
QString StorychainDetailShow::toText() const
{
return chain_path.join("/");
}
void StorychainDetailShow::fromText(const QString &line)
{
chain_path = line.split("/");
}

View File

@ -1,25 +1,155 @@
#ifndef COMMAND_LIST_H #ifndef COMMAND_LIST_H
#define COMMAND_LIST_H #define COMMAND_LIST_H
#include "route.h"
#include <commandsdispatcher.h> #include <commandsdispatcher.h>
namespace CommandList { namespace CommandList {
class NewPackage : public Schedule::GeCommand class NewProject : public Schedule::GeCommand {
{
public: public:
NewPackage(const QList<QString> &names); NewProject(const QDir &dir, const QString &name);
// GeCommand interface // GeCommand interface
public: public:
virtual QString name() const override; 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:
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 QString toText() const override;
virtual void fromText(const QString &line) override; virtual void fromText(const QString &line) override;
private: private:
QList<QString> sequence; QList<QString> sequence;
}; };
} class NewFile : public Schedule::GeCommand {
public:
NewFile(const Core::Route &group, const QString &name,
const QString &suffix);
private:
QList<QString> 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<QString> 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<QString> &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<QString> chain_path;
};
class StorychainJumpTo : public Schedule::GeCommand {
public:
StorychainJumpTo(const QList<QString> &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<QString> jump_path;
};
} // namespace CommandList
#endif // COMMAND_LIST_H #endif // COMMAND_LIST_H

View File

@ -1,5 +1,6 @@
#include "fragmentsorderview.h" #include "fragmentsorderview.h"
#include "DocsManager.h" #include "DocsManager.h"
#include "manager_docs.h"
#include <comdef.h> #include <comdef.h>
#include <StoryUnitDocumentParser.h> #include <StoryUnitDocumentParser.h>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -52,6 +53,10 @@ void FragmentsOrderView::double_click(const QModelIndex &index)
auto unit_ins = this->core_ins->parseCore()->queryStoryUnit(path[0]).first(); auto unit_ins = this->core_ins->parseCore()->queryStoryUnit(path[0]).first();
auto unit_doc = unit_ins->doc(); auto unit_doc = unit_ins->doc();
auto vmgr = this->core_ins->disp_core->get<DocumentsManager>(NAME(DocumentsManager));
index = vmgr->converter(QFileInfo())
this->core_ins->getDocsManager()->openTextDocument(unit_doc->filePath(), unit_doc->docName()); this->core_ins->getDocsManager()->openTextDocument(unit_doc->filePath(), unit_doc->docName());
auto present = this->core_ins->getDocsManager()->queryTextComponent(QFileInfo(unit_doc->filePath())); 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);
}

View File

@ -6,10 +6,11 @@
#include <QWidget> #include <QWidget>
#include <libParse.h> #include <libParse.h>
#include "appcore.h" #include "appcore.h"
#include <commandsdispatcher.h>
namespace Components { namespace Components {
class FragmentsOrderView : public QWidget class FragmentsOrderView : public QWidget, public Schedule::AccessibleObject
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -24,6 +25,10 @@ namespace Components {
QTableView *const table_view; QTableView *const table_view;
QStandardItemModel *const table_base; QStandardItemModel *const table_base;
// AccessibleObject interface
public:
virtual QString name() const override;
}; };
} }

View File

@ -21,12 +21,15 @@
#include <QList> #include <QList>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "command_list.h"
using namespace Project; using namespace Project;
using namespace MakeTools; using namespace MakeTools;
using namespace Parse::Result; using namespace Parse::Result;
using namespace Components; using namespace Components;
using namespace Core; using namespace Core;
using namespace Tools; using namespace Tools;
using namespace CommandList;
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), : QMainWindow(parent),
@ -39,11 +42,11 @@ MainWindow::MainWindow(QWidget *parent)
center_funcs(new QTabWidget(this)), center_funcs(new QTabWidget(this)),
bottom_funcs(new QTabWidget(this)), bottom_funcs(new QTabWidget(this)),
project_manager(new XMLProjectManager(this)), project_manager(new XMLProjectManager(this)),
current_projects(new QListView(this)), welcome_list(new QListView(this)),
project_view(new QTreeView(this)), project_present(new ProjectPresent(app_core, this)),
project_structure(new DocumentManager(app_core, project_manager, this)), docs_container(new DocumentsManager(app_core, project_manager, this)),
chains_view(new StoryChainsPresent(app_core, this)), chains_view(new StorychainsPresent(app_core, this)),
units_view(new StoryUnitsPresent(app_core, this)), units_view(new StoryunitsPresent(app_core, this)),
errors_present(new MessagePresent(app_core->getMakeCore(), this)), errors_present(new MessagePresent(app_core->getMakeCore(), this)),
boards_view(new StoryBoardsPresent(app_core, this)), boards_view(new StoryBoardsPresent(app_core, this)),
concept_view(new StoryConceptsPresent(app_core, this)), concept_view(new StoryConceptsPresent(app_core, this)),
@ -51,7 +54,9 @@ MainWindow::MainWindow(QWidget *parent)
{ {
QApplication::instance()->installEventFilter(this); QApplication::instance()->installEventFilter(this);
this->app_core->setCurrentProject(project_manager); 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); setMinimumSize(1000, 600);
setWindowTitle("提线木偶"); setWindowTitle("提线木偶");
@ -62,8 +67,6 @@ MainWindow::MainWindow(QWidget *parent)
boards_view->setVisible(false); boards_view->setVisible(false);
concept_view->setVisible(false); concept_view->setVisible(false);
fragments_order->setVisible(false); fragments_order->setVisible(false);
project_view->setVisible(false);
project_view->setModel(project_manager->model());
left_funcs->setVisible(false); left_funcs->setVisible(false);
right_funcs->setVisible(false); right_funcs->setVisible(false);
bottom_funcs->setVisible(false); bottom_funcs->setVisible(false);
@ -75,56 +78,71 @@ MainWindow::MainWindow(QWidget *parent)
statusBar()->addWidget(new QLabel("文本消息", this)); statusBar()->addWidget(new QLabel("文本消息", this));
auto mbar = menuBar(); auto mbar = menuBar();
// 项目菜单树 initial_menubar(mbar);
auto project = mbar->addMenu("项目");
auto pnew = project->addAction("新建路径", [this](){
auto packages = QInputDialog::getText(this, "输入包路径名称", "packagea#packageb#packagec");
if(packages == "")
return;
QList<QString> names;
QRegExp exp("([^#]+)"); setCentralWidget(this->vertical_split);
auto idx=0; this->vertical_split->addWidget(this->horizontal_split);
while ((idx = exp.indexIn(packages, idx)) != -1) { this->vertical_split->addWidget(bottom_funcs);
names << exp.capturedTexts()[1];
idx += names.last().length(); 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());
});
} }
project_manager->newPackage(names); MainWindow::~MainWindow()
}); {
sync_kernel->registerActionSync(pnew, [this]()->bool{return project_manager->isOpen();}); }
auto _xnew = project->addMenu("最后卷新建文件"); void MainWindow::initial_menubar(QMenuBar *mbar)
_xnew->addAction("小说章节"); {
_xnew->addSeparator(); // 项目菜单树
_xnew->addAction("发展脉络"); auto project = mbar->addMenu("项目");
_xnew->addAction("故事单元"); auto opnp = project->addAction("打开项目", [this](){
_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 file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)"); auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)");
if(file == "") if(file == "")
return; return;
project_manager->openProject(file); this->app_core->disp_core->postCommand(OpenProject(file));
build_internal(true); build_internal(true);});
}); sync_kernel->actionSync(opnp, [this]()->bool{return !project_manager->isOpen();});
auto newp = project->addAction("新建项目");
sync_kernel->registerActionSync(newp, [this]()->bool{return !project_manager->isOpen();}); auto newp = project->addAction("新建项目", [this](){
connect(newp, &QAction::triggered, [this](){
auto name = QInputDialog::getText(this, "输入项目名称", "项目名称"); auto name = QInputDialog::getText(this, "输入项目名称", "项目名称");
if(name == "") if(name == "")
return; return;
@ -132,53 +150,51 @@ MainWindow::MainWindow(QWidget *parent)
if(dir_path == "") if(dir_path == "")
return; return;
this->project_manager->newProject(dir_path, name); 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("关闭项目");
sync_kernel->registerActionSync(clsp, [this]()->bool{return project_manager->isOpen();}); auto clsp = project->addAction("关闭项目", [this](){
connect(clsp, &QAction::triggered, [this](){ this->app_core->disp_core->postCommand(CloseProject());
this->project_manager->closeProject(); this->refresh_views();});
this->app_core->getDocsManager()->closeAll(); sync_kernel->actionSync(clsp, [this]()->bool{return project_manager->isOpen();});
this->refresh_views();
});
project->addSeparator(); project->addSeparator();
auto pcfg = project->addAction("项目配置");
connect(pcfg, &QAction::triggered, [this](){
QDialog x(this);
auto layout = new QVBoxLayout(&x);
auto widget = new QTabWidget(&x); auto pnew = project->addAction("新建路径", [this](){
widget->setTabPosition(QTabWidget::West); auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:");
layout->addWidget(widget); 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(); auto _xnew = project->addMenu("新建文件");
// for(auto &es : exts){ auto types = docs_container->fileTypes();
// auto cp = es->getNewPanel(app_core->currentProject()->configraions()); for(auto &t : types){
// if(cp) _xnew->addAction(t, [this, &t](){
// widget->addTab(cp, es->extensionName()); auto name = QInputDialog::getText(this, "输入名称", "名称:");
// } if(name == "")
x.exec(); return;
});
sync_kernel->registerActionSync(pcfg, [this]()->bool{ return app_core->currentProject()->isOpen();}); auto idx = project_view->currentIndex();
auto scfg = project->addAction("软件配置"); if(!idx.isValid())
connect(scfg, &QAction::triggered, [this](){ idx = project_manager->model()->item(0)->index();
QDialog x(this);
auto layout = new QVBoxLayout(&x); auto group_path = docs_container->converter(idx);
this->app_core->disp_core->postCommand(NewFile(group_path, name, t));
auto widget = new QTabWidget(&x);
widget->setTabPosition(QTabWidget::West);
layout->addWidget(widget);
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();
}); });
}
sync_kernel->widgetSync(_xnew, [this]()->bool{return project_manager->isOpen();});
project->addSeparator(); 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("编辑"); auto edit = mbar->addMenu("编辑");
@ -228,15 +244,15 @@ MainWindow::MainWindow(QWidget *parent)
change->addAction("编辑视图"); change->addAction("编辑视图");
view->addSeparator(); view->addSeparator();
auto func = view->addMenu("功能视图"); auto func = view->addMenu("功能视图");
// 项目管理 // // 项目管理
{ // {
auto project_v = func->addAction("项目管理", [this](bool v){ // auto project_v = func->addAction("项目管理", [this](bool v){
toggle_widget_visible(v, left_funcs, project_structure, "项目管理"); // toggle_widget_visible(v, left_funcs, project_structure, "项目管理");
}); // });
project_v->setCheckable(true); // project_v->setCheckable(true);
sync_kernel->registerAutoRun([this]()->bool{return this->project_structure->isVisible();}, // sync_kernel->registerAutoRun([this]()->bool{return this->project_structure->isVisible();},
[project_v](bool v){ if(v != project_v->isChecked()) project_v->setChecked(v); }); // [project_v](bool v){ if(v != project_v->isChecked()) project_v->setChecked(v); });
} // }
func->addAction("引用统计"); func->addAction("引用统计");
func->addAction("脉络分蘖"); func->addAction("脉络分蘖");
// 编译信息 // 编译信息
@ -313,7 +329,7 @@ MainWindow::MainWindow(QWidget *parent)
auto build = tool->addAction("编译", [this](){ auto build = tool->addAction("编译", [this](){
this->build_internal(); 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("窗口"); auto window = mbar->addMenu("窗口");
@ -330,67 +346,6 @@ MainWindow::MainWindow(QWidget *parent)
sys->addAction("系统信息"); sys->addAction("系统信息");
sys->addSeparator(); sys->addSeparator();
sys->addAction("关于……"); 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<QFileInfo> 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) void MainWindow::contentViewAppend(QWidget *widget, const QString &name)
@ -426,30 +381,7 @@ void MainWindow::refresh_views()
void MainWindow::build_internal(bool all_from_disk) void MainWindow::build_internal(bool all_from_disk)
{ {
if(!all_from_disk) app_core->disp_core->postCommand(Build(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));
refresh_views(); refresh_views();
} }

View File

@ -18,6 +18,7 @@
#include "storyconceptspresent.h" #include "storyconceptspresent.h"
#include "fragmentsorderview.h" #include "fragmentsorderview.h"
#include "tools.h" #include "tools.h"
#include "projectpresent.h"
class MainWindow : public QMainWindow, public Components::PresentContainer class MainWindow : public QMainWindow, public Components::PresentContainer
{ {
@ -42,17 +43,19 @@ private:
Project::ProjectManager *const project_manager; Project::ProjectManager *const project_manager;
QListView *const current_projects; QListView *const welcome_list;
QTreeView *const project_view; Components::ProjectPresent *const project_present;
Components::DocumentManager *const project_structure; Components::DocumentsManager *const docs_container;
Components::StoryChainsPresent *const chains_view; Components::StorychainsPresent *const chains_view;
Components::StoryUnitsPresent *const units_view; Components::StoryunitsPresent *const units_view;
Components::MessagePresent *const errors_present; Components::MessagePresent *const errors_present;
Components::StoryBoardsPresent *const boards_view; Components::StoryBoardsPresent *const boards_view;
Components::StoryConceptsPresent *const concept_view; Components::StoryConceptsPresent *const concept_view;
Components::FragmentsOrderView *const fragments_order; Components::FragmentsOrderView *const fragments_order;
// 内部逻辑 =========================================== // 内部逻辑 ===========================================
void initial_menubar(QMenuBar *mbar);
void refresh_views(); void refresh_views();
void build_internal(bool all_from_disk = false); void build_internal(bool all_from_disk = false);

View File

@ -2,30 +2,27 @@
#include "DocsManager.h" #include "DocsManager.h"
using namespace Components; using namespace Components;
using namespace Core;
DocumentManager::DocumentManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con) DocumentsManager::DocumentsManager(AppCore *src, Project::ProjectManager *project, PresentContainer *con)
: rtcore(src), pjtins(project), front_end(con) {} : rtcore(src), pjtins(project), present_ui(con) {}
void DocumentManager::newPackage(const QString &path_str) Project::ProjectManager *DocumentsManager::projectManager() const
{ {
QList<QString> path_list; return pjtins;
QRegExp exp("/([^/]+)");
auto offset = -1;
while ((offset = exp.indexIn(path_str, offset + 1)) != -1) {
path_list << exp.capturedTexts()[1].trimmed();
} }
pjtins->newPackage(path_list); void DocumentsManager::newPackage(const Route &link)
}
void DocumentManager::newPackage(const QString &group_path, const QString &name)
{ {
QString path = group_path + "/" + name; pjtins->newPackage(link.links());
newPackage(path);
} }
QList<QString> DocumentManager::fileTypes() const void DocumentsManager::newPackage(const Route &group, const QString &name)
{
newPackage(group|name);
}
QList<QString> DocumentsManager::fileTypes() const
{ {
QList<QString> all_types; QList<QString> all_types;
for(auto &it : rtcore->allViews()) for(auto &it : rtcore->allViews())
@ -33,7 +30,7 @@ QList<QString> DocumentManager::fileTypes() const
return all_types; 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); auto list = rtcore->extensions(suffix);
QDir root = pjtins->projectDir(); 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<QString> path_list; auto path_list = path.links();
QRegExp exp("/([^/]+)");
auto offset = -1;
while ((offset = exp.indexIn(path, offset + 1)) != -1) {
path_list << exp.capturedTexts()[1].trimmed();
}
auto itor_node = pjtins->model()->item(0); auto itor_node = pjtins->model()->item(0);
while (path_list.size()) { while (path_list.size()) {
auto item = path_list.takeAt(0); auto item = path_list.takeAt(0);
@ -71,108 +61,170 @@ QModelIndex DocumentManager::converter(const QString &path)
} }
if(idx == itor_node->rowCount()) if(idx == itor_node->rowCount())
throw new SimpleException("指定的path非法"+path); throw new SimpleException("指定的path非法/"+ path.links().join("/"));
} }
return itor_node->index(); 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 item = pjtins->model()->itemFromIndex(index);
auto pjt_node = pjtins->model()->item(0); auto pjt_node = pjtins->model()->item(0);
while (item != pjt_node) { while (item != pjt_node) {
path.prepend("/" + item->text().trimmed()); path = path | item->text().trimmed();
item = item->parent(); item = item->parent();
} }
return path; 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 activie_file_nodes = actives();
auto file_nodes = pjtins->filesGather(node); auto file_nodes = pjtins->filesGather(node_mindex);
for(auto &n : file_nodes) QList<Route> path_buff;
if(activie_file_nodes.contains(converter(n))) for(auto &n : file_nodes){
close(QList<QString>()<<converter(n)); auto target = converter(n);
if(activie_file_nodes.contains(target))
pjtins->deleteTarget(node); path_buff << target;
} }
void DocumentManager::renameNode(const QString &node_path, const QString &name) close(path_buff);
pjtins->deleteTarget(node_mindex);
}
void DocumentsManager::renameNode(const Route &node_path, const QString &name)
{ {
pjtins->rename(converter(node_path), name); pjtins->rename(converter(node_path), name);
auto activie_file_nodes = actives(); auto activie_file_nodes = actives();
if(activie_file_nodes.contains(node_path)){ if(activie_file_nodes.contains(node_path)){
auto inst = activePresentOf(node_path); auto inst = activePresentOf(node_path);
inst->rename(name); inst->applySetting(name, rtcore);
front_end->active(inst); 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()) if(!info.isFile())
throw new SimpleException("打开的节点不是文件节点"); throw new SimpleException("打开的节点不是文件节点");
if(actives().contains(file_node)){ auto path_union = path_node.links().join("/");
front_end->active(doc_openning[file_node]); if(actives().contains(path_node)){
present_ui->active(doc_openning[path_union]);
return; return;
} }
auto list = rtcore->extensions(info.suffix()); auto list = rtcore->extensions(info.suffix());
auto nview = list.first()->newInst(); auto nview = list.first()->newInst();
nview->load(info); nview->load(info);
doc_openning[file_node] = nview; doc_openning[path_union] = nview;
front_end->append(nview); present_ui->append(nview);
front_end->active(nview); present_ui->active(nview);
} }
QList<QString> DocumentManager::actives() const QList<Route> DocumentsManager::actives() const
{ {
return doc_openning.keys(); QList<Route> 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<QString> &docs) void DocumentsManager::save(const QList<Route> &docs_path)
{ {
auto actives = this->actives(); auto actives_paths = this->actives();
for(auto &idx : docs) for(auto &idx_path : docs_path)
if(actives.contains(idx)) if(actives_paths.contains(idx_path))
activePresentOf(idx)->saveAs(); activePresentOf(idx_path)->saveAs();
} }
void DocumentManager::close(const QList<QString> &doc_paths) void DocumentsManager::close(const QList<Route> &doc_paths)
{ {
auto actives = this->actives(); auto actives = this->actives();
for(auto &idx : doc_paths) for(auto &idx : doc_paths)
if(actives.contains(idx)){ if(actives.contains(idx)){
auto inst = activePresentOf(idx); auto inst = activePresentOf(idx);
inst->saveAs(); inst->saveAs();
front_end->remove(inst); present_ui->remove(inst);
delete 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);
} }

View File

@ -2,6 +2,7 @@
#define VISUABLE_PROJECT_CONTROLLER #define VISUABLE_PROJECT_CONTROLLER
#include "appcore.h" #include "appcore.h"
#include "route.h"
#include <QTreeView> #include <QTreeView>
#include <QWidget> #include <QWidget>
@ -36,25 +37,26 @@ namespace Components {
/** /**
* @brief * @brief
*/ */
class DocumentManager : public Schedule::AccessibleObject class DocumentsManager : public Schedule::AccessibleObject
{ {
Q_OBJECT
public: public:
DocumentManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con); DocumentsManager(Core::AppCore *src, Project::ProjectManager *project, PresentContainer *con);
virtual ~DocumentManager() = default; virtual ~DocumentsManager() = default;
Project::ProjectManager* projectManager() const;
/** /**
* @brief * @brief
* @param path [/x_name]+ * @param path [/x_name]+
*/ */
void newPackage(const QString &path_str); void newPackage(const Core::Route &link);
/** /**
* @brief Index * @brief Index
* @param group * @param group
* @param name * @param name
* @throw SimpleException * @throw SimpleException
*/ */
void newPackage(const QString &group_path, const QString &name); void newPackage(const Core::Route &group, const QString &name);
/** /**
* @brief * @brief
@ -68,17 +70,17 @@ namespace Components {
* @param suffix * @param suffix
* @throw SimpleException * @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); QModelIndex converter(const Core::Route &path);
QString converter(const QModelIndex &index); Core::Route converter(const QModelIndex &index);
/** /**
* @brief * @brief
* @param node * @param node
* @throw SimpleException * @throw SimpleException
*/ */
void removeNode(const QString &node_path); void removeNode(const Core::Route &node_path);
/** /**
* @brief * @brief
@ -86,52 +88,52 @@ namespace Components {
* @param name * @param name
* @throw SimpleException * @throw SimpleException
*/ */
void renameNode(const QString &node_path, const QString &name); void renameNode(const Core::Route &node_path, const QString &name);
/** /**
* @brief * @brief
* @param file_node * @param path_node
* @throw SimpleException * @throw SimpleException
*/ */
void openFile(const QString &file_node); void openFile(const Core::Route &path_node);
/** /**
* @brief * @brief
* @return * @return
*/ */
QList<QString> actives() const; QList<Core::Route> actives() const;
/** /**
* @brief null * @brief null
* @param node * @param node
* @return null或打开的展示实例 * @return null或打开的展示实例
*/ */
MakeTools::ContentPresent* activePresentOf(const QString &node_path); MakeTools::ContentPresent* activePresentOf(const Core::Route &node_path);
/** /**
* @brief * @brief
* @param docs * @param docs
*/ */
void save(const QList<QString> &docs = QList<QString>()); void save(const QList<Core::Route> &docs = QList<Core::Route>());
/** /**
* @brief * @brief
* @param docs * @param docs
*/ */
void close(const QList<QString> &doc_paths = QList<QString>()); void close(const QList<Core::Route> &doc_paths = QList<Core::Route>());
/** /**
* @brief ModelIndex * @brief ModelIndex
* @param ins * @param ins
*/ */
QString pathOf(MakeTools::ContentPresent *ins) const; Core::Route pathOf(MakeTools::ContentPresent *ins) const;
Core::Route pathOf(const QModelIndex &p) const;
/** /**
* @brief * @brief
* @param target * @param disk
* @return
*/ */
QModelIndex pathOf(const QFileInfo &target) const; void build(bool disk);
// AccessibleObject interface // AccessibleObject interface
public: public:
@ -140,7 +142,7 @@ namespace Components {
private: private:
Core::AppCore *const rtcore; Core::AppCore *const rtcore;
Project::ProjectManager *pjtins; Project::ProjectManager *pjtins;
PresentContainer *front_end; PresentContainer *present_ui;
QHash<QString, MakeTools::ContentPresent*> doc_openning; QHash<QString, MakeTools::ContentPresent*> doc_openning;
}; };

View File

@ -70,13 +70,22 @@ namespace Operate {
class OpStream class OpStream
{ {
public: public:
/**
* @brief
* @param peak_proc function<V(count, idx)>
*/
OpStream(std::function<ValueType(int &cnt, int idx)> peak_proc) OpStream(std::function<ValueType(int &cnt, int idx)> peak_proc)
{ {
int count = 0, index = 0; int count = 0, index = 0;
ValueType one = peak_proc(count, index); ValueType one = peak_proc(count, index);
for(; index < count; ++index) for(; index < count; ++index)
source_store << peak_proc(count, index); source_store << peak_proc(count, index);
} }
/**
* @brief
* @param source
*/
OpStream(QList<ValueType> source) OpStream(QList<ValueType> source)
: source_store(source){} : source_store(source){}

View File

@ -1,5 +1,7 @@
#include "storychainspresent.h" #include "storychainspresent.h"
#include "DocsManager.h" #include "DocsManager.h"
#include "manager_docs.h"
#include "command_list.h"
#include <QSplitter> #include <QSplitter>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -8,35 +10,44 @@ using namespace Components;
using namespace Parse; using namespace Parse;
using namespace Parse::Result; using namespace Parse::Result;
using namespace Tools; 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)), StorychainsPresentModel::StorychainsPresentModel(Core::AppCore *core)
sync_tools(new ModelSyncs<DesNode*>( :core_ins(core),
model_base, model_base(new QStandardItemModel),
[](DesNode *const &d, QStandardItem *it)->bool details_base(new QTextDocument)
{ return static_cast<NamedNode*>(d)->name().first() == it->text();},
[](DesNode *const &d, QStandardItem *it)
{ it->setText(static_cast<NamedNode*>(d)->name().first()); }))
{ {
tree_view->setModel(model_base); sync_tools = new ModelSyncs<DesNode*>(
tree_view->setHeaderHidden(true); model_base,
[](DesNode *const &d, QStandardItem *it)->bool {
auto layoutx = new QVBoxLayout(this); return static_cast<NamedNode*>(d)->name().first() == it->text();},
layoutx->setMargin(0); [](DesNode *const &d, QStandardItem *it) {
auto split = new QSplitter(Qt::Vertical, this); it->setText(static_cast<NamedNode*>(d)->name().first()); });
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);
} }
void StoryChainsPresent::refresh() StorychainsPresentModel::~StorychainsPresentModel()
{ {
sync_tools->presentSync([this](DesNode *p)->QList<DesNode*>{ 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){ if(p){
QList<DesNode*> retv; QList<DesNode*> retv;
for(auto &point : p->children()){ for(auto &point : p->children()){
@ -51,20 +62,51 @@ void StoryChainsPresent::refresh()
}); });
} }
void StoryChainsPresent::action_details_show(const QModelIndex &curr) using namespace Operate;
void StorychainsPresentModel::showDetails(const QList<QString> &chain_path)
{ {
if(!curr.isValid()) // 获取第一级初始集合
return; QList<QStandardItem*> item_list = \
OpStream<QStandardItem*>([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<QStandardItem*>(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<QStandardItem*>([&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){ if(item->parent() == nullptr){
auto node = core_ins->parseCore()->queryStoryChain(item->text()); auto node = core_ins->parseCore()->queryStoryChain(item->text());
auto children = node.first()->children(); auto children = node.first()->children();
for(auto &it : children){ for(auto &it : children){
if(it->typeValue() != NODE_STORYPOINT){ 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(); auto children = point.first()->children();
for(auto &it : children){ for(auto &it : children){
details_show->appendPlainText(it->toString()); text_lines += it->toString() + "\n";
}
} }
} }
void StoryChainsPresent::click_to(const QModelIndex &curr) details_base->setPlainText(text_lines);
}
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<StorychainsPresentModel>(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()) if(!curr.isValid())
return; return;
auto pnode = this->model_base->itemFromIndex(curr);
QList<QString> path; QList<QString> path;
while (pnode) { while (true) {
path.insert(0, pnode->text()); auto node = curr.data().toString();
pnode = pnode->parent();
if(node.isEmpty())
break;
else
path << node;
} }
auto chain_ins = this->core_ins->parseCore()->queryStoryChain(path[0]).first(); disp_core->postCommand(StorychainJumpTo(path));
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()));
if(path.size()){
present->jumpTo(path);
} }
void StorychainsPresent::detail_show(const QModelIndex &curr)
{
if(!curr.isValid())
return;
QList<QString> 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)

View File

@ -12,26 +12,54 @@
namespace Components { namespace Components {
class StoryChainsPresent : public QWidget /**
* @brief
*/
class StorychainsPresentModel : public Schedule::AccessibleObject
{ {
Q_OBJECT
public: 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<QString> &chain_path);
// AccessibleObject interface
public:
virtual QString name() const override;
private: private:
Core::AppCore *const core_ins; Core::AppCore *const core_ins;
QStandardItemModel *const model_base; QStandardItemModel *const model_base;
QTextDocument *const details_base;
Tools::ModelSyncs<Parse::Result::DesNode*> *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; QTreeView *const tree_view;
QPlainTextEdit *const details_show; QPlainTextEdit *const details_show;
Tools::ModelSyncs<Parse::Result::DesNode*> *const sync_tools;
void action_details_show(const QModelIndex &curr); void jump_to(const QModelIndex &curr);
void detail_show(const QModelIndex &curr);
void click_to(const QModelIndex &curr);
}; };
} }

View File

@ -7,43 +7,37 @@
using namespace Components; using namespace Components;
using namespace Parse::Result; using namespace Parse::Result;
StoryUnitsPresent::StoryUnitsPresent(Core::AppCore *core, QWidget *parent) StoryunitsPresentModel::StoryunitsPresentModel(Core::AppCore *core)
: QWidget(parent), core_ins(core), : core_ins(core), model_ins(new QStandardItemModel),
model_ins(new QStandardItemModel(this)), details_backend(new QTextDocument) {}
units_view(new QTreeView(this)),
details_show(new QPlainTextEdit(this))
{
units_view->setHeaderHidden(true);
auto layout = new QVBoxLayout(this); StoryunitsPresentModel::~StoryunitsPresentModel() {
layout->setMargin(0); delete model_ins;
delete details_backend;
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);
} }
void StoryUnitsPresent::refresh() QStandardItemModel *StoryunitsPresentModel::treeModel() const {
{ return model_ins;
}
QTextDocument *StoryunitsPresentModel::detailsBackend() const {
return details_backend;
}
void StoryunitsPresentModel::refresh() {
model_ins->clear(); model_ins->clear();
auto units = core_ins->parseCore()->allStoryUnits(); auto units = core_ins->parseCore()->allStoryUnits();
for (auto &unit : units) { for (auto &unit : units) {
auto unit_node = new QStandardItem(static_cast<NamedNode*>(unit)->name()[0]); auto unit_node =
new QStandardItem(static_cast<NamedNode *>(unit)->name()[0]);
unit_node->setEditable(false); unit_node->setEditable(false);
model_ins->appendRow(unit_node); model_ins->appendRow(unit_node);
auto children = unit->children(); auto children = unit->children();
for (auto &frag : children) { for (auto &frag : children) {
if (frag->typeValue() == NODE_STORYFRAGMENT) { if (frag->typeValue() == NODE_STORYFRAGMENT) {
auto frag_node = new QStandardItem(static_cast<NamedNode*>(frag)->name()[0]); auto frag_node = new QStandardItem(
static_cast<NamedNode *>(frag)->name()[0]);
frag_node->setEditable(false); frag_node->setEditable(false);
unit_node->appendRow(frag_node); unit_node->appendRow(frag_node);
} }
@ -51,8 +45,7 @@ void StoryUnitsPresent::refresh()
} }
} }
void StoryUnitsPresent::show_node_description(const QModelIndex &curr) void StoryunitsPresentModel::show_node_description(const QModelIndex &curr) {
{
if (!curr.isValid()) if (!curr.isValid())
return; return;
@ -67,10 +60,11 @@ void StoryUnitsPresent::show_node_description(const QModelIndex &curr)
details_show->appendPlainText(it->toString()); details_show->appendPlainText(it->toString());
} }
} }
} } else {
else{ auto node =
auto node = core_ins->parseCore()->queryStoryUnit(item->parent()->text()); core_ins->parseCore()->queryStoryUnit(item->parent()->text());
auto point = core_ins->parseCore()->queryStoryFragment(node.first(), item->text()); auto point = core_ins->parseCore()->queryStoryFragment(node.first(),
item->text());
auto children = point.first()->children(); auto children = point.first()->children();
for (auto &it : children) { for (auto &it : children) {
@ -79,8 +73,7 @@ void StoryUnitsPresent::show_node_description(const QModelIndex &curr)
} }
} }
void StoryUnitsPresent::click_to(const QModelIndex &curr) void StoryunitsPresentModel::click_to(const QModelIndex &curr) {
{
if (!curr.isValid()) if (!curr.isValid())
return; return;
@ -91,25 +84,42 @@ void StoryUnitsPresent::click_to(const QModelIndex &curr)
pnode = pnode->parent(); 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(); auto chain_doc = unit_ins->doc();
this->core_ins->getDocsManager()->openTextDocument(chain_doc->filePath(), chain_doc->docName()); this->core_ins->getDocsManager()->openTextDocument(chain_doc->filePath(),
auto present = this->core_ins->getDocsManager()->queryTextComponent(QFileInfo(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); 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<StoryunitsPresentModel>(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); }

View File

@ -12,26 +12,46 @@
namespace Components { namespace Components {
class StoryUnitsPresent : public QWidget class StoryunitsPresentModel : public Schedule::AccessibleObject {
{
Q_OBJECT
public: public:
explicit StoryUnitsPresent(Core::AppCore *core, QWidget *parent = nullptr); StoryunitsPresentModel(Core::AppCore *core);
virtual ~StoryunitsPresentModel();
QStandardItemModel *treeModel() const;
QTextDocument *detailsBackend() const;
void refresh(); 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; Core::AppCore *const core_ins;
QStandardItemModel *const model_ins; QStandardItemModel *const model_ins;
QTreeView *const units_view; QTextDocument *const details_backend;
QPlainTextEdit *const details_show;
void show_node_description(const QModelIndex &curr);
void click_to(const QModelIndex &curr);
}; };
}
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 #endif // STORYUNITSPRESENT_H

View File

@ -18,12 +18,12 @@ void Run::exec()
StatusSyncCore::StatusSyncCore(QObject *p) StatusSyncCore::StatusSyncCore(QObject *p)
: QObject(p){} : QObject(p){}
void StatusSyncCore::registerWidgetSync(QWidget *tar, std::function<bool ()> proc) void StatusSyncCore::widgetSync(QWidget *tar, std::function<bool ()> proc)
{ {
widget_trigger_map[tar] = proc; widget_trigger_map[tar] = proc;
} }
void StatusSyncCore::registerActionSync(QAction *tar, std::function<bool ()> proc) void StatusSyncCore::actionSync(QAction *tar, std::function<bool ()> proc)
{ {
action_trigger_map[tar] = proc; action_trigger_map[tar] = proc;
} }

View File

@ -27,8 +27,8 @@ namespace Tools {
virtual ~StatusSyncCore() = default; virtual ~StatusSyncCore() = default;
void registerWidgetSync(QWidget* tar, std::function<bool()> proc); void widgetSync(QWidget* tar, std::function<bool()> proc);
void registerActionSync(QAction* tar, std::function<bool()> proc); void actionSync(QAction* tar, std::function<bool()> proc);
void registerAutoRun(std::function<bool()> judge, std::function<void(bool)> exec); void registerAutoRun(std::function<bool()> judge, std::function<void(bool)> exec);
Run* registerManualRun(std::function<bool()> judge, std::function<void (bool)> exec); Run* registerManualRun(std::function<bool()> judge, std::function<void (bool)> exec);
void sync(); void sync();