diff --git a/src/ExtendedTableWidget.cpp b/src/ExtendedTableWidget.cpp new file mode 100644 index 00000000..cb0f64f2 --- /dev/null +++ b/src/ExtendedTableWidget.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include "ExtendedTableWidget.h" + +ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) : + QTableView(parent) +{ +} + +void ExtendedTableWidget::copy() +{ + // Get list of selected items + QItemSelectionModel* selection = selectionModel(); + QModelIndexList indices = selection->selectedIndexes(); + + // Abort if there's nothing to copy + if(indices.size() == 0) + return; + + // Sort the items by row, then by column + qSort(indices); + + // Go through all the items... + QString result; + QModelIndex prev = indices.front(); + indices.removeFirst(); + foreach(QModelIndex index, indices) + { + // Add the content of this cell to the clipboard string + result.append(QString("\"%1\"").arg(prev.data().toString())); + + // If this is a new row add a line break, if not add a tab for cell separation + if(index.row() != prev.row()) + result.append("\r\n"); + else + result.append("\t"); + + prev = index; + } + result.append(QString("\"%1\"\r\n").arg(indices.last().data().toString())); // And the last cell + + // And finally add it to the clipboard + qApp->clipboard()->setText(result); +} + +void ExtendedTableWidget::keyPressEvent(QKeyEvent* event) +{ + // Call a custom copy method when Ctrl-C is pressed + if(event->matches(QKeySequence::Copy)) + copy(); + else + QTableView::keyPressEvent(event); +} diff --git a/src/ExtendedTableWidget.h b/src/ExtendedTableWidget.h new file mode 100644 index 00000000..7e8adbbf --- /dev/null +++ b/src/ExtendedTableWidget.h @@ -0,0 +1,20 @@ +#ifndef __EXTENDEDTABLEWIDGET_H__ +#define __EXTENDEDTABLEWIDGET_H__ + +#include + +class ExtendedTableWidget : public QTableView +{ + Q_OBJECT + +public: + explicit ExtendedTableWidget(QWidget* parent = 0); + +private: + void copy(); + +protected: + virtual void keyPressEvent(QKeyEvent* event); +}; + +#endif diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 4a05abe6..766bada8 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -27,6 +27,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow), + browseTableModel(new QStandardItemModel(this)), editWin(new EditDialog(this)), findWin(0) { @@ -63,7 +64,9 @@ void MainWindow::init() // Create the SQL sytax highlighter sqliteHighlighterTabSql = new SQLiteSyntaxHighlighter(ui->sqlTextEdit->document()); - // Set up DB model + // Set up DB models + ui->dataTable->setModel(browseTableModel); + queryResultListModel = new QStandardItemModel(this); ui->queryResultTableView->setModel(queryResultListModel); @@ -114,7 +117,6 @@ void MainWindow::init() setAcceptDrops(true); setWindowTitle(QApplication::applicationName()); - // Fonts for edit fields QFont font("Monospace"); font.setStyleHint(QFont::TypeWriter); @@ -285,9 +287,10 @@ void MainWindow::populateTable( const QString & tablename, bool keepColumnWidths } QString orderby = QString::number(curBrowseOrderByIndex) + " " + (curBrowseOrderByMode == ORDERMODE_ASC ? "ASC" : "DESC"); - if (!db.browseTable(tablename, orderby)){ - ui->dataTable->setRowCount( 0 ); - ui->dataTable->setColumnCount( 0 ); + if(!db.browseTable(tablename, orderby)) + { + browseTableModel->setRowCount(0); + browseTableModel->setColumnCount(0); QApplication::restoreOverrideCursor(); if(findWin) findWin->resetFields(db.getTableFields("")); @@ -389,9 +392,10 @@ void MainWindow::addRecord() void MainWindow::deleteRecord() { - if (ui->dataTable->currentRow()!=-1){ - int lastselected = ui->dataTable->currentRow(); - db.deleteRecord(ui->dataTable->currentRow()); + if(ui->dataTable->currentIndex().row() != -1) + { + int lastselected = ui->dataTable->currentIndex().row(); + db.deleteRecord(lastselected); populateTable(db.curBrowseTableName); int nextselected = lastselected ; if (nextselected > db.getRecordCount()){ @@ -427,9 +431,9 @@ void MainWindow::updateTableView(int lineToSelect, bool keepColumnWidths) { QApplication::setOverrideCursor( Qt::WaitCursor ); - ui->dataTable->setRowCount(db.getRecordCount()); - ui->dataTable->setColumnCount( db.browseFields.count() ); - ui->dataTable->setHorizontalHeaderLabels(db.browseFields); + browseTableModel->setRowCount(db.getRecordCount()); + browseTableModel->setColumnCount(db.browseFields.count()); + browseTableModel->setHorizontalHeaderLabels(db.browseFields); rowList tab = db.browseRecs; int maxRecs = db.getRecordCount(); @@ -443,17 +447,17 @@ void MainWindow::updateTableView(int lineToSelect, bool keepColumnWidths) for (int i = 0; i < tab.size(); ++i) { rowLabel.setNum(rowNum+1); - ui->dataTable->setVerticalHeaderItem(rowNum, new QTableWidgetItem( rowLabel )); + browseTableModel->setVerticalHeaderItem(rowNum, new QStandardItem(rowLabel)); colNum = 0; QStringList& rt = tab[i]; for (int e = 1; e < rt.size(); ++e) { QString& content = rt[e]; - QTableWidgetItem* item = new QTableWidgetItem(content); + QStandardItem* item = new QStandardItem(content); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setToolTip(wrapText(content)); - ui->dataTable->setItem( rowNum, colNum, item); + browseTableModel->setItem( rowNum, colNum, item); colNum++; } rowNum++; @@ -462,7 +466,7 @@ void MainWindow::updateTableView(int lineToSelect, bool keepColumnWidths) } if(!keepColumnWidths) { - for(int i = 0; i < ui->dataTable->columnCount(); ++i) + for(int i=0;icolumnCount();++i) { ui->dataTable->resizeColumnToContents(i); if( ui->dataTable->columnWidth(i) > 400 ) @@ -480,13 +484,13 @@ void MainWindow::selectTableLine(int lineToSelect) { ui->dataTable->clearSelection(); ui->dataTable->selectRow(lineToSelect); - ui->dataTable->setCurrentCell(lineToSelect, 0); - ui->dataTable->scrollToItem(ui->dataTable->itemAt(lineToSelect, 0)); + ui->dataTable->setCurrentIndex(ui->dataTable->currentIndex().sibling(lineToSelect, 0)); + ui->dataTable->scrollTo(ui->dataTable->currentIndex().sibling(lineToSelect, 0)); } void MainWindow::navigatePrevious() { - int curRow = ui->dataTable->currentRow(); + int curRow = ui->dataTable->currentIndex().row(); curRow -= 100; if(curRow < 0) curRow = 0; updateTableView(curRow); @@ -495,9 +499,10 @@ void MainWindow::navigatePrevious() void MainWindow::navigateNext() { - int curRow = ui->dataTable->currentRow(); + int curRow = ui->dataTable->currentIndex().row(); curRow += 100; - if(curRow >= ui->dataTable->rowCount()) curRow = ui->dataTable->rowCount()-1; + if(curRow >= browseTableModel->rowCount()) + curRow = browseTableModel->rowCount()-1; updateTableView(curRow); } @@ -518,7 +523,7 @@ void MainWindow::setRecordsetLabel() { int from = ui->dataTable->verticalHeader()->visualIndexAt(0) + 1; int to = ui->dataTable->verticalHeader()->visualIndexAt(ui->dataTable->height()) - 1; - int total = ui->dataTable->rowCount(); + int total = browseTableModel->rowCount(); if(to == -2) to = total; @@ -709,9 +714,9 @@ void MainWindow::updateRecordText(int row, int col, const QString& newtext) QStringList& rt = tab[row]; QString& cv = rt[col+1];//must account for rowid - QTableWidgetItem* item = new QTableWidgetItem(cv); + QStandardItem* item = new QStandardItem(cv); item->setToolTip( wrapText(cv) ); - ui->dataTable->setItem(row, col, item); + browseTableModel->setItem(row, col, item); } @@ -719,7 +724,7 @@ void MainWindow::editWinAway() { editWin->hide(); activateWindow(); - ui->dataTable->setRangeSelected(QTableWidgetSelectionRange(editWin->getCurrentRow(), editWin->getCurrentCol(), editWin->getCurrentRow(), editWin->getCurrentCol()), true); + ui->dataTable->setCurrentIndex(ui->dataTable->currentIndex().sibling(editWin->getCurrentRow(), editWin->getCurrentCol())); } void MainWindow::editText(int row, int col) @@ -732,9 +737,10 @@ void MainWindow::editText(int row, int col) editWin->show(); } -void MainWindow::doubleClickTable( int row, int col ) +void MainWindow::doubleClickTable(const QModelIndex& index) { - if ((row==-1) || (col==-1)){ + if(!index.isValid()) + { qDebug("no cell selected"); return; } @@ -743,9 +749,7 @@ void MainWindow::doubleClickTable( int row, int col ) if(db.getObjectByName(ui->comboBrowseTable->currentText()).gettype() != "table") return; - int realRow = row; - - editText(realRow , col); + editText(index.row(), index.column()); } void MainWindow::executeQuery() @@ -1125,6 +1129,10 @@ void MainWindow::activateFields(bool enable) void MainWindow::browseTableHeaderClicked(int logicalindex) { + // Abort if there is more than one column selected because this tells us that the user pretty sure wants to do a range selection instead of sorting data + if(ui->dataTable->selectionModel()->selectedColumns().count() > 1) + return; + // instead of the column name we just use the column index, +2 because 'rowid, *' is the projection curBrowseOrderByIndex = logicalindex + 2; curBrowseOrderByMode = curBrowseOrderByMode == ORDERMODE_ASC ? ORDERMODE_DESC : ORDERMODE_ASC; @@ -1132,7 +1140,7 @@ void MainWindow::browseTableHeaderClicked(int logicalindex) // select the first item in the column so the header is bold // we might try to select the last selected item - ui->dataTable->setCurrentCell(0, logicalindex); + ui->dataTable->setCurrentIndex(ui->dataTable->currentIndex().sibling(0, logicalindex)); } void MainWindow::resizeEvent(QResizeEvent*) diff --git a/src/MainWindow.h b/src/MainWindow.h index 8625252c..d8ed23a0 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -14,6 +14,7 @@ class SQLiteSyntaxHighlighter; class QStandardItemModel; class QIntValidator; class QLabel; +class QModelIndex; namespace Ui { class MainWindow; @@ -51,6 +52,7 @@ private: Ui::MainWindow* ui; + QStandardItemModel *browseTableModel; QStandardItemModel *queryResultListModel; QMenu *popupTableMenu; QMenu *popupFieldMenu; @@ -128,7 +130,7 @@ private slots: virtual void updateRecordText( int row, int col, const QString& newtext ); virtual void editWinAway(); virtual void editText( int row, int col ); - virtual void doubleClickTable( int row, int col ); + virtual void doubleClickTable(const QModelIndex& index); virtual void executeQuery(); virtual void importTableFromCSV(); virtual void exportTableToCSV(); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 9f637c6a..de2be14d 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -205,12 +205,12 @@ - + This is the database view. You can double-click any record to edit its contents in the cell editor window. - QAbstractItemView::SingleSelection + QAbstractItemView::ExtendedSelection QAbstractItemView::ScrollPerPixel @@ -317,7 +317,7 @@ 0 0 763 - 494 + 444 @@ -843,7 +843,7 @@ - + Query generated data @@ -854,7 +854,7 @@ QAbstractItemView::NoEditTriggers - QAbstractItemView::NoSelection + QAbstractItemView::ExtendedSelection QAbstractItemView::ScrollPerPixel @@ -1399,6 +1399,11 @@ QTextEdit
sqltextedit.h
+ + ExtendedTableWidget + QTableView +
ExtendedTableWidget.h
+
dbTreeWidget @@ -1697,22 +1702,6 @@ - - dataTable - cellDoubleClicked(int,int) - MainWindow - doubleClickTable(int,int) - - - 99 - 113 - - - 399 - 299 - - - mainTab currentChanged(int) @@ -2129,6 +2118,22 @@ + + dataTable + doubleClicked(QModelIndex) + MainWindow + doubleClickTable(QModelIndex) + + + 399 + 211 + + + 399 + 299 + + + fileOpen() @@ -2143,7 +2148,7 @@ browseRefresh() compact() helpWhatsThis() - doubleClickTable(int,int) + doubleClickTable(QModelIndex) browseTableHeaderClicked(int) mainTabSelected(int) executeQuery() @@ -2169,5 +2174,6 @@ deleteField() loadPragmas() savePragmas() + copy() diff --git a/src/src.pro b/src/src.pro index a3bdffe9..8eb6ec88 100644 --- a/src/src.pro +++ b/src/src.pro @@ -24,7 +24,8 @@ HEADERS += \ ExportCsvDialog.h \ ImportCsvDialog.h \ sqltextedit.h \ - sqlitetypes.h + sqlitetypes.h \ + ExtendedTableWidget.h SOURCES += \ sqlitedb.cpp \ @@ -41,7 +42,8 @@ SOURCES += \ ExportCsvDialog.cpp \ ImportCsvDialog.cpp \ sqltextedit.cpp \ - sqlitetypes.cpp + sqlitetypes.cpp \ + ExtendedTableWidget.cpp # create a unittest option CONFIG(unittest) {