diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 9fb102461..6263fb1dc 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -1469,6 +1469,7 @@ void MainWindow::dbState(bool dirty)
{
ui->fileSaveAction->setEnabled(dirty);
ui->fileRevertAction->setEnabled(dirty);
+ ui->undoAction->setEnabled(dirty);
// Unfortunately, sqlite does not allow to backup the DB while there are pending savepoints,
// so we cannot "Save As" when the DB is dirty.
ui->fileSaveAsAction->setEnabled(!dirty);
@@ -1498,6 +1499,14 @@ void MainWindow::fileRevert()
}
}
+void MainWindow::undo()
+{
+ if (db.isOpen()) {
+ db.revertToSavepoint("DB4S_UNDO");
+ refreshTableBrowsers();
+ }
+}
+
void MainWindow::exportDatabaseToSQL()
{
QString current_table;
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 9529631d0..34746cfe1 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -187,6 +187,7 @@ private slots:
void exportTableToJson();
void fileSave();
void fileRevert();
+ void undo();
void exportDatabaseToSQL();
void importDatabaseFromSQL();
void openRecentFile();
diff --git a/src/MainWindow.ui b/src/MainWindow.ui
index ec785be44..8c7b6f81c 100644
--- a/src/MainWindow.ui
+++ b/src/MainWindow.ui
@@ -183,8 +183,8 @@ You can drag SQL statements from an object row and drop them into other applicat
00
- 673
- 544
+ 640
+ 526
@@ -753,7 +753,7 @@ You can drag SQL statements from an object row and drop them into other applicat
001037
- 23
+ 22
@@ -792,6 +792,7 @@ You can drag SQL statements from an object row and drop them into other applicat
+
@@ -882,6 +883,7 @@ You can drag SQL statements from an object row and drop them into other applicat
+
@@ -1254,6 +1256,30 @@ You can drag SQL statements from the Schema column and drop them into the SQL ed
QAction::NoRole
+
+
+ false
+
+
+
+ :/icons/undo.svg:/icons/undo.svg
+
+
+ &Undo
+
+
+ Undo last change to a cell in the browser
+
+
+ Undo last change to a cell in the browser
+
+
+ This action is used to undo the last change performed to a cell in the database browser. Redoing is not possible.
+
+
+ QAction::NoRole
+
+ false
@@ -2530,6 +2556,22 @@ You can drag SQL statements from the Schema column and drop them into the SQL ed
+
+ undoAction
+ triggered()
+ MainWindow
+ undo()
+
+
+ -1
+ -1
+
+
+ 399
+ 299
+
+
+ fileSaveActiontriggered()
@@ -3903,6 +3945,7 @@ You can drag SQL statements from the Schema column and drop them into the SQL ed
importTableFromCSV()exportTableToCSV()fileRevert()
+ undo()fileSave()deleteIndex()createIndex()
diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc
index 96383cd9d..4629144ba 100644
--- a/src/icons/icons.qrc
+++ b/src/icons/icons.qrc
@@ -104,5 +104,6 @@
text_underlined.svgtextfield_delete.svgwrench.svg
+ undo.svg
diff --git a/src/icons/undo.svg b/src/icons/undo.svg
new file mode 100644
index 000000000..cae4034b8
--- /dev/null
+++ b/src/icons/undo.svg
@@ -0,0 +1,29 @@
+
+
+
diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp
index e7539a903..37f1e6fe3 100644
--- a/src/sqlitedb.cpp
+++ b/src/sqlitedb.cpp
@@ -564,7 +564,7 @@ void DBBrowserDB::getSqliteVersion(QString& sqlite, QString& sqlcipher)
#endif
}
-bool DBBrowserDB::setSavepoint(const std::string& pointname)
+bool DBBrowserDB::setSavepoint(const std::string& pointname, bool unique)
{
if(!isOpen())
return false;
@@ -572,7 +572,7 @@ bool DBBrowserDB::setSavepoint(const std::string& pointname)
qWarning() << "setSavepoint: not done. DB is read-only";
return false;
}
- if(contains(savepointList, pointname))
+ if(unique && contains(savepointList, pointname))
return true;
executeSQL("SAVEPOINT " + sqlb::escapeIdentifier(pointname) + ";", false, true);
diff --git a/src/sqlitedb.h b/src/sqlitedb.h
index aa7cb4fa7..8bf2bfab1 100644
--- a/src/sqlitedb.h
+++ b/src/sqlitedb.h
@@ -123,7 +123,7 @@ class DBBrowserDB : public QObject
**/
db_pointer_type get (const QString& user, bool force_wait = false);
- bool setSavepoint(const std::string& pointname = "RESTOREPOINT");
+ bool setSavepoint(const std::string& pointname = "RESTOREPOINT", bool unique = true);
bool releaseSavepoint(const std::string& pointname = "RESTOREPOINT");
bool revertToSavepoint(const std::string& pointname = "RESTOREPOINT");
bool releaseAllSavepoints();
diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp
index 31dd3f216..530484327 100644
--- a/src/sqlitetablemodel.cpp
+++ b/src/sqlitetablemodel.cpp
@@ -473,6 +473,8 @@ bool SqliteTableModel::setTypedData(const QModelIndex& index, bool isBlob, const
return false;
}
+ m_db.setSavepoint("DB4S_UNDO", false);
+
if(index.isValid() && role == Qt::EditRole)
{
std::unique_lock lock(m_mutexDataCache);