changeset 28364:44f2d73df4b3

remove trailing spaces without replacing full editor text (bug #58417) * file-editor-tab.cc (eol_string): move this to octave_qscintilla; (do_save_file): use new method octave_qscintilla::replace_all for removing trailing spaces instead of reading full text, do the replacements and reset the new text to the editor area; * file-editor-tab.h: moved eol_string to octave_qscintilla * octave-qscintilla.cc (eol_string): moved her from file_editor_tab; (replace_all): replace all occurrances of a string by another string and restore old cursor position taking possible changed line lengths into consideration * octave-qscintilla.h: moved eol_string here, new method replace_all
author Torsten Lilge <ttl-octave@mailbox.org>
date Sun, 24 May 2020 22:45:29 +0200
parents abbab3ed2a5f
children 2969b94cac9f
files libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/m-editor/octave-qscintilla.cc libgui/src/m-editor/octave-qscintilla.h
diffstat 4 files changed, 63 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc	Thu May 21 17:37:40 2020 +0200
+++ b/libgui/src/m-editor/file-editor-tab.cc	Sun May 24 22:45:29 2020 +0200
@@ -2007,22 +2007,6 @@
     return eol_mode;
   }
 
-  QString file_editor_tab::eol_string (void)
-  {
-    switch (m_edit_area->eolMode ())
-      {
-      case QsciScintilla::EolWindows:
-        return ("\r\n");
-      case QsciScintilla::EolMac:
-        return ("\r");
-      case QsciScintilla::EolUnix:
-        return ("\n");
-      }
-
-    // Last resort, if the above goes wrong (should never happen)
-    return ("\r\n");
-  }
-
   void file_editor_tab::update_eol_indicator (void)
   {
     switch (m_edit_area->eolMode ())
@@ -2293,25 +2277,7 @@
     gui_settings *settings = rmgr.get_settings ();
 
     if (settings->value (ed_rm_trailing_spaces).toBool ())
-      {
-        int line, col;
-        m_edit_area->getCursorPosition (&line, &col);
-        const int vscroll_pos = m_edit_area->verticalScrollBar()->value();
-
-        QString eol = eol_string ();
-        QString edit_text = m_edit_area->text ();
-
-        edit_text.replace (QRegExp ("[\\t ]+" + eol), eol);  // All lines
-        long int idx = edit_text.lastIndexOf (QRegExp ("[^\\t^ ]"));
-        edit_text.chop (edit_text.length () - idx - 1); // Last line
-
-        m_edit_area->setText (edit_text);
-        const int col_max = m_edit_area->text (line).length () - 1;
-        if (col_max < col)
-          col = col_max;
-        m_edit_area->setCursorPosition (line, col);
-        m_edit_area->verticalScrollBar()->setValue(vscroll_pos);
-      }
+      m_edit_area->replace_all ("[ \\t]+$", "", true, false, false);
 
     // Save the file
     out.setCodec (codec);
@@ -2321,7 +2287,7 @@
     out << m_edit_area->text ();
     if (settings->value (ed_force_newline).toBool ()
         && m_edit_area->text ().length ())
-      out << eol_string ();   // Add newline if desired
+      out << m_edit_area->eol_string ();   // Add newline if desired
 
     out.flush ();
     QApplication::restoreOverrideCursor ();
--- a/libgui/src/m-editor/file-editor-tab.h	Thu May 21 17:37:40 2020 +0200
+++ b/libgui/src/m-editor/file-editor-tab.h	Sun May 24 22:45:29 2020 +0200
@@ -295,7 +295,6 @@
     QString get_function_name (void);
 
     QsciScintilla::EolMode detect_eol_mode (void);
-    QString eol_string (void);
     void update_eol_indicator (void);
 
     octave_qscintilla *m_edit_area;
--- a/libgui/src/m-editor/octave-qscintilla.cc	Thu May 21 17:37:40 2020 +0200
+++ b/libgui/src/m-editor/octave-qscintilla.cc	Sun May 24 22:45:29 2020 +0200
@@ -381,6 +381,22 @@
     markerDeleteAll (marker::selection);
   }
 
+  QString octave_qscintilla::eol_string (void)
+  {
+    switch (eolMode ())
+      {
+      case QsciScintilla::EolWindows:
+        return ("\r\n");
+      case QsciScintilla::EolMac:
+        return ("\r");
+      case QsciScintilla::EolUnix:
+        return ("\n");
+      }
+
+    // Last resort, if the above goes wrong (should never happen)
+    return ("\r\n");
+  }
+
   // Function returning the true cursor position where the tab length
   // is taken into account.
   void octave_qscintilla::get_current_position (int *pos, int *line, int *col)
@@ -1062,6 +1078,47 @@
     QToolTip::showText (global_pos, msg);
   }
 
+  void octave_qscintilla::replace_all (const QString& o_str, const QString& n_str,
+                                       bool re, bool cs, bool wo)
+  {
+    // get the resulting cursor position
+    int pos, line, col, nline, ncol;
+    get_current_position (&pos, &line, &col);
+
+    // remember first visible line for restoring the view afterwards
+    int first_line = firstVisibleLine ();
+
+    // search for first occurrence of the detected word
+    bool find_result_available = findFirst (o_str, re, cs, wo,
+                                            false, true, 0, 0);
+    // replace and find more occurrences in a loop
+    beginUndoAction ();
+    while (find_result_available)
+      {
+        // findNext doesn't work properly if the length of the replacement
+        // text is different from the original
+        replace (n_str);
+        get_current_position (&pos, &nline, &ncol);
+
+        find_result_available = findFirst (o_str, re, cs, wo,
+                                           false, true, nline, ncol);
+      }
+    endUndoAction ();
+
+      // restore the visible area
+      setFirstVisibleLine (first_line);
+
+      // fix cursor column if outside of new line length
+      int eol_len = eol_string ().length ();
+      if (line == lines () - 1)
+        eol_len = 0;
+      const int col_max = text (line).length () - eol_len;
+      if (col_max < col)
+        col = col_max;
+
+      setCursorPosition (line, col);
+  }
+
   void octave_qscintilla::keyPressEvent (QKeyEvent *key_event)
   {
     if (m_selection.isEmpty ())
--- a/libgui/src/m-editor/octave-qscintilla.h	Thu May 21 17:37:40 2020 +0200
+++ b/libgui/src/m-editor/octave-qscintilla.h	Sun May 24 22:45:29 2020 +0200
@@ -65,6 +65,7 @@
     void get_global_textcursor_pos (QPoint *global_pos, QPoint *local_pos);
     bool get_actual_word (void);
     void clear_selection_markers (void);
+    QString eol_string (void);
     void get_current_position (int *pos, int *line, int *col);
     QStringList comment_string (bool comment = true);
     int get_style (int pos = -1);
@@ -80,6 +81,9 @@
 
     void set_selection_marker_color (const QColor& c);
 
+    void replace_all (const QString& o_str, const QString& n_str,
+                      bool re, bool cs, bool wo);
+
   signals:
 
     void execute_command_in_terminal_signal (const QString&);