diff --git a/src/AddRecordDialog.cpp b/src/AddRecordDialog.cpp index f3428dda..d43c7d43 100644 --- a/src/AddRecordDialog.cpp +++ b/src/AddRecordDialog.cpp @@ -112,12 +112,12 @@ public: } }; -AddRecordDialog::AddRecordDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier& tableName, QWidget* parent) +AddRecordDialog::AddRecordDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier& tableName, QWidget* parent, const QString &pseudo_pk) : QDialog(parent), ui(new Ui::AddRecordDialog), pdb(db), curTable(tableName), - m_table(*(pdb.getObjectByName(curTable))) + pseudo_pk(pseudo_pk) { // Create UI ui->setupUi(this); @@ -179,10 +179,28 @@ void AddRecordDialog::populateFields() ui->treeWidget->setItemDelegateForColumn(kType, new NoEditDelegate(this)); ui->treeWidget->setItemDelegateForColumn(kValue, new EditDelegate(this)); - const auto& fields = m_table.fields; - const QStringList& pk = m_table.primaryKey(); - for(const sqlb::Field& f : fields) + sqlb::FieldVector fields; + QVector fks; + QStringList pk; + + // Initialize fields, fks and pk differently depending on whether it's a table or a view. + if (pseudo_pk.isNull()) { + sqlb::TablePtr m_table = pdb.getObjectByName(curTable); + fields = m_table->fields; + for(const sqlb::Field& f : fields) + fks.append(m_table->constraint({f.name()}, sqlb::Constraint::ForeignKeyConstraintType)); + pk = m_table->primaryKey(); + } else { + sqlb::ViewPtr m_view = pdb.getObjectByName(curTable); + fields = m_view->fields; + fks.fill(sqlb::ConstraintPtr(nullptr), fields.size()); + pk = QStringList(pseudo_pk); + } + + for(uint i = 0; i < fields.size(); i++) + { + const sqlb::Field& f = fields[i]; QTreeWidgetItem *tbitem = new QTreeWidgetItem(ui->treeWidget); tbitem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable); @@ -199,7 +217,7 @@ void AddRecordDialog::populateFields() } if (contains(pk, f.name())) tbitem->setIcon(kName, QIcon(":/icons/field_key")); - else if (m_table.constraint({f.name()}, sqlb::Constraint::ForeignKeyConstraintType)) + else if (fks[i]) tbitem->setIcon(kName, QIcon(":/icons/field_fk")); else tbitem->setIcon(kName, QIcon(":/icons/field")); @@ -216,7 +234,7 @@ void AddRecordDialog::populateFields() if (!f.check().isEmpty()) toolTip.append(tr("Check constraint:\t %1\n").arg (f.check())); - auto fk = std::dynamic_pointer_cast(m_table.constraint({f.name()}, sqlb::Constraint::ForeignKeyConstraintType)); + auto fk = std::dynamic_pointer_cast(fks[i]); if(fk) toolTip.append(tr("Foreign key:\t %1\n").arg(fk->toString())); diff --git a/src/AddRecordDialog.h b/src/AddRecordDialog.h index 6497f55e..2da0d991 100644 --- a/src/AddRecordDialog.h +++ b/src/AddRecordDialog.h @@ -19,7 +19,7 @@ class AddRecordDialog : public QDialog Q_OBJECT public: - explicit AddRecordDialog(DBBrowserDB& pdb, const sqlb::ObjectIdentifier& tableName, QWidget* parent = nullptr); + explicit AddRecordDialog(DBBrowserDB& pdb, const sqlb::ObjectIdentifier& tableName, QWidget* parent = nullptr, const QString& pseudo_pk = QString()); ~AddRecordDialog() override; protected: @@ -46,7 +46,7 @@ private: Ui::AddRecordDialog* ui; DBBrowserDB& pdb; sqlb::ObjectIdentifier curTable; - sqlb::Table m_table; + QString pseudo_pk; }; #endif diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 3b91a153..c9dc79a3 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -958,7 +958,8 @@ void MainWindow::addRecord() { int row = m_browseTableModel->rowCount(); - if(m_browseTableModel->insertRow(row)) + // If table has pseudo_pk, then it must be an editable view. Jump straight to inserting by pop-up dialog. + if(!m_browseTableModel->hasPseudoPk() && m_browseTableModel->insertRow(row)) { selectTableLine(row); } else { @@ -970,7 +971,8 @@ void MainWindow::addRecord() void MainWindow::insertValues() { - AddRecordDialog dialog(db, currentlyBrowsedTableName(), this); + QString pseudo_pk = m_browseTableModel->hasPseudoPk() ? m_browseTableModel->pseudoPk() : QString(); + AddRecordDialog dialog(db, currentlyBrowsedTableName(), this, pseudo_pk); if (dialog.exec()) populateTable(); } @@ -1296,7 +1298,7 @@ void MainWindow::doubleClickTable(const QModelIndex& index) return; } - // * Don't allow editing of other objects than tables (on the browse table) * + // * Don't allow editing of other objects than tables and editable views bool isEditingAllowed = !db.readOnly() && m_currentTabTableModel == m_browseTableModel && m_browseTableModel->isEditable(); @@ -1324,7 +1326,7 @@ void MainWindow::dataTableSelectionChanged(const QModelIndex& index) bool editingAllowed = !db.readOnly() && (m_currentTabTableModel == m_browseTableModel) && m_browseTableModel->isEditable(); - // Don't allow editing of other objects than tables + // Don't allow editing of other objects than tables and editable views editDock->setReadOnly(!editingAllowed); // If the Edit Cell dock is visible, load the new value into it @@ -3754,7 +3756,7 @@ void MainWindow::updateInsertDeleteRecordButton() // at least one row to be selected. For the insert button there is an extra rule to disable it when we are browsing a view because inserting // into a view isn't supported yet. bool isEditable = m_browseTableModel->isEditable() && !db.readOnly(); - ui->actionNewRecord->setEnabled(isEditable && !m_browseTableModel->hasPseudoPk()); + ui->actionNewRecord->setEnabled(isEditable); ui->actionDeleteRecord->setEnabled(isEditable && rows != 0); if(rows > 1)