diff options
Diffstat (limited to 'src/gui/widgets/qmainwindowlayout.cpp')
-rw-r--r-- | src/gui/widgets/qmainwindowlayout.cpp | 2017 |
1 files changed, 0 insertions, 2017 deletions
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp deleted file mode 100644 index d4afe075be..0000000000 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ /dev/null @@ -1,2017 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmainwindowlayout_p.h" -#include "qdockarealayout_p.h" - -#ifndef QT_NO_MAINWINDOW -#include "qdockwidget.h" -#include "qdockwidget_p.h" -#include "qtoolbar_p.h" -#include "qmainwindow.h" -#include "qmainwindowlayout_p.h" -#include "qtoolbar.h" -#include "qtoolbarlayout_p.h" -#include "qwidgetanimator_p.h" -#include "qrubberband.h" -#include "qdockwidget_p.h" -#include "qtabbar_p.h" - -#include <qapplication.h> -#include <qstatusbar.h> -#include <qstring.h> -#include <qstyle.h> -#include <qvarlengtharray.h> -#include <qstack.h> -#include <qmap.h> -#include <qtimer.h> - -#include <qdebug.h> - -#include <private/qapplication_p.h> -#include <private/qlayoutengine_p.h> -#ifdef Q_WS_MAC -# include <private/qcore_mac_p.h> -# include <private/qt_cocoa_helpers_mac_p.h> -#endif - -#ifdef QT_NO_DOCKWIDGET -extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); -#endif - -#ifdef Q_DEBUG_MAINWINDOW_LAYOUT -# include <QTextStream> -#endif - -QT_BEGIN_NAMESPACE - -/****************************************************************************** -** debug -*/ - -#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET) - -static QTextStream qout(stderr, QIODevice::WriteOnly); - -static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QString indent); - -static void dumpLayout(QTextStream &qout, const QDockAreaLayoutItem &item, QString indent) -{ - qout << indent << "QDockAreaLayoutItem: " - << "pos: " << item.pos << " size:" << item.size - << " gap:" << (item.flags & QDockAreaLayoutItem::GapItem) - << " keepSize:" << (item.flags & QDockAreaLayoutItem::KeepSize) << '\n'; - indent += QLatin1String(" "); - if (item.widgetItem != 0) { - qout << indent << "widget: " - << item.widgetItem->widget()->metaObject()->className() - << ' ' << item.widgetItem->widget()->windowTitle() << '\n'; - } else if (item.subinfo != 0) { - qout << indent << "subinfo:\n"; - dumpLayout(qout, *item.subinfo, indent + QLatin1String(" ")); - } else if (item.placeHolderItem != 0) { - QRect r = item.placeHolderItem->topLevelRect; - qout << indent << "placeHolder: " - << "pos: " << item.pos << " size:" << item.size - << " gap:" << (item.flags & QDockAreaLayoutItem::GapItem) - << " keepSize:" << (item.flags & QDockAreaLayoutItem::KeepSize) - << " objectName:" << item.placeHolderItem->objectName - << " hidden:" << item.placeHolderItem->hidden - << " window:" << item.placeHolderItem->window - << " rect:" << r.x() << ',' << r.y() << ' ' - << r.width() << 'x' << r.height() << '\n'; - } - qout.flush(); -} - -static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QString indent) -{ - qout << indent << "QDockAreaLayoutInfo: " - << layout.rect.left() << ',' - << layout.rect.top() << ' ' - << layout.rect.width() << 'x' - << layout.rect.height() - << " orient:" << layout.o - << " tabbed:" << layout.tabbed - << " tbshape:" << layout.tabBarShape << '\n'; - - indent += QLatin1String(" "); - - for (int i = 0; i < layout.item_list.count(); ++i) { - qout << indent << "Item: " << i << '\n'; - dumpLayout(qout, layout.item_list.at(i), indent + QLatin1String(" ")); - } - qout.flush(); -}; - -static void dumpLayout(QTextStream &qout, const QDockAreaLayout &layout, QString indent) -{ - qout << indent << "QDockAreaLayout: " - << layout.rect.left() << ',' - << layout.rect.top() << ' ' - << layout.rect.width() << 'x' - << layout.rect.height() << '\n'; - - qout << indent << "TopDockArea:\n"; - dumpLayout(qout, layout.docks[QInternal::TopDock], indent + QLatin1String(" ")); - qout << indent << "LeftDockArea:\n"; - dumpLayout(qout, layout.docks[QInternal::LeftDock], indent + QLatin1String(" ")); - qout << indent << "RightDockArea:\n"; - dumpLayout(qout, layout.docks[QInternal::RightDock], indent + QLatin1String(" ")); - qout << indent << "BottomDockArea:\n"; - dumpLayout(qout, layout.docks[QInternal::BottomDock], indent + QLatin1String(" ")); - - qout.flush(); -}; - -void qt_dumpLayout(QTextStream &qout, QMainWindow *window) -{ - QMainWindowLayout *layout = qt_mainwindow_layout(window); - dumpLayout(qout, layout->layoutState.dockAreaLayout, QString()); -} - -#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET - -/****************************************************************************** -** QMainWindowLayoutState -*/ - -// we deal with all the #ifndefferry here so QMainWindowLayout code is clean - -QMainWindowLayoutState::QMainWindowLayoutState(QMainWindow *win) - : -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout(win), -#endif -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout(win) -#else - centralWidgetItem(0) -#endif - -{ - mainWindow = win; -} - -QSize QMainWindowLayoutState::sizeHint() const -{ - - QSize result(0, 0); - -#ifndef QT_NO_DOCKWIDGET - result = dockAreaLayout.sizeHint(); -#else - if (centralWidgetItem != 0) - result = centralWidgetItem->sizeHint(); -#endif - -#ifndef QT_NO_TOOLBAR - result = toolBarAreaLayout.sizeHint(result); -#endif // QT_NO_TOOLBAR - - return result; -} - -QSize QMainWindowLayoutState::minimumSize() const -{ - QSize result(0, 0); - -#ifndef QT_NO_DOCKWIDGET - result = dockAreaLayout.minimumSize(); -#else - if (centralWidgetItem != 0) - result = centralWidgetItem->minimumSize(); -#endif - -#ifndef QT_NO_TOOLBAR - result = toolBarAreaLayout.minimumSize(result); -#endif // QT_NO_TOOLBAR - - return result; -} - -void QMainWindowLayoutState::apply(bool animated) -{ -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout.apply(animated); -#endif - -#ifndef QT_NO_DOCKWIDGET -// dumpLayout(dockAreaLayout, QString()); - dockAreaLayout.apply(animated); -#else - if (centralWidgetItem != 0) { - QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow); - Q_ASSERT(layout != 0); - layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated); - } -#endif -} - -void QMainWindowLayoutState::fitLayout() -{ - QRect r; -#ifdef QT_NO_TOOLBAR - r = rect; -#else - toolBarAreaLayout.rect = rect; - r = toolBarAreaLayout.fitLayout(); -#endif // QT_NO_TOOLBAR - -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout.rect = r; - dockAreaLayout.fitLayout(); -#else - centralWidgetRect = r; -#endif -} - -void QMainWindowLayoutState::deleteAllLayoutItems() -{ -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout.deleteAllLayoutItems(); -#endif - -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout.deleteAllLayoutItems(); -#endif -} - -void QMainWindowLayoutState::deleteCentralWidgetItem() -{ -#ifndef QT_NO_DOCKWIDGET - delete dockAreaLayout.centralWidgetItem; - dockAreaLayout.centralWidgetItem = 0; -#else - delete centralWidgetItem; - centralWidgetItem = 0; -#endif -} - -QLayoutItem *QMainWindowLayoutState::itemAt(int index, int *x) const -{ -#ifndef QT_NO_TOOLBAR - if (QLayoutItem *ret = toolBarAreaLayout.itemAt(x, index)) - return ret; -#endif - -#ifndef QT_NO_DOCKWIDGET - if (QLayoutItem *ret = dockAreaLayout.itemAt(x, index)) - return ret; -#else - if (centralWidgetItem != 0 && (*x)++ == index) - return centralWidgetItem; -#endif - - return 0; -} - -QLayoutItem *QMainWindowLayoutState::takeAt(int index, int *x) -{ -#ifndef QT_NO_TOOLBAR - if (QLayoutItem *ret = toolBarAreaLayout.takeAt(x, index)) - return ret; -#endif - -#ifndef QT_NO_DOCKWIDGET - if (QLayoutItem *ret = dockAreaLayout.takeAt(x, index)) - return ret; -#else - if (centralWidgetItem != 0 && (*x)++ == index) { - QLayoutItem *ret = centralWidgetItem; - centralWidgetItem = 0; - return ret; - } -#endif - - return 0; -} - -QList<int> QMainWindowLayoutState::indexOf(QWidget *widget) const -{ - QList<int> result; - -#ifndef QT_NO_TOOLBAR - // is it a toolbar? - if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) { - result = toolBarAreaLayout.indexOf(toolBar); - if (!result.isEmpty()) - result.prepend(0); - return result; - } -#endif - -#ifndef QT_NO_DOCKWIDGET - // is it a dock widget? - if (QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget)) { - result = dockAreaLayout.indexOf(dockWidget); - if (!result.isEmpty()) - result.prepend(1); - return result; - } -#endif //QT_NO_DOCKWIDGET - - return result; -} - -bool QMainWindowLayoutState::contains(QWidget *widget) const -{ -#ifndef QT_NO_DOCKWIDGET - if (dockAreaLayout.centralWidgetItem != 0 && dockAreaLayout.centralWidgetItem->widget() == widget) - return true; - if (!dockAreaLayout.indexOf(widget).isEmpty()) - return true; -#else - if (centralWidgetItem != 0 && centralWidgetItem->widget() == widget) - return true; -#endif - -#ifndef QT_NO_TOOLBAR - if (!toolBarAreaLayout.indexOf(widget).isEmpty()) - return true; -#endif - return false; -} - -void QMainWindowLayoutState::setCentralWidget(QWidget *widget) -{ - QLayoutItem *item = 0; - //make sure we remove the widget - deleteCentralWidgetItem(); - - if (widget != 0) - item = new QWidgetItemV2(widget); - -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout.centralWidgetItem = item; -#else - centralWidgetItem = item; -#endif -} - -QWidget *QMainWindowLayoutState::centralWidget() const -{ - QLayoutItem *item = 0; - -#ifndef QT_NO_DOCKWIDGET - item = dockAreaLayout.centralWidgetItem; -#else - item = centralWidgetItem; -#endif - - if (item != 0) - return item->widget(); - return 0; -} - -QList<int> QMainWindowLayoutState::gapIndex(QWidget *widget, - const QPoint &pos) const -{ - QList<int> result; - -#ifndef QT_NO_TOOLBAR - // is it a toolbar? - if (qobject_cast<QToolBar*>(widget) != 0) { - result = toolBarAreaLayout.gapIndex(pos); - if (!result.isEmpty()) - result.prepend(0); - return result; - } -#endif - -#ifndef QT_NO_DOCKWIDGET - // is it a dock widget? - if (qobject_cast<QDockWidget *>(widget) != 0) { - result = dockAreaLayout.gapIndex(pos); - if (!result.isEmpty()) - result.prepend(1); - return result; - } -#endif //QT_NO_DOCKWIDGET - - return result; -} - -bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item) -{ - if (path.isEmpty()) - return false; - - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) { - Q_ASSERT(qobject_cast<QToolBar*>(item->widget()) != 0); - return toolBarAreaLayout.insertGap(path.mid(1), item); - } -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) { - Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0); - return dockAreaLayout.insertGap(path.mid(1), item); - } -#endif //QT_NO_DOCKWIDGET - - return false; -} - -void QMainWindowLayoutState::remove(const QList<int> &path) -{ - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) - toolBarAreaLayout.remove(path.mid(1)); -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - dockAreaLayout.remove(path.mid(1)); -#endif //QT_NO_DOCKWIDGET -} - -void QMainWindowLayoutState::remove(QLayoutItem *item) -{ -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout.remove(item); -#endif - -#ifndef QT_NO_DOCKWIDGET - // is it a dock widget? - if (QDockWidget *dockWidget = qobject_cast<QDockWidget *>(item->widget())) { - QList<int> path = dockAreaLayout.indexOf(dockWidget); - if (!path.isEmpty()) - dockAreaLayout.remove(path); - } -#endif //QT_NO_DOCKWIDGET -} - -void QMainWindowLayoutState::clear() -{ -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout.clear(); -#endif - -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout.clear(); -#else - centralWidgetRect = QRect(); -#endif - - rect = QRect(); -} - -bool QMainWindowLayoutState::isValid() const -{ - return rect.isValid(); -} - -QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path) -{ - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.item(path.mid(1)).widgetItem; -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - return dockAreaLayout.item(path.mid(1)).widgetItem; -#endif //QT_NO_DOCKWIDGET - - return 0; -} - -QRect QMainWindowLayoutState::itemRect(const QList<int> &path) const -{ - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.itemRect(path.mid(1)); -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - return dockAreaLayout.itemRect(path.mid(1)); -#endif //QT_NO_DOCKWIDGET - - return QRect(); -} - -QRect QMainWindowLayoutState::gapRect(const QList<int> &path) const -{ - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.itemRect(path.mid(1)); -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - return dockAreaLayout.gapRect(path.mid(1)); -#endif //QT_NO_DOCKWIDGET - - return QRect(); -} - -QLayoutItem *QMainWindowLayoutState::plug(const QList<int> &path) -{ - int i = path.first(); - -#ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.plug(path.mid(1)); -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - return dockAreaLayout.plug(path.mid(1)); -#endif //QT_NO_DOCKWIDGET - - return 0; -} - -QLayoutItem *QMainWindowLayoutState::unplug(const QList<int> &path, QMainWindowLayoutState *other) -{ - int i = path.first(); - -#ifdef QT_NO_TOOLBAR - Q_UNUSED(other); -#else - if (i == 0) - return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0); -#endif - -#ifndef QT_NO_DOCKWIDGET - if (i == 1) - return dockAreaLayout.unplug(path.mid(1)); -#endif //QT_NO_DOCKWIDGET - - return 0; -} - -void QMainWindowLayoutState::saveState(QDataStream &stream) const -{ -#ifndef QT_NO_DOCKWIDGET - dockAreaLayout.saveState(stream); -#endif -#ifndef QT_NO_TOOLBAR - toolBarAreaLayout.saveState(stream); -#endif -} - -template <typename T> -static QList<T> findChildrenHelper(const QObject *o) -{ - const QObjectList &list = o->children(); - QList<T> result; - - for (int i=0; i < list.size(); ++i) { - if (T t = qobject_cast<T>(list[i])) { - result.append(t); - } - } - - return result; -} - -//pre4.3 tests the format that was used before 4.3 -bool QMainWindowLayoutState::checkFormat(QDataStream &stream, bool pre43) -{ -#ifdef QT_NO_TOOLBAR - Q_UNUSED(pre43); -#endif - while (!stream.atEnd()) { - uchar marker; - stream >> marker; - switch(marker) - { -#ifndef QT_NO_TOOLBAR - case QToolBarAreaLayout::ToolBarStateMarker: - case QToolBarAreaLayout::ToolBarStateMarkerEx: - { - QList<QToolBar *> toolBars = findChildrenHelper<QToolBar*>(mainWindow); - if (!toolBarAreaLayout.restoreState(stream, toolBars, marker, - pre43 /*testing 4.3 format*/, true /*testing*/)) { - return false; - } - } - break; -#endif // QT_NO_TOOLBAR - -#ifndef QT_NO_DOCKWIDGET - case QDockAreaLayout::DockWidgetStateMarker: - { - QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); - if (!dockAreaLayout.restoreState(stream, dockWidgets, true /*testing*/)) { - return false; - } - } - break; -#endif - default: - //there was an error during the parsing - return false; - }// switch - } //while - - //everything went fine: it must be a pre-4.3 saved state - return true; -} - -bool QMainWindowLayoutState::restoreState(QDataStream &_stream, - const QMainWindowLayoutState &oldState) -{ - //make a copy of the data so that we can read it more than once - QByteArray copy; - while(!_stream.atEnd()) { - int length = 1024; - QByteArray ba(length, '\0'); - length = _stream.readRawData(ba.data(), ba.size()); - ba.resize(length); - copy += ba; - } - - QDataStream ds(copy); - const bool oldFormat = !checkFormat(ds, false); - if (oldFormat) { - //we should try with the old format - QDataStream ds2(copy); - if (!checkFormat(ds2, true)) { - return false; //format unknown - } - } - - QDataStream stream(copy); - - while (!stream.atEnd()) { - uchar marker; - stream >> marker; - switch(marker) - { -#ifndef QT_NO_DOCKWIDGET - case QDockAreaLayout::DockWidgetStateMarker: - { - QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); - if (!dockAreaLayout.restoreState(stream, dockWidgets)) - return false; - - for (int i = 0; i < dockWidgets.size(); ++i) { - QDockWidget *w = dockWidgets.at(i); - QList<int> path = dockAreaLayout.indexOf(w); - if (path.isEmpty()) { - QList<int> oldPath = oldState.dockAreaLayout.indexOf(w); - if (oldPath.isEmpty()) { - continue; - } - QDockAreaLayoutInfo *info = dockAreaLayout.info(oldPath); - if (info == 0) { - continue; - } - info->item_list.append(QDockAreaLayoutItem(new QDockWidgetItem(w))); - } - } - } - break; -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_TOOLBAR - case QToolBarAreaLayout::ToolBarStateMarker: - case QToolBarAreaLayout::ToolBarStateMarkerEx: - { - QList<QToolBar *> toolBars = findChildrenHelper<QToolBar*>(mainWindow); - if (!toolBarAreaLayout.restoreState(stream, toolBars, marker, oldFormat)) - return false; - - for (int i = 0; i < toolBars.size(); ++i) { - QToolBar *w = toolBars.at(i); - QList<int> path = toolBarAreaLayout.indexOf(w); - if (path.isEmpty()) { - QList<int> oldPath = oldState.toolBarAreaLayout.indexOf(w); - if (oldPath.isEmpty()) { - continue; - } - toolBarAreaLayout.docks[oldPath.at(0)].insertToolBar(0, w); - } - } - } - break; -#endif //QT_NO_TOOLBAR - default: - return false; - }// switch - } //while - - - return true; -} - -/****************************************************************************** -** QMainWindowLayoutState - toolbars -*/ - -#ifndef QT_NO_TOOLBAR - -static inline void validateToolBarArea(Qt::ToolBarArea &area) -{ - switch (area) { - case Qt::LeftToolBarArea: - case Qt::RightToolBarArea: - case Qt::TopToolBarArea: - case Qt::BottomToolBarArea: - break; - default: - area = Qt::TopToolBarArea; - } -} - -static QInternal::DockPosition toDockPos(Qt::ToolBarArea area) -{ - switch (area) { - case Qt::LeftToolBarArea: return QInternal::LeftDock; - case Qt::RightToolBarArea: return QInternal::RightDock; - case Qt::TopToolBarArea: return QInternal::TopDock; - case Qt::BottomToolBarArea: return QInternal::BottomDock; - default: - break; - } - - return QInternal::DockCount; -} - -static Qt::ToolBarArea toToolBarArea(QInternal::DockPosition pos) -{ - switch (pos) { - case QInternal::LeftDock: return Qt::LeftToolBarArea; - case QInternal::RightDock: return Qt::RightToolBarArea; - case QInternal::TopDock: return Qt::TopToolBarArea; - case QInternal::BottomDock: return Qt::BottomToolBarArea; - default: break; - } - return Qt::NoToolBarArea; -} - -static inline Qt::ToolBarArea toToolBarArea(int pos) -{ - return toToolBarArea(static_cast<QInternal::DockPosition>(pos)); -} - -void QMainWindowLayout::addToolBarBreak(Qt::ToolBarArea area) -{ - validateToolBarArea(area); - - layoutState.toolBarAreaLayout.addToolBarBreak(toDockPos(area)); - if (savedState.isValid()) - savedState.toolBarAreaLayout.addToolBarBreak(toDockPos(area)); - - invalidate(); -} - -void QMainWindowLayout::insertToolBarBreak(QToolBar *before) -{ - layoutState.toolBarAreaLayout.insertToolBarBreak(before); - if (savedState.isValid()) - savedState.toolBarAreaLayout.insertToolBarBreak(before); - invalidate(); -} - -void QMainWindowLayout::removeToolBarBreak(QToolBar *before) -{ - layoutState.toolBarAreaLayout.removeToolBarBreak(before); - if (savedState.isValid()) - savedState.toolBarAreaLayout.removeToolBarBreak(before); - invalidate(); -} - -void QMainWindowLayout::moveToolBar(QToolBar *toolbar, int pos) -{ - layoutState.toolBarAreaLayout.moveToolBar(toolbar, pos); - if (savedState.isValid()) - savedState.toolBarAreaLayout.moveToolBar(toolbar, pos); - invalidate(); -} - -/* Removes the toolbar from the mainwindow so that it can be added again. Does not - explicitly hide the toolbar. */ -void QMainWindowLayout::removeToolBar(QToolBar *toolbar) -{ - if (toolbar) { - QObject::disconnect(parentWidget(), SIGNAL(iconSizeChanged(QSize)), - toolbar, SLOT(_q_updateIconSize(QSize))); - QObject::disconnect(parentWidget(), SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)), - toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle))); - -#ifdef Q_WS_MAC - if (usesHIToolBar(toolbar)) { - removeFromMacToolbar(toolbar); - } else -#endif // Q_WS_MAC - { - removeWidget(toolbar); - } - } -} - -/*! - Adds \a toolbar to \a area, continuing the current line. -*/ -void QMainWindowLayout::addToolBar(Qt::ToolBarArea area, - QToolBar *toolbar, - bool) -{ - validateToolBarArea(area); -#ifdef Q_WS_MAC - if ((area == Qt::TopToolBarArea) - && layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) { - insertIntoMacToolbar(0, toolbar); - } else -#endif - { - //let's add the toolbar to the layout - addChildWidget(toolbar); - QLayoutItem * item = layoutState.toolBarAreaLayout.addToolBar(toDockPos(area), toolbar); - if (savedState.isValid() && item) { - // copy the toolbar also in the saved state - savedState.toolBarAreaLayout.insertItem(toDockPos(area), item); - } - invalidate(); - - //this ensures that the toolbar has the right window flags (not floating any more) - toolbar->d_func()->updateWindowFlags(false /*floating*/); - } -} - -/*! - Adds \a toolbar before \a before -*/ -void QMainWindowLayout::insertToolBar(QToolBar *before, QToolBar *toolbar) -{ -#ifdef Q_WS_MAC - if (usesHIToolBar(before)) { - insertIntoMacToolbar(before, toolbar); - } else -#endif // Q_WS_MAC - { - addChildWidget(toolbar); - QLayoutItem * item = layoutState.toolBarAreaLayout.insertToolBar(before, toolbar); - if (savedState.isValid() && item) { - // copy the toolbar also in the saved state - savedState.toolBarAreaLayout.insertItem(before, item); - } - if (!currentGapPos.isEmpty() && currentGapPos.first() == 0) { - currentGapPos = layoutState.toolBarAreaLayout.currentGapIndex(); - if (!currentGapPos.isEmpty()) { - currentGapPos.prepend(0); - currentGapRect = layoutState.itemRect(currentGapPos); - } - } - invalidate(); - } -} - -Qt::ToolBarArea QMainWindowLayout::toolBarArea(QToolBar *toolbar) const -{ - QInternal::DockPosition pos = layoutState.toolBarAreaLayout.findToolBar(toolbar); - switch (pos) { - case QInternal::LeftDock: return Qt::LeftToolBarArea; - case QInternal::RightDock: return Qt::RightToolBarArea; - case QInternal::TopDock: return Qt::TopToolBarArea; - case QInternal::BottomDock: return Qt::BottomToolBarArea; - default: break; - } -#ifdef Q_WS_MAC - if (pos == QInternal::DockCount) { - if (qtoolbarsInUnifiedToolbarList.contains(toolbar)) - return Qt::TopToolBarArea; - } -#endif - return Qt::NoToolBarArea; -} - -bool QMainWindowLayout::toolBarBreak(QToolBar *toolBar) const -{ - return layoutState.toolBarAreaLayout.toolBarBreak(toolBar); -} - -void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const -{ - option->toolBarArea = toolBarArea(toolBar); - layoutState.toolBarAreaLayout.getStyleOptionInfo(option, toolBar); -} - -void QMainWindowLayout::toggleToolBarsVisible() -{ - bool updateNonUnifiedParts = true; -#ifdef Q_WS_MAC - if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) { - // If we hit this case, someone has pressed the "toolbar button" which will - // toggle the unified toolbar visibility, because that's what the user wants. - // We might be in a situation where someone has hidden all the toolbars - // beforehand (maybe in construction), but now they've hit this button and - // and are expecting the items to show. What do we do? - // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this - // preserves what people would expect (these toolbars were visible when I clicked last time). - // 2) If NONE are visible, then show them all. Again, this preserves the user expectation - // of, "I want to see the toolbars." The user may get more toolbars than expected, but this - // is better seeing nothing. - // Don't worry about any of this if we are going invisible. This does mean we may get - // into issues when switching into and out of fullscreen mode, but this is probably minor. - // If we ever need to do hiding, that would have to be taken care of after the unified toolbar - // has finished hiding. - // People can of course handle the QEvent::ToolBarChange event themselves and do - // WHATEVER they want if they don't like what we are doing (though the unified toolbar - // will fire regardless). - - // Check if we REALLY need to update the geometry below. If we only have items in the - // unified toolbar, all the docks will be empty, so there's very little point - // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well). - // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar - // visibility can get out of sync. I really don't think it's a big issue. It is kept - // to a minimum because we only change the visibility if we absolutely must. - // update the "non unified parts." - updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty(); - - // We get this function before the unified toolbar does its thing. - // So, the value will be opposite of what we expect. - bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow)); - if (goingVisible) { - const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size(); - bool needAllVisible = true; - for (int i = 0; i < ToolBarCount; ++i) { - if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) { - needAllVisible = false; - break; - } - } - if (needAllVisible) { - QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because - // the toggle has already happened. - for (int i = 0; i < ToolBarCount; ++i) - qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true); - } - } - if (!updateNonUnifiedParts) - layoutState.toolBarAreaLayout.visible = goingVisible; - } -#endif - if (updateNonUnifiedParts) { - layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; - if (!layoutState.mainWindow->isMaximized()) { - QPoint topLeft = parentWidget()->geometry().topLeft(); - QRect r = parentWidget()->geometry(); - r = layoutState.toolBarAreaLayout.rectHint(r); - r.moveTo(topLeft); - parentWidget()->setGeometry(r); - } else { - update(); - } - } -} - -#endif // QT_NO_TOOLBAR - -/****************************************************************************** -** QMainWindowLayoutState - dock areas -*/ - -#ifndef QT_NO_DOCKWIDGET - -static inline void validateDockWidgetArea(Qt::DockWidgetArea &area) -{ - switch (area) { - case Qt::LeftDockWidgetArea: - case Qt::RightDockWidgetArea: - case Qt::TopDockWidgetArea: - case Qt::BottomDockWidgetArea: - break; - default: - area = Qt::LeftDockWidgetArea; - } -} - -static QInternal::DockPosition toDockPos(Qt::DockWidgetArea area) -{ - switch (area) { - case Qt::LeftDockWidgetArea: return QInternal::LeftDock; - case Qt::RightDockWidgetArea: return QInternal::RightDock; - case Qt::TopDockWidgetArea: return QInternal::TopDock; - case Qt::BottomDockWidgetArea: return QInternal::BottomDock; - default: - break; - } - - return QInternal::DockCount; -} - -static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos) -{ - switch (pos) { - case QInternal::LeftDock : return Qt::LeftDockWidgetArea; - case QInternal::RightDock : return Qt::RightDockWidgetArea; - case QInternal::TopDock : return Qt::TopDockWidgetArea; - case QInternal::BottomDock : return Qt::BottomDockWidgetArea; - default: - break; - } - - return Qt::NoDockWidgetArea; -} - -inline static Qt::DockWidgetArea toDockWidgetArea(int pos) -{ - return toDockWidgetArea(static_cast<QInternal::DockPosition>(pos)); -} - -void QMainWindowLayout::setCorner(Qt::Corner corner, Qt::DockWidgetArea area) -{ - if (layoutState.dockAreaLayout.corners[corner] == area) - return; - layoutState.dockAreaLayout.corners[corner] = area; - if (savedState.isValid()) - savedState.dockAreaLayout.corners[corner] = area; - invalidate(); -} - -Qt::DockWidgetArea QMainWindowLayout::corner(Qt::Corner corner) const -{ - return layoutState.dockAreaLayout.corners[corner]; -} - -void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area, - QDockWidget *dockwidget, - Qt::Orientation orientation) -{ - addChildWidget(dockwidget); - - // If we are currently moving a separator, then we need to abort the move, since each - // time we move the mouse layoutState is replaced by savedState modified by the move. - if (!movingSeparator.isEmpty()) - endSeparatorMove(movingSeparatorPos); - - layoutState.dockAreaLayout.addDockWidget(toDockPos(area), dockwidget, orientation); - emit dockwidget->dockLocationChanged(area); - invalidate(); -} - -void QMainWindowLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) -{ - addChildWidget(second); - layoutState.dockAreaLayout.tabifyDockWidget(first, second); - emit second->dockLocationChanged(dockWidgetArea(first)); - invalidate(); -} - -bool QMainWindowLayout::restoreDockWidget(QDockWidget *dockwidget) -{ - addChildWidget(dockwidget); - if (!layoutState.dockAreaLayout.restoreDockWidget(dockwidget)) - return false; - emit dockwidget->dockLocationChanged(dockWidgetArea(dockwidget)); - invalidate(); - return true; -} - -#ifndef QT_NO_TABBAR -bool QMainWindowLayout::documentMode() const -{ - return _documentMode; -} - -void QMainWindowLayout::setDocumentMode(bool enabled) -{ - if (_documentMode == enabled) - return; - - _documentMode = enabled; - - // Update the document mode for all tab bars - foreach (QTabBar *bar, usedTabBars) - bar->setDocumentMode(_documentMode); - foreach (QTabBar *bar, unusedTabBars) - bar->setDocumentMode(_documentMode); -} -#endif // QT_NO_TABBAR - -void QMainWindowLayout::setVerticalTabsEnabled(bool enabled) -{ -#ifdef QT_NO_TABBAR - Q_UNUSED(enabled); -#else - if (verticalTabsEnabled == enabled) - return; - - verticalTabsEnabled = enabled; - - updateTabBarShapes(); -#endif // QT_NO_TABBAR -} - -#ifndef QT_NO_TABWIDGET -QTabWidget::TabShape QMainWindowLayout::tabShape() const -{ - return _tabShape; -} - -void QMainWindowLayout::setTabShape(QTabWidget::TabShape tabShape) -{ - if (_tabShape == tabShape) - return; - - _tabShape = tabShape; - - updateTabBarShapes(); -} - -QTabWidget::TabPosition QMainWindowLayout::tabPosition(Qt::DockWidgetArea area) const -{ - return tabPositions[toDockPos(area)]; -} - -void QMainWindowLayout::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition) -{ - const Qt::DockWidgetArea dockWidgetAreas[] = { - Qt::TopDockWidgetArea, - Qt::LeftDockWidgetArea, - Qt::BottomDockWidgetArea, - Qt::RightDockWidgetArea - }; - const QInternal::DockPosition dockPositions[] = { - QInternal::TopDock, - QInternal::LeftDock, - QInternal::BottomDock, - QInternal::RightDock - }; - - for (int i = 0; i < QInternal::DockCount; ++i) - if (areas & dockWidgetAreas[i]) - tabPositions[dockPositions[i]] = tabPosition; - - updateTabBarShapes(); -} - -static inline QTabBar::Shape tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position) -{ - const bool rounded = (shape == QTabWidget::Rounded); - if (position == QTabWidget::North) - return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth; - if (position == QTabWidget::South) - return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth; - if (position == QTabWidget::East) - return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast; - if (position == QTabWidget::West) - return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest; - return QTabBar::RoundedNorth; -} -#endif // QT_NO_TABWIDGET - -#ifndef QT_NO_TABBAR -void QMainWindowLayout::updateTabBarShapes() -{ -#ifndef QT_NO_TABWIDGET - const QTabWidget::TabPosition vertical[] = { - QTabWidget::West, - QTabWidget::East, - QTabWidget::North, - QTabWidget::South - }; -#else - const QTabBar::Shape vertical[] = { - QTabBar::RoundedWest, - QTabBar::RoundedEast, - QTabBar::RoundedNorth, - QTabBar::RoundedSouth - }; -#endif - - QDockAreaLayout &layout = layoutState.dockAreaLayout; - - for (int i = 0; i < QInternal::DockCount; ++i) { -#ifndef QT_NO_TABWIDGET - QTabWidget::TabPosition pos = verticalTabsEnabled ? vertical[i] : tabPositions[i]; - QTabBar::Shape shape = tabBarShapeFrom(_tabShape, pos); -#else - QTabBar::Shape shape = verticalTabsEnabled ? vertical[i] : QTabBar::RoundedSouth; -#endif - layout.docks[i].setTabBarShape(shape); - } -} -#endif // QT_NO_TABBAR - -void QMainWindowLayout::splitDockWidget(QDockWidget *after, - QDockWidget *dockwidget, - Qt::Orientation orientation) -{ - addChildWidget(dockwidget); - layoutState.dockAreaLayout.splitDockWidget(after, dockwidget, orientation); - emit dockwidget->dockLocationChanged(dockWidgetArea(after)); - invalidate(); -} - -Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QDockWidget *widget) const -{ - QList<int> pathToWidget = layoutState.dockAreaLayout.indexOf(widget); - if (pathToWidget.isEmpty()) - return Qt::NoDockWidgetArea; - return toDockWidgetArea(pathToWidget.first()); -} - -void QMainWindowLayout::keepSize(QDockWidget *w) -{ - layoutState.dockAreaLayout.keepSize(w); -} - -#ifndef QT_NO_TABBAR - -class QMainWindowTabBar : public QTabBar -{ -public: - QMainWindowTabBar(QWidget *parent); -protected: - bool event(QEvent *e); -}; - -QMainWindowTabBar::QMainWindowTabBar(QWidget *parent) - : QTabBar(parent) -{ - setExpanding(false); -} - -bool QMainWindowTabBar::event(QEvent *e) -{ - // show the tooltip if tab is too small to fit label - - if (e->type() != QEvent::ToolTip) - return QTabBar::event(e); - QSize size = this->size(); - QSize hint = sizeHint(); - if (shape() == QTabBar::RoundedWest || shape() == QTabBar::RoundedEast) { - size.transpose(); - hint.transpose(); - } - if (size.width() < hint.width()) - return QTabBar::event(e); - e->accept(); - return true; -} - -QTabBar *QMainWindowLayout::getTabBar() -{ - QTabBar *result = 0; - if (!unusedTabBars.isEmpty()) { - result = unusedTabBars.takeLast(); - } else { - result = new QMainWindowTabBar(parentWidget()); - result->setDrawBase(true); - result->setElideMode(Qt::ElideRight); - result->setDocumentMode(_documentMode); - connect(result, SIGNAL(currentChanged(int)), this, SLOT(tabChanged())); - } - - usedTabBars.insert(result); - return result; -} - -// Allocates a new separator widget if needed -QWidget *QMainWindowLayout::getSeparatorWidget() -{ - QWidget *result = 0; - if (!unusedSeparatorWidgets.isEmpty()) { - result = unusedSeparatorWidgets.takeLast(); - } else { - result = new QWidget(parentWidget()); - result->setAttribute(Qt::WA_MouseNoMask, true); - result->setAutoFillBackground(false); - result->setObjectName(QLatin1String("qt_qmainwindow_extended_splitter")); - } - usedSeparatorWidgets.insert(result); - return result; -} - -void QMainWindowLayout::tabChanged() -{ - QTabBar *tb = qobject_cast<QTabBar*>(sender()); - if (tb == 0) - return; - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(tb); - if (info == 0) - return; - info->apply(false); - - if (QWidget *w = centralWidget()) - w->raise(); -} -#endif // QT_NO_TABBAR - -bool QMainWindowLayout::startSeparatorMove(const QPoint &pos) -{ - movingSeparator = layoutState.dockAreaLayout.findSeparator(pos); - - if (movingSeparator.isEmpty()) - return false; - - savedState = layoutState; - movingSeparatorPos = movingSeparatorOrigin = pos; - - return true; -} - -bool QMainWindowLayout::separatorMove(const QPoint &pos) -{ - if (movingSeparator.isEmpty()) - return false; - movingSeparatorPos = pos; - separatorMoveTimer.start(0, this); - return true; -} - -bool QMainWindowLayout::endSeparatorMove(const QPoint&) -{ - bool result = !movingSeparator.isEmpty(); - movingSeparator.clear(); - savedState.clear(); - return result; -} - -void QMainWindowLayout::raise(QDockWidget *widget) -{ - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); - if (info == 0) - return; -#ifndef QT_NO_TABBAR - if (!info->tabbed) - return; - info->setCurrentTab(widget); -#endif -} - -#endif // QT_NO_DOCKWIDGET - - -/****************************************************************************** -** QMainWindowLayoutState - layout interface -*/ - -int QMainWindowLayout::count() const -{ - qWarning("QMainWindowLayout::count: ?"); - return 0; //################################################# -} - -QLayoutItem *QMainWindowLayout::itemAt(int index) const -{ - int x = 0; - - if (QLayoutItem *ret = layoutState.itemAt(index, &x)) - return ret; - - if (statusbar && x++ == index) - return statusbar; - - return 0; -} - -QLayoutItem *QMainWindowLayout::takeAt(int index) -{ - int x = 0; - - if (QLayoutItem *ret = layoutState.takeAt(index, &x)) { - // the widget might in fact have been destroyed by now - if (QWidget *w = ret->widget()) { - widgetAnimator.abort(w); - if (w == pluggingWidget) - pluggingWidget = 0; - } - - if (savedState.isValid() ) { - //we need to remove the item also from the saved state to prevent crash - savedState.remove(ret); - //Also, the item may be contained several times as a gap item. - layoutState.remove(ret); - } - -#ifndef QT_NO_TOOLBAR - if (!currentGapPos.isEmpty() && currentGapPos.first() == 0) { - currentGapPos = layoutState.toolBarAreaLayout.currentGapIndex(); - if (!currentGapPos.isEmpty()) { - currentGapPos.prepend(0); - currentGapRect = layoutState.itemRect(currentGapPos); - } - } -#endif - - return ret; - } - - if (statusbar && x++ == index) { - QLayoutItem *ret = statusbar; - statusbar = 0; - return ret; - } - - return 0; -} - -void QMainWindowLayout::setGeometry(const QRect &_r) -{ - if (savedState.isValid()) - return; - - QRect r = _r; - - QLayout::setGeometry(r); - - if (statusbar) { - QRect sbr(QPoint(0, 0), - QSize(r.width(), statusbar->heightForWidth(r.width())) - .expandedTo(statusbar->minimumSize())); - sbr.moveBottom(r.bottom()); - QRect vr = QStyle::visualRect(parentWidget()->layoutDirection(), _r, sbr); - statusbar->setGeometry(vr); - r.setBottom(sbr.top() - 1); - } - - layoutState.rect = r; - layoutState.fitLayout(); - applyState(layoutState, false); -} - -void QMainWindowLayout::addItem(QLayoutItem *) -{ qWarning("QMainWindowLayout::addItem: Please use the public QMainWindow API instead"); } - -QSize QMainWindowLayout::sizeHint() const -{ - if (!szHint.isValid()) { - szHint = layoutState.sizeHint(); - const QSize sbHint = statusbar ? statusbar->sizeHint() : QSize(0, 0); - szHint = QSize(qMax(sbHint.width(), szHint.width()), - sbHint.height() + szHint.height()); - } - return szHint; -} - -QSize QMainWindowLayout::minimumSize() const -{ - if (!minSize.isValid()) { - minSize = layoutState.minimumSize(); - const QSize sbMin = statusbar ? statusbar->minimumSize() : QSize(0, 0); - minSize = QSize(qMax(sbMin.width(), minSize.width()), - sbMin.height() + minSize.height()); -#ifdef Q_WS_MAC - const QSize storedSize = minSize; - int minWidth = 0; - foreach (QToolBar *toolbar, qtoolbarsInUnifiedToolbarList) { - minWidth += toolbar->sizeHint().width() + 20; - } - minSize = QSize(qMax(minWidth, storedSize.width()), storedSize.height()); -#endif - } - return minSize; -} - -void QMainWindowLayout::invalidate() -{ - QLayout::invalidate(); - minSize = szHint = QSize(); -} - -/****************************************************************************** -** QMainWindowLayout - remaining stuff -*/ - -static void fixToolBarOrientation(QLayoutItem *item, int dockPos) -{ -#ifndef QT_NO_TOOLBAR - QToolBar *toolBar = qobject_cast<QToolBar*>(item->widget()); - if (toolBar == 0) - return; - - QRect oldGeo = toolBar->geometry(); - - QInternal::DockPosition pos - = static_cast<QInternal::DockPosition>(dockPos); - Qt::Orientation o = pos == QInternal::TopDock || pos == QInternal::BottomDock - ? Qt::Horizontal : Qt::Vertical; - if (o != toolBar->orientation()) - toolBar->setOrientation(o); - - QSize hint = toolBar->sizeHint().boundedTo(toolBar->maximumSize()) - .expandedTo(toolBar->minimumSize()); - - if (toolBar->size() != hint) { - QRect newGeo(oldGeo.topLeft(), hint); - if (toolBar->layoutDirection() == Qt::RightToLeft) - newGeo.moveRight(oldGeo.right()); - toolBar->setGeometry(newGeo); - } - -#else - Q_UNUSED(item); - Q_UNUSED(dockPos); -#endif -} - -void QMainWindowLayout::revert(QLayoutItem *widgetItem) -{ - if (!savedState.isValid()) - return; - - QWidget *widget = widgetItem->widget(); - layoutState = savedState; - currentGapPos = layoutState.indexOf(widget); - fixToolBarOrientation(widgetItem, currentGapPos.at(1)); - layoutState.unplug(currentGapPos); - layoutState.fitLayout(); - currentGapRect = layoutState.itemRect(currentGapPos); - - plug(widgetItem); -} - -bool QMainWindowLayout::plug(QLayoutItem *widgetItem) -{ - if (!parentWidget()->isVisible() || parentWidget()->isMinimized() || currentGapPos.isEmpty()) - return false; - - fixToolBarOrientation(widgetItem, currentGapPos.at(1)); - - QWidget *widget = widgetItem->widget(); - - QList<int> previousPath = layoutState.indexOf(widget); - - QLayoutItem *it = layoutState.plug(currentGapPos); - Q_ASSERT(it == widgetItem); - Q_UNUSED(it); - if (!previousPath.isEmpty()) - layoutState.remove(previousPath); - - pluggingWidget = widget; - QRect globalRect = currentGapRect; - globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); -#ifndef QT_NO_DOCKWIDGET - if (qobject_cast<QDockWidget*>(widget) != 0) { - QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout()); - if (layout->nativeWindowDeco()) { - globalRect.adjust(0, layout->titleHeight(), 0, 0); - } else { - int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); - globalRect.adjust(-fw, -fw, fw, fw); - } - } -#endif - widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); - - return true; -} - -void QMainWindowLayout::animationFinished(QWidget *widget) -{ - //this function is called from within the Widget Animator whenever an animation is finished - //on a certain widget -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) { - QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout()); - if (tbl->animating) { - tbl->animating = false; - if (tbl->expanded) - tbl->layoutActions(tb->size()); - tb->update(); - } - } -#endif - - if (widget == pluggingWidget) { - -#ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) - dw->d_func()->plug(currentGapRect); -#endif -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) - tb->d_func()->plug(currentGapRect); -#endif - - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; - //applying the state will make sure that the currentGap is updated correctly - //and all the geometries (especially the one from the central widget) is correct - layoutState.apply(false); - -#ifndef QT_NO_DOCKWIDGET -#ifndef QT_NO_TABBAR - if (qobject_cast<QDockWidget*>(widget) != 0) { - // info() might return null if the widget is destroyed while - // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) - info->setCurrentTab(widget); - } -#endif -#endif - } - - if (!widgetAnimator.animating()) { - //all animations are finished -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); -#ifndef QT_NO_TABBAR - foreach (QTabBar *tab_bar, usedTabBars) - tab_bar->show(); -#endif // QT_NO_TABBAR -#endif // QT_NO_DOCKWIDGET - } - - updateGapIndicator(); -} - -void QMainWindowLayout::restore(bool keepSavedState) -{ - if (!savedState.isValid()) - return; - - layoutState = savedState; - applyState(layoutState); - if (!keepSavedState) - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; - updateGapIndicator(); -} - -QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLayout) - : QLayout(parentLayout ? static_cast<QWidget *>(0) : mainwindow) - , layoutState(mainwindow) - , savedState(mainwindow) - , dockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowTabbedDocks) - , statusbar(0) -#ifndef QT_NO_DOCKWIDGET -#ifndef QT_NO_TABBAR - , _documentMode(false) - , verticalTabsEnabled(false) -#ifndef QT_NO_TABWIDGET - , _tabShape(QTabWidget::Rounded) -#endif -#endif -#endif // QT_NO_DOCKWIDGET - , widgetAnimator(this) - , pluggingWidget(0) -#ifndef QT_NO_RUBBERBAND - , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) -#endif //QT_NO_RUBBERBAND -#ifdef Q_WS_MAC - , blockVisiblityCheck(false) -#endif -{ - if (parentLayout) - setParent(parentLayout); - -#ifndef QT_NO_DOCKWIDGET -#ifndef QT_NO_TABBAR - sep = mainwindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainwindow); -#endif - -#ifndef QT_NO_TABWIDGET - for (int i = 0; i < QInternal::DockCount; ++i) - tabPositions[i] = QTabWidget::South; -#endif -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_RUBBERBAND - // For accessibility to identify this special widget. - gapIndicator->setObjectName(QLatin1String("qt_rubberband")); - gapIndicator->hide(); -#endif - pluggingWidget = 0; - - setObjectName(mainwindow->objectName() + QLatin1String("_layout")); -} - -QMainWindowLayout::~QMainWindowLayout() -{ - layoutState.deleteAllLayoutItems(); - layoutState.deleteCentralWidgetItem(); - -#ifdef Q_WS_MAC - cleanUpMacToolbarItems(); -#endif - - delete statusbar; -} - -void QMainWindowLayout::setDockOptions(QMainWindow::DockOptions opts) -{ - if (opts == dockOptions) - return; - - dockOptions = opts; - -#ifndef QT_NO_DOCKWIDGET - setVerticalTabsEnabled(opts & QMainWindow::VerticalTabs); -#endif - - invalidate(); -} - -#ifndef QT_NO_STATUSBAR -QStatusBar *QMainWindowLayout::statusBar() const -{ return statusbar ? qobject_cast<QStatusBar *>(statusbar->widget()) : 0; } - -void QMainWindowLayout::setStatusBar(QStatusBar *sb) -{ - if (sb) - addChildWidget(sb); - delete statusbar; - statusbar = sb ? new QWidgetItemV2(sb) : 0; - invalidate(); -} -#endif // QT_NO_STATUSBAR - -QWidget *QMainWindowLayout::centralWidget() const -{ - return layoutState.centralWidget(); -} - -void QMainWindowLayout::setCentralWidget(QWidget *widget) -{ - if (widget != 0) - addChildWidget(widget); - layoutState.setCentralWidget(widget); - if (savedState.isValid()) { -#ifndef QT_NO_DOCKWIDGET - savedState.dockAreaLayout.centralWidgetItem = layoutState.dockAreaLayout.centralWidgetItem; - savedState.dockAreaLayout.fallbackToSizeHints = true; -#else - savedState.centralWidgetItem = layoutState.centralWidgetItem; -#endif - } - invalidate(); -} - -QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) -{ - QList<int> path = layoutState.indexOf(widget); - if (path.isEmpty()) - return 0; - - QLayoutItem *item = layoutState.item(path); - if (widget->isWindow()) - return item; - - QRect r = layoutState.itemRect(path); - savedState = layoutState; - -#ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) { - dw->d_func()->unplug(r); - } -#endif -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) { - tb->d_func()->unplug(r); - } -#endif - - - layoutState.unplug(path ,&savedState); - savedState.fitLayout(); - currentGapPos = path; - currentGapRect = r; - updateGapIndicator(); - - fixToolBarOrientation(item, currentGapPos.at(1)); - - return item; -} - -void QMainWindowLayout::updateGapIndicator() -{ -#ifndef QT_NO_RUBBERBAND - gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); - gapIndicator->setGeometry(currentGapRect); -#endif -} - -QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) -{ - if (!parentWidget()->isVisible() || parentWidget()->isMinimized() - || pluggingWidget != 0 || widgetItem == 0) - return QList<int>(); - - QWidget *widget = widgetItem->widget(); - QPoint pos = parentWidget()->mapFromGlobal(mousePos); - - if (!savedState.isValid()) - savedState = layoutState; - - QList<int> path = savedState.gapIndex(widget, pos); - - if (!path.isEmpty()) { - bool allowed = false; - -#ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) - allowed = dw->isAreaAllowed(toDockWidgetArea(path.at(1))); -#endif -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) - allowed = tb->isAreaAllowed(toToolBarArea(path.at(1))); -#endif - - if (!allowed) - path.clear(); - } - - if (path == currentGapPos) - return currentGapPos; // the gap is already there - - currentGapPos = path; - if (path.isEmpty()) { - fixToolBarOrientation(widgetItem, 2); // 2 = top dock, ie. horizontal - restore(true); - return QList<int>(); - } - - fixToolBarOrientation(widgetItem, currentGapPos.at(1)); - - QMainWindowLayoutState newState = savedState; - - if (!newState.insertGap(path, widgetItem)) { - restore(true); // not enough space - return QList<int>(); - } - - QSize min = newState.minimumSize(); - QSize size = newState.rect.size(); - - if (min.width() > size.width() || min.height() > size.height()) { - restore(true); - return QList<int>(); - } - - newState.fitLayout(); - - currentGapRect = newState.gapRect(currentGapPos); - -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); -#endif - layoutState = newState; - applyState(layoutState); - - updateGapIndicator(); - - return path; -} - -void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animate) -{ -#ifndef QT_NO_DOCKWIDGET -#ifndef QT_NO_TABBAR - QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars(); - QSet<QTabBar*> retired = usedTabBars - used; - usedTabBars = used; - foreach (QTabBar *tab_bar, retired) { - tab_bar->hide(); - while (tab_bar->count() > 0) - tab_bar->removeTab(0); - unusedTabBars.append(tab_bar); - } - - if (sep == 1) { - QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets(); - QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps; - usedSeparatorWidgets = usedSeps; - foreach (QWidget *sepWidget, retiredSeps) { - unusedSeparatorWidgets.append(sepWidget); - } - } - - -#endif // QT_NO_TABBAR -#endif // QT_NO_DOCKWIDGET - newState.apply(dockOptions & QMainWindow::AnimatedDocks && animate); -} - -void QMainWindowLayout::saveState(QDataStream &stream) const -{ - layoutState.saveState(stream); -} - -bool QMainWindowLayout::restoreState(QDataStream &stream) -{ - savedState = layoutState; - layoutState.clear(); - layoutState.rect = savedState.rect; - - if (!layoutState.restoreState(stream, savedState)) { - layoutState.deleteAllLayoutItems(); - layoutState = savedState; - if (parentWidget()->isVisible()) - applyState(layoutState, false); // hides tabBars allocated by newState - return false; - } - - if (parentWidget()->isVisible()) { - layoutState.fitLayout(); - applyState(layoutState, false); - } - - savedState.deleteAllLayoutItems(); - savedState.clear(); - -#ifndef QT_NO_DOCKWIDGET - if (parentWidget()->isVisible()) { -#ifndef QT_NO_TABBAR - foreach (QTabBar *tab_bar, usedTabBars) - tab_bar->show(); - -#endif - } -#endif // QT_NO_DOCKWIDGET - - return true; -} - - -// Returns if this toolbar *should* be using HIToolbar. Won't work for all in between cases -// for example, you have a toolbar in the top area and then you suddenly turn on -// HIToolbar. -bool QMainWindowLayout::usesHIToolBar(QToolBar *toolbar) const -{ -#ifndef Q_WS_MAC - Q_UNUSED(toolbar); - return false; -#else - return qtoolbarsInUnifiedToolbarList.contains(toolbar) - || ((toolBarArea(toolbar) == Qt::TopToolBarArea) - && layoutState.mainWindow->unifiedTitleAndToolBarOnMac()); -#endif -} - -void QMainWindowLayout::timerEvent(QTimerEvent *e) -{ -#ifndef QT_NO_DOCKWIDGET - if (e->timerId() == separatorMoveTimer.timerId()) { - //let's move the separators - separatorMoveTimer.stop(); - if (movingSeparator.isEmpty()) - return; - if (movingSeparatorOrigin == movingSeparatorPos) - return; - - //when moving the separator, we need to update the previous position - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); - - layoutState = savedState; - layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin, - movingSeparatorPos); - movingSeparatorPos = movingSeparatorOrigin; - } -#endif - QLayout::timerEvent(e); -} - - -QT_END_NAMESPACE - -#endif // QT_NO_MAINWINDOW |