diff --git a/sources/PropertiesEditor/propertieseditordockwidget.cpp b/sources/PropertiesEditor/propertieseditordockwidget.cpp index 7cf5dffea..a40f7cda6 100644 --- a/sources/PropertiesEditor/propertieseditordockwidget.cpp +++ b/sources/PropertiesEditor/propertieseditordockwidget.cpp @@ -19,6 +19,9 @@ #include "ui_propertieseditordockwidget.h" #include "propertieseditorwidget.h" +#include +#include + /** @brief PropertiesEditorDockWidget::PropertiesEditorDockWidget Constructor @@ -48,6 +51,9 @@ PropertiesEditorDockWidget::~PropertiesEditorDockWidget() */ void PropertiesEditorDockWidget::clear() { + if (!m_editor_list.isEmpty()) + rememberHeight(); + foreach (PropertiesEditorWidget *editor, m_editor_list) { m_editor_list.removeOne(editor); @@ -94,8 +100,11 @@ bool PropertiesEditorDockWidget::addEditor(PropertiesEditorWidget *editor, if (!editor) return false; if (m_editor_list.contains(editor)) return true; + const bool was_empty = m_editor_list.isEmpty(); ui -> m_main_vlayout -> insertWidget(index, editor); m_editor_list << editor; + if (was_empty) + restoreHeight(); return true; } @@ -118,9 +127,84 @@ QList PropertiesEditorDockWidget::editors() const */ bool PropertiesEditorDockWidget::removeEditor(PropertiesEditorWidget *editor) { + if (m_editor_list.size() == 1 && m_editor_list.first() == editor) + rememberHeight(); + bool result = m_editor_list.removeOne(editor); if (result) ui -> m_main_vlayout -> removeWidget(editor); return result; } + +/** + @brief PropertiesEditorDockWidget::rememberHeight + The dock shrinks to its title bar while it has no editor, and the + other docks of its area take the room. Keep the heights the docks + of the area have now, the heights the user gave them, to give them + back when an editor comes back. +*/ +void PropertiesEditorDockWidget::rememberHeight() +{ + // Still the shrunk height: the last editor came and went + // before the heights were given back + if (m_restore_pending || isFloating() || !isVisible()) + return; + auto main_window = qobject_cast(parentWidget()); + if (!main_window) + return; + + m_area_docks.clear(); + m_area_heights.clear(); + const Qt::DockWidgetArea area = main_window->dockWidgetArea(this); + for (QDockWidget *dock : main_window->findChildren()) + { + if (dock->parentWidget() == main_window && !dock->isFloating() + && dock->isVisible() + && main_window->dockWidgetArea(dock) == area) + { + m_area_docks << dock; + m_area_heights << dock->height(); + } + } +} + +/** + @brief PropertiesEditorDockWidget::restoreHeight + Give the docks of the area back the heights they had before this + dock shrank. Without this the area is split again from the docks' + size hints, and giving this dock alone its height back takes the + room only from its neighbours. +*/ +void PropertiesEditorDockWidget::restoreHeight() +{ + if (m_area_docks.isEmpty() || m_restore_pending) + return; + + m_restore_pending = true; + // Once the layout has given the dock its maximum height back + QTimer::singleShot(0, this, [this]() { + m_restore_pending = false; + auto main_window = qobject_cast(parentWidget()); + if (!main_window || isFloating() || !isVisible() + || m_editor_list.isEmpty()) + return; + + QList docks; + QList heights; + const Qt::DockWidgetArea area = main_window->dockWidgetArea(this); + for (int i = 0 ; i < m_area_docks.size() ; ++i) + { + QDockWidget *dock = m_area_docks.at(i); + // Closed, moved or deleted since + if (dock && !dock->isFloating() && dock->isVisible() + && main_window->dockWidgetArea(dock) == area) + { + docks << dock; + heights << m_area_heights.at(i); + } + } + if (docks.contains(this)) + main_window->resizeDocks(docks, heights, Qt::Vertical); + }); +} diff --git a/sources/PropertiesEditor/propertieseditordockwidget.h b/sources/PropertiesEditor/propertieseditordockwidget.h index e5d1054ba..cd7a801a6 100644 --- a/sources/PropertiesEditor/propertieseditordockwidget.h +++ b/sources/PropertiesEditor/propertieseditordockwidget.h @@ -19,6 +19,7 @@ #define SELECTIONPROPERTIESDOCKWIDGET_H #include +#include class PropertiesEditorWidget; @@ -45,7 +46,13 @@ class PropertiesEditorDockWidget : public QDockWidget QList m_editor_list; private: + void rememberHeight(); + void restoreHeight(); + Ui::PropertiesEditorDockWidget *ui; + QList> m_area_docks; + QList m_area_heights; + bool m_restore_pending = false; }; #endif // SELECTIONPROPERTIESDOCKWIDGET_H diff --git a/sources/PropertiesEditor/propertieseditordockwidget.ui b/sources/PropertiesEditor/propertieseditordockwidget.ui index c98821006..9f58f52bf 100644 --- a/sources/PropertiesEditor/propertieseditordockwidget.ui +++ b/sources/PropertiesEditor/propertieseditordockwidget.ui @@ -16,7 +16,7 @@ - QLayout::SetDefaultConstraint + QLayout::SetMaximumSize 0 diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt index 83249d7a1..496e381ee 100644 --- a/tests/qttest/CMakeLists.txt +++ b/tests/qttest/CMakeLists.txt @@ -308,8 +308,8 @@ qet_add_app_test(tst_imagehandleescape tst_imagehandleescape.cpp) # pixels and position; an with no picture does not stop the others. qet_add_app_test(tst_folioimageload tst_folioimageload.cpp) -# The Selection properties panel keeps the height the user gave it when the -# selection has nothing to edit for a moment (#1439). +# The Selection properties panel shrinks while the selection has nothing to +# edit (#1566) and gets back the height the user gave it (#1439). qet_add_app_test(tst_selectionpanelheight tst_selectionpanelheight.cpp) # Opening a project before the elements panel's first reload() left its tree diff --git a/tests/qttest/tst_selectionpanelheight.cpp b/tests/qttest/tst_selectionpanelheight.cpp index 49ccb1024..b15a79b15 100644 --- a/tests/qttest/tst_selectionpanelheight.cpp +++ b/tests/qttest/tst_selectionpanelheight.cpp @@ -6,10 +6,11 @@ #include -// The Selection properties panel keeps the height the user gave it when the -// selection has nothing it can edit for a moment (#1439). It used to shrink -// to its title bar, the other panels took the room, and an element selected -// again brought the panel back at its default height. +// The Selection properties panel shrinks to its title bar while the selection +// 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. class tst_selectionpanelheight : public QObject { Q_OBJECT @@ -57,10 +58,12 @@ class tst_selectionpanelheight : public QObject const int user = panel->height(); QVERIFY2(user > start, "the panel could not be made taller"); - select(nullptr); - QCOMPARE(panel->height(), user); - select(element); - QCOMPARE(panel->height(), user); + for (int round = 0; round < 2; ++round) { + select(nullptr); + QVERIFY2(panel->height() < start / 4, "the empty panel did not shrink"); + select(element); + QCOMPARE(panel->height(), user); + } } };