changeset 30553:2dc31151ca27

make saving editor files more robust against failures while writing * file-editor-tab.cc: include QSaveFile, (do_save_file): use QSaveFile instead of QFile for saving the file via a temporary file, finish writing with commit() and throw error if commit() fails
author Torsten Lilge <ttl-octave@mailbox.org>
date Sat, 25 Dec 2021 17:32:14 +0100
parents 752b71dc41f8
children 72cea722ca21
files libgui/src/m-editor/file-editor-tab.cc
diffstat 1 files changed, 44 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc	Sat Dec 25 16:11:17 2021 +0100
+++ b/libgui/src/m-editor/file-editor-tab.cc	Sat Dec 25 17:32:14 2021 +0100
@@ -45,6 +45,7 @@
 #include <QPrintDialog>
 #include <QPushButton>
 #include <QScrollBar>
+#include <QSaveFile>
 #include <QStyle>
 #include <QTextBlock>
 #include <QTextCodec>
@@ -2183,7 +2184,7 @@
                                       bool remove_on_success,
                                       bool restore_breakpoints)
   {
-    QFile file (file_to_save);
+    QSaveFile file (file_to_save);
 
     // stop watching file
     QStringList trackedFiles = m_file_system_watcher.files ();
@@ -2239,36 +2240,50 @@
 
     out.flush ();
     QApplication::restoreOverrideCursor ();
-    file.flush ();
-    file.close ();
-
-    // file exists now
-    QFileInfo file_info = QFileInfo (file);
-    QString full_file_to_save = file_info.canonicalFilePath ();
-
-    // save filename after closing file as set_file_name starts watching again
-    set_file_name (full_file_to_save);   // make absolute
-
-    // set the window title to actual filename (not modified)
-    update_window_title (false);
-
-    // file is save -> not modified, update encoding in statusbar
-    m_edit_area->setModified (false);
-    m_enc_indicator->setText (m_encoding);
-
-    emit tab_ready_to_close ();
-
-    if (remove_on_success)
+
+    // Finish writing by committing the changes to disk,
+    // where nothing is done when an error occurred while writing above
+    bool writing_ok = file.commit ();
+
+    if (writing_ok)
       {
-        emit tab_remove_request ();
-        return;  // Don't touch member variables after removal
+        // Writing was successful: file exists now
+        QFileInfo file_info = QFileInfo (file.fileName ());
+        QString full_file_to_save = file_info.canonicalFilePath ();
+
+        // save filename after closing file as set_file_name starts watching again
+        set_file_name (full_file_to_save);   // make absolute
+
+        // set the window title to actual filename (not modified)
+        update_window_title (false);
+
+        // file is save -> not modified, update encoding in statusbar
+        m_edit_area->setModified (false);
+        m_enc_indicator->setText (m_encoding);
+
+        emit tab_ready_to_close ();
+
+        if (remove_on_success)
+          {
+            emit tab_remove_request ();
+            return;  // Don't touch member variables after removal
+          }
+
+        // Attempt to restore the breakpoints if that is desired.
+        // This is only allowed if the tab is not closing since changing
+        // breakpoints would reopen the tab in this case.
+        if (restore_breakpoints)
+          check_restore_breakpoints ();
       }
-
-    // Attempt to restore the breakpoints if that is desired.
-    // This is only allowed if the tab is not closing since changing
-    // breakpoints would reopen the tab in this case.
-    if (restore_breakpoints)
-      check_restore_breakpoints ();
+    else
+      {
+        QMessageBox::critical (nullptr,
+                               tr ("Octave Editor"),
+                               tr ("The changes could not be saved to the file\n"
+                                   "%1")
+                                   .arg (file.fileName ())
+                              );
+      }
   }
 
   void file_editor_tab::save_file_as (bool remove_on_success)