Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
|
6ef70b57cf | |
|
5b6c7d2355 | |
|
46f5398d30 | |
|
72e17a50d0 | |
|
0230e60e81 | |
|
bd9a4c156e | |
|
6100d40e31 | |
|
6242c1d2d1 | |
|
456516db01 | |
|
df2d145809 |
|
@ -3,8 +3,7 @@ TEMPLATE = subdirs
|
|||
SUBDIRS += \
|
||||
libGenericConsole \
|
||||
libSplitView \
|
||||
# WordsIDE \
|
||||
WordsIDE \
|
||||
libConfig \
|
||||
libProjectManager \
|
||||
# libTextEdit \
|
||||
u_test
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <QDebug>
|
||||
#include <QTextCodec>
|
||||
|
||||
using namespace Components;
|
||||
using namespace Core;
|
||||
using namespace Presents;
|
||||
|
||||
|
|
|
@ -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 获取实例的别名
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "route.h"
|
||||
#include "Route.h"
|
||||
|
||||
using namespace Core;
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "command_list.h"
|
||||
#include "manager_docs.h"
|
||||
#include "route.h"
|
||||
#include "Route.h"
|
||||
#include "DocsManager.h"
|
||||
|
||||
using namespace CommandList;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef COMMAND_LIST_H
|
||||
#define COMMAND_LIST_H
|
||||
|
||||
#include "route.h"
|
||||
#include "Route.h"
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <commandsdispatcher.h>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 是否可以放置此视图
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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(); }
|
|
@ -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
|
|
@ -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(); }
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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> {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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-records:tuple<ID,tuple<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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<RCC>
|
||||
<qresource prefix="/icons/headertop">
|
||||
<file>story.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -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 瀹炰緥灞炰簬鍛堢幇鏍戯紝璋冪敤瀹屾垚灏嗚瑙i櫎鐖跺瓙寮曠敤
|
||||
* @brief 替换视图,旧视图被剔除呈现树
|
||||
* @param view 新视图,必须闲置视图
|
||||
* @param pos 目标视图
|
||||
*/
|
||||
virtual void replaceView(ViewRes *_new, ViewRes *_old) = 0;
|
||||
|
||||
|
|
|
@ -40,3 +40,6 @@ else:unix: LIBS += -L$$OUT_PWD/../libConfig/ -llibConfig
|
|||
|
||||
INCLUDEPATH += $$PWD/../libConfig
|
||||
DEPENDPATH += $$PWD/../libConfig
|
||||
|
||||
RESOURCES += \
|
||||
defaulticon.qrc
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -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. 全局文档布局设置、段落文档布局设置、行文档布局设置、文本片段布局设置
|
|
@ -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) {}
|
|
@ -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
|
|
@ -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); }
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef LIBTEXTEDIT_H
|
||||
#define LIBTEXTEDIT_H
|
||||
|
||||
#include "libTextEdit_global.h"
|
||||
#include "libtextedit_global.h"
|
||||
|
||||
class LIBTEXTEDIT_EXPORT LibTextEdit
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "text_modelx.h"
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef TEXT_MODELX_H
|
||||
#define TEXT_MODELX_H
|
||||
|
||||
#include "text_present.h"
|
||||
|
||||
namespace text_model
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif // TEXT_MODELX_H
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue