📄 qdockwidgetlayout.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 "qdockwidgetlayout_p.h"#include "qdockwidget.h"#ifndef QT_NO_DOCKWIDGET#include <qapplication.h>#include <qdebug.h>#include <qevent.h>#include <qstyle.h>#include <qvector.h>#include <private/qlayoutengine_p.h>#include "qdockwidget_p.h"#include "qdockwidgetseparator_p.h"#include "qmainwindowlayout_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#endifstatic inline bool canGrow(Qt::Orientation o, const QSizePolicy &sp){ return (o == Qt::Horizontal ? sp.horizontalPolicy() : sp.verticalPolicy()) & QSizePolicy::GrowFlag; }enum { StateFlagVisible = 1, StateFlagFloating = 2 };QDockWidgetLayout::QDockWidgetLayout(Qt::DockWidgetArea a, Qt::Orientation o) : QLayout(static_cast<QWidget*>(0)), area(a), orientation(o), save_layout_info(0), relayout_type(QInternal::RelayoutNormal){ connect(this, SIGNAL(emptied()), SLOT(maybeDelete()), Qt::QueuedConnection); }QDockWidgetLayout::~QDockWidgetLayout(){ for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) { info.item->widget()->hide(); info.item->widget()->deleteLater(); } if (!info.item->layout()) delete info.item; }}void QDockWidgetLayout::saveState(QDataStream &stream) const{ stream << (uchar) Marker; stream << (uchar) orientation; stream << (layout_info.count() + 1) / 2; for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; if (info.item->widget()) { const QDockWidget * const widget = qobject_cast<QDockWidget *>(info.item->widget()); stream << (uchar) WidgetMarker; QString objectName = widget->objectName(); if (objectName.isEmpty()) { qWarning("QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%s'", widget, widget->windowTitle().toLocal8Bit().constData()); } stream << objectName; uchar flags = 0; if (!widget->isHidden()) flags |= StateFlagVisible; if (widget->isFloating()) flags |= StateFlagFloating; stream << flags; if (widget->isFloating()) { stream << widget->x(); stream << widget->y(); stream << widget->width(); stream << widget->height(); } else { stream << info.cur_pos; stream << info.cur_size; stream << info.min_size; stream << info.max_size; } } else if (info.item->layout()) { stream << (uchar) Marker; stream << info.cur_pos; stream << info.cur_size; stream << info.min_size; stream << info.max_size; const QDockWidgetLayout * const layout = qobject_cast<const QDockWidgetLayout *>(info.item->layout()); layout->saveState(stream); } }}bool QDockWidgetLayout::restoreState(QDataStream &stream){ uchar marker; int size; stream >> marker; if (marker != Marker) return false; relayout_type = QInternal::RelayoutDropped; uchar o; stream >> o; orientation = static_cast<Qt::Orientation>(o); stream >> size; QList<QDockWidget *> widgets = qFindChildren<QDockWidget *>(parentWidget()); for (int i = 0; i < size; ++i) { uchar nextMarker; stream >> nextMarker; switch (nextMarker) { case WidgetMarker: { QString objectName; stream >> objectName; uchar flags; stream >> flags; if (objectName.isEmpty()) { qWarning("QMainWindow::restoreState: Cannot restore " "a QDockWidget with an empty 'objectName'"); // discard size/position data for unknown widget QDockWidgetLayoutInfo info(0); stream >> info.cur_pos; stream >> info.cur_size; stream >> info.min_size; stream >> info.max_size; continue; } // find widget QDockWidget *widget = 0; for (int t = 0; t < widgets.size(); ++t) { if (widgets.at(t)->objectName() == objectName) { widget = widgets.at(t); break; } } if (!widget) { qWarning("QMainWindow::restoreState(): cannot find a QDockWidget with " "matching 'objectName' (looking for '%s').", objectName.toLocal8Bit().constData()); // discard size/position data for unknown widget QDockWidgetLayoutInfo info(0); stream >> info.cur_pos; stream >> info.cur_size; stream >> info.min_size; stream >> info.max_size; continue; } QDockWidgetLayoutInfo &info = insert(-1, new QWidgetItem(widget)); if (flags & StateFlagFloating) { widget->hide(); widget->setFloating(true); int x, y, w, h; stream >> x; stream >> y; stream >> w; stream >> h; widget->move(x, y); widget->resize(w, h); widget->setVisible(flags & StateFlagVisible); } else { stream >> info.cur_pos; stream >> info.cur_size; stream >> info.min_size; stream >> info.max_size; widget->setFloating(false); widget->setVisible(flags & StateFlagVisible); } break; } case Marker: { QDockWidgetLayout *layout = new QDockWidgetLayout(area, orientation); layout->setParent(this); QDockWidgetLayoutInfo &info = insert(-1, layout); stream >> info.cur_pos; stream >> info.cur_size; stream >> info.min_size; stream >> info.max_size; if (!layout->restoreState(stream)) { relayout_type = QInternal::RelayoutNormal; return false; } break; } default: // corrupt data relayout_type = QInternal::RelayoutNormal; return false; } } relayout_type = QInternal::RelayoutNormal; return true;}int QDockWidgetLayout::count() const{ qWarning("QDockWidgetLayout::count() is wrong"); return layout_info.count();}QLayoutItem *QDockWidgetLayout::itemAt(int index) const{ VDEBUG("QDockWidgetLayout::itemAt: index %d (%d)", index, layout_info.count()); int x = 0; for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; if (x++ == index) { VDEBUG("END, widget: pos %3d index %3d", i, x); return info.item; } } VDEBUG("END, not found"); return 0;}QLayoutItem *QDockWidgetLayout::takeAt(int index){ DEBUG("QDockWidgetLayout::takeAt: index %d", index); int x = 0; for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; if (x++ == index) { QLayoutItem *layoutitem = info.item; QWidget *widget = info.item->widget(); VDEBUG("QDockWidgetLayout::takeAt: layoutitem '%s'\n" " index %3d pos %4d size %4d %s", (layoutitem->widget() ? layoutitem->widget()->objectName().toLatin1().constData() : "dummy"), i, info.cur_pos, info.cur_size, (widget ? widget->objectName().toLatin1().constData() : "dummy")); // remove the item layout_info.removeAt(i); // remove the separator if (i == layout_info.count()) { // we removed the last dockwidget, so we need to remove // the separator that was above it --i; } if (i != -1) { QDockWidgetLayoutInfo &sep_info = layout_info[i]; Q_ASSERT(sep_info.is_sep); if (!save_layout_info) { delete sep_info.item->widget(); delete sep_info.item; } VDEBUG(" removing separator at %d", i); layout_info.removeAt(i); }#ifdef LAYOUT_DEBUG_VERBOSE dump();#endif if (layout_info.isEmpty()) { if (relayout_type == QInternal::RelayoutDropped) { // probably splitting... } else if (!save_layout_info) { emit emptied(); } else { QLayout *parentLayout = qobject_cast<QLayout *>(parent()); if (parentLayout) parentLayout->removeItem(this); } } VDEBUG("END of remove"); return layoutitem; } } return 0;}/*! \reimp */void QDockWidgetLayout::addItem(QLayoutItem *layoutitem){ if (relayout_type == QInternal::RelayoutDropped && layoutitem->layout()) { // dropping a nested layout! return; } (void) insert(-1, layoutitem); invalidate();}/*! \reimp */void QDockWidgetLayout::setGeometry(const QRect &rect){ VDEBUG("QDockWidgetLayout::setGeometry: width %4d height %4d", rect.width(), rect.height()); QLayout::setGeometry(rect); if (relayout_type != QInternal::RelayoutDragging) { bool first = true; for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; const bool empty = info.item->isEmpty(); if (i > 0) layout_info.at(i - 1).item->widget()->setHidden(first || empty); if (!empty) first = false; } } QVector<QLayoutStruct> a(layout_info.count()); int x; const int separator_extent = parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent); for (x = 0; x < layout_info.count(); ++x) { const QDockWidgetLayoutInfo &info = layout_info.at(x); QLayoutStruct &ls = a[x]; ls.init(); ls.empty = info.item->isEmpty(); if (ls.empty && !info.is_dropped) continue; if (info.is_sep) { VDEBUG(" separator");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -