Compare commits

...

10 Commits

56 changed files with 1756 additions and 1468 deletions

View File

@ -3,8 +3,7 @@ TEMPLATE = subdirs
SUBDIRS += \
libGenericConsole \
libSplitView \
# WordsIDE \
WordsIDE \
libConfig \
libProjectManager \
# libTextEdit \
u_test

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.0, 2024-02-10T14:34:11. -->
<!-- Written by QtCreator 4.15.0, 2024-02-19T11:26:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -234,79 +234,24 @@
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
<value type="QString">-e</value>
<value type="QString">cpu-cycles</value>
<value type="QString">--call-graph</value>
<value type="QString">dwarf,4096</value>
<value type="QString">-F</value>
<value type="QString">250</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="QString" key="Analyzer.Valgrind.Callgrind.Arguments"></value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="QString" key="Analyzer.Valgrind.Memcheck.Arguments"></value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindArguments"></value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:D:/Projects/Cpp/QtNovelDesc/u_test/u_test.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">D:/Projects/Cpp/QtNovelDesc/u_test/u_test.pro</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Projects/Cpp/build-QtNovelDesc-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug/u_test</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:D:/Projects/Cpp/QtNovelDesc/WordsIDE/WordsIDE.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">D:/Projects/Cpp/QtNovelDesc/WordsIDE/WordsIDE.pro</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Projects/Cpp/build-QtNovelDesc-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug/WordsIDE</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
</valuemap>
</data>
<data>

View File

@ -6,7 +6,6 @@
#include <QDebug>
#include <QTextCodec>
using namespace Components;
using namespace Core;
using namespace Presents;

View File

@ -1,10 +1,11 @@
#ifndef DOCSMANAGER_H
#define DOCSMANAGER_H
#include "route.h"
#include "Route.h"
#include <QHash>
#include <QObject>
#include <libConfig.h>
#include <QMenu>
namespace Core {
class DocumentsManager;
@ -19,6 +20,12 @@ namespace Presents {
public:
explicit FilePresent(QObject *parent = nullptr);
virtual ~FilePresent() = default;
/**
* @brief
* @return
*/
virtual QMenu* bindMenu() const = 0;
/**
* @brief

View File

@ -1,4 +1,4 @@
#include "route.h"
#include "Route.h"
using namespace Core;

View File

@ -19,40 +19,38 @@ msvc {
SOURCES += \
DocsManager.cpp \
Route.cpp \
command_list.cpp \
# contentpresenttest.cpp \
# keywordshighlighter.cpp \
main.cpp \
mainwindow.cpp \
manager_docs.cpp \
messageview.cpp \
message_view.cpp \
parsebridge.cpp \
presentcontainerview.cpp \
projectview.cpp \
route.cpp \
present_container.cpp \
project_view.cpp \
session_binder.cpp \
srcedit_defaulttext.cpp \
srcedit_storyboard.cpp \
viewsession.cpp \
viewstackedbar.cpp \
welcomepanel.cpp \
xapp.cpp
HEADERS += \
DocsManager.h \
Route.h \
command_list.h \
# contentpresenttest.h \
# keywordshighlighter.h \
mainwindow.h \
manager_docs.h \
messageview.h \
message_view.h \
parsebridge.h \
presentcontainerview.h \
projectview.h \
route.h \
present_container.h \
project_view.h \
session_binder.h \
srcedit_defaulttext.h \
srcedit_storyboard.h \
viewsession.h \
viewstackedbar.h \
welcomepanel.h \
xapp.h

View File

@ -1,6 +1,6 @@
#include "command_list.h"
#include "manager_docs.h"
#include "route.h"
#include "Route.h"
#include "DocsManager.h"
using namespace CommandList;

View File

@ -1,7 +1,7 @@
#ifndef COMMAND_LIST_H
#define COMMAND_LIST_H
#include "route.h"
#include "Route.h"
#include <QModelIndex>
#include <commandsdispatcher.h>

View File

@ -25,8 +25,8 @@ int main(int argc, char *argv[])
}
}
MainWindow w(&a, "default");
w.show();
// MainWindow w(&a, "default");
// w.show();
return a.exec();
}

View File

@ -1,331 +1,331 @@
#include "mainwindow.h"
#include "srcedit_defaulttext.h"
#include "srcedit_storyboard.h"
#include "xapp.h"
#include <QApplication>
#include <QDateTime>
#include <QDebug>
#include <QFileDialog>
#include <QInputDialog>
#include <QLabel>
#include <QList>
#include <QMenuBar>
#include <QMessageBox>
#include <QStatusBar>
#include <QTextEdit>
#include <QToolBar>
#include <QVBoxLayout>
#include <xmlconfig.h>
#include <xmlprojectmanager.h>
#include "command_list.h"
using namespace Project;
using namespace Components;
using namespace Core;
using namespace CommandList;
using namespace bridge;
MainWindow::MainWindow(XApp *core, const QString &layout, QWidget *parent)
: QMainWindow(parent),
layout_name_store(layout),
core_bind(core),
present_host(new SplitFrame::SplitPanel(this)),
session_service(new ViewSession(XApp::gconfig, this)),
actions_stack(new QToolBar(this)),
views_bar(new ViewStackedBar(present_host, this)),
center_frame(new PresentContainerView(present_host)),
project_present(new ProjectView(present_host, XApp::disp_core, core->docsManager())) {
setMinimumSize(1000, 600);
setWindowTitle(tr("提线木偶"));
QApplication::instance()->installEventFilter(this);
auto mbar = menuBar();
initial_menubar(mbar);
setCentralWidget(present_host->bind());
addToolBar(Qt::LeftToolBarArea, views_bar);
present_host->addListener(views_bar);
session_service->initPresentView(center_frame, project_present, core->parseService()->errorsPresentModel());
project_present->setVisible(true);
core->docsManager()->appendPresent(center_frame);
session_service->viewStatesRestore(this, present_host);
}
MainWindow::~MainWindow() { core_bind->docsManager()->removePresent(center_frame); }
SplitFrame::SplitPanel *MainWindow::bindPresent() const { return present_host; }
QString MainWindow::layoutName() const { return layout_name_store; }
void MainWindow::resetLayoutName(const QString &name) { layout_name_store = name; }
void MainWindow::initial_menubar(QMenuBar *mbar) {
// 项目菜单树
project = mbar->addMenu("项目");
this->build_project_menu(project);
// 编辑菜单
edit = mbar->addMenu("编辑");
this->build_edit_menu(edit);
// 视图菜单
view = mbar->addMenu("视图");
build_view_menu(view);
// 工具菜单
tool = mbar->addMenu("工具");
build_tools_menu(tool);
// 窗口菜单
window = mbar->addMenu("窗口");
build_window_menu(window);
// 系统
system = mbar->addMenu("系统");
system_active = system->addAction("软件激活");
system_info = system->addAction("系统信息");
system->addSeparator();
system_about = system->addAction("关于……");
}
auto action_sync = [](bool enable, const QList<QAction*> &same_state){
for(auto &a : same_state)
a->setEnabled(enable);
};
void MainWindow::build_project_menu(QMenu *project) {
project_open = project->addAction("打开项目", [this]() {
auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)");
if (file == "")
return;
XApp::disp_core->postCommand(OpenProject(file));
});
project_new = project->addAction("新建项目", [this]() {
auto name = QInputDialog::getText(this, "输入项目名称", "项目名称");
if (name == "")
return;
auto dir_path = QFileDialog::getExistingDirectory(this, "指定项目存储路径");
if (dir_path == "")
return;
XApp::disp_core->postCommand(NewProject(QDir(dir_path), name));
});
project_close = project->addAction("关闭项目", []() { XApp::disp_core->postCommand(CloseProject()); });
project->addSeparator();
project_newpath = project->addAction("新建路径", [this]() {
auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:");
if (packages != "")
XApp::disp_core->postCommand(NewPackage(packages));
});
project_newfile = project->addMenu("新建文件");
auto types = core_bind->docsManager()->fileTypes();
for (auto &t : types) {
project_newfile->addAction(t, [this, &t]() {
auto name = QInputDialog::getText(this, "输入名称", "名称:");
if (name == "")
return;
auto idx = project_present->currentIndex();
if (!idx.isValid())
idx = core_bind->pjtManager()->model()->item(0)->index();
auto group_path = core_bind->docsManager()->convertPath(idx);
XApp::disp_core->postCommand(NewFile(group_path, name, t));
});
}
project->addSeparator();
project_save = project->addAction("保存全部", []() { XApp::disp_core->postCommand(SaveAll()); });
project_save->setShortcut(QKeySequence::StandardKey::Save);
project->addSeparator();
software_exit = project->addAction("退出", []() {
XApp::disp_core->postCommand(SaveAll());
QApplication::exit(0);
});
this->hasBeenCLOSE();
}
void MainWindow::build_edit_menu(QMenu *edit) {
edit_undo = edit->addAction("撤销一步");
edit_redo = edit->addAction("重做一步");
edit->addSeparator();
edit_find = edit->addAction("查找关键词");
edit_replace = edit->addAction("替换关键词");
}
void MainWindow::build_view_menu(QMenu *view) {
view_area = view->addMenu("区域管理");
actions_stack->setMovable(false);
addToolBar(Qt::ToolBarArea::TopToolBarArea, actions_stack);
view_area_toolbar = view_area->addAction("工具栏");
connect(view_area_toolbar, &QAction::triggered, [this](bool v) { actions_stack->setVisible(v); });
auto xstatus = statusBar();
xstatus->setVisible(false);
xstatus->addWidget(new QLabel("文本消息", this));
view_area_statusbar = view_area->addAction("状态栏");
connect(view_area_statusbar, &QAction::triggered, [xstatus](bool v) { xstatus->setVisible(v); });
view_config = view->addAction("视图配置", [this]() {
auto dialog = new QDialog();
auto tabs = new QTabWidget(dialog);
auto layout = new QVBoxLayout(dialog);
layout->addWidget(tabs);
core_bind->docsManager()->loadViewConfigWidgets(tabs);
dialog->exec();
});
}
void MainWindow::build_tools_menu(QMenu *tool) {
tool_console = tool->addAction("控制台");
tool->addSeparator();
tool_wcheck = tool->addMenu("敏感词检测");
tool_wcheck_setting = tool_wcheck->addAction("工具配置");
tool_wcheck_wordslist = tool_wcheck->addAction("敏感词编辑");
tool_version = tool->addMenu("版本管理");
tool_version_setting = tool_version->addAction("工具配置");
tool_version_enable = tool_version->addAction("启用");
tool_version_commit = tool_version->addAction("提交版本");
tool_version_rollback = tool_version->addAction("版本回滚");
tool_inout = tool->addMenu("导入导出");
tool_inout_outline_in = tool_inout->addAction("导入WsOutlines");
tool_inout->addSeparator();
tool_inout_outline_out = tool_inout->addAction("导出WsOutlines");
tool_inout_outline_webout = tool_inout->addAction("导出Web大纲");
tool_inout->addSeparator();
tool_inout_storytxt_out = tool_inout->addAction("导出TXT故事");
tool_inout_storyepub_out = tool_inout->addAction("导出EQUP故事");
}
QList<QString> layout_peak_path = {"sys-configs", "foreground", "view-layouts"};
void MainWindow::build_window_menu(QMenu *window) {
window_winnew = window->addMenu("新建窗口");
connect(window_winnew, &QMenu::aboutToShow, [this]() {
auto names = XApp::gconfig->getList(layout_peak_path);
if (!names.size()) {
names << "default";
XApp::gconfig->setList(layout_peak_path, names);
}
window_winnew->clear();
for (auto &n : names)
window_winnew->addAction(n);
});
connect(window_winnew, &QMenu::triggered, [this](QAction *s) {
auto layout = s->text();
auto newone = new MainWindow(this->core_bind, layout);
newone->show();
});
window_winclose = window->addAction("关闭窗口", [this]() {
XApp::disp_core->postCommand(SaveAll());
this->close();
});
window->addSeparator();
window_layout_store = window->addAction("保存当前布局", [this]() {
auto new_name = QInputDialog::getText(this, "输入新布局名称", "名称:");
if (new_name.isEmpty())
return;
auto names = XApp::gconfig->getList(layout_peak_path);
if (names.contains(new_name)) {
QMessageBox::critical(this, "数据校验", "输入错误,输入了重复的布局名称!");
return;
}
names << new_name;
XApp::gconfig->setList(layout_peak_path, names);
this->resetLayoutName(new_name);
session_service->viewStatesSave(this, this->present_host);
});
window_layout_load = window->addMenu("布局切换");
window_layout_del = window->addMenu("布局删除");
}
void MainWindow::closeEvent(QCloseEvent *event) {
// 关闭事件
if (core_bind->pjtManager()->isOpenning()) {
XApp::disp_core->postCommand(CloseProject());
}
session_service->viewStatesSave(this, present_host);
XApp::gconfig->save();
QMainWindow::closeEvent(event);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event) {
auto ev = event->type();
switch (ev) {
case QEvent::Type::MouseButtonPress:
case QEvent::Type::MouseButtonRelease:
case QEvent::Type::Wheel:
case QEvent::Type::MouseMove:
case QEvent::Type::KeyPress:
case QEvent::Type::KeyRelease:
break;
default:
break;
}
return QMainWindow::eventFilter(watched, event);
}
void MainWindow::ProjectNEW(const QString &) {}
void MainWindow::ProjectOPEN(const QString &project_file) {
action_sync(false, {project_new, project_open});
action_sync(true, {project_close, project_newpath, project_save});
project_newfile->setEnabled(true);
this->setWindowTitle(QString("WordIDE::%1 - %2").arg(this->core_bind->pjtManager()->name()).arg(project_file));
}
void MainWindow::hasBeenSAVE() {}
void MainWindow::hasBeenCLOSE() {
action_sync(true, {project_open, project_new});
action_sync(false, {project_close, project_newpath, project_save});
project_newfile->setEnabled(false);
this->setWindowTitle("WordIDE");
}
void MainWindow::hasBeenRENAME(const QModelIndex &path, const QString &new_name) {}
void MainWindow::hasBeenAPPEND(const QModelIndex &new_path) {}
void MainWindow::hasBeenMOVE(const QModelIndex &new_path) {}
void MainWindow::aboutToBeSAVE() {}
void MainWindow::aboutToBeCLOSE() {}
void MainWindow::aboutToBeDELETE(const QModelIndex &path) {}
void MainWindow::aboutToBeMOVE(const QModelIndex &old_path) {}
//#include "mainwindow.h"
//#include "srcedit_defaulttext.h"
//#include "srcedit_storyboard.h"
//#include "xapp.h"
//#include <QApplication>
//#include <QDateTime>
//#include <QDebug>
//#include <QFileDialog>
//#include <QInputDialog>
//#include <QLabel>
//#include <QList>
//#include <QMenuBar>
//#include <QMessageBox>
//#include <QStatusBar>
//#include <QTextEdit>
//#include <QToolBar>
//#include <QVBoxLayout>
//#include <xmlconfig.h>
//#include <xmlprojectmanager.h>
//#include "command_list.h"
//using namespace Project;
//using namespace Components;
//using namespace Core;
//using namespace CommandList;
//using namespace bridge;
//MainWindow::MainWindow(XApp *core, const QString &layout, QWidget *parent)
// : QMainWindow(parent),
// layout_name_store(layout),
// core_bind(core),
// present_host(new SplitFrame::SplitPanel(this)),
// session_service(new ViewSession(XApp::gconfig, this)),
// actions_stack(new QToolBar(this)),
// views_bar(new ViewStackedBar(present_host, this)),
// center_frame(new PresentContainer(present_host)),
// project_present(new ProjectView(present_host, XApp::disp_core, core->docsManager())) {
// setMinimumSize(1000, 600);
// setWindowTitle(tr("提线木偶"));
// QApplication::instance()->installEventFilter(this);
// auto mbar = menuBar();
// initial_menubar(mbar);
// setCentralWidget(present_host->bind());
// addToolBar(Qt::LeftToolBarArea, views_bar);
// present_host->addListener(views_bar);
// session_service->initPresentView(center_frame, project_present, core->parseService()->errorsPresentModel());
// project_present->setVisible(true);
// core->docsManager()->appendPresent(center_frame);
// session_service->viewStatesRestore(this, present_host);
//}
//MainWindow::~MainWindow() { core_bind->docsManager()->removePresent(center_frame); }
//SplitFrame::SplitPanel *MainWindow::bindPresent() const { return present_host; }
//QString MainWindow::layoutName() const { return layout_name_store; }
//void MainWindow::resetLayoutName(const QString &name) { layout_name_store = name; }
//void MainWindow::initial_menubar(QMenuBar *mbar) {
// // 项目菜单树
// project = mbar->addMenu("项目");
// this->build_project_menu(project);
// // 编辑菜单
// edit = mbar->addMenu("编辑");
// this->build_edit_menu(edit);
// // 视图菜单
// view = mbar->addMenu("视图");
// build_view_menu(view);
// // 工具菜单
// tool = mbar->addMenu("工具");
// build_tools_menu(tool);
// // 窗口菜单
// window = mbar->addMenu("窗口");
// build_window_menu(window);
// // 系统
// system = mbar->addMenu("系统");
// system_active = system->addAction("软件激活");
// system_info = system->addAction("系统信息");
// system->addSeparator();
// system_about = system->addAction("关于……");
//}
//auto action_sync = [](bool enable, const QList<QAction*> &same_state){
// for(auto &a : same_state)
// a->setEnabled(enable);
//};
//void MainWindow::build_project_menu(QMenu *project) {
// project_open = project->addAction("打开项目", [this]() {
// auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)");
// if (file == "")
// return;
// XApp::disp_core->postCommand(OpenProject(file));
// });
// project_new = project->addAction("新建项目", [this]() {
// auto name = QInputDialog::getText(this, "输入项目名称", "项目名称");
// if (name == "")
// return;
// auto dir_path = QFileDialog::getExistingDirectory(this, "指定项目存储路径");
// if (dir_path == "")
// return;
// XApp::disp_core->postCommand(NewProject(QDir(dir_path), name));
// });
// project_close = project->addAction("关闭项目", []() { XApp::disp_core->postCommand(CloseProject()); });
// project->addSeparator();
// project_newpath = project->addAction("新建路径", [this]() {
// auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:");
// if (packages != "")
// XApp::disp_core->postCommand(NewPackage(packages));
// });
// project_newfile = project->addMenu("新建文件");
// auto types = core_bind->docsManager()->fileTypes();
// for (auto &t : types) {
// project_newfile->addAction(t, [this, &t]() {
// auto name = QInputDialog::getText(this, "输入名称", "名称:");
// if (name == "")
// return;
// auto idx = project_present->currentIndex();
// if (!idx.isValid())
// idx = core_bind->pjtManager()->model()->item(0)->index();
// auto group_path = core_bind->docsManager()->convertPath(idx);
// XApp::disp_core->postCommand(NewFile(group_path, name, t));
// });
// }
// project->addSeparator();
// project_save = project->addAction("保存全部", []() { XApp::disp_core->postCommand(SaveAll()); });
// project_save->setShortcut(QKeySequence::StandardKey::Save);
// project->addSeparator();
// software_exit = project->addAction("退出", []() {
// XApp::disp_core->postCommand(SaveAll());
// QApplication::exit(0);
// });
// this->hasBeenCLOSE();
//}
//void MainWindow::build_edit_menu(QMenu *edit) {
// edit_undo = edit->addAction("撤销一步");
// edit_redo = edit->addAction("重做一步");
// edit->addSeparator();
// edit_find = edit->addAction("查找关键词");
// edit_replace = edit->addAction("替换关键词");
//}
//void MainWindow::build_view_menu(QMenu *view) {
// view_area = view->addMenu("区域管理");
// actions_stack->setMovable(false);
// addToolBar(Qt::ToolBarArea::TopToolBarArea, actions_stack);
// view_area_toolbar = view_area->addAction("工具栏");
// connect(view_area_toolbar, &QAction::triggered, [this](bool v) { actions_stack->setVisible(v); });
// auto xstatus = statusBar();
// xstatus->setVisible(false);
// xstatus->addWidget(new QLabel("文本消息", this));
// view_area_statusbar = view_area->addAction("状态栏");
// connect(view_area_statusbar, &QAction::triggered, [xstatus](bool v) { xstatus->setVisible(v); });
// view_config = view->addAction("视图配置", [this]() {
// auto dialog = new QDialog();
// auto tabs = new QTabWidget(dialog);
// auto layout = new QVBoxLayout(dialog);
// layout->addWidget(tabs);
// core_bind->docsManager()->loadViewConfigWidgets(tabs);
// dialog->exec();
// });
//}
//void MainWindow::build_tools_menu(QMenu *tool) {
// tool_console = tool->addAction("控制台");
// tool->addSeparator();
// tool_wcheck = tool->addMenu("敏感词检测");
// tool_wcheck_setting = tool_wcheck->addAction("工具配置");
// tool_wcheck_wordslist = tool_wcheck->addAction("敏感词编辑");
// tool_version = tool->addMenu("版本管理");
// tool_version_setting = tool_version->addAction("工具配置");
// tool_version_enable = tool_version->addAction("启用");
// tool_version_commit = tool_version->addAction("提交版本");
// tool_version_rollback = tool_version->addAction("版本回滚");
// tool_inout = tool->addMenu("导入导出");
// tool_inout_outline_in = tool_inout->addAction("导入WsOutlines");
// tool_inout->addSeparator();
// tool_inout_outline_out = tool_inout->addAction("导出WsOutlines");
// tool_inout_outline_webout = tool_inout->addAction("导出Web大纲");
// tool_inout->addSeparator();
// tool_inout_storytxt_out = tool_inout->addAction("导出TXT故事");
// tool_inout_storyepub_out = tool_inout->addAction("导出EQUP故事");
//}
//QList<QString> layout_peak_path = {"sys-configs", "foreground", "view-layouts"};
//void MainWindow::build_window_menu(QMenu *window) {
// window_winnew = window->addMenu("新建窗口");
// connect(window_winnew, &QMenu::aboutToShow, [this]() {
// auto names = XApp::gconfig->getList(layout_peak_path);
// if (!names.size()) {
// names << "default";
// XApp::gconfig->setList(layout_peak_path, names);
// }
// window_winnew->clear();
// for (auto &n : names)
// window_winnew->addAction(n);
// });
// connect(window_winnew, &QMenu::triggered, [this](QAction *s) {
// auto layout = s->text();
// auto newone = new MainWindow(this->core_bind, layout);
// newone->show();
// });
// window_winclose = window->addAction("关闭窗口", [this]() {
// XApp::disp_core->postCommand(SaveAll());
// this->close();
// });
// window->addSeparator();
// window_layout_store = window->addAction("保存当前布局", [this]() {
// auto new_name = QInputDialog::getText(this, "输入新布局名称", "名称:");
// if (new_name.isEmpty())
// return;
// auto names = XApp::gconfig->getList(layout_peak_path);
// if (names.contains(new_name)) {
// QMessageBox::critical(this, "数据校验", "输入错误,输入了重复的布局名称!");
// return;
// }
// names << new_name;
// XApp::gconfig->setList(layout_peak_path, names);
// this->resetLayoutName(new_name);
// session_service->viewStatesSave(this, this->present_host);
// });
// window_layout_load = window->addMenu("布局切换");
// window_layout_del = window->addMenu("布局删除");
//}
//void MainWindow::closeEvent(QCloseEvent *event) {
// // 关闭事件
// if (core_bind->pjtManager()->isOpenning()) {
// XApp::disp_core->postCommand(CloseProject());
// }
// session_service->viewStatesSave(this, present_host);
// XApp::gconfig->save();
// QMainWindow::closeEvent(event);
//}
//bool MainWindow::eventFilter(QObject *watched, QEvent *event) {
// auto ev = event->type();
// switch (ev) {
// case QEvent::Type::MouseButtonPress:
// case QEvent::Type::MouseButtonRelease:
// case QEvent::Type::Wheel:
// case QEvent::Type::MouseMove:
// case QEvent::Type::KeyPress:
// case QEvent::Type::KeyRelease:
// break;
// default:
// break;
// }
// return QMainWindow::eventFilter(watched, event);
//}
//void MainWindow::ProjectNEW(const QString &) {}
//void MainWindow::ProjectOPEN(const QString &project_file) {
// action_sync(false, {project_new, project_open});
// action_sync(true, {project_close, project_newpath, project_save});
// project_newfile->setEnabled(true);
// this->setWindowTitle(QString("WordIDE::%1 - %2").arg(this->core_bind->pjtManager()->name()).arg(project_file));
//}
//void MainWindow::hasBeenSAVE() {}
//void MainWindow::hasBeenCLOSE() {
// action_sync(true, {project_open, project_new});
// action_sync(false, {project_close, project_newpath, project_save});
// project_newfile->setEnabled(false);
// this->setWindowTitle("WordIDE");
//}
//void MainWindow::hasBeenRENAME(const QModelIndex &path, const QString &new_name) {}
//void MainWindow::hasBeenAPPEND(const QModelIndex &new_path) {}
//void MainWindow::hasBeenMOVE(const QModelIndex &new_path) {}
//void MainWindow::aboutToBeSAVE() {}
//void MainWindow::aboutToBeCLOSE() {}
//void MainWindow::aboutToBeDELETE(const QModelIndex &path) {}
//void MainWindow::aboutToBeMOVE(const QModelIndex &old_path) {}

View File

@ -1,128 +1,128 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//#ifndef MAINWINDOW_H
//#define MAINWINDOW_H
#include "DocsManager.h"
#include "manager_docs.h"
#include "messageview.h"
#include "parsebridge.h"
#include "presentcontainerview.h"
#include "projectview.h"
#include "viewsession.h"
#include "viewstackedbar.h"
#include "welcomepanel.h"
#include "xapp.h"
#include <QListView>
#include <QMainWindow>
#include <QSplitter>
#include <QTableView>
#include <QTreeView>
#include <libProjectManager.h>
#include <splitwindow.h>
//#include "DocsManager.h"
//#include "manager_docs.h"
//#include "MessageView.h"
//#include "parsebridge.h"
//#include "PresentContainer.h"
//#include "ProjectView.h"
//#include "viewsession.h"
//#include "viewstackedbar.h"
//#include "welcomepanel.h"
//#include "xapp.h"
//#include <QListView>
//#include <QMainWindow>
//#include <QSplitter>
//#include <QTableView>
//#include <QTreeView>
//#include <libProjectManager.h>
//#include <splitwindow.h>
class MainWindow : public QMainWindow , public Project::ManagerListener{
Q_OBJECT
//class MainWindow : public QMainWindow , public Project::ManagerListener{
// Q_OBJECT
public:
MainWindow(XApp *core, const QString &layout, QWidget *parent = nullptr);
virtual ~MainWindow();
//public:
// MainWindow(XApp *core, const QString &layout, QWidget *parent = nullptr);
// virtual ~MainWindow();
SplitFrame::SplitPanel *bindPresent() const;
QString layoutName() const;
void resetLayoutName(const QString &name);
// SplitFrame::SplitPanel *bindPresent() const;
// QString layoutName() const;
// void resetLayoutName(const QString &name);
private:
QString layout_name_store;
// model ============================================
XApp *const core_bind;
SplitFrame::SplitPanel *const present_host;
Core::ViewSession *const session_service;
//private:
// QString layout_name_store;
// // model ============================================
// XApp *const core_bind;
// SplitFrame::SplitPanel *const present_host;
// Core::ViewSession *const session_service;
// view =============================================
QToolBar *const actions_stack;
Components::ViewStackedBar *const views_bar;
Components::PresentContainerView *const center_frame;
Components::ProjectView *const project_present;
// // view =============================================
// QToolBar *const actions_stack;
// Components::ViewStackedBar *const views_bar;
// Components::PresentContainer *const center_frame;
// Components::ProjectView *const project_present;
// menu =============================================
QMenu *project;
QAction *project_open;
QAction *project_new;
QAction *project_close;
QAction *project_newpath;
QMenu *project_newfile;
QAction *project_save;
QAction *software_exit;
// // menu =============================================
// QMenu *project;
// QAction *project_open;
// QAction *project_new;
// QAction *project_close;
// QAction *project_newpath;
// QMenu *project_newfile;
// QAction *project_save;
// QAction *software_exit;
QMenu *edit;
QAction *edit_undo;
QAction *edit_redo;
QAction *edit_find;
QAction *edit_replace;
// QMenu *edit;
// QAction *edit_undo;
// QAction *edit_redo;
// QAction *edit_find;
// QAction *edit_replace;
QMenu *view;
QMenu *view_area;
QAction *view_area_toolbar;
QAction *view_area_statusbar;
QAction *view_config;
// QMenu *view;
// QMenu *view_area;
// QAction *view_area_toolbar;
// QAction *view_area_statusbar;
// QAction *view_config;
QMenu *tool;
QAction *tool_console;
QMenu *tool_wcheck;
QAction *tool_wcheck_setting;
QAction *tool_wcheck_wordslist;
QMenu *tool_version;
QAction *tool_version_enable;
QAction *tool_version_setting;
QAction *tool_version_commit;
QAction *tool_version_rollback;
QMenu *tool_inout;
QAction *tool_inout_outline_in;
QAction *tool_inout_outline_out;
QAction *tool_inout_outline_webout;
QAction *tool_inout_storytxt_out;
QAction *tool_inout_storyepub_out;
// QMenu *tool;
// QAction *tool_console;
// QMenu *tool_wcheck;
// QAction *tool_wcheck_setting;
// QAction *tool_wcheck_wordslist;
// QMenu *tool_version;
// QAction *tool_version_enable;
// QAction *tool_version_setting;
// QAction *tool_version_commit;
// QAction *tool_version_rollback;
// QMenu *tool_inout;
// QAction *tool_inout_outline_in;
// QAction *tool_inout_outline_out;
// QAction *tool_inout_outline_webout;
// QAction *tool_inout_storytxt_out;
// QAction *tool_inout_storyepub_out;
QMenu *window;
QMenu *window_winnew;
QAction *window_winclose;
QAction *window_layout_store;
QMenu *window_layout_load;
QMenu *window_layout_del;
// QMenu *window;
// QMenu *window_winnew;
// QAction *window_winclose;
// QAction *window_layout_store;
// QMenu *window_layout_load;
// QMenu *window_layout_del;
QMenu *system;
QAction *system_active;
QAction *system_info;
QAction *system_about;
// QMenu *system;
// QAction *system_active;
// QAction *system_info;
// QAction *system_about;
// 内部逻辑 ===========================================
// // 内部逻辑 ===========================================
void initial_menubar(QMenuBar *mbar);
void build_project_menu(QMenu *pmenu);
void build_edit_menu(QMenu *pmenu);
void build_view_menu(QMenu *pmenu);
void build_tools_menu(QMenu *pmenu);
void build_window_menu(QMenu *pmenu);
// void initial_menubar(QMenuBar *mbar);
// void build_project_menu(QMenu *pmenu);
// void build_edit_menu(QMenu *pmenu);
// void build_view_menu(QMenu *pmenu);
// void build_tools_menu(QMenu *pmenu);
// void build_window_menu(QMenu *pmenu);
// QWidget interface
protected:
virtual void closeEvent(QCloseEvent *event) override;
// // QWidget interface
//protected:
// virtual void closeEvent(QCloseEvent *event) override;
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
// // QObject interface
// public:
// virtual bool eventFilter(QObject *watched, QEvent *event) override;
// Project::ManagerListener interface
public:
virtual void ProjectNEW(const QString &project_file) override;
virtual void ProjectOPEN(const QString &project_file) override;
virtual void hasBeenSAVE() override;
virtual void hasBeenCLOSE() override;
virtual void hasBeenRENAME(const QModelIndex &path, const QString &new_name) override;
virtual void hasBeenAPPEND(const QModelIndex &new_path) override;
virtual void hasBeenMOVE(const QModelIndex &new_path) override;
virtual void aboutToBeSAVE() override;
virtual void aboutToBeCLOSE() override;
virtual void aboutToBeDELETE(const QModelIndex &path) override;
virtual void aboutToBeMOVE(const QModelIndex &old_path) override;
};
#endif // MAINWINDOW_H
// // Project::ManagerListener interface
//public:
// virtual void ProjectNEW(const QString &project_file) override;
// virtual void ProjectOPEN(const QString &project_file) override;
// virtual void hasBeenSAVE() override;
// virtual void hasBeenCLOSE() override;
// virtual void hasBeenRENAME(const QModelIndex &path, const QString &new_name) override;
// virtual void hasBeenAPPEND(const QModelIndex &new_path) override;
// virtual void hasBeenMOVE(const QModelIndex &new_path) override;
// virtual void aboutToBeSAVE() override;
// virtual void aboutToBeCLOSE() override;
// virtual void aboutToBeDELETE(const QModelIndex &path) override;
// virtual void aboutToBeMOVE(const QModelIndex &old_path) override;
//};
//#endif // MAINWINDOW_H

View File

@ -2,7 +2,7 @@
#define MANAGER_DOCS_H
#include "DocsManager.h"
#include "route.h"
#include "Route.h"
#include <QList>
#include <QTreeView>
@ -11,16 +11,33 @@
#include <libProjectManager.h>
namespace Presents {
class HostListener{
public:
virtual ~HostListener() = default;
virtual void currentChanged(const Presents::FilePresent *inst) = 0;
};
class PresentHost {
public:
virtual ~PresentHost() = default;
/**
* @brief addListener
* @param lst
*/
virtual void addListener(HostListener *lst) = 0;
/**
* @brief Widget
* @return
*/
virtual QWidget *hostWidget() const = 0;
/**
* @brief
* @return
*/
virtual Presents::FilePresent* currentPresent() const = 0;
/**
* @brief

55
WordsIDE/message_view.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "message_view.h"
#include <QMenu>
#include <QVBoxLayout>
using namespace Components;
MessageView::MessageView() : MessageView(nullptr, nullptr) {}
MessageView::MessageView(QWidget *parent, XApp *core) : QTableView(parent), menu(core ? new QMenu("编译输出",this) : nullptr) {
if(core){
setModel(core->messageModel());
menu->addAction("清除信息", [core](){
auto model = core->messageModel();
while (model->rowCount()) {
model->removeRow(0);
}
});
}
}
ExtendView *MessageView::newInst(QWidget *parent, XApp *core)
{
return new MessageView(parent, core);
}
QMenu *MessageView::bindMenu() const
{
return menu;
}
QString MessageView::typeName() const
{
return "编译输出";
}
ExtendType MessageView::type() const
{
return ExtendType::FEATURE_PRESENT;
}
QWidget *MessageView::presentWidget() const
{
return const_cast<MessageView*>(this);
}
void MessageView::saveProcess()
{
}
void MessageView::closeProcess()
{
}

87
WordsIDE/message_view.h Normal file
View File

@ -0,0 +1,87 @@
#ifndef MESSAGE_VIEW_H
#define MESSAGE_VIEW_H
#include "DocsManager.h"
#include <QHash>
#include <QStandardItemModel>
#include <QTableView>
#include <SplitWindow.h>
#include "xapp.h"
namespace Components {
enum class ExtendType{
FEATURE_PRESENT,
VIEW_CONTAINTER
};
/**
* @brief
*/
class ExtendView {
public:
virtual ~ExtendView() = default;
/**
* @brief
* @param parent
* @param core
* @return
*/
virtual ExtendView* newInst(QWidget *parent, XApp *core) = 0;
/**
* @brief
* @return
*/
virtual QMenu* bindMenu() const = 0;
/**
* @brief
* @return
*/
virtual QString typeName() const = 0;
/**
* @brief
* @return
*/
virtual ExtendType type() const = 0;
/**
* @brief
* @return
*/
virtual QWidget* presentWidget() const = 0;
/**
* @brief
*/
virtual void saveProcess() = 0;
/**
* @brief
*/
virtual void closeProcess() = 0;
};
/**
* @brief
*/
class MessageView : public QTableView, public ExtendView {
public:
MessageView();
MessageView(QWidget*parent = nullptr, XApp *core = nullptr);
virtual ~MessageView() = default;
// ExtendView interface
public:
virtual ExtendView *newInst(QWidget *parent, XApp *core) override;
virtual QMenu *bindMenu() const override;
virtual QString typeName() const override;
virtual ExtendType type() const override;
virtual QWidget* presentWidget() const override;
virtual void saveProcess() override;
virtual void closeProcess() override;
private:
QMenu *const menu;
};
} // namespace Components
#endif // MESSAGE_VIEW_H

View File

@ -1,28 +0,0 @@
#include "messageview.h"
#include <QVBoxLayout>
using namespace Components;
using namespace SplitFrame;
QHash<SplitFrame::SplitPanel *, MessageView *> MessageView::panel_map;
MessageView::MessageView(SplitFrame::SplitPanel *ins, QStandardItemModel *base)
: FnWrap<MessageView, false>(ins), ui_present(new QTableView(this)), items_present(base) {
auto layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(ui_present);
ui_present->setModel(items_present);
ui_present->setMouseTracking(true);
}
MessageView *MessageView::gen(SplitFrame::SplitPanel *host, QStandardItemModel *base) {
if (panel_map.contains(host))
return panel_map[host];
auto vins = new MessageView(host, base);
panel_map[host] = vins;
return vins;
}

View File

@ -1,29 +0,0 @@
#ifndef MESSAGEVIEW_H
#define MESSAGEVIEW_H
#include "DocsManager.h"
#include <QHash>
#include <QStandardItemModel>
#include <QTableView>
#include <splitwindow.h>
namespace Components {
/**
* @brief
*/
class MessageView : public SplitFrame::FnWrap<MessageView, false> {
public:
virtual ~MessageView() = default;
static MessageView *gen(SplitFrame::SplitPanel *host, QStandardItemModel *base);
private:
MessageView(SplitFrame::SplitPanel *ins, QStandardItemModel *base);
QTableView *const ui_present;
QStandardItemModel *const items_present;
static QHash<SplitFrame::SplitPanel *, MessageView *> panel_map;
};
} // namespace Components
#endif // MESSAGEVIEW_H

View File

@ -1,4 +1,4 @@
#include "presentcontainerview.h"
#include "present_container.h"
#include "DocsManager.h"
#include "welcomepanel.h"
@ -10,11 +10,10 @@
using namespace Components;
using namespace Core;
using namespace SplitFrame;
using namespace Presents;
PresentContainerView::PresentContainerView(SplitPanel *host)
: FnWrap<PresentContainerView, true>(host),
PresentContainer::PresentContainer(QWidget *ptr)
: QWidget(ptr),
title_store(new QComboBox(this)),
stack_container(new QStackedWidget(this)),
welcome_list(new WelcomePanel(this)),
@ -40,16 +39,24 @@ PresentContainerView::PresentContainerView(SplitPanel *host)
layout->setColumnStretch(2, 1);
layout->setColumnStretch(3, 0);
connect(title_store, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PresentContainerView::change_view);
connect(close_btn, &QPushButton::toggled, this, &PresentContainerView::close_current_view);
connect(title_store, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PresentContainer::change_view);
connect(close_btn, &QPushButton::toggled, this, &PresentContainer::close_current_view);
connect(stack_container, &QStackedWidget::currentChanged, [this](int idx){
if(idx >= 0){
auto inst = items_store.at(idx);
for(auto &l : listeners_store)
l->currentChanged(inst);
}
});
}
QWidget *PresentContainerView::hostWidget() const { return (QWidget *)this; }
QWidget *PresentContainer::hostWidget() const { return (QWidget *)this; }
#include <libConfig.h>
using namespace Config;
void PresentContainerView::append(FilePresent *ins) {
void PresentContainer::append(FilePresent *ins) {
if (!items_store.contains(ins)) {
items_store.append(ins);
title_store->addItem(ins->name());
@ -62,7 +69,7 @@ void PresentContainerView::append(FilePresent *ins) {
}
#include <QDebug>
bool PresentContainerView::active(const FilePresent *ins) {
bool PresentContainer::active(const FilePresent *ins) {
if (!items_store.contains(ins))
return false;
@ -73,7 +80,7 @@ bool PresentContainerView::active(const FilePresent *ins) {
return true;
}
void PresentContainerView::remove(const FilePresent *ins) {
void PresentContainer::remove(const FilePresent *ins) {
if (!items_store.contains(ins))
return;
@ -83,7 +90,7 @@ void PresentContainerView::remove(const FilePresent *ins) {
stack_container->removeWidget(ins->widget());
}
bool PresentContainerView::contains(const FilePresent *ins) const {
bool PresentContainer::contains(const FilePresent *ins) const {
for (auto &insit : items_store) {
if (insit == ins)
return true;
@ -91,14 +98,14 @@ bool PresentContainerView::contains(const FilePresent *ins) const {
return false;
}
bool PresentContainerView::avaliable(FilePresent *vins) {
bool PresentContainer::avaliable(FilePresent *vins) {
auto global_test = QApplication::activeWindow();
if (!global_test)
return true;
return this->isActiveWindow();
}
void PresentContainerView::change_view(int view_index) {
void PresentContainer::change_view(int view_index) {
auto view_inst = items_store[view_index];
active(view_inst);
@ -106,7 +113,7 @@ void PresentContainerView::change_view(int view_index) {
}
#include <QMessageBox>
void PresentContainerView::close_current_view() {
void PresentContainer::close_current_view() {
auto index = title_store->currentIndex();
const_cast<FilePresent *>(items_store[index])->beforeClose();
}

View File

@ -1,12 +1,13 @@
#ifndef PRESENTCONTAINERVIEW_H
#define PRESENTCONTAINERVIEW_H
#ifndef PRESENT_CONTAINER_H
#define PRESENT_CONTAINER_H
#include "manager_docs.h"
#include <QComboBox>
#include <QPushButton>
#include <QStackedLayout>
#include <QStackedWidget>
#include <splitwindow.h>
#include <SplitWindow.h>
#include "message_view.h"
namespace Presents {
class WelcomePanel;
@ -15,24 +16,37 @@ namespace Presents {
namespace Components {
/**
* @brief
*/
class PresentContainerView : public SplitFrame::FnWrap<PresentContainerView, true>, public Presents::PresentHost {
* @brief
*/
class PresentContainer : public QWidget ,public ExtendView, public Presents::PresentHost {
Q_OBJECT
public:
PresentContainerView(SplitFrame::SplitPanel *host);
// PresentContainer interface
PresentContainer(QWidget *ptr = nullptr);
// PresentHost interface
public:
virtual QWidget *hostWidget() const override;
virtual void addListener(Presents::HostListener *lst) override;
virtual void append(Presents::FilePresent *ins) override;
virtual bool active(const Presents::FilePresent *ins) override;
virtual void remove(const Presents::FilePresent *ins) override;
virtual bool contains(const Presents::FilePresent *ins) const override;
virtual bool avaliable(Presents::FilePresent *vins) override;
virtual Presents::FilePresent *currentPresent() const override;
// ExtendView interface
public:
virtual ExtendView *newInst(QWidget *parent, XApp *core) override;
virtual QMenu *bindMenu() const override;
virtual QString typeName() const override;
virtual ExtendType type() const override;
virtual QWidget *presentWidget() const override;
virtual void saveProcess() override;
virtual void closeProcess() override;
private:
QList<Presents::HostListener*> listeners_store;
QList<const Presents::FilePresent *> items_store;
QComboBox *const title_store;
QStackedWidget *const stack_container;
@ -42,8 +56,9 @@ namespace Components {
void change_view(int view_index);
void close_current_view();
};
} // namespace Components
#endif // PRESENTCONTAINERVIEW_H
#endif // PRESENT_CONTAINER_H

104
WordsIDE/project_view.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "project_view.h"
#include "command_list.h"
#include <QInputDialog>
#include <QMenu>
#include <QVBoxLayout>
using namespace Components;
using namespace CommandList;
using namespace Schedule;
using namespace Core;
ProjectView::ProjectView(QWidget *parent, CommandsDispatcher *core, Core::DocumentsManager *mgr)
: QWidget(parent), project_manager(mgr), source(core), view_present(new QTreeView(this)), menu_root(new QMenu("项目管理")) {
auto layout = new QVBoxLayout(this);
layout->addWidget(view_present);
layout->setMargin(1);
this->menGenerate(menu_root);
view_present->setModel(mgr->projectManager()->model());
view_present->setHeaderHidden(true);
view_present->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view_present, &QTreeView::customContextMenuRequested, this, &ProjectView::menu_popup);
connect(view_present, &QTreeView::doubleClicked, this, &ProjectView::open_target);
connect(view_present->selectionModel(), &QItemSelectionModel::currentChanged, this, &ProjectView::currentIndexChanged);
}
QMenu *ProjectView::menGenerate(QMenu *m)
{
if(!m)
return menu_root;
m->addAction("新建路径", [this](){
auto path_string = QInputDialog::getText(this, "输入路径定义/packa/packb/packc", "路径定义:");
if(path_string.isEmpty())
return;
source->postCommand(NewPackage(path_string));
});
auto index = this->view_present->currentIndex();
if(index.isValid()){
auto mgr = source->get<DocumentsManager>(NAME(DocumentsManager));
auto menu = m->addMenu("新建文件");
auto views = mgr->fileTypes();
for (auto &it : views) {
menu->addAction(it, [this, it, &index, mgr]() {
auto name = QInputDialog::getText(this, "输入文件名称", "文件名称");
auto path = mgr->convertPath(index);
source->postCommand(NewFile(path, name, it));
});
}
m->addSeparator();
m->addAction("移除节点", [&index, this]() { source->postCommand(DeleteTarget(index)); });
}
return m;
}
ProjectView::ProjectView() : project_manager(nullptr), source(nullptr), view_present(nullptr), menu_root(nullptr) {}
ExtendView *ProjectView::newInst(QWidget *parent, XApp *core)
{
return new ProjectView(parent, core->cmdsPort(), core->docsPort());
}
QMenu *ProjectView::bindMenu() const
{
return menu_root;
}
QString ProjectView::typeName() const
{
return "项目管理";
}
ExtendType ProjectView::type() const
{
return ExtendType::FEATURE_PRESENT;
}
QWidget *ProjectView::presentWidget() const
{
return const_cast<ProjectView*>(this);
}
void ProjectView::saveProcess() { project_manager->save(); }
void ProjectView::menu_popup(const QPoint &p)
{
auto m = menGenerate();
m->exec(mapToGlobal(p));
}
void ProjectView::open_target(const QModelIndex &t)
{
auto mgr = source->get<DocumentsManager>(NAME(DocumentsManager));
auto path = mgr->convertPath(t);
source->postCommand(OpenFile(path));
}
void ProjectView::closeProcess() { project_manager->save(); }

50
WordsIDE/project_view.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef PROJECT_VIEW_H
#define PROJECT_VIEW_H
#include "DocsManager.h"
#include "manager_docs.h"
#include <QTreeView>
#include <QWidget>
#include <commandsdispatcher.h>
#include <libProjectManager.h>
#include "message_view.h"
namespace Components {
/**
* @brief
*/
class ProjectView : public QWidget, public ExtendView {
Q_OBJECT
public:
ProjectView();
explicit ProjectView(QWidget *parent, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr);
// ExtendView interface
public:
virtual ExtendView *newInst(QWidget *parent, XApp *core) override;
virtual QMenu *bindMenu() const override;
virtual QString typeName() const override;
virtual Components::ExtendType type() const override;
virtual QWidget *presentWidget() const override;
virtual void saveProcess() override;
virtual void closeProcess() override;
signals:
void currentIndexChanged(const QModelIndex &index);
private:
Core::DocumentsManager *const project_manager;
Schedule::CommandsDispatcher *const source;
QTreeView *const view_present;
QMenu *const menu_root;
void menu_popup(const QPoint &p);
void open_target(const QModelIndex &t);
QMenu* menGenerate(QMenu *m=nullptr);
};
}
#endif // PROJECT_VIEW_H

View File

@ -1,72 +0,0 @@
#include "projectview.h"
#include "command_list.h"
#include <QInputDialog>
#include <QMenu>
#include <QVBoxLayout>
using namespace Components;
using namespace CommandList;
using namespace Schedule;
using namespace SplitFrame;
using namespace Core;
ProjectView::ProjectView(SplitPanel *host, CommandsDispatcher *core, Core::DocumentsManager *mgr)
: FnWrap<ProjectView, false>(host), project_manager(mgr), source(core), view_present(new QTreeView(this)) {
auto layout = new QVBoxLayout(this);
layout->addWidget(view_present);
layout->setMargin(1);
view_present->setModel(mgr->projectManager()->model());
view_present->setHeaderHidden(true);
view_present->setMouseTracking(true);
view_present->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view_present, &QTreeView::customContextMenuRequested,
this, &ProjectView::menu_popup);
connect(view_present, &QTreeView::doubleClicked,
this, &ProjectView::open_target);
}
QModelIndex ProjectView::currentIndex() const { return view_present->currentIndex(); }
void ProjectView::menu_popup(const QPoint &p)
{
QMenu m;
m.addAction("新建路径", [this](){
auto path_string = QInputDialog::getText(this, "输入路径定义/packa/packb/packc", "路径定义:");
if(path_string.isEmpty())
return;
source->postCommand(NewPackage(path_string));
});
auto index = this->view_present->currentIndex();
if(index.isValid()){
auto mgr = source->get<DocumentsManager>(NAME(DocumentsManager));
auto menu = m.addMenu("新建文件");
auto views = mgr->fileTypes();
for (auto &it : views) {
menu->addAction(it, [this, it, &index, mgr]() {
auto name = QInputDialog::getText(this, "输入文件名称", "文件名称");
auto path = mgr->convertPath(index);
source->postCommand(NewFile(path, name, it));
});
}
m.addSeparator();
m.addAction("移除节点", [&index, this]() { source->postCommand(DeleteTarget(index)); });
}
m.exec(mapToGlobal(p));
}
void ProjectView::open_target(const QModelIndex &t)
{
auto mgr = source->get<DocumentsManager>(NAME(DocumentsManager));
auto path = mgr->convertPath(t);
source->postCommand(OpenFile(path));
}
void ProjectView::closeProcess() { project_manager->save(); }

View File

@ -1,38 +0,0 @@
#ifndef PROJECTVIEW_H
#define PROJECTVIEW_H
#include "DocsManager.h"
#include "manager_docs.h"
#include <QTreeView>
#include <QWidget>
#include <commandsdispatcher.h>
#include <libProjectManager.h>
#include <splitwindow.h>
namespace Components {
/**
* @brief
*/
class ProjectView : public SplitFrame::FnWrap<ProjectView, false> {
Q_OBJECT
public:
explicit ProjectView(SplitFrame::SplitPanel *host, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr);
QModelIndex currentIndex() const;
private:
Core::DocumentsManager *const project_manager;
Schedule::CommandsDispatcher *const source;
QTreeView *const view_present;
void menu_popup(const QPoint &p);
void open_target(const QModelIndex &t);
// FnWrap interface
public:
virtual void closeProcess() override;
};
}
#endif // PROJECTVIEW_H

View File

@ -0,0 +1,87 @@
#include "session_binder.h"
#include "mainwindow.h"
#include "message_view.h"
#include "present_container.h"
#include "project_view.h"
#include <QMenuBar>
#include <QMenu>
using namespace Config;
using namespace Core;
using namespace Components;
using namespace split_window;
SessionBinder::SessionBinder(XApp *core)
: QObject(core),
bind_window(new split_window::SplitWindow),
pjt_manager(new ProjectView(bind_window, core->cmdsPort(), core->docsPort())),
msg_present(new MessageView(bind_window, core)),
bind_core(core),
project_op(new QMenu("项目管理")),
edit_op(new QMenu("内容编辑")),
view_op(new QMenu("视图管理")),
build_op(new QMenu("构建服务")),
tool_op(new QMenu("功能拓展")),
system_op(new QMenu("系统帮助"))
{
connect(bind_window, &SplitWindow::windowActived, [this](SplitWindow *inst){
menus_refresh(inst->menuBar());
});
menus_refresh(bind_window->menuBar(), true);
}
#include <DockPanel.h>
void SessionBinder::menus_refresh(QMenuBar *mbar, bool rebuild)
{
if(rebuild){
mbar->addMenu(project_op);
project_op->addActions(pjt_manager->bindMenu()->actions());
mbar->addMenu(edit_op);
mbar->addMenu(view_op);
view_op->addAction("新建窗口");
view_op->addAction("关闭窗口");
view_op->addSeparator();
for(auto &t : bind_core->viewTemplates()){
auto act_item = view_op->addAction(t->typeName());
act_item->setCheckable(t->type() == ExtendType::FEATURE_PRESENT);
std::function<void(bool)> open_view = [=, &open_view](bool state){
auto vinst = t->newInst(bind_window, bind_core);
auto wrap_v = new dock_panel::DockableView(bind_window, vinst->presentWidget());
bind_window->freedomHasBeenAppended(wrap_v);
if(t->type() == ExtendType::FEATURE_PRESENT){
disconnect(act_item, &QAction::triggered, nullptr, nullptr);
connect(act_item, &QAction::triggered, [=, &open_view](bool state){
vinst->presentWidget()->setParent(nullptr);
bind_window->doRetrieve(wrap_v);
bind_window->doClose(wrap_v);
delete vinst;
disconnect(act_item, &QAction::triggered, nullptr, nullptr);
connect(act_item, &QAction::triggered, open_view);
});
}
};
connect(act_item, &QAction::triggered, open_view);
}
mbar->addMenu(build_op);
build_op->addActions(msg_present->bindMenu()->actions());
mbar->addMenu(tool_op);
mbar->addMenu(system_op);
system_op->addAction("关于Qt", []() { QApplication::aboutQt(); });
}
auto action_list = edit_op->actions();
for(auto &it : action_list)
edit_op->removeAction(it);
}

42
WordsIDE/session_binder.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef SESSIONBINDER_H
#define SESSIONBINDER_H
#include "project_view.h"
#include <QList>
#include <QMainWindow>
#include <QStandardItemModel>
#include <libConfig.h>
#include <present_container.h>
#include <SplitWindow.h>
class MainWindow;
namespace Core {
class SessionBinder : public QObject {
Q_OBJECT
public:
SessionBinder(XApp *core);
void menus_refresh(QMenuBar *mbar, bool rebuild = false);
private:
split_window::SplitWindow *const bind_window;
Components::ProjectView *const pjt_manager;
Components::MessageView *const msg_present;
XApp *const bind_core;
QMenu *const project_op; // 项目文件管理
QMenu *const edit_op; // 单个文件编辑操作
QMenu *const view_op; // 窗口视图管理操作
QMenu *const build_op; // 编译服务
QMenu *const tool_op; // 拓展工具
QMenu *const system_op; // 系统菜单
QList<Components::ExtendView*> actived_views;
};
} // namespace Core
#endif // SESSIONBINDER_H

View File

@ -42,6 +42,7 @@ namespace Presents {
virtual void beforeClose() override;
virtual Core::DocumentsManager *docsManager() const override;
virtual Core::Route accessPath() const override;
virtual QMenu *bindMenu() const override;
};
class StorySourceEditFactory : public Presents::TypedPresentFactory<StorySourceEdit> {

View File

@ -1,147 +0,0 @@
#include "viewsession.h"
#include "mainwindow.h"
#include "messageview.h"
#include "presentcontainerview.h"
#include "projectview.h"
using namespace Config;
using namespace Core;
using namespace SplitFrame;
using namespace Components;
ViewSession::ViewSession(Config::Configration *port, MainWindow *host) : host(host->bindPresent()), recover_port(port) {
base_path = {"sys-config", "front-end", host->layoutName(), "view-state"};
}
void ViewSession::initPresentView(PresentContainerView *center_frame, ProjectView *project_present, QStandardItemModel *error_model) {
split_infos.clear();
auto project_panel = host->appendView(project_present, QIcon(":/ui/icons/dir_icon.jpg"), tr("项目管理"));
host->markFreedom(project_panel);
view_store[project_panel->title()] = project_panel;
edit_panel = host->appendView(center_frame, QIcon(":/ui/icons/file_icon.jpg"), tr("编辑窗口"));
view_store[edit_panel->title()] = edit_panel;
auto msg_view = MessageView::gen(host, error_model);
auto msg_panel = host->appendView(msg_view, QIcon(":/ui/icons/file_icon.jpg"), "信息提示");
host->markFreedom(msg_panel);
view_store[msg_panel->title()] = msg_panel;
}
void views_state_store(Config::Configration *port, const QList<QString> &base_path, const QList<RectCom *> &child) {
for (auto &it : child) {
if (!it)
continue;
auto keys_path = base_path;
keys_path << QString("rect_%1").arg(child.indexOf(it));
auto conv = dynamic_cast<SplitView *>(it);
if (conv) { // split
QHash<QString, QString> values;
values["rect-type"] = "split";
values["split-type"] = QString("%1").arg((int)conv->splitType());
values["split-width"] = QString("%1").arg(conv->splitterWidth());
values["split-pos"] = QString("%1").arg(conv->splitterPos());
port->setMap(keys_path, values);
auto split_childs = conv->child();
views_state_store(port, keys_path, QList<RectCom *>() << split_childs.first << split_childs.second);
} else { // view
QHash<QString, QString> values;
values["rect-type"] = "view";
values["view-title"] = it->title();
port->setMap(keys_path, values);
}
}
}
void ViewSession::viewStatesSave(QMainWindow *win, SplitFrame::SplitPanel *root) {
recover_port->deleteX(base_path);
auto childs = root->child();
auto grect = win->geometry();
QHash<QString, QString> values;
values["win-width"] = QString("%1").arg(grect.width());
values["win-height"] = QString("%1").arg(grect.height());
values["win-xpos"] = QString("%1").arg(grect.topLeft().x());
values["win-ypos"] = QString("%1").arg(grect.topLeft().y());
recover_port->setMap(base_path, values);
views_state_store(recover_port, base_path, QList<RectCom *>() << childs.first << childs.second);
}
RectCom *ViewSession::views_state_restore(const QHash<QString, SplitFrame::RectCom *> &cache, const QList<QString> &target_path,
Config::Configration *port, SplitFrame::SplitPanel *host) {
auto values = port->getMap(target_path);
if (!values.size())
return nullptr;
auto type = values["rect-type"];
if (type == "view") {
auto title = values["view-title"];
auto view = cache[title];
host->markFreedom(view, false);
return view;
} else {
auto key_p0 = target_path;
key_p0 << "rect_0";
auto rect0 = views_state_restore(cache, key_p0, port, host);
auto key_p1 = target_path;
key_p1 << "rect_1";
auto rect1 = views_state_restore(cache, key_p1, port, host);
auto ori = values["split-type"].toUInt();
auto width = values["split-width"].toFloat();
auto pos = values["split-pos"].toFloat();
auto split = host->createSplit(rect0, rect1);
this->split_infos[split] = std::make_tuple((SplitType)ori, pos, width);
return split;
}
}
void ViewSession::relayout_cascade(SplitFrame::RectCom *root) {
auto xinst = dynamic_cast<SplitView *>(root);
if (!xinst)
return;
auto info = split_infos[xinst];
xinst->setSplitInfo(std::get<0>(info), std::get<1>(info), std::get<2>(info));
auto child_pair = xinst->child();
relayout_cascade(child_pair.first);
relayout_cascade(child_pair.second);
}
bool ViewSession::eventFilter(QObject *watched, QEvent *event) {
if (watched == (QObject *)host && event->type() == QEvent::Show) {
relayout_cascade(host->child().first);
host->bind()->removeEventFilter(this);
}
return QObject::eventFilter(watched, event);
}
void ViewSession::viewStatesRestore(QMainWindow *win, SplitFrame::SplitPanel *root) {
auto key_path0 = base_path;
key_path0 << "rect_0";
auto rect = views_state_restore(this->view_store, key_path0, recover_port, root);
if (!rect)
rect = edit_panel;
root->resetEngross(rect);
root->objsRelateRebuild();
auto values = recover_port->getMap(base_path);
auto width = values["win-width"].toFloat();
auto height = values["win-height"].toFloat();
auto xpos = values["win-xpos"].toFloat();
auto ypos = values["win-ypos"].toFloat();
win->setGeometry(xpos, ypos, width, height);
root->bind()->installEventFilter(this);
}

View File

@ -1,49 +0,0 @@
#ifndef VIEWSESSION_H
#define VIEWSESSION_H
#include "projectview.h"
#include <QList>
#include <QMainWindow>
#include <QStandardItemModel>
#include <libConfig.h>
#include <presentcontainerview.h>
#include <splitwindow.h>
class MainWindow;
namespace Core {
class ViewSession : public QObject {
Q_OBJECT
public:
ViewSession(Config::Configration *port, MainWindow *host);
void initPresentView(Components::PresentContainerView *center_frame, Components::ProjectView *project_present, QStandardItemModel *model);
void viewStatesSave(QMainWindow *win, SplitFrame::SplitPanel *root);
void viewStatesRestore(QMainWindow *win, SplitFrame::SplitPanel *root);
private:
QList<QString> base_path;
SplitFrame::SplitPanel *host;
SplitFrame::RectCom *edit_panel = nullptr;
Config::Configration *const recover_port;
QHash<QString, SplitFrame::RectCom *> view_store;
typedef float split_pos;
typedef float split_width;
std::map<SplitFrame::SplitView *, std::tuple<SplitFrame::SplitType, split_pos, split_width>> split_infos;
SplitFrame::RectCom *views_state_restore(const QHash<QString, SplitFrame::RectCom *> &cache, const QList<QString> &target_path,
Config::Configration *port, SplitFrame::SplitPanel *host);
void relayout_cascade(SplitFrame::RectCom *root);
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
};
} // namespace Core
#endif // VIEWSESSION_H

View File

@ -1,61 +0,0 @@
#include "viewstackedbar.h"
#include <QLayout>
#include <QMainWindow>
using namespace Components;
using namespace SplitFrame;
ViewStackedBar::ViewStackedBar(SplitPanel *host, QWidget *parent) : QToolBar(parent), host_ptr(host) {
setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonIconOnly);
setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea | Qt::BottomToolBarArea);
setContextMenuPolicy(Qt::CustomContextMenu);
layout()->setMargin(0);
layout()->setSpacing(0);
setIconSize(QSize(30, 30));
}
void ViewStackedBar::freedomAppended(SplitFrame::RectCom *ins, const QIcon &icon, const QString &title) {
if (freedom_views.contains(ins))
return;
auto action = addAction(icon, title);
freedom_views[ins] = action;
connect(action, &QAction::triggered, [ins, this]() {
if (host_ptr->isTemporaryView(ins)) {
host_ptr->temporaryVisible(DockType::LEFT);
} else {
auto pinst = static_cast<QMainWindow *>(this->parent());
DockType position = DockType::LEFT;
switch (pinst->toolBarArea(this)) {
case Qt::ToolBarArea::BottomToolBarArea:
position = DockType::BOTTOM;
break;
case Qt::ToolBarArea::TopToolBarArea:
position = DockType::TOP;
break;
case Qt::ToolBarArea::LeftToolBarArea:
position = DockType::LEFT;
break;
case Qt::ToolBarArea::RightToolBarArea:
position = DockType::RIGHT;
break;
default:
break;
}
host_ptr->temporaryVisible(position, ins);
}
});
}
void ViewStackedBar::freedomRemoved(SplitFrame::RectCom *ins) {
if (freedom_views.contains(ins)) {
auto action = freedom_views[ins];
removeAction(action);
freedom_views.remove(ins);
}
}

View File

@ -1,25 +0,0 @@
#ifndef VIEWSTACKEDBAR_H
#define VIEWSTACKEDBAR_H
#include <QHash>
#include <QToolBar>
#include <splitwindow.h>
namespace Components {
class ViewStackedBar : public QToolBar, public SplitFrame::FreedomViewsListener {
public:
ViewStackedBar(SplitFrame::SplitPanel *host, QWidget *parent = nullptr);
// FreedomViewsListener interface
public:
virtual void freedomAppended(SplitFrame::RectCom *ins, const QIcon &icon, const QString &title) override;
virtual void freedomRemoved(SplitFrame::RectCom *ins) override;
private:
SplitFrame::SplitPanel *const host_ptr;
QHash<SplitFrame::RectCom *, QAction *> freedom_views;
};
} // namespace Components
#endif // VIEWSTACKEDBAR_H

View File

@ -35,3 +35,8 @@ QString WelcomePanel::absoluteTargetPath() const { return ""; }
bool WelcomePanel::isModified() const { return false; }
void WelcomePanel::jumpTo(const QList<QString> &path) {}
QMenu *WelcomePanel::bindMenu() const
{
return nullptr;
}

View File

@ -29,6 +29,7 @@ namespace Presents {
virtual QString absoluteTargetPath() const override;
virtual bool isModified() const override;
virtual void jumpTo(const QList<QString> &path) override;
virtual QMenu *bindMenu() const override;
};
} // namespace Presents

View File

@ -15,7 +15,10 @@ XApp::XApp(int argc, char **argv)
: QApplication(argc, argv),
parse_service(new ParseBridge()),
project_manager(new XMLProjectManager(this)),
active_docscollect(new DocumentsManager(this)) {
active_docscollect(new DocumentsManager(this)),
disp_core(new CommandsDispatcher(QDir("./"), true)),
gconfig(new XMLConfig)
{
gconfig->loadFile("./software.config");
init_commands(disp_core);
@ -38,7 +41,7 @@ ParseBridge *XApp::parseService() const { return parse_service; }
ProjectManager *XApp::pjtManager() const { return project_manager; }
DocumentsManager *XApp::docsManager() const { return active_docscollect; }
DocumentsManager *XApp::docsPort() const { return active_docscollect; }
using namespace CommandList;
void XApp::init_commands(Schedule::CommandsDispatcher *host) {
@ -52,6 +55,3 @@ void XApp::init_commands(Schedule::CommandsDispatcher *host) {
host->registerCommand(new SaveAll());
host->registerCommand(new DeleteTarget(Route()));
}
CommandsDispatcher *const XApp::disp_core = new CommandsDispatcher(QDir("./"), true);
Configration *const XApp::gconfig = new XMLConfig();

View File

@ -9,24 +9,33 @@
#include <libConfig.h>
#include <libProjectManager.h>
namespace Components {
class ExtendView;
}
class XApp : public QApplication {
public:
XApp(int argc, char **argv);
virtual bool notify(QObject *receiver, QEvent *event);
QList<Components::ExtendView*> viewTemplates() const;
bridge::ParseBridge *parseService() const;
Project::ProjectManager *pjtManager() const;
Core::DocumentsManager *docsManager() const;
Core::DocumentsManager *docsPort() const;
Schedule::CommandsDispatcher *cmdsPort() const;
QStandardItemModel* messageModel() const;
public:
static Schedule::CommandsDispatcher *const disp_core;
static Config::Configration *const gconfig;
private:
bridge::ParseBridge *const parse_service;
Project::ProjectManager *const project_manager;
Core::DocumentsManager *const active_docscollect;
Schedule::CommandsDispatcher *const disp_core;
Config::Configration *const gconfig;
void init_commands(Schedule::CommandsDispatcher *core);
};

View File

@ -130,11 +130,19 @@ void accept_panel::AcceptPanel::dropEvent(QDropEvent *ev)
view_manager->doRetrieve(view);
view_manager->siblingAttach(view, anchor_view, SplitType::SPLIT_V_BFIRST);
break;
case HoverType::CUBE_CENTER:
case HoverType::CUBE_CENTER: {
view_manager->doRetrieve(view);
anchor_view->parentRes()->replaceView(view, anchor_view);
view_manager->doRetrieve(anchor_view);
break;
auto pinst = anchor_view->parentRes();
if(pinst){
pinst->replaceView(view, anchor_view);
view_manager->doRetrieve(anchor_view);
dynamic_cast<split_window::SplitWindow*>(view_manager)->freedomHasBeenRemoved(view);
}else{
view_manager->doRetrieve(anchor_view);
dynamic_cast<split_window::SplitWindow*>(view_manager)->setPresentTarget(view);
}
view->setVisible(true);
} break;
default:
break;
}

View File

@ -13,6 +13,7 @@ using namespace dock_panel;
DragHeader::DragHeader(const QString &title, DockableView *bind_core)
: QFrame(bind_core),
bind_core(bind_core),
icon_holder(new QLabel(this)),
title_holder(new QLabel(this)),
close_btn(new QPushButton("x",this)),
minimal_btn(new QPushButton("-",this)) {
@ -22,6 +23,9 @@ DragHeader::DragHeader(const QString &title, DockableView *bind_core)
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
icon_holder->setPixmap(QIcon(":/icons/headertop/story.png").pixmap(22,22));
layout->addWidget(icon_holder, 0, Qt::AlignLeft);
title_holder->setText(title);
title_holder->setContentsMargins(2,0, 0, 0);
layout->addWidget(title_holder, 1, Qt::AlignLeft);
@ -51,7 +55,7 @@ void DragHeader::setTitle(const QString &title)
void DragHeader::setTitle(const QString &title, const QIcon &icon)
{
this->setTitle(title);
this->title_holder->setPixmap(icon.pixmap(22, 22));
this->icon_holder->setPixmap(icon.pixmap(22, 22));
}
void DragHeader::optConfig(bool retrieve, bool close)
@ -104,6 +108,9 @@ DockableView::DockableView(split_frame::ResManager *mgr, QWidget *present)
layout->addWidget(new QWidget(this));
}
this->icon_store = QIcon(":/icons/headertop/story.png");
title_header->setTitle("未命名", icon_store);
layout->setSpacing(0);
layout->setContentsMargins(0, 2, 0, 0);
@ -117,11 +124,12 @@ DockableView::DockableView(split_frame::ResManager *mgr, QWidget *present)
connect(this->title_header, &DragHeader::retrieveRequest, this, &DockableView::retrieveAccept);
connect(this->title_header, &DragHeader::closeRequest, this, &DockableView::closeAccept);
connect(this->title_header, &DragHeader::adjustRequest, this, &DockableView::adjustAccept);
viewConfig(m_replace, m_close, m_retrieve);
}
DockableView::~DockableView() {
manager_inst->removePresentView(this);
qDebug() << "view-deleted";
}
void DockableView::viewConfig(bool replace, bool close, bool retrieve)

View File

@ -18,6 +18,7 @@ namespace dock_panel {
Q_OBJECT
private:
DockableView *const bind_core;
QLabel *const icon_holder;
QLabel *const title_holder;
QPushButton *const close_btn, *const minimal_btn;
std::tuple<bool, QPointF> press_flag = std::make_tuple(false, QPointF());
@ -56,7 +57,7 @@ namespace dock_panel {
/**
* @brief
*/
class SPLITVIEW_EXPORT DockableView : public QWidget, public split_frame::ViewBase {
class SPLITVIEW_EXPORT DockableView : public QFrame, public split_frame::ViewBase {
public:
/**
* @brief
@ -65,13 +66,7 @@ namespace dock_panel {
*/
DockableView(split_frame::ResManager*mgr, QWidget *present);
virtual ~DockableView();
/**
* @brief
* @param replace
* @param close
* @param retrieve
*/
void viewConfig(bool replace, bool close, bool retrieve);
/**
* @brief
@ -91,7 +86,7 @@ namespace dock_panel {
split_frame::ResManager *const manager_inst;
QIcon icon_store;
split_frame::SplitView *parent_res = nullptr;
bool m_replace = false, m_retrieve = false, m_close = false;
bool m_replace = true, m_retrieve = true, m_close = true;
// ViewRes interface
public:
@ -108,6 +103,7 @@ namespace dock_panel {
// ViewBase interface
public:
virtual void viewConfig(bool replace, bool close, bool retrieve) override;
virtual QIcon icon() const override;
virtual QString title() const override;
virtual bool canRetrieve() const override;

View File

@ -9,7 +9,7 @@ using namespace Config;
DragSplitter::DragSplitter(split_frame::SplitType split, split_frame::ViewRes *parent)
: QFrame(parent->widget()){
this->setFrameShape(QFrame::Shape::WinPanel);
this->setFrameShape(QFrame::Shape::StyledPanel);
this->setFrameShadow(QFrame::Shadow::Raised);
switch (split) {
@ -185,7 +185,7 @@ void SplitPanel::sync_status()
auto second = this->split_member.second;
first->setOutline(QRectF(0, 0, width_a, total_h));
second->setOutline(QRectF(width_a + std::get<2>(split_info), 0, width_b, total_h));
second->setOutline(QRectF(width_a + std::get<2>(split_info) - 1, 0, width_b + 1, total_h));
this->splitter_inst->setGeometry(QRect(width_a, 0, std::get<2>(split_info), total_h));
} break;
case SplitType::SPLIT_V_BFIRST:

View File

@ -25,14 +25,49 @@ SplitWindow::SplitWindow(QWidget *parent)
view_root(nullptr) {
accept_port->setVisible(false);
this->addToolBar(Qt::ToolBarArea::LeftToolBarArea, unused_stack);
unused_stack->setMovable(false);
this->addListener(this);
}
SplitWindow::~SplitWindow() {this->active = false;}
void SplitWindow::tempShow(split_frame::DockType t, split_frame::ViewBase *target)
void SplitWindow::tempShow(split_frame::ViewBase *target)
{
this->temp_show = target;
target->setVisible(true);
if(target){
this->temp_show = target;
auto current_center = centralWidget();
if(!current_center){
this->setCentralWidget(temp_show->widget());
freedomHasBeenRemoved(target);
appendPresentView(target);
view_root = target;
}
else{
auto twidget = this->centralWidget();
this->temp_show->widget()->setParent(twidget);
this->temp_show->widget()->setGeometry(0, 0, twidget->width()/3, twidget->height());
}
target->setVisible(true);
}
else if(temp_show){
this->temp_show->widget()->setParent(nullptr);
this->temp_show->setVisible(false);
this->temp_show = nullptr;
}
}
void SplitWindow::freedomHasBeenRemoved(split_frame::ViewBase *inst)
{
for(auto &it : listener_list)
it->freedomRemove(inst);
}
void SplitWindow::freedomHasBeenAppended(split_frame::ViewBase *inst)
{
for(auto &it : listener_list)
it->freedomAppend(inst);
}
void SplitWindow::setPresentTarget(split_frame::ViewRes *inst)
@ -44,6 +79,8 @@ void SplitWindow::setPresentTarget(split_frame::ViewRes *inst)
inst->setParentRes(nullptr);
inst->widget()->setParent(this);
this->setCentralWidget(inst->widget());
appendPresentView(dynamic_cast<ViewBase*>(inst));
freedomHasBeenRemoved(dynamic_cast<ViewBase*>(inst));
} else if (!inst) {
this->takeCentralWidget();
}
@ -103,8 +140,13 @@ void SplitWindow::removeListener(split_frame::FreedomViewsListener *lsn)
void SplitWindow::appendPresentView(split_frame::ViewBase *inst)
{
if(this->active && inst)
if(this->active && inst){
if(!isPresented(inst)){
freedomHasBeenRemoved(inst);
}
this->presents_store[inst->hashCode()] = inst;
}
}
void SplitWindow::removePresentView(split_frame::ViewBase *inst)
@ -123,15 +165,14 @@ bool SplitWindow::isPresented(split_frame::ViewBase *inst) const
void SplitWindow::doRetrieve(split_frame::ViewBase *inst)
{
if(!isPresented(inst)){
throw new Config::SimpleException<QString>("参数错误", "无法回收空闲视图!");
if(inst == temp_show){
temp_show->setVisible(false);
}
return;
}
// 呈现视图结构调整
if(inst == temp_show){
temp_show->setVisible(false);
return;
}
else if (inst == view_root) {
if (inst == view_root) {
setPresentTarget();
inst->setParentRes(nullptr);
}
@ -162,8 +203,7 @@ void SplitWindow::doRetrieve(split_frame::ViewBase *inst)
removePresentView(inst);
// 当前视图已被回收
for(auto &lsn : listener_list)
lsn->freedomAppend(inst);
freedomHasBeenAppended(inst);
}
void SplitWindow::doClose(split_frame::ViewBase *inst)
@ -218,8 +258,7 @@ void SplitWindow::siblingAttach(ViewBase *view, ViewBase *pos, SplitType ori)
break;
}
for(auto &lsn : listener_list)
lsn->freedomRemove(view);
freedomHasBeenRemoved(view);
}
ViewBase *SplitWindow::adjustView() const
@ -231,3 +270,55 @@ void SplitWindow::setAdjustView(split_frame::ViewBase *target)
{
this->adjust_target = target;
}
void SplitWindow::freedomAppend(split_frame::ViewBase *ins)
{
if(ins && !freedom_records.contains(ins->hashCode())){
freedom_records[ins->hashCode()]=std::make_tuple(ins, ins->canReplace(), ins->canClose(), ins->canRetrieve());
ins->viewConfig(false, false, false);
auto act = this->unused_stack->addAction(ins->title(), [this, ins](bool state) {
if (state) {
this->tempShow(ins);
} else {
this->tempShow(nullptr);
}
});
act->setData(ins->hashCode());
act->setIcon(ins->icon());
act->setCheckable(true);
}
}
void SplitWindow::freedomRemove(split_frame::ViewBase *ins)
{
if (ins && freedom_records.contains(ins->hashCode())) {
auto allacts = unused_stack->actions();
for (auto &act : allacts) {
if (act->data().toULongLong() == ins->hashCode()) {
unused_stack->removeAction(act);
break;
}
}
auto record = freedom_records[ins->hashCode()];
ins->viewConfig(std::get<1>(record), std::get<2>(record), std::get<3>(record));
freedom_records.remove(ins->hashCode());
}
}
void SplitWindow::aboutToBeDelete(split_frame::ViewBase *inst)
{
this->freedomRemove(inst);
}
void SplitWindow::hasBeenAppend(split_frame::ViewBase *inst)
{
}
void SplitWindow::focusInEvent(QFocusEvent *event)
{
QMainWindow::focusInEvent(event);
emit this->windowActived(this);
}

View File

@ -14,9 +14,8 @@ namespace split_window {
/**
* @brief
*/
class SPLITVIEW_EXPORT SplitWindow : public QMainWindow, public split_frame::ResManager {
typedef float pos;
typedef float width;
class SPLITVIEW_EXPORT SplitWindow : public QMainWindow, public split_frame::ResManager, public split_frame::FreedomViewsListener {
Q_OBJECT
private:
bool active = false;
@ -28,6 +27,9 @@ namespace split_window {
split_frame::ViewRes *view_root = nullptr, *temp_show = nullptr;
split_frame::ViewBase *adjust_target = nullptr;
// freedom-recordstuple<IDtuple<ptr,replace,close,retrieve>>
QHash<qulonglong, std::tuple<split_frame::ViewBase*, bool, bool, bool>> freedom_records;
public:
SplitWindow(QWidget *parent = nullptr);
@ -39,16 +41,22 @@ namespace split_window {
* @param t
* @param target
*/
void tempShow(split_frame::DockType t, split_frame::ViewBase *target);
void tempShow(split_frame::ViewBase *target);
void freedomHasBeenRemoved(split_frame::ViewBase *inst);
void freedomHasBeenAppended(split_frame::ViewBase *inst);
/**
* @brief * @param inst
* @brief
* @param inst
*/
void setPresentTarget(split_frame::ViewRes *inst = nullptr);
bool eventFilter(QObject *sender, QEvent *ev) override;
signals:
void windowActived(split_window::SplitWindow *inst);
// ResManager interface
public:
virtual void addListener(split_frame::FreedomViewsListener *lsn) override;
@ -61,6 +69,17 @@ namespace split_window {
virtual void siblingAttach(split_frame::ViewBase *view, split_frame::ViewBase *pos, split_frame::SplitType ori) override;
virtual split_frame::ViewBase *adjustView() const override;
virtual void setAdjustView(split_frame::ViewBase *target) override;
// FreedomViewsListener interface
public:
virtual void freedomAppend(split_frame::ViewBase *ins) override;
virtual void freedomRemove(split_frame::ViewBase *ins) override;
virtual void aboutToBeDelete(split_frame::ViewBase *inst) override;
virtual void hasBeenAppend(split_frame::ViewBase *inst) override;
// QWidget interface
protected:
virtual void focusInEvent(QFocusEvent *event) override;
};
} // namespace split_panel

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/icons/headertop">
<file>story.png</file>
</qresource>
</RCC>

View File

@ -86,6 +86,13 @@ namespace split_frame {
public:
virtual ~ViewBase() = default;
/**
* @brief
* @param replace
* @param close
* @param retrieve
*/
virtual void viewConfig(bool replace, bool close, bool retrieve) = 0;
/**
* @brief
* @return
@ -129,7 +136,9 @@ namespace split_frame {
virtual void initViews(ViewRes *a, ViewRes *b) = 0;
/**
* @brief * @param view * @param pos
* @brief
* @param view
* @param pos
*/
virtual void replaceView(ViewRes *_new, ViewRes *_old) = 0;

View File

@ -40,3 +40,6 @@ else:unix: LIBS += -L$$OUT_PWD/../libConfig/ -llibConfig
INCLUDEPATH += $$PWD/../libConfig
DEPENDPATH += $$PWD/../libConfig
RESOURCES += \
defaulticon.qrc

BIN
libSplitView/story.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

37
libTextEdit/README.md Normal file
View File

@ -0,0 +1,37 @@
# 文本编辑控件
## 创建原因
1. 实现一个可以自主掌控的源码编辑控件
2. 验证自己的设计理念,学习基本的文本排版技术
3. 市面上没有一个开源好用的源码编辑器需要以C++内存模型对外暴露文档模型,方便编辑和解析
4. 需要多线程处理高亮渲染,以应对大规模关键词渲染需求
5. 同一个文档模型多开视图窗口,自动同步修改内容,同一模型不同的渲染视图的渲染结果互不影响
6. 自动补全功能
7. 富文本元素排版
8. Unicode内建支持
## 设计目标
1. 富文本渲染控件
1. 支持排版元素:“文本”、“图片”、“超链接”、“列表”、“表格”、“视频”、“音频”;
2. 支持编辑内容:“文本”、“表格”、“列表”
3. 支持编辑引用:“图片”,“超链接”,“视频”,“音频”;
4. 支持元素折叠和展开
5. 块级元素内建排版格式,行内元素排版方向内建
2. 源码文本编辑控件
1. 纯文本控件,支持编辑和呈现文本元素
2. 多种文本格式混合排版
3. 支持块级元素折叠和展开
4. 全局统一排版方向,行内元素排版方向内建
## 开发路线图
1. 基本的源码展示控件WsTextPresent
2. 基本的源码编辑控件WsTextEdit
3. 富文本渲染控件WsRichTextPresent
## WsTextPresent项目开发
### 设计思路
1. 纯文本输入和输出,除了换行符进行内建处理,其他的文本元素一视同仁;
2. 多视角设计:基础内存模型视角,元素排版视角、文本编辑视角;
3. 多线程语法高亮,关键词渲染
4. 统一文档内存模型,多视图渲染
5. 纸稿排版逻辑,基于预设排版位置
6. 全局文档布局设置、段落文档布局设置、行文档布局设置、文本片段布局设置

View File

@ -1,24 +0,0 @@
#include "blockdatas.h"
using namespace PresentDatas;
DisplayGroup::DisplayGroup(const QString &uid) : SpecificEntityData(EntityType::DISPLAY_GROUP, uid) {}
QString DisplayGroup::styledText() const {
QString retvs = QString("<group id='%1'>\n").arg(this->uID());
for (auto &i : children())
retvs += i->styledText();
retvs += "</group>\n";
return retvs;
}
QString DisplayGroup::plainText() const {
QString retvs = "";
for (auto &i : children())
retvs += i->plainText();
retvs += "\n";
return retvs;
}
TextRange::TextRange(const QString &uid) : SpecificEntityData(EntityType::TEXT_RANGE, uid) {}

View File

@ -1,46 +0,0 @@
#ifndef BLOCKDATAS_H
#define BLOCKDATAS_H
#include "entitydata.h"
namespace PresentDatas {
/* enum class EntityType {
TEXT_RANGE, // 字符集合,包含段落和句子
IMAGE_CUBE, // 图片展示块
HREF_FRAGS, // 超链接
TABLE_VIEW, // 表格视图
LIST_VIEW, // 列表视图
INTERACTIVE_EXTENSION, // 交互式拓展插件视图
DISPLAY_GROUP, // 元素混合组织成包
DOCUMENT_ENTITY
};*/
class DisplayGroup : public SpecificEntityData {
public:
DisplayGroup(const QString &uid);
public:
// EntityData interface
public:
virtual QString styledText() const override;
virtual QString plainText() const override;
};
class TextRange : public SpecificEntityData {
public:
TextRange(const QString &uid);
void setStyledText(const QString &content);
void setPlainText(const QString &content);
// EntityData interface
public:
virtual QString styledText() const override;
virtual QString plainText() const override;
private:
};
} // namespace PresentDatas
#endif // BLOCKDATAS_H

View File

@ -1,97 +0,0 @@
#include "entitydata.h"
#include <QList>
using namespace PresentDatas;
SpecificEntityData::SpecificEntityData(EntityType type, const QString &uid) : type_store(type), document_id(uid) {
visible_bool = true;
oritation_store = MemberOri::H_LEFT_TO_RIGHT;
}
void SpecificEntityData::resetContentLayout(MemberOri oritation, MemberType child_type) {
this->oritation_store = oritation;
this->layout_type = child_type;
this->layout_type = MemberType::BLOCKS;
this->anchor_info = std::make_tuple(AnchorTarget::NONE, nullptr, AnchorPos::POINT_LEFT_TOP, 0, 0);
this->size_min = QSizeF(20, 20);
}
void SpecificEntityData::setVisible(bool state){
this->visible_bool = state;
}
void SpecificEntityData::setAnchorTo(AnchorTarget type, EntityData *tptr) {
anchor_info = std::make_tuple(type, tptr, std::get<2>(anchor_info), std::get<3>(anchor_info), std::get<4>(anchor_info));
}
void SpecificEntityData::setAnchorPos(AnchorPos point, offset_h hoffset, offset_v v_offset) {
anchor_info = std::make_tuple(std::get<0>(anchor_info), std::get<1>(anchor_info), point, hoffset, v_offset);
}
void SpecificEntityData::insertChild(EntityData *inst, int index) {
if (index >= 0 && index < children_store.size())
this->children_store.insert(index, inst);
else
this->children_store.append(inst);
}
void SpecificEntityData::removeChild(EntityData *inst) { this->children_store.removeAll(inst); }
void SpecificEntityData::setMinSizeHint(const QSizeF &hint) { this->size_min = hint; }
void SpecificEntityData::setMaxSizeHint(const QSizeF &hint) { this->size_max = hint; }
void SpecificEntityData::setStretchHint(const std::pair<float, float> &hint) { this->stretch_pair = hint; }
QString SpecificEntityData::uID() const { return document_id; }
EntityType SpecificEntityData::type() const { return type_store; }
MemberOri SpecificEntityData::oritation() const { return oritation_store; }
MemberType SpecificEntityData::displayType() const { return layout_type; }
std::pair<AnchorTarget, EntityData *> SpecificEntityData::anchorTarget() const {
return std::make_pair(std::get<0>(anchor_info), std::get<1>(anchor_info));
}
std::tuple<AnchorPos, EntityData::offset_h, EntityData::offset_v> SpecificEntityData::anchorPos() const {
return std::make_tuple(std::get<2>(anchor_info), std::get<3>(anchor_info), std::get<4>(anchor_info));
}
QList<EntityData *> SpecificEntityData::children() const { return children_store; }
bool SpecificEntityData::isVisible() const { return visible_bool; }
QSizeF SpecificEntityData::minSizeHint() const { return this->size_min; }
QSizeF SpecificEntityData::maxSizeHint() const { return this->size_max; }
std::pair<float, float> SpecificEntityData::sizeStretchHint() const { return stretch_pair; }
Document::Document(const QString &name) : SpecificEntityData(EntityType::DOCUMENT_ENTITY, "Document-Unique") {
resetContentLayout(MemberOri::H_LEFT_TO_RIGHT, MemberType::BLOCKS);
}
QString Document::styledText() const
{
QString values = "<docment type = '7' visible='true' >\n";
for(auto &i : children())
values += i->styledText();
values += "</document>";
return values;
}
QString Document::plainText() const
{
QString values = "";
for(auto &i : children())
if(i->isVisible())
values += i->plainText();
return values;
}
void Document::resetContentLayout(MemberOri oritation, MemberType) { SpecificEntityData::resetContentLayout(oritation, MemberType::BLOCKS); }

View File

@ -1,241 +0,0 @@
#ifndef ENTITYDATA_H
#define ENTITYDATA_H
#include <QList>
#include <QRectF>
#include <QString>
#include <tuple>
namespace PresentDatas {
enum class EntityType {
TEXT_RANGE, // 字符集合,包含段落和句子
IMAGE_CUBE, // 图片展示块
HREF_FRAGS, // 超链接
TABLE_VIEW, // 表格视图
LIST_VIEW, // 列表视图
INTERACTIVE_EXTENSION, // 交互式拓展插件视图
DISPLAY_GROUP, // 元素混合组织成包
DOCUMENT_ENTITY
};
enum class MemberOri {
H_LEFT_TO_RIGHT, // 从左到右横向排版
H_RIGHT_TO_LEFT, // 从右到左横向排版
H_CENTER_IN, // 中央对准横向排布
V_LEFT_TO_RIGHT, // 从左到右纵向排布
V_RIGHT_TO_LEFT, // 从右到左纵向排布
V_CENTER_IN // 中央对准纵向排布
};
enum class MemberType {
BLOCKS, // 成员被视为块元素
INLINES // 成员被视图行内元素
};
enum class AnchorTarget {
NONE, // 文档二维平面排版
WINDOW, // 窗口相对偏移定位
DOCUMENT, // 文档相对偏移定位
ELEMENT //元素相对偏移定位
};
enum class AnchorPos {
NONE,
POINT_LEFT_TOP,
POINT_LEFT_CENTER,
POINT_LEFT_BOTTOM,
POINT_CENTER_TOP,
POINT_CENTER_BOTH,
POINT_CENTER_BOTTOM,
POINT_RIGHT_TOP,
POINT_RIGHT_CENTER,
POINT_RIGHT_BOTTOM
};
/**
* @brief
*/
class EntityData {
public:
virtual ~EntityData() = default;
// 标定相关 =================================================================
/**
* @brief ID
* @return
*/
virtual QString uID() const = 0;
/**
* @brief
* @return
*/
virtual QString styledText() const = 0;
/**
* @brief
* @return
*/
virtual QString plainText() const = 0;
// 实体属性 ===================================================================
/**
* @brief
* @return
*/
virtual bool isVisible() const = 0;
/**
* @brief
* @return
*/
virtual EntityType type() const = 0;
// 排版相关 ===================================================================
/**
* @brief
* @return
*/
virtual MemberOri oritation() const = 0;
/**
* @brief
* @return
*/
virtual MemberType displayType() const = 0;
/**
* @brief
* // pair<NONE, nullptr> 文档二维平面排版
* // pair<ELEMENT, inst_ptr> 浮动排版,文档元素定位
* // pair<WINDOW, nullptr> 浮动排版,窗口偏移定位
* // pair<DOCUMENT, nullptr> 浮动排版,文档偏移定位
* @return
*/
virtual std::pair<AnchorTarget, EntityData *> anchorTarget() const = 0;
typedef float offset_h;
typedef float offset_v;
/**
* @brief
* @return
*/
virtual std::tuple<AnchorPos, offset_h, offset_v> anchorPos() const = 0;
virtual QSizeF minSizeHint() const = 0;
virtual QSizeF maxSizeHint() const = 0;
virtual std::pair<float, float> sizeStretchHint() const = 0;
/**
* @brief
* @return
*/
virtual QList<EntityData *> children() const = 0;
};
/**
*
*/
class SpecificEntityData : public EntityData {
public:
SpecificEntityData(EntityType type, const QString &uid);
virtual ~SpecificEntityData() = default;
/**
* @brief
* @param oritation
* @param child_type
*/
virtual void resetContentLayout(MemberOri oritation, MemberType child_type);
/**
* @brief
* @param state
*/
virtual void setVisible(bool state);
/**
* @brief
* @param type
* @param tptr
*/
virtual void setAnchorTo(AnchorTarget type, EntityData *tptr = nullptr);
/**
* @brief
* @param point
* @param hoffset
* @param v_offset
*/
virtual void setAnchorPos(AnchorPos point, EntityData::offset_h hoffset, EntityData::offset_v v_offset);
/**
* @brief
* @param inst
* @param index -1
*/
virtual void insertChild(EntityData *inst, int index = -1);
/**
* @brief
* @param inst
*/
virtual void removeChild(EntityData *inst);
virtual void setMinSizeHint(const QSizeF &hint);
virtual void setMaxSizeHint(const QSizeF &hint);
virtual void setStretchHint(const std::pair<float, float> &hint);
virtual void setStyledText(const QString &content) = 0;
virtual void setPlainText(const QString &content) = 0;
// EntityData ====================================================
virtual QString uID() const override;
virtual EntityType type() const override;
virtual MemberOri oritation() const override;
virtual MemberType displayType() const override;
virtual std::pair<AnchorTarget, EntityData *> anchorTarget() const override;
virtual std::tuple<AnchorPos, EntityData::offset_h, EntityData::offset_v> anchorPos() const override;
virtual QList<EntityData *> children() const override;
virtual bool isVisible() const override;
virtual QSizeF minSizeHint() const override;
virtual QSizeF maxSizeHint() const override;
virtual std::pair<float, float> sizeStretchHint() const override;
private:
bool visible_bool;
EntityType type_store;
QString document_id;
MemberOri oritation_store;
MemberType layout_type;
std::tuple<AnchorTarget, EntityData *, AnchorPos, EntityData::offset_h, EntityData::offset_v> anchor_info;
QList<EntityData *> children_store;
QSizeF size_min, size_max;
std::pair<float, float> stretch_pair;
protected:
float appoint_layout_minvalue() const;
};
/**
* @brief
*/
class Document : public SpecificEntityData {
public:
Document(const QString &name);
// EntityData interface
public:
virtual QString styledText() const override;
virtual QString plainText() const override;
// SpecificEntityData interface
public:
virtual void resetContentLayout(MemberOri oritation, MemberType) override;
};
} // namespace PresentDatas
#endif // ENTITYDATA_H

View File

@ -1,4 +1,4 @@
QT -= gui
QT += gui
TEMPLATE = lib
DEFINES += LIBTEXTEDIT_LIBRARY
@ -10,15 +10,15 @@ CONFIG += c++11
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
blockdatas.cpp \
entitydata.cpp \
libtextedit.cpp
libtextedit.cpp \
text_modelx.cpp \
text_present.cpp
HEADERS += \
blockdatas.h \
entitydata.h \
libTextEdit_global.h \
libtextedit.h
libtextedit.h \
libtextedit_global.h \
text_modelx.h \
text_present.h
msvc {
QMAKE_CFLAGS += /utf-8
@ -30,3 +30,13 @@ unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
README.md
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libConfig/release/ -llibConfig
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libConfig/debug/ -llibConfig
else:unix: LIBS += -L$$OUT_PWD/../libConfig/ -llibConfig
INCLUDEPATH += $$PWD/../libConfig
DEPENDPATH += $$PWD/../libConfig

View File

@ -1,7 +1,7 @@
#ifndef LIBTEXTEDIT_H
#define LIBTEXTEDIT_H
#include "libTextEdit_global.h"
#include "libtextedit_global.h"
class LIBTEXTEDIT_EXPORT LibTextEdit
{

View File

@ -0,0 +1 @@
#include "text_modelx.h"

11
libTextEdit/text_modelx.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef TEXT_MODELX_H
#define TEXT_MODELX_H
#include "text_present.h"
namespace text_model
{
}
#endif // TEXT_MODELX_H

View File

@ -0,0 +1,314 @@
#include "text_present.h"
#include <tuple>
using namespace std;
using namespace model_text;
CharStream CharSetU16::combineToU(const QString &buffer) {
QList<uint32_t> retvs;
if (buffer.size() == 0)
return retvs;
tuple<uint32_t, int> combine_current;
auto aval = buffer[0];
if (buffer.size() < 2)
combine_current = std::make_tuple(aval.unicode(), 1);
else if (buffer.size() >= 2) {
auto bval = buffer[1];
if (aval.isHighSurrogate() && bval.isLowSurrogate()) {
uint32_t avalx = aval.unicode();
combine_current = std::make_tuple((avalx << 16) + bval.unicode(), 2);
} else {
combine_current = std::make_tuple(aval.unicode(), 1);
}
}
retvs.append(std::get<0>(combine_current));
retvs.append(combineToU(buffer.mid(std::get<1>(combine_current))));
return retvs;
}
QString CharSetU16::splitToC(const CharStream &buffer) {
if (!buffer.size())
return "";
QString acc_str = "";
auto head = buffer[0];
if (head > 0xffffu) {
auto high_v = (head & 0xffff0000u) >> 16;
auto low_v = head & 0xffffu;
auto hc = QChar((ushort)high_v);
auto lc = QChar((ushort)low_v);
acc_str.append(hc);
acc_str.append(lc);
} else {
acc_str.append(QChar((ushort)head & 0xffffu));
}
acc_str.append(splitToC(buffer.mid(1)));
return acc_str;
}
bool CharSetU16::contains(uint32_t code) {
if (code <= 0xffffu)
return true;
else {
auto high_v = (code & 0xffff0000u) >> 16;
auto low_v = code & 0xffffu;
auto hc = QChar((ushort)high_v);
auto lc = QChar((ushort)low_v);
return hc.isHighSurrogate() && lc.isLowSurrogate();
}
}
uint CharSetU16::size() { return 1114111u; }
void WsDocument::bindFormat(std::shared_ptr<DocFormat> f) { this->document_format = f; }
std::shared_ptr<DocFormat> WsDocument::getFormat() const { return this->document_format; }
uint32_t WsDocument::blockCount() const
{
return this->block_store.size();
}
QList<std::shared_ptr<WsBlock> > WsDocument::getBlocks(uint32_t offset, uint32_t count) const
{
QList<std::shared_ptr<WsBlock>> retvs;
for (auto idx = offset; idx < this->block_store.size(); ++idx)
retvs << this->block_store.at(idx);
return retvs;
}
void WsDocument::delBlocks(uint32_t offset, uint32_t count)
{
for(auto idx=offset; idx<this->block_store.size();){
this->block_store.removeAt(idx);
}
}
void WsDocument::addBlocks(const QList<std::shared_ptr<WsBlock>> &blks, uint32_t offset)
{
if(offset < this->block_store.size()){
for(auto ptr : blks)
this->block_store.insert(offset, ptr);
}
else{
this->block_store.append(blks);
}
}
QString WsDocument::toPlainText() const
{
QString text_content;
for(auto idx=0; idx<blockCount(); ++idx){
text_content += getBlocks(idx).at(0)->toText();
}
return text_content;
}
void WsDocument::setPlainText(const QString &text)
{
auto sections = text.split("\n");
QList<std::shared_ptr<WsBlock>> blocks;
for(auto &t : sections){
auto binst = std::make_shared<WsBlock>();
blocks.append(binst);
// 转换文本为内存实例
auto codes = CharSetU16::combineToU(t);
auto chars = WsChar::convertFrom(codes);
// 填充段落实例
QList<Element*> buffers;
for(auto &ptr : chars){
ptr->bindFormat(this->getFormat()->defaultCharFormat());
ptr->refer(binst);
buffers.append(ptr);
}
binst->addElements(buffers);
}
addBlocks(blocks);
}
void WsBlock::addElements(const QList<Element*> &text, uint32_t offset){
if(offset < this->element_store.size()){
for(auto *ptr : text)
this->element_store.insert(offset, ptr);
}
else{
this->element_store.append(text);
}
}
QList<Element *> WsBlock::getElements(uint32_t offset, uint32_t count) const
{
QList<Element*> retvs;
for (auto idx = offset; idx < this->element_store.size(); ++idx)
retvs << this->element_store.at(idx);
return retvs;
}
void WsBlock::delElements(uint32_t offset, uint32_t count)
{
for(auto idx=offset; idx<this->element_store.size();){
delete element_store.at(idx);
this->element_store.removeAt(idx);
}
}
QString WsBlock::toText() const
{
QString text_content;
for(auto &it : element_store)
text_content += it->toText();
return text_content;
}
DocFormat::DocFormat(){}
DocFormat::DocFormat(const DocFormat &other){
this->char_format = other.char_format;
this->line_height = other.line_height;
this-> indent_char_count = other.indent_char_count;
this-> margins_store = other.margins_store;
this-> visible_of_additional = other.visible_of_additional;
}
double DocFormat::lineHeight() const { return line_height; }
QMargins DocFormat::margins() const { return margins_store; }
double DocFormat::indentChars() const { return indent_char_count; }
bool DocFormat::additionalVisible() const { return visible_of_additional; }
std::shared_ptr<CharFormat> DocFormat::defaultCharFormat() const { return this->char_format; }
void DocFormat::setLineHeight(double val) { this->line_height = val; }
void DocFormat::setMargins(const QMargins &val) { this->margins_store = val; }
void DocFormat::setIndentChars(double n) { this->indent_char_count = n; }
void DocFormat::setAdditionalVisible(bool ste) { this->visible_of_additional = ste; }
void DocFormat::setDefaultCharFormat(std::shared_ptr<CharFormat> format) { this->char_format = format; }
DocFormat &DocFormat::operator=(const DocFormat &other){
this->char_format = other.char_format;
this->line_height = other.line_height;
this-> indent_char_count = other.indent_char_count;
this-> margins_store = other.margins_store;
this-> visible_of_additional = other.visible_of_additional;
return *this;
}
CharFormat::CharFormat(qulonglong format_id){
this->unique_id = format_id;
}
CharFormat::CharFormat(const CharFormat &other){
this->unique_id = other.unique_id;
this->point_size = other.point_size;
this->fontfamily_store = other.fontfamily_store;
this->bold_store = other.bold_store;
this->italic_flag = other.italic_flag;
this->kerning_flag = other.kerning_flag;
this->overline_flag = other.overline_flag;
this->underline_flag = other.underline_flag;
this->float_Height = other.float_Height;
this->weight_store = other.weight_store;
}
qulonglong CharFormat::formatID() const { return unique_id; }
uint32_t CharFormat::pointSize() const { return point_size; }
QString CharFormat::fontFamily() const { return fontfamily_store; }
bool CharFormat::bold() const { return bold_store; }
bool CharFormat::italic() const { return italic_flag; }
bool CharFormat::kerning() const { return kerning_flag; }
bool CharFormat::overline() const { return overline_flag; }
bool CharFormat::underline() const { return underline_flag; }
double CharFormat::floatHeight() const { return float_Height; }
QFont::Weight CharFormat::weight() const { return weight_store; }
void CharFormat::setPointSize(uint32_t val){this->point_size = val;}
void CharFormat::setFontFamily(const QString &name){this->fontfamily_store = name;}
void CharFormat::setBold(bool ste){this->bold_store = ste;}
void CharFormat::setItalic(bool ste){this->italic_flag = ste;}
void CharFormat::setKerning(bool ste){this->kerning_flag = ste;}
void CharFormat::setOverline(bool ste){this->overline_flag = ste;}
void CharFormat::setUnderline(bool ste){this->underline_flag = ste;}
void CharFormat::setFloatHeight(double val){this->float_Height = val;}
void CharFormat::setWeight(QFont::Weight val){this->weight_store = val;}
bool CharFormat::operator==(const CharFormat &other){
return this->point_size == other.point_size &&
this->fontfamily_store == other.fontfamily_store &&
this->bold_store == other.bold_store &&
this->italic_flag == other.italic_flag &&
this->kerning_flag == other.kerning_flag &&
this->overline_flag == other.overline_flag &&
this->underline_flag == other.underline_flag &&
this->float_Height == other.float_Height &&
this->weight_store == other.weight_store;
}
CharFormat &CharFormat::operator=(const CharFormat &other) {
this->point_size = other.point_size;
this->fontfamily_store = other.fontfamily_store;
this->bold_store = other.bold_store;
this->italic_flag = other.italic_flag;
this->kerning_flag = other.kerning_flag;
this->overline_flag = other.overline_flag;
this->underline_flag = other.underline_flag;
this->float_Height = other.float_Height;
this->weight_store = other.weight_store;
return *this;
}
QList<WsChar *> WsChar::convertFrom(const CharStream &codes)
{
QList<WsChar*> buffers;
for(auto &c : codes)
buffers << new WsChar(c);
return buffers;
}
uint32_t WsChar::blockIndex() const
{
return blockRefer()->blockIndex();
}
void WsPart::insertChars(const QList<WsChar *> &text, uint32_t offset)
{
}

205
libTextEdit/text_present.h Normal file
View File

@ -0,0 +1,205 @@
#ifndef TEXT_PRESENT_H
#define TEXT_PRESENT_H
#include "libtextedit.h"
#include <libConfig.h>
#include <QString>
#include <QFont>
#include <memory>
namespace model_text {
typedef QList<uint32_t> CharStream;
class LIBTEXTEDIT_EXPORT CharSetU16 {
public:
static CharStream combineToU(const QString &buffer);
static QString splitToC(const CharStream &buffer);
static bool contains(uint32_t code);
static uint size();
};
class LIBTEXTEDIT_EXPORT CharFormat {
private:
qulonglong unique_id;
uint32_t point_size;
QString fontfamily_store;
bool bold_store;
bool italic_flag;
bool kerning_flag;
bool overline_flag;
bool underline_flag;
double float_Height;
QFont::Weight weight_store;
public:
CharFormat(qulonglong format_id);
CharFormat(const CharFormat& other);
qulonglong formatID() const;
uint32_t pointSize() const;
QString fontFamily() const;
bool bold() const;
bool italic() const;
bool kerning() const;
bool overline() const;
bool underline() const;
double floatHeight() const;
QFont::Weight weight() const;
void setPointSize(uint32_t val);
void setFontFamily(const QString &name);
void setBold(bool ste);
void setItalic(bool ste);
void setKerning(bool ste);
void setOverline(bool ste);
void setUnderline(bool ste);
void setFloatHeight(double val);
void setWeight(QFont::Weight val);
bool operator==(const CharFormat &other);
CharFormat &operator=(const CharFormat &other);
};
class LIBTEXTEDIT_EXPORT DocFormat {
private:
std::shared_ptr<CharFormat> char_format;
double line_height = 20;
double indent_char_count = 2;
QMargins margins_store = QMargins(5,5,5,5);
bool visible_of_additional = false;
public:
DocFormat();
DocFormat(const DocFormat &other);
double lineHeight() const;
QMargins margins() const;
double indentChars() const;
bool additionalVisible() const;
std::shared_ptr<CharFormat> defaultCharFormat() const;
void setLineHeight(double val);
void setMargins(const QMargins &val);
void setIndentChars(double n);
void setAdditionalVisible(bool ste);
void setDefaultCharFormat(std::shared_ptr<CharFormat> format);
DocFormat& operator=(const DocFormat &other);
};
class WsBlock;
/**
* @brief
*/
class Element {
public:
enum class Type{
Char, Set
};
virtual ~Element() = default;
virtual void refer(std::weak_ptr<WsBlock> ptr) = 0;
virtual std::weak_ptr<WsBlock> blockRefer() const = 0;
virtual uint32_t blockIndex() const = 0;
virtual std::shared_ptr<CharFormat> getFormat() const = 0;
virtual void bindFormat(std::shared_ptr<CharFormat> format) = 0;
virtual Type type() const = 0;
virtual uint32_t index() const = 0;
virtual QString toText() const = 0;
virtual uint32_t childCount() const = 0;
};
class LIBTEXTEDIT_EXPORT WsChar : public Element {
private:
uint32_t code_store;
std::shared_ptr<CharFormat> char_format_refer;
public:
explicit WsChar(uint32_t code){this->code_store = code;}
virtual ~WsChar() = default;
uint32_t code() const { return code_store; }
static QList<WsChar*> convertFrom(const CharStream &codes);
// Element interface
public:
virtual std::shared_ptr<CharFormat> getFormat() const override { return this->char_format_refer; }
virtual void bindFormat(std::shared_ptr<CharFormat> format) override{this->char_format_refer = format;}
virtual Type type() const override { return Type::Char; }
virtual uint32_t blockIndex() const override;
virtual uint32_t index() const override;
virtual QString toText() const override { return CharSetU16::splitToC(QList<uint32_t>() << code_store); }
virtual uint32_t childCount() const override { return 0; }
virtual void refer(std::weak_ptr<WsBlock> ptr) override;
virtual std::weak_ptr<WsBlock> blockRefer() const override;
};
class LIBTEXTEDIT_EXPORT WsPart : public Element {
public:
void insertChars(const QList<WsChar*> &text, uint32_t offset = -1);
QList<WsChar*> getChars(uint32_t offset, uint32_t count) const;
void delChars(uint32_t offset, uint32_t count);
};
class LIBTEXTEDIT_EXPORT WsBlock {
private:
QList<Element*> element_store;
public:
uint32_t blockIndex() const;
void addElements(const QList<Element*> &text, uint32_t offset = UINT32_MAX);
QList<Element*> getElements(uint32_t offset, uint32_t count) const;
void delElements(uint32_t offset, uint32_t count);
QString toText() const;
};
class LIBTEXTEDIT_EXPORT WsDocument : public QObject {
Q_OBJECT
private:
std::shared_ptr<DocFormat> document_format;
QList<std::shared_ptr<WsBlock>> block_store;
public:
void bindFormat(std::shared_ptr<DocFormat> f);
std::shared_ptr<DocFormat> getFormat() const;
void addBlocks(const QList<std::shared_ptr<WsBlock>> &blks, uint32_t offset = UINT32_MAX);
uint32_t blockCount() const;
QList<std::shared_ptr<WsBlock>> getBlocks(uint32_t offset, uint32_t count = 1) const;
void delBlocks(uint32_t offset, uint32_t count = 1);
// void insertText(QList<WsChar> part, uint32_t index = -1);
// QList<WsChar> getText(uint32_t index, uint32_t count);
// void delText(uint32_t index, uint32_t count);
// void select(uint32_t index, uint32_t count);
QString toPlainText() const;
void setPlainText(const QString &text);
// signals:
// void blockHasbeenInserted(uint32_t index);
// void blockAboutTobeDelete(uint32_t index);
// void blockHasbeenChanged(uint32_t index);
// void redoAvaliable();
// void undoAvaliable();
// void cursorPosChanged(uint32_t index);
// void selectionChanged(uint32_t index, uint32_t count);
};
}
#endif // TEXT_PRESENT_H