Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtoolbararealayout.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QWidgetItem>
5#include <QToolBar>
6#include <QStyleOption>
7#include <QApplication>
8#include <qdebug.h>
9
11#include "qmainwindowlayout_p.h"
12#include "qwidgetanimator_p.h"
13#include "qtoolbarlayout_p.h"
14#include "qtoolbar_p.h"
15
16/******************************************************************************
17** QToolBarAreaLayoutItem
18*/
19
21
22// qmainwindow.cpp
23extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow);
24
26{
27 if (skip())
28 return QSize(0, 0);
29 return qSmartMinSize(static_cast<QWidgetItem*>(widgetItem));
30}
31
33{
34 if (skip())
35 return QSize(0, 0);
36
37 return realSizeHint();
38}
39
40//returns the real size hint not taking into account the visibility of the widget
42{
43 QWidget *wid = widgetItem->widget();
44 QSize s = wid->sizeHint().expandedTo(wid->minimumSizeHint());
46 s.setWidth(0);
48 s.setHeight(0);
49 s = s.boundedTo(wid->maximumSize())
50 .expandedTo(wid->minimumSize());
51 return s;
52}
53
55{
56 if (gap)
57 return false;
58 return widgetItem == nullptr || widgetItem->isEmpty();
59}
60
61/******************************************************************************
62** QToolBarAreaLayoutLine
63*/
64
69
71{
72 int a = 0, b = 0;
73 for (int i = 0; i < toolBarItems.size(); ++i) {
75 if (item.skip())
76 continue;
77
78 QSize sh = item.sizeHint();
79 a += item.preferredSize > 0 ? item.preferredSize : pick(o, sh);
80 b = qMax(b, perp(o, sh));
81 }
82
84 rpick(o, result) = a;
85 rperp(o, result) = b;
86
87 return result;
88}
89
91{
92 int a = 0, b = 0;
93 for (int i = 0; i < toolBarItems.size(); ++i) {
95 if (item.skip())
96 continue;
97
98 QSize ms = item.minimumSize();
99 a += pick(o, ms);
100 b = qMax(b, perp(o, ms));
101 }
102
104 rpick(o, result) = a;
105 rperp(o, result) = b;
106
107 return result;
108}
109
111{
112 int last = -1;
113 int min = pick(o, minimumSize());
114 int space = pick(o, rect.size());
115 int extra = qMax(0, space - min);
116
117 for (int i = 0; i < toolBarItems.size(); ++i) {
119 if (item.skip())
120 continue;
121
122 if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout()))
123 tblayout->checkUsePopupMenu();
124
125 const int itemMin = pick(o, item.minimumSize());
126 //preferredSize is the default if it is set, otherwise, we take the sizehint
127 item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint());
128
129 //the extraspace is the space above the item minimum sizehint
130 const int extraSpace = qMin(item.size - itemMin, extra);
131 item.size = itemMin + extraSpace; //that is the real size
132
133 extra -= extraSpace;
134
135 last = i;
136 }
137
138 // calculate the positions from the sizes
139 int pos = 0;
140 for (int i = 0; i < toolBarItems.size(); ++i) {
142 if (item.skip())
143 continue;
144
145 item.pos = pos;
146 if (i == last) // stretch the last item to the end of the line
147 item.size = qMax(0, pick(o, rect.size()) - item.pos);
148 pos += item.size;
149 }
150}
151
153{
154 for (int i = 0; i < toolBarItems.size(); ++i) {
155 if (!toolBarItems.at(i).skip())
156 return false;
157 }
158 return true;
159}
160
161/******************************************************************************
162** QToolBarAreaLayoutInfo
163*/
164
166 : dockPos(pos), dirty(false)
167{
168 switch (pos) {
171 o = Qt::Vertical;
172 break;
176 break;
177 default:
179 break;
180 }
181}
182
184{
185 int a = 0, b = 0;
186 for (int i = 0; i < lines.size(); ++i) {
187 const QToolBarAreaLayoutLine &l = lines.at(i);
188 if (l.skip())
189 continue;
190
191 QSize hint = l.sizeHint();
192 a = qMax(a, pick(o, hint));
193 b += perp(o, hint);
194 }
195
197 rpick(o, result) = a;
198 rperp(o, result) = b;
199
200 return result;
201}
202
204{
205 int a = 0, b = 0;
206 for (int i = 0; i < lines.size(); ++i) {
207 const QToolBarAreaLayoutLine &l = lines.at(i);
208 if (l.skip())
209 continue;
210
211 QSize m = l.minimumSize();
212 a = qMax(a, pick(o, m));
213 b += perp(o, m);
214 }
215
217 rpick(o, result) = a;
218 rperp(o, result) = b;
219
220 return result;
221}
222
224{
225 dirty = false;
226
227 int b = 0;
228
230
231 int i = reverse ? lines.size() - 1 : 0;
232 for (;;) {
233 if ((reverse && i < 0) || (!reverse && i == lines.size()))
234 break;
235
237 if (!l.skip()) {
238 if (o == Qt::Horizontal) {
239 l.rect.setLeft(rect.left());
240 l.rect.setRight(rect.right());
241 l.rect.setTop(b + rect.top());
242 b += l.sizeHint().height();
243 l.rect.setBottom(b - 1 + rect.top());
244 } else {
245 l.rect.setTop(rect.top());
247 l.rect.setLeft(b + rect.left());
248 b += l.sizeHint().width();
249 l.rect.setRight(b - 1 + rect.left());
250 }
251
252 l.fitLayout();
253 }
254
255 i += reverse ? -1 : 1;
256 }
257}
258
260{
261 toolBar->setOrientation(o);
262 QLayoutItem *item = new QWidgetItemV2(toolBar);
263 insertItem(before, item);
264 return item;
265}
266
268{
269 if (before == nullptr) {
270 if (lines.isEmpty())
273 return;
274 }
275
276 for (int j = 0; j < lines.size(); ++j) {
278
279 for (int k = 0; k < line.toolBarItems.size(); ++k) {
280 if (line.toolBarItems.at(k).widgetItem->widget() == before) {
281 line.toolBarItems.insert(k, item);
282 return;
283 }
284 }
285 }
286}
287
289{
290 for (int j = 0; j < lines.size(); ++j) {
292
293 for (int k = 0; k < line.toolBarItems.size(); ++k) {
294 QToolBarAreaLayoutItem &item = line.toolBarItems[k];
295 if (item.widgetItem->widget() == toolBar) {
296 delete item.widgetItem;
297 item.widgetItem = nullptr;
298 line.toolBarItems.removeAt(k);
299
300 if (line.toolBarItems.isEmpty() && j < lines.size() - 1)
302
303 return;
304 }
305 }
306 }
307}
308
310{
311 if (before == nullptr) {
313 return;
315 return;
316 }
317
318 for (int j = 0; j < lines.size(); ++j) {
320
321 for (int k = 0; k < line.toolBarItems.size(); ++k) {
322 if (line.toolBarItems.at(k).widgetItem->widget() == before) {
323 if (k == 0)
324 return;
325
326 QToolBarAreaLayoutLine newLine(o);
327 newLine.toolBarItems = line.toolBarItems.mid(k);
328 line.toolBarItems = line.toolBarItems.mid(0, k);
329 lines.insert(j + 1, newLine);
330
331 return;
332 }
333 }
334 }
335}
336
338{
339 for (int j = 0; j < lines.size(); ++j) {
341
342 for (int k = 0; k < line.toolBarItems.size(); ++k) {
343 if (line.toolBarItems.at(k).widgetItem->widget() == before) {
344 if (k != 0)
345 return;
346 if (j == 0)
347 return;
348
349 lines[j - 1].toolBarItems += lines[j].toolBarItems;
351
352 return;
353 }
354 }
355 }
356}
357
359{
360 if (dirty)
361 fitLayout();
362
363 dirty = true;
364
365 if (o == Qt::Vertical)
366 pos -= rect.top();
367
368 //here we actually update the preferredSize for the line containing the toolbar so that we move it
369 for (int j = 0; j < lines.size(); ++j) {
371
372 int previousIndex = -1;
373 int minPos = 0;
374 for (int k = 0; k < line.toolBarItems.size(); ++k) {
375 QToolBarAreaLayoutItem &current = line.toolBarItems[k];
376 if (current.widgetItem->widget() == toolbar) {
377 int newPos = current.pos;
378
379 if (previousIndex >= 0) {
380 QToolBarAreaLayoutItem &previous = line.toolBarItems[previousIndex];
381 if (pos < current.pos) {
382 newPos = qMax(pos, minPos);
383 } else {
384 //we check the max value for the position (until everything at the right is "compressed")
385 int maxPos = pick(o, rect.size());
386 for(int l = k; l < line.toolBarItems.size(); ++l) {
387 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(l);
388 if (!item.skip()) {
389 maxPos -= pick(o, item.minimumSize());
390 }
391 }
392 newPos = qMin(pos, maxPos);
393 }
394
395 //extra is the number of pixels to add to the previous toolbar
396 int extra = newPos - current.pos;
397
398 //we check if the previous is near its size hint
399 //in which case we try to stick to it
400 const int diff = pick(o, previous.sizeHint()) - (previous.size + extra);
402 //we stick to the default place and size
403 extra += diff;
404 }
405
406 //update for the current item
407 current.extendSize(line.o, -extra);
408
409 if (extra >= 0) {
410 previous.extendSize(line.o, extra);
411 } else {
412 //we need to push the toolbars on the left starting with previous
413 extra = -extra; // we just need to know the number of pixels
415 for(int l = previousIndex; l >=0; --l) {
416 QToolBarAreaLayoutItem &item = line.toolBarItems[l];
417 if (!item.skip()) {
418 const int minPreferredSize = pick(o, item.minimumSize());
419 const int margin = item.size - minPreferredSize;
420 if (margin < extra) {
421 item.resize(line.o, minPreferredSize);
422 extra -= margin;
423 } else {
424 item.extendSize(line.o, -extra);
425 extra = 0;
426 }
427 }
428 }
429 Q_ASSERT(extra == 0);
430 }
431 } else {
432 //the item is the first one, it should be at position 0
433 }
434
435 return;
436
437 } else if (!current.skip()) {
438 previousIndex = k;
439 minPos += pick(o, current.minimumSize());
440 }
441 }
442 }
443}
444
445
446QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance) const
447{
448 if (rect.contains(pos)) {
449 // <pos> is in QToolBarAreaLayout coordinates.
450 // <item.pos> is in local dockarea coordinates (see ~20 lines below)
451 // Since we're comparing p with item.pos, we put them in the same coordinate system.
452 const int p = pick(o, pos - rect.topLeft());
453
454 for (int j = 0; j < lines.size(); ++j) {
456 if (line.skip())
457 continue;
458 if (!line.rect.contains(pos))
459 continue;
460
461 int k = 0;
462 for (; k < line.toolBarItems.size(); ++k) {
463 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
464 if (item.skip())
465 continue;
466
467 int size = qMin(item.size, pick(o, item.sizeHint()));
468
469 if (p > item.pos + size)
470 continue;
471 if (p > item.pos + size/2)
472 ++k;
473 break;
474 }
475
476 QList<int> result;
477 result << j << k;
478 *minDistance = 0; //we found a perfect match
479 return result;
480 }
481 } else {
482 const int dist = distance(pos);
483 //it will only return a path if the minDistance is higher than the current distance
484 if (dist >= 0 && *minDistance > dist) {
485 *minDistance = dist;
486
487 QList<int> result;
488 result << lines.size() << 0;
489 return result;
490 }
491 }
492
493 return QList<int>();
494}
495
497{
498 Q_ASSERT(path.size() == 2);
499 int j = path.first();
500 if (j == lines.size())
502
504 const int k = path.at(1);
505
506 QToolBarAreaLayoutItem gap_item;
507 gap_item.gap = true;
508 gap_item.widgetItem = item;
509
510 //update the previous item's preferred size
511 for(int p = k - 1 ; p >= 0; --p) {
512 QToolBarAreaLayoutItem &previous = line.toolBarItems[p];
513 if (!previous.skip()) {
514 //we found the previous one
515 int previousSizeHint = pick(line.o, previous.sizeHint());
516 int previousExtraSpace = previous.size - previousSizeHint;
517
518 if (previousExtraSpace > 0) {
519 //in this case we reset the space
520 previous.preferredSize = -1;
521 previous.size = previousSizeHint;
522
523 gap_item.resize(o, previousExtraSpace);
524 }
525
526 break;
527 }
528 }
529
530 line.toolBarItems.insert(k, gap_item);
531 return true;
532
533}
534
536{
537 lines.clear();
538 rect = QRect();
539}
540
542{
543 Q_ASSERT(path.size() == 2);
544 int j = path.at(0);
545 int k = path.at(1);
546
548 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
549
550 QRect result = line.rect;
551
552 if (o == Qt::Horizontal) {
553 result.setLeft(item.pos + line.rect.left());
554 result.setWidth(item.size);
555 } else {
556 result.setTop(item.pos + line.rect.top());
557 result.setHeight(item.size);
558 }
559
560 return result;
561}
562
564{
565 switch (dockPos) {
567 if (pos.y() < rect.bottom())
568 return pos.x() - rect.right();
569 break;
571 if (pos.y() < rect.bottom())
572 return rect.left() - pos.x();
573 break;
575 if (pos.x() < rect.right())
576 return pos.y() - rect.bottom();
577 break;
579 if (pos.x() < rect.right())
580 return rect.top() - pos.y();
581 break;
582
584 break;
585 }
586 return -1;
587}
588
589/******************************************************************************
590** QToolBarAreaLayout
591*/
592
593QToolBarAreaLayout::QToolBarAreaLayout(const QMainWindow *win) : mainWindow(win), visible(true)
594{
595 for (int i = 0; i < QInternal::DockCount; ++i) {
598 }
599}
600
602{
603 if (!visible)
604 return rect;
605
609 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
610
611 QRect center = rect.adjusted(left_hint.width(), top_hint.height(),
612 -right_hint.width(), -bottom_hint.height());
613
615 rect.width(), top_hint.height());
616 docks[QInternal::LeftDock].rect = QRect(rect.left(), center.top(),
617 left_hint.width(), center.height());
618 docks[QInternal::RightDock].rect = QRect(center.right() + 1, center.top(),
619 right_hint.width(), center.height());
620 docks[QInternal::BottomDock].rect = QRect(rect.left(), center.bottom() + 1,
621 rect.width(), bottom_hint.height());
622
627
628 return center;
629}
630
632{
633 if (!visible)
634 return centerMin;
635
636 QSize result = centerMin;
637
642
643 result.setWidth(qMax(top_min.width(), result.width()));
644 result.setWidth(qMax(bottom_min.width(), result.width()));
645 result.setHeight(qMax(left_min.height(), result.height()));
646 result.setHeight(qMax(right_min.height(), result.height()));
647
648 result.rwidth() += left_min.width() + right_min.width();
649 result.rheight() += top_min.height() + bottom_min.height();
650
651 return result;
652}
653
655{
656 if (!visible)
657 return centerHint;
658
659 QSize result = centerHint;
660
664 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
665
666 result.setWidth(qMax(top_hint.width(), result.width()));
667 result.setWidth(qMax(bottom_hint.width(), result.width()));
668 result.setHeight(qMax(left_hint.height(), result.height()));
669 result.setHeight(qMax(right_hint.height(), result.height()));
670
671 result.rwidth() += left_hint.width() + right_hint.width();
672 result.rheight() += top_hint.height() + bottom_hint.height();
673
674 return result;
675}
676
678{
679 int coef = visible ? 1 : -1;
680
681 QRect result = r;
682
686 QSize bottom_hint = docks[QInternal::BottomDock].sizeHint();
687
688 result.adjust(-left_hint.width()*coef, -top_hint.height()*coef,
689 right_hint.width()*coef, bottom_hint.height()*coef);
690
691 return result;
692}
693
695{
696 Q_ASSERT(x != nullptr);
697
698 for (int i = 0; i < QInternal::DockCount; ++i) {
699 const QToolBarAreaLayoutInfo &dock = docks[i];
700
701 for (int j = 0; j < dock.lines.size(); ++j) {
702 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
703
704 for (int k = 0; k < line.toolBarItems.size(); ++k) {
705 if ((*x)++ == index)
706 return line.toolBarItems.at(k).widgetItem;
707 }
708 }
709 }
710
711 return nullptr;
712}
713
715{
716 Q_ASSERT(x != nullptr);
717
718 for (int i = 0; i < QInternal::DockCount; ++i) {
720
721 for (int j = 0; j < dock.lines.size(); ++j) {
722 QToolBarAreaLayoutLine &line = dock.lines[j];
723
724 for (int k = 0; k < line.toolBarItems.size(); ++k) {
725 if ((*x)++ == index) {
726 QLayoutItem *result = line.toolBarItems.takeAt(k).widgetItem;
727 if (line.toolBarItems.isEmpty())
728 dock.lines.removeAt(j);
729 return result;
730 }
731 }
732 }
733 }
734
735 return nullptr;
736}
737
739{
740 for (int i = 0; i < QInternal::DockCount; ++i) {
742
743 for (int j = 0; j < dock.lines.size(); ++j) {
744 QToolBarAreaLayoutLine &line = dock.lines[j];
745
746 for (int k = 0; k < line.toolBarItems.size(); ++k) {
747 QToolBarAreaLayoutItem &item = line.toolBarItems[k];
748 if (!item.gap)
749 delete item.widgetItem;
750 item.widgetItem = nullptr;
751 }
752 }
753 }
754}
755
757{
758 for (int i = 0; i < QInternal::DockCount; ++i) {
759 const QToolBarAreaLayoutInfo &dock = docks[i];
760
761 for (int j = 0; j < dock.lines.size(); ++j) {
762 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
763
764 for (int k = 0; k < line.toolBarItems.size(); ++k) {
765 if (line.toolBarItems.at(k).widgetItem->widget() == toolBar)
766 return static_cast<QInternal::DockPosition>(i);
767 }
768 }
769 }
770
772}
773
775{
778 return nullptr;
779
780 return docks[pos].insertToolBar(before, toolBar);
781}
782
784{
787 return;
788 docks[pos].removeToolBar(toolBar);
789}
790
795
803
811
816
818{
821 return;
822 docks[pos].moveToolBar(toolbar, p);
823}
824
825
832
834{
837 return;
838
839 docks[pos].insertItem(before, item);
840}
841
843{
845 Q_ASSERT(layout != nullptr);
846
848
849 for (int i = 0; i < QInternal::DockCount; ++i) {
850 const QToolBarAreaLayoutInfo &dock = docks[i];
851
852 for (int j = 0; j < dock.lines.size(); ++j) {
853 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
854 if (line.skip())
855 continue;
856
857 for (int k = 0; k < line.toolBarItems.size(); ++k) {
858 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
859 if (item.skip() || item.gap)
860 continue;
861
862 QRect geo;
863 if (visible) {
864 if (line.o == Qt::Horizontal) {
865 geo.setTop(line.rect.top());
866 geo.setBottom(line.rect.bottom());
867 geo.setLeft(line.rect.left() + item.pos);
868 geo.setRight(line.rect.left() + item.pos + item.size - 1);
869 } else {
870 geo.setLeft(line.rect.left());
871 geo.setRight(line.rect.right());
872 geo.setTop(line.rect.top() + item.pos);
873 geo.setBottom(line.rect.top() + item.pos + item.size - 1);
874 }
875 }
876
877 QWidget *widget = item.widgetItem->widget();
878 if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
879 QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(toolBar->layout());
880 if (tbl->expanded) {
881 QPoint tr = geo.topRight();
882 QSize size = tbl->expandedSize(geo.size());
883 geo.setSize(size);
884 geo.moveTopRight(tr);
885 if (geo.bottom() > rect.bottom())
886 geo.moveBottom(rect.bottom());
887 if (geo.right() > rect.right())
888 geo.moveRight(rect.right());
889 if (geo.left() < 0)
890 geo.moveLeft(0);
891 if (geo.top() < 0)
892 geo.moveTop(0);
893 }
894 }
895
896 if (visible && dock.o == Qt::Horizontal)
897 geo = QStyle::visualRect(dir, line.rect, geo);
898
899 layout->widgetAnimator.animate(widget, geo, animate);
900 }
901 }
902 }
903}
904
906{
907 for (int i = 0; i < QInternal::DockCount; ++i) {
908 const QToolBarAreaLayoutInfo &dock = docks[i];
909
910 for (int j = 0; j < dock.lines.size(); ++j) {
911 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
912
913 for (int k = 0; k < line.toolBarItems.size(); ++k) {
914 if (line.toolBarItems.at(k).widgetItem->widget() == toolBar)
915 return j > 0 && k == 0;
916 }
917 }
918 }
919
920 return false;
921}
922
923void QToolBarAreaLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const
924{
925 for (int i = 0; i < QInternal::DockCount; ++i) {
926 const QToolBarAreaLayoutInfo &dock = docks[i];
927
928 for (int j = 0; j < dock.lines.size(); ++j) {
929 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
930
931 for (int k = 0; k < line.toolBarItems.size(); ++k) {
932 if (line.toolBarItems.at(k).widgetItem->widget() == toolBar) {
933 if (line.toolBarItems.size() == 1)
934 option->positionWithinLine = QStyleOptionToolBar::OnlyOne;
935 else if (k == 0)
936 option->positionWithinLine = QStyleOptionToolBar::Beginning;
937 else if (k == line.toolBarItems.size() - 1)
938 option->positionWithinLine = QStyleOptionToolBar::End;
939 else
940 option->positionWithinLine = QStyleOptionToolBar::Middle;
941
942 if (dock.lines.size() == 1)
943 option->positionOfLine = QStyleOptionToolBar::OnlyOne;
944 else if (j == 0)
945 option->positionOfLine = QStyleOptionToolBar::Beginning;
946 else if (j == dock.lines.size() - 1)
947 option->positionOfLine = QStyleOptionToolBar::End;
948 else
949 option->positionOfLine = QStyleOptionToolBar::Middle;
950
951 return;
952 }
953 }
954 }
955 }
956}
957
958QList<int> QToolBarAreaLayout::indexOf(QWidget *toolBar) const
959{
960 QList<int> result;
961
962 bool found = false;
963
964 for (int i = 0; i < QInternal::DockCount; ++i) {
965 const QToolBarAreaLayoutInfo &dock = docks[i];
966
967 for (int j = 0; j < dock.lines.size(); ++j) {
968 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
969
970 for (int k = 0; k < line.toolBarItems.size(); ++k) {
971 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
972 if (!item.gap && item.widgetItem->widget() == toolBar) {
973 found = true;
974 result.prepend(k);
975 break;
976 }
977 }
978
979 if (found) {
980 result.prepend(j);
981 break;
982 }
983 }
984
985 if (found) {
986 result.prepend(i);
987 break;
988 }
989 }
990
991 return result;
992}
993
994//this functions returns the path to the possible gapindex for the position pos
996{
998 int minDistance = 80; // when a dock area is empty, how "wide" is it?
999 QList<int> ret; //return value
1000 for (int i = 0; i < QInternal::DockCount; ++i) {
1001 QPoint p = pos;
1002 if (docks[i].o == Qt::Horizontal)
1004 QList<int> result = docks[i].gapIndex(p, &minDistance);
1005 if (!result.isEmpty()) {
1006 result.prepend(i);
1007 ret = result;
1008 }
1009 }
1010
1011 return ret;
1012}
1013
1015{
1016 for (int i = 0; i < QInternal::DockCount; ++i) {
1017 const QToolBarAreaLayoutInfo &dock = docks[i];
1018
1019 for (int j = 0; j < dock.lines.size(); ++j) {
1020 const QToolBarAreaLayoutLine &line = dock.lines[j];
1021
1022 for (int k = 0; k < line.toolBarItems.size(); k++) {
1023 if (line.toolBarItems[k].gap) {
1024 QList<int> result;
1025 result << i << j << k;
1026 return result;
1027 }
1028 }
1029 }
1030 }
1031 return QList<int>();
1032}
1033
1035{
1036 Q_ASSERT(path.size() == 3);
1037 const int i = path.first();
1038 Q_ASSERT(i >= 0 && i < QInternal::DockCount);
1039 return docks[i].insertGap(path.mid(1), item);
1040}
1041
1042void QToolBarAreaLayout::remove(const QList<int> &path)
1043{
1044 Q_ASSERT(path.size() == 3);
1045 QToolBarAreaLayoutInfo &dock = docks[path.at(0)];
1046 QToolBarAreaLayoutLine &line = dock.lines[path.at(1)];
1047 line.toolBarItems.removeAt(path.at(2));
1048 if (line.toolBarItems.isEmpty())
1049 dock.lines.removeAt(path.at(1));
1050}
1051
1053{
1054 for (int i = 0; i < QInternal::DockCount; ++i) {
1056
1057 for (int j = 0; j < dock.lines.size(); ++j) {
1058 QToolBarAreaLayoutLine &line = dock.lines[j];
1059
1060 for (int k = 0; k < line.toolBarItems.size(); k++) {
1061 if (line.toolBarItems[k].widgetItem == item) {
1062 line.toolBarItems.removeAt(k);
1063 if (line.toolBarItems.isEmpty())
1064 dock.lines.removeAt(j);
1065 return;
1066 }
1067 }
1068 }
1069 }
1070}
1071
1073{
1074 for (int i = 0; i < QInternal::DockCount; ++i)
1075 docks[i].clear();
1076 rect = QRect();
1077}
1078
1080{
1081 Q_ASSERT(path.size() == 3);
1082
1083 if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount)
1084 return nullptr;
1086 if (path.at(1) < 0 || path.at(1) >= info.lines.size())
1087 return nullptr;
1088 QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
1089 if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.size())
1090 return nullptr;
1091 return &(line.toolBarItems[path.at(2)]);
1092}
1093
1095{
1096 const int i = path.first();
1097
1098 QRect r = docks[i].itemRect(path.mid(1));
1099 if (docks[i].o == Qt::Horizontal)
1101 docks[i].rect, r);
1102 return r;
1103}
1104
1106{
1107 QToolBarAreaLayoutItem *item = this->item(path);
1108 if (Q_UNLIKELY(!item)) {
1109 qWarning() << "No item at" << path;
1110 return nullptr;
1111 }
1112 Q_ASSERT(item->gap);
1113 Q_ASSERT(item->widgetItem != nullptr);
1114 item->gap = false;
1115 return item->widgetItem;
1116}
1117
1119{
1120 //other needs to be update as well
1121 Q_ASSERT(path.size() == 3);
1122 QToolBarAreaLayoutItem *item = this->item(path);
1123 Q_ASSERT(item);
1124
1125 //update the leading space here
1127 QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
1128 if (item->size != pick(line.o, item->realSizeHint())) {
1129 //the item doesn't have its default size
1130 //so we'll give this to the next item
1131 int newExtraSpace = 0;
1132 //let's iterate over the siblings of the current item that pare placed before it
1133 //we need to find just the one before
1134 for (int i = path.at(2) - 1; i >= 0; --i) {
1135 QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
1136 if (!previous.skip()) {
1137 //we need to check if it has a previous element and a next one
1138 //the previous will get its size changed
1139 for (int j = path.at(2) + 1; j < line.toolBarItems.size(); ++j) {
1140 const QToolBarAreaLayoutItem &next = line.toolBarItems.at(j);
1141 if (!next.skip()) {
1142 newExtraSpace = next.pos - previous.pos - pick(line.o, previous.sizeHint());
1143 previous.resize(line.o, next.pos - previous.pos);
1144 break;
1145 }
1146 }
1147 break;
1148 }
1149 }
1150
1151 if (other) {
1152 QToolBarAreaLayoutInfo &info = other->docks[path.at(0)];
1153 QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
1154 for (int i = path.at(2) - 1; i >= 0; --i) {
1155 QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
1156 if (!previous.skip()) {
1157 previous.resize(line.o, pick(line.o, previous.sizeHint()) + newExtraSpace);
1158 break;
1159 }
1160 }
1161
1162 }
1163 }
1164
1165 Q_ASSERT(!item->gap);
1166 item->gap = true;
1167 return item->widgetItem;
1168}
1169
1170static QRect unpackRect(uint geom0, uint geom1, bool *floating)
1171{
1172 *floating = geom0 & 1;
1173 if (!*floating)
1174 return QRect();
1175
1176 geom0 >>= 1;
1177
1178 int x = (int)(geom0 & 0x0000ffff) - 0x7FFF;
1179 int y = (int)(geom1 & 0x0000ffff) - 0x7FFF;
1180
1181 geom0 >>= 16;
1182 geom1 >>= 16;
1183
1184 int w = geom0 & 0x0000ffff;
1185 int h = geom1 & 0x0000ffff;
1186
1187 return QRect(x, y, w, h);
1188}
1189
1190static void packRect(uint *geom0, uint *geom1, const QRect &rect, bool floating)
1191{
1192 *geom0 = 0;
1193 *geom1 = 0;
1194
1195 if (!floating)
1196 return;
1197
1198 // The 0x7FFF is half of 0xFFFF. We add it so we can handle negative coordinates on
1199 // dual monitors. It's subtracted when unpacking.
1200
1201 *geom0 |= qMax(0, rect.width()) & 0x0000ffff;
1202 *geom1 |= qMax(0, rect.height()) & 0x0000ffff;
1203
1204 *geom0 <<= 16;
1205 *geom1 <<= 16;
1206
1207 *geom0 |= qMax(0, rect.x() + 0x7FFF) & 0x0000ffff;
1208 *geom1 |= qMax(0, rect.y() + 0x7FFF) & 0x0000ffff;
1209
1210 // yeah, we chop one bit off the width, but it still has a range up to 32512
1211
1212 *geom0 <<= 1;
1213 *geom0 |= 1;
1214}
1215
1216
1218{
1219 // save toolbar state
1221
1222 int lineCount = 0;
1223 for (int i = 0; i < QInternal::DockCount; ++i)
1224 lineCount += docks[i].lines.size();
1225
1226 stream << lineCount;
1227
1228 for (int i = 0; i < QInternal::DockCount; ++i) {
1229 const QToolBarAreaLayoutInfo &dock = docks[i];
1230
1231 for (int j = 0; j < dock.lines.size(); ++j) {
1232 const QToolBarAreaLayoutLine &line = dock.lines.at(j);
1233
1234 stream << i << int(line.toolBarItems.size());
1235
1236 for (int k = 0; k < line.toolBarItems.size(); ++k) {
1237 const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
1238 QWidget *widget = const_cast<QLayoutItem*>(item.widgetItem)->widget();
1239 QString objectName = widget->objectName();
1240 if (Q_UNLIKELY(objectName.isEmpty())) {
1241 qWarning("QMainWindow::saveState(): 'objectName' not set for QToolBar %p '%s'",
1243 }
1244 stream << objectName;
1245 // we store information as:
1246 // 1st bit: 1 if shown
1247 // 2nd bit: 1 if orientation is vertical (default is horizontal)
1248 uchar shownOrientation = (uchar)!widget->isHidden();
1249 if (QToolBar * tb= qobject_cast<QToolBar*>(widget)) {
1250 if (tb->orientation() == Qt::Vertical)
1251 shownOrientation |= 2;
1252 }
1253 stream << shownOrientation;
1254 stream << item.pos;
1255 //we store the preferred size. If the use rdidn't resize the toolbars it will be -1
1256 stream << item.preferredSize;
1257
1258 uint geom0, geom1;
1259 packRect(&geom0, &geom1, widget->geometry(), widget->isWindow());
1260 stream << geom0 << geom1;
1261 }
1262 }
1263 }
1264}
1265
1266static inline int getInt(QDataStream &stream)
1267{
1268 int x;
1269 stream >> x;
1270 return x;
1271}
1272
1273
1274bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*> &_toolBars, uchar tmarker, bool testing)
1275{
1276 QList<QToolBar*> toolBars = _toolBars;
1277 int lines;
1278 stream >> lines;
1279
1280 for (int j = 0; j < lines; ++j) {
1281 int pos;
1282 stream >> pos;
1283 if (pos < 0 || pos >= QInternal::DockCount)
1284 return false;
1285 int cnt;
1286 stream >> cnt;
1287
1289 const bool applyingLayout = !testing;
1291
1292 for (int k = 0; k < cnt; ++k) {
1294
1295 QString objectName;
1296 stream >> objectName;
1297 uchar shown;
1298 stream >> shown;
1299 item.pos = getInt(stream);
1300 item.size = getInt(stream);
1301
1302 /*
1303 4.3.0 added floating toolbars, but failed to add the ability to restore them.
1304 We need to store there geometry (four ints). We cannot change the format in a
1305 patch release (4.3.1) by adding ToolBarStateMarkerEx2 to signal extra data. So
1306 for now we'll pack it in the two legacy ints we no longer used in Qt4.3.0.
1307 In 4.4, we should add ToolBarStateMarkerEx2 and fix this properly.
1308 */
1309
1310 QRect rect;
1311 bool floating = false;
1312 uint geom0, geom1;
1313 geom0 = getInt(stream);
1314 if (tmarker == ToolBarStateMarkerEx) {
1315 geom1 = getInt(stream);
1316 rect = unpackRect(geom0, geom1, &floating);
1317 }
1318
1319 QToolBar *toolBar = nullptr;
1320 for (int x = 0; x < toolBars.size(); ++x) {
1321 if (toolBars.at(x)->objectName() == objectName) {
1322 toolBar = toolBars.takeAt(x);
1323 break;
1324 }
1325 }
1326 if (toolBar == nullptr) {
1327 continue;
1328 }
1329
1330 if (applyingLayout) {
1331 // Clear the previous widgetItem for the toolBar, so that it's
1332 // assigned correctly in QWidgetItemV2 constructor.
1333 auto *toolBarPrivate = QWidgetPrivate::get(toolBar);
1334 toolBarPrivate->widgetItem = nullptr;
1335 item.widgetItem = new QWidgetItemV2(toolBar);
1336 toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
1337 toolBar->setVisible(shown & 1);
1338 toolBar->d_func()->setWindowState(floating, false, rect);
1339
1340 item.preferredSize = item.size;
1341 line.toolBarItems.append(item);
1342 }
1343 }
1344
1345 if (applyingLayout) {
1346 dock.lines.append(line);
1347 }
1348 }
1349
1350
1351 return stream.status() == QDataStream::Ok;
1352}
1353
1355{
1356 for (int i = 0; i < QInternal::DockCount; ++i) {
1357 if (!docks[i].lines.isEmpty())
1358 return false;
1359 }
1360 return true;
1361}
1362
int startDragDistance
the minimum distance required for a drag and drop operation to start.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
\inmodule QtCore\reentrant
Definition qdatastream.h:46
QPointF pos() const
Returns the position of the item in parent coordinates.
The QLayoutItem class provides an abstract item that a QLayout manipulates.
Definition qlayoutitem.h:25
virtual bool isEmpty() const =0
Implemented in subclasses to return whether this item is empty, i.e.
virtual QWidget * widget() const
If this item manages a QWidget, returns that widget.
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
T & last()
Definition qlist.h:648
void removeAt(qsizetype i)
Definition qlist.h:590
const T & constLast() const noexcept
Definition qlist.h:650
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void prepend(rvalue_ref t)
Definition qlist.h:473
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
The QMainWindow class provides a main application window.
Definition qmainwindow.h:25
QString objectName
the name of this object
Definition qobject.h:107
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr void setRight(int pos) noexcept
Sets the right edge of the rectangle to the given x coordinate.
Definition qrect.h:197
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:221
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr void setBottom(int pos) noexcept
Sets the bottom edge of the rectangle to the given y coordinate.
Definition qrect.h:200
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:855
constexpr void setLeft(int pos) noexcept
Sets the left edge of the rectangle to the given x coordinate.
Definition qrect.h:191
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
constexpr void setTop(int pos) noexcept
Sets the top edge of the rectangle to the given y coordinate.
Definition qrect.h:194
constexpr Policy verticalPolicy() const noexcept
Returns the vertical component of the size policy.
Definition qsizepolicy.h:67
constexpr Policy horizontalPolicy() const noexcept
Returns the horizontal component of the size policy.
Definition qsizepolicy.h:66
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr QSize expandedTo(const QSize &) const noexcept
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition qsize.h:192
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
QString & removeAt(qsizetype pos)
Definition qstring.h:555
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
QString right(qsizetype n) const &
Definition qstring.h:375
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
QString & insert(qsizetype i, QChar c)
Definition qstring.cpp:3132
QByteArray toLocal8Bit() const &
Definition qstring.h:638
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
QString & append(QChar c)
Definition qstring.cpp:3252
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction.
Definition qstyle.cpp:2143
static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos)
Returns the given logicalPosition converted to screen coordinates based on the specified direction.
Definition qstyle.cpp:2162
QInternal::DockPosition dockPos
void insertToolBarBreak(QToolBar *before)
void insertItem(QToolBar *before, QLayoutItem *item)
QList< QToolBarAreaLayoutLine > lines
void removeToolBar(QToolBar *toolBar)
void removeToolBarBreak(QToolBar *before)
QLayoutItem * insertToolBar(QToolBar *before, QToolBar *toolBar)
QToolBarAreaLayoutInfo(QInternal::DockPosition pos=QInternal::TopDock)
QList< int > gapIndex(const QPoint &pos, int *maxDistance) const
void moveToolBar(QToolBar *toolbar, int pos)
bool insertGap(const QList< int > &path, QLayoutItem *item)
QRect itemRect(const QList< int > &path) const
int distance(const QPoint &pos) const
void resize(Qt::Orientation o, int newSize)
void extendSize(Qt::Orientation o, int extent)
QList< QToolBarAreaLayoutItem > toolBarItems
bool insertGap(const QList< int > &path, QLayoutItem *item)
const QMainWindow * mainWindow
QList< int > indexOf(QWidget *toolBar) const
QSize sizeHint(const QSize &center) const
void removeToolBarBreak(QToolBar *before)
QSize minimumSize(const QSize &centerMin) const
QLayoutItem * unplug(const QList< int > &path, QToolBarAreaLayout *other)
QLayoutItem * insertToolBar(QToolBar *before, QToolBar *toolBar)
void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const
QToolBarAreaLayoutInfo docks[4]
bool restoreState(QDataStream &stream, const QList< QToolBar * > &toolBars, uchar tmarker, bool testing=false)
void insertItem(QInternal::DockPosition pos, QLayoutItem *item)
QRect rectHint(const QRect &r) const
void removeToolBar(QToolBar *toolBar)
QLayoutItem * itemAt(int *x, int index) const
void insertToolBarBreak(QToolBar *before)
void apply(bool animate)
QInternal::DockPosition findToolBar(const QToolBar *toolBar) const
QToolBarAreaLayoutItem * item(const QList< int > &path)
QRect itemRect(const QList< int > &path) const
QToolBarAreaLayout(const QMainWindow *win)
QLayoutItem * takeAt(int *x, int index)
void saveState(QDataStream &stream) const
QLayoutItem * addToolBar(QInternal::DockPosition pos, QToolBar *toolBar)
QList< int > currentGapIndex() const
bool toolBarBreak(QToolBar *toolBar) const
void remove(const QList< int > &path)
void addToolBarBreak(QInternal::DockPosition pos)
QLayoutItem * plug(const QList< int > &path)
QList< int > gapIndex(const QPoint &pos) const
void moveToolBar(QToolBar *toolbar, int pos)
The QToolBar class provides a movable panel that contains a set of controls.
Definition qtoolbar.h:23
The QWidgetItem class is a layout item that represents a widget.
Definition qlayoutitem.h:86
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:212
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
Qt::LayoutDirection layoutDirection
the layout direction for this widget.
Definition qwidget.h:170
bool isHidden() const
Returns true if the widget is hidden, otherwise returns false.
Definition qwidget.h:877
QSize minimumSize
the widget's minimum size
Definition qwidget.h:120
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
QSize maximumSize
the widget's maximum size in pixels
Definition qwidget.h:121
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition qwidget.h:119
QSize minimumSizeHint
the recommended minimum size for the widget
Definition qwidget.h:149
QSize sizeHint
the recommended size for the widget
Definition qwidget.h:148
QString windowTitle
the window title (caption)
Definition qwidget.h:151
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
QOpenGLWidget * widget
[1]
rect
[4]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
LayoutDirection
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
#define Q_UNLIKELY(x)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)
static int pick(bool vertical, const QSize &size)
static int perp(bool vertical, const QSize &size)
EGLStreamKHR stream
Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
#define qWarning
Definition qlogging.h:166
return ret
static int & rperp(Qt::Orientation o, QPoint &pos)
Definition qmenu_p.h:61
static int & rpick(Qt::Orientation o, QPoint &pos)
Definition qmenu_p.h:46
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLsizei GLsizei GLfloat distance
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define tr(X)
static QRect unpackRect(uint geom0, uint geom1, bool *floating)
QT_BEGIN_NAMESPACE QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *mainWindow)
static void packRect(uint *geom0, uint *geom1, const QRect &rect, bool floating)
static int getInt(QDataStream &stream)
unsigned char uchar
Definition qtypes.h:32
unsigned int uint
Definition qtypes.h:34
QWidget * win
Definition settings.cpp:6
std::uniform_real_distribution dist(1, 2.5)
[2]
QVBoxLayout * layout
QSharedPointer< T > other(t)
[5]
QString dir
[11]
QGraphicsItem * item
QHostInfo info
[0]