Mercurial > hg > octave-lyh
diff libgui/src/find-files-dialog.cc @ 16519: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 | |
children | ced9b101723c |
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; +} +