diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2014-09-17 18:08:51 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2014-10-31 14:06:25 +0100 |
commit | ee17adebd23528e541e76d1f422b6ce498ab83bb (patch) | |
tree | feed18525f98fd05fd186a5a91b1b09df3ed58b8 | |
parent | 0678d7c43c1658d2d2ec984be5844054031649a2 (diff) |
Implement QTableWidget/QListWidget::mimeData()
For some reasons lost in history, those methods simply ignore
the list of items passed to them, and always return NULL.
Of course, that's totally broken. Fix that by doing the same thing
that the respective (hidden) models did when calling mimeData().
Surprisingly enough, QTreeWidget has a proper implementation.
Task-number: QTBUG-25900
Change-Id: I99ca7b4d4f87f096fd9ff0b0cb4e58282aa9c26e
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r-- | src/widgets/itemviews/qlistwidget.cpp | 19 | ||||
-rw-r--r-- | src/widgets/itemviews/qlistwidget_p.h | 2 | ||||
-rw-r--r-- | src/widgets/itemviews/qtablewidget.cpp | 19 | ||||
-rw-r--r-- | src/widgets/itemviews/qtablewidget_p.h | 2 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp | 55 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp | 68 |
6 files changed, 160 insertions, 5 deletions
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 51561ac23b..aae75e5651 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1783,9 +1783,24 @@ QStringList QListWidget::mimeTypes() const If the list of items is empty, 0 is returned instead of a serialized empty list. */ -QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*>) const +QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*> items) const { - return d_func()->listModel()->internalMimeData(); + Q_D(const QListWidget); + + QModelIndexList &cachedIndexes = d->listModel()->cachedIndexes; + + // if non empty, it's called from the model's own mimeData + if (cachedIndexes.isEmpty()) { + foreach (QListWidgetItem *item, items) + cachedIndexes << indexFromItem(item); + + QMimeData *result = d->listModel()->internalMimeData(); + + cachedIndexes.clear(); + return result; + } + + return d->listModel()->internalMimeData(); } #ifndef QT_NO_DRAGANDDROP diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h index b019cd5eaf..1f2e9e8819 100644 --- a/src/widgets/itemviews/qlistwidget_p.h +++ b/src/widgets/itemviews/qlistwidget_p.h @@ -72,6 +72,8 @@ public: class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel { Q_OBJECT + friend class QListWidget; + public: QListModel(QListWidget *parent); ~QListModel(); diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 7c24819c0e..eb239f8025 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -2553,9 +2553,24 @@ QStringList QTableWidget::mimeTypes() const If the list of items is empty, 0 is returned rather than a serialized empty list. */ -QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*>) const +QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*> items) const { - return d_func()->tableModel()->internalMimeData(); + Q_D(const QTableWidget); + + QModelIndexList &cachedIndexes = d->tableModel()->cachedIndexes; + + // if non empty, it's called from the model's own mimeData + if (cachedIndexes.isEmpty()) { + foreach (QTableWidgetItem *item, items) + cachedIndexes << indexFromItem(item); + + QMimeData *result = d->tableModel()->internalMimeData(); + + cachedIndexes.clear(); + return result; + } + + return d->tableModel()->internalMimeData(); } /*! diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h index 50b5a66eb5..92a8f5f305 100644 --- a/src/widgets/itemviews/qtablewidget_p.h +++ b/src/widgets/itemviews/qtablewidget_p.h @@ -82,6 +82,8 @@ public: class QTableModel : public QAbstractTableModel { Q_OBJECT + friend class QTableWidget; + public: enum ItemFlagsExtension { ItemIsHeaderItem = 128 diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index 6428bbba10..428b2f0c42 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -123,7 +123,7 @@ private slots: void task258949_keypressHangup(); void QTBUG8086_currentItemChangedOnClick(); void QTBUG14363_completerWithAnyKeyPressedEditTriggers(); - + void mimeData(); protected slots: void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last) @@ -1082,6 +1082,9 @@ public: Q_UNUSED(item); return QListWidget::state() == QListWidget::EditingState; } + + using QListWidget::mimeData; + using QListWidget::indexFromItem; }; void tst_QListWidget::closeEditor() @@ -1662,7 +1665,57 @@ void tst_QListWidget::QTBUG14363_completerWithAnyKeyPressedEditTriggers() QCOMPARE(le->completer()->currentCompletion(), QString("completer")); } +void tst_QListWidget::mimeData() +{ + TestListWidget list; + + for (int x = 0; x < 10; ++x) { + QListWidgetItem *item = new QListWidgetItem(QStringLiteral("123")); + list.addItem(item); + } + + QList<QListWidgetItem *> tableWidgetItemList; + QModelIndexList modelIndexList; + + // do these checks more than once to ensure that the "cached indexes" work as expected + QVERIFY(!list.mimeData(tableWidgetItemList)); + QVERIFY(!list.model()->mimeData(modelIndexList)); + QVERIFY(!list.model()->mimeData(modelIndexList)); + QVERIFY(!list.mimeData(tableWidgetItemList)); + + tableWidgetItemList << list.item(1); + modelIndexList << list.indexFromItem(list.item(1)); + + QMimeData *data; + + QVERIFY(data = list.mimeData(tableWidgetItemList)); + delete data; + QVERIFY(data = list.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = list.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = list.mimeData(tableWidgetItemList)); + delete data; + + // check the saved data is actually the same + + QMimeData *data2; + + data = list.mimeData(tableWidgetItemList); + data2 = list.model()->mimeData(modelIndexList); + + const QString format = QStringLiteral("application/x-qabstractitemmodeldatalist"); + + QVERIFY(data->hasFormat(format)); + QVERIFY(data2->hasFormat(format)); + QVERIFY(data->data(format) == data2->data(format)); + + delete data; + delete data2; +} QTEST_MAIN(tst_QListWidget) #include "tst_qlistwidget.moc" diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 8335497c6c..de88e832aa 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -93,6 +93,7 @@ private slots: void task219380_removeLastRow(); void task262056_sortDuplicate(); void itemWithHeaderItems(); + void mimeData(); private: QTableWidget *testWidget; @@ -1497,5 +1498,72 @@ void tst_QTableWidget::itemWithHeaderItems() QCOMPARE(table.item(0, 1), static_cast<QTableWidgetItem *>(0)); } +class TestTableWidget : public QTableWidget +{ + Q_OBJECT +public: + TestTableWidget(int rows, int columns, QWidget *parent = 0) + : QTableWidget(rows, columns, parent) + { + } + + using QTableWidget::mimeData; + using QTableWidget::indexFromItem; +}; + +void tst_QTableWidget::mimeData() +{ + TestTableWidget table(10, 10); + + for (int x = 0; x < 10; ++x) { + for (int y = 0; y < 10; ++y) { + QTableWidgetItem *item = new QTableWidgetItem(QStringLiteral("123")); + table.setItem(y, x, item); + } + } + + QList<QTableWidgetItem *> tableWidgetItemList; + QModelIndexList modelIndexList; + + // do these checks more than once to ensure that the "cached indexes" work as expected + QVERIFY(!table.mimeData(tableWidgetItemList)); + QVERIFY(!table.model()->mimeData(modelIndexList)); + QVERIFY(!table.model()->mimeData(modelIndexList)); + QVERIFY(!table.mimeData(tableWidgetItemList)); + + tableWidgetItemList << table.item(1, 1); + modelIndexList << table.indexFromItem(table.item(1, 1)); + + QMimeData *data; + + QVERIFY(data = table.mimeData(tableWidgetItemList)); + delete data; + + QVERIFY(data = table.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = table.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = table.mimeData(tableWidgetItemList)); + delete data; + + // check the saved data is actually the same + + QMimeData *data2; + + data = table.mimeData(tableWidgetItemList); + data2 = table.model()->mimeData(modelIndexList); + + const QString format = QStringLiteral("application/x-qabstractitemmodeldatalist"); + + QVERIFY(data->hasFormat(format)); + QVERIFY(data2->hasFormat(format)); + QVERIFY(data->data(format) == data2->data(format)); + + delete data; + delete data2; +} + QTEST_MAIN(tst_QTableWidget) #include "tst_qtablewidget.moc" |