diff options
Diffstat (limited to 'src/quicktemplates2')
30 files changed, 919 insertions, 112 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 5520e074..8632e14c 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -44,7 +44,9 @@ #include <QtGui/qstylehints.h> #include <QtGui/qguiapplication.h> -#include <QtGui/private/qshortcutmap_p.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif #include <QtGui/private/qguiapplication_p.h> #include <QtQuick/private/qquickevents_p_p.h> #include <QtQml/qqmllist.h> @@ -713,7 +715,7 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); d->removeImplicitSizeListener(d->indicator); - delete d->indicator; + QQuickControlPrivate::hideOldItem(d->indicator); d->indicator = indicator; if (indicator) { @@ -1018,8 +1020,8 @@ void QQuickAbstractButton::componentComplete() bool QQuickAbstractButton::event(QEvent *event) { - Q_D(QQuickAbstractButton); #if QT_CONFIG(shortcut) + Q_D(QQuickAbstractButton); if (event->type() == QEvent::Shortcut) { QShortcutEvent *se = static_cast<QShortcutEvent *>(event); if (se->shortcutId() == d->shortcutId) { @@ -1106,9 +1108,9 @@ void QQuickAbstractButton::timerEvent(QTimerEvent *event) void QQuickAbstractButton::itemChange(ItemChange change, const ItemChangeData &value) { - Q_D(QQuickAbstractButton); QQuickControl::itemChange(change, value); #if QT_CONFIG(shortcut) + Q_D(QQuickAbstractButton); if (change == ItemVisibleHasChanged) { if (value.boolValue) d->grabShortcut(); diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index e079836d..9291c1a8 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -50,7 +50,9 @@ #include <QtQuickTemplates2/private/qquickabstractbutton_p.h> #include <QtQuickTemplates2/private/qquickcontrol_p_p.h> -#include <QtGui/qkeysequence.h> +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif QT_BEGIN_NAMESPACE diff --git a/src/quicktemplates2/qquickaction.cpp b/src/quicktemplates2/qquickaction.cpp index 6cb63238..0b083339 100644 --- a/src/quicktemplates2/qquickaction.cpp +++ b/src/quicktemplates2/qquickaction.cpp @@ -40,7 +40,9 @@ #include "qquickshortcutcontext_p_p.h" #include <QtGui/qevent.h> -#include <QtGui/private/qshortcutmap_p.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif #include <QtGui/private/qguiapplication_p.h> #include <QtQuick/private/qquickitem_p.h> @@ -261,6 +263,8 @@ void QQuickActionPrivate::unregisterItem(QQuickItem *item) delete entry; updateDefaultShortcutEntry(); +#else + Q_UNUSED(item); #endif } @@ -277,6 +281,8 @@ void QQuickActionPrivate::itemVisibilityChanged(QQuickItem *item) entry->ungrab(); updateDefaultShortcutEntry(); +#else + Q_UNUSED(item); #endif } @@ -332,8 +338,8 @@ void QQuickActionPrivate::updateDefaultShortcutEntry() QQuickAction::QQuickAction(QObject *parent) : QObject(*(new QQuickActionPrivate), parent) { - Q_D(QQuickAction); #if QT_CONFIG(shortcut) + Q_D(QQuickAction); d->defaultShortcutEntry = new QQuickActionPrivate::ShortcutEntry(this); #endif } @@ -554,8 +560,8 @@ void QQuickActionPrivate::trigger(QObject* source, bool doToggle) bool QQuickAction::event(QEvent *event) { - Q_D(QQuickAction); #if QT_CONFIG(shortcut) + Q_D(QQuickAction); if (event->type() == QEvent::Shortcut) return d->handleShortcutEvent(this, static_cast<QShortcutEvent *>(event)); #endif @@ -564,10 +570,13 @@ bool QQuickAction::event(QEvent *event) bool QQuickAction::eventFilter(QObject *object, QEvent *event) { - Q_D(QQuickAction); #if QT_CONFIG(shortcut) + Q_D(QQuickAction); if (event->type() == QEvent::Shortcut) return d->handleShortcutEvent(object, static_cast<QShortcutEvent *>(event)); +#else + Q_UNUSED(object); + Q_UNUSED(event); #endif return false; } diff --git a/src/quicktemplates2/qquickaction_p_p.h b/src/quicktemplates2/qquickaction_p_p.h index 7c70bab1..252b0075 100644 --- a/src/quicktemplates2/qquickaction_p_p.h +++ b/src/quicktemplates2/qquickaction_p_p.h @@ -51,7 +51,9 @@ #include <QtCore/private/qobject_p.h> #include <QtCore/qvariant.h> #include <QtCore/qstring.h> -#include <QtGui/qkeysequence.h> +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif #include <QtQuick/private/qquickitemchangelistener_p.h> QT_BEGIN_NAMESPACE @@ -119,8 +121,8 @@ public: bool checkable = false; QString text; QQuickIcon icon; - QKeySequence keySequence; #if QT_CONFIG(shortcut) + QKeySequence keySequence; QVariant vshortcut; ShortcutEntry *defaultShortcutEntry = nullptr; QVector<ShortcutEntry *> shortcutEntries; diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 92d19a37..903de676 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -407,7 +407,7 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (!d->background.isExecuting()) d->cancelBackground(); - delete d->background; + QQuickControlPrivate::hideOldItem(d->background); d->background = background; if (background) { background->setParentItem(QQuickWindow::contentItem()); diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 7833b39b..5f3f1cfc 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -51,6 +51,7 @@ #include <QtQml/qqmlcontext.h> #include <QtQml/private/qlazilyallocated_p.h> #include <private/qqmldelegatemodel_p.h> +#include <QtQuick/private/qquickaccessibleattached_p.h> #include <QtQuick/private/qquickevents_p_p.h> #include <QtQuick/private/qquicktextinput_p.h> #include <QtQuick/private/qquickitemview_p.h> @@ -232,13 +233,9 @@ public: void updateEditText(); void updateCurrentText(); void updateCurrentValue(); - void updateCurrentText(bool hasDelegateModelObject); - void updateCurrentValue(bool hasDelegateModelObject); void updateCurrentTextAndValue(); bool isValidIndex(int index) const; - QString fastTextAt(int index) const; - QVariant fastValueAt(int index) const; void acceptInput(); QString tryComplete(const QString &inputText); @@ -268,6 +265,8 @@ public: void itemImplicitWidthChanged(QQuickItem *item) override; void itemImplicitHeightChanged(QQuickItem *item) override; + static void hideOldPopup(QQuickPopup *popup); + bool flat = false; bool down = false; bool hasDown = false; @@ -294,6 +293,7 @@ public: bool editable = false; bool accepting = false; bool allowComplete = false; + bool selectTextByMouse = false; Qt::InputMethodHints inputMethodHints = Qt::ImhNone; QString editText; QValidator *validator = nullptr; @@ -441,34 +441,10 @@ void QQuickComboBoxPrivate::updateEditText() q->setEditText(text); } -// We have these two rather than just using default arguments -// because QObjectPrivate::connect() doesn't accept lambdas. void QQuickComboBoxPrivate::updateCurrentText() { - updateCurrentText(false); -} - -void QQuickComboBoxPrivate::updateCurrentValue() -{ - updateCurrentValue(false); -} - -void QQuickComboBoxPrivate::updateCurrentText(bool hasDelegateModelObject) -{ Q_Q(QQuickComboBox); - QString text; - // If a delegate model object was passed in, it means the calling code - // has decided to reuse it for several function calls to speed things up. - // So, use the faster (private) version in that case. - // For other cases, we use the version that creates the delegate model object - // itself in order to have neater, more convenient calling code. - if (isValidIndex(currentIndex)) { - if (hasDelegateModelObject) - text = fastTextAt(currentIndex); - else - text = q->textAt(currentIndex); - } - + const QString text = q->textAt(currentIndex); if (currentText != text) { currentText = text; if (!hasDisplayText) @@ -483,19 +459,10 @@ void QQuickComboBoxPrivate::updateCurrentText(bool hasDelegateModelObject) q->setEditText(currentText); } -void QQuickComboBoxPrivate::updateCurrentValue(bool hasDelegateModelObject) +void QQuickComboBoxPrivate::updateCurrentValue() { Q_Q(QQuickComboBox); - QVariant value; - // If a delegate model object was passed in, it means the calling code - // has decided to reuse it for several function calls to speed things up. - // So, use the faster (private) version in that case. - if (isValidIndex(currentIndex)) { - if (hasDelegateModelObject) - value = fastValueAt(currentIndex); - else - value = q->valueAt(currentIndex); - } + const QVariant value = q->valueAt(currentIndex); if (currentValue == value) return; @@ -505,15 +472,8 @@ void QQuickComboBoxPrivate::updateCurrentValue(bool hasDelegateModelObject) void QQuickComboBoxPrivate::updateCurrentTextAndValue() { - QObject *object = nullptr; - // For performance reasons, we reuse the same delegate model object: QTBUG-76029. - if (isValidIndex(currentIndex)) - object = delegateModel->object(currentIndex); - const bool hasDelegateModelObject = object != nullptr; - updateCurrentText(hasDelegateModelObject); - updateCurrentValue(hasDelegateModelObject); - if (object) - delegateModel->release(object); + updateCurrentText(); + updateCurrentValue(); } bool QQuickComboBoxPrivate::isValidIndex(int index) const @@ -521,20 +481,6 @@ bool QQuickComboBoxPrivate::isValidIndex(int index) const return delegateModel && index >= 0 && index < delegateModel->count(); } -// For performance reasons (QTBUG-76029), both this and valueAt assume that -// the index is valid and delegateModel->object(index) has been called. -QString QQuickComboBoxPrivate::fastTextAt(int index) const -{ - const QString effectiveTextRole = textRole.isEmpty() ? QStringLiteral("modelData") : textRole; - return delegateModel->stringValue(index, effectiveTextRole); -} - -QVariant QQuickComboBoxPrivate::fastValueAt(int index) const -{ - const QString effectiveValueRole = valueRole.isEmpty() ? QStringLiteral("modelData") : valueRole; - return delegateModel->variantValue(index, effectiveValueRole); -} - void QQuickComboBoxPrivate::acceptInput() { Q_Q(QQuickComboBox); @@ -832,6 +778,21 @@ void QQuickComboBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) emit q->implicitIndicatorHeightChanged(); } +void QQuickComboBoxPrivate::hideOldPopup(QQuickPopup *popup) +{ + if (!popup) + return; + + qCDebug(lcItemManagement) << "hiding old popup" << popup; + + popup->setVisible(false); + popup->setParentItem(nullptr); + // Remove the item from the accessibility tree. + QQuickAccessibleAttached *accessible = accessibleAttached(popup); + if (accessible) + accessible->setIgnored(true); +} + QQuickComboBox::QQuickComboBox(QQuickItem *parent) : QQuickControl(*(new QQuickComboBoxPrivate), parent) { @@ -852,7 +813,7 @@ QQuickComboBox::~QQuickComboBox() // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal // emission during the destruction of the (visible) popup. (QTBUG-57650) QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - delete d->popup; + QQuickComboBoxPrivate::hideOldPopup(d->popup); d->popup = nullptr; } } @@ -1194,7 +1155,7 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); d->removeImplicitSizeListener(d->indicator); - delete d->indicator; + QQuickControlPrivate::hideOldItem(d->indicator); d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) @@ -1242,7 +1203,7 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) if (d->popup) { QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - delete d->popup; + QQuickComboBoxPrivate::hideOldPopup(d->popup); } if (popup) { QQuickPopupPrivate::get(popup)->allowVerticalFlip = true; @@ -1583,13 +1544,8 @@ QVariant QQuickComboBox::valueAt(int index) const if (!d->isValidIndex(index)) return QVariant(); - QObject *object = d->delegateModel->object(index); - QVariant value; - if (object) { - value = d->fastValueAt(index); - d->delegateModel->release(object); - } - return value; + const QString effectiveValueRole = d->valueRole.isEmpty() ? QStringLiteral("modelData") : d->valueRole; + return d->delegateModel->variantValue(index, effectiveValueRole); } /*! @@ -1613,6 +1569,30 @@ int QQuickComboBox::indexOfValue(const QVariant &value) const } /*! + \since QtQuick.Controls 2.15 (Qt 5.15) + \qmlproperty bool QtQuick.Controls::ComboBox::selectTextByMouse + + This property holds whether the text field for an editable ComboBox + can be selected with the mouse. + + The default value is \c false. +*/ +bool QQuickComboBox::selectTextByMouse() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() ? d->extra->selectTextByMouse : false; +} + +void QQuickComboBox::setSelectTextByMouse(bool canSelect) +{ + Q_D(QQuickComboBox); + if (canSelect == selectTextByMouse()) + return; + + d->extra.value().selectTextByMouse = canSelect; + emit selectTextByMouseChanged(); +} +/*! \qmlmethod string QtQuick.Controls::ComboBox::textAt(int index) Returns the text for the specified \a index, or an empty string @@ -1626,13 +1606,8 @@ QString QQuickComboBox::textAt(int index) const if (!d->isValidIndex(index)) return QString(); - QObject *object = d->delegateModel->object(index); - QString text; - if (object) { - text = d->fastTextAt(index); - d->delegateModel->release(object); - } - return text; + const QString effectiveTextRole = d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole; + return d->delegateModel->stringValue(index, effectiveTextRole); } /*! diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index c9063d6a..b52d7545 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -48,10 +48,13 @@ // We mean it. // +#include <QtCore/qloggingcategory.h> #include <QtQuickTemplates2/private/qquickcontrol_p.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcItemManagement) + class QValidator; class QQuickPopup; class QQmlInstanceModel; @@ -89,6 +92,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl // 2.14 (Qt 5.14) Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged FINAL REVISION 14) Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged FINAL REVISION 14) + // 2.15 (Qt 5.15) + Q_PROPERTY(bool selectTextByMouse READ selectTextByMouse WRITE setSelectTextByMouse NOTIFY selectTextByMouseChanged FINAL REVISION 15) public: explicit QQuickComboBox(QQuickItem *parent = nullptr); @@ -166,6 +171,10 @@ public: Q_REVISION(14) Q_INVOKABLE QVariant valueAt(int index) const; Q_REVISION(14) Q_INVOKABLE int indexOfValue(const QVariant &value) const; + // 2.15 (Qt 5.15) + bool selectTextByMouse() const; + void setSelectTextByMouse(bool canSelect); + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); @@ -203,6 +212,8 @@ Q_SIGNALS: // 2.14 (Qt 5.14) Q_REVISION(14) void valueRoleChanged(); Q_REVISION(14) void currentValueChanged(); + // 2.15 (Qt 5.15) + Q_REVISION(15) void selectTextByMouseChanged(); protected: bool eventFilter(QObject *object, QEvent *event) override; diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 19b59e33..f38c2b09 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -219,7 +219,7 @@ void QQuickContainerPrivate::cleanup() QQuickWindowPrivate::get(window)->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason); q->contentItemChange(nullptr, contentItem); - delete contentItem; + QQuickControlPrivate::hideOldItem(contentItem); } QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged); diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 838a841d..4eb411c2 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -56,6 +56,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcItemManagement, "qt.quick.controls.control.itemmanagement") + /*! \qmltype Control \inherits Item @@ -428,7 +430,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) contentItem = item; q->contentItemChange(item, oldContentItem); - delete oldContentItem; + QQuickControlPrivate::hideOldItem(oldContentItem); if (item) { connect(contentItem.data(), &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset); @@ -846,6 +848,22 @@ void QQuickControlPrivate::executeBackground(bool complete) quickCompleteDeferred(q, backgroundName(), background); } +void QQuickControlPrivate::hideOldItem(QQuickItem *item) +{ + if (!item) + return; + + qCDebug(lcItemManagement) << "hiding old item" << item; + + item->setVisible(false); + item->setParentItem(nullptr); + + // Remove the item from the accessibility tree. + QQuickAccessibleAttached *accessible = accessibleAttached(item); + if (accessible) + accessible->setIgnored(true); +} + void QQuickControlPrivate::updateBaselineOffset() { Q_Q(QQuickControl); @@ -1598,7 +1616,7 @@ void QQuickControl::setBackground(QQuickItem *background) } d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); - delete d->background; + QQuickControlPrivate::hideOldItem(d->background); d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 1b59f86d..fa06c97f 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -60,8 +60,12 @@ #include <QtGui/qaccessible.h> #endif +#include <QtCore/qloggingcategory.h> + QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcItemManagement) + class QQuickAccessibleAttached; class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControlPrivate : public QQuickItemPrivate, public QQuickItemChangeListener @@ -168,6 +172,8 @@ public: virtual void cancelBackground(); virtual void executeBackground(bool complete = false); + static void hideOldItem(QQuickItem *item); + void updateBaselineOffset(); static const ChangeTypes ImplicitSizeChanges; diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp index 800dcedb..d56131e4 100644 --- a/src/quicktemplates2/qquickdeferredexecute.cpp +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -92,11 +92,21 @@ static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro typedef QMultiHash<int, const QV4::CompiledData::Binding *> QV4PropertyBindingHash; auto it = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.second); auto last = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.first); +#if Q_QML_PRIVATE_API_VERSION < 7 while (it != last) { if (!state->creator->populateDeferredBinding(property, deferData, *it)) state->errors << state->creator->errors; ++it; } +#else + state->creator->beginPopulateDeferred(deferData->context); + while (it != last) { + state->creator->populateDeferredBinding(property, deferData->deferredIdx, *it); + ++it; + } + state->creator->finalizePopulateDeferred(); + state->errors << state->creator->errors; +#endif deferredState->constructionStates += state; diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index b07628ff..99bd0e98 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -620,7 +620,7 @@ void QQuickDial::setHandle(QQuickItem *handle) if (!d->handle.isExecuting()) d->cancelHandle(); - delete d->handle; + QQuickControlPrivate::hideOldItem(d->handle); d->handle = handle; if (d->handle && !d->handle->parentItem()) d->handle->setParentItem(this); diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp index d448aeed..f3dd2da1 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox.cpp +++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp @@ -545,7 +545,7 @@ void QQuickDialogButtonBox::setAlignment(Qt::Alignment alignment) void QQuickDialogButtonBox::resetAlignment() { - setAlignment(0); + setAlignment({}); } /*! diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h index 6f9c9033..22da9e6d 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox_p_p.h +++ b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h @@ -80,7 +80,7 @@ public: void updateLanguage(); - Qt::Alignment alignment = 0; + Qt::Alignment alignment; QQuickDialogButtonBox::Position position = QQuickDialogButtonBox::Footer; QPlatformDialogHelper::StandardButtons standardButtons = QPlatformDialogHelper::NoButton; QPlatformDialogHelper::ButtonLayout buttonLayout = QPlatformDialogHelper::UnknownLayout; diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index 3dbf3174..70ec30dc 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -199,7 +199,7 @@ void QQuickGroupBox::setLabel(QQuickItem *label) const qreal oldImplicitLabelHeight = implicitLabelHeight(); d->removeImplicitSizeListener(d->label); - delete d->label; + QQuickControlPrivate::hideOldItem(d->label); d->label = label; if (label) { diff --git a/src/quicktemplates2/qquickheaderview.cpp b/src/quicktemplates2/qquickheaderview.cpp new file mode 100644 index 00000000..49463944 --- /dev/null +++ b/src/quicktemplates2/qquickheaderview.cpp @@ -0,0 +1,500 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTemplates2/private/qquickheaderview_p_p.h> +#include <algorithm> + +/*! + \qmltype HorizontalHeaderView + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-containers + \inherits TableView + \brief Provides a horizontal header view to accompany a \l TableView. + + A HorizontalHeaderView provides labeling of the columns of a \l TableView. + To add a horizontal header to a TableView, bind the + \l {HorizontalHeaderView::syncView} {syncView} property to the TableView: + + \snippet qtquickcontrols2-headerview-simple.qml horizontal + + The header displays data from the {syncView}'s model by default, but can + also have its own model. If the model is a QAbstractTableModel, then + the header will display the model's horizontal headerData(); otherwise, + the model's data(). +*/ + +/*! + \qmltype VerticalHeaderView + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-containers + \inherits TableView + \brief Provides a vertical header view to accompany a \l TableView. + + A VerticalHeaderView provides labeling of the rows of a \l TableView. + To add a vertical header to a TableView, bind the + \l {VerticalHeaderView::syncView} {syncView} property to the TableView: + + \snippet qtquickcontrols2-headerview-simple.qml vertical + + The header displays data from the {syncView}'s model by default, but can + also have its own model. If the model is a QAbstractTableModel, then + the header will display the model's vertical headerData(); otherwise, + the model's data(). +*/ + +/*! + \qmlproperty TableView QtQuick::HorizontalHeaderView::syncView + + This property holds the TableView to synchronize with. + + Once this property is bound to another TableView, both header and table + will synchronize with regard to column widths, column spacing, and flicking + horizontally. + + If the \l model is not explicitly set, then the header will use the syncView's + model to label the columns. + + \sa model TableView +*/ + +/*! + \qmlproperty TableView QtQuick::VerticalHeaderView::syncView + + This property holds the TableView to synchronize with. + + Once this property is bound to another TableView, both header and table + will synchronize with regard to row heights, row spacing, and flicking + vertically. + + If the \l model is not explicitly set, then the header will use the syncView's + model to label the rows. + + \sa model TableView +*/ + +/*! + \qmlproperty QVariant QtQuick::HorizontalHeaderView::model + + This property holds the model providing data for the horizontal header view. + + When model is not explicitly set, the header will use the syncView's + model once syncView is set. + + If model is a QAbstractTableModel, its horizontal headerData() will + be accessed. + + If model is a QAbstractItemModel other than QAbstractTableModel, model's data() + will be accessed. + + Otherwise, the behavior is same as setting TableView::model. + + \sa TableView {TableView::model} {model} QAbstractTableModel +*/ + +/*! + \qmlproperty QVariant QtQuick::VerticalHeaderView::model + + This property holds the model providing data for the vertical header view. + + When model is not explicitly set, it will be synchronized with syncView's model + once syncView is set. + + If model is a QAbstractTableModel, its vertical headerData() will + be accessed. + + If model is a QAbstractItemModel other than QAbstractTableModel, model's data() + will be accessed. + + Otherwise, the behavior is same as setting TableView::model. + + \sa TableView {TableView::model} {model} QAbstractTableModel +*/ + +/*! + \qmlproperty QString QtQuick::HorizontalHeaderView::textRole + + This property holds the model role used to display text in each header cell. + + The default value is the \c "display" role. + + \sa QAbstractItemModel::roleNames() +*/ + +/*! + \qmlproperty QString QtQuick::VerticalHeaderView::textRole + + This property holds the model role used to display text in each header cell. + + The default value is the \c "display" role. + + \sa QAbstractItemModel::roleNames() +*/ + +QT_BEGIN_NAMESPACE + +QQuickHeaderViewBasePrivate::QQuickHeaderViewBasePrivate() + : QQuickTableViewPrivate() +{ +} + +QQuickHeaderViewBasePrivate::~QQuickHeaderViewBasePrivate() +{ +} + +const QPointer<QQuickItem> QQuickHeaderViewBasePrivate::delegateItemAt(int row, int col) const +{ + return loadedTableItem(QPoint(col, row))->item; +} + +QVariant QQuickHeaderViewBasePrivate::modelImpl() const +{ + if (auto model = m_headerDataProxyModel.sourceModel()) + return QVariant::fromValue(model.data()); + if (auto model = m_transposeProxyModel.sourceModel()) + return QVariant::fromValue(model); + return QQuickTableViewPrivate::modelImpl(); +} + +template <typename P, typename M> +inline bool proxyModelSetter(QQuickHeaderViewBase *const q, P &proxyModel, M *model) +{ + if (model) { + if (model == proxyModel.sourceModel()) + return true; + proxyModel.setSourceModel(model); + const auto &modelVariant = QVariant::fromValue(std::addressof(proxyModel)); + bool isProxyModelChanged = (modelVariant != QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::modelImpl()); + QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::setModelImpl(modelVariant); + //Necessary, since TableView's assigned model not changed, but proxy's source changed + if (!isProxyModelChanged) + emit q->modelChanged(); + return true; + } + proxyModel.setSourceModel(nullptr); + return false; +} + +void QQuickHeaderViewBasePrivate::setModelImpl(const QVariant &newModel) +{ + Q_Q(QQuickHeaderViewBase); + m_modelExplicitlySetByUser = true; + // Case 1: newModel is QAbstractTableModel + if (proxyModelSetter(q, m_headerDataProxyModel, newModel.value<QAbstractTableModel *>())) + return; + // Case 2: newModel is QAbstractItemModel but not QAbstractTableModel + if (orientation() == Qt::Horizontal + && proxyModelSetter(q, m_transposeProxyModel, newModel.value<QAbstractItemModel *>())) + return; + + QQuickTableViewPrivate::setModelImpl(newModel); +} + +void QQuickHeaderViewBasePrivate::syncModel() +{ + Q_Q(QQuickHeaderViewBase); + if (assignedSyncView && !m_modelExplicitlySetByUser) { + auto newModel = assignedSyncView->model(); + if (auto m = newModel.value<QAbstractTableModel *>()) { + proxyModelSetter(q, m_headerDataProxyModel, m); + } else if (orientation() == Qt::Horizontal) { + if (auto m = newModel.value<QAbstractItemModel *>()) + proxyModelSetter(q, m_transposeProxyModel, m); + } else { + QQuickTableViewPrivate::setModelImpl(newModel); + } + } + + QQuickTableViewPrivate::syncModel(); +} + +void QQuickHeaderViewBasePrivate::syncSyncView() +{ + Q_Q(QQuickHeaderViewBase); + if (assignedSyncDirection != orientation()) { + qmlWarning(q_func()) << "Setting syncDirection other than Qt::" + << QVariant::fromValue(orientation()).toString() + << " is invalid."; + assignedSyncDirection = orientation(); + } + if (assignedSyncView) { + QBoolBlocker fixupGuard(inUpdateContentSize, true); + if (orientation() == Qt::Horizontal) { + q->setLeftMargin(assignedSyncView->leftMargin()); + q->setRightMargin(assignedSyncView->rightMargin()); + } else { + q->setTopMargin(assignedSyncView->topMargin()); + q->setBottomMargin(assignedSyncView->bottomMargin()); + } + } + QQuickTableViewPrivate::syncSyncView(); +} + +QQuickHeaderViewBase::QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent) + : QQuickTableView(*(new QQuickHeaderViewBasePrivate), parent) +{ + d_func()->setOrientation(orient); + setSyncDirection(orient); +} + +QQuickHeaderViewBase::QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent) + : QQuickTableView(dd, parent) +{ +} + +QQuickHeaderViewBase::~QQuickHeaderViewBase() +{ +} + +QString QQuickHeaderViewBase::textRole() const +{ + Q_D(const QQuickHeaderViewBase); + return d->m_textRole; +} + +void QQuickHeaderViewBase::setTextRole(const QString &role) +{ + Q_D(QQuickHeaderViewBase); + if (d->m_textRole == role) + return; + + d->m_textRole = role; + emit textRoleChanged(); +} + +Qt::Orientation QQuickHeaderViewBasePrivate::orientation() const +{ + return m_headerDataProxyModel.orientation(); +} + +void QQuickHeaderViewBasePrivate::setOrientation(Qt::Orientation orientation) +{ + if (QQuickHeaderViewBasePrivate::orientation() == orientation) + return; + m_headerDataProxyModel.setOrientation(orientation); +} + +QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent) + : QQuickHeaderViewBase(dd, parent) +{ +} + +/*! \internal + \class QHeaderDataProxyModel + \brief + QHeaderDataProxyModel is a proxy AbstractItemModel type that maps + source model's headerData() to correspondent data() + */ +QHeaderDataProxyModel::QHeaderDataProxyModel(QObject *parent) + : QAbstractItemModel(parent) +{ +} + +QHeaderDataProxyModel::~QHeaderDataProxyModel() = default; + +void QHeaderDataProxyModel::setSourceModel(QAbstractItemModel *newSourceModel) +{ + if (m_model == newSourceModel) + return; + beginResetModel(); + disconnectFromModel(); + m_model = newSourceModel; + connectToModel(); + endResetModel(); +} + +QModelIndex QHeaderDataProxyModel::index(int row, int column, const QModelIndex &parent) const +{ + return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex(); +} + +QModelIndex QHeaderDataProxyModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return QModelIndex(); +} + +QModelIndex QHeaderDataProxyModel::sibling(int row, int column, const QModelIndex &idx) const +{ + return index(row, column, idx); +} + +int QHeaderDataProxyModel::rowCount(const QModelIndex &parent) const +{ + return m_model.isNull() ? -1 : (m_orientation == Qt::Horizontal ? 1 : m_model->rowCount(parent)); +} + +int QHeaderDataProxyModel::columnCount(const QModelIndex &parent) const +{ + return m_model.isNull() ? -1 : (m_orientation == Qt::Vertical ? 1 : m_model->columnCount(parent)); +} + +QVariant QHeaderDataProxyModel::data(const QModelIndex &index, int role) const +{ + if (m_model.isNull()) + return QVariant(); + if (!hasIndex(index.row(), index.column())) + return QModelIndex(); + auto section = m_orientation == Qt::Vertical ? index.row() : index.column(); + return m_model->headerData(section, m_orientation, role); +} + +bool QHeaderDataProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!hasIndex(index.row(), index.column())) + return false; + auto section = m_orientation == Qt::Vertical ? index.row() : index.column(); + auto ret = m_model->setHeaderData(section, m_orientation, value, role); + emit dataChanged(index, index, { role }); + return ret; +} + +bool QHeaderDataProxyModel::hasChildren(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return false; +} + +QVariant QHeaderDataProxyModel::variantValue() const +{ + return QVariant::fromValue(static_cast<QObject *>(const_cast<QHeaderDataProxyModel *>(this))); +} + +void QHeaderDataProxyModel::setOrientation(Qt::Orientation o) +{ + if (o == m_orientation) + return; + beginResetModel(); + m_orientation = o; + endResetModel(); +} + +Qt::Orientation QHeaderDataProxyModel::orientation() const +{ + return m_orientation; +} + +QPointer<QAbstractItemModel> QHeaderDataProxyModel::sourceModel() const +{ + return m_model; +} + +void QHeaderDataProxyModel::connectToModel() +{ + if (m_model.isNull()) + return; + connect(m_model, &QAbstractItemModel::headerDataChanged, + [this](Qt::Orientation orient, int first, int last) { + if (orient != orientation()) + return; + if (orient == Qt::Horizontal) { + emit dataChanged(createIndex(0, first), createIndex(0, last)); + } else { + emit dataChanged(createIndex(first, 0), createIndex(last, 0)); + } + }); + connect(m_model, &QAbstractItemModel::modelAboutToBeReset, + this, &QHeaderDataProxyModel::modelAboutToBeReset, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::modelReset, + this, &QHeaderDataProxyModel::modelReset, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeMoved, + this, &QHeaderDataProxyModel::rowsAboutToBeMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsMoved, + this, &QHeaderDataProxyModel::rowsMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, + this, &QHeaderDataProxyModel::rowsAboutToBeInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsInserted, + this, &QHeaderDataProxyModel::rowsInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &QHeaderDataProxyModel::rowsAboutToBeRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsRemoved, + this, &QHeaderDataProxyModel::rowsRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeMoved, + this, &QHeaderDataProxyModel::columnsAboutToBeMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsMoved, + this, &QHeaderDataProxyModel::columnsMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeInserted, + this, &QHeaderDataProxyModel::columnsAboutToBeInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsInserted, + this, &QHeaderDataProxyModel::columnsInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeRemoved, + this, &QHeaderDataProxyModel::columnsAboutToBeRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsRemoved, + this, &QHeaderDataProxyModel::columnsRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::layoutAboutToBeChanged, + this, &QHeaderDataProxyModel::layoutAboutToBeChanged, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::layoutChanged, + this, &QHeaderDataProxyModel::layoutChanged, Qt::UniqueConnection); +} + +void QHeaderDataProxyModel::disconnectFromModel() +{ + if (m_model.isNull()) + return; + m_model->disconnect(this); +} + +QQuickHorizontalHeaderView::QQuickHorizontalHeaderView(QQuickItem *parent) + : QQuickHeaderViewBase(Qt::Horizontal, parent) +{ + setFlickableDirection(FlickableDirection::HorizontalFlick); +} + +QQuickHorizontalHeaderView::~QQuickHorizontalHeaderView() +{ +} + +QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickItem *parent) + : QQuickHeaderViewBase(Qt::Vertical, parent) +{ + setFlickableDirection(FlickableDirection::VerticalFlick); +} + +QQuickVerticalHeaderView::~QQuickVerticalHeaderView() +{ +} + +QQuickHorizontalHeaderViewPrivate::QQuickHorizontalHeaderViewPrivate() = default; + +QQuickHorizontalHeaderViewPrivate::~QQuickHorizontalHeaderViewPrivate() = default; + +QQuickVerticalHeaderViewPrivate::QQuickVerticalHeaderViewPrivate() = default; + +QQuickVerticalHeaderViewPrivate::~QQuickVerticalHeaderViewPrivate() = default; + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickheaderview_p.h b/src/quicktemplates2/qquickheaderview_p.h new file mode 100644 index 00000000..10c55c6e --- /dev/null +++ b/src/quicktemplates2/qquickheaderview_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKHEADERVIEW_P_H +#define QQUICKHEADERVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qquicktableview_p.h> +#include <private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickHeaderViewBase; +class QQuickHeaderViewBasePrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHeaderViewBase : public QQuickTableView +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickHeaderViewBase) + Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL) + +public: + explicit QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent = nullptr); + ~QQuickHeaderViewBase(); + + QString textRole() const; + void setTextRole(const QString &role); + +protected: + QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent); + +Q_SIGNALS: + void textRoleChanged(); + +private: + Q_DISABLE_COPY(QQuickHeaderViewBase) + friend class QQuickHorizontalHeaderView; + friend class QQuickVerticalHeaderView; +}; + +class QQuickHorizontalHeaderViewPrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHorizontalHeaderView : public QQuickHeaderViewBase +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickHorizontalHeaderView) + +public: + QQuickHorizontalHeaderView(QQuickItem *parent = nullptr); + ~QQuickHorizontalHeaderView() override; + +protected: + QQuickHorizontalHeaderView(QQuickHorizontalHeaderViewPrivate &dd, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickHorizontalHeaderView) +}; + +class QQuickVerticalHeaderViewPrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickVerticalHeaderView : public QQuickHeaderViewBase +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickVerticalHeaderView) + +public: + QQuickVerticalHeaderView(QQuickItem *parent = nullptr); + ~QQuickVerticalHeaderView() override; + +protected: + QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickVerticalHeaderView) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickHorizontalHeaderView) +QML_DECLARE_TYPE(QQuickVerticalHeaderView) + +#endif // QQUICKHEADERVIEW_P_H diff --git a/src/quicktemplates2/qquickheaderview_p_p.h b/src/quicktemplates2/qquickheaderview_p_p.h new file mode 100644 index 00000000..961c554b --- /dev/null +++ b/src/quicktemplates2/qquickheaderview_p_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKHEADERVIEW_P_P_H +#define QQUICKHEADERVIEW_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QAbstractItemModel> +#include <QtCore/QPointer> +#include <QtCore/QTransposeProxyModel> +#include <QtQuick/private/qquicktableview_p_p.h> +#include <private/qquickheaderview_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QHeaderDataProxyModel : public QAbstractItemModel +{ + Q_OBJECT + Q_DISABLE_COPY(QHeaderDataProxyModel) + Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel) +public: + explicit QHeaderDataProxyModel(QObject *parent = nullptr); + ~QHeaderDataProxyModel(); + + void setSourceModel(QAbstractItemModel *newSourceModel); + QPointer<QAbstractItemModel> sourceModel() const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + QModelIndex sibling(int row, int column, const QModelIndex &idx) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + + inline QVariant variantValue() const; + inline Qt::Orientation orientation() const; + inline void setOrientation(Qt::Orientation o); + +private: + inline void connectToModel(); + inline void disconnectFromModel(); + QPointer<QAbstractItemModel> m_model = nullptr; + Qt::Orientation m_orientation = Qt::Horizontal; +}; + +class QQuickHeaderViewBasePrivate : public QQuickTableViewPrivate +{ + Q_DECLARE_PUBLIC(QQuickHeaderViewBase) +public: + QQuickHeaderViewBasePrivate(); + ~QQuickHeaderViewBasePrivate(); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + const QPointer<QQuickItem> delegateItemAt(int row, int col) const; + QVariant modelImpl() const override; + void setModelImpl(const QVariant &newModel) override; + void syncModel() override; + void syncSyncView() override; + +protected: + QHeaderDataProxyModel m_headerDataProxyModel; + QTransposeProxyModel m_transposeProxyModel; + struct SectionSize + { + int section; + qreal previousSize; + }; + QStack<SectionSize> m_hiddenSectionSizes; + bool m_modelExplicitlySetByUser = false; + QString m_textRole = QStringLiteral("display"); +}; + +class QQuickHorizontalHeaderViewPrivate : public QQuickHeaderViewBasePrivate +{ + Q_DECLARE_PUBLIC(QQuickHorizontalHeaderView) +public: + QQuickHorizontalHeaderViewPrivate(); + ~QQuickHorizontalHeaderViewPrivate(); +}; + +class QQuickVerticalHeaderViewPrivate : public QQuickHeaderViewBasePrivate +{ + Q_DECLARE_PUBLIC(QQuickVerticalHeaderView) +public: + QQuickVerticalHeaderViewPrivate(); + ~QQuickVerticalHeaderViewPrivate(); +}; + +QT_END_NAMESPACE + +#endif // QQUICKHEADERVIEW_P_P_H diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index 9937436c..71b60a2b 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -405,7 +405,7 @@ void QQuickLabel::setBackground(QQuickItem *background) } QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); - delete d->background; + QQuickControlPrivate::hideOldItem(d->background); d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp index 0fbfb90b..ec1ea621 100644 --- a/src/quicktemplates2/qquickmenuitem.cpp +++ b/src/quicktemplates2/qquickmenuitem.cpp @@ -216,7 +216,7 @@ void QQuickMenuItem::setArrow(QQuickItem *arrow) if (!d->arrow.isExecuting()) d->cancelArrow(); - delete d->arrow; + QQuickControlPrivate::hideOldItem(d->arrow); d->arrow = arrow; if (arrow && !arrow->parentItem()) arrow->setParentItem(this); diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index ea72072b..e9f8801d 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -34,10 +34,12 @@ ** ****************************************************************************/ +#include "qquickcontrol_p_p.h" #include "qquickoverlay_p.h" #include "qquickoverlay_p_p.h" #include "qquickpopupitem_p_p.h" #include "qquickpopup_p_p.h" +#include "qquickdrawer_p.h" #include "qquickdrawer_p_p.h" #include "qquickapplicationwindow_p.h" #include <QtQml/qqmlinfo.h> @@ -255,7 +257,7 @@ void QQuickOverlayPrivate::removePopup(QQuickPopup *popup) { Q_Q(QQuickOverlay); allPopups.removeOne(popup); - if (allDrawers.removeOne(static_cast<QQuickDrawer *>(popup))) + if (allDrawers.removeOne(qobject_cast<QQuickDrawer *>(popup))) q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty()); } @@ -341,7 +343,6 @@ void QQuickOverlay::setModal(QQmlComponent *modal) if (d->modal == modal) return; - delete d->modal; d->modal = modal; emit modalChanged(); } @@ -358,7 +359,6 @@ void QQuickOverlay::setModeless(QQmlComponent *modeless) if (d->modeless == modeless) return; - delete d->modeless; d->modeless = modeless; emit modelessChanged(); } @@ -670,7 +670,6 @@ void QQuickOverlayAttached::setModal(QQmlComponent *modal) if (d->modal == modal) return; - delete d->modal; d->modal = modal; emit modalChanged(); } @@ -703,7 +702,6 @@ void QQuickOverlayAttached::setModeless(QQmlComponent *modeless) if (d->modeless == modeless) return; - delete d->modeless; d->modeless = modeless; emit modelessChanged(); } diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index ecb2568e..7a7e00b1 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -1843,6 +1843,8 @@ void QQuickPopup::setModal(bool modal) d->toggleOverlay(); emit modalChanged(); + QQuickItemPrivate::get(d->popupItem)->isTabFence = modal; + if (!d->hasDim) { setDim(modal); d->hasDim = false; diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index fcf23db5..8e169b0b 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -42,7 +42,9 @@ #include "qquickpopup_p_p.h" #include "qquickdeferredexecute_p_p.h" -#include <QtGui/private/qshortcutmap_p.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif #include <QtGui/private/qguiapplication_p.h> #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index bd53963d..9ad12102 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -267,7 +267,7 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) const qreal oldImplicitHandleHeight = implicitHandleHeight(); QQuickControlPrivate::get(d->slider)->removeImplicitSizeListener(d->handle); - delete d->handle; + QQuickControlPrivate::hideOldItem(d->handle); d->handle = handle; if (handle) { diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index 1fb674b6..f4a459fa 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -579,7 +579,7 @@ void QQuickSlider::setHandle(QQuickItem *handle) const qreal oldImplicitHandleHeight = implicitHandleHeight(); d->removeImplicitSizeListener(d->handle); - delete d->handle; + QQuickControlPrivate::hideOldItem(d->handle); d->handle = handle; if (handle) { diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 8b81e4e5..3482af8c 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -1126,7 +1126,7 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator) QQuickSpinBox *spinBox = static_cast<QQuickSpinBox *>(parent()); QQuickSpinBoxPrivate::get(spinBox)->removeImplicitSizeListener(d->indicator); - delete d->indicator; + QQuickControlPrivate::hideOldItem(d->indicator); d->indicator = indicator; if (indicator) { diff --git a/src/quicktemplates2/qquickstackelement.cpp b/src/quicktemplates2/qquickstackelement.cpp index 7ae5c495..4c14022a 100644 --- a/src/quicktemplates2/qquickstackelement.cpp +++ b/src/quicktemplates2/qquickstackelement.cpp @@ -44,6 +44,7 @@ #include <QtQml/private/qv4qobjectwrapper_p.h> #include <QtQml/private/qqmlcomponent_p.h> #include <QtQml/private/qqmlengine_p.h> +#include <QtQml/private/qqmlapiversion_p.h> QT_BEGIN_NAMESPACE @@ -210,7 +211,12 @@ void QQuickStackElement::initialize() QV4::ScopedValue ipv(scope, properties.value()); QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item)); +#if Q_QML_PRIVATE_API_VERSION >= 6 + RequiredProperties requiredPropertiesCurrentlyNotSupported; + QQmlComponentPrivate::setInitialProperties(v4, qmlContext, qmlObject, ipv, requiredPropertiesCurrentlyNotSupported, item); +#else QQmlComponentPrivate::setInitialProperties(v4, qmlContext, qmlObject, ipv); +#endif properties.clear(); } diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 75dfba4e..56dc946d 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -634,7 +634,7 @@ void QQuickTextArea::setBackground(QQuickItem *background) } QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); - delete d->background; + QQuickControlPrivate::hideOldItem(d->background); d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 025139f8..8fa04bd3 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -503,7 +503,7 @@ void QQuickTextField::setBackground(QQuickItem *background) } QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); - delete d->background; + QQuickControlPrivate::hideOldItem(d->background); d->background = background; if (background) { diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index c145c20f..fa6929f9 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -31,6 +31,8 @@ HEADERS += \ $$PWD/qquickframe_p.h \ $$PWD/qquickframe_p_p.h \ $$PWD/qquickgroupbox_p.h \ + $$PWD/qquickheaderview_p.h \ + $$PWD/qquickheaderview_p_p.h \ $$PWD/qquickicon_p.h \ $$PWD/qquickitemdelegate_p.h \ $$PWD/qquickitemdelegate_p_p.h \ @@ -120,6 +122,7 @@ SOURCES += \ $$PWD/qquickdrawer.cpp \ $$PWD/qquickframe.cpp \ $$PWD/qquickgroupbox.cpp \ + $$PWD/qquickheaderview.cpp \ $$PWD/qquickicon.cpp \ $$PWD/qquickitemdelegate.cpp \ $$PWD/qquicklabel.cpp \ |