• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

sublime

ideallayout.cpp

00001 /*
00002   Copyright 2007 Roberto Raggi <roberto@kdevelop.org>
00003   Copyright 2007 Hamish Rodda <rodda@kde.org>
00004   Copyright 2008 Vladimir Prus <ghost@cs.msu.su>
00005 
00006   Permission to use, copy, modify, distribute, and sell this software and its
00007   documentation for any purpose is hereby granted without fee, provided that
00008   the above copyright notice appear in all copies and that both that
00009   copyright notice and this permission notice appear in supporting
00010   documentation.
00011 
00012   The above copyright notice and this permission notice shall be included in
00013   all copies or substantial portions of the Software.
00014 
00015   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00018   KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00019   AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00020   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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     // The code below appears to be completely wrong --
00123     // it will return the maximum size of a single button, not any
00124     // estimate as to how much space is necessary to draw all buttons
00125     // in a minimally acceptable way.
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             /* If we have no items, just use (0, 0) as hint, don't
00184                append any margins.  */
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             // Run out of horizontal space. Try to move button to another
00270             // row.
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     // Uh-oh...??
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     // Uh-oh...??
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                     // TODO: this is not possible with current code
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                     // TODO: this is not possible with current code
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         // FIXME correct?
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"

sublime

Skip menu "sublime"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  •     interfaces
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal