From 5516f5443c3a5c6554bc477709d4fff1bd31d9b7 Mon Sep 17 00:00:00 2001 From: Hualet Wang Date: Thu, 22 Aug 2024 22:24:04 +0800 Subject: [PATCH] feat: remove the limit of term splitting a feature request from here: https://bbs.deepin.org/post/277237 --- src/main/mainwindow.cpp | 20 ++---- src/views/termwidget.cpp | 25 +------ src/views/termwidget.h | 7 -- src/views/termwidgetpage.cpp | 131 +++++++++++++++++++++-------------- 4 files changed, 85 insertions(+), 98 deletions(-) diff --git a/src/main/mainwindow.cpp b/src/main/mainwindow.cpp index 52c343ac4..be8f5c569 100644 --- a/src/main/mainwindow.cpp +++ b/src/main/mainwindow.cpp @@ -1131,14 +1131,8 @@ inline void MainWindow::slotShortcutHorizonzalSplit() if (Service::instance()->isCountEnable()) { TermWidgetPage *page = currentPage(); if (page) { - if (page->currentTerminal()) { - int layer = page->currentTerminal()->getTermLayer(); - DSplitter *splitter = qobject_cast(page->currentTerminal()->parentWidget()); - if (1 == layer || (2 == layer && splitter && Qt::Horizontal == splitter->orientation())) { - page->split(Qt::Horizontal); - return ; - } - } + page->split(Qt::Horizontal); + return ; } } qInfo() << "can't split vertical again"; @@ -1150,14 +1144,8 @@ inline void MainWindow::slotShortcutVerticalSplit() if (Service::instance()->isCountEnable()) { TermWidgetPage *page = currentPage(); if (page) { - if (page->currentTerminal()) { - int layer = page->currentTerminal()->getTermLayer(); - DSplitter *splitter = qobject_cast(page->currentTerminal()->parentWidget()); - if (1 == layer || (2 == layer && splitter && Qt::Vertical == splitter->orientation())) { - page->split(Qt::Vertical); - return ; - } - } + page->split(Qt::Vertical); + return ; } } qInfo() << "can't split vertical again"; diff --git a/src/views/termwidget.cpp b/src/views/termwidget.cpp index 810b53003..d917605b8 100644 --- a/src/views/termwidget.cpp +++ b/src/views/termwidget.cpp @@ -480,15 +480,8 @@ void TermWidget::addMenuActions(const QPoint &pos) m_menu->addSeparator(); - - DSplitter *splitter = qobject_cast(parentWidget()); - int layer = getTermLayer(); - - if (1 == layer || (2 == layer && splitter && Qt::Horizontal == splitter->orientation())) - m_menu->addAction(tr("Horizontal split"), this, &TermWidget::onHorizontalSplit); - - if (1 == layer || (2 == layer && splitter && Qt::Vertical == splitter->orientation())) - m_menu->addAction(tr("Vertical split"), this, &TermWidget::onVerticalSplit); + m_menu->addAction(tr("Horizontal split"), this, &TermWidget::onHorizontalSplit); + m_menu->addAction(tr("Vertical split"), this, &TermWidget::onVerticalSplit); /******** Modify by n014361 wangpeili 2020-02-21: 增加关闭窗口和关闭其它窗口菜单 ****************/ m_menu->addAction(QObject::tr("Close workspace"), this, &TermWidget::onCloseCurrWorkSpace); @@ -554,14 +547,12 @@ void TermWidget::addMenuActions(const QPoint &pos) inline void TermWidget::onHorizontalSplit() { - getTermLayer(); // menu关闭与分屏同时进行时,会导致QT计算光标位置异常。 QTimer::singleShot(10, this, &TermWidget::splitHorizontal); } inline void TermWidget::onVerticalSplit() { - getTermLayer(); // menu关闭与分屏同时进行时,会导致QT计算光标位置异常。 QTimer::singleShot(10, this, &TermWidget::splitVertical); } @@ -823,18 +814,6 @@ void TermWidget::setDeleteMode(const EraseMode &deleteMode) QTermWidget::setDeleteMode(&ch, length); } -int TermWidget::getTermLayer() -{ - int layer = 1; - QWidget *currentW = this; - while (currentW->parentWidget() != parentPage()) { - layer++; - currentW = currentW->parentWidget(); - } - qInfo() << "getTermLayer = " << layer; - return layer; -} - void TermWidget::setTabFormat(const QString &tabFormat) { // 非全局设置优先级更高 diff --git a/src/views/termwidget.h b/src/views/termwidget.h index a63b72c2f..802b51f64 100644 --- a/src/views/termwidget.h +++ b/src/views/termwidget.h @@ -189,13 +189,6 @@ class TermWidget : public QTermWidget */ void setDeleteMode(const EraseMode &deleteMode); - /** - * @brief 获取当前terminal距离page的层次.用于限定分屏 - * @author ut000439 王培利 - * @return - */ - int getTermLayer(); - /** * @brief 设置标签标题格式(全局设置) * @author ut000610 戴正文 diff --git a/src/views/termwidgetpage.cpp b/src/views/termwidgetpage.cpp index 92426ac78..aba339313 100644 --- a/src/views/termwidgetpage.cpp +++ b/src/views/termwidgetpage.cpp @@ -18,6 +18,23 @@ #include #include +static void setEqualSizes(QSplitter *splitter) +{ + QList sizes = splitter->sizes(); + int totalSize = 0; + for (int size : sizes) { + totalSize += size; + } + + int equalSize = totalSize / sizes.size(); + for (int i = 0; i < sizes.size(); ++i) { + sizes[i] = equalSize; + } + + splitter->setSizes(sizes); +} + + TermWidgetPage::TermWidgetPage(const TermProperties &properties, QWidget *parent) : QWidget(parent), m_findBar(new PageSearchBar(this)) { @@ -84,21 +101,26 @@ void TermWidgetPage::setParentMainWindow(MainWindow *mainWin) m_MainWindow = mainWin; } +// TODO(hualet): maybe implement a subclass of DSplitter and +// override the createHandle method, all setSplitStyle should +// be removed. void TermWidgetPage::setSplitStyle(DSplitter *splitter) { splitter->setHandleWidth(1); - QSplitterHandle *handle = splitter->handle(1); - - if (handle) { - //分割线颜色暂时设置为Highlight颜色,需要和UI确认下 - //此处代码暂时保留 //DPalette pa = DApplicationHelper::instance()->palette(handle); - //bug#57044 中的分割线颜色,保留的代码对默认主题,和十个内置主题的颜色是正确获取,但是在自定义的颜色获取存在异常,采取如下方式获取 - DPalette pa = DApplicationHelper::instance()->applicationPalette(); - QColor splitBrush = pa.color(DPalette::Highlight); - pa.setBrush(DPalette::Background, splitBrush); - handle->setPalette(pa); - handle->setBackgroundRole(QPalette::Background); - handle->setAutoFillBackground(true); + + for (int i = 1; i < splitter->count(); ++i) { + QSplitterHandle *handle = splitter->handle(i); + if (handle) { + //分割线颜色暂时设置为Highlight颜色,需要和UI确认下 + //此处代码暂时保留 //DPalette pa = DApplicationHelper::instance()->palette(handle); + //bug#57044 中的分割线颜色,保留的代码对默认主题,和十个内置主题的颜色是正确获取,但是在自定义的颜色获取存在异常,采取如下方式获取 + DPalette pa = DApplicationHelper::instance()->applicationPalette(); + QColor splitBrush = pa.color(DPalette::Highlight); + pa.setBrush(DPalette::Background, splitBrush); + handle->setPalette(pa); + handle->setBackgroundRole(QPalette::Background); + handle->setAutoFillBackground(true); + } } } @@ -118,22 +140,35 @@ void TermWidgetPage::split(Qt::Orientation orientation) { parentMainWindow()->showPlugin(MainWindow::PLUGIN_TYPE_NONE); TermWidget *term = m_currentTerm; - if (1 == getTerminalCount()) { - qInfo() << "first split"; - QSplitter *firstSplit = createSubSplit(term, orientation); - m_layout->addWidget(firstSplit); - //return ; + + QSplitter *splitter = qobject_cast(term->parent()); + // if there's already a splitter, and the orientation is correct, + // just add a new term to the splitter. + if (splitter && splitter->orientation() != orientation) { + TermProperties properties(term->workingDirectory()); + TermWidget *newTerm = createTerm(properties); + splitter->addWidget(newTerm); + setSplitStyle(splitter); + setCurrentTerminal(newTerm); } else { - qInfo() << "not first split"; - QSplitter *upSplit = qobject_cast(term->parent()); - int index = upSplit->indexOf(term); - QList parentSizes = upSplit->sizes(); - - // 用新的Split分割布局替换原来的位置 - QSplitter *subSplit = createSubSplit(term, orientation); - upSplit->insertWidget(index, subSplit); - upSplit->setSizes(parentSizes); - setSplitStyle(upSplit); + // if there's no splitter, or the orientation is not correct, + // create a new splitter, put the 2 terms into the splitter, + // and put the splitter the right postion. + int index = 0; + if (splitter) { + index = splitter->indexOf(term); + } else { + index = m_layout->indexOf(term); + } + + QSplitter *newSplitter = createSubSplit(term, orientation); + + if (splitter) { + splitter->insertWidget(index, newSplitter); + setEqualSizes(splitter); + } else { + m_layout->insertWidget(index, newSplitter); + } } /******** Add by ut001000 renfeixiang 2020-08-07:新增分屏时改变大小,bug#41436***************/ @@ -179,40 +214,32 @@ void TermWidgetPage::closeSplit(TermWidget *term, bool hasConfirmed) showExitConfirmDialog(Utils::CloseType_Terminal, 1, parentMainWindow()); return; } - QSplitter *upSplit = qobject_cast(term->parent()); - term->setParent(nullptr); - // 另一个兄弟也可能是终端,也可能是split, - QWidget *brother = upSplit->widget(0); - TermWidget *nextTerm = upSplit->findChild(); - // 如果上级是分屏 - if ("QSplitter" == QString(upSplit->parent()->metaObject()->className())) { - QSplitter *upupSplit = qobject_cast(upSplit->parent()); - //兄弟替换parent split - upupSplit->replaceWidget(upupSplit->indexOf(upSplit), brother); - } - // 上级不是分屏控件,就是布局在控制了 - else { - qInfo() << "TermWidgetPage only one term exist!"; - m_layout->addWidget(brother); - } - // 子控件的变化会引起焦点的变化,控制焦点要放在最后 - if (nextTerm != nullptr) { - qInfo() << "nextTerm change" << m_currentTerm->getSessionId(); - nextTerm->setFocus(); - } else { - qInfo() << "can not found nextTerm in TermWidget"; + QSplitter *upSplit = qobject_cast(term->parent()); + if (upSplit && upSplit->count() == 1) { + upSplit->setParent(nullptr); + upSplit->deleteLater(); + upSplit = nullptr; } + // TODO(hualet): set focus to another TermWidget. + // 释放控件,并隐藏term、upSplit,避免出现闪现窗口bug#80809 + term->setParent(nullptr); term->hide(); term->deleteLater(); // 断开相关的连接:(UT_MainWindow_Test, slotShortcutCloseWorkspace)出现的崩溃问题 Settings::instance()->disconnect(term); - upSplit->hide(); - upSplit->setParent(nullptr); - upSplit->deleteLater(); + + if (upSplit) { + upSplit->setFocus(); + } + + // upSplit->hide(); + // upSplit->setParent(nullptr); + // upSplit->deleteLater(); + qInfo() << "page terminal count =" << getTerminalCount(); /******** Add by ut001000 renfeixiang 2020-08-07:关闭分屏时改变大小,bug#41436***************/ parentMainWindow()->updateMinHeight();