Skip to content

Commit 09320c2

Browse files
committed
Cut to clipboard operation in data browsers
"Cut" copies the cells to clipboard and then deletes the data taking into account a possible NOT NULL constraint in the field to leave the cell empty instead of setting it to NULL. Rowid column is ignored. See issue #2355
1 parent 4bf7adf commit 09320c2

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

src/ExtendedTableWidget.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
259259
QAction* condFormatAction = new QAction(QIcon(":/icons/edit_cond_formats"), tr("Edit Conditional Formats..."), m_contextMenu);
260260

261261
QAction* nullAction = new QAction(QIcon(":/icons/set_to_null"), tr("Set to NULL"), m_contextMenu);
262+
QAction* cutAction = new QAction(QIcon(":/icons/cut"), tr("Cut"), m_contextMenu);
262263
QAction* copyAction = new QAction(QIcon(":/icons/copy"), tr("Copy"), m_contextMenu);
263264
QAction* copyWithHeadersAction = new QAction(QIcon(":/icons/special_copy"), tr("Copy with Headers"), m_contextMenu);
264265
QAction* copyAsSQLAction = new QAction(QIcon(":/icons/sql_copy"), tr("Copy as SQL"), m_contextMenu);
@@ -281,6 +282,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
281282
m_contextMenu->addSeparator();
282283
m_contextMenu->addAction(nullAction);
283284
m_contextMenu->addSeparator();
285+
m_contextMenu->addAction(cutAction);
284286
m_contextMenu->addAction(copyAction);
285287
m_contextMenu->addAction(copyWithHeadersAction);
286288
m_contextMenu->addAction(copyAsSQLAction);
@@ -296,6 +298,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
296298
// This is only for displaying the shortcut in the context menu.
297299
// An entry in keyPressEvent is still needed.
298300
nullAction->setShortcut(QKeySequence(tr("Alt+Del")));
301+
cutAction->setShortcut(QKeySequence::Cut);
299302
copyAction->setShortcut(QKeySequence::Copy);
300303
copyWithHeadersAction->setShortcut(QKeySequence(tr("Ctrl+Shift+C")));
301304
copyAsSQLAction->setShortcut(QKeySequence(tr("Ctrl+Alt+C")));
@@ -325,6 +328,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
325328
// Try to find out whether the current view is editable and (de)activate menu options according to that
326329
bool editable = editTriggers() != QAbstractItemView::NoEditTriggers;
327330
nullAction->setEnabled(enabled && editable);
331+
cutAction->setEnabled(enabled && editable);
328332
pasteAction->setEnabled(enabled && editable);
329333

330334
// Show menu
@@ -371,6 +375,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
371375
connect(copyAction, &QAction::triggered, [&]() {
372376
copy(false, false);
373377
});
378+
connect(cutAction, &QAction::triggered, this, &ExtendedTableWidget::cut);
374379
connect(copyWithHeadersAction, &QAction::triggered, [&]() {
375380
copy(true, false);
376381
});
@@ -719,6 +724,30 @@ void ExtendedTableWidget::paste()
719724
}
720725
}
721726

727+
void ExtendedTableWidget::cut()
728+
{
729+
const QModelIndexList& indices = selectionModel()->selectedIndexes();
730+
SqliteTableModel* m = qobject_cast<SqliteTableModel*>(model());
731+
sqlb::TablePtr currentTable = m->db().getObjectByName<sqlb::Table>(m->currentTableName());
732+
733+
copy(false, false);
734+
735+
// Check if the column in the selection has a NOT NULL constraint, then update with an empty string, else with NULL
736+
if(currentTable) {
737+
for(const QModelIndex& index : indices) {
738+
// Do not process rowid column
739+
if(index.column() != 0) {
740+
size_t indexField = static_cast<size_t>(index.column()-1);
741+
const sqlb::Field& field = currentTable->fields.at(indexField);
742+
const QVariant newValue = field.notnull() ? QVariant("") : QVariant();
743+
// Update aborting in case of any error (to avoid repetitive errors like "Database is locked"
744+
if(!model()->setData(index, newValue))
745+
return;
746+
}
747+
}
748+
}
749+
}
750+
722751
void ExtendedTableWidget::useAsFilter(const QString& filterOperator, bool binary, const QString& operatorSuffix)
723752
{
724753
QModelIndex index = selectionModel()->currentIndex();
@@ -776,6 +805,9 @@ void ExtendedTableWidget::keyPressEvent(QKeyEvent* event)
776805
{
777806
copy(false, false);
778807
return;
808+
} else if(event->matches(QKeySequence::Cut)) {
809+
// Call a custom cut method when Ctrl-X is pressed
810+
cut();
779811
} else if(event->matches(QKeySequence::Paste)) {
780812
// Call a custom paste method when Ctrl-V is pressed
781813
paste();

src/ExtendedTableWidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public slots:
8181
void copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL);
8282
void copy(const bool withHeaders, const bool inSQL);
8383
void paste();
84+
void cut();
8485

8586
void useAsFilter(const QString& filterOperator, bool binary = false, const QString& operatorSuffix = QString());
8687
void duplicateUpperCell();

src/icons/cut.png

648 Bytes
Loading

src/icons/icons.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,6 @@
103103
<file alias="open_data_in_app">application_go.png</file>
104104
<file>monitor_link.png</file>
105105
<file alias="clone_database">server_add.png</file>
106+
<file alias="cut">cut.png</file>
106107
</qresource>
107108
</RCC>

0 commit comments

Comments
 (0)