#include "SourceEditView.h" #include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Project; using namespace MakeTools; using namespace Parse::Result; using namespace Components; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), horizontal_split(new QSplitter(Qt::Horizontal, this)), vertical_split(new QSplitter(Qt::Vertical, this)), left_funcs(new QTabWidget(this)), right_funcs(new QTabWidget(this)), center_funcs(new QTabWidget(this)), bottom_funcs(new QTabWidget(this)), project_manager(new XMLProjectManager(this)), syntax_core(new ParseCore()), make_tool(new StoryTool(syntax_core)), project_view(new ProjectView(project_manager, this)), errors_present(new MessagePresent(make_tool, this)), framework(new SensitiveCore(make_tool)) { setMinimumSize(1000, 600); setWindowTitle("提线木偶集成开发工具"); auto xtool = new QToolBar(this); addToolBar(Qt::ToolBarArea::TopToolBarArea, xtool); auto xstatus = statusBar(); statusBar()->addWidget(new QLabel("文本消息", this)); auto mbar = menuBar(); // 项目菜单树 auto project = mbar->addMenu("项目"); project->addAction("新建路径", [this](){ auto packages = QInputDialog::getText(this, "输入包路径名称", "packagea#packageb#packagec"); if(packages == "") return; QList names; QRegExp exp("([^#]+)"); auto idx=0; while ((idx = exp.indexIn(packages, idx)) != -1) { names << exp.capturedTexts()[1]; idx += names.last().length(); } project_manager->newPath(names); }); auto _xnew = project->addMenu("最后卷新建文件"); _xnew->addAction("发展脉络"); _xnew->addAction("故事单元"); _xnew->addAction("故事大纲"); _xnew->addAction("叙事大纲"); _xnew->addSeparator(); _xnew->addAction("小说章节"); project->addSeparator(); auto sav = project->addAction("保存"); sav->setEnabled(false); connect(sav, &QAction::triggered, [this](){ this->project_manager->save(); framework->saveAll(); }); project->addSeparator(); auto opnp = project->addAction("打开项目"); connect(opnp, &QAction::triggered, [this, sav](){ auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)"); if(file == "") return; project_manager->openProject(file); sav->setEnabled(true); build_internal(true); }); auto newp = project->addAction("新建项目"); connect(newp, &QAction::triggered, [this, sav](){ auto name = QInputDialog::getText(this, "输入项目名称", "项目名称"); if(name == "") return; auto dir_path = QFileDialog::getExistingDirectory(this, "指定项目存储路径"); if(dir_path == "") return; sav->setEnabled(true); this->project_manager->newProject(dir_path, name); }); auto clsp = project->addAction("关闭项目"); connect(clsp, &QAction::triggered, [this, sav](){ this->project_manager->closeProject(); sav->setEnabled(false); }); project->addSeparator(); project->addAction("项目配置"); project->addAction("软件配置"); project->addSeparator(); project->addAction("退出", [](){ QApplication::exit(0); }); // 编辑菜单 auto edit = mbar->addMenu("编辑"); edit->addAction("撤销一步"); edit->addAction("重做一步"); edit->addSeparator(); edit->addAction("查找关键词"); edit->addAction("替换关键词"); // 视图菜单 auto view = mbar->addMenu("视图"); auto area = view->addMenu("区域管理"); auto act_tool = area->addAction("工具栏"); act_tool->setCheckable(true); act_tool->setChecked(true); connect(act_tool, &QAction::triggered, [xtool](bool v){ xtool->setVisible(v); }); auto act_status = area->addAction("状态栏"); act_status->setCheckable(true); act_status->setChecked(true); connect(act_status,&QAction::triggered, [xstatus](bool v){xstatus->setVisible(v);}); auto act_left = area->addAction("左侧功能区"); act_left->setCheckable(true); act_left->setChecked(true); connect(act_left, &QAction::triggered, [this](bool v){this->left_funcs->setVisible(v);}); auto act_right = area->addAction("右侧功能区"); act_right->setCheckable(true); act_right->setChecked(true); connect(act_right, &QAction::triggered, [this](bool v){this->right_funcs->setVisible(v);}); auto act_bottom = area->addAction("底部功能区"); act_bottom->setCheckable(true); act_bottom->setChecked(true); connect(act_bottom, &QAction::triggered, [this](bool v){this->bottom_funcs->setVisible(v);}); view->addSeparator(); auto change = view->addMenu("内容切换"); change->addAction("序列视图"); change->addAction("编辑视图"); view->addSeparator(); auto func = view->addMenu("功能视图"); func->addAction("项目结构"); func->addAction("引用统计"); func->addAction("脉络分蘖"); func->addAction("终端输出"); // 工具菜单 auto tool = mbar->addMenu("工具"); auto word = tool->addMenu("敏感词检测"); word->addAction("工具配置"); word->addAction("敏感词编辑"); auto vcs = tool->addMenu("版本管理"); vcs->addAction("工具配置"); vcs->addAction("启用"); auto exp = tool->addMenu("导入导出"); exp->addAction("导入TXT"); exp->addSeparator(); exp->addAction("导出TXT内容"); exp->addAction("导出TXT大纲"); tool->addAction("编译", [this](){ this->build_internal(); }); // 窗口菜单 auto window = mbar->addMenu("窗口"); window->addAction("新建窗口"); window->addAction("关闭窗口"); window->addSeparator(); window->addAction("布局管理"); window->addMenu("布局切换"); window->addMenu("窗口切换"); // 系统 auto sys = mbar->addMenu("系统"); sys->addAction("软件激活"); sys->addAction("系统信息"); sys->addSeparator(); sys->addAction("关于……"); this->horizontal_split->addWidget(left_funcs); this->horizontal_split->addWidget(vertical_split); this->horizontal_split->addWidget(right_funcs); this->vertical_split->addWidget(center_funcs); this->vertical_split->addWidget(bottom_funcs); setCentralWidget(this->horizontal_split); center_funcs->addTab(new QTextEdit(this), "编辑区域"); left_funcs->addTab(project_view, "项目管理"); connect(project_view, &ProjectView::activeDocument, [this](const QString &file_path, const QString &name){ if(framework->contains(file_path)){ auto ins = framework->queryComponent(QFileInfo(file_path)); center_funcs->setCurrentWidget(ins->textView()); return; } VariedTextView *tview = nullptr; if(file_path.endsWith("storychain")){ tview = new Components::StoryChainSourceEdit(QFileInfo(file_path), this); framework->addPerceptionList(tview); auto doc = syntax_core->queryDocument(QFileInfo(file_path)); tview->reset(doc); } else if(file_path.endsWith("storyunit")){ tview = new Components::StoryUnitSourceEdit(QFileInfo(file_path), this); framework->addPerceptionList(tview); } else if(file_path.endsWith("storyboard")){ tview = new Components::StoryBoardSourceEdit(QFileInfo(file_path), this); framework->addPerceptionList(tview); } else if(file_path.endsWith("storyvolume")){ tview = new Components::StoryVolumeSourceEdit(QFileInfo(file_path), this); framework->addPerceptionList(tview); } else{ tview = new Components::TextContentEdit(QFileInfo(file_path), this); framework->addPerceptionList(tview, SensitiveType::DoNothing); } if(tview == nullptr) { QMessageBox::critical(this, "系统错误", "指定文件类型没有确定编辑器"); return; } QFile fin(file_path); if(!fin.open(QIODevice::ReadOnly | QIODevice::Text)){ QMessageBox::critical(this, "系统错误", QString("无法打开指定文件:%1(%2)").arg(name, file_path)); return; } QTextStream tin(&fin); tview->textContentReset(tin.readAll()); center_funcs->addTab(tview->textView(), name); center_funcs->setCurrentWidget(tview->textView()); }); bottom_funcs->addTab(errors_present, "错误列表"); framework->addProcTrigger([this](){ errors_present->refresh(); }); } MainWindow::~MainWindow() { } void MainWindow::build_internal(bool all_from_disk) { if(!all_from_disk) framework->saveAll(); auto chains = project_manager->filesWithEnds("storychain"); for(auto &it : chains) make_tool->compile(it); auto units = project_manager->filesWithEnds("storyunit"); for(auto &it : units) make_tool->compile(it); auto storys = project_manager->filesWithEnds("storyboard"); for(auto &it : storys) make_tool->compile(it); auto volumes = project_manager->filesWithEnds("storyvolume"); for(auto &it : volumes) make_tool->compile(it); errors_present->refresh(); } void MainWindow::closeEvent(QCloseEvent *event) { // 关闭事件 if(project_manager->isOpen()){ project_manager->save(); framework->saveAll(); } QMainWindow::closeEvent(event); }