changeset 15426:8ae34ffe5c1b

Retain QsciAPIs lexer_api as part of lexer_octave_gui object (bug #37359) This way, it may be deleted upon deconstruction and not cause segmentation fault at startup * file-editor-tab.cc, file-editor-tab.h (file_editor_tab::update_tracked_file): Delete. (file_editor_tab::set_file_name): Rather than clear whole list, just subtract out the old file name then add the new name. (file_editor_tab::load_file): Remove update_tracked_file, it's part of set_file_name. (file_editor_tab::file_has_changed): Remove update_tracked_file, it's part of set_file_name. (file_editor_tab::save_file): Move file close before set_file_name so watcher doesn't notice. Remove inelegant code that solved this by clearing watcher files. * lexer-octave-gui.cc, file-editor-tab.cc (file_editor_tab::update_lexer, lexer_octave_gui::lexer_octave_gui, lexer_octave_gui : public QsciLexer): Move all the lexer preparatory code to the constructor so that lexer_api can be retained as part of object. (lexer_octave_gui::~lexer_octave_gui): Make destructor non-virtual and delete lexer_gui when done. * octave-gui.cc, main-window-h, main-window.cc, file-editor.cc (octave_start_gui, file_editor::construct): Move read_settings from constructor to after construction in octave_start_gui so that no signal occur referencing a partially constructed object. * file-editor.cc (file_editor::construct): Tidy code.
author Daniel J Sebald <daniel.sebald@ieee.org>
date Thu, 20 Sep 2012 04:08:53 -0500
parents 7b69cd89868c
children a42d69d5a36d
files libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/m-editor/file-editor.cc libgui/src/m-editor/lexer-octave-gui.cc libgui/src/m-editor/lexer-octave-gui.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-gui.cc
diffstat 8 files changed, 47 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc
+++ b/libgui/src/m-editor/file-editor-tab.cc
@@ -145,9 +145,15 @@
 void
 file_editor_tab::set_file_name (const QString& fileName)
 {
+  // update tracked file
+  QStringList trackedFiles = _file_system_watcher.files ();
+  if (!trackedFiles.isEmpty ())
+    _file_system_watcher.removePath (_file_name);
+  _file_system_watcher.addPath (fileName);
   _file_name = fileName;
+
+  // update lexer after _file_name change
   update_lexer ();
-  update_tracked_file ();
 }
 
 void
@@ -188,31 +194,6 @@
   if (_file_name.endsWith (".m") || _file_name.endsWith (".M"))
     {
       lexer = new lexer_octave_gui ();
-
-      // The API info that is used for auto completion
-      // TODO: Where to store a file with API info (raw or prepared?)?
-      // TODO: Also provide infos on octave-forge functions?
-      // TODO: Also provide infos on function parameters?
-      // By now, use the keywords-list from syntax highlighting
-
-      QsciAPIs *lexer_api = new QsciAPIs (lexer);
-
-      QString keyword;
-      QStringList keywordList;
-
-      // get whole string with all keywords
-      keyword = lexer->keywords (1);
-      // split into single strings
-      keywordList = keyword.split (QRegExp ("\\s+"));
-
-      int i;
-      for (i = 0; i < keywordList.size (); i++)
-        {
-          // add single strings to the API
-          lexer_api->add (keywordList.at (i));
-        }
-      // prepare API info ... this make take some time
-      lexer_api->prepare ();
     }
   else if (_file_name.endsWith (".c")
            || _file_name.endsWith (".cc")
@@ -365,24 +346,13 @@
   emit editor_state_changed ();
 }
 
-void
-file_editor_tab::update_tracked_file ()
-{
-  QStringList trackedFiles = _file_system_watcher.files ();
-  if (!trackedFiles.isEmpty ())
-    _file_system_watcher.removePaths (trackedFiles);
-
-  if (_file_name != UNNAMED_FILE)
-    _file_system_watcher.addPath (_file_name);
-}
-
 int
 file_editor_tab::check_file_modified (const QString& msg, int cancelButton)
 {
   int decision = QMessageBox::Yes;
   if (_edit_area->isModified ())
     {
-      // file is modified but not saved, aks user what to do
+      // file is modified but not saved, ask user what to do
       decision = QMessageBox::warning (this,
                                        msg,
                                        tr ("The file %1\n"
@@ -590,9 +560,6 @@
   QApplication::restoreOverrideCursor ();
 
   set_file_name (fileName);
-  update_tracked_file ();
-
-
   update_window_title (false); // window title (no modification)
   _edit_area->setModified (false); // loaded file is not modified yet
 
@@ -627,10 +594,6 @@
       return save_file_as();
     }
 
-  QStringList watched_files = _file_system_watcher.files();
-  if (!watched_files.isEmpty ())
-    _file_system_watcher.removePaths(watched_files);
-
   // open the file for writing
   QFile file (saveFileName);
   if (!file.open (QFile::WriteOnly))
@@ -638,7 +601,6 @@
       QMessageBox::warning (this, tr ("Octave Editor"),
                             tr ("Could not open file %1 for write:\n%2.").
                             arg (saveFileName).arg (file.errorString ()));
-      _file_system_watcher.addPaths (watched_files);
       return false;
     }
 
@@ -647,17 +609,15 @@
   QApplication::setOverrideCursor (Qt::WaitCursor);
   out << _edit_area->text ();
   QApplication::restoreOverrideCursor ();
+  file.close();
 
-  // save file name for later use
-  _file_name = saveFileName;
+  // save file name after closing file otherwise tracker will notice file change
+  set_file_name (saveFileName);
   // set the window title to actual file name (not modified)
   update_window_title (false);
   // files is save -> not modified
   _edit_area->setModified (false);
-  file.close();
 
-  if (!watched_files.isEmpty ())
-    _file_system_watcher.addPaths (watched_files);
   return true;
 }
 
@@ -760,7 +720,6 @@
               set_file_name (UNNAMED_FILE);
               update_window_title (true); // window title (no modification)
               set_modified (true);
-              update_tracked_file ();
             }
         }
       else
--- a/libgui/src/m-editor/file-editor-tab.h
+++ b/libgui/src/m-editor/file-editor-tab.h
@@ -100,7 +100,6 @@
   void request_add_breakpoint (int line);
   void request_remove_breakpoint (int line);
 
-  void update_tracked_file ();
   int check_file_modified (const QString& msg, int cancelButton);
   void do_comment_selected_text (bool comment);
 
--- a/libgui/src/m-editor/file-editor.cc
+++ b/libgui/src/m-editor/file-editor.cc
@@ -594,8 +594,8 @@
     {
       QStringList sessionFileNames = settings->value("editor/savedSessionTabs", QStringList()).toStringList ();
 
-      for (int n=0;n<sessionFileNames.count();++n)
-        request_open_file(sessionFileNames.at(n), true);
+      for (int n=0; n < sessionFileNames.count (); ++n)
+        request_open_file (sessionFileNames.at (n), true);
     }
 }
 
--- a/libgui/src/m-editor/lexer-octave-gui.cc
+++ b/libgui/src/m-editor/lexer-octave-gui.cc
@@ -34,10 +34,37 @@
 lexer_octave_gui::lexer_octave_gui (QObject *p)
   : QsciLexer (p)
 {
+  // The API info that is used for auto completion
+  // TODO: Where to store a file with API info (raw or prepared?)?
+  // TODO: Also provide infos on octave-forge functions?
+  // TODO: Also provide infos on function parameters?
+  // By now, use the keywords-list from syntax highlighting
+
+  QString keyword;
+  QStringList keywordList;
+
+  // get whole string with all keywords
+  keyword = this->keywords (1);
+  // split into single strings
+  keywordList = keyword.split (QRegExp ("\\s+"));
+
+  lexer_api = new QsciAPIs (this);
+  if (lexer_api)
+    {
+      for (int i = 0; i < keywordList.size (); i++)
+        {
+          // add single strings to the API
+          lexer_api->add (keywordList.at (i));
+        }
+      // prepare API info ... this may take some time
+      lexer_api->prepare ();
+    }
 }
 
 lexer_octave_gui::~lexer_octave_gui()
 {
+  if (lexer_api)
+    delete lexer_api;
 }
 
 const char *lexer_octave_gui::language() const
--- a/libgui/src/m-editor/lexer-octave-gui.h
+++ b/libgui/src/m-editor/lexer-octave-gui.h
@@ -27,7 +27,7 @@
 #include <QObject>
 #include <Qsci/qsciglobal.h>
 #include <Qsci/qscilexer.h>
-
+#include <Qsci/qsciapis.h>
 
 class lexer_octave_gui : public QsciLexer
 {
@@ -49,7 +49,7 @@
     };
 
   lexer_octave_gui (QObject *parent = 0);
-  virtual ~lexer_octave_gui ();
+  ~lexer_octave_gui ();
   const char *language () const;
   const char *lexer () const;
   QColor defaultColor (int style) const;
@@ -60,6 +60,7 @@
 private:
   lexer_octave_gui (const lexer_octave_gui &);
   lexer_octave_gui &operator= (const lexer_octave_gui &);
+  QsciAPIs *lexer_api;
 };
 
 #endif
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -860,7 +860,6 @@
   addDockWidget (Qt::BottomDockWidgetArea, _terminal_dock_widget);
   addDockWidget (Qt::RightDockWidgetArea, _documentation_dock_widget);
   setStatusBar (_status_bar);
-  read_settings ();
 
   _octave_qt_event_listener = new octave_qt_event_listener ();
   octave_link::register_event_listener (_octave_qt_event_listener);
--- a/libgui/src/main-window.h
+++ b/libgui/src/main-window.h
@@ -114,10 +114,11 @@
   void debug_step_out ();
   void debug_quit ();
 
+  void read_settings ();
+  void write_settings ();
+
 protected:
   void closeEvent (QCloseEvent * closeEvent);
-  void read_settings ();
-  void write_settings ();
 
 private:
   void construct ();
--- a/libgui/src/octave-gui.cc
+++ b/libgui/src/octave-gui.cc
@@ -110,6 +110,7 @@
           resource_manager::update_network_settings ();
 
           main_window w;
+          w.read_settings ();  // Get the widget settings after construction and before showing
           w.show ();
           w.focus_command_window ();