Merge pull request #1594 from jp2images/fix/tabbed-selection-panel

Keep a tabbed Selection properties panel from locking its tab stack
This commit is contained in:
Laurent Trinques
2026-10-24 02:40:00 +02:00
committed by GitHub
3 changed files with 118 additions and 2 deletions
@@ -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<QMainWindow *>(parentWidget());
if (!main_window)
return;
@@ -187,7 +203,7 @@ void PropertiesEditorDockWidget::restoreHeight()
m_restore_pending = false;
auto main_window = qobject_cast<QMainWindow *>(parentWidget());
if (!main_window || isFloating() || !isVisible()
|| m_editor_list.isEmpty())
|| m_editor_list.isEmpty() || isTabbed())
return;
QList<QDockWidget *> 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<QMainWindow *>(parentWidget());
return main_window && !isFloating()
&& !main_window->tabifiedDockWidgets(
const_cast<PropertiesEditorDockWidget *>(this)).isEmpty();
}
@@ -48,6 +48,8 @@ class PropertiesEditorDockWidget : public QDockWidget
private:
void rememberHeight();
void restoreHeight();
void updateSizeConstraint();
bool isTabbed() const;
Ui::PropertiesEditorDockWidget *ui;
QList<QPointer<QDockWidget>> m_area_docks;
+65 -1
View File
@@ -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<Element *>(qgi);
QVERIFY(element);
auto panel = editor->findChild<QDockWidget *>("diagram_properties_editor_dock_widget");
auto collections = editor->findChild<QDockWidget *>("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)