Show the display role inside the editor for the relation in a QComboBox
When a QComboBox is used as the editor for a relation inside a view then it could end up showing the contents of the EditRole. This would be the field which is used to represent the entry as opposed to the DisplayRole which is what the user would expect to see is. Therefore, setEditorData() is overridden to ensure that it is showing the right data to the user. When the model gets updated, it will take the corresponding EditRole value as before to ensure it is updated correctly. Task-number: QTBUG-59632 Change-Id: Ibbccc3e9477de1cdefb654051b97dd111df36382 Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
This commit is contained in:
parent
84b39d6ad5
commit
b92db8a4ad
@ -55,7 +55,7 @@ QT_REQUIRE_CONFIG(sqlmodel);
|
||||
#endif
|
||||
#include <QtSql/qsqldriver.h>
|
||||
#include <QtSql/qsqlrelationaltablemodel.h>
|
||||
|
||||
#include <QtCore/qmetaobject.h>
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
@ -99,6 +99,27 @@ QWidget *createEditor(QWidget *aParent,
|
||||
return combo;
|
||||
}
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (qobject_cast<QComboBox *>(editor)) {
|
||||
// Taken from QItemDelegate::setEditorData() as we need
|
||||
// to present the DisplayRole and not the EditRole which
|
||||
// is the id reference to the related model
|
||||
QVariant v = index.data(Qt::DisplayRole);
|
||||
QByteArray n = editor->metaObject()->userProperty().name();
|
||||
if (!n.isEmpty()) {
|
||||
if (!v.isValid())
|
||||
v = QVariant(editor->property(n).userType(), nullptr);
|
||||
editor->setProperty(n, v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
@ -0,0 +1,5 @@
|
||||
CONFIG += testcase
|
||||
TARGET = tst_qsqlrelationaldelegate
|
||||
SOURCES += tst_qsqlrelationaldelegate.cpp
|
||||
|
||||
QT = core sql testlib core-private sql-private widgets
|
@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** 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-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtSql/QtSql>
|
||||
#include <QTableView>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "../../kernel/qsqldatabase/tst_databases.h"
|
||||
|
||||
const QString reltest1(qTableName("reltest1", __FILE__, QSqlDatabase())),
|
||||
reltest2(qTableName("reltest2", __FILE__, QSqlDatabase()));
|
||||
|
||||
class tst_QSqlRelationalDelegate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void recreateTestTables(QSqlDatabase);
|
||||
|
||||
tst_Databases dbs;
|
||||
|
||||
public slots:
|
||||
void initTestCase_data();
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void comboBoxEditor();
|
||||
private:
|
||||
void dropTestTables(QSqlDatabase db);
|
||||
};
|
||||
|
||||
|
||||
void tst_QSqlRelationalDelegate::initTestCase_data()
|
||||
{
|
||||
QVERIFY(dbs.open());
|
||||
if (dbs.fillTestTable() == 0)
|
||||
QSKIP("No database drivers are available in this Qt configuration");
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::recreateTestTables(QSqlDatabase db)
|
||||
{
|
||||
dropTestTables(db);
|
||||
|
||||
QSqlQuery q(db);
|
||||
QVERIFY_SQL(q, exec("create table " + reltest1 +
|
||||
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(1, 'harry', 1, 2)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(2, 'trond', 2, 1)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(3, 'vohi', 1, 2)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(4, 'boris', 2, 2)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)"));
|
||||
|
||||
QVERIFY_SQL(q, exec("create table " + reltest2 + " (id int not null primary key, title varchar(20))"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(1, 'herr')"));
|
||||
QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(2, 'mister')"));
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::initTestCase()
|
||||
{
|
||||
foreach (const QString &dbname, dbs.dbNames) {
|
||||
QSqlDatabase db=QSqlDatabase::database(dbname);
|
||||
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::Interbase) {
|
||||
db.exec("SET DIALECT 3");
|
||||
} else if (dbType == QSqlDriver::MSSqlServer) {
|
||||
db.exec("SET ANSI_DEFAULTS ON");
|
||||
db.exec("SET IMPLICIT_TRANSACTIONS OFF");
|
||||
} else if (dbType == QSqlDriver::PostgreSQL) {
|
||||
db.exec("set client_min_messages='warning'");
|
||||
}
|
||||
recreateTestTables(db);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::cleanupTestCase()
|
||||
{
|
||||
foreach (const QString &dbName, dbs.dbNames) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
dropTestTables(QSqlDatabase::database(dbName));
|
||||
}
|
||||
dbs.close();
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::dropTestTables(QSqlDatabase db)
|
||||
{
|
||||
QStringList tableNames = { reltest1, reltest2 };
|
||||
tst_Databases::safeDropTables(db, tableNames);
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::init()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QSqlRelationalDelegate::comboBoxEditor()
|
||||
{
|
||||
QFETCH_GLOBAL(QString, dbName);
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
QTableView tv;
|
||||
QSqlRelationalTableModel model(0, db);
|
||||
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
|
||||
model.setTable(reltest1);
|
||||
model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
|
||||
model.setRelation(3, QSqlRelation(reltest2, "id", "title"));
|
||||
tv.setModel(&model);
|
||||
QVERIFY_SQL(model, select());
|
||||
|
||||
QSqlRelationalDelegate delegate;
|
||||
tv.setItemDelegate(&delegate);
|
||||
tv.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&tv));
|
||||
|
||||
QModelIndex index = model.index(0, 2);
|
||||
tv.setCurrentIndex(index);
|
||||
tv.edit(index);
|
||||
QList<QComboBox*> comboBoxes = tv.viewport()->findChildren<QComboBox *>();
|
||||
QCOMPARE(comboBoxes.count(), 1);
|
||||
|
||||
QComboBox *editor = comboBoxes.at(0);
|
||||
QCOMPARE(editor->currentText(), "herr");
|
||||
QTest::keyClick(editor, Qt::Key_Down);
|
||||
QTest::keyClick(editor, Qt::Key_Enter);
|
||||
QCOMPARE(editor->currentText(), "mister");
|
||||
QVERIFY_SQL(model, submitAll());
|
||||
|
||||
QSqlQuery qry(db);
|
||||
QVERIFY_SQL(qry, exec("SELECT title_key FROM " + reltest1 + " WHERE id=1"));
|
||||
QVERIFY(qry.next());
|
||||
QCOMPARE(qry.value(0).toString(), "mister");
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSqlRelationalDelegate)
|
||||
#include "tst_qsqlrelationaldelegate.moc"
|
Loading…
Reference in New Issue
Block a user