Skip to content

Commit

Permalink
feat: remove the limit of term splitting
Browse files Browse the repository at this point in the history
a feature request from here: https://bbs.deepin.org/post/277237
  • Loading branch information
Hualet Wang committed Aug 26, 2024
1 parent 8cc8579 commit 5516f54
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 98 deletions.
20 changes: 4 additions & 16 deletions src/main/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DSplitter *>(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";
Expand All @@ -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<DSplitter *>(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";
Expand Down
25 changes: 2 additions & 23 deletions src/views/termwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,15 +480,8 @@ void TermWidget::addMenuActions(const QPoint &pos)

m_menu->addSeparator();


DSplitter *splitter = qobject_cast<DSplitter *>(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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
{
// 非全局设置优先级更高
Expand Down
7 changes: 0 additions & 7 deletions src/views/termwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,6 @@ class TermWidget : public QTermWidget
*/
void setDeleteMode(const EraseMode &deleteMode);

/**
* @brief 获取当前terminal距离page的层次.用于限定分屏
* @author ut000439 王培利
* @return
*/
int getTermLayer();

/**
* @brief 设置标签标题格式(全局设置)
* @author ut000610 戴正文
Expand Down
131 changes: 79 additions & 52 deletions src/views/termwidgetpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@
#include <QVBoxLayout>
#include <QApplication>

static void setEqualSizes(QSplitter *splitter)
{
QList<int> sizes = splitter->sizes();
int totalSize = 0;
for (int size : sizes) {
totalSize += size;

Check warning on line 26 in src/views/termwidgetpage.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Consider using std::accumulate algorithm instead of a raw loop.
}

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))
{
Expand Down Expand Up @@ -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);
}
}
}

Expand All @@ -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<QSplitter *>(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<QSplitter *>(term->parent());
int index = upSplit->indexOf(term);
QList<int> 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***************/
Expand Down Expand Up @@ -179,40 +214,32 @@ void TermWidgetPage::closeSplit(TermWidget *term, bool hasConfirmed)
showExitConfirmDialog(Utils::CloseType_Terminal, 1, parentMainWindow());
return;
}
QSplitter *upSplit = qobject_cast<QSplitter *>(term->parent());
term->setParent(nullptr);

// 另一个兄弟也可能是终端,也可能是split,
QWidget *brother = upSplit->widget(0);
TermWidget *nextTerm = upSplit->findChild<TermWidget *>();
// 如果上级是分屏
if ("QSplitter" == QString(upSplit->parent()->metaObject()->className())) {
QSplitter *upupSplit = qobject_cast<QSplitter *>(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<QSplitter *>(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();
Expand Down

0 comments on commit 5516f54

Please sign in to comment.