summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2015-03-19 17:47:13 +0100
committerOlivier Goffart (Woboq GmbH) <ogoffart@woboq.com>2015-08-16 08:23:32 +0000
commitf029468b8d822da378a20577f7b8c16a447e4e1b (patch)
tree1880893f39f04e8ab95240671f2b4b7f381ad62d
parent385202c27caa070e07eba098a1b968f9d466aaad (diff)
Add QMainWindow::resizeDocks
This API allows to programatically resize QDockWidgets Task-number: QTBUG-32001 Change-Id: I58072a391f8e7f325a26745b5bedd3fe49508e91 Reviewed-by: Jocelyn Turcotte (Woboq GmbH) <jturcotte@woboq.com>
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp47
-rw-r--r--src/widgets/widgets/qdockarealayout_p.h1
-rw-r--r--src/widgets/widgets/qmainwindow.cpp29
-rw-r--r--src/widgets/widgets/qmainwindow.h3
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp93
5 files changed, 173 insertions, 0 deletions
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index c61984a457..0a00086138 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -3101,6 +3101,53 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
remove(index);
}
+void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation o)
+{
+ if (docks.count() != sizes.count()) {
+ qWarning("QMainWidget::resizeDocks: size of the lists are not the same");
+ return;
+ }
+ int count = docks.count();
+ fallbackToSizeHints = false;
+ for (int i = 0; i < count; ++i) {
+ QList<int> path = indexOf(docks[i]);
+ if (path.isEmpty()) {
+ qWarning("QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
+ continue;
+ }
+ int size = sizes[i];
+ if (size <= 0) {
+ qWarning("QMainWidget::resizeDocks: all sizes need to be larger than 0");
+ size = 1;
+ }
+
+ while (path.size() > 1) {
+ QDockAreaLayoutInfo *info = this->info(path);
+ if (!info->tabbed && info->o == o) {
+ info->item_list[path.last()].size = size;
+ int totalSize = 0;
+ foreach (const QDockAreaLayoutItem &item, info->item_list) {
+ if (!item.skip()) {
+ if (totalSize != 0)
+ totalSize += sep;
+ totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size;
+ }
+ }
+ size = totalSize;
+ }
+ path.removeLast();
+ }
+
+ const int dockNum = path.first();
+ Q_ASSERT(dockNum < QInternal::DockCount);
+ QRect &r = this->docks[dockNum].rect;
+ QSize s = r.size();
+ rpick(o, s) = size;
+ r.setSize(s);
+ }
+}
+
void QDockAreaLayout::splitDockWidget(QDockWidget *after,
QDockWidget *dockWidget,
Qt::Orientation orientation)
diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h
index 93b005f64f..5d352f0124 100644
--- a/src/widgets/widgets/qdockarealayout_p.h
+++ b/src/widgets/widgets/qdockarealayout_p.h
@@ -268,6 +268,7 @@ public:
void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
Qt::Orientation orientation);
void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
+ void resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o);
void apply(bool animate);
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 5d53e7def4..ff4bb3cc98 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1237,6 +1237,35 @@ void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
{ return d_func()->layout->dockWidgetArea(dockwidget); }
+
+/*!
+ \since 5.6
+ Resizes the dock widgets in the list \a docks to the corresponding size in
+ pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts
+ the width, otherwise adjusts the height of the dock widgets.
+ The sizes will be adjusted such that the maximum and the minimum sizes are
+ respected and the QMainWindow itself will not be resized.
+ Any additional/missing space is distributed amongst the widgets according
+ to the relative weight of the sizes.
+
+ Example:
+ \code
+ resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal);
+ \endcode
+ If the blue and the yellow widget are nested on the same level they will be
+ resized such that the yellowWidget is twice as big as the blueWidget
+
+ If some widgets are grouped in tabs, only one widget per group should be
+ specified. Widgets not in the list might be changed to repect the constraints.
+*/
+void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation orientation)
+{
+ d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation);
+ d_func()->layout->invalidate();
+}
+
+
#endif // QT_NO_DOCKWIDGET
/*!
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
index ab6ee22748..70d78a7904 100644
--- a/src/widgets/widgets/qmainwindow.h
+++ b/src/widgets/widgets/qmainwindow.h
@@ -165,6 +165,9 @@ public:
bool restoreDockWidget(QDockWidget *dockwidget);
Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
+
+ void resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation orientation);
#endif // QT_NO_DOCKWIDGET
QByteArray saveState(int version = 0) const;
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index e8c533f301..6282028746 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -149,6 +149,8 @@ private slots:
void toggleUnifiedTitleAndToolBarOnMac();
#endif
void QTBUG21378_animationFinished();
+ void resizeDocks();
+ void resizeDocks_data();
};
@@ -1950,5 +1952,96 @@ void tst_QMainWindow::QTBUG21378_animationFinished()
delete mwClickTimer;
QVERIFY(true);
}
+
+Q_DECLARE_METATYPE(Qt::Orientation)
+
+void tst_QMainWindow::resizeDocks_data()
+{
+ QTest::addColumn<Qt::Orientation>("orientation");
+ QTest::addColumn<QStringList>("docks");
+ QTest::addColumn<QList<int> >("sizes");
+
+ QTest::newRow("1") << Qt::Horizontal
+ << (QStringList() << "blue" << "orange" << "green" << "gray")
+ << (QList<int>() << 190 << 190 << 320 << 160);
+
+ QTest::newRow("2") << Qt::Vertical
+ << (QStringList() << "yellow" << "orange")
+ << (QList<int>() << 147 << 133 );
+
+
+ QTest::newRow("3") << Qt::Horizontal
+ << (QStringList() << "blue" << "yellow")
+ << (QList<int>() << 190 << 600);
+}
+
+void tst_QMainWindow::resizeDocks()
+{
+ AddList addList;
+ addList
+ << AddDockWidget("blue", Qt::LeftDockWidgetArea)
+ << AddDockWidget("red", Qt::TopDockWidgetArea)
+ << AddDockWidget("pink", "red")
+ << AddDockWidget("yellow", Qt::RightDockWidgetArea)
+ << AddDockWidget("orange", Qt::RightDockWidgetArea)
+ << AddDockWidget("green", "orange", Qt::Horizontal)
+ << AddDockWidget("gray", "orange", Qt::Horizontal);
+ /*
+ +--------------------------------+
+ | red/pink |
+ +------+-+-----------------------+
+ | | | yellow |
+ | blue + +--------+------+-------+
+ | | | orange | gray | green |
+ +------+-+--------+------+-------+
+
+ */
+
+ QMainWindow mw(0, Qt::BypassWindowManagerHint);
+ mw.setDockNestingEnabled(true);
+ mw.resize(1800, 600);
+
+ foreach (const AddDockWidget &i, addList)
+ i.apply(&mw);
+
+ foreach (QDockWidget *dw, mw.findChildren<QDockWidget *>())
+ dw->setStyleSheet( "* { background-color: " + dw->objectName() +" }");
+
+ mw.setCentralWidget(new QTextEdit);
+
+ mw.show();
+ QTest::qWaitForWindowExposed(&mw);
+
+ QFETCH(Qt::Orientation, orientation);
+ QFETCH(QStringList, docks);
+ QFETCH(QList<int>, sizes);
+
+ QList<QDockWidget *> list;
+ foreach (const QString &name, docks) {
+ QDockWidget *d = mw.findChild<QDockWidget *>(name);
+ QVERIFY(d);
+ list << d;
+ }
+
+ mw.resizeDocks(list, sizes, orientation);
+
+ qApp->processEvents();
+
+ int totalFromList = 0;
+ int actualTotal = 0;
+ for (int i = 0; i < docks.count(); ++i) {
+ totalFromList += sizes[i];
+ QSize s = list[i]->size();
+ actualTotal += (orientation == Qt::Horizontal) ? s.width() : s.height();
+// qDebug() << list[i] << list[i]->size() << sizes[i];
+ }
+
+ for (int i = 0; i < docks.count(); ++i) {
+ QSize s = list[i]->size();
+ int value = (orientation == Qt::Horizontal) ? s.width() : s.height();
+ QCOMPARE(value, qRound(sizes[i]*actualTotal/double(totalFromList)));
+ }
+}
+
QTEST_MAIN(tst_QMainWindow)
#include "tst_qmainwindow.moc"