Fix no newlines warnings. Patch by Peter Oberndorfer
[kdevelopdvcssupport.git] / sublime / ideallayout.cpp
blobe585ddcdc2d1d334ef1f7bea4e55e9675c15a752
1 /*
2 Copyright 2007 Roberto Raggi <roberto@kdevelop.org>
3 Copyright 2007 Hamish Rodda <rodda@kde.org>
4 Copyright 2008 Vladimir Prus <ghost@cs.msu.su>
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include "ideallayout.h"
24 #include "ideal.h"
26 #include "kdebug.h"
27 #include <KConfigGroup>
28 #include <KGlobal>
29 #include <KConfig>
31 using namespace Sublime;
33 IdealMainLayout::Role Sublime ::roleForArea(Qt::DockWidgetArea area)
35 switch (area) {
36 case Qt::LeftDockWidgetArea:
37 return IdealMainLayout::Left;
39 case Qt::RightDockWidgetArea:
40 return IdealMainLayout::Right;
42 case Qt::BottomDockWidgetArea:
43 return IdealMainLayout::Bottom;
45 case Qt::TopDockWidgetArea:
46 return IdealMainLayout::Top;
48 default:
49 Q_ASSERT(false);
50 return IdealMainLayout::Left;
54 Qt::DockWidgetArea Sublime ::areaForRole(IdealMainLayout::Role role)
56 switch (role) {
57 case IdealMainLayout::Left:
58 return Qt::LeftDockWidgetArea;
60 case IdealMainLayout::Right:
61 return Qt::RightDockWidgetArea;
63 case IdealMainLayout::Bottom:
64 return Qt::BottomDockWidgetArea;
66 case IdealMainLayout::Top:
67 return Qt::TopDockWidgetArea;
69 default:
70 Q_ASSERT(false);
71 return Qt::LeftDockWidgetArea;
75 IdealButtonBarLayout::IdealButtonBarLayout(Qt::Orientation orientation, QWidget *parent)
76 : QLayout(parent)
77 , _orientation(orientation)
78 , _height(0)
81 if (orientation == Qt::Vertical)
82 setContentsMargins(2, 0, 2, 0);
83 else
84 setContentsMargins(0, 2, 0, 0);
85 setSpacing(2);
86 invalidate();
89 void IdealButtonBarLayout::invalidate()
91 m_minSizeDirty = true;
92 m_sizeHintDirty = true;
93 m_layoutDirty = true;
94 QLayout::invalidate();
97 IdealButtonBarLayout::~IdealButtonBarLayout()
99 qDeleteAll(_items);
102 void IdealButtonBarLayout::setHeight(int height)
104 Q_ASSERT(orientation() == Qt::Vertical);
105 _height = height;
107 (void) invalidate();
110 Qt::Orientation IdealButtonBarLayout::orientation() const
112 return _orientation;
115 Qt::Orientations IdealButtonBarLayout::expandingDirections() const
117 return orientation();
120 QSize IdealButtonBarLayout::minimumSize() const
122 // The code below appears to be completely wrong --
123 // it will return the maximum size of a single button, not any
124 // estimate as to how much space is necessary to draw all buttons
125 // in a minimally acceptable way.
126 if (m_minSizeDirty) {
127 if (orientation() == Qt::Vertical) {
128 const int width = doVerticalLayout(QRect(0, 0, 0, _height), false);
129 return QSize(width, 0);
132 m_min = QSize(0, 0);
133 foreach (QLayoutItem *item, _items)
134 m_min = m_min.expandedTo(item->minimumSize());
136 m_minSizeDirty = false;
138 return m_min;
141 QSize IdealButtonBarLayout::sizeHint() const
143 if (m_sizeHintDirty) {
144 int orientationSize = 0;
145 int crossSize = 0;
147 bool first = true;
148 foreach (QLayoutItem *item, _items)
150 QSize hint = item->sizeHint();
151 int orientationSizeHere;
152 int crossSizeHere;
153 if (orientation() == Qt::Vertical)
155 orientationSizeHere = hint.height();
156 crossSizeHere = hint.width();
158 else
160 orientationSizeHere = hint.width();
161 crossSizeHere = hint.height();
164 if (first)
166 crossSize = crossSizeHere;
168 else
170 orientationSize += spacing();
172 orientationSize += orientationSizeHere;
173 first = false;
176 if (orientation() == Qt::Vertical)
177 m_hint = QSize(crossSize, orientationSize);
178 else
179 m_hint = QSize(orientationSize, crossSize);
181 if (!_items.empty())
183 /* If we have no items, just use (0, 0) as hint, don't
184 append any margins. */
185 int l, t, r, b;
186 getContentsMargins(&l, &t, &r, &b);
187 m_hint += QSize(l+r, t+b);
190 m_sizeHintDirty = false;
192 return m_hint;
195 void IdealButtonBarLayout::setGeometry(const QRect &rect)
197 if (m_layoutDirty || rect != geometry())
198 if (orientation() == Qt::Vertical)
199 doVerticalLayout(rect);
200 else
201 doHorizontalLayout(rect);
204 void IdealButtonBarLayout::addItem(QLayoutItem *item)
206 _items.append(item);
209 QLayoutItem* IdealButtonBarLayout::itemAt(int index) const
211 return _items.value(index, 0);
214 QLayoutItem* IdealButtonBarLayout::takeAt(int index)
216 if (index >= 0 && index < _items.count())
217 return _items.takeAt(index);
218 return 0;
221 int IdealButtonBarLayout::count() const
223 return _items.count();
226 int IdealButtonBarLayout::doVerticalLayout(const QRect &rect, bool updateGeometry) const
228 int l, t, r, b;
229 getContentsMargins(&l, &t, &r, &b);
230 int x = rect.x() + l;
231 int y = rect.y() + t;
232 int currentLineWidth = 0;
234 foreach (QLayoutItem *item, _items) {
235 const QSize itemSizeHint = item->sizeHint();
236 if (y + itemSizeHint.height() + b > rect.height()) {
237 int newX = x + currentLineWidth + spacing();
238 if (newX + itemSizeHint.width() + r <= rect.width())
240 x += currentLineWidth + spacing();
241 y = rect.y() + t;
245 if (updateGeometry)
246 item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHint.height()));
248 currentLineWidth = qMax(currentLineWidth, itemSizeHint.width());
250 y += itemSizeHint.height() + spacing();
253 m_layoutDirty = updateGeometry;
255 return x + currentLineWidth + r;
258 int IdealButtonBarLayout::doHorizontalLayout(const QRect &rect, bool updateGeometry) const
260 int l, t, r, b;
261 getContentsMargins(&l, &t, &r, &b);
262 int x = rect.x() + l;
263 int y = rect.y() + t;
264 int currentLineHeight = 0;
266 foreach (QLayoutItem *item, _items) {
267 QSize itemSizeHint = item->sizeHint();
268 if (x + itemSizeHint.width() + r > rect.width()) {
269 // Run out of horizontal space. Try to move button to another
270 // row.
271 int newY = y + currentLineHeight + spacing();
272 if (newY + itemSizeHint.height() + b <= rect.height())
274 y = newY;
275 x = rect.x() + l;
276 currentLineHeight = 0;
280 if (updateGeometry)
281 item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHint.height()));
283 currentLineHeight = qMax(currentLineHeight, itemSizeHint.height());
285 x += itemSizeHint.width() + spacing();
288 m_layoutDirty = updateGeometry;
290 return y + currentLineHeight + b;
293 IdealDockWidget* IdealMainLayout::lastDockWidget() const
295 return qobject_cast<IdealDockWidget*>(m_lastDockWidget);
298 IdealDockWidget * IdealMainLayout::lastDockWidget(IdealMainLayout::Role role) const
300 return qobject_cast<IdealDockWidget*>(m_items[role]->last);
303 IdealMainLayout::IdealMainLayout(QWidget * parent)
304 : QLayout(parent)
305 , m_layoutDirty(true)
306 , m_minDirty(true)
307 , m_lastDockWidgetRole(Left)
308 , m_topOwnsTopLeft(0)
309 , m_topOwnsTopRight(0)
310 , m_bottomOwnsBottomLeft(0)
311 , m_bottomOwnsBottomRight(0)
312 , m_maximizedWidget(0)
314 createArea(Left);
315 createArea(Right);
316 createArea(Top);
317 createArea(Bottom);
318 createArea(Central);
320 setMargin(0);
321 m_splitterWidth = parent->style()->pixelMetric(QStyle::PM_SplitterWidth, 0, parentWidget());
323 loadSettings();
325 anchorWidget(true, Left);
326 anchorWidget(true, Right);
327 anchorWidget(true, Top);
328 anchorWidget(true, Bottom);
331 IdealMainLayout::~ IdealMainLayout()
335 QSize IdealMainLayout::minimumSize() const
337 if (m_minDirty) {
338 if (m_maximizedWidget) {
339 m_min = m_maximizedWidget->minimumSize();
340 m_minDirty = false;
341 return m_min;
344 int minHeight = 0;
345 int softMinHeight = 0;
346 int minWidth = 0;
347 int softMinWidth = 0;
349 minimumSize(Left, minWidth, softMinWidth, minHeight, softMinHeight);
350 minimumSize(Right, minWidth, softMinWidth, minHeight, softMinHeight);
351 minimumSize(Top, minWidth, softMinWidth, minHeight, softMinHeight);
352 minimumSize(Bottom, minWidth, softMinWidth, minHeight, softMinHeight);
354 if (QLayoutItem* item = m_items[Central]->first()) {
355 const QSize itemSizeHint = item->minimumSize();
356 minHeight += qMax(softMinHeight, itemSizeHint.height() + splitterWidth());
357 minWidth += qMax(softMinWidth, itemSizeHint.width() + splitterWidth());
360 m_min = QSize(minHeight, minWidth);
361 m_minDirty = true;
364 return m_min;
367 void IdealMainLayout::minimumSize(Role role, int& minWidth, int& softMinWidth, int& minHeight, int& softMinHeight) const
369 foreach (QLayoutItem* item, m_items[role]->items()) {
370 const QSize itemSizeHint = item->minimumSize();
371 switch (role) {
372 case Left:
373 case Right:
374 if (m_items[role]->anchored)
375 minWidth += itemSizeHint.width() + splitterWidth();
376 softMinHeight = qMax(softMinHeight, itemSizeHint.height() + splitterWidth());
377 break;
379 case Top:
380 case Bottom:
381 if (m_items[role]->anchored)
382 minHeight += itemSizeHint.height() + splitterWidth();
383 softMinWidth = qMax(softMinWidth, itemSizeHint.width() + splitterWidth());
384 break;
386 default:
387 break;
392 QLayoutItem * IdealMainLayout::itemAt(int index) const
394 int at = 0;
395 if (QLayoutItem* item = m_items[Left]->itemAt(index, at))
396 return item;
398 index -= at;
399 at = 0;
400 if (QLayoutItem* item = m_items[Right]->itemAt(index, at))
401 return item;
403 index -= at;
404 at = 0;
405 if (QLayoutItem* item = m_items[Top]->itemAt(index, at))
406 return item;
408 index -= at;
409 at = 0;
410 if (QLayoutItem* item = m_items[Bottom]->itemAt(index, at))
411 return item;
413 index -= at;
414 at = 0;
415 if (QLayoutItem* item = m_items[Central]->itemAt(index, at))
416 return item;
418 return 0;
421 void IdealMainLayout::addItem(QLayoutItem * item)
423 Q_UNUSED(item)
425 // Uh-oh...??
426 Q_ASSERT(false);
429 void IdealMainLayout::setGeometry(const QRect & rect)
431 if (m_layoutDirty || rect != geometry()) {
432 QLayout::setGeometry(rect);
433 doLayout(rect);
437 QSize IdealMainLayout::sizeHint() const
439 return QSize();
442 QLayoutItem * IdealMainLayout::takeAt(int index)
444 Q_UNUSED(index)
446 // Uh-oh...??
447 Q_ASSERT(false);
449 return 0;
452 int IdealMainLayout::count() const
454 return m_items[Left]->count() + m_items[Right]->count()
455 + m_items[Top]->count() + m_items[Bottom]->count() + m_items[Central]->count();
458 void IdealMainLayout::doLayout(QRect rect) const
460 if (m_maximizedWidget) {
461 m_maximizedWidget->setGeometry(rect);
462 return;
465 if (m_topOwnsTopLeft)
466 if (m_topOwnsTopRight)
467 if (m_bottomOwnsBottomLeft)
468 if (m_bottomOwnsBottomRight)
469 layout(Top, Bottom, Left, Right, rect);
470 else
471 layout(Top, Right, Bottom, Left, rect);
472 else
473 if (m_bottomOwnsBottomRight)
474 layout(Top, Left, Bottom, Right, rect);
475 else
476 layout(Top, Right, Left, Bottom, rect);
477 else
478 if (m_bottomOwnsBottomLeft)
479 if (m_bottomOwnsBottomRight)
480 layout(Bottom, Right, Top, Left, rect);
481 else
482 layout(Right, Top, Left, Bottom, rect);
483 else
484 if (m_bottomOwnsBottomRight)
485 // TODO: this is not possible with current code
486 layout(Top, Left, Bottom, Right, rect);
487 else
488 layout(Right, Top, Left, Bottom, rect);
489 else
490 if (m_topOwnsTopRight)
491 if (m_bottomOwnsBottomLeft)
492 if (m_bottomOwnsBottomRight)
493 layout(Bottom, Left, Top, Right, rect);
494 else
495 layout(Left, Top, Right, Bottom, rect);
496 else
497 if (m_bottomOwnsBottomRight)
498 layout(Left, Bottom, Top, Right, rect);
499 else
500 layout(Right, Left, Bottom, Top, rect);
501 else
502 if (m_bottomOwnsBottomLeft)
503 if (m_bottomOwnsBottomRight)
504 layout(Bottom, Right, Left, Top, rect);
505 else
506 layout(Right, Bottom, Left, Top, rect);
507 else
508 if (m_bottomOwnsBottomRight)
509 // TODO: this is not possible with current code
510 layout(Left, Bottom, Right, Top, rect);
511 else
512 layout(Right, Left, Bottom, Top, rect);
515 if (QLayoutItem* item = m_items[Central]->first()) {
516 QSize itemSizeHint = item->sizeHint();
517 if (itemSizeHint.height() > rect.height()) {
518 itemSizeHint.setHeight(qMax(item->minimumSize().height(), rect.height()));
520 if (itemSizeHint.height() > rect.height())
521 rect.setHeight(itemSizeHint.height());
524 if (itemSizeHint.width() > rect.width()) {
525 itemSizeHint.setWidth(qMax(item->minimumSize().width(), rect.width()));
527 if (itemSizeHint.width() > rect.width())
528 rect.setWidth(itemSizeHint.width());
531 item->setGeometry(rect);
534 m_layoutDirty = false;
537 void IdealMainLayout::layout(Role role1, Role role2, Role role3, Role role4, QRect & rect) const
539 layoutItem(role1, rect);
540 layoutItem(role2, rect);
541 layoutItem(role3, rect);
542 layoutItem(role4, rect);
545 void IdealMainLayout::layoutItem(Role role, QRect& rect) const
547 DockArea* area = m_items[role];
549 QWidgetItem* buttonBar = area->buttonBar();
550 if (buttonBar)
552 const QSize hint = buttonBar->sizeHint();
553 QRect geometry = rect;
554 if (role == Left) {
555 geometry.setWidth(hint.width());
556 rect.setLeft(hint.width());
558 else if (role == Bottom) {
559 int y = rect.height() - hint.height();
560 geometry.setTop(geometry.y() + y);
561 rect.setBottom(y);
563 else if (role == Right) {
564 int x = rect.width() - hint.width();
565 geometry.setLeft(geometry.x() + x);
566 rect.setWidth(x);
568 else if (role == Top) {
569 geometry.setHeight(hint.height());
570 rect.setTop(hint.height());
573 buttonBar->setGeometry(geometry);
576 foreach (QLayoutItem* item, area->items()) {
577 int hintDimension = 0;
578 if (m_items[role]->width != -1) {
579 hintDimension = m_items[role]->width;
581 } else {
582 const QSize itemSize = item->sizeHint();
583 switch (role) {
584 case Left:
585 case Right:
586 hintDimension = itemSize.width() + splitterWidth();
587 if (hintDimension + splitterWidth() > rect.width()) {
588 hintDimension = item->minimumSize().width();
590 if (hintDimension + splitterWidth() > rect.width())
591 rect.setWidth(hintDimension + splitterWidth());
593 break;
595 case Top:
596 case Bottom:
597 hintDimension = itemSize.height();
598 if (hintDimension + splitterWidth() > rect.height()) {
599 hintDimension = item->minimumSize().height();
601 if (hintDimension + splitterWidth() > rect.height())
602 rect.setHeight(hintDimension + splitterWidth());
604 break;
606 default:
607 break;
611 switch (role) {
612 case Left:
613 item->setGeometry(QRect(rect.x(), rect.y(), hintDimension, rect.height()));
614 area->mainSplitter()->setGeometry(QRect(rect.x() + hintDimension, rect.y(), splitterWidth(), rect.height()));
615 break;
617 case Right:
618 item->setGeometry(QRect(rect.x() + rect.width() - hintDimension, rect.y(), hintDimension, rect.height()));
619 area->mainSplitter()->setGeometry(QRect(rect.x() + rect.width() - hintDimension - splitterWidth(), rect.y(), splitterWidth(), rect.height()));
620 break;
622 case Top:
623 item->setGeometry(QRect(rect.x(), rect.y(), rect.width(), hintDimension));
624 area->mainSplitter()->setGeometry(QRect(rect.x(), rect.y() + hintDimension, rect.width(), splitterWidth()));
625 break;
627 case Bottom:
628 item->setGeometry(QRect(rect.x(), rect.y() + rect.height() - hintDimension, rect.width(), hintDimension));
629 area->mainSplitter()->setGeometry(QRect(rect.x(), rect.y() + rect.height() - hintDimension - splitterWidth(), rect.width(), splitterWidth()));
630 break;
632 default:
633 break;
636 if (m_items[role]->anchored) {
637 switch (role) {
638 case Left:
639 rect.setX(rect.x() + hintDimension + splitterWidth());
640 break;
642 case Right:
643 rect.setWidth(rect.width() - hintDimension - splitterWidth());
644 break;
646 case Top:
647 rect.setY(rect.y() + hintDimension + splitterWidth());
648 break;
650 case Bottom:
651 rect.setHeight(rect.height() - hintDimension - splitterWidth());
652 break;
654 default:
655 break;
661 IdealSplitterHandle* IdealMainLayout::createSplitter(Role role, bool reverse)
663 IdealSplitterHandle* splitter = 0;
665 Qt::Orientation direction = ((role == Left || role == Right) ^ reverse)
666 ? Qt::Vertical
667 : Qt::Horizontal;
669 splitter = new IdealSplitterHandle(direction, parentWidget(), role);
670 addChildWidget(splitter);
672 connect(splitter, SIGNAL(resize(int, IdealMainLayout::Role)),
673 SLOT(resizeWidget(int, IdealMainLayout::Role)));
675 splitter->hide();
676 return splitter;
679 void IdealMainLayout::createArea(Role role)
681 DockArea* area = new DockArea(this, role);
682 m_items.insert(role, area);
684 if (role != Central)
685 area->setMainSplitter(createSplitter(role));
688 void IdealMainLayout::addWidget(QWidget * widget, Role role)
690 if (m_maximizedWidget)
691 maximizeWidget(0);
693 if (IdealDockWidget* dock = qobject_cast<IdealDockWidget*>(widget))
694 if (dock->isFloating())
695 dock->setFloating(false);
697 if (widget->parent() != parentWidget()) {
698 widget->setParent(parentWidget());
699 addChildWidget(widget);
702 DockArea* area = m_items[role];
704 area->addWidget(widget);
706 area->setVisible(true, !m_maximizedWidget);
708 if (role != Central) {
709 m_lastDockWidget = widget;
710 m_lastDockWidgetRole = role;
711 m_items[role]->last = widget;
712 mainWidget()->setAnchorActionStatus(isAreaAnchored(role));
715 area->raise();
716 widget->setFocus();
719 void IdealMainLayout::addButtonBar(QWidget* widget, Role role)
721 DockArea* area = m_items[role];
722 area->setButtonBar(widget);
723 addChildWidget(widget);
726 void IdealMainLayout::removeWidgets(Role role)
728 if (m_maximizedWidget)
729 // FIXME correct?
730 maximizeWidget(0);
732 DockArea* area = m_items[role];
733 area->setVisible(false);
736 void IdealMainLayout::removeWidget(QWidget * widget, Role role)
738 DockArea* area = m_items[role];
739 area->removeWidget(widget);
740 if (area->items().isEmpty())
741 area->setVisible(false, false);
744 void IdealMainLayout::removeUnanchored()
746 if (!m_items[Left]->anchored)
747 removeWidgets(Left);
749 if (!m_items[Right]->anchored)
750 removeWidgets(Right);
752 if (!m_items[Top]->anchored)
753 removeWidgets(Top);
755 if (!m_items[Bottom]->anchored)
756 removeWidgets(Bottom);
759 void IdealMainLayout::invalidate()
761 m_layoutDirty = true;
762 m_minDirty = true;
763 QLayout::invalidate();
766 int IdealMainLayout::splitterWidth() const
768 return m_splitterWidth;
771 void IdealMainLayout::resizeWidget(int thickness, IdealMainLayout::Role role)
773 int offset = 0;
775 if (QWidgetItem* bar = m_items[role]->buttonBar())
776 if (role == Left || role == Right)
777 offset = bar->geometry().width();
778 else
779 offset = bar->geometry().height();
781 m_items[role]->width = thickness - offset;
783 invalidate();
785 emit widgetResized(role, thickness);
788 void IdealMainLayout::anchorWidget(bool anchor, IdealMainLayout::Role role)
790 m_items[role]->anchored = anchor;
792 invalidate();
795 void IdealMainLayout::maximizeWidget(QWidget* widget)
797 m_maximizedWidget = widget;
799 if (m_maximizedWidget) {
800 for (Role role = Left; role <= Central; role = static_cast<Role>(role + 1))
801 m_items[role]->setVisible(false, false, m_maximizedWidget);
803 } else {
804 for (Role role = Left; role <= Central; role = static_cast<Role>(role + 1))
805 if (!m_items[role]->items().isEmpty())
806 m_items[role]->setVisible(true, role != Central, m_maximizedWidget);
809 invalidate();
812 int IdealMainLayout::widthForRole(Role role) const
814 return m_items[role]->width;
817 void IdealMainLayout::setWidthForRole(Role role, int width)
819 m_items[role]->width = width;
820 invalidate();
823 bool IdealMainLayout::isAreaAnchored(Role role) const
825 return m_items[role]->anchored;
828 IdealMainWidget * IdealMainLayout::mainWidget() const
830 return dynamic_cast<IdealMainWidget*>(parentWidget());
833 void IdealMainLayout::loadSettings()
835 KConfigGroup cg(KGlobal::config(), "UiSettings");
837 bool invalid = false;
839 int topOwnsTopLeft = cg.readEntry("TopLeftCornerOwner", 0);
840 if (m_topOwnsTopLeft != topOwnsTopLeft) {
841 m_topOwnsTopLeft = topOwnsTopLeft;
842 invalid = true;
845 int topOwnsTopRight = cg.readEntry("TopRightCornerOwner", 0);
846 if (m_topOwnsTopRight != topOwnsTopRight) {
847 m_topOwnsTopRight = topOwnsTopRight;
848 invalid = true;
851 int bottomOwnsBottomLeft = cg.readEntry("BottomLeftCornerOwner", 0);
852 if (m_bottomOwnsBottomLeft != bottomOwnsBottomLeft) {
853 m_bottomOwnsBottomLeft = bottomOwnsBottomLeft;
854 invalid = true;
857 int bottomOwnsBottomRight = cg.readEntry("BottomRightCornerOwner", 0);
858 if (m_bottomOwnsBottomRight != bottomOwnsBottomRight) {
859 m_bottomOwnsBottomRight = bottomOwnsBottomRight;
860 invalid = true;
863 if (invalid)
864 invalidate();
867 IdealMainLayout::Role IdealMainLayout::lastDockWidgetRole() const
869 return m_lastDockWidgetRole;
872 QWidgetItem * IdealMainLayout::DockArea::mainSplitter() const
874 return m_mainSplitter;
877 void IdealMainLayout::DockArea::setMainSplitter(QWidget* widget)
879 m_mainSplitter = new QWidgetItem(widget);
882 IdealMainLayout::DockArea::DockArea(IdealMainLayout* layout, Role role)
883 : width(250)
884 , anchored(false)
885 , m_layout(layout)
886 , m_role(role)
887 , m_mainSplitter(0)
888 , m_buttonBarItem(0)
892 void IdealMainLayout::DockArea::removeMainSplitter()
894 if (m_mainSplitter) {
895 delete m_mainSplitter->widget();
896 delete m_mainSplitter;
897 m_mainSplitter = 0;
901 void IdealMainLayout::DockArea::setVisible(bool visible, bool showMainSplitter, QWidget* maximizedWidget)
903 foreach (QLayoutItem* item, m_items) {
904 bool itemVisible = visible || item->widget() == maximizedWidget;
905 if (item->widget()->isVisible() != itemVisible)
906 item->widget()->setVisible(itemVisible);
909 if (m_mainSplitter) {
910 bool mainSplitterVisible = (visible && showMainSplitter && !maximizedWidget);
911 if (m_mainSplitter->widget()->isVisible() != mainSplitterVisible)
912 m_mainSplitter->widget()->setVisible(mainSplitterVisible);
915 bool subSplitterVisible = visible && !maximizedWidget;
916 foreach (QWidgetItem* item, m_subSplitters) {
917 if (item->widget()->isVisible() != subSplitterVisible)
918 item->widget()->setVisible(subSplitterVisible);
922 const QList< QWidgetItem * > IdealMainLayout::DockArea::items() const
924 return m_items;
927 QWidgetItem * IdealMainLayout::DockArea::first() const
929 Q_ASSERT(!m_items.isEmpty());
930 return m_items.first();
933 void IdealMainLayout::DockArea::addWidget(QWidget * widget)
935 m_items.append(new QWidgetItem(widget));
936 m_heights.append(-1);
939 void IdealMainLayout::DockArea::removeWidget(QWidget * widget)
941 int index = 0;
942 while (index < m_items.count()) {
943 if (m_items.at(index)->widget() == widget)
944 break;
945 ++index;
948 Q_ASSERT(index < m_items.count());
949 Q_ASSERT(m_heights.count() == m_items.count());
951 QWidgetItem* item = m_items.takeAt(index);
952 item->widget()->hide();
953 delete item;
955 m_heights.removeAt(index);
958 IdealMainLayout::DockArea::~DockArea()
960 removeButtonBar();
961 removeMainSplitter();
962 removeWidgets();
965 void IdealMainLayout::DockArea::removeWidgets()
967 for (int i = m_items.count() - 1; i >= 0; --i)
968 removeWidget(m_items.at(i)->widget());
971 int Sublime::IdealMainLayout::DockArea::count() const
973 int count = 0;
974 if (m_buttonBarItem)
975 ++count;
976 if (m_mainSplitter)
977 ++count;
978 count += m_items.count();
979 count += m_subSplitters.count();
980 return count;
983 QLayoutItem * Sublime::IdealMainLayout::DockArea::itemAt(int index, int& at) const
985 if (m_buttonBarItem)
986 if (index == at)
987 return m_buttonBarItem;
988 else
989 ++at;
991 if (m_mainSplitter)
992 if (index == at)
993 return m_mainSplitter;
994 else
995 ++at;
997 if (index < m_items.count() + at)
998 return m_items.at(index - at);
1000 at += m_items.count();
1001 if (index < m_subSplitters.count())
1002 return m_subSplitters.at(index - at);
1004 return 0;
1007 void Sublime::IdealMainLayout::DockArea::raise()
1009 foreach (QLayoutItem* item, m_items)
1010 item->widget()->raise();
1012 foreach (QLayoutItem* item, m_subSplitters)
1013 item->widget()->raise();
1015 if (m_mainSplitter)
1016 m_mainSplitter->widget()->raise();
1019 Sublime::Position Sublime::IdealMainLayout::positionForRole(Role role)
1021 switch (role)
1023 case Left:
1024 return Sublime::Left;
1025 case Right:
1026 return Sublime::Right;
1027 case Bottom:
1028 return Sublime::Bottom;
1029 case Top:
1030 return Sublime::Top;
1031 default:
1032 case Central:
1033 Q_ASSERT (false && "called with center role");
1034 return Sublime::Left;
1038 QWidgetItem * Sublime::IdealMainLayout::DockArea::buttonBar() const
1040 return m_buttonBarItem;
1043 void Sublime::IdealMainLayout::DockArea::setButtonBar(QWidget * buttonBar)
1045 delete m_buttonBarItem;
1046 m_buttonBarItem = new QWidgetItem(buttonBar);
1049 void Sublime::IdealMainLayout::DockArea::removeButtonBar()
1051 if (m_buttonBarItem) {
1052 delete m_buttonBarItem->widget();
1053 delete m_buttonBarItem;
1054 m_buttonBarItem = 0;
1058 #include "ideallayout.moc"