Check for unsaved content in editor before closing

Check for unsaved content in the editor widget/query input editor before
closing the editor and the main window, still todo: Documentation in
main window/mdi area
This commit is contained in:
Lea Laux 2021-03-01 13:16:28 +01:00 committed by KDV Admin
parent 5bb167a375
commit 6fbfb10d64
3 changed files with 97 additions and 8 deletions

View File

@ -1124,15 +1124,80 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
# Execute the query with the database query executor and the editor execution process. # Execute the query with the database query executor and the editor execution process.
self.execute_current_query(query) self.execute_current_query(query)
def check_for_unsaved_changes(self):
"""
Check for unsaved changes in the query input editor.
"""
# Check for a text in the editor. If the text is an empty string, nothing happened.
if self.query_input_editor.text() == "":
# Return False, because there are no unsaved changes.
return False
# Check for existence the corresponding saved file. At this point, there is a text in the editor.
if self.corresponding_saved_file is None:
# Return True, because the text in the editor is not saved in the file.
return True
# Get the file save status. If the status is not empty, there is an unsaved change.
if self.get_file_save_status_string_for_window_title() != "":
# Return True for an unsaved change.
return True
# If this point is reached, there are no unsaved changes.
return False
def warn_about_unsaved_changes(self):
"""
Warn the user about unsaved changes in the editor. The function is normally called before a closing event is
processed.
"""
# Warn the user about unsaved content and ask how to proceed.
question_message_box = QMessageBox.question(self, "Unsaved Content", "The content in the editor is not saved in"
"a file. Do you still want to close the "
"editor and loose the current content? "
"(Ignore for ignoring these warnings in "
"the future)",
QMessageBox.Yes | QMessageBox.No | QMessageBox.Ignore)
# Proceed normally for a yes.
if question_message_box == QMessageBox.Yes:
return True
# Stop the process for a no.
elif question_message_box == QMessageBox.No:
return False
# Proceed with setting the configuration and normally for an ignore.
elif question_message_box == QMessageBox.Ignore:
global_app_configurator.set_single_configuration("check_unsaved_files", False)
global_app_configurator.save_configuration_data()
return True
def closeEvent(self, a0: QtGui.QCloseEvent) -> None: def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
""" """
Overwrite the close event: If the configuration for opening the previous is set and the corresponding save file Overwrite the close event: If the configuration for opening the previous is set and the corresponding save file
exists, delete it from the file manager, because it does not have to be opened after a restart of the program. exists, delete it from the file manager, because it does not have to be opened after a restart of the program.
a0 is the event, which can be accepted or ignored.
""" """
# Check for an existing file, which should be opened at the next start.
if self.corresponding_saved_file is not None \ if self.corresponding_saved_file is not None \
and global_app_configurator.get_single_configuration("open_previous_files") is True: and global_app_configurator.get_single_configuration("open_previous_files") is True:
global_file_manager.delete_file(self.corresponding_saved_file) global_file_manager.delete_file(self.corresponding_saved_file)
global_file_manager.commit_current_files_to_yaml() global_file_manager.commit_current_files_to_yaml()
self.close() # Check for unsaved changes and the current configuration for processing them.
if self.check_for_unsaved_changes() and global_app_configurator.get_single_configuration("check_unsaved_files")\
is not False:
# Get the user's opinion about the closing process.
close_anyway = self.warn_about_unsaved_changes()
# If the user does not want to close the editor, ignore the event and end the function.
if close_anyway is not True:
a0.ignore()
return
# Accept the close event and close the widget.
a0.accept()

View File

@ -1,7 +1,7 @@
import os import os
import logging import logging
from PyQt5 import QtCore from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import QIcon, QPixmap, QKeySequence from PyQt5.QtGui import QIcon, QPixmap, QKeySequence
from PyQt5.QtWidgets import QMainWindow, QAction, QToolBar, QMessageBox, QMenu, QFileDialog, QShortcut from PyQt5.QtWidgets import QMainWindow, QAction, QToolBar, QMessageBox, QMenu, QFileDialog, QShortcut
from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtCore import Qt, pyqtSlot
@ -159,7 +159,7 @@ class MainWindow(QMainWindow):
alternate_menu=settings_menu) alternate_menu=settings_menu)
# Add an action for leaving the application. # Add an action for leaving the application.
self.add_action_to_menu_bar("Exit", self.close_program) self.add_action_to_menu_bar("Exit", self.close)
# Create a new menu bar point: An editor menu. # Create a new menu bar point: An editor menu.
editor_menu = self.menu_bar.addMenu("Editor") editor_menu = self.menu_bar.addMenu("Editor")
@ -554,9 +554,12 @@ class MainWindow(QMainWindow):
# empty editor with this command. # empty editor with this command.
self.command_history_dialog.get_double_click_command.connect(self.load_empty_editor_with_command) self.command_history_dialog.get_double_click_command.connect(self.load_empty_editor_with_command)
def close_program(self): def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
""" # TODO: Docu
Define a wrapper function for closing the application. if global_app_configurator.get_single_configuration("check_unsaved_files") is not False \
""" and self.mdi_area.check_for_unsaved_editor_tabs() is True:
a0.ignore()
return
a0.accept()
self.close()

View File

@ -304,3 +304,24 @@ class MdiArea(QMdiArea):
# None will be returned, if the search for a currently existing empty editor widget is unsuccessful. # None will be returned, if the search for a currently existing empty editor widget is unsuccessful.
return None return None
def check_for_unsaved_editor_tabs(self):
# TODO: Docu
unsaved_changes = False
editor_widget_list = [sub_window.widget() for sub_window in self.subWindowList()
if isinstance(sub_window.widget(), EditorWidget)]
for editor_widget in editor_widget_list:
if editor_widget.check_for_unsaved_changes() is True:
close_anyway = editor_widget.warn_about_unsaved_changes()
if close_anyway is True:
unsaved_changes = False
else:
unsaved_changes = True
break
return unsaved_changes