mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-02-11 06:08:33 -06:00
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
This commit is contained in:
@@ -259,6 +259,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
QAction* condFormatAction = new QAction(QIcon(":/icons/edit_cond_formats"), tr("Edit Conditional Formats..."), m_contextMenu);
|
||||
|
||||
QAction* nullAction = new QAction(QIcon(":/icons/set_to_null"), tr("Set to NULL"), m_contextMenu);
|
||||
QAction* cutAction = new QAction(QIcon(":/icons/cut"), tr("Cut"), m_contextMenu);
|
||||
QAction* copyAction = new QAction(QIcon(":/icons/copy"), tr("Copy"), m_contextMenu);
|
||||
QAction* copyWithHeadersAction = new QAction(QIcon(":/icons/special_copy"), tr("Copy with Headers"), m_contextMenu);
|
||||
QAction* copyAsSQLAction = new QAction(QIcon(":/icons/sql_copy"), tr("Copy as SQL"), m_contextMenu);
|
||||
@@ -281,6 +282,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
m_contextMenu->addSeparator();
|
||||
m_contextMenu->addAction(nullAction);
|
||||
m_contextMenu->addSeparator();
|
||||
m_contextMenu->addAction(cutAction);
|
||||
m_contextMenu->addAction(copyAction);
|
||||
m_contextMenu->addAction(copyWithHeadersAction);
|
||||
m_contextMenu->addAction(copyAsSQLAction);
|
||||
@@ -296,6 +298,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
// This is only for displaying the shortcut in the context menu.
|
||||
// An entry in keyPressEvent is still needed.
|
||||
nullAction->setShortcut(QKeySequence(tr("Alt+Del")));
|
||||
cutAction->setShortcut(QKeySequence::Cut);
|
||||
copyAction->setShortcut(QKeySequence::Copy);
|
||||
copyWithHeadersAction->setShortcut(QKeySequence(tr("Ctrl+Shift+C")));
|
||||
copyAsSQLAction->setShortcut(QKeySequence(tr("Ctrl+Alt+C")));
|
||||
@@ -325,6 +328,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
// Try to find out whether the current view is editable and (de)activate menu options according to that
|
||||
bool editable = editTriggers() != QAbstractItemView::NoEditTriggers;
|
||||
nullAction->setEnabled(enabled && editable);
|
||||
cutAction->setEnabled(enabled && editable);
|
||||
pasteAction->setEnabled(enabled && editable);
|
||||
|
||||
// Show menu
|
||||
@@ -371,6 +375,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
connect(copyAction, &QAction::triggered, [&]() {
|
||||
copy(false, false);
|
||||
});
|
||||
connect(cutAction, &QAction::triggered, this, &ExtendedTableWidget::cut);
|
||||
connect(copyWithHeadersAction, &QAction::triggered, [&]() {
|
||||
copy(true, false);
|
||||
});
|
||||
@@ -719,6 +724,30 @@ void ExtendedTableWidget::paste()
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::cut()
|
||||
{
|
||||
const QModelIndexList& indices = selectionModel()->selectedIndexes();
|
||||
SqliteTableModel* m = qobject_cast<SqliteTableModel*>(model());
|
||||
sqlb::TablePtr currentTable = m->db().getObjectByName<sqlb::Table>(m->currentTableName());
|
||||
|
||||
copy(false, false);
|
||||
|
||||
// Check if the column in the selection has a NOT NULL constraint, then update with an empty string, else with NULL
|
||||
if(currentTable) {
|
||||
for(const QModelIndex& index : indices) {
|
||||
// Do not process rowid column
|
||||
if(index.column() != 0) {
|
||||
size_t indexField = static_cast<size_t>(index.column()-1);
|
||||
const sqlb::Field& field = currentTable->fields.at(indexField);
|
||||
const QVariant newValue = field.notnull() ? QVariant("") : QVariant();
|
||||
// Update aborting in case of any error (to avoid repetitive errors like "Database is locked"
|
||||
if(!model()->setData(index, newValue))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::useAsFilter(const QString& filterOperator, bool binary, const QString& operatorSuffix)
|
||||
{
|
||||
QModelIndex index = selectionModel()->currentIndex();
|
||||
@@ -776,6 +805,9 @@ void ExtendedTableWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
copy(false, false);
|
||||
return;
|
||||
} else if(event->matches(QKeySequence::Cut)) {
|
||||
// Call a custom cut method when Ctrl-X is pressed
|
||||
cut();
|
||||
} else if(event->matches(QKeySequence::Paste)) {
|
||||
// Call a custom paste method when Ctrl-V is pressed
|
||||
paste();
|
||||
|
||||
@@ -81,6 +81,7 @@ private:
|
||||
void copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL);
|
||||
void copy(const bool withHeaders, const bool inSQL);
|
||||
void paste();
|
||||
void cut();
|
||||
|
||||
void useAsFilter(const QString& filterOperator, bool binary = false, const QString& operatorSuffix = QString());
|
||||
void duplicateUpperCell();
|
||||
|
||||
BIN
src/icons/cut.png
Normal file
BIN
src/icons/cut.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 648 B |
@@ -103,5 +103,6 @@
|
||||
<file alias="open_data_in_app">application_go.png</file>
|
||||
<file>monitor_link.png</file>
|
||||
<file alias="clone_database">server_add.png</file>
|
||||
<file alias="cut">cut.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
Reference in New Issue
Block a user