aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquicktableview.cpp')
-rw-r--r--src/quick/items/qquicktableview.cpp118
1 files changed, 68 insertions, 50 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 4105996b31..c7882fb2b1 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -82,7 +82,7 @@
The following example shows how to create a model from C++ with multiple
columns:
- \snippet qml/tableview/cpp-tablemodel.cpp 0
+ \snippet qml/tableview/cpp-tablemodel.h 0
And then how to use it from QML:
@@ -193,8 +193,10 @@
\qmlproperty int QtQuick::TableView::rows
\readonly
- This property holds the number of rows in the table. This is
- equal to the number of rows in the model.
+ This property holds the number of rows in the table.
+
+ \note \a rows is usually equal to the number of rows in the model, but can
+ temporarily differ until all pending model changes have been processed.
This property is read only.
*/
@@ -203,9 +205,12 @@
\qmlproperty int QtQuick::TableView::columns
\readonly
- This property holds the number of columns in the table. This is
- equal to the number of columns in the model. If the model is
- a list, columns will be \c 1.
+ This property holds the number of rows in the table.
+
+ \note \a columns is usually equal to the number of columns in the model, but
+ can temporarily differ until all pending model changes have been processed.
+
+ If the model is a list, columns will be \c 1.
This property is read only.
*/
@@ -457,6 +462,8 @@ QQuickTableViewPrivate::~QQuickTableViewPrivate()
QString QQuickTableViewPrivate::tableLayoutToString() const
{
+ if (loadedItems.isEmpty())
+ return QLatin1String("table is empty!");
return QString(QLatin1String("table cells: (%1,%2) -> (%3,%4), item count: %5, table rect: %6,%7 x %8,%9"))
.arg(leftColumn()).arg(topRow())
.arg(rightColumn()).arg(bottomRow())
@@ -493,20 +500,34 @@ QQuickTableViewAttached *QQuickTableViewPrivate::getAttachedObject(const QObject
int QQuickTableViewPrivate::modelIndexAtCell(const QPoint &cell) const
{
- int availableRows = tableSize.height();
- int modelIndex = cell.y() + (cell.x() * availableRows);
- Q_TABLEVIEW_ASSERT(modelIndex < model->count(),
- "modelIndex:" << modelIndex << "cell:" << cell << "count:" << model->count());
- return modelIndex;
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ return (cell.y() * availableColumns) + cell.x();
+ } else {
+ int availableRows = tableSize.height();
+ return (cell.x() * availableRows) + cell.y();
+ }
}
QPoint QQuickTableViewPrivate::cellAtModelIndex(int modelIndex) const
{
- int availableRows = tableSize.height();
- Q_TABLEVIEW_ASSERT(availableRows > 0, availableRows);
- int column = int(modelIndex / availableRows);
- int row = modelIndex % availableRows;
- return QPoint(column, row);
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ int row = int(modelIndex / availableColumns);
+ int column = modelIndex % availableColumns;
+ return QPoint(column, row);
+ } else {
+ int availableRows = tableSize.height();
+ int column = int(modelIndex / availableRows);
+ int row = modelIndex % availableRows;
+ return QPoint(column, row);
+ }
}
int QQuickTableViewPrivate::edgeToArrayIndex(Qt::Edge edge)
@@ -1083,15 +1104,8 @@ void QQuickTableViewPrivate::releaseItem(FxTableItem *fxTableItem, QQmlTableInst
Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
delete item;
} else if (item) {
- // Only QQmlTableInstanceModel supports reusing items
- auto releaseFlag = tableModel ?
- tableModel->release(item, reusableFlag) :
- model->release(item);
-
- if (releaseFlag != QQmlInstanceModel::Destroyed) {
- // When items are not destroyed, it typically means that the
- // item is reused, or that the model is an ObjectModel. If
- // so, we just hide the item instead.
+ auto releaseFlag = model->release(item, reusableFlag);
+ if (releaseFlag == QQmlInstanceModel::Pooled) {
fxTableItem->setVisible(false);
// If the item (or a descendant) has focus, remove it, so
@@ -1241,12 +1255,13 @@ void QQuickTableViewPrivate::updateTableSize()
QSize QQuickTableViewPrivate::calculateTableSize()
{
+ QSize size(0, 0);
if (tableModel)
- return QSize(tableModel->columns(), tableModel->rows());
+ size = QSize(tableModel->columns(), tableModel->rows());
else if (model)
- return QSize(1, model->count());
+ size = QSize(1, model->count());
- return QSize(0, 0);
+ return isTransposed ? size.transposed() : size;
}
qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
@@ -2257,6 +2272,21 @@ void QQuickTableViewPrivate::syncDelegate()
tableModel->setDelegate(assignedDelegate);
}
+QVariant QQuickTableViewPrivate::modelImpl() const
+{
+ return assignedModel;
+}
+
+void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel)
+{
+ if (newModel == assignedModel)
+ return;
+
+ assignedModel = newModel;
+ scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
+ emit q_func()->modelChanged();
+}
+
void QQuickTableViewPrivate::syncModel()
{
if (modelVariant == assignedModel)
@@ -2350,14 +2380,11 @@ void QQuickTableViewPrivate::connectToModel()
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::connect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- // Connect atYEndChanged to a function that fetches data if more is available
- QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
// When the model exposes a QAIM, we connect to it directly. This means that if the current model is
@@ -2385,13 +2412,10 @@ void QQuickTableViewPrivate::disconnectFromModel()
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::disconnect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
disconnect(aim, &QAbstractItemModel::rowsMoved, this, &QQuickTableViewPrivate::rowsMovedCallback);
@@ -2678,18 +2702,12 @@ void QQuickTableView::setColumnWidthProvider(const QJSValue &provider)
QVariant QQuickTableView::model() const
{
- return d_func()->assignedModel;
+ return d_func()->modelImpl();
}
void QQuickTableView::setModel(const QVariant &newModel)
{
- Q_D(QQuickTableView);
- if (newModel == d->assignedModel)
- return;
-
- d->assignedModel = newModel;
- d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
- emit modelChanged();
+ return d_func()->setModelImpl(newModel);
}
QQmlComponent *QQuickTableView::delegate() const