📄 qmainwindowlayout.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qmainwindowlayout_p.h"#ifndef QT_NO_MAINWINDOW#include "qdockseparator_p.h"#include "qdockwidgetlayout_p.h"#include "qdockwidget.h"#include "qmainwindow.h"#include "qtoolbar.h"#include <qapplication.h>#include <qdebug.h>#include <qstatusbar.h>#include <qstyle.h>#include <qvarlengtharray.h>#include <qstack.h>#include <qmap.h>#include <private/qlayoutengine_p.h>// #define LAYOUT_DEBUG#if defined(LAYOUT_DEBUG)# define DEBUG qDebug#else# define DEBUG if(false)qDebug#endif// #define LAYOUT_DEBUG_VERBOSE#if defined(LAYOUT_DEBUG_VERBOSE)# define VDEBUG qDebug#else# define VDEBUG if(false)qDebug#endif// #define TOOLBAR_DEBUG#if defined(TOOLBAR_DEBUG)# define TBDEBUG qDebug#else# define TBDEBUG if(false)qDebug#endifenum POSITION { LEFT, RIGHT, TOP, BOTTOM, CENTER, NPOSITIONS};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 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 inline uint areaForPosition(int pos){ return ((1u << pos) & 0xf); }static inline POSITION positionForArea(Qt::DockWidgetArea area){ switch (area) { case Qt::LeftDockWidgetArea: return LEFT; case Qt::RightDockWidgetArea: return RIGHT; case Qt::TopDockWidgetArea: return TOP; case Qt::BottomDockWidgetArea: return BOTTOM; default: break; } return CENTER;}#ifndef QT_NO_TOOLBARstatic inline POSITION positionForArea(Qt::ToolBarArea area){ switch (area) { case Qt::LeftToolBarArea: return LEFT; case Qt::RightToolBarArea: return RIGHT; case Qt::TopToolBarArea: return TOP; case Qt::BottomToolBarArea: return BOTTOM; default: break; } return CENTER;}#endifstatic inline int pick(POSITION p, const QSize &s){ return p == TOP || p == BOTTOM ? s.height() : s.width(); }static inline int pick(POSITION p, const QPoint &pt){ return p == TOP || p == BOTTOM ? pt.y() : pt.x(); }static inline void set(POSITION p, QSize &s, int x){ if (p == LEFT || p == RIGHT) s.setWidth(x); else s.setHeight(x); }static inline int pick_perp(POSITION p, const QSize &s){ return p == TOP || p == BOTTOM ? s.width() : s.height(); }static inline int pick_perp(POSITION p, const QPoint &pt){ return p == TOP || p == BOTTOM ? pt.x() : pt.y(); }static inline void set_perp(POSITION p, QSize &s, int x){ if (p == TOP || p == BOTTOM) s.setWidth(x); else s.setHeight(x); }static inline void set_perp(POSITION p, QPoint &pt, int x){ if (p == TOP || p == BOTTOM) pt.setX(x); else pt.setY(x); }class QMainWindowLayoutItem : public QWidgetItem{public: inline QMainWindowLayoutItem(QWidget *w, const QRect &r) : QWidgetItem(w), rect(r) { } inline QSize sizeHint() const { return rect.size(); } inline void setGeometry( const QRect &r) { rect = r; } inline QRect geometry() const { return rect; } inline bool isEmpty() const { return false; } QWidget *widget; QRect rect;};QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) : QLayout(mainwindow), statusbar(0), relayout_type(QInternal::RelayoutNormal), save_layout_info(0)#ifndef QT_NO_TOOLBAR , save_tb_layout_info(0)#endif{ setObjectName(mainwindow->objectName() + "_layout"); corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea; corners[Qt::TopRightCorner] = Qt::TopDockWidgetArea; corners[Qt::BottomLeftCorner] = Qt::BottomDockWidgetArea; corners[Qt::BottomRightCorner] = Qt::BottomDockWidgetArea; for (int i = 0; i < Qt::NDockWidgetAreas + 1; ++i) { QMainWindowLayoutInfo info; info.item = 0; info.sep = 0; info.is_dummy = false; layout_info.append(info); }}QMainWindowLayout::~QMainWindowLayout(){#ifndef QT_NO_TOOLBAR for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); for (int i = 0; i < lineInfo.list.size(); ++i) delete lineInfo.list.at(i).item; } tb_layout_info.clear();#endif for (int i = 0; i < NPOSITIONS; ++i) { delete layout_info[i].item; if (layout_info[i].sep) delete layout_info[i].sep->widget(); delete layout_info[i].sep; layout_info[i].item = 0; layout_info[i].sep = 0; } delete statusbar;}#ifndef QT_NO_STATUSBARQStatusBar *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 QWidgetItem(sb) : 0; invalidate();}#endif // QT_NO_STATUSBARQWidget *QMainWindowLayout::centralWidget() const{ return layout_info[CENTER].item ? layout_info[CENTER].item->widget() : 0; }void QMainWindowLayout::setCentralWidget(QWidget *cw){ if (cw) addChildWidget(cw); delete layout_info[CENTER].item; layout_info[CENTER].item = cw ? new QWidgetItem(cw) : 0; layout_info[CENTER].size = QSize(); invalidate();}#ifndef QT_NO_TOOLBARvoid QMainWindowLayout::addToolBarBreak(Qt::ToolBarArea area){ ToolBarLineInfo newLine; validateToolBarArea(area); newLine.pos = positionForArea(area); switch (newLine.pos) { case TOP: case BOTTOM: { for (int line = 0; line < tb_layout_info.size(); ++line) { ToolBarLineInfo &lineInfo = tb_layout_info[line]; if (lineInfo.pos == LEFT || lineInfo.pos == RIGHT) { tb_layout_info.insert(line, newLine); return; } } } // fall through intended default: tb_layout_info.append(newLine); TBDEBUG() << "appended new line"; break; }}void QMainWindowLayout::insertToolBarBreak(QToolBar *before){ for (int line = 0; line < tb_layout_info.size(); ++line) { ToolBarLineInfo &lineInfo = tb_layout_info[line]; for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); if (info.item->widget() == before) { ToolBarLineInfo newLine; newLine.pos = lineInfo.pos; for (; i < lineInfo.list.size(); ++i) newLine.list += lineInfo.list.takeAt(i); tb_layout_info.insert(line + 1, newLine); return; } } }}/*! Adds \a toolbar to \a area, continuing the current line.*/void QMainWindowLayout::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar, bool needAddChildWidget){ if (needAddChildWidget) addChildWidget(toolbar); else removeToolBarInfo(toolbar); validateToolBarArea(area); POSITION pos = positionForArea(area); // see if we have an existing line in the tb - append it in the last in line for (int line = 0; line < tb_layout_info.size(); ++line) { if (tb_layout_info.at(line).pos == pos) { while (line < tb_layout_info.size() - 1 && tb_layout_info.at(line + 1).pos == pos) ++line; switch (pos) { case TOP: case BOTTOM: toolbar->setOrientation(Qt::Horizontal); break; case LEFT: case RIGHT: toolbar->setOrientation(Qt::Vertical); break; default: break; } ToolBarLineInfo &lineInfo = tb_layout_info[line]; ToolBarLayoutInfo newinfo; newinfo.item = new QWidgetItem(toolbar); lineInfo.list.append(newinfo); return; } } // no line to continue, add one and recurse addToolBarBreak(area); addToolBar(area, toolbar, false);}/*! Adds \a toolbar before \a before*/void QMainWindowLayout::insertToolBar(QToolBar *before, QToolBar *toolbar){ addChildWidget(toolbar); for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); if (info.item->widget() == before) { ToolBarLayoutInfo newInfo; newInfo.item = new QWidgetItem(toolbar); tb_layout_info[line].list.insert(i, newInfo); return; } } }}Qt::ToolBarArea QMainWindowLayout::toolBarArea(QToolBar *toolbar) const{ for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); if (info.item->widget() == toolbar) return static_cast<Qt::ToolBarArea>(areaForPosition(lineInfo.pos)); } } return Qt::ToolBarArea(0);}#endif // QT_NO_TOOLBAR#ifndef QT_NO_DOCKWIDGETQDockWidgetLayout *QMainWindowLayout::layoutForArea(Qt::DockWidgetArea area){ validateDockWidgetArea(area); POSITION pos = positionForArea(area); QMainWindowLayoutInfo &info = layout_info[pos]; QDockWidgetLayout *l = 0; if (!info.item) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -