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