Skip to content

Commit fbe69b0

Browse files
committed
Add menu items for inserting and removing table rows
1 parent 7959b7d commit fbe69b0

4 files changed

Lines changed: 130 additions & 28 deletions

File tree

gui/source/pre/models/TableModel.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,59 @@ void TableModel::fetchMore(const QModelIndex& parent) {
101101
endInsertRows();
102102
}
103103

104+
bool TableModel::insertRows(int row, int count, const QModelIndex& parent) {
105+
beginInsertRows(parent, row, row + count - 1);
106+
107+
// Create a new map where all entries below "row" are shifted down by "count" rows
108+
QMap<QModelIndex, double> newEntries;
109+
for(auto [oldIndex, oldValue]: entries.asKeyValueRange()) {
110+
if(oldIndex.row() < row) {
111+
// Entry stays in place
112+
newEntries.insert(oldIndex, oldValue);
113+
}
114+
else {
115+
// Entry gets shifted
116+
QModelIndex newIndex = index(oldIndex.row() + count, oldIndex.column());
117+
newEntries.insert(newIndex, oldValue);
118+
}
119+
}
120+
121+
// Assign shifted entries
122+
entries = newEntries;
123+
124+
endInsertRows();
125+
return true;
126+
}
127+
128+
bool TableModel::removeRows(int row, int count, const QModelIndex& parent) {
129+
beginRemoveRows(parent, row, row + count - 1);
130+
131+
// Create a new map where all entries below "row" are shifted up by "count" rows
132+
QMap<QModelIndex, double> newEntries;
133+
for(auto [oldIndex, oldValue]: entries.asKeyValueRange()) {
134+
if(oldIndex.row() < row) {
135+
// Entry stays in place
136+
newEntries.insert(oldIndex, oldValue);
137+
}
138+
else if(oldIndex.row() < row + count) {
139+
// Entry is deleted
140+
}
141+
else {
142+
// Entry gets shifted
143+
QModelIndex newIndex = index(oldIndex.row() - count, oldIndex.column());
144+
newEntries.insert(newIndex, oldValue);
145+
}
146+
}
147+
148+
// Assign shifted entries
149+
entries = newEntries;
150+
151+
endRemoveRows();
152+
emit contentModified();
153+
154+
return true;
155+
}
156+
104157
Points TableModel::getPoints() const {
105158
Points data;
106159
data.reserve(2*entries.size()); // Upper bound on number of valid data points

gui/source/pre/models/TableModel.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class TableModel: public QAbstractTableModel {
2323
bool canFetchMore(const QModelIndex& parent) const override;
2424
void fetchMore(const QModelIndex& parent) override;
2525

26+
bool insertRows(int row, int count, const QModelIndex& parent) override;
27+
bool removeRows(int row, int count, const QModelIndex& parent) override;
28+
2629
signals:
2730
void contentModified();
2831

gui/source/pre/views/primitive/TableView.cpp

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,39 +57,82 @@ TableView::TableView() {
5757
this->verticalHeader()->sectionResizeMode(QHeaderView::Fixed);
5858
this->verticalHeader()->hide();
5959

60-
auto action_cut = new QAction("&Cut", this);
61-
QObject::connect(action_cut, &QAction::triggered, this, &TableView::cutSelection);
62-
action_cut->setShortcuts(QKeySequence::Cut);
63-
this->addAction(action_cut);
64-
65-
auto action_copy = new QAction("Cop&y", this);
66-
QObject::connect(action_copy, &QAction::triggered, this, &TableView::copySelection);
67-
action_copy->setShortcuts(QKeySequence::Copy);
68-
this->addAction(action_copy);
69-
70-
auto action_paste = new QAction("&Paste", this);
71-
QObject::connect(action_paste, &QAction::triggered, this, &TableView::pasteToSelection);
72-
action_paste->setShortcuts(QKeySequence::Paste);
73-
this->addAction(action_paste);
74-
75-
auto action_delete = new QAction("&Delete", this);
76-
QObject::connect(action_delete, &QAction::triggered, this, &TableView::deleteSelection);
77-
action_delete->setShortcut(QKeySequence::Delete);
78-
action_delete->setShortcutContext(Qt::WidgetShortcut);
79-
this->addAction(action_delete);
60+
auto actionInsertAbove = new QAction("Insert above", this);
61+
QObject::connect(actionInsertAbove, &QAction::triggered, this, &TableView::insertAbove);
62+
this->addAction(actionInsertAbove);
63+
64+
auto actionInsertBelow = new QAction("Insert below", this);
65+
QObject::connect(actionInsertBelow, &QAction::triggered, this, &TableView::insertBelow);
66+
this->addAction(actionInsertBelow);
67+
68+
auto actionRemoveRow = new QAction("Remove rows", this);
69+
QObject::connect(actionRemoveRow, &QAction::triggered, this, &TableView::removeRows);
70+
this->addAction(actionRemoveRow);
71+
72+
auto actionCut = new QAction("&Cut", this);
73+
QObject::connect(actionCut, &QAction::triggered, this, &TableView::cutSelection);
74+
actionCut->setShortcuts(QKeySequence::Cut);
75+
this->addAction(actionCut);
76+
77+
auto actionCopy = new QAction("Cop&y", this);
78+
QObject::connect(actionCopy, &QAction::triggered, this, &TableView::copySelection);
79+
actionCopy->setShortcuts(QKeySequence::Copy);
80+
this->addAction(actionCopy);
81+
82+
auto actionPaste = new QAction("&Paste", this);
83+
QObject::connect(actionPaste, &QAction::triggered, this, &TableView::pasteToSelection);
84+
actionPaste->setShortcuts(QKeySequence::Paste);
85+
this->addAction(actionPaste);
86+
87+
auto actionDelete = new QAction("&Delete", this);
88+
QObject::connect(actionDelete, &QAction::triggered, this, &TableView::deleteSelection);
89+
actionDelete->setShortcut(QKeySequence::Delete);
90+
actionDelete->setShortcutContext(Qt::WidgetShortcut);
91+
this->addAction(actionDelete);
8092

8193
this->setContextMenuPolicy(Qt::CustomContextMenu);
82-
QObject::connect(this, &TableView::customContextMenuRequested, [=](const QPoint& pos){
94+
QObject::connect(this, &TableView::customContextMenuRequested, [=](const QPoint& pos) {
8395
QMenu menu(this);
84-
menu.addAction(action_cut);
85-
menu.addAction(action_copy);
86-
menu.addAction(action_paste);
96+
menu.addAction(actionInsertAbove);
97+
menu.addAction(actionInsertBelow);
98+
menu.addAction(actionRemoveRow);
8799
menu.addSeparator();
88-
menu.addAction(action_delete);
100+
menu.addAction(actionCut);
101+
menu.addAction(actionCopy);
102+
menu.addAction(actionPaste);
103+
menu.addSeparator();
104+
menu.addAction(actionDelete);
89105
menu.exec(this->viewport()->mapToGlobal(pos));
90106
});
91107
}
92108

109+
void TableView::insertAbove() {
110+
QModelIndex index = selectedIndexes().at(0);
111+
model()->insertRow(index.row());
112+
}
113+
114+
void TableView::insertBelow() {
115+
QModelIndex index = selectedIndexes().at(0);
116+
model()->insertRow(index.row() + 1);
117+
}
118+
119+
void TableView::removeRows() {
120+
// Collect all selected rows
121+
QSet<int> rows;
122+
for (const QModelIndex& index: selectedIndexes()) {
123+
rows.insert(index.row());
124+
}
125+
126+
// Convert to list and sort descending
127+
QList<int> rowList = rows.values();
128+
std::sort(rowList.begin(), rowList.end(), std::greater<int>());
129+
130+
// Remove rows from bottom to top
131+
for(int row: rowList) {
132+
model()->removeRow(row);
133+
}
134+
}
135+
93136
void TableView::cutSelection() {
94137
copySelection();
95138
deleteSelection();
@@ -114,9 +157,9 @@ void TableView::pasteToSelection() {
114157
QString text = QApplication::clipboard()->text();
115158
QStringList rowContents = text.split("\n", Qt::SkipEmptyParts);
116159

117-
QModelIndex initIndex = selectedIndexes().at(0);
118-
int i0 = initIndex.row();
119-
int j0 = initIndex.column();
160+
QModelIndex index = selectedIndexes().at(0);
161+
int i0 = index.row();
162+
int j0 = index.column();
120163

121164
for(int i = 0; i < rowContents.size(); ++i) {
122165
QStringList columnContents = rowContents.at(i).split("\t");

gui/source/pre/views/primitive/TableView.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class TableView: public QTableView {
2929
TableView();
3030

3131
private:
32+
void insertAbove();
33+
void insertBelow();
34+
void removeRows();
3235
void cutSelection();
3336
void copySelection();
3437
void pasteToSelection();

0 commit comments

Comments
 (0)