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>
This commit is contained in:
Giuseppe D'Angelo 2014-09-17 18:08:51 +02:00
parent 0678d7c43c
commit ee17adebd2
6 changed files with 160 additions and 5 deletions

View File

@ -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

View File

@ -72,6 +72,8 @@ public:
class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
{
Q_OBJECT
friend class QListWidget;
public:
QListModel(QListWidget *parent);
~QListModel();

View File

@ -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();
}
/*!

View File

@ -82,6 +82,8 @@ public:
class QTableModel : public QAbstractTableModel
{
Q_OBJECT
friend class QTableWidget;
public:
enum ItemFlagsExtension {
ItemIsHeaderItem = 128

View File

@ -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"

View File

@ -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"