Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-18 09:26:38

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
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             // Taken from QItemDelegate::setEditorData() as we need
0073             // to present the DisplayRole and not the EditRole which
0074             // is the id reference to the related model
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 // QT_WIDGETS_LIB
0119 
0120 #endif // QSQLRELATIONALDELEGATE_H