Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsqlrelationaldelegate.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QSQLRELATIONALDELEGATE_H
6#define QSQLRELATIONALDELEGATE_H
7
8#include <QtSql/qtsqlglobal.h>
9
11
12#ifdef QT_WIDGETS_LIB
13
14#include <QtWidgets/qstyleditemdelegate.h>
15#if QT_CONFIG(listview)
16#include <QtWidgets/qlistview.h>
17#endif
18#if QT_CONFIG(combobox)
19#include <QtWidgets/qcombobox.h>
20#endif
21#include <QtSql/qsqldriver.h>
22#include <QtSql/qsqlrelationaltablemodel.h>
23#include <QtCore/qmetaobject.h>
24QT_BEGIN_NAMESPACE
25
26class QSqlRelationalDelegate : public QStyledItemDelegate
27{
28 static int fieldIndex(const QSqlTableModel *const model,
29 const QSqlDriver *const driver,
30 const QString &fieldName)
31 {
32 const QString stripped = driver->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)
33 ? driver->stripDelimiters(fieldName, QSqlDriver::FieldName)
34 : fieldName;
35 return model->fieldIndex(stripped);
36 }
37
38public:
39
40 explicit QSqlRelationalDelegate(QObject *aParent = nullptr)
41 : QStyledItemDelegate(aParent)
42 {}
43
44 ~QSqlRelationalDelegate()
45 {}
46
47 QWidget *createEditor(QWidget *aParent,
48 const QStyleOptionViewItem &option,
49 const QModelIndex &index) const override
50 {
51 const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel *>(index.model());
52 QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : nullptr;
53 if (!childModel)
54 return QStyledItemDelegate::createEditor(aParent, option, index);
55 const QSqlDriver *const driver = childModel->database().driver();
56
57 QComboBox *combo = new QComboBox(aParent);
58 combo->setModel(childModel);
59 combo->setModelColumn(fieldIndex(childModel, driver,
60 sqlModel->relation(index.column()).displayColumn()));
61 combo->installEventFilter(const_cast<QSqlRelationalDelegate *>(this));
62
63 return combo;
64 }
65
66 void setEditorData(QWidget *editor, const QModelIndex &index) const override
67 {
68 if (!index.isValid())
69 return;
70
71 if (qobject_cast<QComboBox *>(editor)) {
72 // Taken from QItemDelegate::setEditorData() as we need
73 // to present the DisplayRole and not the EditRole which
74 // is the id reference to the related model
75 QVariant v = index.data(Qt::DisplayRole);
76 const QByteArray n = editor->metaObject()->userProperty().name();
77 if (!n.isEmpty()) {
78 if (!v.isValid())
79 v = QVariant(editor->property(n.data()).metaType());
80 editor->setProperty(n.data(), v);
81 return;
82 }
83 }
84 QStyledItemDelegate::setEditorData(editor, index);
85 }
86
87void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
88{
89 if (!index.isValid())
90 return;
91
92 QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);
93 QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : nullptr;
94 QComboBox *combo = qobject_cast<QComboBox *>(editor);
95 if (!sqlModel || !childModel || !combo) {
96 QStyledItemDelegate::setModelData(editor, model, index);
97 return;
98 }
99 const QSqlDriver *const driver = childModel->database().driver();
100
101 int currentItem = combo->currentIndex();
102 int childColIndex = fieldIndex(childModel, driver,
103 sqlModel->relation(index.column()).displayColumn());
104 int childEditIndex = fieldIndex(childModel, driver,
105 sqlModel->relation(index.column()).indexColumn());
106 sqlModel->setData(index,
107 childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole),
108 Qt::DisplayRole);
109 sqlModel->setData(index,
110 childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole),
111 Qt::EditRole);
112}
113
114};
115
116QT_END_NAMESPACE
117
118#endif // QT_WIDGETS_LIB
119
120#endif // QSQLRELATIONALDELEGATE_H
QT_REQUIRE_CONFIG(sqlmodel)