save
This commit is contained in:
parent
c9d4b1374c
commit
d3f0438af4
|
@ -1,7 +1,7 @@
|
|||
#单元 中南世界的故事片段
|
||||
{
|
||||
中南世界,主角从一个小角色,逐渐混成大佬的事迹。
|
||||
#情节 故事的开端{
|
||||
#情节 故事的开端 19201202{
|
||||
中南世界的街头,异常热闹的故事开场{@节点 示例脉络 示例节点},主角从这里出发
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
中南世界,主角从一个小角色,逐渐混成大佬的事迹。
|
||||
asfjlakdjf;aldkjf;aldsf
|
||||
#情节 故事的开端{
|
||||
#情节 故事的开端 16601045{
|
||||
中南世界的街头,异常热闹的故事开场{@节点 示例脉络 示例节点},主角从这里出发
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[])
|
|||
MakeTools::StoryTool tool(&core);
|
||||
|
||||
// auto path = "D:\\Projects\\Cpp\\QtNovelDesc\\DesParser\\example.storyvolume";
|
||||
auto path = "D:\\Projects\\Cpp\\QtNovelDesc\\DesParser\\example.storyconcept";
|
||||
auto path = "D:\\Projects\\Cpp\\QtNovelDesc\\DesParser\\example.storyunit";
|
||||
tool.compile(QFileInfo(path), "后台编译");
|
||||
|
||||
auto doc = core.queryDocument(QFileInfo(path));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.15.0, 2022-12-01T15:03:57. -->
|
||||
<!-- Written by QtCreator 4.15.0, 2022-12-09T02:02:06. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
|
|
@ -13,6 +13,7 @@ SOURCES += \
|
|||
SensitiveCore.cpp \
|
||||
SourceEditView.cpp \
|
||||
appcore.cpp \
|
||||
fragmentsorderview.cpp \
|
||||
keywordshightlighter.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
|
@ -34,6 +35,7 @@ HEADERS += \
|
|||
SensitiveCore.h \
|
||||
SourceEditView.h \
|
||||
appcore.h \
|
||||
fragmentsorderview.h \
|
||||
keywordshightlighter.h \
|
||||
mainwindow.h \
|
||||
messagepresent.h \
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#include "fragmentsorderview.h"
|
||||
#include "SensitiveCore.h"
|
||||
#include <comdef.h>
|
||||
#include <StoryUnitDocumentParser.h>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
using namespace Components;
|
||||
using namespace Parse;
|
||||
|
||||
FragmentsOrderView::FragmentsOrderView(Core::AppCore *core, QWidget *parent)
|
||||
: QWidget(parent), core_ins(core), table_view(new QTableView(this)),
|
||||
table_base(new QStandardItemModel(this))
|
||||
{
|
||||
this->table_view->setModel(table_base);
|
||||
table_base->setHorizontalHeaderLabels(QStringList() << "情节名称" << "单元名称" << "索引值");
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->addWidget(table_view);
|
||||
connect(this->table_view, &QTableView::doubleClicked, this, &FragmentsOrderView::double_click);
|
||||
}
|
||||
|
||||
void FragmentsOrderView::refresh()
|
||||
{
|
||||
table_base->clear();
|
||||
table_base->setHorizontalHeaderLabels(QStringList() << "情节名称" << "单元名称" << "索引值");
|
||||
|
||||
auto node_list = core_ins->parseCore()->queryOrdersFragment();
|
||||
|
||||
for(auto &ins : node_list){
|
||||
QList<QStandardItem*> row;
|
||||
row << new QStandardItem(ins.first->name()[0]);
|
||||
row << new QStandardItem(ins.first->name()[1]);
|
||||
row << new QStandardItem(QString("%1").arg(ins.second, 8, 'f'));
|
||||
|
||||
for(auto &i : row) i->setEditable(false);
|
||||
|
||||
table_base->appendRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
void FragmentsOrderView::double_click(const QModelIndex &index)
|
||||
{
|
||||
if(!index.isValid())
|
||||
return;
|
||||
|
||||
auto frag = table_base->item(index.row());
|
||||
auto unit = table_base->item(index.row(), 1);
|
||||
|
||||
QList<QString> path;
|
||||
path << unit->text() << frag->text();
|
||||
|
||||
|
||||
auto unit_ins = this->core_ins->parseCore()->queryStoryUnit(path[0]).first();
|
||||
auto unit_doc = unit_ins->doc();
|
||||
this->core_ins->openTextDocument(unit_doc->filePath(), unit_doc->docName());
|
||||
auto present = this->core_ins->getFramework()->queryTextComponent(QFileInfo(unit_doc->filePath()));
|
||||
|
||||
if(path.size()){
|
||||
present->jumpTo(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef FRAGMENTSORDERVIEW_H
|
||||
#define FRAGMENTSORDERVIEW_H
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
#include <QWidget>
|
||||
#include <libParse.h>
|
||||
#include "appcore.h"
|
||||
|
||||
namespace Components {
|
||||
|
||||
class FragmentsOrderView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FragmentsOrderView(Core::AppCore *core, QWidget *parent = nullptr);
|
||||
|
||||
void refresh();
|
||||
|
||||
void double_click(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
Core::AppCore *const core_ins;
|
||||
QTableView *const table_view;
|
||||
QStandardItemModel *const table_base;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // FRAGMENTSORDERVIEW_H
|
|
@ -45,7 +45,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
units_view(new StoryUnitsPresent(app_core, this)),
|
||||
errors_present(new MessagePresent(app_core->getMake_tool(), this)),
|
||||
boards_view(new StoryBoardsPresent(app_core, this)),
|
||||
concept_view(new StoryConceptsPresent(app_core, this))
|
||||
concept_view(new StoryConceptsPresent(app_core, this)),
|
||||
fragments_order(new FragmentsOrderView(app_core, this))
|
||||
{
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
this->app_core->setCurrentProject(project_manager);
|
||||
|
@ -58,6 +59,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
errors_present->setVisible(false);
|
||||
boards_view->setVisible(false);
|
||||
concept_view->setVisible(false);
|
||||
fragments_order->setVisible(false);
|
||||
project_structure->setVisible(false);
|
||||
left_funcs->setVisible(false);
|
||||
right_funcs->setVisible(false);
|
||||
|
@ -277,6 +279,15 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
sync_kernel->registerAutoRun([this]()->bool{return right_funcs->indexOf(concept_view)!=-1;},
|
||||
[concept_v](bool v){if(v != concept_v->isChecked()) concept_v->setChecked(v);});
|
||||
}
|
||||
// 情节序列
|
||||
{
|
||||
auto fragments_v = func->addAction("情节序列", [this](bool v){
|
||||
toggle_widget_visible(v, right_funcs, fragments_order, "情节序列");
|
||||
});
|
||||
fragments_v->setCheckable(true);
|
||||
sync_kernel->registerAutoRun([this]()->bool{return right_funcs->indexOf(fragments_order)!=-1;},
|
||||
[fragments_v](bool v){if(v != fragments_v->isChecked()) fragments_v->setChecked(v);});
|
||||
}
|
||||
|
||||
// 工具菜单
|
||||
auto tool = mbar->addMenu("工具");
|
||||
|
@ -361,6 +372,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
this->errors_present->refresh();
|
||||
this->boards_view->refresh();
|
||||
this->concept_view->refresh();
|
||||
this->fragments_order->refresh();
|
||||
});
|
||||
|
||||
|
||||
|
@ -425,6 +437,7 @@ void MainWindow::build_internal(bool all_from_disk)
|
|||
units_view->refresh();
|
||||
boards_view->refresh();
|
||||
concept_view->refresh();
|
||||
fragments_order->refresh();
|
||||
}
|
||||
|
||||
void MainWindow::toggle_widget_visible(bool visible, QTabWidget *con, QWidget *target, const QString &title)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "ContentPresent.h"
|
||||
#include "storyboardspresent.h"
|
||||
#include "storyconceptspresent.h"
|
||||
#include "fragmentsorderview.h"
|
||||
#include "tools.h"
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
|
@ -49,6 +50,7 @@ private:
|
|||
Components::MessagePresent *const errors_present;
|
||||
Components::StoryBoardsPresent *const boards_view;
|
||||
Components::StoryConceptsPresent *const concept_view;
|
||||
Components::FragmentsOrderView *const fragments_order;
|
||||
|
||||
// 内部逻辑 ===========================================
|
||||
void build_internal(bool all_from_disk = false);
|
||||
|
|
|
@ -18,7 +18,12 @@ void NodeStoryBoard::setIndex(const QString &val)
|
|||
|
||||
QString NodeStoryBoard::index() const
|
||||
{
|
||||
return index_store;
|
||||
return this->index_store;
|
||||
}
|
||||
|
||||
int NodeStoryBoard::indexValue(bool &valid) const
|
||||
{
|
||||
return index_store.toInt(&valid);
|
||||
}
|
||||
|
||||
bool NodeStoryBoard::check(QList<ErrorMessage> &reasons) const
|
||||
|
@ -26,7 +31,7 @@ bool NodeStoryBoard::check(QList<ErrorMessage> &reasons) const
|
|||
auto nodes = doc()->core()->queryStoryBoard(name()[0]);
|
||||
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义大纲";
|
||||
ins.Text = name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -35,12 +40,27 @@ bool NodeStoryBoard::check(QList<ErrorMessage> &reasons) const
|
|||
reasons << ins;
|
||||
}
|
||||
|
||||
bool is_valid = false;
|
||||
indexValue(is_valid);
|
||||
if(!is_valid){
|
||||
ErrorMessage msg(this);
|
||||
msg.CodeRow = refered().first()->row();
|
||||
msg.CodeCol = refered().first()->column();
|
||||
msg.FilePath = doc()->filePath();
|
||||
msg.Text = index();
|
||||
msg.Reason = "指定故事编排索引格式错误";
|
||||
|
||||
reasons << msg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return nodes.size() == 1;
|
||||
}
|
||||
|
||||
QString NodeStoryBoard::toString() const
|
||||
{
|
||||
QString des = "#故事 "+name()[0] + " " + index() +" {";
|
||||
bool ignore;
|
||||
QString des = "#故事 "+name()[0] + " " + QString("%1").arg(indexValue(ignore)) +" {";
|
||||
for(auto n : children())
|
||||
des += "\n" + n->toString();
|
||||
des += "\n}";
|
||||
|
@ -59,11 +79,16 @@ QString NodeStoryFragmentRefer::unit() const{
|
|||
return this->unit_name_store;
|
||||
}
|
||||
|
||||
QString NodeStoryFragmentRefer::fragment() const
|
||||
{
|
||||
return this->fragment_name;
|
||||
}
|
||||
|
||||
bool NodeStoryFragmentRefer::check(QList<ErrorMessage> &reasons) const
|
||||
{
|
||||
auto unitx = doc()->core()->queryStoryUnit(unit());
|
||||
if(!unitx.size()){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "指定的单元不存在";
|
||||
ins.Text = unit();
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -75,7 +100,7 @@ bool NodeStoryFragmentRefer::check(QList<ErrorMessage> &reasons) const
|
|||
|
||||
auto fragment = doc()->core()->queryStoryFragment(unitx[0], name()[0]);
|
||||
if(!fragment.size()){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "指定的情节不存在";
|
||||
ins.Text = unit() + ":" + name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Parse {
|
|||
|
||||
void setIndex(const QString &val);
|
||||
QString index() const;
|
||||
int indexValue(bool &valid) const;
|
||||
|
||||
// DesNode interface
|
||||
public:
|
||||
|
@ -58,6 +59,8 @@ namespace Parse {
|
|||
void setUnit(const QString &name);
|
||||
QString unit() const;
|
||||
|
||||
QString fragment() const;
|
||||
|
||||
// DesNode interface
|
||||
public:
|
||||
virtual bool check(QList<ErrorMessage> &reasons) const override;
|
||||
|
|
|
@ -155,7 +155,7 @@ bool NodeStoryChain::check(QList<ErrorMessage> &reasons) const
|
|||
{
|
||||
auto nodes = doc()->core()->queryStoryChain(name()[0]);
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义脉络";
|
||||
ins.Text = name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -190,7 +190,8 @@ bool NodeStoryPoint::check(QList<ErrorMessage> &reasons) const
|
|||
auto chain = parent();
|
||||
auto nodes = chain->doc()->core()->queryStoryPoint(chain, name()[0]);
|
||||
|
||||
if(nodes.size() > 1){ ErrorMessage ins;
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义脉络节点";
|
||||
ins.Text = static_cast<NamedNode*>(chain)->name()[0] +":"+ name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
|
|
@ -79,7 +79,8 @@ bool NodeStoryDepiction::check(QList<ErrorMessage> &reasons) const
|
|||
{
|
||||
auto nodes = doc()->core()->queryStoryDepiction(name()[0]);
|
||||
|
||||
if(nodes.size() > 1){ ErrorMessage ins;
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义叙述";
|
||||
ins.Text = name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
|
|
@ -9,9 +9,10 @@
|
|||
using namespace MakeTools;
|
||||
using namespace Parse;
|
||||
using namespace Parse::Result;
|
||||
using namespace CheckTools;
|
||||
|
||||
StoryTool::StoryTool(Parse::Result::ParseCore *core)
|
||||
: parse_core(core){}
|
||||
: parse_core(core), fragment_check(new FragmentsCheck(core)){}
|
||||
|
||||
QList<QString> StoryTool::compile(const QFileInfo &file, const QString &doc_name)
|
||||
{
|
||||
|
@ -118,7 +119,7 @@ bool StoryTool::checkPass(QList<ErrorMessage> &errors)
|
|||
auto docs = this->parse_core->allDocuments();
|
||||
for(auto &d : docs){
|
||||
for(auto &w : d->unknowns()->refered()){
|
||||
ErrorMessage error;
|
||||
ErrorMessage error(w->host());
|
||||
error.Reason = "无法识别内容";
|
||||
error.Text = w->toString();
|
||||
error.FilePath = d->filePath();
|
||||
|
@ -131,6 +132,7 @@ bool StoryTool::checkPass(QList<ErrorMessage> &errors)
|
|||
for(auto &n : this->parse_core->queryRootNodes(d))
|
||||
error_check(n, errors);
|
||||
}
|
||||
fragment_check->check(errors);
|
||||
return errors.size() == 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "SyntaxBase.h"
|
||||
#include "libParse.h"
|
||||
#include "parsechecks.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
|
@ -22,6 +23,7 @@ namespace MakeTools {
|
|||
|
||||
private:
|
||||
Parse::Result::ParseCore *const parse_core;
|
||||
CheckTools::FragmentsCheck *const fragment_check;
|
||||
|
||||
bool error_check(Parse::Result::DesNode *node, QList<Parse::ErrorMessage> &err_out);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ bool NodeStoryUnit::check(QList<ErrorMessage> &reasons) const
|
|||
auto unit_nodes = doc()->core()->queryStoryUnit(name()[0]);
|
||||
|
||||
if(unit_nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义单元";
|
||||
ins.Text = name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -22,6 +22,7 @@ bool NodeStoryUnit::check(QList<ErrorMessage> &reasons) const
|
|||
ins.CodeCol = refered().first()->column();
|
||||
reasons << ins;
|
||||
}
|
||||
|
||||
return unit_nodes.size() == 1;
|
||||
}
|
||||
|
||||
|
@ -35,14 +36,24 @@ QString NodeStoryUnit::toString() const
|
|||
}
|
||||
|
||||
|
||||
NodeStoryFragment::NodeStoryFragment(NodeStoryUnit * unit, const QString & name)
|
||||
: Result::NamedNode(name, unit->doc(), NODE_STORYFRAGMENT, unit){ store_name = name; }
|
||||
NodeStoryFragment::NodeStoryFragment(NodeStoryUnit * unit, const QString & name, const QString &order)
|
||||
: Result::NamedNode(name, unit->doc(), NODE_STORYFRAGMENT, unit){ store_name = name; order_text = order; }
|
||||
|
||||
QString NodeStoryFragment::order() const
|
||||
{
|
||||
return order_text;
|
||||
}
|
||||
|
||||
double NodeStoryFragment::orderValue(bool &isvalid) const
|
||||
{
|
||||
return order_text.toDouble(&isvalid);
|
||||
}
|
||||
|
||||
bool NodeStoryFragment::check(QList<ErrorMessage> &reasons) const
|
||||
{
|
||||
auto nodes = doc()->core()->queryStoryFragment(parent(), name()[0]);
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "重复定义情节";
|
||||
ins.Text = name()[0];
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -51,13 +62,27 @@ bool NodeStoryFragment::check(QList<ErrorMessage> &reasons) const
|
|||
reasons << ins;
|
||||
}
|
||||
|
||||
bool isvalid = false;
|
||||
this->orderValue(isvalid);
|
||||
if(!isvalid){
|
||||
ErrorMessage msg(this);
|
||||
msg.CodeRow = refered().first()->row();
|
||||
msg.CodeCol = refered().first()->column();
|
||||
msg.FilePath = doc()->filePath();
|
||||
msg.Text = this->order();
|
||||
msg.Reason = "指定情节序列格式错误";
|
||||
|
||||
reasons << msg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return nodes.size() == 1;
|
||||
}
|
||||
|
||||
QString NodeStoryFragment::toString() const
|
||||
{
|
||||
QString rets = QString(depth(), ' ') + "#情节 " + name()[0] + "{";
|
||||
for (auto cin : children())
|
||||
QString rets = QString(depth(), ' ') + "#情节 " + name()[0] +" " + order() + "{";
|
||||
for (auto &cin : children())
|
||||
rets += "\n" + QString(depth(), ' ') + cin->toString();
|
||||
return rets + "\n"+QString(depth(), ' ') + "}";
|
||||
}
|
||||
|
@ -88,7 +113,7 @@ bool NodeStoryPointRefer::check(QList<ErrorMessage> &reasons) const
|
|||
{
|
||||
auto chain = doc()->core()->queryStoryChain(chainName());
|
||||
if(!chain.size()){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "指定脉络不存在";
|
||||
ins.Text = chainName();
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -100,7 +125,7 @@ bool NodeStoryPointRefer::check(QList<ErrorMessage> &reasons) const
|
|||
else{
|
||||
auto point = doc()->core()->queryStoryPoint(chain[0], pointName());
|
||||
if(!point.size()){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.Reason = "指定脉络节点不存在";
|
||||
ins.Text = chainName() + ":" + pointName();
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -118,72 +143,6 @@ QString NodeStoryPointRefer::toString() const
|
|||
return QString("{@节点 %1 %2}").arg(chain_name).arg(point_name);
|
||||
}
|
||||
|
||||
//NodeStoryFragmentComment::NodeStoryFragmentComment(DesNode * parent,
|
||||
// const QString &order, const QString & name)
|
||||
// : parent_ins(parent), name_store(name), order_name(order)
|
||||
//{
|
||||
//}
|
||||
|
||||
//QString NodeStoryFragmentComment::order() const
|
||||
//{
|
||||
// return order_name;
|
||||
//}
|
||||
|
||||
//DocCore * NodeStoryFragmentComment::document() const
|
||||
//{
|
||||
// return parent_ins->document();
|
||||
//}
|
||||
|
||||
//int NodeStoryFragmentComment::typeValue() const
|
||||
//{
|
||||
// return NODE_ORDEREDCOMMENT;
|
||||
//}
|
||||
|
||||
//DesNode * NodeStoryFragmentComment::parent() const
|
||||
//{
|
||||
// return parent_ins;
|
||||
//}
|
||||
|
||||
//void NodeStoryFragmentComment::appendChild(DesNode * ins)
|
||||
//{
|
||||
// children_nodes << ins;
|
||||
//}
|
||||
|
||||
//QList<DesNode*> NodeStoryFragmentComment::children() const
|
||||
//{
|
||||
// return children_nodes;
|
||||
//}
|
||||
|
||||
//bool NodeStoryFragmentComment::check(QList<QString>& reasons) const
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//QString NodeStoryFragmentComment::toString() const
|
||||
//{
|
||||
// auto xrets = QString(depth(), ' ') + "#注解 " + name() +" "+ order() +" "+ orderValue() + "{";
|
||||
// for (auto it : children_nodes)
|
||||
// xrets += "\n" + QString(depth(), ' ') + it->toString();
|
||||
// xrets += "\n" + QString(depth(), ' ') + "}";
|
||||
|
||||
// return xrets;
|
||||
//}
|
||||
|
||||
//QString NodeStoryFragmentComment::name() const
|
||||
//{
|
||||
// return name_store;
|
||||
//}
|
||||
|
||||
//QString NodeStoryFragmentComment::orderValue() const
|
||||
//{
|
||||
// return order_value;
|
||||
//}
|
||||
|
||||
//void NodeStoryFragmentComment::resetValue(const QString &value)
|
||||
//{
|
||||
// this->order_value = value;
|
||||
//}
|
||||
|
||||
NodeStoryUnitParser::NodeStoryUnitParser(ParseCore * core)
|
||||
: XSyntaxBase("故事单元"), pjt_core(core)
|
||||
{
|
||||
|
@ -256,22 +215,25 @@ NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser)
|
|||
{
|
||||
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
|
||||
auto rule = addRule("进入情节解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult {
|
||||
auto nmidx = cnt - 1, defidx = cnt - 2;;
|
||||
auto nmidx = cnt - 2, defidx = cnt - 3, ordidx=cnt-1;
|
||||
|
||||
auto parent_parser = nodeStoryUnitParser();
|
||||
auto node = new NodeStoryFragment(static_cast<NodeStoryUnit*>(parent_parser->currNode()), seqs[nmidx].Text);
|
||||
auto node = new NodeStoryFragment(static_cast<NodeStoryUnit*>(parent_parser->currNode()),
|
||||
seqs[nmidx].Text, seqs[ordidx].Text);
|
||||
this->refocusNode(node);
|
||||
parent_parser->currNode()->appendChild(node);
|
||||
|
||||
auto word0 = new Words(node, docRef(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol);
|
||||
auto word1 = new Words(node, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
|
||||
auto word2 = new Words(node, docRef(), seqs[ordidx].Text, seqs[ordidx].StartRow, seqs[ordidx].StartCol);
|
||||
docRef()->append(word0);
|
||||
docRef()->append(word1);
|
||||
docRef()->append(word2);
|
||||
|
||||
return ParseResult::SelfManipulate;
|
||||
});
|
||||
|
||||
rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}", true) });
|
||||
rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", true) });
|
||||
rule->addExpression("拓展情节解析", { Exp("::换行前缀"), Exp("基础情节解析", true) });
|
||||
|
||||
rule = addRule("情节成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult {
|
||||
|
|
|
@ -37,9 +37,12 @@ namespace Parse {
|
|||
class NodeStoryFragment : public Result::NamedNode
|
||||
{
|
||||
public:
|
||||
explicit NodeStoryFragment(NodeStoryUnit* unit, const QString &name);
|
||||
explicit NodeStoryFragment(NodeStoryUnit* unit, const QString &name, const QString& order);
|
||||
virtual ~NodeStoryFragment() = default;
|
||||
|
||||
QString order() const;
|
||||
double orderValue(bool &isvalid) const;
|
||||
|
||||
// 通过 NamedNode 继承
|
||||
virtual bool check(QList<ErrorMessage>& reasons) const override;
|
||||
virtual QString toString() const override;
|
||||
|
@ -48,6 +51,7 @@ namespace Parse {
|
|||
|
||||
private:
|
||||
QString store_name;
|
||||
QString order_text;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "libParse.h"
|
||||
#include "SyntaxBase.h"
|
||||
#include "StoryUnitDocumentParser.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace Parse;
|
||||
|
@ -29,6 +30,8 @@ namespace Parse {
|
|||
};
|
||||
}
|
||||
|
||||
ErrorMessage::ErrorMessage(const DesNode *obj): object(obj){}
|
||||
|
||||
NamedNode::NamedNode(const QString &name, DocCore *core, int type, DesNode *pnode)
|
||||
: Result::DesNode(core, type, pnode), name_store(name){}
|
||||
|
||||
|
@ -230,6 +233,33 @@ QList<Result::DesNode*> ParseCore::queryStoryFragment(DesNode *unit, const QStri
|
|||
return retlist;
|
||||
}
|
||||
|
||||
QList<std::pair<NamedNode *, double> > ParseCore::queryOrdersFragment() const
|
||||
{
|
||||
QList<std::pair<NamedNode*, double>> node_list;
|
||||
auto units = allStoryUnits();
|
||||
for(auto &uins : units){
|
||||
auto children = uins->children();
|
||||
for(auto &c : children){
|
||||
if(c->typeValue() != NODE_STORYFRAGMENT)
|
||||
continue;
|
||||
|
||||
bool isvalid;
|
||||
auto fragment = static_cast<NodeStoryFragment*>(c);
|
||||
node_list << std::make_pair(fragment, fragment->orderValue(isvalid));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(node_list.begin(), node_list.end(),
|
||||
[](const std::pair<NamedNode*, double> &a, const std::pair<NamedNode*, double> &b)->bool{
|
||||
bool valid;
|
||||
auto val_a = static_cast<NodeStoryFragment*>(a.first)->orderValue(valid);
|
||||
auto val_b = static_cast<NodeStoryFragment*>(b.first)->orderValue(valid);
|
||||
return val_a < val_b;
|
||||
});
|
||||
|
||||
return node_list;
|
||||
}
|
||||
|
||||
QList<DesNode *> ParseCore::allStoryBoards() const
|
||||
{
|
||||
QList<Result::DesNode*> retlist;
|
||||
|
|
|
@ -10,20 +10,28 @@
|
|||
|
||||
namespace Parse
|
||||
{
|
||||
struct ErrorMessage
|
||||
namespace Result
|
||||
{
|
||||
class DesNode;
|
||||
}
|
||||
|
||||
class ErrorMessage
|
||||
{
|
||||
public:
|
||||
ErrorMessage(const Result::DesNode *obj);
|
||||
|
||||
QString Reason;
|
||||
QString Text;
|
||||
QString FilePath;
|
||||
int CodeRow;
|
||||
int CodeCol;
|
||||
|
||||
const Result::DesNode *const object;
|
||||
};
|
||||
|
||||
namespace Result
|
||||
{
|
||||
namespace Result{
|
||||
class ParseCore;
|
||||
class DocCore;
|
||||
class DesNode;
|
||||
|
||||
enum class DocType
|
||||
{
|
||||
|
@ -314,6 +322,7 @@ namespace Parse
|
|||
virtual QList<Result::DesNode*> allStoryUnits() const;
|
||||
virtual QList<Result::DesNode*> queryStoryUnit(const QString &name) const;
|
||||
virtual QList<Result::DesNode*> queryStoryFragment(Result::DesNode *unit, const QString &name) const;
|
||||
virtual QList<std::pair<Result::NamedNode*, double>> queryOrdersFragment() const;
|
||||
|
||||
virtual QList<Result::DesNode*> allStoryBoards() const;
|
||||
virtual QList<Result::DesNode*> queryStoryBoard(const QString &name) const;
|
||||
|
|
|
@ -20,6 +20,7 @@ SOURCES += \
|
|||
WordsPeak.cpp \
|
||||
XSyntaxBase.cpp \
|
||||
libParse.cpp \
|
||||
parsechecks.cpp \
|
||||
storyconceptdocumentparser.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
@ -36,6 +37,7 @@ HEADERS += \
|
|||
XSyntaxBase.h \
|
||||
libParse.h \
|
||||
libParse_global.h \
|
||||
parsechecks.h \
|
||||
storyconceptdocumentparser.h
|
||||
|
||||
TRANSLATIONS += \
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#include "parsechecks.h"
|
||||
#include "StoryBoardDocumentParser.h"
|
||||
#include "StoryUnitDocumentParser.h"
|
||||
#include "../WordsIDE/opstream.h"
|
||||
|
||||
using namespace Parse;
|
||||
|
||||
CheckTools::FragmentsCheck::FragmentsCheck(Parse::Result::ParseCore *const core)
|
||||
: core_ins(core){}
|
||||
|
||||
bool CheckTools::FragmentsCheck::check(QList<Parse::ErrorMessage> &reasons) const
|
||||
{
|
||||
auto stories = core_ins->allStoryBoards();
|
||||
|
||||
// 编排索引顺序校验
|
||||
for(auto &ins : stories){
|
||||
auto xins = static_cast<Parse::NodeStoryBoard*>(ins);
|
||||
|
||||
double temp = -DBL_MAX;
|
||||
auto refers = xins->children();
|
||||
for(auto &ref : refers){
|
||||
if(ref->typeValue() == NODE_FRAGMENTREFERENCE){
|
||||
auto ins_ref = static_cast<NodeStoryFragmentRefer*>(ref);
|
||||
auto u = core_ins->queryStoryUnit(ins_ref->unit());
|
||||
auto frag = core_ins->queryStoryFragment(u[0], ins_ref->fragment());
|
||||
auto frag_ins = static_cast<NodeStoryFragment*>(frag[0]);
|
||||
|
||||
bool isvalid;
|
||||
double order_value = frag_ins->orderValue(isvalid);
|
||||
if(temp > order_value)
|
||||
{
|
||||
ErrorMessage msg(ins_ref);
|
||||
msg.CodeRow = ins_ref->refered().first()->row();
|
||||
msg.CodeCol = ins_ref->refered().first()->column();
|
||||
msg.FilePath = ins_ref->doc()->filePath();
|
||||
msg.Text = ins_ref->unit() + ":"+ ins_ref->fragment();
|
||||
msg.Reason = QString("%1:指定节点索引顺序颠倒").arg(ins_ref->fragment());
|
||||
|
||||
reasons << msg;
|
||||
return false;
|
||||
}
|
||||
|
||||
temp = order_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef PARSECHECKS_H
|
||||
#define PARSECHECKS_H
|
||||
|
||||
#include "libParse.h"
|
||||
|
||||
namespace CheckTools {
|
||||
/**
|
||||
* @brief 情节校对工具
|
||||
*/
|
||||
class FragmentsCheck
|
||||
{
|
||||
public:
|
||||
FragmentsCheck(Parse::Result::ParseCore *const core);
|
||||
|
||||
/**
|
||||
* @brief 错误校验
|
||||
* @param reasons 错误原因
|
||||
* @return 错误指示
|
||||
*/
|
||||
bool check(QList<Parse::ErrorMessage> &reasons) const;
|
||||
|
||||
private:
|
||||
Parse::Result::ParseCore *const core_ins;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // PARSECHECKS_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ bool NodeStoryConcept::check(QList<ErrorMessage> &reasons) const
|
|||
{
|
||||
auto nodes = doc()->core()->queryStoryConcept(name()[0]);
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.CodeRow = refered().first()->row();
|
||||
ins.CodeCol = refered().first()->column();
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
@ -66,7 +66,7 @@ bool NodeStoryStrongPoint::check(QList<ErrorMessage> &reasons) const
|
|||
auto concept = parent();
|
||||
auto nodes = doc()->core()->queryStoryStrongPoint(concept, name()[0]);
|
||||
if(nodes.size() > 1){
|
||||
ErrorMessage ins;
|
||||
ErrorMessage ins(this);
|
||||
ins.CodeRow = refered().first()->row();
|
||||
ins.CodeCol = refered().first()->column();
|
||||
ins.FilePath = doc()->filePath();
|
||||
|
|
Loading…
Reference in New Issue