changeset 33554:6f33e7ee3c3d

add find widget to experimental terminal widget * command-widget.cc (command_widget): initialize find widget without close button, connect find widget signals to the new slots, add find widget into layout; (notice_settings): call find widget method for updating settings; (console::find_incremental): new slot for incremental search; (console::find): new slot for forward and backward search * command-widget.h: include find-widget.h, new private slots console::find and console::find_incremental, new class variable containing find_widget some find history * find-widget.cc (find_widget): add a clear button to the line edit
author Torsten Lilge <ttl-octave@mailbox.org>
date Thu, 09 May 2024 21:05:52 +0200
parents 444190b10644
children 4b0987b80bb7
files libgui/src/command-widget.cc libgui/src/command-widget.h libgui/src/find-widget.cc
diffstat 3 files changed, 105 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/command-widget.cc	Thu May 09 20:35:50 2024 +0200
+++ b/libgui/src/command-widget.cc	Thu May 09 21:05:52 2024 +0200
@@ -54,22 +54,37 @@
 command_widget::command_widget (QWidget *p)
   : QWidget (p), m_incomplete_parse (false),
     m_prompt (QString ()),
-    m_console (new console (this))
+    m_console (new console (this)),
+    m_find_widget (new find_widget (false, this))
+
 {
+  gui_settings settings;
+
   QPushButton *pause_button = new QPushButton (tr("Pause"), this);
   QPushButton *stop_button = new QPushButton (tr("Stop"), this);
   QPushButton *resume_button = new QPushButton (tr("Continue"), this);
 
-  QGroupBox *input_group_box = new QGroupBox ();
+  connect (m_find_widget, &find_widget::find_signal,
+           m_console, &console::find);
+  connect (m_find_widget, &find_widget::find_incremental_signal,
+           m_console, &console::find_incremental);
+
+  QWidget *input_widget = new QWidget;
   QHBoxLayout *input_layout = new QHBoxLayout;
   input_layout->addWidget (pause_button);
   input_layout->addWidget (stop_button);
   input_layout->addWidget (resume_button);
-  input_group_box->setLayout (input_layout);
+  input_layout->addStretch ();
+  input_layout->addWidget (m_find_widget);
+  input_layout->setContentsMargins (0, 0, 0, 0);
+  input_widget->setLayout (input_layout);
+  input_widget->setContentsMargins (0, 0, 0, 0);
 
   QVBoxLayout *main_layout = new QVBoxLayout ();
   main_layout->addWidget (m_console);
-  main_layout->addWidget (input_group_box);
+  main_layout->addWidget (input_widget);
+  main_layout->setSpacing (0);
+  main_layout->setContentsMargins (2, 2, 2, 0);
 
   setLayout (main_layout);
 
@@ -97,7 +112,6 @@
            this, qOverload<const meth_callback&> (&command_widget::interpreter_event));
 
   insert_interpreter_output ("\n\n    Welcome to Octave\n\n");
-
 }
 
 void
@@ -208,6 +222,8 @@
 
   m_console->setStyleSheet (QString ("color: %1; background-color:%2;")
                             .arg (fgc.name ()).arg (bgc.name ()));
+
+  m_find_widget->notice_settings ();
 }
 
 // The console itself using QScintilla.
@@ -221,7 +237,10 @@
     m_cursor_position (0),
     m_text_changed (false),
     m_command_widget (p),
-    m_last_key_string (QString ())
+    m_last_key_string (QString ()),
+    m_find_result_available (false),
+    m_find_direction (false),
+    m_last_find_inc_result (QString ())
 {
   setMargins (0);
   setWrapMode (QsciScintilla::WrapWord);
@@ -337,6 +356,72 @@
   m_text_changed = true;
 }
 
+// find incremental
+void
+console::find_incremental (const QString& text)
+{
+  int line = -1, col = -1;
+
+  // Go the start of last incremental find result avoiding that the next
+  // match is found instead of the current one
+  if (! m_last_find_inc_result.isEmpty ())
+    {
+      getCursorPosition (&line, &col);
+      int currpos = positionFromLineIndex (line, col);
+      currpos = currpos - (m_last_find_inc_result.length ());
+      lineIndexFromPosition (currpos, &line, &col);
+    }
+
+
+  if (findFirst (text, false, false, false, true, true, line, col))
+    m_last_find_inc_result = text;
+  else
+    m_last_find_inc_result.clear ();
+}
+
+// find
+void
+console::find (const QString& text, bool backward)
+{
+  bool direction_changed = m_find_direction != backward;
+
+  int line = -1, col = -1;
+
+  if (direction_changed)
+    {
+      // Direction changed
+      m_find_direction = backward;
+      if (m_find_result_available)
+        {
+          // Something was found but direction changed, go to start/end of selection
+          if (m_find_result_available)
+            {
+              getCursorPosition (&line, &col);
+              int currpos = positionFromLineIndex (line, col);
+              if (backward)
+                currpos = currpos - (text.length ());
+              else
+                currpos = currpos + (text.length ());
+              if (currpos < 0)
+                currpos = 0;
+              lineIndexFromPosition (currpos, &line, &col);
+            }
+        }
+    }
+  else
+    {
+      // Direction not changed
+      if (m_find_result_available)
+        {
+          m_find_result_available = findNext ();
+          return;
+        }
+    }
+
+  m_find_result_available =
+      findFirst (text, false, false, false, true, ! backward, line, col);
+}
+
 // Re-implement key event
 void
 console::keyPressEvent (QKeyEvent *e)
--- a/libgui/src/command-widget.h	Thu May 09 20:35:50 2024 +0200
+++ b/libgui/src/command-widget.h	Thu May 09 21:05:52 2024 +0200
@@ -30,6 +30,8 @@
 
 #include <Qsci/qsciscintilla.h>
 
+#include "find-widget.h"
+
 // FIXME: We need the following header for the fcn_callback and
 // meth_callback typedefs.  Maybe it would be better to declare those in
 // a separate file because inclding "event-manager.h" pulls in a lot of
@@ -67,6 +69,10 @@
 
   void execute_command (const QString& command);
 
+  void find_incremental (const QString&);
+
+  void find (const QString&, bool);
+
 protected:
 
   void keyPressEvent (QKeyEvent *e);
@@ -82,6 +88,9 @@
   bool m_text_changed;
   command_widget *m_command_widget;
   QString m_last_key_string;
+  bool m_find_result_available;
+  bool m_find_direction;
+  QString m_last_find_inc_result;
 
 };
 
@@ -128,6 +137,8 @@
   bool m_incomplete_parse;
   QString m_prompt;
   console *m_console;
+  find_widget *m_find_widget;
+
 };
 
 OCTAVE_END_NAMESPACE(octave)
--- a/libgui/src/find-widget.cc	Thu May 09 20:35:50 2024 +0200
+++ b/libgui/src/find-widget.cc	Thu May 09 21:05:52 2024 +0200
@@ -38,6 +38,7 @@
 // of the doc dock widget
 find_widget::find_widget (bool x_button, QWidget *p)
   : QWidget (p),
+    m_find_line_edit (new QLineEdit (this)),
     m_findnext_shortcut (new QShortcut (this)),
     m_findprev_shortcut (new QShortcut (this))
 {
@@ -45,7 +46,8 @@
 
   QLabel *find_label = new QLabel (tr ("Find:"), this);
 
-  m_find_line_edit = new QLineEdit (this);
+  m_find_line_edit->setClearButtonEnabled (true);
+
   connect (m_find_line_edit, &QLineEdit::returnPressed,
            this, &find_widget::find);
   connect (m_find_line_edit, &QLineEdit::textEdited,