diff options
Diffstat (limited to 'src/widgets')
45 files changed, 738 insertions, 2429 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 2e6518dd17..4c5fb18766 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -907,10 +907,8 @@ public: QColSpinBox(QWidget *parent) : QSpinBox(parent) { setRange(0, 255); } void setValue(int i) { - bool block = signalsBlocked(); - blockSignals(true); + const QSignalBlocker blocker(this); QSpinBox::setValue(i); - blockSignals(block); } }; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index da026d23a6..1c3a793234 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1723,7 +1723,7 @@ int QFileDialogPrivate::maxNameLength(const QString &path) { #if defined(Q_OS_UNIX) return ::pathconf(QFile::encodeName(path).data(), _PC_NAME_MAX); -#elif defined(Q_OS_WINCE) +#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT) Q_UNUSED(path); return MAX_PATH; #elif defined(Q_OS_WIN) @@ -2621,9 +2621,8 @@ void QFileDialog::accept() // special case for ".." if (lineEditText == QLatin1String("..")) { d->_q_navigateToParent(); - bool block = d->qFileDialogUi->fileNameEdit->blockSignals(true); + const QSignalBlocker blocker(d->qFileDialogUi->fileNameEdit); d->lineEdit()->selectAll(); - d->qFileDialogUi->fileNameEdit->blockSignals(block); return; } diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index fa6306005b..bda448bde3 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -1715,7 +1715,7 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile #ifndef QT_NO_FILESYSTEMWATCHER node->populate(info); #endif -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //The parentNode is "" so we are listing the drives if (parentNode->fileName.isEmpty()) { wchar_t name[MAX_PATH + 1]; diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index d908a683a9..94e96a52c5 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -632,12 +632,11 @@ void QFontDialogPrivate::updateSizes() } sizeList->setCurrentItem(current); - sizeEdit->blockSignals(true); + const QSignalBlocker blocker(sizeEdit); sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText())); if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) && sizeList->hasFocus()) sizeEdit->selectAll(); - sizeEdit->blockSignals(false); } else { sizeEdit->clear(); } @@ -750,9 +749,8 @@ void QFontDialogPrivate::_q_sizeChanged(const QString &s) if (sizeList->text(i).toInt() >= this->size) break; } - sizeList->blockSignals(true); + const QSignalBlocker blocker(sizeList); sizeList->setCurrentItem(i); - sizeList->blockSignals(false); } _q_updateSample(); } diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp index 4eec2eb3e2..10d693b4a3 100644 --- a/src/widgets/dialogs/qinputdialog.cpp +++ b/src/widgets/dialogs/qinputdialog.cpp @@ -771,10 +771,11 @@ void QInputDialog::setComboBoxItems(const QStringList &items) Q_D(QInputDialog); d->ensureComboBox(); - d->comboBox->blockSignals(true); - d->comboBox->clear(); - d->comboBox->addItems(items); - d->comboBox->blockSignals(false); + { + const QSignalBlocker blocker(d->comboBox); + d->comboBox->clear(); + d->comboBox->addItems(items); + } if (inputMode() == TextInput) d->chooseRightTextInputWidget(); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ee2ef409d8..1b64b0ba67 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) HMENU qt_getWindowsSystemMenu(const QWidget *w) { if (QWindow *window = QApplicationPrivate::windowForWidget(w)) @@ -1620,7 +1620,7 @@ void QMessageBox::showEvent(QShowEvent *e) QAccessibleEvent event(this, QAccessible::Alert); QAccessible::updateAccessibility(&event); #endif -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) if (const HMENU systemMenu = qt_getWindowsSystemMenu(this)) { EnableMenuItem(systemMenu, SC_CLOSE, d->detectedEscapeButton ? MF_BYCOMMAND|MF_ENABLED : MF_BYCOMMAND|MF_GRAYED); diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index a667f299e8..0ad1dad1b8 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -129,22 +129,41 @@ static bool objectInheritsXAndXIsCloserThanY(const QObject *object, const QByteA return false; } -const int NFallbackDefaultProperties = 7; - const struct { - const char *className; - const char *property; - const char *changedSignal; -} fallbackProperties[NFallbackDefaultProperties] = { + const char className[16]; + const char property[13]; +} fallbackProperties[] = { // If you modify this list, make sure to update the documentation (and the auto test) - { "QAbstractButton", "checked", SIGNAL(toggled(bool)) }, - { "QAbstractSlider", "value", SIGNAL(valueChanged(int)) }, - { "QComboBox", "currentIndex", SIGNAL(currentIndexChanged(int)) }, - { "QDateTimeEdit", "dateTime", SIGNAL(dateTimeChanged(QDateTime)) }, - { "QLineEdit", "text", SIGNAL(textChanged(QString)) }, - { "QListWidget", "currentRow", SIGNAL(currentRowChanged(int)) }, - { "QSpinBox", "value", SIGNAL(valueChanged(int)) } + { "QAbstractButton", "checked" }, + { "QAbstractSlider", "value" }, + { "QComboBox", "currentIndex" }, + { "QDateTimeEdit", "dateTime" }, + { "QLineEdit", "text" }, + { "QListWidget", "currentRow" }, + { "QSpinBox", "value" }, }; +const size_t NFallbackDefaultProperties = sizeof fallbackProperties / sizeof *fallbackProperties; + +static const char *changed_signal(int which) +{ + // since it might expand to a runtime function call (to + // qFlagLocations()), we cannot store the result of SIGNAL() in a + // character array and expect it to be statically initialized. To + // avoid the relocations caused by a char pointer table, use a + // switch statement: + switch (which) { + case 0: return SIGNAL(toggled(bool)); + case 1: return SIGNAL(valueChanged(int)); + case 2: return SIGNAL(currentIndexChanged(int)); + case 3: return SIGNAL(dateTimeChanged(QDateTime)); + case 4: return SIGNAL(textChanged(QString)); + case 5: return SIGNAL(currentRowChanged(int)); + case 6: return SIGNAL(valueChanged(int)); + }; + Q_STATIC_ASSERT(7 == NFallbackDefaultProperties); + Q_UNREACHABLE(); + return 0; +} class QWizardDefaultProperty { @@ -737,10 +756,10 @@ void QWizardPrivate::init() updateButtonLayout(); - for (int i = 0; i < NFallbackDefaultProperties; ++i) + for (uint i = 0; i < NFallbackDefaultProperties; ++i) defaultPropertyTable.append(QWizardDefaultProperty(fallbackProperties[i].className, fallbackProperties[i].property, - fallbackProperties[i].changedSignal)); + changed_signal(i))); } void QWizardPrivate::reset() @@ -887,9 +906,28 @@ void QWizardPrivate::switchToPage(int newId, Direction direction) } // keep in sync with QWizard::WizardButton -static const char * const buttonSlots[QWizard::NStandardButtons] = { - SLOT(back()), SLOT(next()), SLOT(next()), SLOT(accept()), SLOT(reject()), - SIGNAL(helpRequested()) +static const char * buttonSlots(QWizard::WizardButton which) +{ + switch (which) { + case QWizard::BackButton: + return SLOT(back()); + case QWizard::NextButton: + case QWizard::CommitButton: + return SLOT(next()); + case QWizard::FinishButton: + return SLOT(accept()); + case QWizard::CancelButton: + return SLOT(reject()); + case QWizard::HelpButton: + return SIGNAL(helpRequested()); + case QWizard::CustomButton1: + case QWizard::CustomButton2: + case QWizard::CustomButton3: + case QWizard::Stretch: + case QWizard::NoButton: + Q_UNREACHABLE(); + }; + return 0; }; QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage() @@ -1405,7 +1443,7 @@ void QWizardPrivate::connectButton(QWizard::WizardButton which) const { Q_Q(const QWizard); if (which < QWizard::NStandardButtons) { - QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots[which]); + QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots(which)); } else { QObject::connect(btns[which], SIGNAL(clicked()), q, SLOT(_q_emitCustomButtonClicked())); } @@ -1576,7 +1614,7 @@ bool QWizardPrivate::handleAeroStyleChange() if (isWindow) vistaHelper->setTitleBarIconAndCaptionVisible(false); QObject::connect( - vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots[QWizard::BackButton]); + vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots(QWizard::BackButton)); vistaHelper->backButton()->show(); } else { q->setMouseTracking(true); // ### original value possibly different diff --git a/src/widgets/graphicsview/graphicsview.pri b/src/widgets/graphicsview/graphicsview.pri index a0fc4bc8d3..b81f736ef4 100644 --- a/src/widgets/graphicsview/graphicsview.pri +++ b/src/widgets/graphicsview/graphicsview.pri @@ -23,7 +23,8 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ - graphicsview/qgridlayoutengine_p.h \ + graphicsview/qgraphicslayoutstyleinfo_p.h \ + graphicsview/qgraphicsgridlayoutengine_p.h \ graphicsview/qgraph_p.h \ graphicsview/qsimplex_p.h \ graphicsview/qgraphicsanchorlayout_p.h \ @@ -47,7 +48,8 @@ SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicsview.cpp \ graphicsview/qgraphicswidget.cpp \ graphicsview/qgraphicswidget_p.cpp \ - graphicsview/qgridlayoutengine.cpp \ + graphicsview/qgraphicslayoutstyleinfo.cpp \ + graphicsview/qgraphicsgridlayoutengine.cpp \ graphicsview/qsimplex_p.cpp \ graphicsview/qgraphicsanchorlayout_p.cpp \ graphicsview/qgraphicsanchorlayout.cpp diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.cpp b/src/widgets/graphicsview/qgraphicsgridlayout.cpp index 6d9dd98839..0ecb4af6bd 100644 --- a/src/widgets/graphicsview/qgraphicsgridlayout.cpp +++ b/src/widgets/graphicsview/qgraphicsgridlayout.cpp @@ -89,30 +89,35 @@ #include "qgraphicslayoutitem.h" #include "qgraphicsgridlayout.h" #include "qgraphicswidget.h" -#include "qgridlayoutengine_p.h" -#include <QtCore/qdebug.h> +#include "qgraphicsgridlayoutengine_p.h" +#include "qgraphicslayoutstyleinfo_p.h" +#ifdef QT_DEBUG +# include <QtCore/qdebug.h> +#endif QT_BEGIN_NAMESPACE class QGraphicsGridLayoutPrivate : public QGraphicsLayoutPrivate { public: - QGraphicsGridLayoutPrivate() { } - QLayoutStyleInfo styleInfo() const; + QGraphicsGridLayoutPrivate(): m_styleInfo(0) { } + QGraphicsLayoutStyleInfo *styleInfo() const; - QGridLayoutEngine engine; -#ifdef QT_DEBUG + mutable QGraphicsLayoutStyleInfo *m_styleInfo; + QGraphicsGridLayoutEngine engine; + +#ifdef QGRIDLAYOUTENGINE_DEBUG void dump(int indent) const; #endif }; -Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget); -QLayoutStyleInfo QGraphicsGridLayoutPrivate::styleInfo() const +QGraphicsLayoutStyleInfo *QGraphicsGridLayoutPrivate::styleInfo() const { - QGraphicsItem *item = parentItem(); - QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style(); - return QLayoutStyleInfo(style, globalStyleInfoWidget()); + if (!m_styleInfo) + m_styleInfo = new QGraphicsLayoutStyleInfo(this); + m_styleInfo->updateChanged(QAbstractLayoutStyleInfo::Unknown); + return m_styleInfo; } /*! @@ -172,7 +177,8 @@ void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column d->addChildLayoutItem(item); - new QGridLayoutItem(&d->engine, item, row, column, rowSpan, columnSpan, alignment); + QGraphicsGridLayoutEngineItem *gridEngineItem = new QGraphicsGridLayoutEngineItem(item, row, column, rowSpan, columnSpan, alignment); + d->engine.insertItem(gridEngineItem, -1); invalidate(); } @@ -199,7 +205,7 @@ void QGraphicsGridLayout::setHorizontalSpacing(qreal spacing) qreal QGraphicsGridLayout::horizontalSpacing() const { Q_D(const QGraphicsGridLayout); - return d->engine.spacing(d->styleInfo(), Qt::Horizontal); + return d->engine.spacing(Qt::Horizontal, d->styleInfo()); } /*! @@ -218,7 +224,7 @@ void QGraphicsGridLayout::setVerticalSpacing(qreal spacing) qreal QGraphicsGridLayout::verticalSpacing() const { Q_D(const QGraphicsGridLayout); - return d->engine.spacing(d->styleInfo(), Qt::Vertical); + return d->engine.spacing(Qt::Vertical, d->styleInfo()); } /*! @@ -535,8 +541,8 @@ QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int row, int column) const qWarning("QGraphicsGridLayout::itemAt: invalid row, column %d, %d", row, column); return 0; } - if (QGridLayoutItem *item = d->engine.itemAt(row, column)) - return item->layoutItem(); + if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(row, column))) + return engineItem->layoutItem(); return 0; } @@ -561,8 +567,8 @@ QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int index) const return 0; } QGraphicsLayoutItem *item = 0; - if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) - item = gridItem->layoutItem(); + if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) + item = engineItem->layoutItem(); return item; } @@ -579,7 +585,8 @@ void QGraphicsGridLayout::removeAt(int index) qWarning("QGraphicsGridLayout::removeAt: invalid index %d", index); return; } - if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) { + + if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) { if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem()) layoutItem->setParentLayoutItem(0); d->engine.removeItem(gridItem); @@ -619,10 +626,12 @@ void QGraphicsGridLayout::invalidate() { Q_D(QGraphicsGridLayout); d->engine.invalidate(); + if (d->m_styleInfo) + d->m_styleInfo->invalidate(); QGraphicsLayout::invalidate(); } -#ifdef QT_DEBUG +#ifdef QGRIDLAYOUTENGINE_DEBUG void QGraphicsGridLayoutPrivate::dump(int indent) const { if (qt_graphicsLayoutDebug()) { @@ -646,8 +655,8 @@ void QGraphicsGridLayout::setGeometry(const QRectF &rect) if (visualDir == Qt::RightToLeft) qSwap(left, right); effectiveRect.adjust(+left, +top, -right, -bottom); - d->engine.setGeometries(d->styleInfo(), effectiveRect); -#ifdef QT_DEBUG + d->engine.setGeometries(effectiveRect, d->styleInfo()); +#ifdef QGRIDLAYOUTENGINE_DEBUG if (qt_graphicsLayoutDebug()) { static int counter = 0; qDebug("==== BEGIN DUMP OF QGraphicsGridLayout (%d)====", counter++); @@ -666,7 +675,7 @@ QSizeF QGraphicsGridLayout::sizeHint(Qt::SizeHint which, const QSizeF &constrain qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); const QSizeF extraMargins(left + right, top + bottom); - return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; + return d->engine.sizeHint(which , constraint - extraMargins, d->styleInfo()) + extraMargins; } diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp new file mode 100644 index 0000000000..6de41c308b --- /dev/null +++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgraphicsgridlayoutengine_p.h" +#include "qgraphicslayoutitem_p.h" +#include "qgraphicslayout_p.h" +#include "qgraphicswidget.h" + +QT_BEGIN_NAMESPACE + +/* + returns \c true if the size policy returns \c true for either hasHeightForWidth() + or hasWidthForHeight() + */ +bool QGraphicsGridLayoutEngineItem::hasDynamicConstraint() const +{ + return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() + || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); +} + +Qt::Orientation QGraphicsGridLayoutEngineItem::dynamicConstraintOrientation() const +{ + if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) + return Qt::Vertical; + else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) + return Qt::Horizontal; +} + + +void QGraphicsGridLayoutEngine::setAlignment(QGraphicsLayoutItem *graphicsLayoutItem, Qt::Alignment alignment) +{ + if (QGraphicsGridLayoutEngineItem *gridEngineItem = findLayoutItem(graphicsLayoutItem)) { + gridEngineItem->setAlignment(alignment); + invalidate(); + } +} + +Qt::Alignment QGraphicsGridLayoutEngine::alignment(QGraphicsLayoutItem *graphicsLayoutItem) const +{ + if (QGraphicsGridLayoutEngineItem *gridEngineItem = findLayoutItem(graphicsLayoutItem)) + return gridEngineItem->alignment(); + return 0; +} + + +void QGraphicsGridLayoutEngine::setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, + Qt::Orientation orientation) +{ + Q_ASSERT(stretch >= 0); + + if (QGraphicsGridLayoutEngineItem *item = findLayoutItem(layoutItem)) + item->setStretchFactor(stretch, orientation); +} + +int QGraphicsGridLayoutEngine::stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const +{ + if (QGraphicsGridLayoutEngineItem *item = findLayoutItem(layoutItem)) + return item->stretchFactor(orientation); + return 0; +} + + +QT_END_NAMESPACE diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h new file mode 100644 index 0000000000..1e987e30d2 --- /dev/null +++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSGRIDLAYOUTENGINE_P_H +#define QGRAPHICSGRIDLAYOUTENGINE_P_H + +#include <QtGui/private/qgridlayoutengine_p.h> + +#include <QtWidgets/qsizepolicy.h> +#include <QtWidgets/qstyle.h> +#include <QtWidgets/qstyleoption.h> +#include "qgraphicslayoutitem.h" + +QT_BEGIN_NAMESPACE + +class QGraphicsLayoutPrivate; + +class QGraphicsGridLayoutEngineItem : public QGridLayoutItem { +public: + QGraphicsGridLayoutEngineItem(QGraphicsLayoutItem *item, int row, int columns, int rowSpan = 1, int columnSpan = 1, + Qt::Alignment alignment = 0) + : QGridLayoutItem(row, columns, rowSpan, columnSpan, alignment), q_layoutItem(item) {} + + virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const Q_DECL_OVERRIDE + { + QSizePolicy sizePolicy(q_layoutItem->sizePolicy()); + return (QLayoutPolicy::Policy)((orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy() + : sizePolicy.verticalPolicy()); + } + + virtual QLayoutPolicy::ControlTypes controlTypes(LayoutSide) const Q_DECL_OVERRIDE + { + const QSizePolicy::ControlType ct = q_layoutItem->sizePolicy().controlType(); + return (QLayoutPolicy::ControlTypes)ct; + } + + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const Q_DECL_OVERRIDE + { + return q_layoutItem->effectiveSizeHint(which, constraint); + } + + virtual void setGeometry(const QRectF &rect) Q_DECL_OVERRIDE + { + q_layoutItem->setGeometry(rect); + } + + virtual bool hasDynamicConstraint() const Q_DECL_OVERRIDE; + virtual Qt::Orientation dynamicConstraintOrientation() const Q_DECL_OVERRIDE; + + QGraphicsLayoutItem *layoutItem() const { return q_layoutItem; } + +protected: + QGraphicsLayoutItem *q_layoutItem; +}; + + +class QGraphicsGridLayoutEngine : public QGridLayoutEngine +{ +public: + QGraphicsGridLayoutEngineItem *findLayoutItem(QGraphicsLayoutItem *layoutItem) const + { + const int index = indexOf(layoutItem); + if (index < 0) + return 0; + return static_cast<QGraphicsGridLayoutEngineItem*>(q_items.at(index)); + } + + int indexOf(QGraphicsLayoutItem *item) const + { + for (int i = 0; i < q_items.count(); ++i) { + if (item == static_cast<QGraphicsGridLayoutEngineItem*>(q_items.at(i))->layoutItem()) + return i; + } + return -1; + } + + void setAlignment(QGraphicsLayoutItem *graphicsLayoutItem, Qt::Alignment alignment); + Qt::Alignment alignment(QGraphicsLayoutItem *graphicsLayoutItem) const; + + void setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, Qt::Orientation orientation); + int stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const; + +}; + +QT_END_NAMESPACE + +#endif // QGRAPHICSGRIDLAYOUTENGINE_P_H diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp new file mode 100644 index 0000000000..3270fc20a3 --- /dev/null +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qgraphicslayoutstyleinfo_p.h" +#include "qgraphicslayout_p.h" +#include "qgraphicswidget.h" +#include <QtWidgets/qstyle.h> +#include <QtWidgets/qwidget.h> +#include <QtWidgets/qapplication.h> + +QT_BEGIN_NAMESPACE + +QGraphicsLayoutStyleInfo::QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout) + : m_layout(layout), m_style(0) +{ + m_widget = new QWidget; // pixelMetric might need a widget ptr + if (m_widget) + m_styleOption.initFrom(m_widget); + m_isWindow = m_styleOption.state & QStyle::State_Window; +} + +QGraphicsLayoutStyleInfo::~QGraphicsLayoutStyleInfo() +{ + delete m_widget; +} + +qreal QGraphicsLayoutStyleInfo::combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1, + QLayoutPolicy::ControlTypes controls2, + Qt::Orientation orientation) const +{ + Q_ASSERT(style()); + return style()->combinedLayoutSpacing(QSizePolicy::ControlTypes(int(controls1)), QSizePolicy::ControlTypes(int(controls2)), + orientation, const_cast<QStyleOption*>(&m_styleOption), widget()); +} + +qreal QGraphicsLayoutStyleInfo::perItemSpacing(QLayoutPolicy::ControlType control1, + QLayoutPolicy::ControlType control2, + Qt::Orientation orientation) const +{ + Q_ASSERT(style()); + return style()->layoutSpacing(QSizePolicy::ControlType(control1), QSizePolicy::ControlType(control2), + orientation, const_cast<QStyleOption*>(&m_styleOption), widget()); +} + +qreal QGraphicsLayoutStyleInfo::spacing(Qt::Orientation orientation) const +{ + Q_ASSERT(style()); + return style()->pixelMetric(orientation == Qt::Horizontal ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing); +} + +qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const +{ + return style()->pixelMetric(orientation == Qt::Vertical + ? QStyle::PM_LayoutBottomMargin + : QStyle::PM_LayoutRightMargin, + const_cast<QStyleOption*>(&m_styleOption), widget()); +} + +QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget; } + +QStyle *QGraphicsLayoutStyleInfo::style() const +{ + if (!m_style) { + Q_ASSERT(m_layout); + QGraphicsItem *item = m_layout->parentItem(); + m_style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style(); + } + return m_style; +} + +QT_END_NAMESPACE diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h new file mode 100644 index 0000000000..275ebab6a1 --- /dev/null +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QGRAPHICSLAYOUTSTYLEINFO_P_H +#define QGRAPHICSLAYOUTSTYLEINFO_P_H + +#include <QtGui/private/qabstractlayoutstyleinfo_p.h> +#include <QtWidgets/qstyleoption.h> + +QT_BEGIN_NAMESPACE + +class QStyle; +class QWidget; +class QGraphicsLayoutPrivate; + +class QGraphicsLayoutStyleInfo : public QAbstractLayoutStyleInfo +{ +public: + QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout); + ~QGraphicsLayoutStyleInfo(); + + virtual qreal combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1, + QLayoutPolicy::ControlTypes controls2, + Qt::Orientation orientation) const Q_DECL_OVERRIDE; + + virtual qreal perItemSpacing(QLayoutPolicy::ControlType control1, + QLayoutPolicy::ControlType control2, + Qt::Orientation orientation) const Q_DECL_OVERRIDE; + + virtual qreal spacing(Qt::Orientation orientation) const Q_DECL_OVERRIDE; + + virtual qreal windowMargin(Qt::Orientation orientation) const Q_DECL_OVERRIDE; + + virtual void invalidate() Q_DECL_OVERRIDE + { + m_style = 0; + QAbstractLayoutStyleInfo::invalidate(); + } + + virtual bool hasChangedCore() const Q_DECL_OVERRIDE + { + QStyle *s = m_style; + // Note that style() will change m_style + return s != style(); + } + + QWidget *widget() const; + QStyle *style() const; + +private: + const QGraphicsLayoutPrivate *m_layout; + mutable QStyle *m_style; + QStyleOption m_styleOption; + QWidget *m_widget; +}; + +QT_END_NAMESPACE + +#endif // QGRAPHICSLAYOUTSTYLEINFO_P_H
\ No newline at end of file diff --git a/src/widgets/graphicsview/qgraphicslinearlayout.cpp b/src/widgets/graphicsview/qgraphicslinearlayout.cpp index 00076502ea..5c438e0495 100644 --- a/src/widgets/graphicsview/qgraphicslinearlayout.cpp +++ b/src/widgets/graphicsview/qgraphicslinearlayout.cpp @@ -122,7 +122,8 @@ #include "qgraphicslayoutitem.h" #include "qgraphicslinearlayout.h" #include "qgraphicswidget.h" -#include "qgridlayoutengine_p.h" +#include "qgraphicsgridlayoutengine_p.h" +#include "qgraphicslayoutstyleinfo_p.h" #ifdef QT_DEBUG #include <QtCore/qdebug.h> #endif @@ -132,16 +133,20 @@ QT_BEGIN_NAMESPACE class QGraphicsLinearLayoutPrivate : public QGraphicsLayoutPrivate { public: - QGraphicsLinearLayoutPrivate(Qt::Orientation orientation) : orientation(orientation) { } + QGraphicsLinearLayoutPrivate(Qt::Orientation orientation) + : orientation(orientation), + m_styleInfo(0) + { } void removeGridItem(QGridLayoutItem *gridItem); - QLayoutStyleInfo styleInfo() const; + QGraphicsLayoutStyleInfo *styleInfo() const; void fixIndex(int *index) const; int gridRow(int index) const; int gridColumn(int index) const; Qt::Orientation orientation; - QGridLayoutEngine engine; + mutable QGraphicsLayoutStyleInfo *m_styleInfo; + QGraphicsGridLayoutEngine engine; }; void QGraphicsLinearLayoutPrivate::removeGridItem(QGridLayoutItem *gridItem) @@ -172,13 +177,12 @@ int QGraphicsLinearLayoutPrivate::gridColumn(int index) const return int(qMin(uint(index), uint(engine.columnCount()))); } -Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget) - -QLayoutStyleInfo QGraphicsLinearLayoutPrivate::styleInfo() const +QGraphicsLayoutStyleInfo *QGraphicsLinearLayoutPrivate::styleInfo() const { - QGraphicsItem *item = parentItem(); - QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style(); - return QLayoutStyleInfo(style, globalStyleInfoWidget()); + if (!m_styleInfo) + m_styleInfo = new QGraphicsLayoutStyleInfo(this); + m_styleInfo->updateChanged(QAbstractLayoutStyleInfo::Unknown); + return m_styleInfo; } /*! @@ -281,7 +285,8 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); - new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); + QGraphicsGridLayoutEngineItem *gridEngineItem = new QGraphicsGridLayoutEngineItem(item, d->gridRow(index), d->gridColumn(index), 1, 1, 0); + d->engine.insertItem(gridEngineItem, index); invalidate(); } @@ -309,7 +314,7 @@ void QGraphicsLinearLayout::insertStretch(int index, int stretch) void QGraphicsLinearLayout::removeItem(QGraphicsLayoutItem *item) { Q_D(QGraphicsLinearLayout); - if (QGridLayoutItem *gridItem = d->engine.findLayoutItem(item)) { + if (QGraphicsGridLayoutEngineItem *gridItem = d->engine.findLayoutItem(item)) { item->setParentLayoutItem(0); d->removeGridItem(gridItem); delete gridItem; @@ -330,7 +335,8 @@ void QGraphicsLinearLayout::removeAt(int index) qWarning("QGraphicsLinearLayout::removeAt: invalid index %d", index); return; } - if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) { + + if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) { if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem()) layoutItem->setParentLayoutItem(0); d->removeGridItem(gridItem); @@ -365,7 +371,7 @@ void QGraphicsLinearLayout::setSpacing(qreal spacing) qreal QGraphicsLinearLayout::spacing() const { Q_D(const QGraphicsLinearLayout); - return d->engine.spacing(d->styleInfo(), d->orientation); + return d->engine.spacing(d->orientation, d->styleInfo()); } /*! @@ -485,7 +491,7 @@ QGraphicsLayoutItem *QGraphicsLinearLayout::itemAt(int index) const return 0; } QGraphicsLayoutItem *item = 0; - if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) + if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem *>(d->engine.itemAt(index))) item = gridItem->layoutItem(); return item; } @@ -505,15 +511,15 @@ void QGraphicsLinearLayout::setGeometry(const QRectF &rect) if (visualDir == Qt::RightToLeft) qSwap(left, right); effectiveRect.adjust(+left, +top, -right, -bottom); -#ifdef QT_DEBUG +#ifdef QGRIDLAYOUTENGINE_DEBUG if (qt_graphicsLayoutDebug()) { static int counter = 0; qDebug() << counter++ << "QGraphicsLinearLayout::setGeometry - " << rect; dump(1); } #endif - d->engine.setGeometries(d->styleInfo(), effectiveRect); -#ifdef QT_DEBUG + d->engine.setGeometries(effectiveRect, d->styleInfo()); +#ifdef QGRIDLAYOUTENGINE_DEBUG if (qt_graphicsLayoutDebug()) { qDebug() << "post dump"; dump(1); @@ -530,7 +536,7 @@ QSizeF QGraphicsLinearLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); const QSizeF extraMargins(left + right, top + bottom); - return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; + return d->engine.sizeHint(which , constraint - extraMargins, d->styleInfo()) + extraMargins; } /*! @@ -540,6 +546,8 @@ void QGraphicsLinearLayout::invalidate() { Q_D(QGraphicsLinearLayout); d->engine.invalidate(); + if (d->m_styleInfo) + d->m_styleInfo->invalidate(); QGraphicsLayout::invalidate(); } @@ -548,7 +556,7 @@ void QGraphicsLinearLayout::invalidate() */ void QGraphicsLinearLayout::dump(int indent) const { -#ifdef QT_DEBUG +#ifdef QGRIDLAYOUTENGINE_DEBUG if (qt_graphicsLayoutDebug()) { Q_D(const QGraphicsLinearLayout); qDebug("%*s%s layout", indent, "", diff --git a/src/widgets/graphicsview/qgridlayoutengine.cpp b/src/widgets/graphicsview/qgridlayoutengine.cpp deleted file mode 100644 index a1affdb55e..0000000000 --- a/src/widgets/graphicsview/qgridlayoutengine.cpp +++ /dev/null @@ -1,1745 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglobal.h" - -#ifndef QT_NO_GRAPHICSVIEW - -#include <math.h> - -#include "qgraphicslayoutitem.h" -#include "qgridlayoutengine_p.h" -#include "qstyleoption.h" -#include "qvarlengtharray.h" - -#include <QtDebug> -#include <QtCore/qmath.h> - -QT_BEGIN_NAMESPACE - -template <typename T> -static void insertOrRemoveItems(QVector<T> &items, int index, int delta) -{ - int count = items.count(); - if (index < count) { - if (delta > 0) { - items.insert(index, delta, T()); - } else if (delta < 0) { - items.remove(index, qMin(-delta, count - index)); - } - } -} - -static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) -{ - Q_ASSERT(sumDesired != 0.0); - return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); -} - -static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize) -{ - if (descent < 0.0) - return -1.0; - - Q_ASSERT(descent >= 0.0); - Q_ASSERT(ascent >= 0.0); - Q_ASSERT(targetSize >= ascent + descent); - - qreal extra = targetSize - (ascent + descent); - return descent + (extra / 2.0); -} - -static qreal compare(const QGridLayoutBox &box1, const QGridLayoutBox &box2, int which) -{ - qreal size1 = box1.q_sizes(which); - qreal size2 = box2.q_sizes(which); - - if (which == MaximumSize) { - return size2 - size1; - } else { - return size1 - size2; - } -} - -void QGridLayoutBox::add(const QGridLayoutBox &other, int stretch, qreal spacing) -{ - Q_ASSERT(q_minimumDescent < 0.0); - - q_minimumSize += other.q_minimumSize + spacing; - q_preferredSize += other.q_preferredSize + spacing; - q_maximumSize += ((stretch == 0) ? other.q_preferredSize : other.q_maximumSize) + spacing; -} - -void QGridLayoutBox::combine(const QGridLayoutBox &other) -{ - q_minimumDescent = qMax(q_minimumDescent, other.q_minimumDescent); - q_minimumAscent = qMax(q_minimumAscent, other.q_minimumAscent); - - q_minimumSize = qMax(q_minimumAscent + q_minimumDescent, - qMax(q_minimumSize, other.q_minimumSize)); - qreal maxMax; - if (q_maximumSize == FLT_MAX && other.q_maximumSize != FLT_MAX) - maxMax = other.q_maximumSize; - else if (other.q_maximumSize == FLT_MAX && q_maximumSize != FLT_MAX) - maxMax = q_maximumSize; - else - maxMax = qMax(q_maximumSize, other.q_maximumSize); - - q_maximumSize = qMax(q_minimumSize, maxMax); - q_preferredSize = qBound(q_minimumSize, qMax(q_preferredSize, other.q_preferredSize), - q_maximumSize); -} - -void QGridLayoutBox::normalize() -{ - q_maximumSize = qMax(qreal(0.0), q_maximumSize); - q_minimumSize = qBound(qreal(0.0), q_minimumSize, q_maximumSize); - q_preferredSize = qBound(q_minimumSize, q_preferredSize, q_maximumSize); - q_minimumDescent = qMin(q_minimumDescent, q_minimumSize); - - Q_ASSERT((q_minimumDescent < 0.0) == (q_minimumAscent < 0.0)); -} - -#ifdef QT_DEBUG -void QGridLayoutBox::dump(int indent) const -{ - qDebug("%*sBox (%g <= %g <= %g [%g/%g])", indent, "", q_minimumSize, q_preferredSize, - q_maximumSize, q_minimumAscent, q_minimumDescent); -} -#endif - -bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2) -{ - for (int i = 0; i < NSizes; ++i) { - if (box1.q_sizes(i) != box2.q_sizes(i)) - return false; - } - return box1.q_minimumDescent == box2.q_minimumDescent - && box1.q_minimumAscent == box2.q_minimumAscent; -} - -void QGridLayoutRowData::reset(int count) -{ - ignore.fill(false, count); - boxes.fill(QGridLayoutBox(), count); - multiCellMap.clear(); - stretches.fill(0, count); - spacings.fill(0.0, count); - hasIgnoreFlag = false; -} - -void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) -{ - MultiCellMap::const_iterator i = multiCellMap.constBegin(); - for (; i != multiCellMap.constEnd(); ++i) { - int start = i.key().first; - int span = i.key().second; - int end = start + span; - const QGridLayoutBox &box = i.value().q_box; - int stretch = i.value().q_stretch; - - QGridLayoutBox totalBox = this->totalBox(start, end); - QVarLengthArray<QGridLayoutBox> extras(span); - QVarLengthArray<qreal> dummy(span); - QVarLengthArray<qreal> newSizes(span); - - for (int j = 0; j < NSizes; ++j) { - qreal extra = compare(box, totalBox, j); - if (extra > 0.0) { - calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(), - 0, totalBox, rowInfo); - - for (int k = 0; k < span; ++k) - extras[k].q_sizes(j) = newSizes[k]; - } - } - - for (int k = 0; k < span; ++k) { - boxes[start + k].combine(extras[k]); - if (stretch != 0) - stretches[start + k] = qMax(stretches[start + k], stretch); - } - } - multiCellMap.clear(); -} - -void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSize, qreal *positions, - qreal *sizes, qreal *descents, - const QGridLayoutBox &totalBox, - const QGridLayoutRowInfo &rowInfo) -{ - Q_ASSERT(end > start); - - targetSize = qMax(totalBox.q_minimumSize, targetSize); - - int n = end - start; - QVarLengthArray<qreal> newSizes(n); - QVarLengthArray<qreal> factors(n); - qreal sumFactors = 0.0; - int sumStretches = 0; - qreal sumAvailable; - - for (int i = 0; i < n; ++i) { - if (stretches[start + i] > 0) - sumStretches += stretches[start + i]; - } - - if (targetSize < totalBox.q_preferredSize) { - stealBox(start, end, MinimumSize, positions, sizes); - - sumAvailable = targetSize - totalBox.q_minimumSize; - if (sumAvailable > 0.0) { - qreal sumDesired = totalBox.q_preferredSize - totalBox.q_minimumSize; - - for (int i = 0; i < n; ++i) { - if (ignore.testBit(start + i)) { - factors[i] = 0.0; - continue; - } - - const QGridLayoutBox &box = boxes.at(start + i); - qreal desired = box.q_preferredSize - box.q_minimumSize; - factors[i] = growthFactorBelowPreferredSize(desired, sumAvailable, sumDesired); - sumFactors += factors[i]; - } - - for (int i = 0; i < n; ++i) { - Q_ASSERT(sumFactors > 0.0); - qreal delta = sumAvailable * factors[i] / sumFactors; - newSizes[i] = sizes[i] + delta; - } - } - } else { - bool isLargerThanMaximum = (targetSize > totalBox.q_maximumSize); - if (isLargerThanMaximum) { - stealBox(start, end, MaximumSize, positions, sizes); - sumAvailable = targetSize - totalBox.q_maximumSize; - } else { - stealBox(start, end, PreferredSize, positions, sizes); - sumAvailable = targetSize - totalBox.q_preferredSize; - } - - if (sumAvailable > 0.0) { - qreal sumCurrentAvailable = sumAvailable; - bool somethingHasAMaximumSize = false; - - qreal sumSizes = 0.0; - for (int i = 0; i < n; ++i) - sumSizes += sizes[i]; - - for (int i = 0; i < n; ++i) { - if (ignore.testBit(start + i)) { - newSizes[i] = 0.0; - factors[i] = 0.0; - continue; - } - - const QGridLayoutBox &box = boxes.at(start + i); - qreal boxSize; - - qreal desired; - if (isLargerThanMaximum) { - boxSize = box.q_maximumSize; - desired = rowInfo.boxes.value(start + i).q_maximumSize - boxSize; - } else { - boxSize = box.q_preferredSize; - desired = box.q_maximumSize - boxSize; - } - if (desired == 0.0) { - newSizes[i] = sizes[i]; - factors[i] = 0.0; - } else { - Q_ASSERT(desired > 0.0); - - int stretch = stretches[start + i]; - if (sumStretches == 0) { - if (hasIgnoreFlag || sizes[i] == 0.0) { - factors[i] = (stretch < 0) ? 1.0 : 0.0; - } else { - factors[i] = (stretch < 0) ? sizes[i] : 0.0; - } - } else if (stretch == sumStretches) { - factors[i] = 1.0; - } else if (stretch <= 0) { - factors[i] = 0.0; - } else { - qreal ultimateSize; - qreal ultimateSumSizes; - qreal x = ((stretch * sumSizes) - - (sumStretches * boxSize)) - / (sumStretches - stretch); - if (x >= 0.0) { - ultimateSize = boxSize + x; - ultimateSumSizes = sumSizes + x; - } else { - ultimateSize = boxSize; - ultimateSumSizes = (sumStretches * boxSize) - / stretch; - } - - /* - We multiply these by 1.5 to give some space for a smooth transition - (at the expense of the stretch factors, which are not fully respected - during the transition). - */ - ultimateSize = ultimateSize * 3 / 2; - ultimateSumSizes = ultimateSumSizes * 3 / 2; - - qreal beta = ultimateSumSizes - sumSizes; - if (!beta) { - factors[i] = 1; - } else { - qreal alpha = qMin(sumCurrentAvailable, beta); - qreal ultimateFactor = (stretch * ultimateSumSizes / sumStretches) - - (boxSize); - qreal transitionalFactor = sumCurrentAvailable * (ultimateSize - boxSize) / beta; - - factors[i] = ((alpha * ultimateFactor) - + ((beta - alpha) * transitionalFactor)) / beta; - } - - } - sumFactors += factors[i]; - if (desired < sumCurrentAvailable) - somethingHasAMaximumSize = true; - - newSizes[i] = -1.0; - } - } - - bool keepGoing = somethingHasAMaximumSize; - while (keepGoing) { - keepGoing = false; - - for (int i = 0; i < n; ++i) { - if (newSizes[i] >= 0.0) - continue; - - qreal maxBoxSize; - if (isLargerThanMaximum) - maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize; - else - maxBoxSize = boxes.at(start + i).q_maximumSize; - - qreal avail = sumCurrentAvailable * factors[i] / sumFactors; - if (sizes[i] + avail >= maxBoxSize) { - newSizes[i] = maxBoxSize; - sumCurrentAvailable -= maxBoxSize - sizes[i]; - sumFactors -= factors[i]; - keepGoing = (sumCurrentAvailable > 0.0); - if (!keepGoing) - break; - } - } - } - - for (int i = 0; i < n; ++i) { - if (newSizes[i] < 0.0) { - qreal delta = (sumFactors == 0.0) ? 0.0 - : sumCurrentAvailable * factors[i] / sumFactors; - newSizes[i] = sizes[i] + delta; - } - } - } - } - - if (sumAvailable > 0) { - qreal offset = 0; - for (int i = 0; i < n; ++i) { - qreal delta = newSizes[i] - sizes[i]; - positions[i] += offset; - sizes[i] += delta; - offset += delta; - } - -#if 0 // some "pixel allocation" - int surplus = targetSize - (positions[n - 1] + sizes[n - 1]); - Q_ASSERT(surplus >= 0 && surplus <= n); - - int prevSurplus = -1; - while (surplus > 0 && surplus != prevSurplus) { - prevSurplus = surplus; - - int offset = 0; - for (int i = 0; i < n; ++i) { - const QGridLayoutBox &box = boxes.at(start + i); - int delta = (!ignore.testBit(start + i) && surplus > 0 - && factors[i] > 0 && sizes[i] < box.q_maximumSize) - ? 1 : 0; - - positions[i] += offset; - sizes[i] += delta; - offset += delta; - surplus -= delta; - } - } - Q_ASSERT(surplus == 0); -#endif - } - - if (descents) { - for (int i = 0; i < n; ++i) { - if (ignore.testBit(start + i)) - continue; - const QGridLayoutBox &box = boxes.at(start + i); - descents[i] = fixedDescent(box.q_minimumDescent, box.q_minimumAscent, sizes[i]); - } - } -} - -QGridLayoutBox QGridLayoutRowData::totalBox(int start, int end) const -{ - QGridLayoutBox result; - if (start < end) { - result.q_maximumSize = 0.0; - qreal nextSpacing = 0.0; - for (int i = start; i < end; ++i) { - if (ignore.testBit(i)) - continue; - result.add(boxes.at(i), stretches.at(i), nextSpacing); - nextSpacing = spacings.at(i); - } - } - return result; -} - -void QGridLayoutRowData::stealBox(int start, int end, int which, qreal *positions, qreal *sizes) -{ - qreal offset = 0.0; - qreal nextSpacing = 0.0; - - for (int i = start; i < end; ++i) { - qreal avail = 0.0; - - if (!ignore.testBit(i)) { - const QGridLayoutBox &box = boxes.at(i); - avail = box.q_sizes(which); - offset += nextSpacing; - nextSpacing = spacings.at(i); - } - - *positions++ = offset; - *sizes++ = avail; - offset += avail; - } -} - -#ifdef QT_DEBUG -void QGridLayoutRowData::dump(int indent) const -{ - qDebug("%*sData", indent, ""); - - for (int i = 0; i < ignore.count(); ++i) { - qDebug("%*s Row %d (stretch %d, spacing %g)", indent, "", i, stretches.at(i), - spacings.at(i)); - if (ignore.testBit(i)) - qDebug("%*s Ignored", indent, ""); - boxes.at(i).dump(indent + 2); - } - - MultiCellMap::const_iterator it = multiCellMap.constBegin(); - while (it != multiCellMap.constEnd()) { - qDebug("%*s Multi-cell entry <%d, %d> (stretch %d)", indent, "", it.key().first, - it.key().second, it.value().q_stretch); - it.value().q_box.dump(indent + 2); - } -} -#endif - -QGridLayoutItem::QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem *layoutItem, - int row, int column, int rowSpan, int columnSpan, - Qt::Alignment alignment, int itemAtIndex) - : q_engine(engine), q_layoutItem(layoutItem), q_alignment(alignment) -{ - q_firstRows[Hor] = column; - q_firstRows[Ver] = row; - q_rowSpans[Hor] = columnSpan; - q_rowSpans[Ver] = rowSpan; - q_stretches[Hor] = -1; - q_stretches[Ver] = -1; - - q_engine->insertItem(this, itemAtIndex); -} - -int QGridLayoutItem::firstRow(Qt::Orientation orientation) const -{ - return q_firstRows[orientation == Qt::Vertical]; -} - -int QGridLayoutItem::firstColumn(Qt::Orientation orientation) const -{ - return q_firstRows[orientation == Qt::Horizontal]; -} - -int QGridLayoutItem::lastRow(Qt::Orientation orientation) const -{ - return firstRow(orientation) + rowSpan(orientation) - 1; -} - -int QGridLayoutItem::lastColumn(Qt::Orientation orientation) const -{ - return firstColumn(orientation) + columnSpan(orientation) - 1; -} - -int QGridLayoutItem::rowSpan(Qt::Orientation orientation) const -{ - return q_rowSpans[orientation == Qt::Vertical]; -} - -int QGridLayoutItem::columnSpan(Qt::Orientation orientation) const -{ - return q_rowSpans[orientation == Qt::Horizontal]; -} - -void QGridLayoutItem::setFirstRow(int row, Qt::Orientation orientation) -{ - q_firstRows[orientation == Qt::Vertical] = row; -} - -void QGridLayoutItem::setRowSpan(int rowSpan, Qt::Orientation orientation) -{ - q_rowSpans[orientation == Qt::Vertical] = rowSpan; -} - -int QGridLayoutItem::stretchFactor(Qt::Orientation orientation) const -{ - int stretch = q_stretches[orientation == Qt::Vertical]; - if (stretch >= 0) - return stretch; - - QSizePolicy::Policy policy = sizePolicy(orientation); - - if (policy & QSizePolicy::ExpandFlag) { - return 1; - } else if (policy & QSizePolicy::GrowFlag) { - return -1; // because we max it up - } else { - return 0; - } -} - -void QGridLayoutItem::setStretchFactor(int stretch, Qt::Orientation orientation) -{ - Q_ASSERT(stretch >= 0); // ### deal with too big stretches - q_stretches[orientation == Qt::Vertical] = stretch; -} - -QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) const -{ - QSizePolicy sizePolicy(q_layoutItem->sizePolicy()); - return (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy() - : sizePolicy.verticalPolicy(); -} - -/* - returns \c true if the size policy returns \c true for either hasHeightForWidth() - or hasWidthForHeight() - */ -bool QGridLayoutItem::hasDynamicConstraint() const -{ - return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() - || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); -} - -Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const -{ - if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) - return Qt::Vertical; - else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) - return Qt::Horizontal; -} - -QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const -{ - return q_layoutItem->sizePolicy().controlType(); -} - -QSizeF QGridLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const -{ - return q_layoutItem->effectiveSizeHint(which, constraint); -} - -QGridLayoutBox QGridLayoutItem::box(Qt::Orientation orientation, qreal constraint) const -{ - QGridLayoutBox result; - QSizePolicy::Policy policy = sizePolicy(orientation); - - if (orientation == Qt::Horizontal) { - QSizeF constraintSize(-1.0, constraint); - - result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).width(); - - if (policy & QSizePolicy::ShrinkFlag) { - result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).width(); - } else { - result.q_minimumSize = result.q_preferredSize; - } - - if (policy & (QSizePolicy::GrowFlag | QSizePolicy::ExpandFlag)) { - result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).width(); - } else { - result.q_maximumSize = result.q_preferredSize; - } - } else { - QSizeF constraintSize(constraint, -1.0); - - result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).height(); - - if (policy & QSizePolicy::ShrinkFlag) { - result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).height(); - } else { - result.q_minimumSize = result.q_preferredSize; - } - - if (policy & (QSizePolicy::GrowFlag | QSizePolicy::ExpandFlag)) { - result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).height(); - } else { - result.q_maximumSize = result.q_preferredSize; - } - - result.q_minimumDescent = sizeHint(Qt::MinimumDescent, constraintSize).height(); - if (result.q_minimumDescent >= 0.0) - result.q_minimumAscent = result.q_minimumSize - result.q_minimumDescent; - } - if (policy & QSizePolicy::IgnoreFlag) - result.q_preferredSize = result.q_minimumSize; - - return result; -} - -QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal height, - qreal rowDescent) const -{ - rowDescent = -1.0; // ### This disables the descent - - QGridLayoutBox vBox = box(Qt::Vertical); - if (vBox.q_minimumDescent < 0.0 || rowDescent < 0.0) { - qreal cellWidth = width; - qreal cellHeight = height; - - - QSizeF size = effectiveMaxSize(QSizeF(-1,-1)); - if (hasDynamicConstraint()) { - if (dynamicConstraintOrientation() == Qt::Vertical) { - if (size.width() > cellWidth) - size = effectiveMaxSize(QSizeF(cellWidth, -1)); - } else if (size.height() > cellHeight) { - size = effectiveMaxSize(QSizeF(-1, cellHeight)); - } - } - size = size.boundedTo(QSizeF(cellWidth, cellHeight)); - width = size.width(); - height = size.height(); - - Qt::Alignment align = q_engine->effectiveAlignment(this); - switch (align & Qt::AlignHorizontal_Mask) { - case Qt::AlignHCenter: - x += (cellWidth - width)/2; - break; - case Qt::AlignRight: - x += cellWidth - width; - break; - default: - break; - } - switch (align & Qt::AlignVertical_Mask) { - case Qt::AlignVCenter: - y += (cellHeight - height)/2; - break; - case Qt::AlignBottom: - y += cellHeight - height; - break; - default: - break; - } - return QRectF(x, y, width, height); - } else { - qreal descent = vBox.q_minimumDescent; - qreal ascent = vBox.q_minimumSize - descent; - return QRectF(x, y + height - rowDescent - ascent, width, ascent + descent); - } -} - -void QGridLayoutItem::setGeometry(const QRectF &rect) -{ - q_layoutItem->setGeometry(rect); -} - -void QGridLayoutItem::transpose() -{ - qSwap(q_firstRows[Hor], q_firstRows[Ver]); - qSwap(q_rowSpans[Hor], q_rowSpans[Ver]); - qSwap(q_stretches[Hor], q_stretches[Ver]); -} - -void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation) -{ - int oldFirstRow = firstRow(orientation); - if (oldFirstRow >= row) { - setFirstRow(oldFirstRow + delta, orientation); - } else if (lastRow(orientation) >= row) { - setRowSpan(rowSpan(orientation) + delta, orientation); - } -} -/*! - \internal - returns the effective maximumSize, will take the sizepolicy into - consideration. (i.e. if sizepolicy does not have QSizePolicy::Grow, then - maxSizeHint will be the preferredSize) - Note that effectiveSizeHint does not take sizePolicy into consideration, - (since it only evaluates the hints, as the name implies) -*/ -QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const -{ - QSizeF size = constraint; - bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; - bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; - if (!vGrow || !hGrow) { - QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); - if (!vGrow) - size.setHeight(pref.height()); - if (!hGrow) - size.setWidth(pref.width()); - } - - if (!size.isValid()) { - QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, size); - if (size.width() == -1) - size.setWidth(maxSize.width()); - if (size.height() == -1) - size.setHeight(maxSize.height()); - } - return size; -} - -#ifdef QT_DEBUG -void QGridLayoutItem::dump(int indent) const -{ - qDebug("%*s%p (%d, %d) %d x %d", indent, "", q_layoutItem, firstRow(), firstColumn(), - rowSpan(), columnSpan()); - - if (q_stretches[Hor] >= 0) - qDebug("%*s Horizontal stretch: %d", indent, "", q_stretches[Hor]); - if (q_stretches[Ver] >= 0) - qDebug("%*s Vertical stretch: %d", indent, "", q_stretches[Ver]); - if (q_alignment != 0) - qDebug("%*s Alignment: %x", indent, "", uint(q_alignment)); - qDebug("%*s Horizontal size policy: %x Vertical size policy: %x", - indent, "", sizePolicy(Qt::Horizontal), sizePolicy(Qt::Vertical)); -} -#endif - -void QGridLayoutRowInfo::insertOrRemoveRows(int row, int delta) -{ - count += delta; - - insertOrRemoveItems(stretches, row, delta); - insertOrRemoveItems(spacings, row, delta); - insertOrRemoveItems(alignments, row, delta); - insertOrRemoveItems(boxes, row, delta); -} - -#ifdef QT_DEBUG -void QGridLayoutRowInfo::dump(int indent) const -{ - qDebug("%*sInfo (count: %d)", indent, "", count); - for (int i = 0; i < count; ++i) { - QString message; - - if (stretches.value(i).value() >= 0) - message += QString::fromLatin1(" stretch %1").arg(stretches.value(i).value()); - if (spacings.value(i).value() >= 0.0) - message += QString::fromLatin1(" spacing %1").arg(spacings.value(i).value()); - if (alignments.value(i) != 0) - message += QString::fromLatin1(" alignment %1").arg(int(alignments.value(i)), 16); - - if (!message.isEmpty() || boxes.value(i) != QGridLayoutBox()) { - qDebug("%*s Row %d:%s", indent, "", i, qPrintable(message)); - if (boxes.value(i) != QGridLayoutBox()) - boxes.value(i).dump(indent + 1); - } - } -} -#endif - -QGridLayoutEngine::QGridLayoutEngine() -{ - m_visualDirection = Qt::LeftToRight; - invalidate(); -} - -int QGridLayoutEngine::rowCount(Qt::Orientation orientation) const -{ - return q_infos[orientation == Qt::Vertical].count; -} - -int QGridLayoutEngine::columnCount(Qt::Orientation orientation) const -{ - return q_infos[orientation == Qt::Horizontal].count; -} - -int QGridLayoutEngine::itemCount() const -{ - return q_items.count(); -} - -QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const -{ - Q_ASSERT(index >= 0 && index < itemCount()); - return q_items.at(index); -} - -int QGridLayoutEngine::indexOf(QGraphicsLayoutItem *item) const -{ - for (int i = 0; i < q_items.size(); ++i) { - if (item == q_items.at(i)->layoutItem()) - return i; - } - return -1; -} - -int QGridLayoutEngine::effectiveFirstRow(Qt::Orientation orientation) const -{ - ensureEffectiveFirstAndLastRows(); - return q_cachedEffectiveFirstRows[orientation == Qt::Vertical]; -} - -int QGridLayoutEngine::effectiveLastRow(Qt::Orientation orientation) const -{ - ensureEffectiveFirstAndLastRows(); - return q_cachedEffectiveLastRows[orientation == Qt::Vertical]; -} - -void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations) -{ - Q_ASSERT(spacing >= 0.0); - if (orientations & Qt::Horizontal) - q_defaultSpacings[Hor].setUserValue(spacing); - if (orientations & Qt::Vertical) - q_defaultSpacings[Ver].setUserValue(spacing); - - invalidate(); -} - -qreal QGridLayoutEngine::spacing(const QLayoutStyleInfo &styleInfo, Qt::Orientation orientation) const -{ - if (q_defaultSpacings[orientation == Qt::Vertical].isDefault()) { - QStyle *style = styleInfo.style(); - QStyleOption option; - option.initFrom(styleInfo.widget()); - qreal defaultSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing - : QStyle::PM_LayoutHorizontalSpacing, &option, styleInfo.widget()); - q_defaultSpacings[orientation == Qt::Vertical].setCachedValue(defaultSpacing); - } - return q_defaultSpacings[orientation == Qt::Vertical].value(); -} - -void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation orientation) -{ - Q_ASSERT(row >= 0); - - QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - if (row >= rowInfo.spacings.count()) - rowInfo.spacings.resize(row + 1); - if (spacing >= 0) - rowInfo.spacings[row].setUserValue(spacing); - else - rowInfo.spacings[row] = QLayoutParameter<qreal>(); - invalidate(); -} - -qreal QGridLayoutEngine::rowSpacing(int row, Qt::Orientation orientation) const -{ - QLayoutParameter<qreal> spacing = q_infos[orientation == Qt::Vertical].spacings.value(row); - if (!spacing.isDefault()) - return spacing.value(); - return q_defaultSpacings[orientation == Qt::Vertical].value(); -} - -void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientation orientation) -{ - Q_ASSERT(row >= 0); - Q_ASSERT(stretch >= 0); - - maybeExpandGrid(row, -1, orientation); - - QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - if (row >= rowInfo.stretches.count()) - rowInfo.stretches.resize(row + 1); - rowInfo.stretches[row].setUserValue(stretch); -} - -int QGridLayoutEngine::rowStretchFactor(int row, Qt::Orientation orientation) const -{ - QStretchParameter stretch = q_infos[orientation == Qt::Vertical].stretches.value(row); - if (!stretch.isDefault()) - return stretch.value(); - return 0; -} - -void QGridLayoutEngine::setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, - Qt::Orientation orientation) -{ - Q_ASSERT(stretch >= 0); - - if (QGridLayoutItem *item = findLayoutItem(layoutItem)) - item->setStretchFactor(stretch, orientation); -} - -int QGridLayoutEngine::stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const -{ - if (QGridLayoutItem *item = findLayoutItem(layoutItem)) - return item->stretchFactor(orientation); - return 0; -} - -void QGridLayoutEngine::setRowSizeHint(Qt::SizeHint which, int row, qreal size, - Qt::Orientation orientation) -{ - Q_ASSERT(row >= 0); - Q_ASSERT(size >= 0.0); - - maybeExpandGrid(row, -1, orientation); - - QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - if (row >= rowInfo.boxes.count()) - rowInfo.boxes.resize(row + 1); - rowInfo.boxes[row].q_sizes(which) = size; -} - -qreal QGridLayoutEngine::rowSizeHint(Qt::SizeHint which, int row, Qt::Orientation orientation) const -{ - return q_infos[orientation == Qt::Vertical].boxes.value(row).q_sizes(which); -} - -void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment, - Qt::Orientation orientation) -{ - Q_ASSERT(row >= 0); - - maybeExpandGrid(row, -1, orientation); - - QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - if (row >= rowInfo.alignments.count()) - rowInfo.alignments.resize(row + 1); - rowInfo.alignments[row] = alignment; -} - -Qt::Alignment QGridLayoutEngine::rowAlignment(int row, Qt::Orientation orientation) const -{ - Q_ASSERT(row >= 0); - return q_infos[orientation == Qt::Vertical].alignments.value(row); -} - -void QGridLayoutEngine::setAlignment(QGraphicsLayoutItem *layoutItem, Qt::Alignment alignment) -{ - if (QGridLayoutItem *item = findLayoutItem(layoutItem)) - item->setAlignment(alignment); - invalidate(); -} - -Qt::Alignment QGridLayoutEngine::alignment(QGraphicsLayoutItem *layoutItem) const -{ - if (QGridLayoutItem *item = findLayoutItem(layoutItem)) - return item->alignment(); - return 0; -} - -Qt::Alignment QGridLayoutEngine::effectiveAlignment(const QGridLayoutItem *layoutItem) const -{ - Qt::Alignment align = layoutItem->alignment(); - if (!(align & Qt::AlignVertical_Mask)) { - // no vertical alignment, respect the row alignment - int y = layoutItem->firstRow(); - align |= (rowAlignment(y, Qt::Vertical) & Qt::AlignVertical_Mask); - } - if (!(align & Qt::AlignHorizontal_Mask)) { - // no horizontal alignment, respect the column alignment - int x = layoutItem->firstColumn(); - align |= (rowAlignment(x, Qt::Horizontal) & Qt::AlignHorizontal_Mask); - } - return align; -} - -/*! - \internal - The \a index is only used by QGraphicsLinearLayout to ensure that itemAt() reflects the order - of visual arrangement. Strictly speaking it does not have to, but most people expect it to. - (And if it didn't we would have to add itemArrangedAt(int index) or something..) - */ -void QGridLayoutEngine::insertItem(QGridLayoutItem *item, int index) -{ - maybeExpandGrid(item->lastRow(), item->lastColumn()); - - if (index == -1) - q_items.append(item); - else - q_items.insert(index, item); - - for (int i = item->firstRow(); i <= item->lastRow(); ++i) { - for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) { - if (itemAt(i, j)) - qWarning("QGridLayoutEngine::addItem: Cell (%d, %d) already taken", i, j); - setItemAt(i, j, item); - } - } -} - -void QGridLayoutEngine::addItem(QGridLayoutItem *item) -{ - insertItem(item, -1); -} - -void QGridLayoutEngine::removeItem(QGridLayoutItem *item) -{ - Q_ASSERT(q_items.contains(item)); - - invalidate(); - - for (int i = item->firstRow(); i <= item->lastRow(); ++i) { - for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) { - if (itemAt(i, j) == item) - setItemAt(i, j, 0); - } - } - - q_items.removeAll(item); -} - -QGridLayoutItem *QGridLayoutEngine::findLayoutItem(QGraphicsLayoutItem *layoutItem) const -{ - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->layoutItem() == layoutItem) - return item; - } - return 0; -} - -QGridLayoutItem *QGridLayoutEngine::itemAt(int row, int column, Qt::Orientation orientation) const -{ - if (orientation == Qt::Horizontal) - qSwap(row, column); - if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount())) - return 0; - return q_grid.at((row * internalGridColumnCount()) + column); -} - -void QGridLayoutEngine::invalidate() -{ - q_cachedEffectiveFirstRows[Hor] = -1; - q_cachedEffectiveFirstRows[Ver] = -1; - q_cachedEffectiveLastRows[Hor] = -1; - q_cachedEffectiveLastRows[Ver] = -1; - q_cachedDataForStyleInfo.invalidate(); - q_cachedSize = QSizeF(); - q_cachedConstraintOrientation = UnknownConstraint; -} - -static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect) -{ - if (dir == Qt::RightToLeft) - geom->moveRight(contentsRect.right() - (geom->left() - contentsRect.left())); -} - -void QGridLayoutEngine::setGeometries(const QLayoutStyleInfo &styleInfo, - const QRectF &contentsGeometry) -{ - if (rowCount() < 1 || columnCount() < 1) - return; - - ensureGeometries(styleInfo, contentsGeometry.size()); - - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - - qreal x = q_xx[item->firstColumn()]; - qreal y = q_yy[item->firstRow()]; - qreal width = q_widths[item->lastColumn()]; - qreal height = q_heights[item->lastRow()]; - - if (item->columnSpan() != 1) - width += q_xx[item->lastColumn()] - x; - if (item->rowSpan() != 1) - height += q_yy[item->lastRow()] - y; - - QRectF geom = item->geometryWithin(contentsGeometry.x() + x, contentsGeometry.y() + y, - width, height, q_descents[item->lastRow()]); - visualRect(&geom, visualDirection(), contentsGeometry); - item->setGeometry(geom); - } -} - -// ### candidate for deletion -QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo, - const QRectF &contentsGeometry, int row, int column, int rowSpan, - int columnSpan) const -{ - if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount()) - || rowSpan < 1 || columnSpan < 1) - return QRectF(); - - ensureGeometries(styleInfo, contentsGeometry.size()); - - int lastColumn = qMax(column + columnSpan, columnCount()) - 1; - int lastRow = qMax(row + rowSpan, rowCount()) - 1; - - qreal x = q_xx[column]; - qreal y = q_yy[row]; - qreal width = q_widths[lastColumn]; - qreal height = q_heights[lastRow]; - - if (columnSpan != 1) - width += q_xx[lastColumn] - x; - if (rowSpan != 1) - height += q_yy[lastRow] - y; - - return QRectF(contentsGeometry.x() + x, contentsGeometry.y() + y, width, height); -} - -QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, - const QSizeF &constraint) const -{ - QGridLayoutBox sizehint_totalBoxes[NOrientations]; - - bool sizeHintCalculated = false; - - if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) { - if (constraintOrientation() == Qt::Vertical) { - //We have items whose height depends on their width - if (constraint.width() >= 0) { - if (q_cachedDataForStyleInfo != styleInfo) - ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); - else - sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; - QVector<qreal> sizehint_xx; - QVector<qreal> sizehint_widths; - - sizehint_xx.resize(columnCount()); - sizehint_widths.resize(columnCount()); - qreal width = constraint.width(); - //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as - //constraints to find the row heights - q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), - 0, sizehint_totalBoxes[Hor], q_infos[Hor]); - ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical); - sizeHintCalculated = true; - } - } else { - if (constraint.height() >= 0) { - //We have items whose width depends on their height - ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); - QVector<qreal> sizehint_yy; - QVector<qreal> sizehint_heights; - - sizehint_yy.resize(rowCount()); - sizehint_heights.resize(rowCount()); - qreal height = constraint.height(); - //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as - //constraints to find the column widths - q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), - 0, sizehint_totalBoxes[Ver], q_infos[Ver]); - ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal); - sizeHintCalculated = true; - } - } - } - - if (!sizeHintCalculated) { - //No items with height for width, so it doesn't matter which order we do these in - if (q_cachedDataForStyleInfo != styleInfo) { - ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); - ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); - } else { - sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; - sizehint_totalBoxes[Ver] = q_totalBoxes[Ver]; - } - } - - switch (which) { - case Qt::MinimumSize: - return QSizeF(sizehint_totalBoxes[Hor].q_minimumSize, sizehint_totalBoxes[Ver].q_minimumSize); - case Qt::PreferredSize: - return QSizeF(sizehint_totalBoxes[Hor].q_preferredSize, sizehint_totalBoxes[Ver].q_preferredSize); - case Qt::MaximumSize: - return QSizeF(sizehint_totalBoxes[Hor].q_maximumSize, sizehint_totalBoxes[Ver].q_maximumSize); - case Qt::MinimumDescent: - return QSizeF(-1.0, sizehint_totalBoxes[Hor].q_minimumDescent); // ### doesn't work - default: - break; - } - return QSizeF(); -} - -QSizePolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const -{ - Qt::Orientation orientation = (side == Top || side == Bottom) ? Qt::Vertical : Qt::Horizontal; - int row = (side == Top || side == Left) ? effectiveFirstRow(orientation) - : effectiveLastRow(orientation); - QSizePolicy::ControlTypes result = 0; - - for (int column = columnCount(orientation) - 1; column >= 0; --column) { - if (QGridLayoutItem *item = itemAt(row, column, orientation)) - result |= item->controlTypes(side); - } - return result; -} - -void QGridLayoutEngine::transpose() -{ - invalidate(); - - for (int i = q_items.count() - 1; i >= 0; --i) - q_items.at(i)->transpose(); - - qSwap(q_defaultSpacings[Hor], q_defaultSpacings[Ver]); - qSwap(q_infos[Hor], q_infos[Ver]); - - regenerateGrid(); -} - -void QGridLayoutEngine::setVisualDirection(Qt::LayoutDirection direction) -{ - m_visualDirection = direction; -} - -Qt::LayoutDirection QGridLayoutEngine::visualDirection() const -{ - return m_visualDirection; -} - -#ifdef QT_DEBUG -void QGridLayoutEngine::dump(int indent) const -{ - qDebug("%*sEngine", indent, ""); - - qDebug("%*s Items (%d)", indent, "", q_items.count()); - int i; - for (i = 0; i < q_items.count(); ++i) - q_items.at(i)->dump(indent + 2); - - qDebug("%*s Grid (%d x %d)", indent, "", internalGridRowCount(), - internalGridColumnCount()); - for (int row = 0; row < internalGridRowCount(); ++row) { - QString message = QLatin1String("[ "); - for (int column = 0; column < internalGridColumnCount(); ++column) { - message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3); - message += QLatin1Char(' '); - } - message += QLatin1Char(']'); - qDebug("%*s %s", indent, "", qPrintable(message)); - } - - if (q_defaultSpacings[Hor].value() >= 0.0 || q_defaultSpacings[Ver].value() >= 0.0) - qDebug("%*s Default spacings: %g %g", indent, "", q_defaultSpacings[Hor].value(), - q_defaultSpacings[Ver].value()); - - qDebug("%*s Column and row info", indent, ""); - q_infos[Hor].dump(indent + 2); - q_infos[Ver].dump(indent + 2); - - qDebug("%*s Column and row data", indent, ""); - q_columnData.dump(indent + 2); - q_rowData.dump(indent + 2); - - qDebug("%*s Geometries output", indent, ""); - QVector<qreal> *cellPos = &q_yy; - for (int pass = 0; pass < 2; ++pass) { - QString message; - for (i = 0; i < cellPos->count(); ++i) { - message += QLatin1String((message.isEmpty() ? "[" : ", ")); - message += QString::number(cellPos->at(i)); - } - message += QLatin1Char(']'); - qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message)); - cellPos = &q_xx; - } -} -#endif - -void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation orientation) -{ - invalidate(); // ### move out of here? - - if (orientation == Qt::Horizontal) - qSwap(row, column); - - if (row < rowCount() && column < columnCount()) - return; - - int oldGridRowCount = internalGridRowCount(); - int oldGridColumnCount = internalGridColumnCount(); - - q_infos[Ver].count = qMax(row + 1, rowCount()); - q_infos[Hor].count = qMax(column + 1, columnCount()); - - int newGridRowCount = internalGridRowCount(); - int newGridColumnCount = internalGridColumnCount(); - - int newGridSize = newGridRowCount * newGridColumnCount; - if (newGridSize != q_grid.count()) { - q_grid.resize(newGridSize); - - if (newGridColumnCount != oldGridColumnCount) { - for (int i = oldGridRowCount - 1; i >= 1; --i) { - for (int j = oldGridColumnCount - 1; j >= 0; --j) { - int oldIndex = (i * oldGridColumnCount) + j; - int newIndex = (i * newGridColumnCount) + j; - - Q_ASSERT(newIndex > oldIndex); - q_grid[newIndex] = q_grid[oldIndex]; - q_grid[oldIndex] = 0; - } - } - } - } -} - -void QGridLayoutEngine::regenerateGrid() -{ - q_grid.fill(0); - - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - - for (int j = item->firstRow(); j <= item->lastRow(); ++j) { - for (int k = item->firstColumn(); k <= item->lastColumn(); ++k) { - setItemAt(j, k, item); - } - } - } -} - -void QGridLayoutEngine::setItemAt(int row, int column, QGridLayoutItem *item) -{ - Q_ASSERT(row >= 0 && row < rowCount()); - Q_ASSERT(column >= 0 && column < columnCount()); - q_grid[(row * internalGridColumnCount()) + column] = item; -} - -void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation) -{ - int oldRowCount = rowCount(orientation); - Q_ASSERT(uint(row) <= uint(oldRowCount)); - - invalidate(); - - // appending rows (or columns) is easy - if (row == oldRowCount && delta > 0) { - maybeExpandGrid(oldRowCount + delta - 1, -1, orientation); - return; - } - - q_infos[orientation == Qt::Vertical].insertOrRemoveRows(row, delta); - - for (int i = q_items.count() - 1; i >= 0; --i) - q_items.at(i)->insertOrRemoveRows(row, delta, orientation); - - q_grid.resize(internalGridRowCount() * internalGridColumnCount()); - regenerateGrid(); -} - -void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, - qreal *colPositions, qreal *colSizes, - Qt::Orientation orientation) const -{ - const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton; - const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - const QGridLayoutRowInfo &columnInfo = q_infos[orientation == Qt::Horizontal]; - LayoutSide top = (orientation == Qt::Vertical) ? Top : Left; - LayoutSide bottom = (orientation == Qt::Vertical) ? Bottom : Right; - - QStyle *style = styleInfo.style(); - QStyleOption option; - option.initFrom(styleInfo.widget()); - - const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation == Qt::Vertical]; - qreal innerSpacing = 0.0; - if (style) - innerSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing - : QStyle::PM_LayoutHorizontalSpacing, - &option, styleInfo.widget()); - if (innerSpacing >= 0.0) - defaultSpacing.setCachedValue(innerSpacing); - - for (int row = 0; row < rowInfo.count; ++row) { - bool rowIsEmpty = true; - bool rowIsIdenticalToPrevious = (row > 0); - - for (int column = 0; column < columnInfo.count; ++column) { - QGridLayoutItem *item = itemAt(row, column, orientation); - - if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation)) - rowIsIdenticalToPrevious = false; - - if (item) - rowIsEmpty = false; - } - - if ((rowIsEmpty || rowIsIdenticalToPrevious) - && rowInfo.spacings.value(row).isDefault() - && rowInfo.stretches.value(row).isDefault() - && rowInfo.boxes.value(row) == QGridLayoutBox()) - rowData->ignore.setBit(row, true); - - if (rowInfo.spacings.value(row).isUser()) { - rowData->spacings[row] = rowInfo.spacings.at(row).value(); - } else if (!defaultSpacing.isDefault()) { - rowData->spacings[row] = defaultSpacing.value(); - } - - rowData->stretches[row] = rowInfo.stretches.value(row).value(); - } - - struct RowAdHocData { - int q_row; - unsigned int q_hasButtons : 8; - unsigned int q_hasNonButtons : 8; - - inline RowAdHocData() : q_row(-1), q_hasButtons(false), q_hasNonButtons(false) {} - inline void init(int row) { - this->q_row = row; - q_hasButtons = false; - q_hasNonButtons = false; - } - inline bool hasOnlyButtons() const { return q_hasButtons && !q_hasNonButtons; } - inline bool hasOnlyNonButtons() const { return q_hasNonButtons && !q_hasButtons; } - }; - RowAdHocData lastRowAdHocData; - RowAdHocData nextToLastRowAdHocData; - RowAdHocData nextToNextToLastRowAdHocData; - - rowData->hasIgnoreFlag = false; - for (int row = 0; row < rowInfo.count; ++row) { - if (rowData->ignore.testBit(row)) - continue; - - QGridLayoutBox &rowBox = rowData->boxes[row]; - if (option.state & QStyle::State_Window) { - nextToNextToLastRowAdHocData = nextToLastRowAdHocData; - nextToLastRowAdHocData = lastRowAdHocData; - lastRowAdHocData.init(row); - } - - bool userRowStretch = rowInfo.stretches.value(row).isUser(); - int &rowStretch = rowData->stretches[row]; - - bool hasIgnoreFlag = true; - for (int column = 0; column < columnInfo.count; ++column) { - QGridLayoutItem *item = itemAt(row, column, orientation); - if (item) { - int itemRow = item->firstRow(orientation); - int itemColumn = item->firstColumn(orientation); - - if (itemRow == row && itemColumn == column) { - int itemStretch = item->stretchFactor(orientation); - if (!(item->sizePolicy(orientation) & QSizePolicy::IgnoreFlag)) - hasIgnoreFlag = false; - int itemRowSpan = item->rowSpan(orientation); - - int effectiveRowSpan = 1; - for (int i = 1; i < itemRowSpan; ++i) { - if (!rowData->ignore.testBit(i + itemRow)) - ++effectiveRowSpan; - } - - QGridLayoutBox *box; - if (effectiveRowSpan == 1) { - box = &rowBox; - if (!userRowStretch && itemStretch != 0) - rowStretch = qMax(rowStretch, itemStretch); - } else { - QGridLayoutMultiCellData &multiCell = - rowData->multiCellMap[qMakePair(row, effectiveRowSpan)]; - box = &multiCell.q_box; - multiCell.q_stretch = itemStretch; - } - // Items with constraints need to be passed the constraint - if (colSizes && colPositions && item->hasDynamicConstraint() && orientation == item->dynamicConstraintOrientation()) { - /* Get the width of the item by summing up the widths of the columns that it spans. - * We need to have already calculated the widths of the columns by calling - * q_columns->calculateGeometries() before hand and passing the value in the colSizes - * and colPositions parameters. - * The variable name is still colSizes even when it actually has the row sizes - */ - qreal length = colSizes[item->lastColumn(orientation)]; - if (item->columnSpan(orientation) != 1) - length += colPositions[item->lastColumn(orientation)] - colPositions[item->firstColumn(orientation)]; - box->combine(item->box(orientation, length)); - } else { - box->combine(item->box(orientation)); - } - - if (effectiveRowSpan == 1) { - QSizePolicy::ControlTypes controls = item->controlTypes(top); - if (controls & ButtonMask) - lastRowAdHocData.q_hasButtons = true; - if (controls & ~ButtonMask) - lastRowAdHocData.q_hasNonButtons = true; - } - } - } - } - if (row < rowInfo.boxes.count()) { - QGridLayoutBox rowBoxInfo = rowInfo.boxes.at(row); - rowBoxInfo.normalize(); - rowBox.q_minimumSize = qMax(rowBox.q_minimumSize, rowBoxInfo.q_minimumSize); - rowBox.q_maximumSize = qMax(rowBox.q_minimumSize, - (rowBoxInfo.q_maximumSize != FLT_MAX ? - rowBoxInfo.q_maximumSize : rowBox.q_maximumSize)); - rowBox.q_preferredSize = qBound(rowBox.q_minimumSize, - qMax(rowBox.q_preferredSize, rowBoxInfo.q_preferredSize), - rowBox.q_maximumSize); - } - if (hasIgnoreFlag) - rowData->hasIgnoreFlag = true; - } - - /* - Heuristic: Detect button boxes that don't use QSizePolicy::ButtonBox. - This is somewhat ad hoc but it usually does the trick. - */ - bool lastRowIsButtonBox = (lastRowAdHocData.hasOnlyButtons() - && nextToLastRowAdHocData.hasOnlyNonButtons()); - bool lastTwoRowsIsButtonBox = (lastRowAdHocData.hasOnlyButtons() - && nextToLastRowAdHocData.hasOnlyButtons() - && nextToNextToLastRowAdHocData.hasOnlyNonButtons() - && orientation == Qt::Vertical); - - if (defaultSpacing.isDefault()) { - int prevRow = -1; - for (int row = 0; row < rowInfo.count; ++row) { - if (rowData->ignore.testBit(row)) - continue; - - if (prevRow != -1 && !rowInfo.spacings.value(prevRow).isUser()) { - qreal &rowSpacing = rowData->spacings[prevRow]; - for (int column = 0; column < columnInfo.count; ++column) { - QGridLayoutItem *item1 = itemAt(prevRow, column, orientation); - QGridLayoutItem *item2 = itemAt(row, column, orientation); - - if (item1 && item2 && item1 != item2) { - QSizePolicy::ControlTypes controls1 = item1->controlTypes(bottom); - QSizePolicy::ControlTypes controls2 = item2->controlTypes(top); - - if (controls2 & QSizePolicy::PushButton) { - if ((row == nextToLastRowAdHocData.q_row && lastTwoRowsIsButtonBox) - || (row == lastRowAdHocData.q_row && lastRowIsButtonBox)) { - controls2 &= ~QSizePolicy::PushButton; - controls2 |= QSizePolicy::ButtonBox; - } - } - - qreal spacing = style->combinedLayoutSpacing(controls1, controls2, - orientation, &option, - styleInfo.widget()); - if (orientation == Qt::Horizontal) { - qreal width1 = rowData->boxes.at(prevRow).q_minimumSize; - qreal width2 = rowData->boxes.at(row).q_minimumSize; - QRectF rect1 = item1->geometryWithin(0.0, 0.0, width1, FLT_MAX, -1.0); - QRectF rect2 = item2->geometryWithin(0.0, 0.0, width2, FLT_MAX, -1.0); - spacing -= (width1 - (rect1.x() + rect1.width())) + rect2.x(); - } else { - const QGridLayoutBox &box1 = rowData->boxes.at(prevRow); - const QGridLayoutBox &box2 = rowData->boxes.at(row); - qreal height1 = box1.q_minimumSize; - qreal height2 = box2.q_minimumSize; - qreal rowDescent1 = fixedDescent(box1.q_minimumDescent, - box1.q_minimumAscent, height1); - qreal rowDescent2 = fixedDescent(box2.q_minimumDescent, - box2.q_minimumAscent, height2); - QRectF rect1 = item1->geometryWithin(0.0, 0.0, FLT_MAX, height1, - rowDescent1); - QRectF rect2 = item2->geometryWithin(0.0, 0.0, FLT_MAX, height2, - rowDescent2); - spacing -= (height1 - (rect1.y() + rect1.height())) + rect2.y(); - } - rowSpacing = qMax(spacing, rowSpacing); - } - } - } - prevRow = row; - } - } else if (lastRowIsButtonBox || lastTwoRowsIsButtonBox) { - /* - Even for styles that define a uniform spacing, we cheat a - bit and use the window margin as the spacing. This - significantly improves the look of dialogs. - */ - int prevRow = lastRowIsButtonBox ? nextToLastRowAdHocData.q_row - : nextToNextToLastRowAdHocData.q_row; - if (!defaultSpacing.isUser() && !rowInfo.spacings.value(prevRow).isUser()) { - qreal windowMargin = style->pixelMetric(orientation == Qt::Vertical - ? QStyle::PM_LayoutBottomMargin - : QStyle::PM_LayoutRightMargin, - &option, styleInfo.widget()); - - qreal &rowSpacing = rowData->spacings[prevRow]; - rowSpacing = qMax(windowMargin, rowSpacing); - } - } -} - -void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const -{ - if (q_cachedEffectiveFirstRows[Hor] == -1 && !q_items.isEmpty()) { - int rowCount = this->rowCount(); - int columnCount = this->columnCount(); - - q_cachedEffectiveFirstRows[Ver] = rowCount; - q_cachedEffectiveFirstRows[Hor] = columnCount; - q_cachedEffectiveLastRows[Ver] = -1; - q_cachedEffectiveLastRows[Hor] = -1; - - for (int i = q_items.count() - 1; i >= 0; --i) { - const QGridLayoutItem *item = q_items.at(i); - - for (int j = 0; j < NOrientations; ++j) { - Qt::Orientation orientation = (j == Hor) ? Qt::Horizontal : Qt::Vertical; - if (item->firstRow(orientation) < q_cachedEffectiveFirstRows[j]) - q_cachedEffectiveFirstRows[j] = item->firstRow(orientation); - if (item->lastRow(orientation) > q_cachedEffectiveLastRows[j]) - q_cachedEffectiveLastRows[j] = item->lastRow(orientation); - } - } - } -} - -void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, - const QLayoutStyleInfo &styleInfo, - qreal *colPositions, qreal *colSizes, - Qt::Orientation orientation) const -{ - rowData->reset(rowCount(orientation)); - fillRowData(rowData, styleInfo, colPositions, colSizes, orientation); - const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - rowData->distributeMultiCells(rowInfo); - *totalBox = rowData->totalBox(0, rowCount(orientation)); - //We have items whose width depends on their height -} - -/** - returns \c false if the layout has contradicting constraints (i.e. some items with a horizontal - constraint and other items with a vertical constraint) - */ -bool QGridLayoutEngine::ensureDynamicConstraint() const -{ - if (q_cachedConstraintOrientation == UnknownConstraint) { - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->hasDynamicConstraint()) { - Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); - if (q_cachedConstraintOrientation == UnknownConstraint) { - q_cachedConstraintOrientation = itemConstraintOrientation; - } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { - q_cachedConstraintOrientation = UnfeasibleConstraint; - qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" - " vertical constraint in the same layout"); - return false; - } - } - } - if (q_cachedConstraintOrientation == UnknownConstraint) - q_cachedConstraintOrientation = NoConstraint; - } - return true; -} - -bool QGridLayoutEngine::hasDynamicConstraint() const -{ - if (!ensureDynamicConstraint()) - return false; - return q_cachedConstraintOrientation != NoConstraint; -} - -/* - * return value is only valid if hasConstraint() returns \c true - */ -Qt::Orientation QGridLayoutEngine::constraintOrientation() const -{ - (void)ensureDynamicConstraint(); - return (Qt::Orientation)q_cachedConstraintOrientation; -} - -void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, - const QSizeF &size) const -{ - if (q_cachedDataForStyleInfo == styleInfo && q_cachedSize == size) - return; - - q_cachedDataForStyleInfo = styleInfo; - q_cachedSize = size; - - q_xx.resize(columnCount()); - q_widths.resize(columnCount()); - q_yy.resize(rowCount()); - q_heights.resize(rowCount()); - q_descents.resize(rowCount()); - - if (constraintOrientation() != Qt::Horizontal) { - // We might have items whose height depends on their width, - // or none of the items has a dynamic constraint. - ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); - //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as - //constraints to find the row heights - q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor], q_infos[Hor] ); - ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical); - //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() - q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); - } else { - // We have items whose width depends on their height - ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); - //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as - //constraints to find the column widths - q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); - ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal); - //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() - q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor], q_infos[Hor]); - } -} - -QT_END_NAMESPACE - -#endif //QT_NO_GRAPHICSVIEW diff --git a/src/widgets/graphicsview/qgridlayoutengine_p.h b/src/widgets/graphicsview/qgridlayoutengine_p.h deleted file mode 100644 index fbc5bd6ad2..0000000000 --- a/src/widgets/graphicsview/qgridlayoutengine_p.h +++ /dev/null @@ -1,458 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRIDLAYOUTENGINE_P_H -#define QGRIDLAYOUTENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the graphics view layout classes. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include "qalgorithms.h" -#include "qbitarray.h" -#include "qlist.h" -#include "qmap.h" -#include "qpair.h" -#include "qvector.h" -#include "qgraphicslayout_p.h" -#include <float.h> - -QT_BEGIN_NAMESPACE - -class QGraphicsLayoutItem; -class QStyle; -class QWidget; - -// ### deal with Descent in a similar way -enum { - MinimumSize = Qt::MinimumSize, - PreferredSize = Qt::PreferredSize, - MaximumSize = Qt::MaximumSize, - NSizes -}; - -// do not reorder -enum { - Hor, - Ver, - NOrientations -}; - -// do not reorder -enum LayoutSide { - Left, - Top, - Right, - Bottom -}; - -enum { - NoConstraint, - HorizontalConstraint, // Width depends on the height - VerticalConstraint, // Height depends on the width - UnknownConstraint, // need to update cache - UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints -}; - -template <typename T> -class QLayoutParameter -{ -public: - enum State { Default, User, Cached }; - - inline QLayoutParameter() : q_value(T()), q_state(Default) {} - inline QLayoutParameter(T value, State state = Default) : q_value(value), q_state(state) {} - - inline void setUserValue(T value) { - q_value = value; - q_state = User; - } - inline void setCachedValue(T value) const { - if (q_state != User) { - q_value = value; - q_state = Cached; - } - } - inline T value() const { return q_value; } - inline T value(T defaultValue) const { return isUser() ? q_value : defaultValue; } - inline bool isDefault() const { return q_state == Default; } - inline bool isUser() const { return q_state == User; } - inline bool isCached() const { return q_state == Cached; } - -private: - mutable T q_value; - mutable State q_state; -}; - -class QStretchParameter : public QLayoutParameter<int> -{ -public: - QStretchParameter() : QLayoutParameter<int>(-1) {} - -}; - -class QGridLayoutBox -{ -public: - inline QGridLayoutBox() - : q_minimumSize(0), q_preferredSize(0), q_maximumSize(FLT_MAX), - q_minimumDescent(-1), q_minimumAscent(-1) {} - - void add(const QGridLayoutBox &other, int stretch, qreal spacing); - void combine(const QGridLayoutBox &other); - void normalize(); - -#ifdef QT_DEBUG - void dump(int indent = 0) const; -#endif - // This code could use the union-struct-array trick, but a compiler - // bug prevents this from working. - qreal q_minimumSize; - qreal q_preferredSize; - qreal q_maximumSize; - qreal q_minimumDescent; - qreal q_minimumAscent; - inline qreal &q_sizes(int which) - { - qreal *t; - switch (which) { - case Qt::MinimumSize: - t = &q_minimumSize; - break; - case Qt::PreferredSize: - t = &q_preferredSize; - break; - case Qt::MaximumSize: - t = &q_maximumSize; - break; - case Qt::MinimumDescent: - t = &q_minimumDescent; - break; - case (Qt::MinimumDescent + 1): - t = &q_minimumAscent; - break; - default: - t = 0; - break; - } - return *t; - } - inline const qreal &q_sizes(int which) const - { - const qreal *t; - switch (which) { - case Qt::MinimumSize: - t = &q_minimumSize; - break; - case Qt::PreferredSize: - t = &q_preferredSize; - break; - case Qt::MaximumSize: - t = &q_maximumSize; - break; - case Qt::MinimumDescent: - t = &q_minimumDescent; - break; - case (Qt::MinimumDescent + 1): - t = &q_minimumAscent; - break; - default: - t = 0; - break; - } - return *t; - } -}; - -bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2); -inline bool operator!=(const QGridLayoutBox &box1, const QGridLayoutBox &box2) - { return !operator==(box1, box2); } - -class QGridLayoutMultiCellData -{ -public: - inline QGridLayoutMultiCellData() : q_stretch(-1) {} - - QGridLayoutBox q_box; - int q_stretch; -}; - -typedef QMap<QPair<int, int>, QGridLayoutMultiCellData> MultiCellMap; - -class QGridLayoutRowInfo; - -class QGridLayoutRowData -{ -public: - void reset(int count); - void distributeMultiCells(const QGridLayoutRowInfo &rowInfo); - void calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, - qreal *descents, const QGridLayoutBox &totalBox, - const QGridLayoutRowInfo &rowInfo); - QGridLayoutBox totalBox(int start, int end) const; - void stealBox(int start, int end, int which, qreal *positions, qreal *sizes); - -#ifdef QT_DEBUG - void dump(int indent = 0) const; -#endif - - QBitArray ignore; // ### rename q_ - QVector<QGridLayoutBox> boxes; - MultiCellMap multiCellMap; - QVector<int> stretches; - QVector<qreal> spacings; - bool hasIgnoreFlag; -}; - -class QGridLayoutEngine; - -class QGridLayoutItem -{ -public: - QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem *layoutItem, int row, int column, - int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = 0, - int itemAtIndex = -1); - - inline int firstRow() const { return q_firstRows[Ver]; } - inline int firstColumn() const { return q_firstRows[Hor]; } - inline int rowSpan() const { return q_rowSpans[Ver]; } - inline int columnSpan() const { return q_rowSpans[Hor]; } - inline int lastRow() const { return firstRow() + rowSpan() - 1; } - inline int lastColumn() const { return firstColumn() + columnSpan() - 1; } - - int firstRow(Qt::Orientation orientation) const; - int firstColumn(Qt::Orientation orientation) const; - int lastRow(Qt::Orientation orientation) const; - int lastColumn(Qt::Orientation orientation) const; - int rowSpan(Qt::Orientation orientation) const; - int columnSpan(Qt::Orientation orientation) const; - void setFirstRow(int row, Qt::Orientation orientation = Qt::Vertical); - void setRowSpan(int rowSpan, Qt::Orientation orientation = Qt::Vertical); - - int stretchFactor(Qt::Orientation orientation) const; - void setStretchFactor(int stretch, Qt::Orientation orientation); - - inline Qt::Alignment alignment() const { return q_alignment; } - inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; } - - QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const; - - bool hasDynamicConstraint() const; - Qt::Orientation dynamicConstraintOrientation() const; - - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; - QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; - QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const; - QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent) const; - - QGraphicsLayoutItem *layoutItem() const { return q_layoutItem; } - - void setGeometry(const QRectF &rect); - void transpose(); - void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); - QSizeF effectiveMaxSize(const QSizeF &constraint) const; - -#ifdef QT_DEBUG - void dump(int indent = 0) const; -#endif - -private: - QGridLayoutEngine *q_engine; // ### needed? - QGraphicsLayoutItem *q_layoutItem; - int q_firstRows[NOrientations]; - int q_rowSpans[NOrientations]; - int q_stretches[NOrientations]; - Qt::Alignment q_alignment; -}; - -class QGridLayoutRowInfo -{ -public: - inline QGridLayoutRowInfo() : count(0) {} - - void insertOrRemoveRows(int row, int delta); - -#ifdef QT_DEBUG - void dump(int indent = 0) const; -#endif - - int count; - QVector<QStretchParameter> stretches; - QVector<QLayoutParameter<qreal> > spacings; - QVector<Qt::Alignment> alignments; - QVector<QGridLayoutBox> boxes; -}; - -class QGridLayoutEngine -{ -public: - QGridLayoutEngine(); - inline ~QGridLayoutEngine() { qDeleteAll(q_items); } - - int rowCount(Qt::Orientation orientation) const; - int columnCount(Qt::Orientation orientation) const; - inline int rowCount() const { return q_infos[Ver].count; } - inline int columnCount() const { return q_infos[Hor].count; } - // returns the number of items inserted, which may be less than (rowCount * columnCount) - int itemCount() const; - QGridLayoutItem *itemAt(int index) const; - int indexOf(QGraphicsLayoutItem *item) const; - - int effectiveFirstRow(Qt::Orientation orientation = Qt::Vertical) const; - int effectiveLastRow(Qt::Orientation orientation = Qt::Vertical) const; - - void setSpacing(qreal spacing, Qt::Orientations orientations); - qreal spacing(const QLayoutStyleInfo &styleInfo, Qt::Orientation orientation) const; - // ### setSpacingAfterRow(), spacingAfterRow() - void setRowSpacing(int row, qreal spacing, Qt::Orientation orientation = Qt::Vertical); - qreal rowSpacing(int row, Qt::Orientation orientation = Qt::Vertical) const; - - void setRowStretchFactor(int row, int stretch, Qt::Orientation orientation = Qt::Vertical); - int rowStretchFactor(int row, Qt::Orientation orientation = Qt::Vertical) const; - - void setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, - Qt::Orientation orientation); - int stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const; - - void setRowSizeHint(Qt::SizeHint which, int row, qreal size, - Qt::Orientation orientation = Qt::Vertical); - qreal rowSizeHint(Qt::SizeHint which, int row, - Qt::Orientation orientation = Qt::Vertical) const; - - void setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation); - Qt::Alignment rowAlignment(int row, Qt::Orientation orientation) const; - - void setAlignment(QGraphicsLayoutItem *layoutItem, Qt::Alignment alignment); - Qt::Alignment alignment(QGraphicsLayoutItem *layoutItem) const; - Qt::Alignment effectiveAlignment(const QGridLayoutItem *layoutItem) const; - - - void insertItem(QGridLayoutItem *item, int index); - void addItem(QGridLayoutItem *item); - void removeItem(QGridLayoutItem *item); - QGridLayoutItem *findLayoutItem(QGraphicsLayoutItem *layoutItem) const; - QGridLayoutItem *itemAt(int row, int column, Qt::Orientation orientation = Qt::Vertical) const; - inline void insertRow(int row, Qt::Orientation orientation = Qt::Vertical) - { insertOrRemoveRows(row, +1, orientation); } - inline void removeRows(int row, int count, Qt::Orientation orientation) - { insertOrRemoveRows(row, -count, orientation); } - - void invalidate(); - void setGeometries(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry); - QRectF cellRect(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry, int row, - int column, int rowSpan, int columnSpan) const; - QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, - const QSizeF &constraint) const; - - // heightForWidth / widthForHeight support - QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; - bool ensureDynamicConstraint() const; - bool hasDynamicConstraint() const; - Qt::Orientation constraintOrientation() const; - - - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; - void transpose(); - void setVisualDirection(Qt::LayoutDirection direction); - Qt::LayoutDirection visualDirection() const; -#ifdef QT_DEBUG - void dump(int indent = 0) const; -#endif - -private: - static int grossRoundUp(int n) { return ((n + 2) | 0x3) - 2; } - - void maybeExpandGrid(int row, int column, Qt::Orientation orientation = Qt::Vertical); - void regenerateGrid(); - inline int internalGridRowCount() const { return grossRoundUp(rowCount()); } - inline int internalGridColumnCount() const { return grossRoundUp(columnCount()); } - void setItemAt(int row, int column, QGridLayoutItem *item); - void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); - void fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, - qreal *colPositions, qreal *colSizes, - Qt::Orientation orientation = Qt::Vertical) const; - void ensureEffectiveFirstAndLastRows() const; - void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, - const QLayoutStyleInfo &styleInfo, - qreal *colPositions, qreal *colSizes, - Qt::Orientation orientation) const; - - void ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const; - - // User input - QVector<QGridLayoutItem *> q_grid; - QList<QGridLayoutItem *> q_items; - QLayoutParameter<qreal> q_defaultSpacings[NOrientations]; - QGridLayoutRowInfo q_infos[NOrientations]; - Qt::LayoutDirection m_visualDirection; - - // Lazily computed from the above user input - mutable int q_cachedEffectiveFirstRows[NOrientations]; - mutable int q_cachedEffectiveLastRows[NOrientations]; - mutable quint8 q_cachedConstraintOrientation : 3; - - // Layout item input - mutable QLayoutStyleInfo q_cachedDataForStyleInfo; - mutable QGridLayoutRowData q_columnData; - mutable QGridLayoutRowData q_rowData; - mutable QGridLayoutBox q_totalBoxes[NOrientations]; - - // Output - mutable QSizeF q_cachedSize; - mutable QVector<qreal> q_xx; - mutable QVector<qreal> q_yy; - mutable QVector<qreal> q_widths; - mutable QVector<qreal> q_heights; - mutable QVector<qreal> q_descents; - - friend class QGridLayoutItem; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/widgets/graphicsview/qsimplex_p.h b/src/widgets/graphicsview/qsimplex_p.h index 842044fa7f..3fa3417eaf 100644 --- a/src/widgets/graphicsview/qsimplex_p.h +++ b/src/widgets/graphicsview/qsimplex_p.h @@ -149,9 +149,10 @@ struct QSimplexConstraint class QSimplex { + Q_DISABLE_COPY(QSimplex) public: QSimplex(); - virtual ~QSimplex(); + ~QSimplex(); qreal solveMin(); qreal solveMax(); @@ -163,8 +164,8 @@ public: private: // Matrix handling - qreal valueAt(int row, int column); - void setValueAt(int row, int column, qreal value); + inline qreal valueAt(int row, int column); + inline void setValueAt(int row, int column, qreal value); void clearRow(int rowIndex); void clearColumns(int first, int last); void combineRows(int toIndex, int fromIndex, qreal factor); diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 7edad74f54..771753b7da 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2939,14 +2939,13 @@ void QAbstractItemView::keyboardSearch(const QString &search) } // search from start with wraparound - const QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput; QModelIndex current = start; QModelIndexList match; QModelIndex firstMatch; QModelIndex startMatch; QModelIndexList previous; do { - match = d->model->match(current, Qt::DisplayRole, searchString); + match = d->model->match(current, Qt::DisplayRole, d->keyboardInput); if (match == previous) break; firstMatch = match.value(0); diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index 71697ddc40..b12ab736f4 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -53,8 +53,10 @@ #if defined(Q_OS_WIN) # include <qt_windows.h> -# include <commctrl.h> -# include <objbase.h> +# ifndef Q_OS_WINRT +# include <commctrl.h> +# include <objbase.h> +# endif #endif #if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK) @@ -313,7 +315,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const return retIcon; if (info.isRoot()) -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) { UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 75a513fb67..75ca1e656e 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -751,7 +751,7 @@ void QHeaderView::moveSection(int from, int to) //int oldHeaderLength = length(); // ### for debugging; remove later d->initializeIndexMapping(); - QBitArray sectionHidden = d->sectionHidden; + QBitArray sectionHidden = d->sectionsHiddenToBitVector(); int *visualIndices = d->visualIndices.data(); int *logicalIndices = d->logicalIndices.data(); int logical = logicalIndices[from]; @@ -788,8 +788,8 @@ void QHeaderView::moveSection(int from, int to) } } if (!sectionHidden.isEmpty()) { - sectionHidden.setBit(to, d->sectionHidden.testBit(from)); - d->sectionHidden = sectionHidden; + sectionHidden.setBit(to, d->isVisualIndexHidden(from)); + d->setHiddenSectionsFromBitVector(sectionHidden); } visualIndices[logical] = to; logicalIndices[to] = logical; @@ -860,11 +860,11 @@ void QHeaderView::swapSections(int first, int second) d->visualIndices[secondLogical] = first; d->logicalIndices[first] = secondLogical; - if (!d->sectionHidden.isEmpty()) { - bool firstHidden = d->sectionHidden.testBit(first); - bool secondHidden = d->sectionHidden.testBit(second); - d->sectionHidden.setBit(first, secondHidden); - d->sectionHidden.setBit(second, firstHidden); + if (!d->hiddenSectionSize.isEmpty()) { + bool firstHidden = d->isVisualIndexHidden(first); + bool secondHidden = d->isVisualIndexHidden(second); + d->setVisualIndexHidden(first, secondHidden); + d->setVisualIndexHidden(second, firstHidden); } d->viewport->update(); @@ -992,11 +992,11 @@ bool QHeaderView::isSectionHidden(int logicalIndex) const { Q_D(const QHeaderView); d->executePostedLayout(); - if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount()) + if (d->hiddenSectionSize.isEmpty() || logicalIndex < 0 || logicalIndex >= d->sectionCount()) return false; int visual = visualIndex(logicalIndex); Q_ASSERT(visual != -1); - return d->sectionHidden.testBit(visual); + return d->isVisualIndexHidden(visual); } /*! @@ -1035,20 +1035,13 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide) if (!d->hasAutoResizeSections()) resizeSection(logicalIndex, 0); d->hiddenSectionSize.insert(logicalIndex, size); - if (d->sectionHidden.count() < count()) - d->sectionHidden.resize(count()); - d->sectionHidden.setBit(visual, true); + d->setVisualIndexHidden(visual, true); if (d->hasAutoResizeSections()) d->doDelayedResizeSections(); } else { int size = d->hiddenSectionSize.value(logicalIndex, d->defaultSectionSize); d->hiddenSectionSize.remove(logicalIndex); - if (d->hiddenSectionSize.isEmpty()) { - d->sectionHidden.clear(); - } else { - Q_ASSERT(visual <= d->sectionHidden.count()); - d->sectionHidden.setBit(visual, false); - } + d->setVisualIndexHidden(visual, false); resizeSection(logicalIndex, size); } } @@ -1901,17 +1894,6 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent, } } - // insert sections into sectionsHidden - if (!d->sectionHidden.isEmpty()) { - QBitArray sectionHidden(d->sectionHidden); - sectionHidden.resize(sectionHidden.count() + insertCount); - sectionHidden.fill(false, logicalFirst, logicalLast + 1); - for (int j = logicalLast + 1; j < sectionHidden.count(); ++j) - //here we simply copy the old sectionHidden - sectionHidden.setBit(j, d->sectionHidden.testBit(j - insertCount)); - d->sectionHidden = sectionHidden; - } - // insert sections into hiddenSectionSize QHash<int, int> newHiddenSectionSize; // from logical index to section size for (int i = 0; i < logicalFirst; ++i) @@ -1960,19 +1942,6 @@ void QHeaderViewPrivate::updateHiddenSections(int logicalFirst, int logicalLast) if (q->isSectionHidden(j)) newHiddenSectionSize[j - changeCount] = hiddenSectionSize[j]; hiddenSectionSize = newHiddenSectionSize; - - // remove sections from sectionsHidden - if (!sectionHidden.isEmpty()) { - const int newsize = qMin(sectionCount() - changeCount, sectionHidden.size()); - QBitArray newSectionHidden(newsize); - for (int j = 0, k = 0; j < sectionHidden.size(); ++j) { - const int logical = logicalIndex(j); - if (logical < logicalFirst || logical > logicalLast) { - newSectionHidden[k++] = sectionHidden[j]; - } - } - sectionHidden = newSectionHidden; - } } void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent, @@ -2061,8 +2030,11 @@ void QHeaderViewPrivate::_q_layoutAboutToBeChanged() || model->columnCount(root) == 0) return; - for (int i = 0; i < sectionHidden.count(); ++i) - if (sectionHidden.testBit(i)) // ### note that we are using column or row 0 + if (hiddenSectionSize.count() == 0) + return; + + for (int i = 0; i < sectionItems.count(); ++i) + if (isVisualIndexHidden(i)) // ### note that we are using column or row 0 persistentHiddenSections.append(orientation == Qt::Horizontal ? model->index(0, logicalIndex(i), root) : model->index(logicalIndex(i), 0, root)); @@ -2079,7 +2051,8 @@ void QHeaderViewPrivate::_q_layoutChanged() return; } - QBitArray oldSectionHidden = sectionHidden; + QBitArray oldSectionHidden = sectionsHiddenToBitVector(); + oldSectionHidden.resize(sectionItems.size()); bool sectionCountChanged = false; for (int i = 0; i < persistentHiddenSections.count(); ++i) { @@ -2193,8 +2166,6 @@ void QHeaderView::initializeSections(int start, int end) d->stretchSections = newSectionCount; else if (d->globalResizeMode == ResizeToContents) d->contentsSections = newSectionCount; - if (!d->sectionHidden.isEmpty()) - d->sectionHidden.resize(newSectionCount); if (newSectionCount > oldCount) d->createSectionItems(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode); @@ -3385,7 +3356,6 @@ void QHeaderViewPrivate::clear() visualIndices.clear(); logicalIndices.clear(); sectionSelected.clear(); - sectionHidden.clear(); hiddenSectionSize.clear(); sectionItems.clear(); invalidateCachedSizeHint(); @@ -3526,7 +3496,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size) preventCursorChangeInSetOffset = true; for (int i = 0; i < sectionItems.count(); ++i) { QHeaderViewPrivate::SectionItem §ion = sectionItems[i]; - if (sectionHidden.isEmpty() || !sectionHidden.testBit(i)) { // resize on not hidden. + if (hiddenSectionSize.isEmpty() || !isVisualIndexHidden(i)) { // resize on not hidden. const int newSize = size; if (newSize != section.size) { length += newSize - section.size; //the whole length is changed @@ -3629,11 +3599,11 @@ int QHeaderViewPrivate::viewSectionSizeHint(int logical) const int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const { - if (!sectionHidden.isEmpty()) { + if (!hiddenSectionSize.isEmpty()) { int adjustedVisualIndex = visualIndex; int currentVisualIndex = 0; for (int i = 0; i < sectionItems.count(); ++i) { - if (sectionHidden.testBit(i)) + if (isVisualIndexHidden(i)) ++adjustedVisualIndex; else ++currentVisualIndex; @@ -3669,7 +3639,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const out << visualIndices; out << logicalIndices; - out << sectionHidden; + out << sectionsHiddenToBitVector(); out << hiddenSectionSize; out << length; @@ -3706,6 +3676,7 @@ bool QHeaderViewPrivate::read(QDataStream &in) in >> visualIndices; in >> logicalIndices; + QBitArray sectionHidden; in >> sectionHidden; in >> hiddenSectionSize; @@ -3739,6 +3710,7 @@ bool QHeaderViewPrivate::read(QDataStream &in) newSectionItems.append(sectionItems[u]); } sectionItems = newSectionItems; + setHiddenSectionsFromBitVector(sectionHidden); recalcSectionStartPos(); int tmpint; diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index b2af821e9b..81f1b176ee 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -171,11 +171,11 @@ public: } inline bool isVisualIndexHidden(int visual) const { - return !sectionHidden.isEmpty() && sectionHidden.at(visual); + return sectionItems.at(visual).isHidden; } inline void setVisualIndexHidden(int visual, bool hidden) { - if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden); + sectionItems[visual].isHidden = hidden; } inline bool hasAutoResizeSections() const { @@ -258,7 +258,6 @@ public: mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex) mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model mutable QBitArray sectionSelected; // from logical index to bit - mutable QBitArray sectionHidden; // from visual index to bit mutable QHash<int, int> hiddenSectionSize; // from logical index to section size mutable QHash<int, int> cascadingSectionSize; // from visual index to section size mutable QSize cachedSizeHint; @@ -301,7 +300,7 @@ public: struct SectionItem { uint size : 20; - uint reservedForIsHidden : 1; + uint isHidden : 1; uint resizeMode : 5; // (holding QHeaderView::ResizeMode) uint currentlyUnusedPadding : 6; @@ -311,9 +310,9 @@ public: int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true }; // to ensure that calculated_startpos will be calculated afterwards. - inline SectionItem() : size(0), resizeMode(QHeaderView::Interactive) {} + inline SectionItem() : size(0), isHidden(0), resizeMode(QHeaderView::Interactive) {} inline SectionItem(int length, QHeaderView::ResizeMode mode) - : size(length), resizeMode(mode), calculated_startpos(-1) {} + : size(length), isHidden(0), resizeMode(mode), calculated_startpos(-1) {} inline int sectionSize() const { return size; } inline int calculatedEndPos() const { return calculated_startpos + size; } #ifndef QT_NO_DATASTREAM @@ -339,6 +338,23 @@ public: return len; } + QBitArray sectionsHiddenToBitVector() const + { + QBitArray sectionHidden; + if (!hiddenSectionSize.isEmpty()) { + sectionHidden.resize(sectionItems.size()); + for (int u = 0; u < sectionItems.size(); ++u) + sectionHidden[u] = sectionItems.at(u).isHidden; + } + return sectionHidden; + } + + void setHiddenSectionsFromBitVector(const QBitArray §ionHidden) { + SectionItem *sectionData = sectionItems.data(); + for (int i = 0; i < sectionHidden.count(); ++i) + sectionData[i].isHidden = sectionHidden.at(i); + } + int headerSectionSize(int visual) const; int headerSectionPosition(int visual) const; int headerVisualIndexAt(int position) const; diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index e75f602e90..3ce757847c 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -493,8 +493,7 @@ bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) { beginRemoveRows(parent, row, row + count - 1); - bool blockSignal = signalsBlocked(); - blockSignals(true); + QSignalBlocker blocker(this); QTreeWidgetItem *itm = item(parent); for (int i = row + count - 1; i >= row; --i) { @@ -504,7 +503,7 @@ bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) { delete child; child = 0; } - blockSignals(blockSignal); + blocker.unblock(); endRemoveRows(); return true; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index c9d6593662..be349bfced 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2611,7 +2611,7 @@ QDesktopWidget *QApplication::desktop() void QApplication::setStartDragTime(int ms) { - Q_UNUSED(ms) + QGuiApplication::styleHints()->setStartDragTime(ms); } /*! @@ -2644,7 +2644,7 @@ int QApplication::startDragTime() void QApplication::setStartDragDistance(int l) { - Q_UNUSED(l); + QGuiApplication::styleHints()->setStartDragDistance(l); } /*! @@ -3611,7 +3611,7 @@ bool QApplication::keypadNavigationEnabled() */ void QApplication::setCursorFlashTime(int msecs) { - Q_UNUSED(msecs); + QGuiApplication::styleHints()->setCursorFlashTime(msecs); } int QApplication::cursorFlashTime() @@ -3626,12 +3626,10 @@ int QApplication::cursorFlashTime() The default value on X11 is 400 milliseconds. On Windows and Mac OS, the operating system's value is used. - - Setting the interval is not supported anymore in Qt 5. */ void QApplication::setDoubleClickInterval(int ms) { - Q_UNUSED(ms); + QGuiApplication::styleHints()->setMouseDoubleClickInterval(ms); } int QApplication::doubleClickInterval() @@ -3659,7 +3657,7 @@ int QApplication::doubleClickInterval() */ void QApplication::setKeyboardInputInterval(int ms) { - Q_UNUSED(ms); + QGuiApplication::styleHints()->setKeyboardInputInterval(ms); } int QApplication::keyboardInputInterval() diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 1f8e950d00..7977ae3528 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -451,7 +451,7 @@ void qt_init(QApplicationPrivate *priv, int type) QApplicationPrivate::initializeWidgetFontHash(); } -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // #fixme: Remove. static HDC displayDC = 0; // display device context @@ -470,7 +470,7 @@ void qt_cleanup() QColormap::cleanup(); QApplicationPrivate::active_window = 0; //### this should not be necessary -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) if (displayDC) { ReleaseDC(0, displayDC); displayDC = 0; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 08e8975f9d..7a86b6affe 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4178,7 +4178,7 @@ const QPalette &QWidget::palette() const if (!isEnabled()) { data->pal.setCurrentColorGroup(QPalette::Disabled); } else if ((!isVisible() || isActiveWindow()) -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this)) #endif ) { diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 02fa80bef6..9fcd14e813 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -120,7 +120,7 @@ static inline void qt_flush(QWidget *widget, const QRegion ®ion, QBackingStor } #ifndef QT_NO_PAINT_DEBUG -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec) { @@ -160,7 +160,7 @@ static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("releaseDC"), nativeWindow); ::Sleep(msec); } -#endif // Q_OS_WIN +#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped) { @@ -175,7 +175,7 @@ void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePa widget = nativeParent; } -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) Q_UNUSED(unclipped); showYellowThing_win(widget, paintRegion, msec); #else diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index d5cba740d1..76bb709e2b 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -2,6 +2,6 @@ # -------------------------------------------------------------------- INCLUDEPATH += ../3rdparty/wintab -!wince* { +!wince*:!winrt { LIBS_PRIVATE *= -lshell32 } diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index dde705f9b9..9ab8f8f08a 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -252,7 +252,7 @@ void QWindowsStyle::polish(QApplication *app) d->inactiveGradientCaptionColor = app->palette().dark().color(); d->inactiveCaptionText = app->palette().background().color(); -#if defined(Q_OS_WIN) //fetch native title bar colors +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors if(app->desktopSettingsAware()){ DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION); DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION); @@ -413,6 +413,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW #if defined(Q_OS_WIN) +#ifndef Q_OS_WINRT // There is no title bar in Windows Runtime applications case PM_TitleBarHeight: if (widget && (widget->windowType() == Qt::Tool)) { // MS always use one less than they say @@ -426,16 +427,17 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW } break; +#endif // !Q_OS_WINRT case PM_ScrollBarExtent: { -#ifndef Q_OS_WINCE +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) NONCLIENTMETRICS ncm; ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth); else -#endif +#endif // !Q_OS_WINCE && !Q_OS_WINRT ret = QCommonStyle::pixelMetric(pm, opt, widget); } break; @@ -446,6 +448,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW break; #if defined(Q_OS_WIN) +#ifndef Q_OS_WINRT // Mdi concept not available for WinRT applications case PM_MdiSubWindowFrameWidth: #if defined(Q_OS_WINCE) ret = GetSystemMetrics(SM_CYDLGFRAME); @@ -453,7 +456,8 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW ret = GetSystemMetrics(SM_CYFRAME); #endif break; -#endif +#endif // !Q_OS_WINRT +#endif // Q_OS_WIN case PM_ToolBarItemMargin: ret = 1; break; @@ -477,7 +481,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QPixmap desktopIcon; switch(standardPixmap) { case SP_DriveCDIcon: @@ -516,7 +520,7 @@ QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyl if (!desktopIcon.isNull()) { return desktopIcon; } -#endif +#endif // Q_OS_WIN && !Q_OS_WINCE && !Q_OS_WINRT return QCommonStyle::standardPixmap(standardPixmap, opt, widget); } @@ -554,7 +558,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid ret = 0; break; -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Option not used on WinRT -> common style case SH_UnderlineShortcut: { ret = 1; @@ -590,7 +594,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid #endif // QT_NO_ACCESSIBILITY break; } -#endif +#endif // Q_OS_WIN && !Q_OS_WINRT #ifndef QT_NO_RUBBERBAND case SH_RubberBand_Mask: if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri index 072c736f71..b4bbc5fc30 100644 --- a/src/widgets/util/util.pri +++ b/src/widgets/util/util.pri @@ -27,7 +27,7 @@ SOURCES += \ util/qundostack.cpp \ util/qundoview.cpp -win32:!wince* { +win32:!wince*:!winrt { SOURCES += util/qsystemtrayicon_win.cpp } else:contains(QT_CONFIG, xcb) { SOURCES += util/qsystemtrayicon_x11.cpp diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 25369a01b6..92af91b66e 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -396,6 +396,30 @@ bool QAbstractSpinBox::isAccelerated() const } /*! + \property QAbstractSpinBox::showGroupSeparator + \since 5.3 + + + This property holds whether a thousands separator is enabled. By default this + property is false. +*/ +bool QAbstractSpinBox::isGroupSeparatorShown() const +{ + Q_D(const QAbstractSpinBox); + return d->showGroupSeparator; +} + +void QAbstractSpinBox::setGroupSeparatorShown(bool shown) +{ + Q_D(QAbstractSpinBox); + if (d->showGroupSeparator == shown) + return; + d->showGroupSeparator = shown; + d->setValue(d->value, EmitIfChanged); + updateGeometry(); +} + +/*! \enum QAbstractSpinBox::CorrectionMode This enum type describes the mode the spinbox will use to correct @@ -1316,7 +1340,8 @@ QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate() cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false), ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true), cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue), - acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0) + acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0), + showGroupSeparator(0) { } @@ -1491,13 +1516,12 @@ void QAbstractSpinBoxPrivate::_q_editorCursorPositionChanged(int oldpos, int new * (newpos < pos ? -1 : 1)) - newpos + pos : 0; - const bool wasBlocked = edit->blockSignals(true); + const QSignalBlocker blocker(edit); if (selSize != 0) { edit->setSelection(pos - selSize, selSize); } else { edit->setCursorPosition(pos); } - edit->blockSignals(wasBlocked); } ignoreCursorPositionChanged = false; } @@ -1697,7 +1721,7 @@ void QAbstractSpinBoxPrivate::updateEdit() const bool empty = edit->text().isEmpty(); int cursor = edit->cursorPosition(); int selsize = edit->selectedText().size(); - const bool sb = edit->blockSignals(true); + const QSignalBlocker blocker(edit); edit->setText(newText); if (!specialValue()) { @@ -1709,7 +1733,6 @@ void QAbstractSpinBoxPrivate::updateEdit() edit->setCursorPosition(empty ? prefix.size() : cursor); } } - edit->blockSignals(sb); q->update(); } diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h index 4f6aad0cde..7989000cc8 100644 --- a/src/widgets/widgets/qabstractspinbox.h +++ b/src/widgets/widgets/qabstractspinbox.h @@ -72,6 +72,7 @@ class Q_WIDGETS_EXPORT QAbstractSpinBox : public QWidget Q_PROPERTY(CorrectionMode correctionMode READ correctionMode WRITE setCorrectionMode) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking) + Q_PROPERTY(bool showGroupSeparator READ isGroupSeparatorShown WRITE setGroupSeparatorShown) public: explicit QAbstractSpinBox(QWidget *parent = 0); ~QAbstractSpinBox(); @@ -114,6 +115,9 @@ public: void setAccelerated(bool on); bool isAccelerated() const; + void setGroupSeparatorShown(bool shown); + bool isGroupSeparatorShown() const; + QSize sizeHint() const; QSize minimumSizeHint() const; void interpretText(); diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h index 0eeec02abc..da9f1d9757 100644 --- a/src/widgets/widgets/qabstractspinbox_p.h +++ b/src/widgets/widgets/qabstractspinbox_p.h @@ -150,6 +150,7 @@ public: QRect hoverRect; QAbstractSpinBox::ButtonSymbols buttonSymbols; QSpinBoxValidator *validator; + uint showGroupSeparator : 1; }; class QSpinBoxValidator : public QValidator diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2c09f5a8f1..17a6ededfe 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2608,9 +2608,9 @@ void QComboBox::hidePopup() Q_D(QComboBox); if (d->container && d->container->isVisible()) { #if !defined(QT_NO_EFFECTS) - d->model->blockSignals(true); - d->container->itemView()->blockSignals(true); - d->container->blockSignals(true); + QSignalBlocker modelBlocker(d->model); + QSignalBlocker viewBlocker(d->container->itemView()); + QSignalBlocker containerBlocker(d->container); // Flash selected/triggered item (if any). if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) { QItemSelectionModel *selectionModel = view() ? view()->selectionModel() : 0; @@ -2646,9 +2646,9 @@ void QComboBox::hidePopup() #endif // Q_OS_MAC // Other platform implementations welcome :-) } - d->model->blockSignals(false); - d->container->itemView()->blockSignals(false); - d->container->blockSignals(false); + containerBlocker.unblock(); + viewBlocker.unblock(); + modelBlocker.unblock(); if (!didFade) #endif // QT_NO_EFFECTS diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index a0bbbbf7c7..6bfc251a2a 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1718,7 +1718,7 @@ void QDateTimeEditPrivate::updateEdit() if (newText == displayText()) return; int selsize = edit->selectedText().size(); - const bool sb = edit->blockSignals(true); + const QSignalBlocker blocker(edit); edit->setText(newText); @@ -1740,7 +1740,6 @@ void QDateTimeEditPrivate::updateEdit() } } - edit->blockSignals(sb); } @@ -1871,7 +1870,7 @@ void QDateTimeEditPrivate::clearSection(int index) { const QLatin1Char space(' '); int cursorPos = edit->cursorPosition(); - bool blocked = edit->blockSignals(true); + const QSignalBlocker blocker(edit); QString t = edit->text(); const int pos = sectionPos(index); if (pos == -1) { @@ -1883,8 +1882,6 @@ void QDateTimeEditPrivate::clearSection(int index) edit->setText(t); edit->setCursorPosition(cursorPos); QDTEDEBUG << cursorPos; - - edit->blockSignals(blocked); } @@ -2574,10 +2571,9 @@ void QDateTimeEditPrivate::syncCalendarWidget() { Q_Q(QDateTimeEdit); if (monthCalendar) { - const bool sb = monthCalendar->blockSignals(true); + const QSignalBlocker blocker(monthCalendar); monthCalendar->setDateRange(q->minimumDate(), q->maximumDate()); monthCalendar->setDate(q->date()); - monthCalendar->blockSignals(sb); } } diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 72a463b30b..8dab6afb81 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2096,7 +2096,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const that->tabBar->setDrawBase(true); } - bool blocked = tabBar->blockSignals(true); + const QSignalBlocker blocker(tabBar); bool gap = false; int tab_idx = 0; @@ -2147,8 +2147,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->removeTab(tab_idx); } - tabBar->blockSignals(blocked); - //returns if the tabbar is visible or not return ( (gap ? 1 : 0) + tabBar->count()) > 1; } diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index 0b0efa2bdf..2bbf3730db 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -346,9 +346,10 @@ void QFontComboBoxPrivate::_q_updateModel() //this prevents the current index from changing //it will be updated just after this ///TODO: we should finda way to avoid blocking signals and have a real update of the model - const bool old = m->blockSignals(true); - m->setStringList(list); - m->blockSignals(old); + { + const QSignalBlocker blocker(m); + m->setStringList(list); + } if (list.isEmpty()) { if (currentFont != QFont()) { diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h index 3dde1527f2..ba7b2d8494 100644 --- a/src/widgets/widgets/qlcdnumber.h +++ b/src/widgets/widgets/qlcdnumber.h @@ -43,7 +43,6 @@ #define QLCDNUMBER_H #include <QtWidgets/qframe.h> -#include <QtCore/qbitarray.h> QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index df5ae0171c..1833dce40b 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -333,7 +333,12 @@ void QLineEdit::setText(const QString& text) \brief the line edit's placeholder text Setting this property makes the line edit display a grayed-out - placeholder text as long as the text() is empty. + placeholder text as long as the line edit is empty. + + Normally, an empty line edit shows the placeholder text even + when it has focus. However, if the content is horizontally + centered, the placeholder text is not displayed under + the cursor when the line edit has focus. By default, this property contains an empty string. @@ -350,7 +355,7 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText) Q_D(QLineEdit); if (d->placeholderText != placeholderText) { d->placeholderText = placeholderText; - if (d->control->text().isEmpty()) + if (d->shouldShowPlaceholderText()) update(); } } @@ -1895,7 +1900,7 @@ void QLineEdit::paintEvent(QPaintEvent *) int minLB = qMax(0, -fm.minLeftBearing()); int minRB = qMax(0, -fm.minRightBearing()); - if (d->control->text().isEmpty() && d->control->preeditAreaText().isEmpty()) { + if (d->shouldShowPlaceholderText()) { if (!d->placeholderText.isEmpty()) { QColor col = pal.text().color(); col.setAlpha(128); diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 181a23449b..aa5b57a920 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -148,6 +148,11 @@ public: { return !control->isReadOnly(); } + inline bool shouldShowPlaceholderText() const + { + return control->text().isEmpty() && control->preeditAreaText().isEmpty() + && !((alignment & Qt::AlignHCenter) && q_func()->hasFocus()); + } static inline QLineEditPrivate *get(QLineEdit *lineEdit) { return lineEdit->d_func(); diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index 349d8c3423..600d9b536f 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -1115,10 +1115,9 @@ void QMdiAreaPrivate::updateActiveWindow(int removedIndex, bool activeRemoved) #ifndef QT_NO_TABBAR if (tabBar && removedIndex >= 0) { - tabBar->blockSignals(true); + const QSignalBlocker blocker(tabBar); tabBar->removeTab(removedIndex); updateTabBarGeometry(); - tabBar->blockSignals(false); } #endif diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 3a4fd449c8..d1b0da1a55 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -435,7 +435,7 @@ void QMenuPrivate::hideMenu(QMenu *menu) if (!menu) return; #if !defined(QT_NO_EFFECTS) - menu->blockSignals(true); + QSignalBlocker blocker(menu); aboutToHide = true; // Flash item which is about to trigger (if any). if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem) @@ -455,7 +455,7 @@ void QMenuPrivate::hideMenu(QMenu *menu) } aboutToHide = false; - menu->blockSignals(false); + blocker.unblock(); #endif // QT_NO_EFFECTS menu->close(); } diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 90f2e47cd3..df86d141b4 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -639,9 +639,10 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) lineNumber = maxTopLine - block.firstLineNumber(); } - bool vbarSignalsBlocked = vbar->blockSignals(true); - vbar->setValue(newTopLine); - vbar->blockSignals(vbarSignalsBlocked); + { + const QSignalBlocker blocker(vbar); + vbar->setValue(newTopLine); + } if (!dx && blockNumber == control->topBlock && lineNumber == topLine) return; @@ -657,9 +658,10 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) control->topBlock = blockNumber; topLine = lineNumber; - bool vbarSignalsBlocked = vbar->blockSignals(true); - vbar->setValue(block.firstLineNumber() + lineNumber); - vbar->blockSignals(vbarSignalsBlocked); + { + const QSignalBlocker blocker(vbar); + vbar->setValue(block.firstLineNumber() + lineNumber); + } if (dx || dy) { viewport->scroll(q->isRightToLeft() ? -dx : dx, dy); @@ -1006,9 +1008,11 @@ void QPlainTextEditPrivate::_q_adjustScrollbars() QTextBlock firstVisibleBlock = q->firstVisibleBlock(); if (firstVisibleBlock.isValid()) visualTopLine = firstVisibleBlock.firstLineNumber() + topLine; - bool vbarSignalsBlocked = vbar->blockSignals(true); - vbar->setValue(visualTopLine); - vbar->blockSignals(vbarSignalsBlocked); + + { + const QSignalBlocker blocker(vbar); + vbar->setValue(visualTopLine); + } hbar->setRange(0, (int)documentSize.width() - viewport->width()); hbar->setPageStep(viewport->width()); diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index 2a34451408..e198dae168 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -463,8 +463,8 @@ void QSpinBox::setDisplayIntegerBase(int base) display the given \a value. The default implementation returns a string containing \a value printed in the standard way using QWidget::locale().toString(), but with the thousand separator - removed. Reimplementations may return anything. (See the example - in the detailed description.) + removed unless setGroupSeparatorShown() is set. Reimplementations may + return anything. (See the example in the detailed description.) Note: QSpinBox does not call this function for specialValueText() and that neither prefix() nor suffix() should be included in the @@ -487,7 +487,7 @@ QString QSpinBox::textFromValue(int value) const str.prepend('-'); } else { str = locale().toString(value); - if (qAbs(value) >= 1000 || value == INT_MIN) { + if (!d->showGroupSeparator && (qAbs(value) >= 1000 || value == INT_MIN)) { str.remove(locale().groupSeparator()); } } @@ -538,7 +538,8 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const */ void QSpinBox::fixup(QString &input) const { - input.remove(locale().groupSeparator()); + if (!isGroupSeparatorShown()) + input.remove(locale().groupSeparator()); } @@ -891,7 +892,8 @@ void QDoubleSpinBox::setDecimals(int decimals) display the given \a value. The default implementation returns a string containing \a value printed using QWidget::locale().toString(\a value, QLatin1Char('f'), decimals()) and will remove the thousand - separator. Reimplementations may return anything. + separator unless setGroupSeparatorShown() is set. Reimplementations may + return anything. Note: QDoubleSpinBox does not call this function for specialValueText() and that neither prefix() nor suffix() should @@ -908,9 +910,9 @@ QString QDoubleSpinBox::textFromValue(double value) const { Q_D(const QDoubleSpinBox); QString str = locale().toString(value, 'f', d->decimals); - if (qAbs(value) >= 1000.0) { + if (!d->showGroupSeparator && qAbs(value) >= 1000.0) str.remove(locale().groupSeparator()); - } + return str; } diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index b2a0d3f8b8..db9db68039 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -251,7 +251,9 @@ inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000) break; QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); -#ifdef Q_OS_WIN +#if defined(Q_OS_WINRT) + WaitForSingleObjectEx(GetCurrentThread(), TimeOutMs, false); +#elif defined(Q_OS_WIN) Sleep(uint(TimeOutMs)); #else struct timespec ts = { TimeOutMs / 1000, (TimeOutMs % 1000) * 1000 * 1000 }; diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 8c15b3e58e..fced1c01ec 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -759,11 +759,10 @@ void QTabWidgetPrivate::_q_removeTab(int index) void QTabWidgetPrivate::_q_tabMoved(int from, int to) { - stack->blockSignals(true); + const QSignalBlocker blocker(stack); QWidget *w = stack->widget(from); stack->removeWidget(w); stack->insertWidget(to, w); - stack->blockSignals(false); } /* |