diff --git a/src/ExtendedTableWidget.cpp b/src/ExtendedTableWidget.cpp index 0d288d26..5f366596 100644 --- a/src/ExtendedTableWidget.cpp +++ b/src/ExtendedTableWidget.cpp @@ -22,6 +22,8 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) : // Set up filter row m_tableHeader = new FilterTableHeader(this); setHorizontalHeader(m_tableHeader); + + verticalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); } void ExtendedTableWidget::copy() diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 8862bd9d..324c34f8 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -135,6 +135,11 @@ void MainWindow::init() popupBrowseDataHeaderMenu->addSeparator(); popupBrowseDataHeaderMenu->addAction(ui->actionSetAllTablesEncoding); + popupRecordMenu = new QMenu(this); + popupRecordMenu->addAction(ui->actionDittoRecord); + QShortcut* dittoRecordShortcut = new QShortcut(QKeySequence("Ctrl+\""), this); + connect(dittoRecordShortcut, SIGNAL(activated()), this, SLOT(dittoRecord())); + // Add menu item for log dock ui->viewMenu->insertAction(ui->viewDBToolbarAction, ui->dockLog->toggleViewAction()); ui->viewMenu->actions().at(0)->setShortcut(QKeySequence(tr("Ctrl+L"))); @@ -188,6 +193,7 @@ void MainWindow::init() connect(editDock, SIGNAL(updateRecordText(int, int, bool, QByteArray)), this, SLOT(updateRecordText(int, int, bool, QByteArray))); connect(ui->dbTreeWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(changeTreeSelection())); connect(ui->dataTable->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDataColumnPopupMenu(QPoint))); + connect(ui->dataTable->verticalHeader(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showRecordPopupMenu(QPoint))); // Load window settings tabifyDockWidget(ui->dockLog, ui->dockPlot); @@ -599,6 +605,26 @@ void MainWindow::deleteRecord() } } +void MainWindow::dittoRecord() +{ + const QString sCurrentTable = ui->comboBrowseTable->currentText(); + if (!(db.getObjectByName(sCurrentTable).gettype() == "table" && !db.readOnly())) + return; + + int row; + if (qobject_cast(sender())) + row = ui->dataTable->currentIndex().row(); + else + row = ui->actionDittoRecord->property("current_row").toInt(); + + if (row == -1) + return; + + addRecord(); + QModelIndex idx = m_browseTableModel->dittoRecord(row); + ui->dataTable->setCurrentIndex(idx); +} + void MainWindow::selectTableLine(int lineToSelect) { // Are there even that many lines? @@ -2394,6 +2420,20 @@ void MainWindow::showDataColumnPopupMenu(const QPoint& pos) popupBrowseDataHeaderMenu->exec(ui->dataTable->horizontalHeader()->mapToGlobal(pos)); } +void MainWindow::showRecordPopupMenu(const QPoint& pos) +{ + const QString sCurrentTable = ui->comboBrowseTable->currentText(); + if (!(db.getObjectByName(sCurrentTable).gettype() == "table" && !db.readOnly())) + return; + + int row = ui->dataTable->verticalHeader()->logicalIndexAt(pos); + if (row == -1) + return; + + ui->actionDittoRecord->setProperty("current_row", row); + popupRecordMenu->exec(ui->dataTable->verticalHeader()->mapToGlobal(pos)); +} + void MainWindow::editDataColumnDisplayFormat() { // Get the current table name and fetch its table object, then retrieve the fields of that table and look up the index of the clicked table header diff --git a/src/MainWindow.h b/src/MainWindow.h index 42cff2a2..ece8dcd0 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -109,6 +109,7 @@ private: QMenu *recentFilesMenu; QMenu *popupSaveSqlFileMenu; QMenu* popupBrowseDataHeaderMenu; + QMenu* popupRecordMenu; QLabel* statusEncodingLabel; QLabel* statusEncryptionLabel; @@ -164,6 +165,7 @@ private slots: bool fileClose(); void addRecord(); void deleteRecord(); + void dittoRecord(); void selectTableLine( int lineToSelect ); void navigatePrevious(); void navigateNext(); @@ -222,6 +224,7 @@ private slots: void on_comboLineType_currentIndexChanged(int index); void on_comboPointShape_currentIndexChanged(int index); void showDataColumnPopupMenu(const QPoint& pos); + void showRecordPopupMenu(const QPoint& pos); void editDataColumnDisplayFormat(); void showRowidColumn(bool show); void browseDataSetTableEncoding(bool forAllTables = false); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index a5a99b0e..e5392596 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -1824,6 +1824,14 @@ Change the default encoding assumed for all tables in the database + + + Duplicate record + + + Duplicate record + + @@ -2837,6 +2845,22 @@ + + actionDittoRecord + triggered() + MainWindow + dittoRecord() + + + -1 + -1 + + + 518 + 314 + + + fileOpen() @@ -2898,5 +2922,6 @@ browseDataSetTableEncoding() browseDataSetDefaultTableEncoding() browseDataFetchAllData() + dittoRecord() diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index cdba79ea..d1f809d2 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -432,6 +432,26 @@ bool SqliteTableModel::removeRows(int row, int count, const QModelIndex& parent) return true; } +QModelIndex SqliteTableModel::dittoRecord(int old_row) +{ + int firstEditedColumn = 0; + int new_row = rowCount() - 1; + + sqlb::Table t = sqlb::Table::parseSQL(m_db->getObjectByName(m_sTable).getsql()).first; + + for (int col = 0; col < t.fields().size(); ++col) { + if (!t.fields().at(col)->primaryKey()) { + if (!firstEditedColumn) + firstEditedColumn = col + 1; + + QVariant value = data(index(old_row, col + 1), Qt::EditRole); + setData(index(new_row, col + 1), value); + } + } + + return index(new_row, firstEditedColumn); +} + void SqliteTableModel::fetchData(unsigned int from, unsigned to) { int currentsize = m_data.size(); diff --git a/src/sqlitetablemodel.h b/src/sqlitetablemodel.h index c2ce5ce5..0abc6ade 100644 --- a/src/sqlitetablemodel.h +++ b/src/sqlitetablemodel.h @@ -29,6 +29,8 @@ public: bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); + QModelIndex dittoRecord(int old_row); + void setQuery(const QString& sQuery, bool dontClearHeaders = false); QString query() const { return m_sQuery; } void setTable(const QString& table, const QVector &display_format = QVector());