aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp7
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h1
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp8
-rw-r--r--src/quicktemplates2/qquickcombobox_p.h1
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp12
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h2
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp7
-rw-r--r--src/quicktemplates2/qquickheaderview.cpp500
-rw-r--r--src/quicktemplates2/qquickheaderview_p.h125
-rw-r--r--src/quicktemplates2/qquickheaderview_p_p.h136
-rw-r--r--src/quicktemplates2/qquicktooltip.cpp20
-rw-r--r--src/quicktemplates2/quicktemplates2.pri3
12 files changed, 814 insertions, 8 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 8ce4d0e5..8632e14c 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -178,7 +178,7 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
if (wasPressed) {
emit q->released();
- if (!wasHeld)
+ if (!wasHeld && !wasDoubleClick)
trigger();
} else {
emit q->canceled();
@@ -188,6 +188,8 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
stopPressRepeat();
else
stopPressAndHold();
+
+ wasDoubleClick = false;
}
void QQuickAbstractButtonPrivate::handleUngrab()
@@ -201,6 +203,7 @@ void QQuickAbstractButtonPrivate::handleUngrab()
q->setPressed(false);
stopPressRepeat();
stopPressAndHold();
+ wasDoubleClick = false;
emit q->canceled();
}
@@ -1080,8 +1083,10 @@ void QQuickAbstractButton::mousePressEvent(QMouseEvent *event)
void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event)
{
+ Q_D(QQuickAbstractButton);
QQuickControl::mouseDoubleClickEvent(event);
emit doubleClicked();
+ d->wasDoubleClick = true;
}
void QQuickAbstractButton::timerEvent(QTimerEvent *event)
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index 8ad479e2..9291c1a8 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -124,6 +124,7 @@ public:
bool autoExclusive = false;
bool autoRepeat = false;
bool wasHeld = false;
+ bool wasDoubleClick = false;
int holdTimer = 0;
int delayTimer = 0;
int repeatTimer = 0;
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 5f3f1cfc..d9bbd2bd 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -1865,6 +1865,14 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event)
}
#endif
+bool QQuickComboBox::event(QEvent *e)
+{
+ Q_D(QQuickComboBox);
+ if (e->type() == QEvent::LanguageChange)
+ d->updateCurrentText();
+ return QQuickControl::event(e);
+}
+
void QQuickComboBox::componentComplete()
{
Q_D(QQuickComboBox);
diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h
index b52d7545..282f3d23 100644
--- a/src/quicktemplates2/qquickcombobox_p.h
+++ b/src/quicktemplates2/qquickcombobox_p.h
@@ -227,6 +227,7 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *event) override;
#endif
+ bool event(QEvent *e) override;
void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 6b845ae6..4eb411c2 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -180,6 +180,12 @@ bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
return true;
}
+ // If the control is on a Flickable that has a pressDelay, then the press is never
+ // sent as a touch event, therefore we need to check for this case.
+ if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased &&
+ point.pos() == previousPressPos) {
+ return true;
+ }
return false;
}
#endif
@@ -215,6 +221,8 @@ void QQuickControlPrivate::handleRelease(const QPointF &)
if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
setActiveFocus(q, Qt::MouseFocusReason);
touchId = -1;
+ pressWasTouch = false;
+ previousPressPos = QPointF();
}
void QQuickControlPrivate::handleUngrab()
@@ -2121,6 +2129,10 @@ void QQuickControl::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickControl);
d->handlePress(event->localPos());
+ if (event->source() == Qt::MouseEventSynthesizedByQt) {
+ d->pressWasTouch = true;
+ d->previousPressPos = event->localPos();
+ }
event->accept();
}
diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h
index b649db0a..fa06c97f 100644
--- a/src/quicktemplates2/qquickcontrol_p_p.h
+++ b/src/quicktemplates2/qquickcontrol_p_p.h
@@ -230,7 +230,9 @@ public:
bool explicitHoverEnabled = false;
#endif
bool resizingBackground = false;
+ bool pressWasTouch = false;
int touchId = -1;
+ QPointF previousPressPos;
qreal padding = 0;
qreal horizontalPadding = 0;
qreal verticalPadding = 0;
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index 2c09cd11..f3dd2da1 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -455,8 +455,11 @@ void QQuickDialogButtonBoxPrivate::updateLanguage()
qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true));
const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached);
const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton;
- const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton);
- button->setText(QPlatformTheme::removeMnemonics(buttonText));
+ // The button might be a custom one with explicitly specified text, so we shouldn't change it in that case.
+ if (standardButton != QPlatformDialogHelper::NoButton) {
+ const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton);
+ button->setText(QPlatformTheme::removeMnemonics(buttonText));
+ }
}
--i;
}
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/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp
index 9ea0160e..8b61375e 100644
--- a/src/quicktemplates2/qquicktooltip.cpp
+++ b/src/quicktemplates2/qquicktooltip.cpp
@@ -252,9 +252,18 @@ void QQuickToolTip::setVisible(bool visible)
{
Q_D(QQuickToolTip);
if (visible) {
- if (!d->visible && d->delay > 0) {
- d->startDelay();
- return;
+ if (!d->visible) {
+ // We are being made visible, and we weren't before.
+ if (d->delay > 0) {
+ d->startDelay();
+ return;
+ }
+ } else {
+ // We are being made visible, even though we already were.
+ // We've probably been re-opened before our exit transition could finish.
+ // In that case, we need to manually start the timeout, as that is usually
+ // done in itemChange(), which won't be called in this situation.
+ d->startTimeout();
}
} else {
d->stopDelay();
@@ -557,8 +566,9 @@ void QQuickToolTipAttached::hide()
QQuickToolTip *tip = d->instance(false);
if (!tip)
return;
-
- tip->close();
+ // check the parent item to prevent unexpectedly closing tooltip by new created invisible tooltip
+ if (parent() == tip->parentItem())
+ tip->close();
}
QT_END_NAMESPACE
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 \