diff --git a/sources/PropertiesEditor/propertieseditordockwidget.cpp b/sources/PropertiesEditor/propertieseditordockwidget.cpp index a40f7cda6..97ce5ddef 100644 --- a/sources/PropertiesEditor/propertieseditordockwidget.cpp +++ b/sources/PropertiesEditor/propertieseditordockwidget.cpp @@ -32,6 +32,13 @@ PropertiesEditorDockWidget::PropertiesEditorDockWidget(QWidget *parent) : ui(new Ui::PropertiesEditorDockWidget) { ui->setupUi(this); + // Tabbed or not can change without the selection changing + connect(this, &QDockWidget::dockLocationChanged, + this, &PropertiesEditorDockWidget::updateSizeConstraint); + connect(this, &QDockWidget::topLevelChanged, + this, &PropertiesEditorDockWidget::updateSizeConstraint); + connect(this, &QDockWidget::visibilityChanged, + this, &PropertiesEditorDockWidget::updateSizeConstraint); } /** @@ -62,6 +69,7 @@ void PropertiesEditorDockWidget::clear() } m_editor_list.clear(); + updateSizeConstraint(); } /** @@ -105,6 +113,7 @@ bool PropertiesEditorDockWidget::addEditor(PropertiesEditorWidget *editor, m_editor_list << editor; if (was_empty) restoreHeight(); + updateSizeConstraint(); return true; } @@ -133,6 +142,7 @@ bool PropertiesEditorDockWidget::removeEditor(PropertiesEditorWidget *editor) bool result = m_editor_list.removeOne(editor); if (result) ui -> m_main_vlayout -> removeWidget(editor); + updateSizeConstraint(); return result; } @@ -150,6 +160,12 @@ void PropertiesEditorDockWidget::rememberHeight() // before the heights were given back if (m_restore_pending || isFloating() || !isVisible()) return; + // A tabbed dock does not shrink: nothing to give back + if (isTabbed()) { + m_area_docks.clear(); + m_area_heights.clear(); + return; + } auto main_window = qobject_cast(parentWidget()); if (!main_window) return; @@ -187,7 +203,7 @@ void PropertiesEditorDockWidget::restoreHeight() m_restore_pending = false; auto main_window = qobject_cast(parentWidget()); if (!main_window || isFloating() || !isVisible() - || m_editor_list.isEmpty()) + || m_editor_list.isEmpty() || isTabbed()) return; QList docks; @@ -208,3 +224,37 @@ void PropertiesEditorDockWidget::restoreHeight() main_window->resizeDocks(docks, heights, Qt::Vertical); }); } + +/** + @brief PropertiesEditorDockWidget::updateSizeConstraint + The empty dock shrinks to its title bar, but not while it shares a tab + stack with other docks: the stack takes the smallest maximum height of + its tabs, so the empty dock would hold every other tab at its title bar + and the stack could not be resized. +*/ +void PropertiesEditorDockWidget::updateSizeConstraint() +{ + const bool tabbed = isTabbed(); + const QLayout::SizeConstraint constraint = tabbed + ? QLayout::SetDefaultConstraint + : QLayout::SetMaximumSize; + if (ui->verticalLayout->sizeConstraint() == constraint) + return; + + ui->verticalLayout->setSizeConstraint(constraint); + // SetMaximumSize left its maximum on the contents + if (tabbed) + ui->dockWidgetContents->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +/** + @brief PropertiesEditorDockWidget::isTabbed + @return true if this dock shares a tab stack with other docks +*/ +bool PropertiesEditorDockWidget::isTabbed() const +{ + auto main_window = qobject_cast(parentWidget()); + return main_window && !isFloating() + && !main_window->tabifiedDockWidgets( + const_cast(this)).isEmpty(); +} diff --git a/sources/PropertiesEditor/propertieseditordockwidget.h b/sources/PropertiesEditor/propertieseditordockwidget.h index cd7a801a6..f87e78d41 100644 --- a/sources/PropertiesEditor/propertieseditordockwidget.h +++ b/sources/PropertiesEditor/propertieseditordockwidget.h @@ -48,6 +48,8 @@ class PropertiesEditorDockWidget : public QDockWidget private: void rememberHeight(); void restoreHeight(); + void updateSizeConstraint(); + bool isTabbed() const; Ui::PropertiesEditorDockWidget *ui; QList> m_area_docks; diff --git a/tests/qttest/tst_selectionpanelheight.cpp b/tests/qttest/tst_selectionpanelheight.cpp index b15a79b15..d8643918f 100644 --- a/tests/qttest/tst_selectionpanelheight.cpp +++ b/tests/qttest/tst_selectionpanelheight.cpp @@ -10,7 +10,9 @@ // has nothing it can edit, so the other panels get the room (#1566), and gets // back the height the user gave it when an element is selected again. Before // #1439 it came back at its default height; #1533 kept the height but no -// longer shrank. +// longer shrank. Tabbed with another panel, it does not shrink: a tab stack +// takes the smallest maximum height of its tabs, and the empty panel held +// the Collections tab at its title bar. class tst_selectionpanelheight : public QObject { Q_OBJECT @@ -65,6 +67,68 @@ class tst_selectionpanelheight : public QObject QCOMPARE(panel->height(), user); } } + + void tabbedStackResizes() + { + QETDiagramEditor *editor = QetAppTest::editor(); + QVERIFY(editor); + editor->resize(1600, 1500); + editor->show(); + QVERIFY(QTest::qWaitForWindowExposed(editor)); + const QString copy = m_dir.filePath("q.qet"); + QVERIFY(QFile::copy(QFINDTESTDATA("fixtures/ten_sequential_numbers.qet"), copy)); + QVERIFY(editor->openAndAddProject(copy, false)); + Diagram *diagram = editor->currentProjectView()->currentDiagram()->diagram(); + Element *element = nullptr; + for (QGraphicsItem *qgi : diagram->items()) + if (qgi->type() == Element::Type) + element = static_cast(qgi); + QVERIFY(element); + auto panel = editor->findChild("diagram_properties_editor_dock_widget"); + auto collections = editor->findChild("elements_collection_widget"); + QVERIFY(panel); + QVERIFY(collections); + + // Collections dragged onto the empty panel, as a tab in front + element->setSelected(true); + QTest::qWait(200); + diagram->clearSelection(); + QTest::qWait(200); + QVERIFY2(panel->maximumHeight() < 100, "the panel is not empty"); + editor->tabifyDockWidget(panel, collections); + collections->raise(); + QTest::qWait(200); + QCOMPARE(editor->dockWidgetArea(collections), editor->dockWidgetArea(panel)); + QVERIFY(editor->tabifiedDockWidgets(panel).contains(collections)); + + const int start = collections->height(); + // Above the minimum height of the element's editor, which + // a tab stack keeps while the editor is shown + editor->resizeDocks({collections}, {start + 700}, Qt::Vertical); + QTest::qWait(200); + const int user = collections->height(); + QVERIFY2(user > start, "the tab stack could not be made taller"); + + // Selecting and deselecting leaves the stack alone + element->setSelected(true); + QTest::qWait(200); + diagram->clearSelection(); + QTest::qWait(200); + QCOMPARE(collections->height(), user); + + // Back on its own, the empty panel shrinks again + editor->removeDockWidget(collections); + editor->addDockWidget(Qt::RightDockWidgetArea, collections); + collections->show(); + QTest::qWait(200); + QVERIFY(editor->tabifiedDockWidgets(panel).isEmpty()); + element->setSelected(true); + QTest::qWait(200); + const int selected = panel->height(); + diagram->clearSelection(); + QTest::qWait(200); + QVERIFY2(panel->height() < selected / 4, "the empty panel did not shrink once untabbed"); + } }; QET_APP_TEST_MAIN(tst_selectionpanelheight)