📄 qlayout_widget.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer 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 "qlayout_widget_p.h"#include "qdesigner_widget_p.h"#include "qdesigner_command_p.h"#include "layout_p.h"#include "invisible_widget_p.h"#include <QtDesigner/QtDesigner>#include <QtDesigner/QExtensionManager>#include <QtGui/QBitmap>#include <QtGui/QPixmapCache>#include <QtGui/QToolButton>#include <QtGui/QPainter>#include <QtGui/QApplication>#include <QtGui/QLayout>#include <QtGui/QAction>#include <QtGui/QMessageBox>#include <QtGui/qevent.h>#include <QtCore/qdebug.h>namespace qdesigner_internal {class FriendlyLayout: public QLayout{public: inline FriendlyLayout(): QLayout() { Q_ASSERT(0); } friend class ::QLayoutWidgetItem;};} // namespace qdesigner_internalusing namespace qdesigner_internal;// ---- QLayoutSupport ----QLayoutSupport::QLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent) : QObject(parent), m_formWindow(formWindow), m_widget(widget), m_currentIndex(-1), m_currentInsertMode(QDesignerLayoutDecorationExtension::InsertWidgetMode){ QPalette p; p.setColor(QPalette::Base, Qt::red); m_indicatorLeft = new InvisibleWidget(m_widget); m_indicatorLeft->setAutoFillBackground(true); m_indicatorLeft->setPalette(p); m_indicatorLeft->hide(); m_indicatorTop = new InvisibleWidget(m_widget); m_indicatorTop->setAutoFillBackground(true); m_indicatorTop->setPalette(p); m_indicatorTop->hide(); m_indicatorRight = new InvisibleWidget(m_widget); m_indicatorRight->setAutoFillBackground(true); m_indicatorRight->setPalette(p); m_indicatorRight->hide(); m_indicatorBottom = new InvisibleWidget(m_widget); m_indicatorBottom->setAutoFillBackground(true); m_indicatorBottom->setPalette(p); m_indicatorBottom->hide(); if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow->core()->extensionManager(), m_widget)) { sheet->setChanged(sheet->indexOf(QLatin1String("margin")), true); sheet->setChanged(sheet->indexOf(QLatin1String("spacing")), true); }}QLayoutSupport::~QLayoutSupport(){ if (m_indicatorLeft) m_indicatorLeft->deleteLater(); if (m_indicatorTop) m_indicatorTop->deleteLater(); if (m_indicatorRight) m_indicatorRight->deleteLater(); if (m_indicatorBottom) m_indicatorBottom->deleteLater();}void QLayoutSupport::tryRemoveRow(int row){ Q_ASSERT(gridLayout()); bool please_removeRow = true; int index = 0; while (QLayoutItem *item = gridLayout()->itemAt(index)) { QRect info = itemInfo(index); ++index; if (info.y() == row && !isEmptyItem(item)) { please_removeRow = false; break; } } if (please_removeRow) { removeRow(row); gridLayout()->invalidate(); }}void QLayoutSupport::removeRow(int row){ QHash<QLayoutItem*, QRect> infos; computeGridLayout(&infos); QMutableHashIterator<QLayoutItem*, QRect> it(infos); while (it.hasNext()) { it.next(); QRect info = it.value(); if (info.y() == row) { QLayoutItem *item = it.key(); it.remove(); layout()->takeAt(indexOf(item)); delete item; } else if (info.y() > row) { info.translate(0, -1); it.setValue(info); } } rebuildGridLayout(&infos);}void QLayoutSupport::removeColumn(int column){ QHash<QLayoutItem*, QRect> infos; computeGridLayout(&infos); QMutableHashIterator<QLayoutItem*, QRect> it(infos); while (it.hasNext()) { it.next(); QRect info = it.value(); if (info.x() == column) { QLayoutItem *item = it.key(); it.remove(); layout()->takeAt(indexOf(item)); delete item; } else if (info.x() > column) { info.translate(-1, 0); it.setValue(info); } } rebuildGridLayout(&infos);}void QLayoutSupport::tryRemoveColumn(int column){ Q_ASSERT(gridLayout()); bool please_removeColumn = true; int index = 0; while (QLayoutItem *item = gridLayout()->itemAt(index)) { QRect info = itemInfo(index); ++index; if (info.x() == column && !isEmptyItem(item)) { please_removeColumn = false; break; } } if (please_removeColumn) { removeColumn(column); gridLayout()->invalidate(); }}void QLayoutSupport::simplifyLayout(){ if (!gridLayout()) return; for (int r = 0; r < gridLayout()->rowCount(); ++r) { tryRemoveRow(r); } for (int c = 0; c < gridLayout()->columnCount(); ++c) { tryRemoveColumn(c); } if (QGridLayout *g = gridLayout()) createEmptyCells(g);}void QLayoutSupport::adjustIndicator(const QPoint &pos, int index){ if (index == -1) { m_indicatorLeft->hide(); m_indicatorTop->hide(); m_indicatorRight->hide(); m_indicatorBottom->hide(); return; } m_currentIndex = index; m_currentInsertMode = QDesignerLayoutDecorationExtension::InsertWidgetMode; QLayoutItem *item = layout()->itemAt(index); QRect g = extendedGeometry(index); int dx = g.right() - pos.x(); int dy = g.bottom() - pos.y(); int dx1 = pos.x() - g.x(); int dy1 = pos.y() - g.y(); int mx = qMin(dx, dx1); int my = qMin(dy, dy1); bool isVertical = mx < my; // ### cleanup if (isEmptyItem(item)) { QPalette p; p.setColor(QPalette::Background, Qt::red); m_indicatorRight->setPalette(p); m_indicatorBottom->setPalette(p); m_indicatorLeft->setGeometry(g.x(), g.y(), 2, g.height()); m_indicatorTop->setGeometry(g.x(), g.y(), g.width(), 2); m_indicatorRight->setGeometry(g.right(), g.y(), 2, g.height()); m_indicatorBottom->setGeometry(g.x(), g.bottom(), g.width(), 2); m_indicatorLeft->show(); m_indicatorLeft->raise(); m_indicatorTop->show(); m_indicatorTop->raise(); m_indicatorRight->show(); m_indicatorRight->raise(); m_indicatorBottom->show(); m_indicatorBottom->raise(); if (QGridLayout *gridLayout = qobject_cast<QGridLayout*>(layout())) { m_currentInsertMode = QDesignerLayoutDecorationExtension::InsertWidgetMode; int row, column, rowspan, colspan; gridLayout->getItemPosition(m_currentIndex, &row, &column, &rowspan, &colspan); m_currentCell = qMakePair(row, column); } else { qWarning("Warning: found a fake spacer inside a vbox layout"); m_currentCell = qMakePair(0, 0); } } else { QPalette p; p.setColor(QPalette::Background, Qt::blue); m_indicatorRight->setPalette(p); m_indicatorBottom->setPalette(p); QRect r(layout()->geometry().topLeft(), layout()->parentWidget()->size()); if (isVertical) { m_indicatorBottom->hide(); if (!qobject_cast<QVBoxLayout*>(layout())) { m_indicatorRight->setGeometry((mx == dx1) ? g.x() : g.right(), 0, 2, r.height()); m_indicatorRight->show(); m_indicatorRight->raise(); int incr = (mx == dx1) ? 0 : +1; if (qobject_cast<QGridLayout*>(layout())) { m_currentInsertMode = QDesignerLayoutDecorationExtension::InsertColumnMode; QRect info = itemInfo(m_currentIndex); m_currentCell = qMakePair(info.top(), incr ? info.right() + 1 : info.left()); } else if (QBoxLayout *box = qobject_cast<QBoxLayout*>(layout())) { m_currentCell = qMakePair(0, box->indexOf(item->widget()) + incr); } } } else { m_indicatorRight->hide(); if (!qobject_cast<QHBoxLayout*>(layout())) { m_indicatorBottom->setGeometry(r.x(), (my == dy1) ? g.y() : g.bottom(), r.width(), 2); m_indicatorBottom->show(); m_indicatorBottom->raise(); int incr = (my == dy1) ? 0 : +1; if (qobject_cast<QGridLayout*>(layout())) { m_currentInsertMode = QDesignerLayoutDecorationExtension::InsertRowMode; QRect info = itemInfo(m_currentIndex); m_currentCell = qMakePair(incr ? info.bottom() + 1 : info.top(), info.left()); } else if (QBoxLayout *box = qobject_cast<QBoxLayout*>(layout())) { m_currentCell = qMakePair(box->indexOf(item->widget()) + incr, 0); } } } m_indicatorLeft->hide(); m_indicatorTop->hide(); }}int QLayoutSupport::indexOf(QLayoutItem *i) const{ if (!layout()) return -1; int index = 0; while (QLayoutItem *item = layout()->itemAt(index)) { if (item == i) return index; ++index; } return -1;}int QLayoutSupport::indexOf(QWidget *widget) const{ if (!layout()) return -1; int index = 0; while (QLayoutItem *item = layout()->itemAt(index)) { if (item->widget() == widget) return index; ++index; } return -1;}QDesignerFormEditorInterface *QLayoutSupport::core() const{ return formWindow()->core();}void QLayoutSupport::removeWidget(QWidget *widget){ LayoutInfo::Type layoutType = LayoutInfo::layoutType(core(), m_widget); switch (layoutType) { case LayoutInfo::Grid: { int index = indexOf(widget); if (index != -1) { QGridLayout *gridLayout = qobject_cast<QGridLayout*>(layout()); Q_ASSERT(gridLayout); int row, column, rowspan, colspan; gridLayout->getItemPosition(index, &row, &column, &rowspan, &colspan); gridLayout->takeAt(index); QSpacerItem *spacer = new QSpacerItem(20, 20); gridLayout->addItem(spacer, row, column, rowspan, colspan); } } break; case LayoutInfo::VBox: case LayoutInfo::HBox: { QBoxLayout *box = static_cast<QBoxLayout*>(layout()); box->removeWidget(widget); } break; default: break; }}QList<QWidget*> QLayoutSupport::widgets(QLayout *layout) const{ if (!layout) return QList<QWidget*>(); QList<QWidget*> lst; int index = 0; while (QLayoutItem *item = layout->itemAt(index)) { ++index; QWidget *widget = item->widget(); if (widget && formWindow()->isManaged(widget)) lst.append(widget); } return lst;}void QLayoutSupport::insertWidget(QWidget *widget, const QPair<int, int> &cell){ QDesignerFormEditorInterface *core = formWindow()->core(); LayoutInfo::Type lt = LayoutInfo::layoutType(core, layout()); switch (lt) { case LayoutInfo::VBox: { QVBoxLayout *vbox = static_cast<QVBoxLayout*>(layout()); insert_into_box_layout(vbox, cell.first, widget); } break; case LayoutInfo::HBox: { QHBoxLayout *hbox = static_cast<QHBoxLayout*>(layout()); insert_into_box_layout(hbox, cell.second, widget); } break; case LayoutInfo::Grid: { int index = findItemAt(cell.first, cell.second); Q_ASSERT(index != -1); insertWidget(index, widget); } break; default: {#ifdef QD_DEBUG qWarning() << "expected a layout here!"; Q_ASSERT(0);#endif } } // end switch}int QLayoutSupport::findItemAt(int at_row, int at_column) const{ if (QGridLayout *gridLayout = qobject_cast<QGridLayout*>(layout())) return findItemAt(gridLayout, at_row, at_column); return -1;}int QLayoutSupport::findItemAt(QGridLayout *gridLayout, int at_row, int at_column){ Q_ASSERT(gridLayout); int index = 0; while (gridLayout->itemAt(index)) { int row, column, rowspan, colspan; gridLayout->getItemPosition(index, &row, &column, &rowspan, &colspan); if (at_row >= row && at_row < (row + rowspan)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -