# HG changeset patch # User Torsten Lilge # Date 1576402694 -3600 # Node ID 6bbff502f89d534db77fafd6f116955b8bccc542 # Parent f426dd9750a3426be420d39442f007f20bb9b4e1 add mru lists for search/replace texts in editor find dialog (bug #57238) * find-dialog.cc (find_dialog): use a combo-box instead line edit for search and replace texts, do not use signal on text changes anymore; (save_settings): clean up mru lists and save them in the preferences file; (restore_settings): get mru lists from preferences file, clip length to its maximum length and add items to the combo-boxes (handle_search_text_changed): return if current text is the first in the mru list, update mru list; (handle_replace_text_changed): new method for updating replace mru list (mru_update): new method for doing the update of the desired mrulist, removing empty entries, removing the current text an inserting the current text at the beginning; (init_search_text): updates due to changing from line edit to combo-box; (find): call method for updating search text mru list with current text, updates due to changing from line edit to combo-box; (do_replace): updates due to changing from line edit to combo-box; (replace, replace_all): call method for updating replace mru list with current text; * find-dialog.h: handle_search_text_changed with no argiments, new method handle_replace_text_changed and mru_update, switched from line edit to combo-box, new const for mru max length diff -r f426dd9750a3 -r 6bbff502f89d libgui/src/m-editor/find-dialog.cc --- a/libgui/src/m-editor/find-dialog.cc Sat Dec 14 07:12:55 2019 -0800 +++ b/libgui/src/m-editor/find-dialog.cc Sun Dec 15 10:38:14 2019 +0100 @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -92,12 +93,25 @@ setWindowIcon (QIcon (":/actions/icons/find.png")); _search_label = new QLabel (tr ("Find &what:")); - _search_line_edit = new QLineEdit; + _search_line_edit = new QComboBox (this); + _search_line_edit->setToolTip (tr ("Enter text to search for")); + _search_line_edit->setEditable (true); + _search_line_edit->setMaxCount (m_mru_length); + _search_line_edit->completer ()->setCaseSensitivity (Qt::CaseSensitive); _search_label->setBuddy (_search_line_edit); + _replace_label = new QLabel (tr ("Re&place with:")); - _replace_line_edit = new QLineEdit; + _replace_line_edit = new QComboBox (this); + _replace_line_edit->setToolTip (tr ("Enter new text replacing search hits")); + _replace_line_edit->setEditable (true); + _replace_line_edit->setMaxCount (m_mru_length); + _replace_line_edit->completer ()->setCaseSensitivity (Qt::CaseSensitive); _replace_label->setBuddy (_replace_line_edit); + int width = QFontMetrics (_search_line_edit->font ()).averageCharWidth(); + _search_line_edit->setFixedWidth (20*width); + _replace_line_edit->setFixedWidth (20*width); + _case_check_box = new QCheckBox (tr ("Match &case")); _from_start_check_box = new QCheckBox (tr ("Search from &start")); _wrap_check_box = new QCheckBox (tr ("&Wrap while searching")); @@ -140,8 +154,6 @@ this, SLOT (handle_backward_search_changed (int))); connect (_button_box, SIGNAL (rejected ()), this, SLOT (close ())); - connect (_search_line_edit, SIGNAL (textChanged (QString)), - this, SLOT (handle_search_text_changed (QString))); connect (_search_selection_check_box, SIGNAL (stateChanged (int)), this, SLOT (handle_sel_search_changed (int))); @@ -218,9 +230,22 @@ s->setValue (ed_fdlg_pos.key, m_last_position); - s->setValue (ed_fdlg_search.key, _search_line_edit->text ()); - s->setValue (ed_fdlg_replace.key, _replace_line_edit->text ()); + // Is current search/replace text in the mru list? + mru_update (_search_line_edit); + mru_update (_replace_line_edit); + // Store mru lists + QStringList mru; + for (int i = 0; i < _search_line_edit->count (); i++) + mru.append (_search_line_edit->itemText (i)); + s->setValue (ed_fdlg_search.key, mru); + + mru.clear (); + for (int i = 0; i < _replace_line_edit->count (); i++) + mru.append (_replace_line_edit->itemText (i)); + s->setValue (ed_fdlg_replace.key, mru); + + // Store dialog's options int opts = 0 + _extension->isVisible () * FIND_DLG_MORE + _case_check_box->isChecked () * FIND_DLG_CASE @@ -240,9 +265,18 @@ resource_manager& rmgr = m_octave_qobj.get_resource_manager (); gui_settings *s = rmgr.get_settings (); - _search_line_edit->setText (s->value (ed_fdlg_search.key).toString ()); - _replace_line_edit->setText (s->value (ed_fdlg_replace.key).toString ()); + // Get mru lists for search and replace text + QStringList mru = s->value (ed_fdlg_search.key).toStringList (); + while (mru.length () > m_mru_length) + mru.removeLast (); + _search_line_edit->addItems (mru); + mru = s->value (ed_fdlg_replace.key).toStringList (); + while (mru.length () > m_mru_length) + mru.removeLast (); + _replace_line_edit->addItems (mru); + + // Get the dialog's options int opts = s->value (ed_fdlg_opts.key, ed_fdlg_opts.def).toInt (); _extension->setVisible (FIND_DLG_MORE & opts); @@ -273,10 +307,54 @@ } // search text has changed: reset the search - void find_dialog::handle_search_text_changed (QString) + void find_dialog::handle_search_text_changed (void) { + // Return if nothing has changed + if (_search_line_edit->currentText () == _search_line_edit->itemText (0)) + return; + if (_search_selection_check_box->isChecked ()) _find_result_available = false; + + mru_update (_search_line_edit); + } + + // replaced text has changed: reset the search + void find_dialog::handle_replace_text_changed (void) + { + // Return if nothing has changed + if (_replace_line_edit->currentText () + == _replace_line_edit->itemText (0)) + return; + + mru_update (_replace_line_edit); + } + + // Update the mru list + void find_dialog::mru_update (QComboBox *mru) + { + // Remove possible empty entries from the mru list + int index; + while ((index = mru->findText (QString ())) >= 0) + mru->removeItem (index); + + // Get current text and return if it is empty + QString text = mru->currentText (); + + if (text.isEmpty ()) + return; + + // Remove occurrences of the current text in the mru list + while ((index = mru->findText (text)) >= 0) + mru->removeItem (index); + + // Remove the last entry from the end if the list is full + if (mru->count () == m_mru_length) + mru->removeItem (m_mru_length -1); + + // Insert new item at the beginning and set it as current item + mru->insertItem (0, text); + mru->setCurrentIndex (0); } void find_dialog::handle_sel_search_changed (int selected) @@ -302,12 +380,12 @@ int lbeg, lend, cbeg, cend; _edit_area->getSelection (&lbeg,&cbeg,&lend,&cend); if (lbeg == lend) - _search_line_edit->setText (_edit_area->selectedText ()); + _search_line_edit->setCurrentText (_edit_area->selectedText ()); } // set focus to "Find what" and select all text _search_line_edit->setFocus (); - _search_line_edit->selectAll (); + _search_line_edit->lineEdit ()->selectAll (); // Default to "find" next time. // Otherwise, it defaults to the last action, which may be "replace all". @@ -329,6 +407,8 @@ if (! _edit_area) return; + handle_search_text_changed (); + // line adn col: -1 means search starts at current position int line = -1, col = -1; @@ -411,7 +491,7 @@ if (_find_result_available && _edit_area->hasSelectedText ()) { int currpos = _edit_area->positionFromLineIndex (line,col); - currpos -= (_search_line_edit->text ().length ()); + currpos -= (_search_line_edit->currentText ().length ()); if (currpos < 0) currpos = 0; _edit_area->lineIndexFromPosition (currpos, &line, &col); @@ -421,7 +501,7 @@ // Do the search _find_result_available - = _edit_area->findFirst (_search_line_edit->text (), + = _edit_area->findFirst (_search_line_edit->currentText (), _regex_check_box->isChecked (), _case_check_box->isChecked (), _whole_words_check_box->isChecked (), @@ -481,13 +561,13 @@ { _rep_active = true; // changes in selection not made by the user - _edit_area->replace (_replace_line_edit->text ()); + _edit_area->replace (_replace_line_edit->currentText ()); 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 (); + - _search_line_edit->currentText ().toUtf8 ().size () + + _replace_line_edit->currentText ().toUtf8 ().size (); } _rep_active = false; @@ -498,6 +578,8 @@ { if (_edit_area) { + handle_replace_text_changed (); + // Do the replace if we have selected text if (_find_result_available && _edit_area->hasSelectedText ()) do_replace (); @@ -512,6 +594,8 @@ if (_edit_area) { + handle_replace_text_changed (); + _edit_area->getCursorPosition (&line,&col); _rep_all = 1; diff -r f426dd9750a3 -r 6bbff502f89d libgui/src/m-editor/find-dialog.h --- a/libgui/src/m-editor/find-dialog.h Sat Dec 14 07:12:55 2019 -0800 +++ b/libgui/src/m-editor/find-dialog.h Sun Dec 15 10:38:14 2019 +0100 @@ -63,6 +63,7 @@ #define octave_find_dialog_h 1 #include +#include #include "octave-qscintilla.h" #include "octave-dock-widget.h" @@ -112,7 +113,6 @@ void handle_selection_changed (bool has_selected); void handle_backward_search_changed (int); - void handle_search_text_changed (QString new_search_text); void find (bool forward = true); void replace (void); @@ -131,15 +131,21 @@ //! Reimplemented close event void closeEvent (QCloseEvent* e); + //! Update mru lists with new entry + void mru_update (QComboBox *mru); + void no_matches_message (void); void do_replace (void); + void handle_search_text_changed (void); + void handle_replace_text_changed (void); + octave_dock_widget *m_editor; QLabel *_search_label; - QLineEdit *_search_line_edit; + QComboBox *_search_line_edit; QLabel *_replace_label; - QLineEdit *_replace_line_edit; + QComboBox *_replace_line_edit; QCheckBox *_case_check_box; QCheckBox *_from_start_check_box; QCheckBox *_wrap_check_box; @@ -164,6 +170,8 @@ int m_sel_end; QPoint m_last_position; + + const int m_mru_length = 10; }; }