diff options
Diffstat (limited to 'src/quick/items/qquicktableview.cpp')
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 118 |
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 |