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();
}
void CommandsDispatcher::postCommand(GeCommand &c)
void CommandsDispatcher::postCommand(const GeCommand &c)
{
if(!command_types.contains(c.name()))
throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + c.name());

View File

@ -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

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<data>
<variable>EnvironmentId</variable>

View File

@ -72,9 +72,10 @@ namespace Operate {
public:
OpStream(std::function<ValueType(int &cnt, int idx)> 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<ValueType> source)

View File

@ -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<CompileFeature*>(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<CompileFeature*>(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<void ()> exc)
{
this->trigger_list << exc;
}
//void DocsManager::addProcTrigger(std::function<void ()> 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<CompileFeature*>(view);
make_core->compileSource(QFileInfo(file_path), cins->getText(), doc_name);
// auto view = this->sourcecode_map[file_path];
// auto cins = dynamic_cast<CompileFeature*>(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)

View File

@ -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<void()> exc);
// void addPerceptionList(ContentPresent *ins, SensitiveType type = SensitiveType::CompileAtChanged);
// void addProcTrigger(std::function<void()> exc);
private:
Core::AppCore *const host_core;
MainWindow *const views_holder;
StoryTool *const make_core;
QHash<QString, ContentPresent*> sourcecode_map;
QHash<QString, ContentPresent*> plaintext_map;
QList<std::function<void()>> trigger_list;
// private:
// Core::AppCore *const host_core;
// MainWindow *const views_holder;
// StoryTool *const make_core;
// QHash<QString, ContentPresent*> sourcecode_map;
// QHash<QString, ContentPresent*> plaintext_map;
// 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

View File

@ -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 \

View File

@ -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;
//}

View File

@ -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;
};
}

View File

@ -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<QString> &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<DocumentManager>
(NAME(DocumentManager));
vmgr->newPackage(sequence);
auto vmgr = core->get<DocumentsManager>(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<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
#define COMMAND_LIST_H
#include "route.h"
#include <commandsdispatcher.h>
namespace CommandList {
class NewPackage : public Schedule::GeCommand
{
public:
NewPackage(const QList<QString> &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<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

View File

@ -1,5 +1,6 @@
#include "fragmentsorderview.h"
#include "DocsManager.h"
#include "manager_docs.h"
#include <comdef.h>
#include <StoryUnitDocumentParser.h>
#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_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());
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 <libParse.h>
#include "appcore.h"
#include <commandsdispatcher.h>
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;
};
}

View File

@ -21,12 +21,15 @@
#include <QList>
#include <QVBoxLayout>
#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<QString> 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<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)
@ -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();
}

View File

@ -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);

View File

@ -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<QString> 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<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;
for(auto &it : rtcore->allViews())
@ -33,7 +30,7 @@ QList<QString> 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<QString> 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<QString>()<<converter(n));
QList<Route> 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<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();
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<QString> &doc_paths)
void DocumentsManager::close(const QList<Route> &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);
}

View File

@ -2,6 +2,7 @@
#define VISUABLE_PROJECT_CONTROLLER
#include "appcore.h"
#include "route.h"
#include <QTreeView>
#include <QWidget>
@ -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<QString> actives() const;
QList<Core::Route> 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<QString> &docs = QList<QString>());
void save(const QList<Core::Route> &docs = QList<Core::Route>());
/**
* @brief
* @param docs
*/
void close(const QList<QString> &doc_paths = QList<QString>());
void close(const QList<Core::Route> &doc_paths = QList<Core::Route>());
/**
* @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<QString, MakeTools::ContentPresent*> doc_openning;
};

View File

@ -70,13 +70,22 @@ namespace Operate {
class OpStream
{
public:
/**
* @brief
* @param peak_proc function<V(count, idx)>
*/
OpStream(std::function<ValueType(int &cnt, int idx)> 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<ValueType> source)
: source_store(source){}

View File

@ -1,5 +1,7 @@
#include "storychainspresent.h"
#include "DocsManager.h"
#include "manager_docs.h"
#include "command_list.h"
#include <QSplitter>
#include <QVBoxLayout>
@ -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<DesNode*>(
model_base,
[](DesNode *const &d, QStandardItem *it)->bool
{ return static_cast<NamedNode*>(d)->name().first() == it->text();},
[](DesNode *const &d, QStandardItem *it)
{ it->setText(static_cast<NamedNode*>(d)->name().first()); }))
StorychainsPresentModel::StorychainsPresentModel(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<DesNode*>(
model_base,
[](DesNode *const &d, QStandardItem *it)->bool {
return static_cast<NamedNode*>(d)->name().first() == it->text();},
[](DesNode *const &d, QStandardItem *it) {
it->setText(static_cast<NamedNode*>(d)->name().first()); });
}
void StoryChainsPresent::refresh()
StorychainsPresentModel::~StorychainsPresentModel()
{
sync_tools->presentSync([this](DesNode *p)->QList<DesNode*>{
if(p){
QList<DesNode*> retv;
for(auto &point : p->children()){
if(point->typeValue() == NODE_STORYPOINT){
retv << point;
delete model_base;
delete details_base;
delete sync_tools;
}
QStandardItemModel *StorychainsPresentModel::treeModel() const
{
return model_base;
}
QTextDocument *const StorychainsPresentModel::detailsBackend() const
{
return details_base;
}
void StorychainsPresentModel::refreshTree()
{
sync_tools->presentSync(
[this](DesNode *p)->QList<DesNode*>{
if(p){
QList<DesNode*> retv;
for(auto &point : p->children()){
if(point->typeValue() == NODE_STORYPOINT){
retv << point;
}
}
return retv;
}
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<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){
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<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())
return;
auto pnode = this->model_base->itemFromIndex(curr);
QList<QString> 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<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 {
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<QString> &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<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;
QPlainTextEdit *const details_show;
Tools::ModelSyncs<Parse::Result::DesNode*> *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);
};
}

View File

@ -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<NamedNode*>(unit)->name()[0]);
for (auto &unit : units) {
auto unit_node =
new QStandardItem(static_cast<NamedNode *>(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<NamedNode*>(frag)->name()[0]);
for (auto &frag : children) {
if (frag->typeValue() == NODE_STORYFRAGMENT) {
auto frag_node = new QStandardItem(
static_cast<NamedNode *>(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<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 {
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

View File

@ -18,12 +18,12 @@ void Run::exec()
StatusSyncCore::StatusSyncCore(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;
}
void StatusSyncCore::registerActionSync(QAction *tar, std::function<bool ()> proc)
void StatusSyncCore::actionSync(QAction *tar, std::function<bool ()> proc)
{
action_trigger_map[tar] = proc;
}

View File

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