#include "radixwidgets/tableview.hh" #include "radixbug/bug.hh" #include #include #include #include namespace radix { class TableView::PImpl { public: bool allow_paste; char separator; PImpl(); }; TableView::PImpl::PImpl() { allow_paste = false; separator = '\t'; } TableView::TableView(QWidget *parent) : QTableView(parent) , p(new PImpl(), [](PImpl *impl) { delete impl; }) { } char TableView::separator() const { return p->separator; } void TableView::setSeparator(char value) { p->separator = value; } bool TableView::allowPaste() const { return p->allow_paste; } void TableView::setAllowPaste(bool value) { p->allow_paste = value; } void TableView::copy() { // selected items auto selected = selectionModel()->selectedIndexes(); // selection is empty if (selected.empty()) { return; } // data cells, unique rows, unique columns QHash> cells; QList rows; QList cols; // process selected indices { // row/column sets QSet rs; QSet cs; // determine min/max row/columns for (const auto &index : selected) { rs << index.row(); cs << index.column(); cells[index.row()][index.column()] = index.data().toString(); } rows = rs.toList(); cols = cs.toList(); qSort(rows); qSort(cols); } // row/column header models auto rhmodel = verticalHeader()->model(); auto chmodel = horizontalHeader()->model(); // table data QString data; // add column headers if (horizontalHeader()->isVisible()) { if (verticalHeader()->isVisible()) { data.append(p->separator); } for (auto col : cols) { data.append(chmodel->headerData(col, Qt::Horizontal).toString()) .append(p->separator); } data.append('\n'); } // add cell data for (auto row : rows) { // add row header if (verticalHeader()->isVisible()) { data.append(rhmodel->headerData(row, Qt::Vertical).toString()) .append(p->separator); } // add row's cells for (auto col : cols) { // row's data auto &rd = cells[row]; // current cell is valid if (rd.contains(col)) { data.append(rd[col]); } data.append(p->separator); } data.append('\n'); } // store in clipboard QApplication::clipboard()->setText(data); } void TableView::paste() { radix_tagged_line("paste()"); QModelIndex selectedCell = currentIndex(); if (selectedCell.isValid() == false) selectedCell = model()->index(0, 0); // store in clipboard QString text = QApplication::clipboard()->text(); // split into lines QStringList rows = text.split("\n", QString::SkipEmptyParts); for (int r = 0; r < rows.size(); ++r) { if (model()->rowCount() == r) { model()->insertRow(r); } QStringList columns = rows.at(r).split(p->separator); for (int c = 0; c < columns.size(); ++c) { if (model()->columnCount() == c) { model()->insertColumn(c); } model()->setData( model()->index(selectedCell.row() + r, selectedCell.column() + c), columns.at(c)); } } } void TableView::keyPressEvent(QKeyEvent *event) { if (event->matches(QKeySequence::Copy)) { copy(); } else if (event->matches(QKeySequence::Paste) && p->allow_paste) { paste(); } else { QTableView::keyPressEvent(event); } } } // namespace radix