1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QWidgetItem>
41#include <QToolBar>
42#include <QStyleOption>
43#include <QApplication>
44#include <qdebug.h>
45
46#include "qtoolbararealayout_p.h"
47#include "qmainwindowlayout_p.h"
48#include "qwidgetanimator_p.h"
49#include "qtoolbarlayout_p.h"
50#include "qtoolbar_p.h"
51
52/******************************************************************************
53** QToolBarAreaLayoutItem
54*/
55
56QT_BEGIN_NAMESPACE
57
58// qmainwindow.cpp
59extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow);
60
61QSize QToolBarAreaLayoutItem::minimumSize() const
62{
63 if (skip())
64 return QSize(0, 0);
65 return qSmartMinSize(i: static_cast<QWidgetItem*>(widgetItem));
66}
67
68QSize QToolBarAreaLayoutItem::sizeHint() const
69{
70 if (skip())
71 return QSize(0, 0);
72
73 return realSizeHint();
74}
75
76//returns the real size hint not taking into account the visibility of the widget
77QSize QToolBarAreaLayoutItem::realSizeHint() const
78{
79 QWidget *wid = widgetItem->widget();
80 QSize s = wid->sizeHint().expandedTo(otherSize: wid->minimumSizeHint());
81 if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
82 s.setWidth(0);
83 if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
84 s.setHeight(0);
85 s = s.boundedTo(otherSize: wid->maximumSize())
86 .expandedTo(otherSize: wid->minimumSize());
87 return s;
88}
89
90bool QToolBarAreaLayoutItem::skip() const
91{
92 if (gap)
93 return false;
94 return widgetItem == nullptr || widgetItem->isEmpty();
95}
96
97/******************************************************************************
98** QToolBarAreaLayoutLine
99*/
100
101QToolBarAreaLayoutLine::QToolBarAreaLayoutLine(Qt::Orientation orientation)
102 : o(orientation)
103{
104}
105
106QSize QToolBarAreaLayoutLine::sizeHint() const
107{
108 int a = 0, b = 0;
109 for (int i = 0; i < toolBarItems.count(); ++i) {
110 const QToolBarAreaLayoutItem &item = toolBarItems.at(i);
111 if (item.skip())
112 continue;
113
114 QSize sh = item.sizeHint();
115 a += item.preferredSize > 0 ? item.preferredSize : pick(o, size: sh);
116 b = qMax(a: b, b: perp(o, size: sh));
117 }
118
119 QSize result;
120 rpick(o, size&: result) = a;
121 rperp(o, size&: result) = b;
122
123 return result;
124}
125
126QSize QToolBarAreaLayoutLine::minimumSize() const
127{
128 int a = 0, b = 0;
129 for (int i = 0; i < toolBarItems.count(); ++i) {
130 const QToolBarAreaLayoutItem &item = toolBarItems[i];
131 if (item.skip())
132 continue;
133
134 QSize ms = item.minimumSize();
135 a += pick(o, size: ms);
136 b = qMax(a: b, b: perp(o, size: ms));
137 }
138
139 QSize result;
140 rpick(o, size&: result) = a;
141 rperp(o, size&: result) = b;
142
143 return result;
144}
145
146void QToolBarAreaLayoutLine::fitLayout()
147{
148 int last = -1;
149 int min = pick(o, size: minimumSize());
150 int space = pick(o, size: rect.size());
151 int extra = qMax(a: 0, b: space - min);
152
153 for (int i = 0; i < toolBarItems.count(); ++i) {
154 QToolBarAreaLayoutItem &item = toolBarItems[i];
155 if (item.skip())
156 continue;
157
158 if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(object: item.widgetItem->widget()->layout()))
159 tblayout->checkUsePopupMenu();
160
161 const int itemMin = pick(o, size: item.minimumSize());
162 //preferredSize is the default if it is set, otherwise, we take the sizehint
163 item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, size: item.sizeHint());
164
165 //the extraspace is the space above the item minimum sizehint
166 const int extraSpace = qMin(a: item.size - itemMin, b: extra);
167 item.size = itemMin + extraSpace; //that is the real size
168
169 extra -= extraSpace;
170
171 last = i;
172 }
173
174 // calculate the positions from the sizes
175 int pos = 0;
176 for (int i = 0; i < toolBarItems.count(); ++i) {
177 QToolBarAreaLayoutItem &item = toolBarItems[i];
178 if (item.skip())
179 continue;
180
181 item.pos = pos;
182 if (i == last) // stretch the last item to the end of the line
183 item.size = qMax(a: 0, b: pick(o, size: rect.size()) - item.pos);
184 pos += item.size;
185 }
186}
187
188bool QToolBarAreaLayoutLine::skip() const
189{
190 for (int i = 0; i < toolBarItems.count(); ++i) {
191 if (!toolBarItems.at(i).skip())
192 return false;
193 }
194 return true;
195}
196
197/******************************************************************************
198** QToolBarAreaLayoutInfo
199*/
200
201QToolBarAreaLayoutInfo::QToolBarAreaLayoutInfo(QInternal::DockPosition pos)
202 : dockPos(pos), dirty(false)
203{
204 switch (pos) {
205 case QInternal::LeftDock:
206 case QInternal::RightDock:
207 o = Qt::Vertical;
208 break;
209 case QInternal::TopDock:
210 case QInternal::BottomDock:
211 o = Qt::Horizontal;
212 break;
213 default:
214 o = Qt::Horizontal;
215 break;
216 }
217}
218
219QSize QToolBarAreaLayoutInfo::sizeHint() const
220{
221 int a = 0, b = 0;
222 for (int i = 0; i < lines.count(); ++i) {
223 const QToolBarAreaLayoutLine &l = lines.at(i);
224 if (l.skip())
225 continue;
226
227 QSize hint = l.sizeHint();
228 a = qMax(a, b: pick(o, size: hint));
229 b += perp(o, size: hint);
230 }
231
232 QSize result;
233 rpick(o, size&: result) = a;
234 rperp(o, size&: result) = b;
235
236 return result;
237}
238
239QSize QToolBarAreaLayoutInfo::minimumSize() const
240{
241 int a = 0, b = 0;
242 for (int i = 0; i < lines.count(); ++i) {
243 const QToolBarAreaLayoutLine &l = lines.at(i);
244 if (l.skip())
245 continue;
246
247 QSize m = l.minimumSize();
248 a = qMax(a, b: pick(o, size: m));
249 b += perp(o, size: m);
250 }
251
252 QSize result;
253 rpick(o, size&: result) = a;
254 rperp(o, size&: result) = b;
255
256 return result;
257}
258
259void QToolBarAreaLayoutInfo::fitLayout()
260{
261 dirty = false;
262
263 int b = 0;
264
265 bool reverse = dockPos == QInternal::RightDock || dockPos == QInternal::BottomDock;
266
267 int i = reverse ? lines.count() - 1 : 0;
268 for (;;) {
269 if ((reverse && i < 0) || (!reverse && i == lines.count()))
270 break;
271
272 QToolBarAreaLayoutLine &l = lines[i];
273 if (!l.skip()) {
274 if (o == Qt::Horizontal) {
275 l.rect.setLeft(rect.left());
276 l.rect.setRight(rect.right());
277 l.rect.setTop(b + rect.top());
278 b += l.sizeHint().height();
279 l.rect.setBottom(b - 1 + rect.top());
280 } else {
281 l.rect.setTop(rect.top());
282 l.rect.setBottom(rect.bottom());
283 l.rect.setLeft(b + rect.left());
284 b += l.sizeHint().width();
285 l.rect.setRight(b - 1 + rect.left());
286 }
287
288 l.fitLayout();
289 }
290
291 i += reverse ? -1 : 1;
292 }
293}
294
295QLayoutItem *QToolBarAreaLayoutInfo::insertToolBar(QToolBar *before, QToolBar *toolBar)
296{
297 toolBar->setOrientation(o);
298 QLayoutItem *item = new QWidgetItemV2(toolBar);
299 insertItem(before, item);
300 return item;
301}
302
303void QToolBarAreaLayoutInfo::insertItem(QToolBar *before, QLayoutItem *item)
304{
305 if (before == nullptr) {
306 if (lines.isEmpty())
307 lines.append(t: QToolBarAreaLayoutLine(o));
308 lines.last().toolBarItems.append(t: item);
309 return;
310 }
311
312 for (int j = 0; j < lines.count(); ++j) {
313 QToolBarAreaLayoutLine &line = lines[j];
314
315 for (int k = 0; k < line.toolBarItems.count(); ++k) {
316 if (line.toolBarItems.at(i: k).widgetItem->widget() == before) {
317 line.toolBarItems.insert(i: k, t: item);
318 return;
319 }
320 }
321 }
322}
323
324void QToolBarAreaLayoutInfo::removeToolBar(QToolBar *toolBar)
325{
326 for (int j = 0; j < lines.count(); ++j) {
327 QToolBarAreaLayoutLine &line = lines[j];
328
329 for (int k = 0; k < line.toolBarItems.count(); ++k) {
330 QToolBarAreaLayoutItem &item = line.toolBarItems[k];
331 if (item.widgetItem->widget() == toolBar) {
332 delete item.widgetItem;
333 item.widgetItem = nullptr;
334 line.toolBarItems.removeAt(i: k);
335
336 if (line.toolBarItems.isEmpty() && j < lines.count() - 1)
337 lines.removeAt(i: j);
338
339 return;
340 }
341 }
342 }
343}
344
345void QToolBarAreaLayoutInfo::insertToolBarBreak(QToolBar *before)
346{
347 if (before == nullptr) {
348 if (!lines.isEmpty() && lines.constLast().toolBarItems.isEmpty())
349 return;
350 lines.append(t: QToolBarAreaLayoutLine(o));
351 return;
352 }
353
354 for (int j = 0; j < lines.count(); ++j) {
355 QToolBarAreaLayoutLine &line = lines[j];
356
357 for (int k = 0; k < line.toolBarItems.count(); ++k) {
358 if (line.toolBarItems.at(i: k).widgetItem->widget() == before) {
359 if (k == 0)
360 return;
361
362 QToolBarAreaLayoutLine newLine(o);
363 newLine.toolBarItems = line.toolBarItems.mid(pos: k);
364 line.toolBarItems = line.toolBarItems.mid(pos: 0, len: k);
365 lines.insert(i: j + 1, t: newLine);
366
367 return;
368 }
369 }
370 }
371}
372
373void QToolBarAreaLayoutInfo::removeToolBarBreak(QToolBar *before)
374{
375 for (int j = 0; j < lines.count(); ++j) {
376 const QToolBarAreaLayoutLine &line = lines.at(i: j);
377
378 for (int k = 0; k < line.toolBarItems.count(); ++k) {
379 if (line.toolBarItems.at(i: k).widgetItem->widget() == before) {
380 if (k != 0)
381 return;
382 if (j == 0)
383 return;
384
385 lines[j - 1].toolBarItems += lines[j].toolBarItems;
386 lines.removeAt(i: j);
387
388 return;
389 }
390 }
391 }
392}
393
394void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
395{
396 if (dirty)
397 fitLayout();
398
399 dirty = true;
400
401 if (o == Qt::Vertical)
402 pos -= rect.top();
403
404 //here we actually update the preferredSize for the line containing the toolbar so that we move it
405 for (int j = 0; j < lines.count(); ++j) {
406 QToolBarAreaLayoutLine &line = lines[j];
407
408 int previousIndex = -1;
409 int minPos = 0;
410 for (int k = 0; k < line.toolBarItems.count(); ++k) {
411 QToolBarAreaLayoutItem &current = line.toolBarItems[k];
412 if (current.widgetItem->widget() == toolbar) {
413 int newPos = current.pos;
414
415 if (previousIndex >= 0) {
416 QToolBarAreaLayoutItem &previous = line.toolBarItems[previousIndex];
417 if (pos < current.pos) {
418 newPos = qMax(a: pos, b: minPos);
419 } else {
420 //we check the max value for the position (until everything at the right is "compressed")
421 int maxPos = pick(o, size: rect.size());
422 for(int l = k; l < line.toolBarItems.count(); ++l) {
423 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: l);
424 if (!item.skip()) {
425 maxPos -= pick(o, size: item.minimumSize());
426 }
427 }
428 newPos = qMin(a: pos, b: maxPos);
429 }
430
431 //extra is the number of pixels to add to the previous toolbar
432 int extra = newPos - current.pos;
433
434 //we check if the previous is near its size hint
435 //in which case we try to stick to it
436 const int diff = pick(o, size: previous.sizeHint()) - (previous.size + extra);
437 if (qAbs(t: diff) < QApplication::startDragDistance()) {
438 //we stick to the default place and size
439 extra += diff;
440 }
441
442 //update for the current item
443 current.extendSize(o: line.o, extent: -extra);
444
445 if (extra >= 0) {
446 previous.extendSize(o: line.o, extent: extra);
447 } else {
448 //we need to push the toolbars on the left starting with previous
449 extra = -extra; // we just need to know the number of pixels
450 ///at this point we need to get extra pixels from the toolbars at the left
451 for(int l = previousIndex; l >=0; --l) {
452 QToolBarAreaLayoutItem &item = line.toolBarItems[l];
453 if (!item.skip()) {
454 const int minPreferredSize = pick(o, size: item.minimumSize());
455 const int margin = item.size - minPreferredSize;
456 if (margin < extra) {
457 item.resize(o: line.o, newSize: minPreferredSize);
458 extra -= margin;
459 } else {
460 item.extendSize(o: line.o, extent: -extra);
461 extra = 0;
462 }
463 }
464 }
465 Q_ASSERT(extra == 0);
466 }
467 } else {
468 //the item is the first one, it should be at position 0
469 }
470
471 return;
472
473 } else if (!current.skip()) {
474 previousIndex = k;
475 minPos += pick(o, size: current.minimumSize());
476 }
477 }
478 }
479}
480
481
482QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance) const
483{
484 if (rect.contains(p: pos)) {
485 // <pos> is in QToolBarAreaLayout coordinates.
486 // <item.pos> is in local dockarea coordinates (see ~20 lines below)
487 // Since we're comparing p with item.pos, we put them in the same coordinate system.
488 const int p = pick(o, pos: pos - rect.topLeft());
489
490 for (int j = 0; j < lines.count(); ++j) {
491 const QToolBarAreaLayoutLine &line = lines.at(i: j);
492 if (line.skip())
493 continue;
494 if (!line.rect.contains(p: pos))
495 continue;
496
497 int k = 0;
498 for (; k < line.toolBarItems.count(); ++k) {
499 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: k);
500 if (item.skip())
501 continue;
502
503 int size = qMin(a: item.size, b: pick(o, size: item.sizeHint()));
504
505 if (p > item.pos + size)
506 continue;
507 if (p > item.pos + size/2)
508 ++k;
509 break;
510 }
511
512 QList<int> result;
513 result << j << k;
514 *minDistance = 0; //we found a perfect match
515 return result;
516 }
517 } else {
518 const int dist = distance(pos);
519 //it will only return a path if the minDistance is higher than the current distance
520 if (dist >= 0 && *minDistance > dist) {
521 *minDistance = dist;
522
523 QList<int> result;
524 result << lines.count() << 0;
525 return result;
526 }
527 }
528
529 return QList<int>();
530}
531
532bool QToolBarAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *item)
533{
534 Q_ASSERT(path.count() == 2);
535 int j = path.first();
536 if (j == lines.count())
537 lines.append(t: QToolBarAreaLayoutLine(o));
538
539 QToolBarAreaLayoutLine &line = lines[j];
540 const int k = path.at(i: 1);
541
542 QToolBarAreaLayoutItem gap_item;
543 gap_item.gap = true;
544 gap_item.widgetItem = item;
545
546 //update the previous item's preferred size
547 for(int p = k - 1 ; p >= 0; --p) {
548 QToolBarAreaLayoutItem &previous = line.toolBarItems[p];
549 if (!previous.skip()) {
550 //we found the previous one
551 int previousSizeHint = pick(o: line.o, size: previous.sizeHint());
552 int previousExtraSpace = previous.size - previousSizeHint;
553
554 if (previousExtraSpace > 0) {
555 //in this case we reset the space
556 previous.preferredSize = -1;
557 previous.size = previousSizeHint;
558
559 gap_item.resize(o, newSize: previousExtraSpace);
560 }
561
562 break;
563 }
564 }
565
566 line.toolBarItems.insert(i: k, t: gap_item);
567 return true;
568
569}
570
571void QToolBarAreaLayoutInfo::clear()
572{
573 lines.clear();
574 rect = QRect();
575}
576
577QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const
578{
579 Q_ASSERT(path.count() == 2);
580 int j = path.at(i: 0);
581 int k = path.at(i: 1);
582
583 const QToolBarAreaLayoutLine &line = lines.at(i: j);
584 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: k);
585
586 QRect result = line.rect;
587
588 if (o == Qt::Horizontal) {
589 result.setLeft(item.pos + line.rect.left());
590 result.setWidth(item.size);
591 } else {
592 result.setTop(item.pos + line.rect.top());
593 result.setHeight(item.size);
594 }
595
596 return result;
597}
598
599int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const
600{
601 switch (dockPos) {
602 case QInternal::LeftDock:
603 if (pos.y() < rect.bottom())
604 return pos.x() - rect.right();
605 break;
606 case QInternal::RightDock:
607 if (pos.y() < rect.bottom())
608 return rect.left() - pos.x();
609 break;
610 case QInternal::TopDock:
611 if (pos.x() < rect.right())
612 return pos.y() - rect.bottom();
613 break;
614 case QInternal::BottomDock:
615 if (pos.x() < rect.right())
616 return rect.top() - pos.y();
617 break;
618
619 case QInternal::DockCount:
620 break;
621 }
622 return -1;
623}
624
625/******************************************************************************
626** QToolBarAreaLayout
627*/
628
629QToolBarAreaLayout::QToolBarAreaLayout(const QMainWindow *win) : mainWindow(win), visible(true)
630{
631 for (int i = 0; i < QInternal::DockCount; ++i) {
632 QInternal::DockPosition pos = static_cast<QInternal::DockPosition>(i);
633 docks[i] = QToolBarAreaLayoutInfo(pos);
634 }
635}
636
637QRect QToolBarAreaLayout::fitLayout()
638{
639 if (!visible)
640 return rect;
641
642 QSize left_hint = docks[QInternal::LeftDock].sizeHint();
643 QSize right_hint = docks[QInternal::RightDock].sizeHint();
644 QSize top_hint = docks[QInternal::TopDock].sizeHint();
645 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
646
647 QRect center = rect.adjusted(xp1: left_hint.width(), yp1: top_hint.height(),
648 xp2: -right_hint.width(), yp2: -bottom_hint.height());
649
650 docks[QInternal::TopDock].rect = QRect(rect.left(), rect.top(),
651 rect.width(), top_hint.height());
652 docks[QInternal::LeftDock].rect = QRect(rect.left(), center.top(),
653 left_hint.width(), center.height());
654 docks[QInternal::RightDock].rect = QRect(center.right() + 1, center.top(),
655 right_hint.width(), center.height());
656 docks[QInternal::BottomDock].rect = QRect(rect.left(), center.bottom() + 1,
657 rect.width(), bottom_hint.height());
658
659 docks[QInternal::TopDock].fitLayout();
660 docks[QInternal::LeftDock].fitLayout();
661 docks[QInternal::RightDock].fitLayout();
662 docks[QInternal::BottomDock].fitLayout();
663
664 return center;
665}
666
667QSize QToolBarAreaLayout::minimumSize(const QSize &centerMin) const
668{
669 if (!visible)
670 return centerMin;
671
672 QSize result = centerMin;
673
674 QSize left_min = docks[QInternal::LeftDock].minimumSize();
675 QSize right_min = docks[QInternal::RightDock].minimumSize();
676 QSize top_min = docks[QInternal::TopDock].minimumSize();
677 QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
678
679 result.setWidth(qMax(a: top_min.width(), b: result.width()));
680 result.setWidth(qMax(a: bottom_min.width(), b: result.width()));
681 result.setHeight(qMax(a: left_min.height(), b: result.height()));
682 result.setHeight(qMax(a: right_min.height(), b: result.height()));
683
684 result.rwidth() += left_min.width() + right_min.width();
685 result.rheight() += top_min.height() + bottom_min.height();
686
687 return result;
688}
689
690QSize QToolBarAreaLayout::sizeHint(const QSize &centerHint) const
691{
692 if (!visible)
693 return centerHint;
694
695 QSize result = centerHint;
696
697 QSize left_hint = docks[QInternal::LeftDock].sizeHint();
698 QSize right_hint = docks[QInternal::RightDock].sizeHint();
699 QSize top_hint = docks[QInternal::TopDock].sizeHint();
700 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
701
702 result.setWidth(qMax(a: top_hint.width(), b: result.width()));
703 result.setWidth(qMax(a: bottom_hint.width(), b: result.width()));
704 result.setHeight(qMax(a: left_hint.height(), b: result.height()));
705 result.setHeight(qMax(a: right_hint.height(), b: result.height()));
706
707 result.rwidth() += left_hint.width() + right_hint.width();
708 result.rheight() += top_hint.height() + bottom_hint.height();
709
710 return result;
711}
712
713QRect QToolBarAreaLayout::rectHint(const QRect &r) const
714{
715 int coef = visible ? 1 : -1;
716
717 QRect result = r;
718
719 QSize left_hint = docks[QInternal::LeftDock].sizeHint();
720 QSize right_hint = docks[QInternal::RightDock].sizeHint();
721 QSize top_hint = docks[QInternal::TopDock].sizeHint();
722 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
723
724 result.adjust(dx1: -left_hint.width()*coef, dy1: -top_hint.height()*coef,
725 dx2: right_hint.width()*coef, dy2: bottom_hint.height()*coef);
726
727 return result;
728}
729
730QLayoutItem *QToolBarAreaLayout::itemAt(int *x, int index) const
731{
732 Q_ASSERT(x != nullptr);
733
734 for (int i = 0; i < QInternal::DockCount; ++i) {
735 const QToolBarAreaLayoutInfo &dock = docks[i];
736
737 for (int j = 0; j < dock.lines.count(); ++j) {
738 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
739
740 for (int k = 0; k < line.toolBarItems.count(); ++k) {
741 if ((*x)++ == index)
742 return line.toolBarItems.at(i: k).widgetItem;
743 }
744 }
745 }
746
747 return nullptr;
748}
749
750QLayoutItem *QToolBarAreaLayout::takeAt(int *x, int index)
751{
752 Q_ASSERT(x != nullptr);
753
754 for (int i = 0; i < QInternal::DockCount; ++i) {
755 QToolBarAreaLayoutInfo &dock = docks[i];
756
757 for (int j = 0; j < dock.lines.count(); ++j) {
758 QToolBarAreaLayoutLine &line = dock.lines[j];
759
760 for (int k = 0; k < line.toolBarItems.count(); ++k) {
761 if ((*x)++ == index) {
762 QLayoutItem *result = line.toolBarItems.takeAt(i: k).widgetItem;
763 if (line.toolBarItems.isEmpty())
764 dock.lines.removeAt(i: j);
765 return result;
766 }
767 }
768 }
769 }
770
771 return nullptr;
772}
773
774void QToolBarAreaLayout::deleteAllLayoutItems()
775{
776 for (int i = 0; i < QInternal::DockCount; ++i) {
777 QToolBarAreaLayoutInfo &dock = docks[i];
778
779 for (int j = 0; j < dock.lines.count(); ++j) {
780 QToolBarAreaLayoutLine &line = dock.lines[j];
781
782 for (int k = 0; k < line.toolBarItems.count(); ++k) {
783 QToolBarAreaLayoutItem &item = line.toolBarItems[k];
784 if (!item.gap)
785 delete item.widgetItem;
786 item.widgetItem = nullptr;
787 }
788 }
789 }
790}
791
792QInternal::DockPosition QToolBarAreaLayout::findToolBar(const QToolBar *toolBar) const
793{
794 for (int i = 0; i < QInternal::DockCount; ++i) {
795 const QToolBarAreaLayoutInfo &dock = docks[i];
796
797 for (int j = 0; j < dock.lines.count(); ++j) {
798 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
799
800 for (int k = 0; k < line.toolBarItems.count(); ++k) {
801 if (line.toolBarItems.at(i: k).widgetItem->widget() == toolBar)
802 return static_cast<QInternal::DockPosition>(i);
803 }
804 }
805 }
806
807 return QInternal::DockCount;
808}
809
810QLayoutItem *QToolBarAreaLayout::insertToolBar(QToolBar *before, QToolBar *toolBar)
811{
812 QInternal::DockPosition pos = findToolBar(toolBar: before);
813 if (pos == QInternal::DockCount)
814 return nullptr;
815
816 return docks[pos].insertToolBar(before, toolBar);
817}
818
819void QToolBarAreaLayout::removeToolBar(QToolBar *toolBar)
820{
821 QInternal::DockPosition pos = findToolBar(toolBar);
822 if (pos == QInternal::DockCount)
823 return;
824 docks[pos].removeToolBar(toolBar);
825}
826
827QLayoutItem *QToolBarAreaLayout::addToolBar(QInternal::DockPosition pos, QToolBar *toolBar)
828{
829 return docks[pos].insertToolBar(before: nullptr, toolBar);
830}
831
832void QToolBarAreaLayout::insertToolBarBreak(QToolBar *before)
833{
834 QInternal::DockPosition pos = findToolBar(toolBar: before);
835 if (pos == QInternal::DockCount)
836 return;
837 docks[pos].insertToolBarBreak(before);
838}
839
840void QToolBarAreaLayout::removeToolBarBreak(QToolBar *before)
841{
842 QInternal::DockPosition pos = findToolBar(toolBar: before);
843 if (pos == QInternal::DockCount)
844 return;
845 docks[pos].removeToolBarBreak(before);
846}
847
848void QToolBarAreaLayout::addToolBarBreak(QInternal::DockPosition pos)
849{
850 docks[pos].insertToolBarBreak(before: nullptr);
851}
852
853void QToolBarAreaLayout::moveToolBar(QToolBar *toolbar, int p)
854{
855 QInternal::DockPosition pos = findToolBar(toolBar: toolbar);
856 if (pos == QInternal::DockCount)
857 return;
858 docks[pos].moveToolBar(toolbar, pos: p);
859}
860
861
862void QToolBarAreaLayout::insertItem(QInternal::DockPosition pos, QLayoutItem *item)
863{
864 if (docks[pos].lines.isEmpty())
865 docks[pos].lines.append(t: QToolBarAreaLayoutLine(docks[pos].o));
866 docks[pos].lines.last().toolBarItems.append(t: item);
867}
868
869void QToolBarAreaLayout::insertItem(QToolBar *before, QLayoutItem *item)
870{
871 QInternal::DockPosition pos = findToolBar(toolBar: before);
872 if (pos == QInternal::DockCount)
873 return;
874
875 docks[pos].insertItem(before, item);
876}
877
878void QToolBarAreaLayout::apply(bool animate)
879{
880 QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
881 Q_ASSERT(layout != nullptr);
882
883 Qt::LayoutDirection dir = mainWindow->layoutDirection();
884
885 for (int i = 0; i < QInternal::DockCount; ++i) {
886 const QToolBarAreaLayoutInfo &dock = docks[i];
887
888 for (int j = 0; j < dock.lines.count(); ++j) {
889 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
890 if (line.skip())
891 continue;
892
893 for (int k = 0; k < line.toolBarItems.count(); ++k) {
894 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: k);
895 if (item.skip() || item.gap)
896 continue;
897
898 QRect geo;
899 if (visible) {
900 if (line.o == Qt::Horizontal) {
901 geo.setTop(line.rect.top());
902 geo.setBottom(line.rect.bottom());
903 geo.setLeft(line.rect.left() + item.pos);
904 geo.setRight(line.rect.left() + item.pos + item.size - 1);
905 } else {
906 geo.setLeft(line.rect.left());
907 geo.setRight(line.rect.right());
908 geo.setTop(line.rect.top() + item.pos);
909 geo.setBottom(line.rect.top() + item.pos + item.size - 1);
910 }
911 }
912
913 QWidget *widget = item.widgetItem->widget();
914 if (QToolBar *toolBar = qobject_cast<QToolBar*>(object: widget)) {
915 QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(object: toolBar->layout());
916 if (tbl->expanded) {
917 QPoint tr = geo.topRight();
918 QSize size = tbl->expandedSize(size: geo.size());
919 geo.setSize(size);
920 geo.moveTopRight(p: tr);
921 if (geo.bottom() > rect.bottom())
922 geo.moveBottom(pos: rect.bottom());
923 if (geo.right() > rect.right())
924 geo.moveRight(pos: rect.right());
925 if (geo.left() < 0)
926 geo.moveLeft(pos: 0);
927 if (geo.top() < 0)
928 geo.moveTop(pos: 0);
929 }
930 }
931
932 if (visible && dock.o == Qt::Horizontal)
933 geo = QStyle::visualRect(direction: dir, boundingRect: line.rect, logicalRect: geo);
934
935 layout->widgetAnimator.animate(widget, final_geometry: geo, animate);
936 }
937 }
938 }
939}
940
941bool QToolBarAreaLayout::toolBarBreak(QToolBar *toolBar) const
942{
943 for (int i = 0; i < QInternal::DockCount; ++i) {
944 const QToolBarAreaLayoutInfo &dock = docks[i];
945
946 for (int j = 0; j < dock.lines.count(); ++j) {
947 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
948
949 for (int k = 0; k < line.toolBarItems.count(); ++k) {
950 if (line.toolBarItems.at(i: k).widgetItem->widget() == toolBar)
951 return j > 0 && k == 0;
952 }
953 }
954 }
955
956 return false;
957}
958
959void QToolBarAreaLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const
960{
961 for (int i = 0; i < QInternal::DockCount; ++i) {
962 const QToolBarAreaLayoutInfo &dock = docks[i];
963
964 for (int j = 0; j < dock.lines.count(); ++j) {
965 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
966
967 for (int k = 0; k < line.toolBarItems.count(); ++k) {
968 if (line.toolBarItems.at(i: k).widgetItem->widget() == toolBar) {
969 if (line.toolBarItems.count() == 1)
970 option->positionWithinLine = QStyleOptionToolBar::OnlyOne;
971 else if (k == 0)
972 option->positionWithinLine = QStyleOptionToolBar::Beginning;
973 else if (k == line.toolBarItems.count() - 1)
974 option->positionWithinLine = QStyleOptionToolBar::End;
975 else
976 option->positionWithinLine = QStyleOptionToolBar::Middle;
977
978 if (dock.lines.count() == 1)
979 option->positionOfLine = QStyleOptionToolBar::OnlyOne;
980 else if (j == 0)
981 option->positionOfLine = QStyleOptionToolBar::Beginning;
982 else if (j == dock.lines.count() - 1)
983 option->positionOfLine = QStyleOptionToolBar::End;
984 else
985 option->positionOfLine = QStyleOptionToolBar::Middle;
986
987 return;
988 }
989 }
990 }
991 }
992}
993
994QList<int> QToolBarAreaLayout::indexOf(QWidget *toolBar) const
995{
996 QList<int> result;
997
998 bool found = false;
999
1000 for (int i = 0; i < QInternal::DockCount; ++i) {
1001 const QToolBarAreaLayoutInfo &dock = docks[i];
1002
1003 for (int j = 0; j < dock.lines.count(); ++j) {
1004 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
1005
1006 for (int k = 0; k < line.toolBarItems.count(); ++k) {
1007 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: k);
1008 if (!item.gap && item.widgetItem->widget() == toolBar) {
1009 found = true;
1010 result.prepend(t: k);
1011 break;
1012 }
1013 }
1014
1015 if (found) {
1016 result.prepend(t: j);
1017 break;
1018 }
1019 }
1020
1021 if (found) {
1022 result.prepend(t: i);
1023 break;
1024 }
1025 }
1026
1027 return result;
1028}
1029
1030//this functions returns the path to the possible gapindex for the position pos
1031QList<int> QToolBarAreaLayout::gapIndex(const QPoint &pos) const
1032{
1033 Qt::LayoutDirection dir = mainWindow->layoutDirection();
1034 int minDistance = 80; // when a dock area is empty, how "wide" is it?
1035 QList<int> ret; //return value
1036 for (int i = 0; i < QInternal::DockCount; ++i) {
1037 QPoint p = pos;
1038 if (docks[i].o == Qt::Horizontal)
1039 p = QStyle::visualPos(direction: dir, boundingRect: docks[i].rect, logicalPos: p);
1040 QList<int> result = docks[i].gapIndex(pos: p, minDistance: &minDistance);
1041 if (!result.isEmpty()) {
1042 result.prepend(t: i);
1043 ret = result;
1044 }
1045 }
1046
1047 return ret;
1048}
1049
1050QList<int> QToolBarAreaLayout::currentGapIndex() const
1051{
1052 for (int i = 0; i < QInternal::DockCount; ++i) {
1053 const QToolBarAreaLayoutInfo &dock = docks[i];
1054
1055 for (int j = 0; j < dock.lines.count(); ++j) {
1056 const QToolBarAreaLayoutLine &line = dock.lines[j];
1057
1058 for (int k = 0; k < line.toolBarItems.count(); k++) {
1059 if (line.toolBarItems[k].gap) {
1060 QList<int> result;
1061 result << i << j << k;
1062 return result;
1063 }
1064 }
1065 }
1066 }
1067 return QList<int>();
1068}
1069
1070bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item)
1071{
1072 Q_ASSERT(path.count() == 3);
1073 const int i = path.first();
1074 Q_ASSERT(i >= 0 && i < QInternal::DockCount);
1075 return docks[i].insertGap(path: path.mid(pos: 1), item);
1076}
1077
1078void QToolBarAreaLayout::remove(const QList<int> &path)
1079{
1080 Q_ASSERT(path.count() == 3);
1081 QToolBarAreaLayoutInfo &dock = docks[path.at(i: 0)];
1082 QToolBarAreaLayoutLine &line = dock.lines[path.at(i: 1)];
1083 line.toolBarItems.removeAt(i: path.at(i: 2));
1084 if (line.toolBarItems.isEmpty())
1085 dock.lines.removeAt(i: path.at(i: 1));
1086}
1087
1088void QToolBarAreaLayout::remove(QLayoutItem *item)
1089{
1090 for (int i = 0; i < QInternal::DockCount; ++i) {
1091 QToolBarAreaLayoutInfo &dock = docks[i];
1092
1093 for (int j = 0; j < dock.lines.count(); ++j) {
1094 QToolBarAreaLayoutLine &line = dock.lines[j];
1095
1096 for (int k = 0; k < line.toolBarItems.count(); k++) {
1097 if (line.toolBarItems[k].widgetItem == item) {
1098 line.toolBarItems.removeAt(i: k);
1099 if (line.toolBarItems.isEmpty())
1100 dock.lines.removeAt(i: j);
1101 return;
1102 }
1103 }
1104 }
1105 }
1106}
1107
1108void QToolBarAreaLayout::clear()
1109{
1110 for (int i = 0; i < QInternal::DockCount; ++i)
1111 docks[i].clear();
1112 rect = QRect();
1113}
1114
1115QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList<int> &path)
1116{
1117 Q_ASSERT(path.count() == 3);
1118
1119 if (path.at(i: 0) < 0 || path.at(i: 0) >= QInternal::DockCount)
1120 return nullptr;
1121 QToolBarAreaLayoutInfo &info = docks[path.at(i: 0)];
1122 if (path.at(i: 1) < 0 || path.at(i: 1) >= info.lines.count())
1123 return nullptr;
1124 QToolBarAreaLayoutLine &line = info.lines[path.at(i: 1)];
1125 if (path.at(i: 2) < 0 || path.at(i: 2) >= line.toolBarItems.count())
1126 return nullptr;
1127 return &(line.toolBarItems[path.at(i: 2)]);
1128}
1129
1130QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
1131{
1132 const int i = path.first();
1133
1134 QRect r = docks[i].itemRect(path: path.mid(pos: 1));
1135 if (docks[i].o == Qt::Horizontal)
1136 r = QStyle::visualRect(direction: mainWindow->layoutDirection(),
1137 boundingRect: docks[i].rect, logicalRect: r);
1138 return r;
1139}
1140
1141QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
1142{
1143 QToolBarAreaLayoutItem *item = this->item(path);
1144 if (Q_UNLIKELY(!item)) {
1145 qWarning() << "No item at" << path;
1146 return nullptr;
1147 }
1148 Q_ASSERT(item->gap);
1149 Q_ASSERT(item->widgetItem != nullptr);
1150 item->gap = false;
1151 return item->widgetItem;
1152}
1153
1154QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other)
1155{
1156 //other needs to be update as well
1157 Q_ASSERT(path.count() == 3);
1158 QToolBarAreaLayoutItem *item = this->item(path);
1159 Q_ASSERT(item);
1160
1161 //update the leading space here
1162 QToolBarAreaLayoutInfo &info = docks[path.at(i: 0)];
1163 QToolBarAreaLayoutLine &line = info.lines[path.at(i: 1)];
1164 if (item->size != pick(o: line.o, size: item->realSizeHint())) {
1165 //the item doesn't have its default size
1166 //so we'll give this to the next item
1167 int newExtraSpace = 0;
1168 //let's iterate over the siblings of the current item that pare placed before it
1169 //we need to find just the one before
1170 for (int i = path.at(i: 2) - 1; i >= 0; --i) {
1171 QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
1172 if (!previous.skip()) {
1173 //we need to check if it has a previous element and a next one
1174 //the previous will get its size changed
1175 for (int j = path.at(i: 2) + 1; j < line.toolBarItems.count(); ++j) {
1176 const QToolBarAreaLayoutItem &next = line.toolBarItems.at(i: j);
1177 if (!next.skip()) {
1178 newExtraSpace = next.pos - previous.pos - pick(o: line.o, size: previous.sizeHint());
1179 previous.resize(o: line.o, newSize: next.pos - previous.pos);
1180 break;
1181 }
1182 }
1183 break;
1184 }
1185 }
1186
1187 if (other) {
1188 QToolBarAreaLayoutInfo &info = other->docks[path.at(i: 0)];
1189 QToolBarAreaLayoutLine &line = info.lines[path.at(i: 1)];
1190 for (int i = path.at(i: 2) - 1; i >= 0; --i) {
1191 QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
1192 if (!previous.skip()) {
1193 previous.resize(o: line.o, newSize: pick(o: line.o, size: previous.sizeHint()) + newExtraSpace);
1194 break;
1195 }
1196 }
1197
1198 }
1199 }
1200
1201 Q_ASSERT(!item->gap);
1202 item->gap = true;
1203 return item->widgetItem;
1204}
1205
1206static QRect unpackRect(uint geom0, uint geom1, bool *floating)
1207{
1208 *floating = geom0 & 1;
1209 if (!*floating)
1210 return QRect();
1211
1212 geom0 >>= 1;
1213
1214 int x = (int)(geom0 & 0x0000ffff) - 0x7FFF;
1215 int y = (int)(geom1 & 0x0000ffff) - 0x7FFF;
1216
1217 geom0 >>= 16;
1218 geom1 >>= 16;
1219
1220 int w = geom0 & 0x0000ffff;
1221 int h = geom1 & 0x0000ffff;
1222
1223 return QRect(x, y, w, h);
1224}
1225
1226static void packRect(uint *geom0, uint *geom1, const QRect &rect, bool floating)
1227{
1228 *geom0 = 0;
1229 *geom1 = 0;
1230
1231 if (!floating)
1232 return;
1233
1234 // The 0x7FFF is half of 0xFFFF. We add it so we can handle negative coordinates on
1235 // dual monitors. It's subtracted when unpacking.
1236
1237 *geom0 |= qMax(a: 0, b: rect.width()) & 0x0000ffff;
1238 *geom1 |= qMax(a: 0, b: rect.height()) & 0x0000ffff;
1239
1240 *geom0 <<= 16;
1241 *geom1 <<= 16;
1242
1243 *geom0 |= qMax(a: 0, b: rect.x() + 0x7FFF) & 0x0000ffff;
1244 *geom1 |= qMax(a: 0, b: rect.y() + 0x7FFF) & 0x0000ffff;
1245
1246 // yeah, we chop one bit off the width, but it still has a range up to 32512
1247
1248 *geom0 <<= 1;
1249 *geom0 |= 1;
1250}
1251
1252
1253void QToolBarAreaLayout::saveState(QDataStream &stream) const
1254{
1255 // save toolbar state
1256 stream << (uchar) ToolBarStateMarkerEx;
1257
1258 int lineCount = 0;
1259 for (int i = 0; i < QInternal::DockCount; ++i)
1260 lineCount += docks[i].lines.count();
1261
1262 stream << lineCount;
1263
1264 for (int i = 0; i < QInternal::DockCount; ++i) {
1265 const QToolBarAreaLayoutInfo &dock = docks[i];
1266
1267 for (int j = 0; j < dock.lines.count(); ++j) {
1268 const QToolBarAreaLayoutLine &line = dock.lines.at(i: j);
1269
1270 stream << i << line.toolBarItems.count();
1271
1272 for (int k = 0; k < line.toolBarItems.count(); ++k) {
1273 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(i: k);
1274 QWidget *widget = const_cast<QLayoutItem*>(item.widgetItem)->widget();
1275 QString objectName = widget->objectName();
1276 if (Q_UNLIKELY(objectName.isEmpty())) {
1277 qWarning(msg: "QMainWindow::saveState(): 'objectName' not set for QToolBar %p '%s'",
1278 widget, widget->windowTitle().toLocal8Bit().constData());
1279 }
1280 stream << objectName;
1281 // we store information as:
1282 // 1st bit: 1 if shown
1283 // 2nd bit: 1 if orientation is vertical (default is horizontal)
1284 uchar shownOrientation = (uchar)!widget->isHidden();
1285 if (QToolBar * tb= qobject_cast<QToolBar*>(object: widget)) {
1286 if (tb->orientation() == Qt::Vertical)
1287 shownOrientation |= 2;
1288 }
1289 stream << shownOrientation;
1290 stream << item.pos;
1291 //we store the preferred size. If the use rdidn't resize the toolbars it will be -1
1292 stream << item.preferredSize;
1293
1294 uint geom0, geom1;
1295 packRect(geom0: &geom0, geom1: &geom1, rect: widget->geometry(), floating: widget->isWindow());
1296 stream << geom0 << geom1;
1297 }
1298 }
1299 }
1300}
1301
1302static inline int getInt(QDataStream &stream)
1303{
1304 int x;
1305 stream >> x;
1306 return x;
1307}
1308
1309
1310bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*> &_toolBars, uchar tmarker, bool testing)
1311{
1312 QList<QToolBar*> toolBars = _toolBars;
1313 int lines;
1314 stream >> lines;
1315
1316 for (int j = 0; j < lines; ++j) {
1317 int pos;
1318 stream >> pos;
1319 if (pos < 0 || pos >= QInternal::DockCount)
1320 return false;
1321 int cnt;
1322 stream >> cnt;
1323
1324 QToolBarAreaLayoutInfo &dock = docks[pos];
1325 const bool applyingLayout = !testing;
1326 QToolBarAreaLayoutLine line(dock.o);
1327
1328 for (int k = 0; k < cnt; ++k) {
1329 QToolBarAreaLayoutItem item;
1330
1331 QString objectName;
1332 stream >> objectName;
1333 uchar shown;
1334 stream >> shown;
1335 item.pos = getInt(stream);
1336 item.size = getInt(stream);
1337
1338 /*
1339 4.3.0 added floating toolbars, but failed to add the ability to restore them.
1340 We need to store there geometry (four ints). We cannot change the format in a
1341 patch release (4.3.1) by adding ToolBarStateMarkerEx2 to signal extra data. So
1342 for now we'll pack it in the two legacy ints we no longer used in Qt4.3.0.
1343 In 4.4, we should add ToolBarStateMarkerEx2 and fix this properly.
1344 */
1345
1346 QRect rect;
1347 bool floating = false;
1348 uint geom0, geom1;
1349 geom0 = getInt(stream);
1350 if (tmarker == ToolBarStateMarkerEx) {
1351 geom1 = getInt(stream);
1352 rect = unpackRect(geom0, geom1, floating: &floating);
1353 }
1354
1355 QToolBar *toolBar = nullptr;
1356 for (int x = 0; x < toolBars.count(); ++x) {
1357 if (toolBars.at(i: x)->objectName() == objectName) {
1358 toolBar = toolBars.takeAt(i: x);
1359 break;
1360 }
1361 }
1362 if (toolBar == nullptr) {
1363 continue;
1364 }
1365
1366 if (applyingLayout) {
1367 item.widgetItem = new QWidgetItemV2(toolBar);
1368 toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
1369 toolBar->setVisible(shown & 1);
1370 toolBar->d_func()->setWindowState(floating, unplug: true, rect);
1371
1372 item.preferredSize = item.size;
1373 line.toolBarItems.append(t: item);
1374 }
1375 }
1376
1377 if (applyingLayout) {
1378 dock.lines.append(t: line);
1379 }
1380 }
1381
1382
1383 return stream.status() == QDataStream::Ok;
1384}
1385
1386bool QToolBarAreaLayout::isEmpty() const
1387{
1388 for (int i = 0; i < QInternal::DockCount; ++i) {
1389 if (!docks[i].lines.isEmpty())
1390 return false;
1391 }
1392 return true;
1393}
1394
1395QT_END_NAMESPACE
1396

source code of qtbase/src/widgets/widgets/qtoolbararealayout.cpp