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:
		@@ -1124,15 +1124,80 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
 | 
			
		||||
        # Execute the query with the database query executor and the editor execution process.
 | 
			
		||||
        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:
 | 
			
		||||
        """
 | 
			
		||||
        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.
 | 
			
		||||
        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 \
 | 
			
		||||
                and global_app_configurator.get_single_configuration("open_previous_files") is True:
 | 
			
		||||
            global_file_manager.delete_file(self.corresponding_saved_file)
 | 
			
		||||
            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()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import os
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from PyQt5 import QtCore
 | 
			
		||||
from PyQt5 import QtCore, QtGui
 | 
			
		||||
from PyQt5.QtGui import QIcon, QPixmap, QKeySequence
 | 
			
		||||
from PyQt5.QtWidgets import QMainWindow, QAction, QToolBar, QMessageBox, QMenu, QFileDialog, QShortcut
 | 
			
		||||
from PyQt5.QtCore import Qt, pyqtSlot
 | 
			
		||||
@@ -159,7 +159,7 @@ class MainWindow(QMainWindow):
 | 
			
		||||
                                    alternate_menu=settings_menu)
 | 
			
		||||
 | 
			
		||||
        # 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.
 | 
			
		||||
        editor_menu = self.menu_bar.addMenu("Editor")
 | 
			
		||||
@@ -554,9 +554,12 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        # empty editor with this command.
 | 
			
		||||
        self.command_history_dialog.get_double_click_command.connect(self.load_empty_editor_with_command)
 | 
			
		||||
 | 
			
		||||
    def close_program(self):
 | 
			
		||||
        """
 | 
			
		||||
        Define a wrapper function for closing the application.
 | 
			
		||||
        """
 | 
			
		||||
    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
 | 
			
		||||
        # TODO: Docu
 | 
			
		||||
        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()
 | 
			
		||||
 
 | 
			
		||||
@@ -304,3 +304,24 @@ class MdiArea(QMdiArea):
 | 
			
		||||
 | 
			
		||||
        # None will be returned, if the search for a currently existing empty editor widget is unsuccessful.
 | 
			
		||||
        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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user