File indexing completed on 2026-09-18 09:26:38
0001
0002
0003
0004
0005 #ifndef QSQLRELATIONALDELEGATE_H
0006 #define QSQLRELATIONALDELEGATE_H
0007
0008 #include <QtSql/qtsqlglobal.h>
0009
0010 QT_REQUIRE_CONFIG(sqlmodel);
0011
0012 #ifdef QT_WIDGETS_LIB
0013
0014 #include <QtWidgets/qstyleditemdelegate.h>
0015 #if QT_CONFIG(listview)
0016 #include <QtWidgets/qlistview.h>
0017 #endif
0018 #if QT_CONFIG(combobox)
0019 #include <QtWidgets/qcombobox.h>
0020 #endif
0021 #include <QtSql/qsqldriver.h>
0022 #include <QtSql/qsqlrelationaltablemodel.h>
0023 #include <QtCore/qmetaobject.h>
0024 QT_BEGIN_NAMESPACE
0025
0026 class QSqlRelationalDelegate : public QStyledItemDelegate
0027 {
0028 static int fieldIndex(const QSqlTableModel *const model,
0029 const QSqlDriver *const driver,
0030 const QString &fieldName)
0031 {
0032 const QString stripped = driver->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)
0033 ? driver->stripDelimiters(fieldName, QSqlDriver::FieldName)
0034 : fieldName;
0035 return model->fieldIndex(stripped);
0036 }
0037
0038 public:
0039
0040 explicit QSqlRelationalDelegate(QObject *aParent = nullptr)
0041 : QStyledItemDelegate(aParent)
0042 {}
0043
0044 ~QSqlRelationalDelegate()
0045 {}
0046
0047 QWidget *createEditor(QWidget *aParent,
0048 const QStyleOptionViewItem &option,
0049 const QModelIndex &index) const override
0050 {
0051 const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel *>(index.model());
0052 QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : nullptr;
0053 if (!childModel)
0054 return QStyledItemDelegate::createEditor(aParent, option, index);
0055 const QSqlDriver *const driver = childModel->database().driver();
0056
0057 QComboBox *combo = new QComboBox(aParent);
0058 combo->setModel(childModel);
0059 combo->setModelColumn(fieldIndex(childModel, driver,
0060 sqlModel->relation(index.column()).displayColumn()));
0061 combo->installEventFilter(const_cast<QSqlRelationalDelegate *>(this));
0062
0063 return combo;
0064 }
0065
0066 void setEditorData(QWidget *editor, const QModelIndex &index) const override
0067 {
0068 if (!index.isValid())
0069 return;
0070
0071 if (qobject_cast<QComboBox *>(editor)) {
0072
0073
0074
0075 QVariant v = index.data(Qt::DisplayRole);
0076 const QByteArray n = editor->metaObject()->userProperty().name();
0077 if (!n.isEmpty()) {
0078 if (!v.isValid())
0079 v = QVariant(editor->property(n.data()).metaType());
0080 editor->setProperty(n.data(), v);
0081 return;
0082 }
0083 }
0084 QStyledItemDelegate::setEditorData(editor, index);
0085 }
0086
0087 void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
0088 {
0089 if (!index.isValid())
0090 return;
0091
0092 QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);
0093 QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : nullptr;
0094 QComboBox *combo = qobject_cast<QComboBox *>(editor);
0095 if (!sqlModel || !childModel || !combo) {
0096 QStyledItemDelegate::setModelData(editor, model, index);
0097 return;
0098 }
0099 const QSqlDriver *const driver = childModel->database().driver();
0100
0101 int currentItem = combo->currentIndex();
0102 int childColIndex = fieldIndex(childModel, driver,
0103 sqlModel->relation(index.column()).displayColumn());
0104 int childEditIndex = fieldIndex(childModel, driver,
0105 sqlModel->relation(index.column()).indexColumn());
0106 sqlModel->setData(index,
0107 childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole),
0108 Qt::DisplayRole);
0109 sqlModel->setData(index,
0110 childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole),
0111 Qt::EditRole);
0112 }
0113
0114 };
0115
0116 QT_END_NAMESPACE
0117
0118 #endif
0119
0120 #endif