#include "viewsession.h" #include "messagespresent.h" #include "presentcontainer.h" #include "projectpresent.h" using namespace Config; using namespace Core; using namespace SplitFrame; using namespace Components; ViewSession::ViewSession(Config::Configration *port, ViewPresent *host) : host(host), recover_port(port) {} void ViewSession::initPresentView(PresentContainer *center_frame, ProjectPresent *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 = MessagesPresent::gen(host, error_model, host->bind()); auto msg_panel = host->appendView(msg_view, QIcon(":/ui/icons/file_icon.jpg"), "信息提示"); host->markFreedom(msg_panel); view_store[msg_panel->title()] = msg_panel; } const QList base_path = {"sys-config", "front-end", "view-state"}; void views_state_store(Config::Configration *port, const QList &base_path, const QList &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(it); if (conv) { // split QHash 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() << split_childs.first << split_childs.second); } else { // view QHash values; values["rect-type"] = "view"; values["view-title"] = it->title(); port->setMap(keys_path, values); } } } void ViewSession::viewStatesSave(QMainWindow *win, SplitFrame::ViewPresent *root) { recover_port->deleteX(base_path); auto childs = root->child(); auto grect = win->geometry(); QHash 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() << childs.first << childs.second); } RectCom *ViewSession::views_state_restore(const QHash &cache, const QList &target_path, Config::Configration *port, SplitFrame::ViewPresent *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(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::ViewPresent *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); }