Mercurial > octave
changeset 27133:fbe46901ae62
fix editors search and replace in selection (bug #56405)
* file-editor-tab.cc (handle_double_click): update call to changed method
octave_qscintilla::show_selection_markers
* find-dialog.cc (find_dialog): parent is class octave_qscintilla,
initialize the new class variables for searching in the selection;
(handle_selection_changed): only disable selection checkbox if no text
is selected, but leave check state as it is, remove the conditial
compilation based on HAVE_QSCI_FINDSELECTION;
(find): remove consitional compilation, initialize line and column for
the search start also for selected text, remember start and end of a
possible selection, remove workaround for wrong selection length update,
only use finFirst also for the case with selection, check if search
hit lies within the selection if necessary and stop search if required,
update slection marker for showing the current selected area, remove this
marker and restore real selection if no more occurrance of search text was
found;
(do_replace): update the length of the selection when replacing text;
(replace): remove workaround for buggy selection length update
* find-dialog.h: include octave_qscintilla, parent and _edit_area are
of type octave_qscintilla, new class variable for storing and
handling search in selection as well as selection begin and end
* octave-qscintilla.cc (show_selection_markers): paraemters are now
start line and column as wells as end line and column
* octave-qscintilla.h: new parameters for show_selection_markers
author | Torsten Lilge <ttl-octave@mailbox.org> |
---|---|
date | Sat, 01 Jun 2019 19:30:56 +0200 |
parents | 8ea53aa9ac39 |
children | 8229d4e15a28 |
files | libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/find-dialog.cc libgui/src/m-editor/find-dialog.h libgui/src/m-editor/octave-qscintilla.cc libgui/src/m-editor/octave-qscintilla.h |
diffstat | 5 files changed, 136 insertions(+), 96 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc Sat Jun 01 08:56:51 2019 -0700 +++ b/libgui/src/m-editor/file-editor-tab.cc Sat Jun 01 19:30:56 2019 +0200 @@ -3166,7 +3166,7 @@ // get cursor position after having found an occurrence _edit_area->getCursorPosition (&oline, &ocol); // mark the selection - _edit_area->show_selection_markers (oline, ocol, wlen); + _edit_area->show_selection_markers (oline, ocol-wlen, oline, ocol); // find next occurrence find_result_available = _edit_area->findNext ();
--- a/libgui/src/m-editor/find-dialog.cc Sat Jun 01 08:56:51 2019 -0700 +++ b/libgui/src/m-editor/find-dialog.cc Sat Jun 01 19:30:56 2019 +0200 @@ -80,9 +80,9 @@ namespace octave { - find_dialog::find_dialog (QsciScintilla *edit_area, + find_dialog::find_dialog (octave_qscintilla *edit_area, QList<QAction *> find_actions, QWidget *p) - : QDialog (p) + : QDialog (p), m_in_sel (false), m_sel_beg (-1), m_sel_end (-1) { setWindowTitle (tr ("Find and Replace")); setWindowIcon (QIcon (":/actions/icons/find.png")); @@ -120,14 +120,9 @@ _regex_check_box = new QCheckBox (tr ("Regular E&xpressions")); _backward_check_box = new QCheckBox (tr ("Search &backward")); _search_selection_check_box = new QCheckBox (tr ("Search se&lection")); -#if defined (HAVE_QSCI_FINDSELECTION) _search_selection_check_box->setCheckable (true); if (edit_area) _search_selection_check_box->setEnabled (edit_area->hasSelectedText ()); -#else - _search_selection_check_box->setCheckable (false); - _search_selection_check_box->setEnabled (false); -#endif _edit_area = edit_area; connect (_find_next_button, SIGNAL (clicked ()), @@ -147,12 +142,10 @@ connect (_search_line_edit, SIGNAL (textChanged (QString)), this, SLOT (handle_search_text_changed (QString))); -#if defined (HAVE_QSCI_FINDSELECTION) connect (_edit_area, SIGNAL (copyAvailable (bool)), this, SLOT (handle_selection_changed (bool))); connect (_search_selection_check_box, SIGNAL (stateChanged (int)), this, SLOT (handle_sel_search_changed (int))); -#endif QVBoxLayout *extension_layout = new QVBoxLayout (); extension_layout->setMargin (0); @@ -251,17 +244,12 @@ _find_result_available = false; } -#if defined (HAVE_QSCI_FINDSELECTION) void find_dialog::handle_sel_search_changed (int selected) { _from_start_check_box->setEnabled (! selected); _find_result_available = false; } -#else - void find_dialog::handle_sel_search_changed (int /* selected */) { } -#endif -#if defined (HAVE_QSCI_FINDSELECTION) void find_dialog::handle_selection_changed (bool has_selected) { if (_rep_active) @@ -269,12 +257,7 @@ _search_selection_check_box->setEnabled (has_selected); _find_result_available = false; - if (! has_selected) - _search_selection_check_box->setChecked (false); } -#else - void find_dialog::handle_selection_changed (bool /* has_selected */) { } -#endif // initialize search text with selected text if this is in one single line void find_dialog::init_search_text (void) @@ -311,46 +294,84 @@ if (! _edit_area) return; - int line, col; - line = col = -1; + // line adn col: -1 means search starts at current position + int line = -1, col = -1; + bool do_wrap = _wrap_check_box->isChecked (); bool do_forward = forward; + // Initialize the selection begin and end if it is the first search + if (! _find_result_available) + { + if (_search_selection_check_box->isChecked () + && _edit_area->hasSelectedText ()) + { + int l1, c1, l2, c2; + _edit_area->getSelection (&l1, &c1, &l2, &c2); + + // Store the position of the selection + m_sel_beg = _edit_area->positionFromLineIndex (l1, c1); + m_sel_end = _edit_area->positionFromLineIndex (l2, c2); + m_in_sel = true; + } + else + m_in_sel = false; + } + + // Get the correct line/col for beginning the search if (_rep_all) { + // Replace All if (_rep_all == 1) { - line = 0; - col = 0; - } - do_wrap = false; - // The following line is a workaround for the issue that when replacing - // a text with a new one with different size within the selection, - // the selection is not updated leading to missing or extra replacements. - // This does not happen, when the selection is search backwards - do_forward = ! _search_selection_check_box->isChecked (); - } - else - { - if (_from_start_check_box->isChecked ()) - { - if (do_forward) + // Start at the beginning of file/sel if it is the first try + if (m_in_sel) + _edit_area->lineIndexFromPosition (m_sel_beg, &line, &col); + else { line = 0; col = 0; } + } + do_wrap = false; // Never wrap when replacing all + } + else + { + // Normal search (not replace all): calculate start position of + // search (in file or selection) + if (_from_start_check_box->isChecked () + || (m_in_sel && (! _find_result_available))) + { + // From the beginning or the end of file/sel + if (do_forward) + { + // From the beginning + if (m_in_sel) + _edit_area->lineIndexFromPosition (m_sel_beg, &line, &col); + else + { + line = 0; + col = 0; + } + } else { - line = _edit_area->lines () - 1; - col = _edit_area->text (line).length () - 1; - if (col == -1) - col = 0; + // From the end + if (m_in_sel) + _edit_area->lineIndexFromPosition (m_sel_end, &line, &col); + else + { + line = _edit_area->lines () - 1; + col = _edit_area->text (line).length () - 1; + if (col == -1) + col = 0; + } } } else if (! do_forward) { - // search from position before search characters text length - // if search backward on existing results, + // Start from where the cursor is. Fix QScintilla's cursor + // positioning _edit_area->getCursorPosition (&line,&col); if (_find_result_available && _edit_area->hasSelectedText ()) { @@ -358,54 +379,65 @@ currpos -= (_search_line_edit->text ().length ()); if (currpos < 0) currpos = 0; - _edit_area->lineIndexFromPosition (currpos, &line,&col); + _edit_area->lineIndexFromPosition (currpos, &line, &col); } } } - if (_edit_area->hasSelectedText () - && _search_selection_check_box->isChecked ()) - { -#if defined (HAVE_QSCI_FINDSELECTION) - if (_find_result_available) - _find_result_available = _edit_area->findNext (); - else - _find_result_available - = _edit_area->findFirstInSelection ( - _search_line_edit->text (), - _regex_check_box->isChecked (), - _case_check_box->isChecked (), - _whole_words_check_box->isChecked (), - do_forward, - true + // Do the search + _find_result_available = _edit_area->findFirst ( + _search_line_edit->text (), + _regex_check_box->isChecked (), + _case_check_box->isChecked (), + _whole_words_check_box->isChecked (), + do_wrap, + do_forward, + line,col, + true #if defined (HAVE_QSCI_VERSION_2_6_0) - , true + , true #endif - ); -#endif - } - else + ); + + if (_find_result_available) { - _find_result_available - = _edit_area->findFirst (_search_line_edit->text (), - _regex_check_box->isChecked (), - _case_check_box->isChecked (), - _whole_words_check_box->isChecked (), - do_wrap, - do_forward, - line,col, - true -#if defined (HAVE_QSCI_VERSION_2_6_0) - , true -#endif - ); + // Search successful: reset search-from-start box and check for + // the current selection + _from_start_check_box->setChecked (0); + + if (m_in_sel) + { + _edit_area->getCursorPosition (&line,&col); + int pos = _edit_area->positionFromLineIndex (line, col); + + int l1, c1, l2, c2; + _edit_area->lineIndexFromPosition (m_sel_beg, &l1, &c1); + _edit_area->lineIndexFromPosition (m_sel_end, &l2, &c2); + _edit_area->show_selection_markers (l1, c1, l2, c2); + + // Check if new start position is still wihtin the selection + _find_result_available = pos >= m_sel_beg && pos <= m_sel_end; + } } + // No more search hits + if (! _find_result_available) + { + if (m_in_sel) + { + // Restore real selection and remove marker for selection + int l1, c1, l2, c2; + _edit_area->lineIndexFromPosition (m_sel_beg, &l1, &c1); + _edit_area->lineIndexFromPosition (m_sel_end, &l2, &c2); + _edit_area->setSelection (l1, c1, l2, c2); + _edit_area->clear_selection_markers (); + } - if (_find_result_available) - _from_start_check_box->setChecked (0); - else if (! _rep_all) - no_matches_message (); + // Display message if not replace all + if (! _rep_all) + no_matches_message (); + } + } void find_dialog::do_replace (void) @@ -413,7 +445,16 @@ if (_edit_area) { _rep_active = true; // changes in selection not made by the user + _edit_area->replace (_replace_line_edit->text ()); + if (m_in_sel) + { + // Update the length of the selection + m_sel_end = m_sel_end + - _search_line_edit->text ().toUtf8 ().size () + + _replace_line_edit->text ().toUtf8 ().size (); + } + _rep_active = false; } } @@ -422,14 +463,7 @@ { if (_edit_area) { - // The following line is a workaround for the issue that when replacing - // a text with a new one with different size within the selection, - // the selection is not updated leading to missing or extra replacements. - // This does not happen, when the selection is search backwards - if (_search_selection_check_box->isChecked ()) - _backward_check_box->setChecked (true); - - // do the replace if we have selected text + // Do the replace if we have selected text if (_find_result_available && _edit_area->hasSelectedText ()) do_replace ();
--- a/libgui/src/m-editor/find-dialog.h Sat Jun 01 08:56:51 2019 -0700 +++ b/libgui/src/m-editor/find-dialog.h Sat Jun 01 19:30:56 2019 +0200 @@ -63,7 +63,8 @@ #define octave_find_dialog_h 1 #include <QDialog> -#include <Qsci/qsciscintilla.h> + +#include "octave-qscintilla.h" class QCheckBox; class QDialogButtonBox; @@ -102,7 +103,7 @@ FIND_DLG_SEL = 128 }; - find_dialog (QsciScintilla *edit_area, QList<QAction *> find_actions, + find_dialog (octave_qscintilla *edit_area, QList<QAction *> find_actions, QWidget *parent = nullptr); void init_search_text (void); void save_data (find_dialog_data *fdlg_data); @@ -144,10 +145,14 @@ QPushButton *_replace_all_button; QPushButton *_more_button; QWidget *_extension; - QsciScintilla *_edit_area; + octave_qscintilla *_edit_area; bool _find_result_available; int _rep_all; bool _rep_active; + + bool m_in_sel; + int m_sel_beg; + int m_sel_end; }; }
--- a/libgui/src/m-editor/octave-qscintilla.cc Sat Jun 01 08:56:51 2019 -0700 +++ b/libgui/src/m-editor/octave-qscintilla.cc Sat Jun 01 19:30:56 2019 +0200 @@ -726,11 +726,12 @@ } } - void octave_qscintilla::show_selection_markers (int line, int col, int len) + void octave_qscintilla::show_selection_markers (int l1, int c1, int l2, int c2) { - fillIndicatorRange (line, col - len, line, col, m_indicator_id); + fillIndicatorRange (l1, c1, l2, c2, m_indicator_id); - markerAdd (line, marker::selection); + if (l1 == l2) + markerAdd (l1, marker::selection); } void octave_qscintilla::contextmenu_help (bool)
--- a/libgui/src/m-editor/octave-qscintilla.h Sat Jun 01 08:56:51 2019 -0700 +++ b/libgui/src/m-editor/octave-qscintilla.h Sat Jun 01 19:30:56 2019 +0200 @@ -69,7 +69,7 @@ void set_word_selection (const QString& word = QString ()); - void show_selection_markers (int line, int col, int len); + void show_selection_markers (int l1, int c1, int l2, int c2); void set_selection_marker_color (const QColor& c);