GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — sqlitebrowser/src/ForeignKeyEditorDelegate.cpp at master · sqlitebrowser/sqlitebrowser Expand file tree/ Copy pathForeignKeyEditorDelegate.cppMore file actions 203 lines (168 loc) · 7.54 KB / Copy pathForeignKeyEditorDelegate.cppFile metadata and controls203 lines (168 loc) · 7.54 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 #include "sqlitedb.h" #include "ForeignKeyEditorDelegate.h" #include <QComboBox> #include <QLineEdit> #include <QPushButton> #include <QHBoxLayout> Q_DECLARE_METATYPE(sqlb::StringVector) class ForeignKeyEditor : public QWidget { Q_OBJECT public: explicit ForeignKeyEditor(QWidget* parent = nullptr) : QWidget(parent) , tablesComboBox(new QComboBox(this)) , idsComboBox(new QComboBox(this)) , clauseEdit(new QLineEdit(this)) , m_btnReset(new QPushButton(tr("&Reset"), this)) { idsComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); clauseEdit->setPlaceholderText(tr("Foreign key clauses (ON UPDATE, ON DELETE etc.)")); QHBoxLayout* layout = new QHBoxLayout(this); layout->addWidget(tablesComboBox); layout->addWidget(idsComboBox); layout->addWidget(clauseEdit); layout->addWidget(m_btnReset); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); connect(m_btnReset, &QPushButton::clicked, this, [&] { tablesComboBox->setCurrentIndex(-1); idsComboBox->setCurrentIndex(-1); clauseEdit->clear(); }); connect(tablesComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) { // reset ids combo box idsComboBox->setCurrentIndex(-1); // disable clauses editor if none of tables is selected bool enableClausesEditor = (index!= -1); clauseEdit->setEnabled(enableClausesEditor); }); } QString getSql() const { if (tablesComboBox->currentText().isEmpty()) return QString(); const QString table = sqlb::escapeIdentifier(tablesComboBox->currentText()); const QString clauses = clauseEdit->text(); QString id = idsComboBox->currentText(); if (!id.isEmpty()) id = QString("(%1)").arg(sqlb::escapeIdentifier(id)); return QString("%1%2 %3").arg( table, id, clauses) .trimmed(); } QComboBox* tablesComboBox; QComboBox* idsComboBox; QLineEdit* clauseEdit; // for ON CASCADE and such std::shared_ptr<sqlb::ForeignKeyClause> foreignKey; // This can be used for storing a pointer to the foreign key object currently edited private: QPushButton* m_btnReset; }; ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::Table& table, QObject* parent) : QStyledItemDelegate(parent) , m_db(db) , m_table(table) { for(const auto& it : m_db.schemata) { for(const auto& jt : it.second.tables) { // Don't insert the current table into the list. The name and fields of the current table are always taken from the m_table reference if(jt.first != m_table.name()) m_tablesIds.insert({jt.first, jt.second->fieldNames()}); } } } QWidget* ForeignKeyEditorDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(option) Q_UNUSED(index) ForeignKeyEditor* editor = new ForeignKeyEditor(parent); editor->setAutoFillBackground(true); connect(editor->tablesComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int idx) { QString tableName = editor->tablesComboBox->itemText(idx); QComboBox* box = editor->idsComboBox; box->clear(); box->addItem(QString()); // for those heroes who don't like to specify key explicitly // For recursive foreign keys get the field list from the m_table reference. For other foreign keys from the prepared field lists. if(tableName.toStdString() == m_table.name()) { for(const auto& n : m_table.fieldNames()) box->addItem(QString::fromStdString(n)); } else { for(const auto& n : m_tablesIds[tableName.toStdString()]) box->addItem(QString::fromStdString(n)); } box->setCurrentIndex(0); }); editor->tablesComboBox->clear(); editor->tablesComboBox->addItem(QString::fromStdString(m_table.name())); // For recursive foreign keys editor->tablesComboBox->insertSeparator(1); for(const auto& i : m_tablesIds) editor->tablesComboBox->addItem(QString::fromStdString(i.first)); return editor; } void ForeignKeyEditorDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { ForeignKeyEditor* fkEditor = static_cast<ForeignKeyEditor*>(editor); // First try to get the fields list by assuming this is called for a constraints table in which the first column contains a list of fields. // If this fails, assume this is called for a fields table in which the first column contains the name of a single table field. sqlb::StringVector fields = index.sibling(index.row(), 0).data(Qt::UserRole).value<sqlb::StringVector>(); if(fields.empty()) fields.push_back(index.sibling(index.row(), 0).data().toString().toStdString()); fkEditor->foreignKey = m_table.foreignKey(fields); if (fkEditor->foreignKey) { fkEditor->tablesComboBox->setCurrentText(QString::fromStdString(fkEditor->foreignKey->table())); fkEditor->clauseEdit->setText(QString::fromStdString(fkEditor->foreignKey->constraint())); if (!fkEditor->foreignKey->columns().empty()) fkEditor->idsComboBox->setCurrentText(QString::fromStdString(fkEditor->foreignKey->columns().front())); } else { fkEditor->tablesComboBox->setCurrentIndex(-1); } } void ForeignKeyEditorDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { ForeignKeyEditor* fkEditor = static_cast<ForeignKeyEditor*>(editor); QString sql = fkEditor->getSql(); // First try to get the fields list by assuming this is called for a constraints table in which the first column contains a list of fields. // If this fails, assume this is called for a fields table in which the first column contains the name of a single table field. sqlb::StringVector fields = index.sibling(index.row(), 0).data(Qt::UserRole).value<sqlb::StringVector>(); if(fields.empty()) fields.push_back(index.sibling(index.row(), 0).data().toString().toStdString()); if (sql.isEmpty() && fkEditor->foreignKey) { // Remove the foreign key m_table.removeConstraint(fkEditor->foreignKey); } else { // Create a new foreign key object if required if(!fkEditor->foreignKey) { fkEditor->foreignKey = std::make_shared<sqlb::ForeignKeyClause>(); m_table.addConstraint(fields, fkEditor->foreignKey); } // Set data const auto table = fkEditor->tablesComboBox->currentText().toStdString(); const auto id = fkEditor->idsComboBox->currentText().toStdString(); const auto clause = fkEditor->clauseEdit->text().trimmed().toStdString(); fkEditor->foreignKey->setTable(table); if(id.empty()) fkEditor->foreignKey->setColumns({}); else fkEditor->foreignKey->setColumns({id}); fkEditor->foreignKey->setConstraint(clause); } model->setData(index, sql); } void ForeignKeyEditorDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(index) editor->setGeometry(option.rect); } #include "ForeignKeyEditorDelegate.moc" |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |