Skip to content

Commit bba874c

Browse files
committedMay 6, 2020
prompt before closing SQL editor tabs with unsaved changes (fix #14636)
1 parent 1e0b890 commit bba874c

File tree

3 files changed

+83
-7
lines changed

3 files changed

+83
-7
lines changed
 

‎python/plugins/db_manager/db_manager.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,13 @@ def unregisterAllActions(self):
362362
def close_tab(self, index):
363363
widget = self.tabs.widget(index)
364364
if widget not in [self.info, self.table, self.preview]:
365-
self.tabs.removeTab(index)
366-
widget.deleteLater()
365+
if hasattr(widget, "close"):
366+
if widget.close():
367+
self.tabs.removeTab(index)
368+
widget.deleteLater()
369+
else:
370+
self.tabs.removeTab(index)
371+
widget.deleteLater()
367372

368373
def toolBarOrientation(self):
369374
button_style = Qt.ToolButtonIconOnly

‎python/plugins/db_manager/dlg_sql_layer_window.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,20 @@
2727
from hashlib import md5
2828

2929
from qgis.PyQt.QtCore import Qt, pyqtSignal
30-
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QStyledItemDelegate
31-
from qgis.PyQt.QtGui import QKeySequence, QCursor, QClipboard, QIcon, QStandardItemModel, QStandardItem
30+
from qgis.PyQt.QtWidgets import (QDialog,
31+
QWidget,
32+
QAction,
33+
QApplication,
34+
QStyledItemDelegate,
35+
QMessageBox
36+
)
37+
from qgis.PyQt.QtGui import (QKeySequence,
38+
QCursor,
39+
QClipboard,
40+
QIcon,
41+
QStandardItemModel,
42+
QStandardItem
43+
)
3244
from qgis.PyQt.Qsci import QsciAPIs
3345
from qgis.PyQt.QtXml import QDomDocument
3446

@@ -61,6 +73,7 @@
6173

6274
class DlgSqlLayerWindow(QWidget, Ui_Dialog):
6375
nameChanged = pyqtSignal(str)
76+
hasChanged = False
6477

6578
def __init__(self, iface, layer, parent=None):
6679
QWidget.__init__(self, parent)
@@ -104,6 +117,7 @@ def __init__(self, iface, layer, parent=None):
104117
self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
105118
self.editSql.setMarginVisible(True)
106119
self.initCompleter()
120+
self.editSql.textChanged.connect(lambda: self.setHasChanged(True))
107121

108122
# allow copying results
109123
copyAction = QAction("copy", self)
@@ -542,3 +556,23 @@ def setFilter(self):
542556
if dlg.exec_():
543557
self.filter = dlg.sql()
544558
layer.deleteLater()
559+
560+
def setHasChanged(self, hasChanged):
561+
self.hasChanged = hasChanged
562+
563+
def close(self):
564+
if self.hasChanged:
565+
ret = QMessageBox.question(
566+
self, self.tr('Unsaved Changes?'),
567+
self.tr('There are unsaved changes. Do you want to keep them?'),
568+
QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard, QMessageBox.Cancel)
569+
570+
if ret == QMessageBox.Save:
571+
self.saveAsFilePreset()
572+
return True
573+
elif ret == QMessageBox.Discard:
574+
return True
575+
else:
576+
return False
577+
else:
578+
return True

‎python/plugins/db_manager/dlg_sql_window.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,23 @@
2929
import os
3030

3131
from qgis.PyQt.QtCore import Qt, pyqtSignal, QDir
32-
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QInputDialog, QStyledItemDelegate, QTableWidgetItem, QFileDialog
33-
from qgis.PyQt.QtGui import QKeySequence, QCursor, QClipboard, QIcon, QStandardItemModel, QStandardItem
32+
from qgis.PyQt.QtWidgets import (QDialog,
33+
QWidget,
34+
QAction,
35+
QApplication,
36+
QInputDialog,
37+
QStyledItemDelegate,
38+
QTableWidgetItem,
39+
QFileDialog,
40+
QMessageBox
41+
)
42+
from qgis.PyQt.QtGui import (QKeySequence,
43+
QCursor,
44+
QClipboard,
45+
QIcon,
46+
QStandardItemModel,
47+
QStandardItem
48+
)
3449
from qgis.PyQt.Qsci import QsciAPIs
3550

3651
from qgis.core import (
@@ -94,6 +109,7 @@ def check_comments_in_sql(raw_sql_input):
94109
class DlgSqlWindow(QWidget, Ui_Dialog):
95110
nameChanged = pyqtSignal(str)
96111
QUERY_HISTORY_LIMIT = 20
112+
hasChanged = False
97113

98114
def __init__(self, iface, db, parent=None):
99115
QWidget.__init__(self, parent)
@@ -121,6 +137,7 @@ def __init__(self, iface, db, parent=None):
121137
self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
122138
self.editSql.setMarginVisible(True)
123139
self.initCompleter()
140+
self.editSql.textChanged.connect(lambda: self.setHasChanged(True))
124141

125142
settings = QgsSettings()
126143
self.history = settings.value('DB_Manager/queryHistory/' + self.dbType, {self.connectionName: []})
@@ -325,6 +342,7 @@ def clearSql(self):
325342
self.editSql.clear()
326343
self.editSql.setFocus()
327344
self.filter = ""
345+
self.setHasChanged(True)
328346

329347
def updateUiWhileSqlExecution(self, status):
330348
if status:
@@ -387,7 +405,6 @@ def executeSqlCompleted(self):
387405
self.geomCombo.clear()
388406

389407
def executeSql(self):
390-
391408
sql = self._getExecutableSqlQuery()
392409
if sql == "":
393410
return
@@ -664,3 +681,23 @@ def setFilter(self):
664681
if dlg.exec_():
665682
self.filter = dlg.sql()
666683
layer.deleteLater()
684+
685+
def setHasChanged(self, hasChanged):
686+
self.hasChanged = hasChanged
687+
688+
def close(self):
689+
if self.hasChanged:
690+
ret = QMessageBox.question(
691+
self, self.tr('Unsaved Changes?'),
692+
self.tr('There are unsaved changes. Do you want to keep them?'),
693+
QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard, QMessageBox.Cancel)
694+
695+
if ret == QMessageBox.Save:
696+
self.saveAsFilePreset()
697+
return True
698+
elif ret == QMessageBox.Discard:
699+
return True
700+
else:
701+
return False
702+
else:
703+
return True

0 commit comments

Comments
 (0)
Please sign in to comment.