summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2018-05-15 15:05:29 +0200
committerAndy Shaw <andy.shaw@qt.io>2018-05-29 22:08:28 +0000
commitb92db8a4adf985fe842ec0693e17c81d9e816b93 (patch)
treee46337daac71a8fb549e629c327cd8be94cec34e
parent84b39d6ad551a701d7377716b8dd56e62d919ac9 (diff)
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>
-rw-r--r--src/sql/models/qsqlrelationaldelegate.h23
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro5
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp170
3 files changed, 197 insertions, 1 deletions
diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h
index 0af87f64ae..e8ae5a229d 100644
--- a/src/sql/models/qsqlrelationaldelegate.h
+++ b/src/sql/models/qsqlrelationaldelegate.h
@@ -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())
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro b/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro
new file mode 100644
index 0000000000..d911a46259
--- /dev/null
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qsqlrelationaldelegate
+SOURCES += tst_qsqlrelationaldelegate.cpp
+
+QT = core sql testlib core-private sql-private widgets
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
new file mode 100644
index 0000000000..36f592395e
--- /dev/null
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
@@ -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"