#include "TablesPage.h" #include "ui_TablesPage.h" #include "catalog/PgAttribute.h" #include "catalog/PgDatabaseCatalog.h" #include "catalog/PgIndexContainer.h" #include "catalog/PgTriggerContainer.h" #include "ColumnPage.h" #include "ColumnTableModel.h" #include "ConstraintModel.h" #include "IconColumnDelegate.h" #include "IndexModel.h" #include "PgLabItemDelegate.h" #include "PropertiesPage.h" #include "ResultTableModelUtil.h" #include "SqlFormattingUtils.h" #include "SqlSyntaxHighlighter.h" #include "TriggerPage.h" #include "UserConfiguration.h" #include "SqlCodePreview.h" #include #include #include "plugin_support/IPluginContentWidgetContext.h" TablesPage::TablesPage(IPluginContentWidgetContext *context_, QWidget *parent) : PluginContentWidget(context_, parent) , ui(new Ui::TablesPage) { ui->setupUi(this); SetTableViewDefault(ui->tableListTable); m_tablesModel = new TablesTableModel(this); ui->tableListTable->setModel(m_tablesModel); ui->tableListTable->setItemDelegate(new PgLabItemDelegate(this)); ui->tableListTable->setSortingEnabled(true); ui->tableListTable->sortByColumn(0, Qt::AscendingOrder); ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows); // Constraints SetTableViewDefault(ui->constraintsTable); m_constraintModel = new ConstraintModel(this); ui->constraintsTable->setModel(m_constraintModel); ui->constraintsTable->setItemDelegateForColumn(0, new IconColumnDelegate(this)); // Indexes SetTableViewDefault(ui->indexesTable); m_indexModel = new IndexModel(this); ui->indexesTable->setModel(m_indexModel); ui->indexesTable->setItemDelegate(new PgLabItemDelegate(this)); ui->indexesTable->setItemDelegateForColumn(0, new IconColumnDelegate(this)); // Set code editor fonts QFont code_font = UserConfiguration::instance()->codeFont(); ui->constraintSqlEdit->setFont(code_font); ui->indexSqlEdit->setFont(code_font); // Connect signals // --------------- // Table selection connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &TablesPage::tableListTable_currentRowChanged); connect(m_tablesModel, &QAbstractItemModel::layoutChanged, this, &TablesPage::tableListTable_layoutChanged); //layoutChanged(const QList &parents = ..., QAbstractItemModel::LayoutChangeHint hint = ...) connect(ui->constraintsTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TablesPage::constraintsTable_selectionChanged); connect(ui->constraintsTable->model(), &QAbstractItemModel::modelReset, this, &TablesPage::constraintsTable_modelReset); // React to changes in de selected indexes, does not trigger when model is reset connect(ui->indexesTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TablesPage::indexesTable_selectionChanged); // Capture model reset independently connect(ui->indexesTable->model(), &QAbstractItemModel::modelReset, this, &TablesPage::indexesTable_modelReset); // Non designer based code // - Columns page m_columnsPage = new ColumnPage(this); ui->twDetails->insertTab(0, m_columnsPage, ""); // - Properties page m_propertiesPage = new PropertiesPage(this); m_propertiesPage->setSourceModel(m_tablesModel); ui->twDetails->addTab(m_propertiesPage, ""); connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged, m_propertiesPage, &PropertiesPage::setActiveRow); // - Trigger page m_triggerPage = new TriggerPage(this); ui->twDetails->addTab(m_triggerPage, ""); // SQL tab m_sqlCodePreview = new SqlCodePreview(this); ui->twDetails->addTab(m_sqlCodePreview, ""); // Force focus on columns tab by default ui->twDetails->setCurrentIndex(0); retranslateUi(false); } void TablesPage::retranslateUi(bool all) { if (all) ui->retranslateUi(this); auto set_tabtext = [this] (QWidget *widget, QString translation) { ui->twDetails->setTabText(ui->twDetails->indexOf(widget), translation); }; set_tabtext(m_columnsPage, QApplication::translate("TablesPage", "Columns", nullptr)); set_tabtext(m_propertiesPage, QApplication::translate("TablesPage", "Properties", nullptr)); set_tabtext(m_triggerPage, QApplication::translate("TablesPage", "Triggers", nullptr)); set_tabtext(m_sqlCodePreview, QApplication::translate("TablesPage", "SQL", nullptr)); } TablesPage::~TablesPage() { delete ui; } void TablesPage::setCatalog(std::shared_ptr cat) { m_catalog = cat; m_tablesModel->setCatalog(cat); ui->tableListTable->resizeColumnsToContents(); m_triggerPage->setCatalog(cat); auto highlighter = new SqlSyntaxHighlighter(ui->constraintSqlEdit->document()); highlighter->setTypes(*cat->types()); highlighter = new SqlSyntaxHighlighter(ui->indexSqlEdit->document()); highlighter->setTypes(*cat->types()); } void TablesPage::setNamespaceFilter(TablesTableModel::NamespaceFilter filter) { m_tablesModel->setNamespaceFilter(filter); } void TablesPage::tableListTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) { if (current.row() != previous.row()) { if (current.isValid()) { PgClass table = m_tablesModel->getTable(current.row()); selectedTableChanged(table); } else selectedTableChanged({}); } } void TablesPage::tableListTable_layoutChanged(const QList &, QAbstractItemModel::LayoutChangeHint ) { auto&& index = ui->tableListTable->selectionModel()->currentIndex(); if (index.isValid()) { PgClass table = m_tablesModel->getTable(index.row()); selectedTableChanged(table); } else selectedTableChanged({}); } void TablesPage::selectedTableChanged(const std::optional &table) { m_columnsPage->setData(m_catalog, table); m_constraintModel->setData(m_catalog, table); ui->constraintsTable->resizeColumnsToContents(); ui->constraintsTable->selectionModel()->reset(); m_indexModel->setData(m_catalog, table); ui->indexesTable->resizeColumnsToContents(); m_triggerPage->setFilter(table); updateSqlTab(table); } void TablesPage::constraintsTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/) { const auto indexes = ui->constraintsTable->selectionModel()->selectedIndexes(); std::unordered_set rijen; for (const auto &e : indexes) rijen.insert(e.row()); QString drops; QString creates; for (auto rij : rijen) { const PgConstraint constraint = m_constraintModel->constraint(rij); drops += getDropConstraintDefinition(*m_catalog, constraint) % "\n"; creates += getAlterTableConstraintDefinition(*m_catalog, constraint) % "\n"; } ui->constraintSqlEdit->setPlainText(drops % "\n" % creates); } void TablesPage::constraintsTable_modelReset() { ui->constraintSqlEdit->clear(); } void TablesPage::indexesTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/) { const auto indexes = ui->indexesTable->selectionModel()->selectedIndexes(); std::unordered_set rijen; for (const auto &e : indexes) rijen.insert(e.row()); QString drops; QString creates; for (auto rij : rijen) { const PgIndex index = m_indexModel->getIndex(rij); drops += index.dropSql() % "\n"; creates += index.createSql() % "\n"; } ui->indexSqlEdit->setPlainText(drops % "\n" % creates); } void TablesPage::indexesTable_modelReset() { ui->indexSqlEdit->clear(); } void TablesPage::on_tableListTable_doubleClicked(const QModelIndex &index) { PgClass table = m_tablesModel->getTable(index.row()); if (table.oid() != InvalidOid) { context()->moduleAction("pglab.crudpage", "open", { { "oid", table.oid() } }); } } void TablesPage::updateSqlTab(const std::optional &table) { if (!table.has_value()) { m_sqlCodePreview->clear(); return; } QString drop_sql; QString create_sql; // create table create_sql += table->createSql(); // - columns // - constraints // table details (inherits etc) // Indexes drop_sql += "-- drop Indexes\n"; create_sql += "-- create Indexes\n"; auto && indexes = m_catalog->indexes()->getIndexesForTable(table->oid()); for (auto && index : indexes) { drop_sql += index.dropSql() % "\n"; create_sql += index.createSql() % "\n"; } // Triggers drop_sql += "-- drop Triggers\n"; create_sql += "-- create Triggers\n"; auto && triggers = m_catalog->triggers()->getTriggersForRelation(table->oid()); for (auto && trg : triggers) { drop_sql += trg.dropSql() % "\n"; create_sql += trg.createSql() % "\n"; } // Privileges create_sql += "-- set Privileges\n"; create_sql += table->grantSql() % "\n"; // Comments create_sql += "-- set Comments table + columns\n"; // m_sqlCodePreview->setPlainText(drop_sql % "\n\n" % create_sql); }