diff --git a/QtNovelDesc.pro.user b/QtNovelDesc.pro.user index 2a8bdde..1b59f3b 100644 --- a/QtNovelDesc.pro.user +++ b/QtNovelDesc.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/WordsIDE/command_list.cpp b/WordsIDE/command_list.cpp index 632e534..07b3b5c 100644 --- a/WordsIDE/command_list.cpp +++ b/WordsIDE/command_list.cpp @@ -99,60 +99,7 @@ QString SaveAll::toText() const return ""; } -void SaveAll::fromText(const QString &line) -{ - -} - -OpenProject::OpenProject(const QString &path) - : project_path(path) -{ - -} - -QString OpenProject::name() const -{ - return NAME(OpenProject); -} - -void OpenProject::run(Schedule::CommandsDispatcher *core) const -{ - auto vmgr = core->get(NAME(DocumentsManager)); - vmgr->projectManager()->openProject(project_path); -} - -QString OpenProject::toText() const -{ - return project_path; -} - -void OpenProject::fromText(const QString &line) -{ - project_path = line; -} - -CloseProject::CloseProject() -{ - -} - -QString CloseProject::name() const -{ - return NAME(CloseProject); -} - -void CloseProject::run(Schedule::CommandsDispatcher *core) const -{ - auto vmgr = core->get(NAME(DocumentsManager)); - vmgr->save(); - vmgr->closeFile(vmgr->actives()); - vmgr->projectManager()->save(); - vmgr->projectManager()->closeProject(); -} - -QString CloseProject::toText() const { return ""; } - -void CloseProject::fromText(const QString &line) {} +void SaveAll::fromText(const QString &line) {} OpenFile::OpenFile(const Core::Route &path_node) { path_store = path_node.links(); } @@ -209,3 +156,32 @@ void CompVisible::fromText(const QString &line) { state_val = list[0].toUInt(); path = Route::collect(list[1].split(":")); } + +OpenProject::OpenProject(const QString &path) : project_path(path) {} + +QString OpenProject::name() const { return NAME(OpenProject); } + +void OpenProject::run(Schedule::CommandsDispatcher *core) const { + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->projectManager()->openProject(project_path); +} + +QString OpenProject::toText() const { return project_path; } + +void OpenProject::fromText(const QString &line) { project_path = line; } + +CloseProject::CloseProject() {} + +QString CloseProject::name() const { return NAME(CloseProject); } + +void CloseProject::run(Schedule::CommandsDispatcher *core) const { + auto vmgr = core->get(NAME(DocumentsManager)); + vmgr->save(); + vmgr->closeFile(vmgr->actives()); + vmgr->projectManager()->save(); + vmgr->projectManager()->closeProject(); +} + +QString CloseProject::toText() const { return ""; } + +void CloseProject::fromText(const QString &line) {} diff --git a/WordsIDE/command_list.h b/WordsIDE/command_list.h index d1d7083..38238ee 100644 --- a/WordsIDE/command_list.h +++ b/WordsIDE/command_list.h @@ -33,21 +33,22 @@ namespace CommandList { OpenProject(const QString &path); // GeCommand interface - public: + public: virtual QString name() const override; virtual void run(Schedule::CommandsDispatcher *core) const override; virtual QString toText() const override; virtual void fromText(const QString &line) override; - private: + private: QString project_path; }; + class CloseProject : public Schedule::GeCommand { - public: + public: CloseProject(); // GeCommand interface - public: + public: virtual QString name() const override; virtual void run(Schedule::CommandsDispatcher *core) const override; virtual QString toText() const override; @@ -124,11 +125,11 @@ namespace CommandList { virtual QString toText() const override; virtual void fromText(const QString &line) override; - private: - Presents::PresentHost *host_ins; - Presents::FilePresent *target_ins; - Core::Route path; - bool state_val; + private: + Presents::PresentHost *host_ins; + Presents::FilePresent *target_ins; + Core::Route path; + bool state_val; }; } // namespace CommandList diff --git a/WordsIDE/main.cpp b/WordsIDE/main.cpp index 406fc3b..80e77fb 100644 --- a/WordsIDE/main.cpp +++ b/WordsIDE/main.cpp @@ -15,23 +15,6 @@ int main(int argc, char *argv[]) { XApp a(argc, argv); -#ifdef UNIT_TEST - - MakeTools::ContentPresent *array[] = { - new Components::DefaultTextPresent(), - new Components::StorychainSourceEdit(), - new Components::StoryunitSourceEdit(), - new Components::StoryboardSourceEdit(), - new Components::StoryvolumeSourceEdit(), - new Components::StoryconceptSourceEdit() - }; - - for(auto &it : array){ - TestCase::ContentPresentTest tx0(it); - QTest::qExec(&tx0, argc, argv); - } - -#else QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { @@ -42,9 +25,8 @@ int main(int argc, char *argv[]) } } - MainWindow w("default"); + MainWindow w(&a, "default"); w.show(); -#endif return a.exec(); } diff --git a/WordsIDE/mainwindow.cpp b/WordsIDE/mainwindow.cpp index b028f15..e3005c0 100644 --- a/WordsIDE/mainwindow.cpp +++ b/WordsIDE/mainwindow.cpp @@ -28,42 +28,40 @@ using namespace Tools; using namespace CommandList; using namespace bridge; -MainWindow::MainWindow(const QString &layout, QWidget *parent) +MainWindow::MainWindow(XApp *core, const QString &layout, QWidget *parent) : QMainWindow(parent), layout_name_store(layout), + core_bind(core), sync_kernel(new StatusSyncCore(this)), - parse_service(new ParseBridge()), - project_manager(new XMLProjectManager(this)), - active_docscollect(new DocumentsManager(project_manager)), present_host(new SplitFrame::ViewPresent(this)), session_service(new ViewSession(XApp::global_configration, this)), + actions_stack(new QToolBar(this)), views_bar(new ViewStackedBar(present_host, this)), - center_frame(new PresentContainerView(present_host, this)), - project_present(new ProjectView(present_host, XApp::disp_core, active_docscollect, 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); initial_commandlist(XApp::disp_core); + auto mbar = menuBar(); + initial_menubar(mbar); - XApp::disp_core->registerMember(active_docscollect); + XApp::disp_core->registerMember(core->docsManager()); - setMinimumSize(1000, 600); - setWindowTitle(tr("提线木偶")); setCentralWidget(present_host->bind()); addToolBar(Qt::LeftToolBarArea, views_bar); present_host->addListener(views_bar); - session_service->initPresentView(center_frame, project_present, parse_service->errorsPresentModel()); - - auto mbar = menuBar(); - initial_menubar(mbar); + session_service->initPresentView(center_frame, project_present, core->parseService()->errorsPresentModel()); project_present->setVisible(true); - this->active_docscollect->appendPresent(center_frame); + core->docsManager()->appendPresent(center_frame); session_service->viewStatesRestore(this, present_host); } -MainWindow::~MainWindow() { active_docscollect->removePresent(center_frame); } +MainWindow::~MainWindow() { core_bind->docsManager()->removePresent(center_frame); } SplitFrame::ViewPresent *MainWindow::bindPresent() const { return present_host; } @@ -73,103 +71,16 @@ void MainWindow::initial_menubar(QMenuBar *mbar) { // 项目菜单树 auto project = mbar->addMenu("项目"); - auto opnp = project->addAction("打开项目", [this]() { - auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)"); - if (file == "") - return; - - XApp::disp_core->postCommand(OpenProject(file)); - }); - sync_kernel->actionEnableSync(opnp, [this]() -> bool { return !project_manager->isOpenning(); }); - - auto newp = 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)); - }); - sync_kernel->actionEnableSync(newp, [this]() -> bool { return !project_manager->isOpenning(); }); - - auto clsp = project->addAction("关闭项目", [this]() { XApp::disp_core->postCommand(CloseProject()); }); - sync_kernel->actionEnableSync(clsp, [this]() -> bool { return project_manager->isOpenning(); }); - - project->addSeparator(); - - auto pnew = project->addAction("新建路径", [this]() { - auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:"); - if (packages != "") - XApp::disp_core->postCommand(NewPackage(packages)); - }); - sync_kernel->actionEnableSync(pnew, [this]() -> bool { return project_manager->isOpenning(); }); - - auto _xnew = project->addMenu("新建文件"); - _xnew->setEnabled(project_manager->isOpenning()); - auto types = active_docscollect->fileTypes(); - for (auto &t : types) { - _xnew->addAction(t, [this, &t]() { - auto name = QInputDialog::getText(this, "输入名称", "名称:"); - if (name == "") - return; - - auto idx = project_present->currentIndex(); - if (!idx.isValid()) - idx = project_manager->model()->item(0)->index(); - - auto group_path = active_docscollect->convertPath(idx); - XApp::disp_core->postCommand(NewFile(group_path, name, t)); - }); - } - sync_kernel->widgetEnableSync(_xnew, [this]() -> bool { return project_manager->isOpenning(); }); - project->addSeparator(); - - auto sav = project->addAction("保存全部", [this]() { XApp::disp_core->postCommand(SaveAll()); }); - sav->setShortcut(QKeySequence::StandardKey::Save); - sync_kernel->actionEnableSync(sav, [this]() -> bool { return project_manager->isOpenning(); }); - - project->addSeparator(); - - project->addAction("退出", [this]() { - XApp::disp_core->postCommand(SaveAll()); - QApplication::exit(0); - }); + this->build_project_menu(project); // 编辑菜单 auto edit = mbar->addMenu("编辑"); - edit->addAction("撤销一步"); - edit->addAction("重做一步"); - edit->addSeparator(); - edit->addAction("查找关键词"); - edit->addAction("替换关键词"); + this->build_edit_menu(edit); // 视图菜单 auto view = mbar->addMenu("视图"); - auto area = view->addMenu("区域管理"); + build_view_menu(view); - auto xtool = new QToolBar(this); - xtool->setVisible(false); - addToolBar(Qt::ToolBarArea::TopToolBarArea, xtool); - auto act_tool = area->addAction("工具栏"); - sync_kernel->actionCheckSync(act_tool, [xtool]() -> bool { return xtool->isVisible(); }); - connect(act_tool, &QAction::triggered, [xtool](bool v) { xtool->setVisible(v); }); - - auto xstatus = statusBar(); - xstatus->setVisible(false); - xstatus->addWidget(new QLabel("文本消息", this)); - auto act_status = area->addAction("状态栏"); - sync_kernel->actionCheckSync(act_status, [xstatus]() -> bool { return xstatus->isVisible(); }); - connect(act_status, &QAction::triggered, [xstatus](bool v) { xstatus->setVisible(v); }); - - view->addSeparator(); - auto change = view->addMenu("内容切换"); - change->addAction("序列视图"); - change->addAction("编辑视图"); - view->addSeparator(); - auto func = view->addMenu("功能视图"); - sync_kernel->widgetEnableSync(func, [this]() { return this->project_manager->isOpenning(); }); // 项目管理 // 工具菜单 @@ -191,12 +102,14 @@ void MainWindow::initial_menubar(QMenuBar *mbar) { // 窗口菜单 auto window = mbar->addMenu("窗口"); - window->addAction("新建窗口"); + auto newa = window->addMenu("新建窗口"); + newa->addAction("LayoutName1"); + newa->addAction("LayoutNameB"); window->addAction("关闭窗口"); window->addSeparator(); - window->addAction("布局管理"); + window->addAction("保存当前布局"); window->addMenu("布局切换"); - window->addMenu("窗口切换"); + window->addMenu("布局删除"); // 系统 auto sys = mbar->addMenu("系统"); @@ -206,6 +119,106 @@ void MainWindow::initial_menubar(QMenuBar *mbar) { sys->addAction("关于……"); } +void MainWindow::build_project_menu(QMenu *project) { + auto opnp = project->addAction("打开项目", [this]() { + auto file = QFileDialog::getOpenFileName(this, "打开项目", QString(), "小说项目(*.nsf)"); + if (file == "") + return; + + XApp::disp_core->postCommand(OpenProject(file)); + }); + sync_kernel->actionEnableSync(opnp, [this]() -> bool { return !core_bind->pjtManager()->isOpenning(); }); + + auto newp = 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)); + }); + sync_kernel->actionEnableSync(newp, [this]() -> bool { return !core_bind->pjtManager()->isOpenning(); }); + + auto clsp = project->addAction("关闭项目", [this]() { XApp::disp_core->postCommand(CloseProject()); }); + sync_kernel->actionEnableSync(clsp, [this]() -> bool { return core_bind->pjtManager()->isOpenning(); }); + + project->addSeparator(); + + auto pnew = project->addAction("新建路径", [this]() { + auto packages = QInputDialog::getText(this, "输入包路径名称/PackA/PackB/PackC", "包路径:"); + if (packages != "") + XApp::disp_core->postCommand(NewPackage(packages)); + }); + sync_kernel->actionEnableSync(pnew, [this]() -> bool { return core_bind->pjtManager()->isOpenning(); }); + + auto _xnew = project->addMenu("新建文件"); + _xnew->setEnabled(core_bind->pjtManager()->isOpenning()); + auto types = core_bind->docsManager()->fileTypes(); + for (auto &t : types) { + _xnew->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)); + }); + } + sync_kernel->widgetEnableSync(_xnew, [this]() -> bool { return core_bind->pjtManager()->isOpenning(); }); + project->addSeparator(); + + auto sav = project->addAction("保存全部", []() { XApp::disp_core->postCommand(SaveAll()); }); + sav->setShortcut(QKeySequence::StandardKey::Save); + sync_kernel->actionEnableSync(sav, [this]() -> bool { return core_bind->pjtManager()->isOpenning(); }); + + project->addSeparator(); + + project->addAction("退出", []() { + XApp::disp_core->postCommand(SaveAll()); + QApplication::exit(0); + }); +} + +void MainWindow::build_edit_menu(QMenu *edit) { + + edit->addAction("撤销一步"); + edit->addAction("重做一步"); + edit->addSeparator(); + edit->addAction("查找关键词"); + edit->addAction("替换关键词"); +} + +void MainWindow::build_view_menu(QMenu *view) { + auto area = view->addMenu("区域管理"); + + actions_stack->setMovable(false); + addToolBar(Qt::ToolBarArea::TopToolBarArea, actions_stack); + auto act_tool = area->addAction("工具栏"); + sync_kernel->actionCheckSync(act_tool, [this]() -> bool { return actions_stack->isVisible(); }); + connect(act_tool, &QAction::triggered, [this](bool v) { actions_stack->setVisible(v); }); + + auto xstatus = statusBar(); + xstatus->setVisible(false); + xstatus->addWidget(new QLabel("文本消息", this)); + auto act_status = area->addAction("状态栏"); + sync_kernel->actionCheckSync(act_status, [xstatus]() -> bool { return xstatus->isVisible(); }); + connect(act_status, &QAction::triggered, [xstatus](bool v) { xstatus->setVisible(v); }); + + view->addSeparator(); + auto change = view->addMenu("内容切换"); + change->addAction("序列视图"); + change->addAction("编辑视图"); + view->addSeparator(); + auto func = view->addMenu("功能视图"); + sync_kernel->widgetEnableSync(func, [this]() { return this->core_bind->pjtManager()->isOpenning(); }); +} + void MainWindow::initial_commandlist(Schedule::CommandsDispatcher *host) { host->registerCommand(new CloseProject()); @@ -219,7 +232,7 @@ void MainWindow::initial_commandlist(Schedule::CommandsDispatcher *host) { void MainWindow::closeEvent(QCloseEvent *event) { // 关闭事件 - if (project_manager->isOpenning()) { + if (core_bind->pjtManager()->isOpenning()) { XApp::disp_core->postCommand(CloseProject()); } diff --git a/WordsIDE/mainwindow.h b/WordsIDE/mainwindow.h index b858cfe..ace096a 100644 --- a/WordsIDE/mainwindow.h +++ b/WordsIDE/mainwindow.h @@ -11,6 +11,7 @@ #include "viewsession.h" #include "viewstackedbar.h" #include "welcomepanel.h" +#include "xapp.h" #include #include #include @@ -23,7 +24,7 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(const QString &layout, QWidget *parent = nullptr); + MainWindow(XApp *core, const QString &layout, QWidget *parent = nullptr); virtual ~MainWindow(); SplitFrame::ViewPresent *bindPresent() const; @@ -32,22 +33,25 @@ public: private: QString layout_name_store; // model ============================================ + XApp *const core_bind; Tools::StatusSyncCore *const sync_kernel; - bridge::ParseBridge *const parse_service; - Project::ProjectManager *const project_manager; - Core::DocumentsManager *const active_docscollect; SplitFrame::ViewPresent *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; // 内部逻辑 =========================================== - void initial_menubar(QMenuBar *mbar); void initial_commandlist(Schedule::CommandsDispatcher *host); + void initial_menubar(QMenuBar *mbar); + void build_project_menu(QMenu *pmenu); + void build_edit_menu(QMenu *pmenu); + void build_view_menu(QMenu *pmenu); + // QWidget interface protected: virtual void closeEvent(QCloseEvent *event) override; diff --git a/WordsIDE/messageview.cpp b/WordsIDE/messageview.cpp index 2c7c1c0..138aa51 100644 --- a/WordsIDE/messageview.cpp +++ b/WordsIDE/messageview.cpp @@ -7,21 +7,22 @@ using namespace SplitFrame; QHash MessageView::panel_map; -MessageView::MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base, QWidget *parent) - : FnWrap(ins, parent), ui_present(new QTableView(this)), items_present(base) { +MessageView::MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base) + : FnWrap(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::ViewPresent *host, QStandardItemModel *base, QWidget *parent) { +MessageView *MessageView::gen(SplitFrame::ViewPresent *host, QStandardItemModel *base) { if (panel_map.contains(host)) return panel_map[host]; - auto vins = new MessageView(host, base, parent); + auto vins = new MessageView(host, base); panel_map[host] = vins; return vins; } diff --git a/WordsIDE/messageview.h b/WordsIDE/messageview.h index 0bf4800..b5b556e 100644 --- a/WordsIDE/messageview.h +++ b/WordsIDE/messageview.h @@ -15,10 +15,10 @@ namespace Components { public: virtual ~MessageView() = default; - static MessageView *gen(SplitFrame::ViewPresent *host, QStandardItemModel *base, QWidget *parent = nullptr); + static MessageView *gen(SplitFrame::ViewPresent *host, QStandardItemModel *base); private: - MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base, QWidget *parent = nullptr); + MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base); QTableView *const ui_present; QStandardItemModel *const items_present; diff --git a/WordsIDE/presentcontainerview.cpp b/WordsIDE/presentcontainerview.cpp index 02d6df2..4455eda 100644 --- a/WordsIDE/presentcontainerview.cpp +++ b/WordsIDE/presentcontainerview.cpp @@ -13,8 +13,8 @@ using namespace Core; using namespace SplitFrame; using namespace Presents; -PresentContainerView::PresentContainerView(ViewPresent *host, QWidget *parent) - : FnWrap(host, parent), +PresentContainerView::PresentContainerView(ViewPresent *host) + : FnWrap(host), title_store(new QComboBox(this)), stack_container(new QStackedWidget(this)), welcome_list(new WelcomePanel(this)), diff --git a/WordsIDE/presentcontainerview.h b/WordsIDE/presentcontainerview.h index a69ccde..12e51e1 100644 --- a/WordsIDE/presentcontainerview.h +++ b/WordsIDE/presentcontainerview.h @@ -18,7 +18,7 @@ namespace Components { class PresentContainerView : public SplitFrame::FnWrap, public Presents::PresentHost { Q_OBJECT public: - PresentContainerView(SplitFrame::ViewPresent *host, QWidget *parent = nullptr); + PresentContainerView(SplitFrame::ViewPresent *host); // PresentContainer interface public: diff --git a/WordsIDE/projectview.cpp b/WordsIDE/projectview.cpp index ec5c680..9c5a0d7 100644 --- a/WordsIDE/projectview.cpp +++ b/WordsIDE/projectview.cpp @@ -11,14 +11,15 @@ using namespace Schedule; using namespace SplitFrame; using namespace Core; -ProjectView::ProjectView(ViewPresent *host, CommandsDispatcher *core, Core::DocumentsManager *mgr, QWidget *parent) - : FnWrap(host, parent), project_manager(mgr), source(core), view_present(new QTreeView(this)) { +ProjectView::ProjectView(ViewPresent *host, CommandsDispatcher *core, Core::DocumentsManager *mgr) + : FnWrap(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, diff --git a/WordsIDE/projectview.h b/WordsIDE/projectview.h index 1d001ed..bc6cc18 100644 --- a/WordsIDE/projectview.h +++ b/WordsIDE/projectview.h @@ -17,8 +17,7 @@ namespace Components { class ProjectView : public SplitFrame::FnWrap { Q_OBJECT public: - explicit ProjectView(SplitFrame::ViewPresent *host, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr, - QWidget *parent = nullptr); + explicit ProjectView(SplitFrame::ViewPresent *host, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr); QModelIndex currentIndex() const; diff --git a/WordsIDE/viewsession.cpp b/WordsIDE/viewsession.cpp index 4ce873a..b11b2a4 100644 --- a/WordsIDE/viewsession.cpp +++ b/WordsIDE/viewsession.cpp @@ -23,7 +23,7 @@ void ViewSession::initPresentView(PresentContainerView *center_frame, ProjectVie 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, host->bind()); + 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; diff --git a/WordsIDE/xapp.cpp b/WordsIDE/xapp.cpp index 2f94093..c6ea89f 100644 --- a/WordsIDE/xapp.cpp +++ b/WordsIDE/xapp.cpp @@ -2,11 +2,21 @@ #include #include #include +#include using namespace Schedule; using namespace Config; +using namespace bridge; +using namespace Core; +using namespace Project; -XApp::XApp(int argc, char **argv) : QApplication(argc, argv) { global_configration->loadFile("./software.config"); } +XApp::XApp(int argc, char **argv) + : QApplication(argc, argv), + parse_service(new ParseBridge()), + project_manager(new XMLProjectManager(this)), + active_docscollect(new DocumentsManager(project_manager)) { + global_configration->loadFile("./software.config"); +} bool XApp::notify(QObject *receiver, QEvent *event) { try { @@ -19,5 +29,11 @@ bool XApp::notify(QObject *receiver, QEvent *event) { return false; } -CommandsDispatcher *const XApp::disp_core = new CommandsDispatcher(QDir::home(), true); +ParseBridge *XApp::parseService() const { return parse_service; } + +ProjectManager *XApp::pjtManager() const { return project_manager; } + +DocumentsManager *XApp::docsManager() const { return active_docscollect; } + +CommandsDispatcher *const XApp::disp_core = new CommandsDispatcher(QDir("./"), true); Configration *const XApp::global_configration = new XMLConfig(); diff --git a/WordsIDE/xapp.h b/WordsIDE/xapp.h index db2778a..2adf651 100644 --- a/WordsIDE/xapp.h +++ b/WordsIDE/xapp.h @@ -1,9 +1,13 @@ #ifndef XAPPLICATION_H #define XAPPLICATION_H +#include "manager_docs.h" +#include "parsebridge.h" + #include #include #include +#include class XApp : public QApplication { public: @@ -11,9 +15,18 @@ class XApp : public QApplication { virtual bool notify(QObject *receiver, QEvent *event); - public: + bridge::ParseBridge *parseService() const; + Project::ProjectManager *pjtManager() const; + Core::DocumentsManager *docsManager() const; + +public: static Schedule::CommandsDispatcher *const disp_core; static Config::Configration *const global_configration; + +private: + bridge::ParseBridge *const parse_service; + Project::ProjectManager *const project_manager; + Core::DocumentsManager *const active_docscollect; }; #endif // XAPPLICATION_H diff --git a/libSplitView/baseview.cpp b/libSplitView/baseview.cpp index 22714ce..e57a842 100644 --- a/libSplitView/baseview.cpp +++ b/libSplitView/baseview.cpp @@ -75,12 +75,14 @@ void DragHeader::mouseMoveEvent(QMouseEvent *event) { } } -BaseView::BaseView(const QString &title, QWidget *view, bool empty, QWidget *parent) : QWidget(parent), title_header(nullptr), parent_store(nullptr) { +BaseView::BaseView(const QString &title, QWidget *view, bool empty, bool replaceable, QWidget *parent) + : QWidget(parent), replace_able(replaceable), title_header(nullptr), parent_store(nullptr) { auto layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); registElement(this); + setCursor(Qt::CursorShape::ArrowCursor); if (!empty) { title_header = new DragHeader(this); @@ -115,14 +117,18 @@ void BaseView::setIcon(const QIcon &icon) { QIcon BaseView::viewIcon() const { return this->icon_store; } +bool BaseView::canReplace() const { return replace_able; } + void BaseView::registElement(QWidget *child) { if (this->comps_list.contains(child)) return; comps_list << child; - if (child != this) + child->setMouseTracking(true); + if (child != this) { child->setParent(this); + } } ViewPresent *BaseView::viewPanel() const { diff --git a/libSplitView/baseview.h b/libSplitView/baseview.h index ba837d9..d4b5b17 100644 --- a/libSplitView/baseview.h +++ b/libSplitView/baseview.h @@ -42,7 +42,7 @@ namespace SplitFrame { friend class ViewPresent; public: - BaseView(const QString &title, QWidget *view, bool empty = false, QWidget *parent = nullptr); + BaseView(const QString &title, QWidget *view, bool empty = false, bool replaceable = false, QWidget *parent = nullptr); virtual ~BaseView(); virtual void setTitle(const QString &title); @@ -51,6 +51,7 @@ namespace SplitFrame { virtual void setIcon(const QIcon &icon); virtual QIcon viewIcon() const; + virtual bool canReplace() const override; virtual bool contains(QWidget *inst) const override; // ViewRes interface @@ -70,6 +71,7 @@ namespace SplitFrame { virtual void paintEvent(QPaintEvent *ev) override; private: + bool replace_able; QIcon icon_store; QString title_store; DragHeader *title_header; diff --git a/libSplitView/splitpanel.cpp b/libSplitView/splitpanel.cpp index 207683d..2aa30f1 100644 --- a/libSplitView/splitpanel.cpp +++ b/libSplitView/splitpanel.cpp @@ -77,7 +77,8 @@ void AttachPanel::paintEvent(QPaintEvent *event) { p.fillRect(QRectF(rect.center() - QPointF(rect.width() / 2, 0), QSizeF(rect.width(), rect.height() / 2)), Qt::gray); break; case ActiveArea::CENTER: - p.fillRect(rect, Qt::gray); + if (attachmentTarget()->canReplace()) + p.fillRect(rect, Qt::gray); break; default: break; @@ -92,7 +93,8 @@ void AttachPanel::paintEvent(QPaintEvent *event) { rects << std::get<1>(x_views); rects << std::get<2>(x_views); rects << std::get<3>(x_views); - rects << std::get<4>(x_views); + if (attachmentTarget()->canReplace()) + rects << std::get<4>(x_views); p.drawRects(rects); } @@ -135,41 +137,44 @@ void AttachPanel::dropEvent(QDropEvent *event) { auto target = this->attachmentTarget(); if (target != xfrom && active_comp != ActiveArea::NONE) { - static_cast(xfrom->parentRes())->removeComp(xfrom); - adjust_host->objsRelateRebuild(); + if (active_comp == ActiveArea::CENTER && !target->canReplace()) { + } else { + static_cast(xfrom->parentRes())->removeComp(xfrom); + adjust_host->objsRelateRebuild(); - auto ptarget = static_cast(target->parentRes()); - auto target_rect = target->outline(); + auto ptarget = static_cast(target->parentRes()); + auto target_rect = target->outline(); - RectCom *new_split = nullptr; - switch (this->active_comp) { - case ActiveArea::LEFT: { - new_split = new SplitView(xfrom, target, adjust_host->bind()); - static_cast(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false); - } break; - case ActiveArea::RIGHT: { - new_split = new SplitView(target, xfrom, adjust_host->bind()); - static_cast(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false); - } break; - case ActiveArea::TOP: { - new_split = new SplitView(xfrom, target, adjust_host->bind()); - static_cast(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false); - } break; - case ActiveArea::BOTTOM: { - new_split = new SplitView(target, xfrom, adjust_host->bind()); - static_cast(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false); - } break; - case ActiveArea::CENTER: { - new_split = xfrom; - adjust_host->markFreedom(target); - } break; - default: - return; + RectCom *new_split = nullptr; + switch (this->active_comp) { + case ActiveArea::LEFT: { + new_split = new SplitView(xfrom, target, adjust_host->bind()); + static_cast(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false); + } break; + case ActiveArea::RIGHT: { + new_split = new SplitView(target, xfrom, adjust_host->bind()); + static_cast(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false); + } break; + case ActiveArea::TOP: { + new_split = new SplitView(xfrom, target, adjust_host->bind()); + static_cast(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false); + } break; + case ActiveArea::BOTTOM: { + new_split = new SplitView(target, xfrom, adjust_host->bind()); + static_cast(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false); + } break; + case ActiveArea::CENTER: { + new_split = xfrom; + adjust_host->markFreedom(target); + } break; + default: + return; + } + + ptarget->replaceComp(new_split, target); + new_split->relayout(target_rect); + adjust_host->objsRelateRebuild(); } - - ptarget->replaceComp(new_split, target); - new_split->relayout(target_rect); - adjust_host->objsRelateRebuild(); } adjust_host->setAdjustView(); @@ -414,6 +419,8 @@ void ViewPresent::relayout(const QRectF &outline) { QString ViewPresent::title() const { return ""; } +bool ViewPresent::canReplace() const { return true; } + void ViewPresent::pRelease() { throw new SimpleException("非法操作", "不允许对ViewPanel调用pRelease"); } void ViewPresent::pClose() { throw new SimpleException("非法操作", "不允许对ViewPanel调用pClose"); } @@ -479,46 +486,9 @@ void ViewPresent::resizeEvent(QResizeEvent *ev) { QWidget::resizeEvent(ev); relayout(); } -void ViewPresent::mousePressEvent(QMouseEvent *event) { - QWidget::mousePressEvent(event); - - if (event->button() == Qt::MouseButton::LeftButton) { - if (handle_rect().contains(event->pos())) - this->press_flags = true; - } -} -void ViewPresent::mouseReleaseEvent(QMouseEvent *event) { - QWidget::mouseReleaseEvent(event); - - if (event->button() == Qt::MouseButton::LeftButton) { - this->press_flags = false; - } -} -void ViewPresent::mouseMoveEvent(QMouseEvent *event) { - QWidget::mouseMoveEvent(event); - - auto drag_rect = handle_rect(); - if (drag_rect.contains(event->pos())) { - if (splitType() == SplitType::SPLIT_H) - setCursor(QCursor(Qt::CursorShape::SplitHCursor)); - else - setCursor(QCursor(Qt::CursorShape::SplitVCursor)); - } else { - setCursor(QCursor(Qt::CursorShape::ArrowCursor)); - } - - if (this->press_flags) { - auto pos = this->mapFromGlobal(event->globalPos()); - auto split_margin = splitterWidth(); - if (std::get<0>(split_info_store) == SplitType::SPLIT_H) { - setSplitInfo(splitType(), pos.x() - split_margin / 2, split_margin, true); - } else { - setSplitInfo(splitType(), pos.y() - split_margin / 2, split_margin, true); - } - - update(); - } -} +void ViewPresent::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); } +void ViewPresent::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); } +void ViewPresent::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); } void ViewPresent::relayout() { if (display_members) { @@ -549,53 +519,12 @@ void ViewPresent::relayout() { update(); } -std::pair ViewPresent::view_rects() { - auto xrect = this->rect(); - auto type = (int)splitType(); - if (!type) { - auto width0 = splitterPos(); - if (width0 + splitterWidth() > xrect.width()) - width0 = xrect.width() - splitterWidth(); - if (width0 < 0) - width0 = 0; +RectCom *ViewPresent::create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag, bool replace_flag) { + auto vinst = new BaseView(title, bview, empty_flag, replace_flag); + bview->setParent(vinst); - setSplitInfo(splitType(), width0, splitterWidth(), false); - - auto rect0 = QRectF(xrect.topLeft(), QSizeF(width0, xrect.height())); - auto rect1 = QRectF(xrect.topLeft() + QPointF(rect0.width() + splitterWidth(), 0), - QSizeF(xrect.width() - rect0.width() - splitterWidth(), xrect.height())); - return std::make_pair(rect0, rect1); - } else { - auto height0 = splitterPos(); - if (height0 + splitterWidth() > xrect.height()) - height0 = xrect.height() - splitterWidth(); - if (height0 < 0) - height0 = 0; - - setSplitInfo(splitType(), height0, splitterWidth(), false); - - auto rect0 = QRectF(xrect.topLeft(), QSizeF(xrect.width(), height0)); - auto rect1 = QRectF(xrect.topLeft() + QPointF(0, rect0.height() + splitterWidth()), - QSizeF(xrect.width(), xrect.height() - splitterWidth() - rect0.height())); - return std::make_pair(rect0, rect1); - } -} -QRectF ViewPresent::handle_rect() const { - QRectF rect; - - auto width_middle = splitterWidth() - 2; - if (splitType() == SplitType::SPLIT_H) { - rect = QRectF(splitterPos() + 1, 0, width_middle, outline().height()); - } else { - rect = QRectF(0, splitterPos() + 1, outline().width(), width_middle); - } - - return rect; -} - -RectCom *ViewPresent::create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag) { - auto vinst = new BaseView(title, bview, empty_flag); + bview->setMouseTracking(true); vinst->setTitle(title); vinst->setIcon(icon); return vinst; diff --git a/libSplitView/splitpanel.h b/libSplitView/splitpanel.h index eebbf8b..a99274a 100644 --- a/libSplitView/splitpanel.h +++ b/libSplitView/splitpanel.h @@ -65,6 +65,7 @@ namespace SplitFrame { public: virtual ~RectCom() = default; + virtual bool canReplace() const = 0; virtual bool contains(QWidget *ptr) const = 0; virtual QRectF outline() const = 0; @@ -82,7 +83,7 @@ namespace SplitFrame { ViewPresent *const host_store; public: - explicit FnWrap(ViewPresent *bind, QWidget *parent = nullptr) : QWidget(parent), host_store(bind) {} + explicit FnWrap(ViewPresent *bind) : QWidget(), host_store(bind) {} virtual ~FnWrap() { this->closeProcess(); } ViewPresent *bindHost() const { return host_store; } @@ -153,7 +154,7 @@ namespace SplitFrame { if (view_inst->bindHost() != this) throw new Config::SimpleException("非法操作", "不允许混用不同ViewPresent的成员"); - auto panel = create_base_panel(view_inst, icon, title, _blank); + auto panel = create_base_panel(view_inst, icon, title, _blank, !_blank); regist_basepanel(panel); return panel; @@ -166,6 +167,7 @@ namespace SplitFrame { virtual QRectF outline() const override; virtual void relayout(const QRectF &outline) override; virtual QString title() const override; + virtual bool canReplace() const override; // ViewRes interface public: @@ -209,9 +211,8 @@ namespace SplitFrame { AttachPanel *const accept_panel; // 拖拽属性=================================== - RectCom *adjust_view_temp; // 拖拽中转 - bool press_flags = false; // 空间调整标志 - // 方向,splitter位置,splitter宽度 + RectCom *adjust_view_temp; // 拖拽中转 + // 方向,splitter位置,splitter宽度 std::tuple split_info_store = std::make_tuple(SplitType::SPLIT_H, 200, 8); // 视图展现堆栈=============================== @@ -221,11 +222,8 @@ namespace SplitFrame { std::pair temp_visible_view = std::make_pair(DockType::LEFT, nullptr); - std::pair view_rects(); - QRectF handle_rect() const; - virtual void relayout(); - RectCom *create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag = false); + RectCom *create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag = false, bool replace_flag = true); void regist_basepanel(RectCom *it); }; diff --git a/libSplitView/splitview.cpp b/libSplitView/splitview.cpp index f566027..ce43993 100644 --- a/libSplitView/splitview.cpp +++ b/libSplitView/splitview.cpp @@ -53,6 +53,12 @@ SplitType SplitView::splitType() const { return std::get<0>(split_info_value); } void SplitView::setSplitInfo(SplitType type, float pos, float width, bool relayout) { this->split_info_value = std::make_tuple(type, pos, width); + + if (type == SplitType::SPLIT_H) + setCursor(Qt::CursorShape::SplitHCursor); + else + setCursor(Qt::CursorShape::SplitVCursor); + if (relayout) this->relayout(); } @@ -110,6 +116,8 @@ bool SplitView::contains(QWidget *) const { return false; } QString SplitView::title() const { return ""; } +bool SplitView::canReplace() const { return true; } + void SplitView::resizeEvent(QResizeEvent *ev) { QWidget::resizeEvent(ev); relayout(); @@ -120,7 +128,7 @@ void SplitView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::MouseButton::LeftButton) { if (handle_rect().contains(event->pos())) - this->press_flags = true; + drags_state = true; } } @@ -128,26 +136,14 @@ void SplitView::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); if (event->button() == Qt::MouseButton::LeftButton) { - this->press_flags = false; + drags_state = false; } } void SplitView::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); - auto drag_rect = handle_rect() + QMargins(2, 2, 2, 2); - if (drag_rect.contains(event->pos())) { - if (splitType() == SplitType::SPLIT_H) - setCursor(QCursor(Qt::CursorShape::SplitHCursor)); - else - setCursor(QCursor(Qt::CursorShape::SplitVCursor)); - - drags_flag = true; - } else { - setCursor(QCursor(Qt::CursorShape::ArrowCursor)); - } - - if (this->press_flags) { + if (drags_state) { auto pos = this->mapFromGlobal(event->globalPos()); auto split_margin = splitterWidth(); if (std::get<0>(split_info_value) == SplitType::SPLIT_H) { @@ -159,20 +155,6 @@ void SplitView::mouseMoveEvent(QMouseEvent *event) { } } -bool SplitView::eventFilter(QObject *watched, QEvent *event) { - if (watched != this && this->drags_flag && event->type() == QEvent::MouseMove) { - auto x = static_cast(event); - auto pos = mapFromGlobal(x->globalPos()); - if (!handle_rect().contains(pos)) { - setCursor(QCursor(Qt::CursorShape::ArrowCursor)); - this->drags_flag = false; - } - return true; - } - - return QWidget::eventFilter(watched, event); -} - void SplitView::relayout() { auto rects = view_rects(); auto pair = child(); diff --git a/libSplitView/splitview.h b/libSplitView/splitview.h index 1f16c69..c00f8ee 100644 --- a/libSplitView/splitview.h +++ b/libSplitView/splitview.h @@ -31,6 +31,7 @@ namespace SplitFrame { virtual void paintEvent(QPaintEvent *ev) override; virtual bool contains(QWidget *) const override; virtual QString title() const override; + virtual bool canReplace() const override; // SplitRect interface public: @@ -42,10 +43,6 @@ namespace SplitFrame { virtual SplitType splitType() const override; virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override; - // QObject interface - public: - virtual bool eventFilter(QObject *watched, QEvent *event) override; - // QWidget interface protected: virtual void mousePressEvent(QMouseEvent *event) override; @@ -58,7 +55,7 @@ namespace SplitFrame { QList child_store; // type, pos, width std::tuple split_info_value; - bool press_flags = false, drags_flag = false; + bool drags_state = false; virtual void relayout(); std::pair view_rects(); diff --git a/u_test/unnnn.cpp b/u_test/unnnn.cpp index 8c6082a..fff56e5 100644 --- a/u_test/unnnn.cpp +++ b/u_test/unnnn.cpp @@ -3,7 +3,7 @@ #include using namespace SplitFrame; -XWidget::XWidget(ViewPresent *host, Qt::GlobalColor c, QWidget *parent) : FnWrap(host, parent), c_store(c) {} +XWidget::XWidget(ViewPresent *host, Qt::GlobalColor c, QWidget *parent) : FnWrap(host), c_store(c) {} void XWidget::paintEvent(QPaintEvent *ev) { QPainter p(this); @@ -12,7 +12,7 @@ void XWidget::paintEvent(QPaintEvent *ev) { void XWidget::closeProcess() {} -YWidget::YWidget(ViewPresent *host, QWidget *parent) : FnWrap(host, parent) {} +YWidget::YWidget(ViewPresent *host, QWidget *parent) : FnWrap(host) {} void YWidget::paintEvent(QPaintEvent *ev) { QPainter p(this);