00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ideallayout.h"
00024 #include "ideal.h"
00025
00026 #include "kdebug.h"
00027 #include <KConfigGroup>
00028 #include <KGlobal>
00029 #include <KConfig>
00030
00031 using namespace Sublime;
00032
00033 IdealMainLayout::Role Sublime ::roleForArea(Qt::DockWidgetArea area)
00034 {
00035 switch (area) {
00036 case Qt::LeftDockWidgetArea:
00037 return IdealMainLayout::Left;
00038
00039 case Qt::RightDockWidgetArea:
00040 return IdealMainLayout::Right;
00041
00042 case Qt::BottomDockWidgetArea:
00043 return IdealMainLayout::Bottom;
00044
00045 case Qt::TopDockWidgetArea:
00046 return IdealMainLayout::Top;
00047
00048 default:
00049 Q_ASSERT(false);
00050 return IdealMainLayout::Left;
00051 }
00052 }
00053
00054 Qt::DockWidgetArea Sublime ::areaForRole(IdealMainLayout::Role role)
00055 {
00056 switch (role) {
00057 case IdealMainLayout::Left:
00058 return Qt::LeftDockWidgetArea;
00059
00060 case IdealMainLayout::Right:
00061 return Qt::RightDockWidgetArea;
00062
00063 case IdealMainLayout::Bottom:
00064 return Qt::BottomDockWidgetArea;
00065
00066 case IdealMainLayout::Top:
00067 return Qt::TopDockWidgetArea;
00068
00069 default:
00070 Q_ASSERT(false);
00071 return Qt::LeftDockWidgetArea;
00072 }
00073 }
00074
00075 IdealButtonBarLayout::IdealButtonBarLayout(Qt::Orientation orientation, QWidget *parent)
00076 : QLayout(parent)
00077 , _orientation(orientation)
00078 , _height(0)
00079
00080 {
00081 if (orientation == Qt::Vertical)
00082 setContentsMargins(2, 0, 2, 0);
00083 else
00084 setContentsMargins(0, 2, 0, 0);
00085 setSpacing(2);
00086 invalidate();
00087 }
00088
00089 void IdealButtonBarLayout::invalidate()
00090 {
00091 m_minSizeDirty = true;
00092 m_sizeHintDirty = true;
00093 m_layoutDirty = true;
00094 QLayout::invalidate();
00095 }
00096
00097 IdealButtonBarLayout::~IdealButtonBarLayout()
00098 {
00099 qDeleteAll(_items);
00100 }
00101
00102 void IdealButtonBarLayout::setHeight(int height)
00103 {
00104 Q_ASSERT(orientation() == Qt::Vertical);
00105 _height = height;
00106
00107 (void) invalidate();
00108 }
00109
00110 Qt::Orientation IdealButtonBarLayout::orientation() const
00111 {
00112 return _orientation;
00113 }
00114
00115 Qt::Orientations IdealButtonBarLayout::expandingDirections() const
00116 {
00117 return orientation();
00118 }
00119
00120 QSize IdealButtonBarLayout::minimumSize() const
00121 {
00122
00123
00124
00125
00126 if (m_minSizeDirty) {
00127 if (orientation() == Qt::Vertical) {
00128 const int width = doVerticalLayout(QRect(0, 0, 0, _height), false);
00129 return QSize(width, 0);
00130 }
00131
00132 m_min = QSize(0, 0);
00133 foreach (QLayoutItem *item, _items)
00134 m_min = m_min.expandedTo(item->minimumSize());
00135
00136 m_minSizeDirty = false;
00137 }
00138 return m_min;
00139 }
00140
00141 QSize IdealButtonBarLayout::sizeHint() const
00142 {
00143 if (m_sizeHintDirty) {
00144 int orientationSize = 0;
00145 int crossSize = 0;
00146
00147 bool first = true;
00148 foreach (QLayoutItem *item, _items)
00149 {
00150 QSize hint = item->sizeHint();
00151 int orientationSizeHere;
00152 int crossSizeHere;
00153 if (orientation() == Qt::Vertical)
00154 {
00155 orientationSizeHere = hint.height();
00156 crossSizeHere = hint.width();
00157 }
00158 else
00159 {
00160 orientationSizeHere = hint.width();
00161 crossSizeHere = hint.height();
00162 }
00163
00164 if (first)
00165 {
00166 crossSize = crossSizeHere;
00167 }
00168 else
00169 {
00170 orientationSize += spacing();
00171 }
00172 orientationSize += orientationSizeHere;
00173 first = false;
00174 }
00175
00176 if (orientation() == Qt::Vertical)
00177 m_hint = QSize(crossSize, orientationSize);
00178 else
00179 m_hint = QSize(orientationSize, crossSize);
00180
00181 if (!_items.empty())
00182 {
00183
00184
00185 int l, t, r, b;
00186 getContentsMargins(&l, &t, &r, &b);
00187 m_hint += QSize(l+r, t+b);
00188 }
00189
00190 m_sizeHintDirty = false;
00191 }
00192 return m_hint;
00193 }
00194
00195 void IdealButtonBarLayout::setGeometry(const QRect &rect)
00196 {
00197 if (m_layoutDirty || rect != geometry())
00198 if (orientation() == Qt::Vertical)
00199 doVerticalLayout(rect);
00200 else
00201 doHorizontalLayout(rect);
00202 }
00203
00204 void IdealButtonBarLayout::addItem(QLayoutItem *item)
00205 {
00206 _items.append(item);
00207 }
00208
00209 QLayoutItem* IdealButtonBarLayout::itemAt(int index) const
00210 {
00211 return _items.value(index, 0);
00212 }
00213
00214 QLayoutItem* IdealButtonBarLayout::takeAt(int index)
00215 {
00216 if (index >= 0 && index < _items.count())
00217 return _items.takeAt(index);
00218 return 0;
00219 }
00220
00221 int IdealButtonBarLayout::count() const
00222 {
00223 return _items.count();
00224 }
00225
00226 int IdealButtonBarLayout::doVerticalLayout(const QRect &rect, bool updateGeometry) const
00227 {
00228 int l, t, r, b;
00229 getContentsMargins(&l, &t, &r, &b);
00230 int x = rect.x() + l;
00231 int y = rect.y() + t;
00232 int currentLineWidth = 0;
00233
00234 foreach (QLayoutItem *item, _items) {
00235 const QSize itemSizeHint = item->sizeHint();
00236 if (y + itemSizeHint.height() + b > rect.height()) {
00237 int newX = x + currentLineWidth + spacing();
00238 if (newX + itemSizeHint.width() + r <= rect.width())
00239 {
00240 x += currentLineWidth + spacing();
00241 y = rect.y() + t;
00242 }
00243 }
00244
00245 if (updateGeometry)
00246 item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHint.height()));
00247
00248 currentLineWidth = qMax(currentLineWidth, itemSizeHint.width());
00249
00250 y += itemSizeHint.height() + spacing();
00251 }
00252
00253 m_layoutDirty = updateGeometry;
00254
00255 return x + currentLineWidth + r;
00256 }
00257
00258 int IdealButtonBarLayout::doHorizontalLayout(const QRect &rect, bool updateGeometry) const
00259 {
00260 int l, t, r, b;
00261 getContentsMargins(&l, &t, &r, &b);
00262 int x = rect.x() + l;
00263 int y = rect.y() + t;
00264 int currentLineHeight = 0;
00265
00266 foreach (QLayoutItem *item, _items) {
00267 QSize itemSizeHint = item->sizeHint();
00268 if (x + itemSizeHint.width() + r > rect.width()) {
00269
00270
00271 int newY = y + currentLineHeight + spacing();
00272 if (newY + itemSizeHint.height() + b <= rect.height())
00273 {
00274 y = newY;
00275 x = rect.x() + l;
00276 currentLineHeight = 0;
00277 }
00278 }
00279
00280 if (updateGeometry)
00281 item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHint.height()));
00282
00283 currentLineHeight = qMax(currentLineHeight, itemSizeHint.height());
00284
00285 x += itemSizeHint.width() + spacing();
00286 }
00287
00288 m_layoutDirty = updateGeometry;
00289
00290 return y + currentLineHeight + b;
00291 }
00292
00293 IdealDockWidget* IdealMainLayout::lastDockWidget() const
00294 {
00295 return qobject_cast<IdealDockWidget*>(m_lastDockWidget);
00296 }
00297
00298 IdealDockWidget * IdealMainLayout::lastDockWidget(IdealMainLayout::Role role) const
00299 {
00300 return qobject_cast<IdealDockWidget*>(m_items[role]->last);
00301 }
00302
00303 IdealMainLayout::IdealMainLayout(QWidget * parent)
00304 : QLayout(parent)
00305 , m_layoutDirty(true)
00306 , m_minDirty(true)
00307 , m_lastDockWidgetRole(Left)
00308 , m_topOwnsTopLeft(0)
00309 , m_topOwnsTopRight(0)
00310 , m_bottomOwnsBottomLeft(0)
00311 , m_bottomOwnsBottomRight(0)
00312 , m_maximizedWidget(0)
00313 {
00314 createArea(Left);
00315 createArea(Right);
00316 createArea(Top);
00317 createArea(Bottom);
00318 createArea(Central);
00319
00320 setMargin(0);
00321 m_splitterWidth = parent->style()->pixelMetric(QStyle::PM_SplitterWidth, 0, parentWidget());
00322
00323 loadSettings();
00324
00325 anchorWidget(true, Left);
00326 anchorWidget(true, Right);
00327 anchorWidget(true, Top);
00328 anchorWidget(true, Bottom);
00329 }
00330
00331 IdealMainLayout::~ IdealMainLayout()
00332 {
00333 }
00334
00335 QSize IdealMainLayout::minimumSize() const
00336 {
00337 if (m_minDirty) {
00338 if (m_maximizedWidget) {
00339 m_min = m_maximizedWidget->minimumSize();
00340 m_minDirty = false;
00341 return m_min;
00342 }
00343
00344 int minHeight = 0;
00345 int softMinHeight = 0;
00346 int minWidth = 0;
00347 int softMinWidth = 0;
00348
00349 minimumSize(Left, minWidth, softMinWidth, minHeight, softMinHeight);
00350 minimumSize(Right, minWidth, softMinWidth, minHeight, softMinHeight);
00351 minimumSize(Top, minWidth, softMinWidth, minHeight, softMinHeight);
00352 minimumSize(Bottom, minWidth, softMinWidth, minHeight, softMinHeight);
00353
00354 if (QLayoutItem* item = m_items[Central]->first()) {
00355 const QSize itemSizeHint = item->minimumSize();
00356 minHeight += qMax(softMinHeight, itemSizeHint.height() + splitterWidth());
00357 minWidth += qMax(softMinWidth, itemSizeHint.width() + splitterWidth());
00358 }
00359
00360 m_min = QSize(minHeight, minWidth);
00361 m_minDirty = true;
00362 }
00363
00364 return m_min;
00365 }
00366
00367 void IdealMainLayout::minimumSize(Role role, int& minWidth, int& softMinWidth, int& minHeight, int& softMinHeight) const
00368 {
00369 foreach (QLayoutItem* item, m_items[role]->items()) {
00370 const QSize itemSizeHint = item->minimumSize();
00371 switch (role) {
00372 case Left:
00373 case Right:
00374 if (m_items[role]->anchored)
00375 minWidth += itemSizeHint.width() + splitterWidth();
00376 softMinHeight = qMax(softMinHeight, itemSizeHint.height() + splitterWidth());
00377 break;
00378
00379 case Top:
00380 case Bottom:
00381 if (m_items[role]->anchored)
00382 minHeight += itemSizeHint.height() + splitterWidth();
00383 softMinWidth = qMax(softMinWidth, itemSizeHint.width() + splitterWidth());
00384 break;
00385
00386 default:
00387 break;
00388 }
00389 }
00390 }
00391
00392 QLayoutItem * IdealMainLayout::itemAt(int index) const
00393 {
00394 int at = 0;
00395 if (QLayoutItem* item = m_items[Left]->itemAt(index, at))
00396 return item;
00397
00398 index -= at;
00399 at = 0;
00400 if (QLayoutItem* item = m_items[Right]->itemAt(index, at))
00401 return item;
00402
00403 index -= at;
00404 at = 0;
00405 if (QLayoutItem* item = m_items[Top]->itemAt(index, at))
00406 return item;
00407
00408 index -= at;
00409 at = 0;
00410 if (QLayoutItem* item = m_items[Bottom]->itemAt(index, at))
00411 return item;
00412
00413 index -= at;
00414 at = 0;
00415 if (QLayoutItem* item = m_items[Central]->itemAt(index, at))
00416 return item;
00417
00418 return 0;
00419 }
00420
00421 void IdealMainLayout::addItem(QLayoutItem * item)
00422 {
00423 Q_UNUSED(item)
00424
00425
00426 Q_ASSERT(false);
00427 }
00428
00429 void IdealMainLayout::setGeometry(const QRect & rect)
00430 {
00431 if (m_layoutDirty || rect != geometry()) {
00432 QLayout::setGeometry(rect);
00433 doLayout(rect);
00434 }
00435 }
00436
00437 QSize IdealMainLayout::sizeHint() const
00438 {
00439 return QSize();
00440 }
00441
00442 QLayoutItem * IdealMainLayout::takeAt(int index)
00443 {
00444 Q_UNUSED(index)
00445
00446
00447 Q_ASSERT(false);
00448
00449 return 0;
00450 }
00451
00452 int IdealMainLayout::count() const
00453 {
00454 return m_items[Left]->count() + m_items[Right]->count()
00455 + m_items[Top]->count() + m_items[Bottom]->count() + m_items[Central]->count();
00456 }
00457
00458 void IdealMainLayout::doLayout(QRect rect) const
00459 {
00460 if (m_maximizedWidget) {
00461 m_maximizedWidget->setGeometry(rect);
00462 return;
00463 }
00464
00465 if (m_topOwnsTopLeft)
00466 if (m_topOwnsTopRight)
00467 if (m_bottomOwnsBottomLeft)
00468 if (m_bottomOwnsBottomRight)
00469 layout(Top, Bottom, Left, Right, rect);
00470 else
00471 layout(Top, Right, Bottom, Left, rect);
00472 else
00473 if (m_bottomOwnsBottomRight)
00474 layout(Top, Left, Bottom, Right, rect);
00475 else
00476 layout(Top, Right, Left, Bottom, rect);
00477 else
00478 if (m_bottomOwnsBottomLeft)
00479 if (m_bottomOwnsBottomRight)
00480 layout(Bottom, Right, Top, Left, rect);
00481 else
00482 layout(Right, Top, Left, Bottom, rect);
00483 else
00484 if (m_bottomOwnsBottomRight)
00485
00486 layout(Top, Left, Bottom, Right, rect);
00487 else
00488 layout(Right, Top, Left, Bottom, rect);
00489 else
00490 if (m_topOwnsTopRight)
00491 if (m_bottomOwnsBottomLeft)
00492 if (m_bottomOwnsBottomRight)
00493 layout(Bottom, Left, Top, Right, rect);
00494 else
00495 layout(Left, Top, Right, Bottom, rect);
00496 else
00497 if (m_bottomOwnsBottomRight)
00498 layout(Left, Bottom, Top, Right, rect);
00499 else
00500 layout(Right, Left, Bottom, Top, rect);
00501 else
00502 if (m_bottomOwnsBottomLeft)
00503 if (m_bottomOwnsBottomRight)
00504 layout(Bottom, Right, Left, Top, rect);
00505 else
00506 layout(Right, Bottom, Left, Top, rect);
00507 else
00508 if (m_bottomOwnsBottomRight)
00509
00510 layout(Left, Bottom, Right, Top, rect);
00511 else
00512 layout(Right, Left, Bottom, Top, rect);
00513
00514
00515 if (QLayoutItem* item = m_items[Central]->first()) {
00516 QSize itemSizeHint = item->sizeHint();
00517 if (itemSizeHint.height() > rect.height()) {
00518 itemSizeHint.setHeight(qMax(item->minimumSize().height(), rect.height()));
00519
00520 if (itemSizeHint.height() > rect.height())
00521 rect.setHeight(itemSizeHint.height());
00522 }
00523
00524 if (itemSizeHint.width() > rect.width()) {
00525 itemSizeHint.setWidth(qMax(item->minimumSize().width(), rect.width()));
00526
00527 if (itemSizeHint.width() > rect.width())
00528 rect.setWidth(itemSizeHint.width());
00529 }
00530
00531 item->setGeometry(rect);
00532 }
00533
00534 m_layoutDirty = false;
00535 }
00536
00537 void IdealMainLayout::layout(Role role1, Role role2, Role role3, Role role4, QRect & rect) const
00538 {
00539 layoutItem(role1, rect);
00540 layoutItem(role2, rect);
00541 layoutItem(role3, rect);
00542 layoutItem(role4, rect);
00543 }
00544
00545 void IdealMainLayout::layoutItem(Role role, QRect& rect) const
00546 {
00547 DockArea* area = m_items[role];
00548
00549 QWidgetItem* buttonBar = area->buttonBar();
00550 if (buttonBar)
00551 {
00552 const QSize hint = buttonBar->sizeHint();
00553 QRect geometry = rect;
00554 if (role == Left) {
00555 geometry.setWidth(hint.width());
00556 rect.setLeft(hint.width());
00557 }
00558 else if (role == Bottom) {
00559 int y = rect.height() - hint.height();
00560 geometry.setTop(geometry.y() + y);
00561 rect.setBottom(y);
00562 }
00563 else if (role == Right) {
00564 int x = rect.width() - hint.width();
00565 geometry.setLeft(geometry.x() + x);
00566 rect.setWidth(x);
00567 }
00568 else if (role == Top) {
00569 geometry.setHeight(hint.height());
00570 rect.setTop(hint.height());
00571 }
00572
00573 buttonBar->setGeometry(geometry);
00574 }
00575
00576 foreach (QLayoutItem* item, area->items()) {
00577 int hintDimension = 0;
00578 if (m_items[role]->width != -1) {
00579 hintDimension = m_items[role]->width;
00580
00581 } else {
00582 const QSize itemSize = item->sizeHint();
00583 switch (role) {
00584 case Left:
00585 case Right:
00586 hintDimension = itemSize.width() + splitterWidth();
00587 if (hintDimension + splitterWidth() > rect.width()) {
00588 hintDimension = item->minimumSize().width();
00589
00590 if (hintDimension + splitterWidth() > rect.width())
00591 rect.setWidth(hintDimension + splitterWidth());
00592 }
00593 break;
00594
00595 case Top:
00596 case Bottom:
00597 hintDimension = itemSize.height();
00598 if (hintDimension + splitterWidth() > rect.height()) {
00599 hintDimension = item->minimumSize().height();
00600
00601 if (hintDimension + splitterWidth() > rect.height())
00602 rect.setHeight(hintDimension + splitterWidth());
00603 }
00604 break;
00605
00606 default:
00607 break;
00608 }
00609 }
00610
00611 switch (role) {
00612 case Left:
00613 item->setGeometry(QRect(rect.x(), rect.y(), hintDimension, rect.height()));
00614 area->mainSplitter()->setGeometry(QRect(rect.x() + hintDimension, rect.y(), splitterWidth(), rect.height()));
00615 break;
00616
00617 case Right:
00618 item->setGeometry(QRect(rect.x() + rect.width() - hintDimension, rect.y(), hintDimension, rect.height()));
00619 area->mainSplitter()->setGeometry(QRect(rect.x() + rect.width() - hintDimension - splitterWidth(), rect.y(), splitterWidth(), rect.height()));
00620 break;
00621
00622 case Top:
00623 item->setGeometry(QRect(rect.x(), rect.y(), rect.width(), hintDimension));
00624 area->mainSplitter()->setGeometry(QRect(rect.x(), rect.y() + hintDimension, rect.width(), splitterWidth()));
00625 break;
00626
00627 case Bottom:
00628 item->setGeometry(QRect(rect.x(), rect.y() + rect.height() - hintDimension, rect.width(), hintDimension));
00629 area->mainSplitter()->setGeometry(QRect(rect.x(), rect.y() + rect.height() - hintDimension - splitterWidth(), rect.width(), splitterWidth()));
00630 break;
00631
00632 default:
00633 break;
00634 }
00635
00636 if (m_items[role]->anchored) {
00637 switch (role) {
00638 case Left:
00639 rect.setX(rect.x() + hintDimension + splitterWidth());
00640 break;
00641
00642 case Right:
00643 rect.setWidth(rect.width() - hintDimension - splitterWidth());
00644 break;
00645
00646 case Top:
00647 rect.setY(rect.y() + hintDimension + splitterWidth());
00648 break;
00649
00650 case Bottom:
00651 rect.setHeight(rect.height() - hintDimension - splitterWidth());
00652 break;
00653
00654 default:
00655 break;
00656 }
00657 }
00658 }
00659 }
00660
00661 IdealSplitterHandle* IdealMainLayout::createSplitter(Role role, bool reverse)
00662 {
00663 IdealSplitterHandle* splitter = 0;
00664
00665 Qt::Orientation direction = ((role == Left || role == Right) ^ reverse)
00666 ? Qt::Vertical
00667 : Qt::Horizontal;
00668
00669 splitter = new IdealSplitterHandle(direction, parentWidget(), role);
00670 addChildWidget(splitter);
00671
00672 connect(splitter, SIGNAL(resize(int, IdealMainLayout::Role)),
00673 SLOT(resizeWidget(int, IdealMainLayout::Role)));
00674
00675 splitter->hide();
00676 return splitter;
00677 }
00678
00679 void IdealMainLayout::createArea(Role role)
00680 {
00681 DockArea* area = new DockArea(this, role);
00682 m_items.insert(role, area);
00683
00684 if (role != Central)
00685 area->setMainSplitter(createSplitter(role));
00686 }
00687
00688 void IdealMainLayout::addWidget(QWidget * widget, Role role)
00689 {
00690 if (m_maximizedWidget)
00691 maximizeWidget(0);
00692
00693 if (IdealDockWidget* dock = qobject_cast<IdealDockWidget*>(widget))
00694 if (dock->isFloating())
00695 dock->setFloating(false);
00696
00697 if (widget->parent() != parentWidget()) {
00698 widget->setParent(parentWidget());
00699 addChildWidget(widget);
00700 }
00701
00702 DockArea* area = m_items[role];
00703
00704 area->addWidget(widget);
00705
00706 area->setVisible(true, !m_maximizedWidget);
00707
00708 if (role != Central) {
00709 m_lastDockWidget = widget;
00710 m_lastDockWidgetRole = role;
00711 m_items[role]->last = widget;
00712 mainWidget()->setAnchorActionStatus(isAreaAnchored(role));
00713 }
00714
00715 area->raise();
00716 widget->setFocus();
00717 }
00718
00719 void IdealMainLayout::addButtonBar(QWidget* widget, Role role)
00720 {
00721 DockArea* area = m_items[role];
00722 area->setButtonBar(widget);
00723 addChildWidget(widget);
00724 }
00725
00726 void IdealMainLayout::removeWidgets(Role role)
00727 {
00728 if (m_maximizedWidget)
00729
00730 maximizeWidget(0);
00731
00732 DockArea* area = m_items[role];
00733 area->setVisible(false);
00734 }
00735
00736 void IdealMainLayout::removeWidget(QWidget * widget, Role role)
00737 {
00738 DockArea* area = m_items[role];
00739 area->removeWidget(widget);
00740 if (area->items().isEmpty())
00741 area->setVisible(false, false);
00742 }
00743
00744 void IdealMainLayout::removeUnanchored()
00745 {
00746 if (!m_items[Left]->anchored)
00747 removeWidgets(Left);
00748
00749 if (!m_items[Right]->anchored)
00750 removeWidgets(Right);
00751
00752 if (!m_items[Top]->anchored)
00753 removeWidgets(Top);
00754
00755 if (!m_items[Bottom]->anchored)
00756 removeWidgets(Bottom);
00757 }
00758
00759 void IdealMainLayout::invalidate()
00760 {
00761 m_layoutDirty = true;
00762 m_minDirty = true;
00763 QLayout::invalidate();
00764 }
00765
00766 int IdealMainLayout::splitterWidth() const
00767 {
00768 return m_splitterWidth;
00769 }
00770
00771 void IdealMainLayout::resizeWidget(int thickness, IdealMainLayout::Role role)
00772 {
00773 int offset = 0;
00774
00775 if (QWidgetItem* bar = m_items[role]->buttonBar())
00776 if (role == Left || role == Right)
00777 offset = bar->geometry().width();
00778 else
00779 offset = bar->geometry().height();
00780
00781 m_items[role]->width = thickness - offset;
00782
00783 invalidate();
00784
00785 emit widgetResized(role, thickness);
00786 }
00787
00788 void IdealMainLayout::anchorWidget(bool anchor, IdealMainLayout::Role role)
00789 {
00790 m_items[role]->anchored = anchor;
00791
00792 invalidate();
00793 }
00794
00795 void IdealMainLayout::maximizeWidget(QWidget* widget)
00796 {
00797 m_maximizedWidget = widget;
00798
00799 if (m_maximizedWidget) {
00800 for (Role role = Left; role <= Central; role = static_cast<Role>(role + 1))
00801 m_items[role]->setVisible(false, false, m_maximizedWidget);
00802
00803 } else {
00804 for (Role role = Left; role <= Central; role = static_cast<Role>(role + 1))
00805 if (!m_items[role]->items().isEmpty())
00806 m_items[role]->setVisible(true, role != Central, m_maximizedWidget);
00807 }
00808
00809 invalidate();
00810 }
00811
00812 int IdealMainLayout::widthForRole(Role role) const
00813 {
00814 return m_items[role]->width;
00815 }
00816
00817 void IdealMainLayout::setWidthForRole(Role role, int width)
00818 {
00819 m_items[role]->width = width;
00820 invalidate();
00821 }
00822
00823 bool IdealMainLayout::isAreaAnchored(Role role) const
00824 {
00825 return m_items[role]->anchored;
00826 }
00827
00828 IdealMainWidget * IdealMainLayout::mainWidget() const
00829 {
00830 return dynamic_cast<IdealMainWidget*>(parentWidget());
00831 }
00832
00833 void IdealMainLayout::loadSettings()
00834 {
00835 KConfigGroup cg(KGlobal::config(), "UiSettings");
00836
00837 bool invalid = false;
00838
00839 int topOwnsTopLeft = cg.readEntry("TopLeftCornerOwner", 0);
00840 if (m_topOwnsTopLeft != topOwnsTopLeft) {
00841 m_topOwnsTopLeft = topOwnsTopLeft;
00842 invalid = true;
00843 }
00844
00845 int topOwnsTopRight = cg.readEntry("TopRightCornerOwner", 0);
00846 if (m_topOwnsTopRight != topOwnsTopRight) {
00847 m_topOwnsTopRight = topOwnsTopRight;
00848 invalid = true;
00849 }
00850
00851 int bottomOwnsBottomLeft = cg.readEntry("BottomLeftCornerOwner", 0);
00852 if (m_bottomOwnsBottomLeft != bottomOwnsBottomLeft) {
00853 m_bottomOwnsBottomLeft = bottomOwnsBottomLeft;
00854 invalid = true;
00855 }
00856
00857 int bottomOwnsBottomRight = cg.readEntry("BottomRightCornerOwner", 0);
00858 if (m_bottomOwnsBottomRight != bottomOwnsBottomRight) {
00859 m_bottomOwnsBottomRight = bottomOwnsBottomRight;
00860 invalid = true;
00861 }
00862
00863 if (invalid)
00864 invalidate();
00865 }
00866
00867 IdealMainLayout::Role IdealMainLayout::lastDockWidgetRole() const
00868 {
00869 return m_lastDockWidgetRole;
00870 }
00871
00872 QWidgetItem * IdealMainLayout::DockArea::mainSplitter() const
00873 {
00874 return m_mainSplitter;
00875 }
00876
00877 void IdealMainLayout::DockArea::setMainSplitter(QWidget* widget)
00878 {
00879 m_mainSplitter = new QWidgetItem(widget);
00880 }
00881
00882 IdealMainLayout::DockArea::DockArea(IdealMainLayout* layout, Role role)
00883 : width(250)
00884 , anchored(false)
00885 , m_layout(layout)
00886 , m_role(role)
00887 , m_mainSplitter(0)
00888 , m_buttonBarItem(0)
00889 {
00890 }
00891
00892 void IdealMainLayout::DockArea::removeMainSplitter()
00893 {
00894 if (m_mainSplitter) {
00895 delete m_mainSplitter->widget();
00896 delete m_mainSplitter;
00897 m_mainSplitter = 0;
00898 }
00899 }
00900
00901 void IdealMainLayout::DockArea::setVisible(bool visible, bool showMainSplitter, QWidget* maximizedWidget)
00902 {
00903 foreach (QLayoutItem* item, m_items) {
00904 bool itemVisible = visible || item->widget() == maximizedWidget;
00905 if (item->widget()->isVisible() != itemVisible)
00906 item->widget()->setVisible(itemVisible);
00907 }
00908
00909 if (m_mainSplitter) {
00910 bool mainSplitterVisible = (visible && showMainSplitter && !maximizedWidget);
00911 if (m_mainSplitter->widget()->isVisible() != mainSplitterVisible)
00912 m_mainSplitter->widget()->setVisible(mainSplitterVisible);
00913 }
00914
00915 bool subSplitterVisible = visible && !maximizedWidget;
00916 foreach (QWidgetItem* item, m_subSplitters) {
00917 if (item->widget()->isVisible() != subSplitterVisible)
00918 item->widget()->setVisible(subSplitterVisible);
00919 }
00920 }
00921
00922 const QList< QWidgetItem * > IdealMainLayout::DockArea::items() const
00923 {
00924 return m_items;
00925 }
00926
00927 QWidgetItem * IdealMainLayout::DockArea::first() const
00928 {
00929 Q_ASSERT(!m_items.isEmpty());
00930 return m_items.first();
00931 }
00932
00933 void IdealMainLayout::DockArea::addWidget(QWidget * widget)
00934 {
00935 m_items.append(new QWidgetItem(widget));
00936 m_heights.append(-1);
00937 }
00938
00939 void IdealMainLayout::DockArea::removeWidget(QWidget * widget)
00940 {
00941 int index = 0;
00942 while (index < m_items.count()) {
00943 if (m_items.at(index)->widget() == widget)
00944 break;
00945 ++index;
00946 }
00947
00948 Q_ASSERT(index < m_items.count());
00949 Q_ASSERT(m_heights.count() == m_items.count());
00950
00951 QWidgetItem* item = m_items.takeAt(index);
00952 item->widget()->hide();
00953 delete item;
00954
00955 m_heights.removeAt(index);
00956 }
00957
00958 IdealMainLayout::DockArea::~DockArea()
00959 {
00960 removeButtonBar();
00961 removeMainSplitter();
00962 removeWidgets();
00963 }
00964
00965 void IdealMainLayout::DockArea::removeWidgets()
00966 {
00967 for (int i = m_items.count() - 1; i >= 0; --i)
00968 removeWidget(m_items.at(i)->widget());
00969 }
00970
00971 int Sublime::IdealMainLayout::DockArea::count() const
00972 {
00973 int count = 0;
00974 if (m_buttonBarItem)
00975 ++count;
00976 if (m_mainSplitter)
00977 ++count;
00978 count += m_items.count();
00979 count += m_subSplitters.count();
00980 return count;
00981 }
00982
00983 QLayoutItem * Sublime::IdealMainLayout::DockArea::itemAt(int index, int& at) const
00984 {
00985 if (m_buttonBarItem)
00986 if (index == at)
00987 return m_buttonBarItem;
00988 else
00989 ++at;
00990
00991 if (m_mainSplitter)
00992 if (index == at)
00993 return m_mainSplitter;
00994 else
00995 ++at;
00996
00997 if (index < m_items.count() + at)
00998 return m_items.at(index - at);
00999
01000 at += m_items.count();
01001 if (index < m_subSplitters.count())
01002 return m_subSplitters.at(index - at);
01003
01004 return 0;
01005 }
01006
01007 void Sublime::IdealMainLayout::DockArea::raise()
01008 {
01009 foreach (QLayoutItem* item, m_items)
01010 item->widget()->raise();
01011
01012 foreach (QLayoutItem* item, m_subSplitters)
01013 item->widget()->raise();
01014
01015 if (m_mainSplitter)
01016 m_mainSplitter->widget()->raise();
01017 }
01018
01019 Sublime::Position Sublime::IdealMainLayout::positionForRole(Role role)
01020 {
01021 switch (role)
01022 {
01023 case Left:
01024 return Sublime::Left;
01025 case Right:
01026 return Sublime::Right;
01027 case Bottom:
01028 return Sublime::Bottom;
01029 case Top:
01030 return Sublime::Top;
01031 default:
01032 case Central:
01033 Q_ASSERT (false && "called with center role");
01034 return Sublime::Left;
01035 }
01036 }
01037
01038 QWidgetItem * Sublime::IdealMainLayout::DockArea::buttonBar() const
01039 {
01040 return m_buttonBarItem;
01041 }
01042
01043 void Sublime::IdealMainLayout::DockArea::setButtonBar(QWidget * buttonBar)
01044 {
01045 delete m_buttonBarItem;
01046 m_buttonBarItem = new QWidgetItem(buttonBar);
01047 }
01048
01049 void Sublime::IdealMainLayout::DockArea::removeButtonBar()
01050 {
01051 if (m_buttonBarItem) {
01052 delete m_buttonBarItem->widget();
01053 delete m_buttonBarItem;
01054 m_buttonBarItem = 0;
01055 }
01056 }
01057
01058 #include "ideallayout.moc"