changeset 16521:3e8fd0c479b4

Add find files implemtation to main window menu * libgui/src/find-files-dialog.cc, libgui/src/find-files-dialog.h, libgui/src/find-files-model.cc, libgui/src/find-files-model.h: New files. * libgui/src/main-window.cc, libgui/src/main-window.h (main-window::main-window): Initialize find_files_dlg. Connect Find files menu. (main_window::find_files): New function. (main_window::find_files_finished): New function. * libgui/src/module.mk: Update file lists.
author John Donoghue <john.donoghue@ieee.org>
date Mon, 15 Apr 2013 02:06:00 -0400
parents 59dbdaeeea40
children 086b5e81245b
files libgui/src/find-files-dialog.cc libgui/src/find-files-dialog.h libgui/src/find-files-model.cc libgui/src/find-files-model.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/module.mk
diffstat 7 files changed, 680 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/libgui/src/find-files-dialog.cc
@@ -0,0 +1,349 @@
+/*
+
+Copyright (C) 2013 John Donoghue
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include  "find-files-dialog.h"
+#include  "find-files-model.h"
+#include "resource-manager.h"
+#include <QPushButton>
+#include <QDialogButtonBox>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QCheckBox>
+#include <QHeaderView>
+#include <QTableView>
+#include <QFileDialog>
+#include <QStatusBar>
+#include <QIcon>
+#include <QFileInfo>
+#include <QTimer>
+#include <QDirIterator>
+#include <QTextStream>
+
+find_files_dialog::find_files_dialog (QWidget * p)
+ : QDialog (p)
+{
+  setWindowTitle (tr("Find Files"));
+  setWindowIcon (QIcon (":/actions/icons/search.png"));
+
+  _dir_iterator = 0;
+
+  _timer = new QTimer (this);
+  connect(_timer, SIGNAL(timeout()), this, SLOT(look_for_files()));
+
+  QSettings *settings = resource_manager::get_settings ();
+
+  QLabel * file_name_label = new QLabel (tr ("Named:"));
+  _file_name_edit = new QLineEdit;
+  _file_name_edit->setToolTip (tr ("Enter the filename expression"));
+
+  _file_name_edit->setText (settings->value ("findfiles/file_name","*").toString ());
+  file_name_label->setBuddy (_file_name_edit);
+
+  QLabel * start_dir_label = new QLabel (tr ("Start in:"));
+
+  _start_dir_edit = new QLineEdit;
+  _start_dir_edit->setText (settings->value ("findfiles/start_dir",QDir::currentPath()).toString());
+  _start_dir_edit->setToolTip (tr ("Enter the start directory"));
+  start_dir_label->setBuddy (_start_dir_edit);
+
+  QPushButton * browse_button = new QPushButton (tr ("Browse...")); 
+  browse_button->setToolTip (tr ("Browse for start directory"));
+  connect(browse_button, SIGNAL(clicked()), this, SLOT(browse_folders()));
+
+  _recurse_dirs_check = new QCheckBox (tr ("Recurse directories"));
+  _recurse_dirs_check->setChecked (settings->value ("findfiles/recurse_dirs", false).toBool());
+  _recurse_dirs_check->setToolTip (tr ("Search recursively through directories for matching files"));
+
+  _include_dirs_check = new QCheckBox (tr ("Include directories"));
+  _include_dirs_check->setChecked (settings->value ("findfiles/include_dirs", false).toBool());
+  _include_dirs_check->setToolTip (tr ("Include matching directories in search results"));
+
+  _name_case_check = new QCheckBox (tr ("Name case insensitive"));
+  _name_case_check->setChecked (settings->value ("findfiles/name_case", false).toBool());
+  _name_case_check->setToolTip (tr ("Set matching name is case insensitive"));
+
+  _contains_text_check = new QCheckBox (tr("Contains text:"));
+  _contains_text_check->setToolTip (tr ("Search must match text"));
+  _contains_text_check->setChecked (settings->value ("findfiles/check_text", false).toBool());
+
+  _contains_text_edit = new QLineEdit ();
+  _contains_text_edit->setToolTip (tr ("Text to match"));
+  _contains_text_edit->setText (settings->value ("findfiles/contains_text", "").toString());
+
+  _content_case_check = new QCheckBox (tr("Text case insensitive"));
+  _content_case_check->setChecked (settings->value ("findfiles/content_case", false).toBool());
+  _content_case_check->setToolTip (tr ("Set text content is case insensitive"));
+  
+  find_files_model * model = new find_files_model ();
+  _file_list = new QTableView;
+  _file_list->setWordWrap (false);
+  _file_list->setModel (model);
+  _file_list->setShowGrid (false);
+  _file_list->setToolTip (tr ("Search results"));
+  _file_list->horizontalHeader ()->restoreState (settings->value ("findfiles/column_state").toByteArray ());
+  _file_list->sortByColumn (
+              settings->value ("findfiles/sort_files_by_column",0).toInt (),
+              static_cast<Qt::SortOrder>(settings->value ("findfiles/sort_files_by_order",Qt::AscendingOrder).toUInt ()));
+
+  connect (_file_list, SIGNAL(doubleClicked(const QModelIndex&)),
+           this,       SLOT(item_double_clicked(const QModelIndex &)));
+
+  _status_bar = new QStatusBar;
+  _status_bar->showMessage (tr("Idle."));
+
+  _find_button =  new QPushButton (tr("Find"));
+  _find_button->setToolTip (tr ("Start search for matching files"));
+  connect (_find_button, SIGNAL(clicked()), this, SLOT(start_find()));
+
+  _stop_button =  new QPushButton (tr("Stop"));
+  _stop_button->setToolTip (tr ("Stop searching"));
+  _stop_button->setEnabled (false);
+  connect (_stop_button, SIGNAL(clicked()), this, SLOT(stop_find()));
+
+  _close_button =  new QPushButton (tr("Close"));
+  _close_button->setToolTip (tr ("Close the search window"));
+  connect (_close_button, SIGNAL(clicked()), this, SLOT(accept()));
+
+  // layout everything
+  QDialogButtonBox * button_box = new QDialogButtonBox (Qt::Vertical);
+  button_box->addButton (_find_button, QDialogButtonBox::ActionRole);
+  button_box->addButton (_stop_button, QDialogButtonBox::ActionRole);
+  button_box->addButton (_close_button, QDialogButtonBox::ActionRole);
+ 
+  QGridLayout * left_layout = new QGridLayout;
+  left_layout->addWidget (file_name_label,1,1, 1,1);
+  left_layout->addWidget (_file_name_edit,1,2, 1,-1);
+
+  left_layout->addWidget (start_dir_label,2,1);
+  left_layout->addWidget (_start_dir_edit,2,2,1,3);
+  left_layout->addWidget (browse_button,2,5);
+  left_layout->setColumnStretch (2,1);
+
+  left_layout->addWidget (_recurse_dirs_check,3,1);
+  left_layout->addWidget (_include_dirs_check,3,2);
+  left_layout->addWidget (_name_case_check,3,3);
+
+  left_layout->addWidget (_contains_text_check,4,1);
+  left_layout->addWidget (_contains_text_edit,4,2,1,3);
+  left_layout->addWidget (_content_case_check,5,1);
+
+  QGridLayout *main_layout = new QGridLayout;
+  main_layout->setSizeConstraint (QLayout::SetFixedSize);
+  main_layout->addLayout (left_layout, 0, 0);
+  main_layout->addWidget (button_box, 0, 1);
+  main_layout->addWidget (_file_list,1,0);
+  main_layout->setRowStretch (1,1);
+  main_layout->addWidget (_status_bar,2,0,1,-1);
+
+  setLayout (main_layout);
+
+  connect (this, SIGNAL(finished(int)), this, SLOT(handle_done(int)));
+}
+
+find_files_dialog::~find_files_dialog ()
+{
+  QSettings *settings = resource_manager::get_settings ();
+
+  int sort_column = _file_list->horizontalHeader ()->sortIndicatorSection ();
+  Qt::SortOrder sort_order = _file_list->horizontalHeader ()->sortIndicatorOrder ();
+  settings->setValue ("findfiles/sort_files_by_column", sort_column);
+  settings->setValue ("findfiles/sort_files_by_order", sort_order);
+  settings->setValue ("findfiles/column_state", _file_list->horizontalHeader ()->saveState ());
+
+  settings->setValue ("findfiles/file_name", _file_name_edit->text());
+
+  settings->setValue ("findfiles/start_dir", _start_dir_edit->text());
+
+  settings->setValue ("findfiles/recurse_dirs", _recurse_dirs_check->text());
+  settings->setValue ("findfiles/include_dirs", _include_dirs_check->text());
+  settings->setValue ("findfiles/name_case", _name_case_check->text());
+
+  settings->setValue ("findfiles/contains_text", _contains_text_edit->text());
+  settings->setValue ("findfiles/check_text", _contains_text_check->isChecked ());
+  settings->setValue ("findfiles/content_case", _content_case_check->isChecked ());
+
+  settings->sync ();
+
+  if(_dir_iterator)
+    delete _dir_iterator;
+}
+
+void find_files_dialog::handle_done (int button)
+{
+  // make sure we stopped processing 
+  stop_find ();
+}
+
+void find_files_dialog::set_search_dir(const QString &dir)
+{
+  stop_find();
+  _start_dir_edit->setText(dir);
+}
+
+void 
+find_files_dialog::start_find ()
+{
+  stop_find();
+
+  find_files_model *m = static_cast<find_files_model *> (_file_list->model());
+  m->clear();
+
+  QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags;
+  if (_recurse_dirs_check->isChecked ())  flags |= QDirIterator::Subdirectories;
+
+  QDir::Filters filters = QDir::Dirs|QDir::NoDotAndDotDot|QDir::Files;
+  if (!_name_case_check->isChecked ())
+    filters |=  QDir::CaseSensitive;
+
+  QStringList nameFilters;
+  nameFilters.append (_file_name_edit->text());
+
+  if (_dir_iterator) delete _dir_iterator;
+
+  _dir_iterator = new QDirIterator (_start_dir_edit->text(), nameFilters, filters, flags);
+  
+  // enable/disable widgets 
+  _find_button->setEnabled (false);
+  _stop_button->setEnabled (true);
+  _close_button->setEnabled (false);
+  _start_dir_edit->setEnabled (false);
+  _file_name_edit->setEnabled (false);
+  _recurse_dirs_check->setEnabled (false);
+  _include_dirs_check->setEnabled (false);
+  _name_case_check->setEnabled (false);
+  _contains_text_check->setEnabled (false);
+  _content_case_check->setEnabled (false);
+  _contains_text_edit->setEnabled (false);
+
+  _status_bar->showMessage (tr("Searching..."));
+  _timer->start (0);
+}
+
+void 
+find_files_dialog::stop_find ()
+{
+  _timer->stop ();
+
+  _find_button->setEnabled (true);
+  _stop_button->setEnabled (false);
+  _close_button->setEnabled (true);
+  _start_dir_edit->setEnabled (true);
+  _file_name_edit->setEnabled (true);
+  _recurse_dirs_check->setEnabled (true);
+  _include_dirs_check->setEnabled (true);
+  _name_case_check->setEnabled (true);
+  _contains_text_check->setEnabled (true);
+  _content_case_check->setEnabled (true);
+  _contains_text_edit->setEnabled (true);
+
+  find_files_model *m = static_cast<find_files_model *> (_file_list->model());
+  QString res_str = QString ("%1 matches").arg(m->rowCount());
+
+  _status_bar->showMessage (res_str);
+}
+
+void 
+find_files_dialog::browse_folders ()
+{
+  QString dir =
+    QFileDialog::getExistingDirectory (this, tr ("Set search directory"), 
+      _start_dir_edit->text());
+
+  if (! dir.isEmpty ())
+    {
+      _start_dir_edit->setText (dir);
+    }
+}
+
+void 
+find_files_dialog::item_double_clicked (const QModelIndex &idx)
+{
+  find_files_model *m = static_cast<find_files_model *> (_file_list->model());
+
+  QFileInfo info = m->fileInfo (idx);
+
+  if(info.isDir())
+    emit dir_selected (info.absoluteFilePath());
+  else
+    emit file_selected (info.absoluteFilePath());
+}
+
+void
+find_files_dialog::look_for_files ()
+{
+  if(_dir_iterator && _dir_iterator->hasNext ())
+    {
+      QFileInfo info (_dir_iterator->next ());
+    
+      find_files_model *m = static_cast<find_files_model *> (_file_list->model ());
+
+      if(is_match (info))
+        m->addFile (info);
+    } 
+  else
+    {
+      stop_find (); 
+    }
+}
+
+bool find_files_dialog::is_match (const QFileInfo &info)
+{
+  bool match = true;
+  if (info.isDir ())
+    {
+      if(!_include_dirs_check->isChecked ()) match = false;
+      if(_contains_text_check->isChecked ()) match = false;
+    }
+  else
+    {
+      // a file
+      if (_contains_text_check->isChecked ())
+        {
+          match = false;
+
+          QFile file(info.absoluteFilePath ());
+          if (file.open (QIODevice::ReadOnly))
+            {
+              QTextStream stream (&file);
+
+              QString line;
+              QString match_str = _contains_text_edit->text ();
+
+              Qt::CaseSensitivity cs = _content_case_check->isChecked () ?
+                   Qt::CaseInsensitive : Qt::CaseSensitive;
+
+              do
+                {
+                  line = stream.readLine ();
+                  match = line.contains (match_str, cs);
+                }
+              while(!line.isNull () && match == false);
+            }
+
+        }
+    }
+
+  return match; 
+}
+
new file mode 100644
--- /dev/null
+++ b/libgui/src/find-files-dialog.h
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 2013 John Donoghue
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+#if !defined (find_files_dialog_h)
+#define find_files_dialog_h
+
+#include <QDialog>
+#include <QModelIndex>
+#include <QFileInfo>
+
+class QLineEdit;
+class QPushButton;
+class QTableView;
+class QTimer;
+class QDirIterator;
+class QCheckBox;
+class QStatusBar;
+
+class find_files_dialog : public QDialog
+{
+  Q_OBJECT
+public:
+  find_files_dialog (QWidget * parent=0);
+  virtual ~find_files_dialog ();
+
+signals:
+  void file_selected (const QString &fileName);
+  void dir_selected (const QString &fileName);
+
+public slots:
+  void set_search_dir(const QString &dir);
+
+private slots:
+  void start_find ();
+  void stop_find ();
+  void browse_folders ();
+  void look_for_files ();
+  void item_double_clicked (const QModelIndex&);
+  void handle_done(int);
+private:
+  bool is_match(const QFileInfo &info);
+  QLineEdit * _start_dir_edit;
+  QLineEdit * _file_name_edit;
+  QPushButton * _stop_button;
+  QPushButton * _find_button;
+  QPushButton * _close_button;
+  QTableView   * _file_list;
+  QTimer      * _timer;
+  QCheckBox   * _recurse_dirs_check;
+  QCheckBox   * _include_dirs_check;
+  QCheckBox   * _name_case_check;
+  QCheckBox   * _contains_text_check;
+  QCheckBox   * _content_case_check;
+  QLineEdit * _contains_text_edit;
+  QDirIterator * _dir_iterator;
+  QStatusBar * _status_bar;
+};
+
+#endif // find_files_dialog_h
+
new file mode 100644
--- /dev/null
+++ b/libgui/src/find-files-model.cc
@@ -0,0 +1,135 @@
+/*
+
+Copyright (C) 2013 John Donoghue
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include "find-files-model.h"
+#include <QFileIconProvider>
+
+find_files_model::find_files_model (QObject *p)
+  : QAbstractListModel(p)
+{
+  _columnNames.append (tr ("Filename"));
+  _columnNames.append (tr ("Directory"));
+}
+
+find_files_model::~find_files_model ()
+{
+}
+
+void 
+find_files_model::clear ()
+{
+  beginResetModel();
+
+  _files.clear();
+
+  endResetModel ();
+}
+
+void 
+find_files_model::addFile (const QFileInfo &info)
+{
+  beginInsertRows(QModelIndex(), _files.size(), _files.size() );
+
+  _files.append(info);
+
+  endInsertRows(); 
+}
+
+int 
+find_files_model::rowCount (const QModelIndex & p) const
+{
+  return _files.size();
+}
+
+int 
+find_files_model::columnCount (const QModelIndex & p) const
+{
+  return _columnNames.size ();
+}
+
+QVariant 
+find_files_model::data (const QModelIndex& idx, int role) const
+{
+  QVariant retval;
+
+  if (idx.isValid ())
+    {
+      if(role == Qt::DisplayRole)
+      {
+        switch (idx.column ())
+          {
+          case 0:
+            retval = QVariant (_files[idx.row()].fileName());
+            break;
+
+          case 1:
+            retval = QVariant (_files[idx.row()].absolutePath());
+            break;
+
+          default:
+            break;
+          }
+      }
+      else if(role == Qt:: DecorationRole)
+      {
+        switch (idx.column())
+          {
+          case 0:
+            retval = fileIcon(idx);
+          default:
+            break;
+          }
+      }
+    }
+
+  return retval;
+}
+
+QVariant 
+find_files_model::headerData (int section, Qt::Orientation orientation, int role) const
+{
+  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+    return _columnNames[section];
+  else
+    return QVariant ();
+}
+
+QFileInfo 
+find_files_model::fileInfo (const QModelIndex & p) const
+{
+  if(p.isValid ())
+  {
+    return _files[p.row()];
+  }
+  return QFileInfo ();
+}
+
+QIcon
+find_files_model::fileIcon (const QModelIndex &p) const
+{
+  QFileIconProvider icon_provider;
+  if(p.isValid ())
+  {
+    return icon_provider.icon (_files[p.row()]);
+  }
+  return QIcon ();
+}
new file mode 100644
--- /dev/null
+++ b/libgui/src/find-files-model.h
@@ -0,0 +1,59 @@
+/*
+
+Copyright (C) 2013 John Donoghue
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+#if !defined (find_files_model_h)
+#define find_files_model_h
+
+#include <QAbstractListModel>
+#include <QStringList>
+#include <QList>
+#include <QFileInfo>
+#include <QIcon>
+
+
+class find_files_model : public QAbstractListModel
+{
+public:
+  find_files_model(QObject *p=0);
+  ~find_files_model ();
+
+  void clear();
+
+  void addFile(const QFileInfo &info);
+
+  int rowCount(const QModelIndex & p=QModelIndex()) const;
+
+  int columnCount(const QModelIndex & p=QModelIndex()) const;
+
+  QVariant data (const QModelIndex& idx, int role) const;
+
+  QVariant headerData (int section, Qt::Orientation orientation,
+                       int role = Qt::DisplayRole) const;
+
+  QFileInfo fileInfo (const QModelIndex & p) const;
+  QIcon     fileIcon (const QModelIndex &p) const;
+private:
+  QList<QFileInfo> _files;
+  QStringList _columnNames;
+};
+
+#endif // find_files_model_h
+
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -74,6 +74,7 @@
     doc_browser_window (new documentation_dock_widget (this)),
     editor_window (create_default_editor (this)),
     workspace_window (new workspace_view (this)),
+    find_files_dlg (0),
     _octave_main_thread (0),
     _octave_qt_link (0)
 {
@@ -94,6 +95,11 @@
   delete history_window;
   delete status_bar;
   delete _workspace_model;
+  if (find_files_dlg) 
+    {
+      delete find_files_dlg;
+      find_files_dlg = 0;
+    }
   delete _octave_main_thread;
   delete _octave_qt_link;
 }
@@ -960,7 +966,6 @@
   QAction *find_files_action
     = edit_menu->addAction (tr ("Find Files..."));
   find_files_action->setShortcut (ctrl_shift + Qt::Key_F);
-  find_files_action->setEnabled (false); // TODO: Make this work.
 
   edit_menu->addSeparator ();
 
@@ -979,6 +984,9 @@
   connect (_paste_action, SIGNAL (triggered()),
            command_window, SLOT (pasteClipboard ()));
 
+  connect (find_files_action, SIGNAL (triggered()),
+           this, SLOT (find_files ()));
+
   connect (clear_command_window_action, SIGNAL (triggered ()),
            this, SLOT (handle_clear_command_window_request ()));
 
@@ -1403,3 +1411,41 @@
 {
   Fquit ();
 }
+
+void
+main_window::find_files(const QString &start_dir)
+{
+
+  if (! find_files_dlg)
+    {
+      find_files_dlg = new find_files_dialog (this);
+
+      connect (find_files_dlg, SIGNAL (finished (int)),
+               this, SLOT (find_files_finished (int)));
+
+      connect (find_files_dlg, SIGNAL (dir_selected(const QString &)),
+               file_browser_window, SLOT(set_current_directory(const QString&)));
+
+      connect (find_files_dlg, SIGNAL (file_selected(const QString &)),
+               this, SLOT(open_file(const QString &)));
+
+      find_files_dlg->setWindowModality (Qt::NonModal);
+    }
+
+  if (! find_files_dlg->isVisible ())
+    {
+      find_files_dlg->show ();
+    }
+
+  find_files_dlg->set_search_dir(start_dir);
+
+  find_files_dlg->activateWindow ();
+
+}
+
+void 
+main_window::find_files_finished(int button)
+{
+
+}
+
--- a/libgui/src/main-window.h
+++ b/libgui/src/main-window.h
@@ -53,6 +53,7 @@
 #include "terminal-dock-widget.h"
 #include "documentation-dock-widget.h"
 #include "octave-qt-link.h"
+#include "find-files-dialog.h"
 
 /**
  * \class MainWindow
@@ -140,6 +141,9 @@
                                   const QIntList&, const QIntList&,
                                   const QStringList&);
 
+  // find files dialog 
+  void find_files(const QString &startdir=QDir::currentPath());
+  void find_files_finished(int);
 protected:
   void closeEvent (QCloseEvent * closeEvent);
 
@@ -235,6 +239,9 @@
   static const int current_directory_max_count = 16;
   QLineEdit *_current_directory_line_edit;
 
+  // Find files dialog
+  find_files_dialog * find_files_dlg;
+
   octave_main_thread *_octave_main_thread;
 
   octave_qt_link *_octave_qt_link;
--- a/libgui/src/module.mk
+++ b/libgui/src/module.mk
@@ -84,6 +84,7 @@
   src/moc-welcome-wizard.cc \
   src/moc-workspace-model.cc \
   src/moc-workspace-view.cc \
+  src/moc-find-files-dialog.cc \
   src/qtinfo/moc-parser.cc \
   src/qtinfo/moc-webinfo.cc \
   src/moc-octave-dock-widget.cc
@@ -120,6 +121,8 @@
   src/terminal-dock-widget.h \
   src/color-picker.h \
   src/welcome-wizard.h \
+  src/find-files-dialog.h \
+  src/find-files-model.h \
   src/workspace-model.h \
   src/workspace-view.h
 
@@ -143,6 +146,8 @@
   src/terminal-dock-widget.cc \
   src/color-picker.cc \
   src/welcome-wizard.cc \
+  src/find-files-dialog.cc \
+  src/find-files-model.cc \
   src/workspace-model.cc \
   src/workspace-view.cc