Commit cc682234 authored by jhammen's avatar jhammen

text search project scope

parent 67962d60
......@@ -81,7 +81,7 @@ bool EditorWidget::save() {
return true;
}
QList<EditorLink> EditorWidget::findAll(const QString &term) {
QList<EditorLink> EditorWidget::findAll(const QString &term, bool active) {
QList<EditorLink> ret;
// grab current cursor location
QTextCursor cursor = textCursor();
......@@ -107,7 +107,12 @@ QList<EditorLink> EditorWidget::findAll(const QString &term) {
setExtraSelections(selections);
// return to original cursor
setTextCursor(cursor);
findNext(term);
// if active editor find next
if (active) {
if (!cursor.selectedText().endsWith(term, Qt::CaseInsensitive)) {
findNext(term);
}
}
return ret;
}
......
......@@ -56,7 +56,7 @@ class EditorWidget : public QPlainTextEdit {
bool hasSelection() { return textCursor().hasSelection(); }
bool load();
bool save();
QList<EditorLink> findAll(const QString &term);
QList<EditorLink> findAll(const QString &term, bool active);
void findNext(const QString &term);
void focusLine(int line, int column = 0);
void focusLocation(EditorLocation &loc);
......
......@@ -60,6 +60,8 @@ MainWindow::MainWindow(QWidget *parent)
ui->leftTabWidget->addTab(searchWidget, "Search");
connect(searchWidget, SIGNAL(searchCurrent(QString)), this, SLOT(searchCurrent(QString)));
connect(searchWidget, SIGNAL(searchNext(QString)), this, SLOT(searchNext(QString)));
connect(searchWidget, SIGNAL(searchProject(QString)), this, SLOT(searchProject(QString)));
connect(searchWidget, SIGNAL(clearSearch()), this, SLOT(clearSearch()));
connect(searchWidget, SIGNAL(navigateResult(EditorLocation &)), this,
SLOT(handleLink(EditorLocation &)));
......@@ -219,11 +221,56 @@ void MainWindow::markDirty(bool value) {
void MainWindow::searchCurrent(const QString &term) {
EditorWidget *editor = currentEditor();
if (editor) {
searchWidget->results(editor->findAll(term));
searchWidget->addResults(editor->name(), editor->findAll(term, true), true);
}
}
void MainWindow::searchNext(const QString &term) { currentEditor()->findNext(term); }
void MainWindow::searchNext(const QString &term) {
if (currentEditor()) {
currentEditor()->findNext(term);
}
}
void MainWindow::searchFolder(const QString &term, NamedFile &folder) {
QDir dir(folder.path);
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
foreach (QFileInfo fileInfo, dir.entryInfoList()) {
if (fileInfo.isFile()) {
EditorWidget *editor = findEditor(fileInfo.filePath());
if (editor) {
QList<EditorLink> results = editor->findAll(term, false);
if (results.size()) {
searchWidget->addResults(editor->name(), results, true);
}
} else {
QList<EditorLink> results = searchFile(term, fileInfo.filePath());
if (results.size()) {
searchWidget->addResults(fileInfo.fileName(), results, false);
}
}
} else if (fileInfo.isDir()) {
NamedFile childFolder(fileInfo.baseName(), fileInfo.filePath());
searchFolder(term, childFolder);
}
}
}
void MainWindow::searchProject(const QString &term) {
Project &project = projectList.currentProject();
for (int i = 0; i < project.folderCount(); ++i) {
NamedFile &folder = project.folder(i);
searchFolder(term, folder);
}
}
void MainWindow::clearSearch() {
for (int i = 0; i < ui->tabWidget->count(); i++) {
EditorWidget *editor = qobject_cast<EditorWidget *>(ui->tabWidget->widget(i));
QList<QTextEdit::ExtraSelection> empty;
editor->setExtraSelections(empty);
}
}
void MainWindow::showTime(Position pos) {
QTime qtime(0, 0, 0);
......@@ -358,6 +405,11 @@ void MainWindow::on_actionFastForward_triggered() {
audioEngine.reposition(transportPosition);
}
void MainWindow::on_actionFind_in_Project_triggered() {
searchWidget->newProjectSearch();
ui->leftTabWidget->setCurrentWidget(searchWidget);
}
/**
* @brief MainWindow::on_actionRun_triggered
*
......@@ -593,6 +645,8 @@ void MainWindow::loadProject() {
if (editor) {
ui->tabWidget->setCurrentWidget(editor);
}
searchWidget->clear();
ui->leftTabWidget->setCurrentWidget(ui->folderTree);
}
bool MainWindow::saveAllTabs() {
......@@ -624,6 +678,33 @@ bool MainWindow::saveOrAbandon(EditorWidget *editor) {
return true;
}
QList<EditorLink> MainWindow::searchFile(const QString &term, const QString &path) {
QList<EditorLink> ret;
QFile file(path);
if (file.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&file);
int lineindex = 0;
while (!in.atEnd()) {
QString line = in.readLine();
int index = line.indexOf(term, 0, Qt::CaseInsensitive);
while (index != -1) {
NamedFile nfile(file.fileName(), path);
int anchor = lineindex + index;
// find snippet
int space = line.indexOf(QRegExp("\\s+"), index);
int end = (space == -1 ? line.size() : space);
QString text = line.mid(index, end - index);
// create and add editor link
EditorLink link(text, nfile, anchor, anchor + term.size());
ret.append(link);
index = line.indexOf(term, index + 1, Qt::CaseInsensitive);
}
lineindex += line.length() + 1;
}
}
return ret;
}
bool MainWindow::killAllScripts() {
for (int i = 0; i < ui->outputTabWidget->count(); i++) {
OutputWidget *output = qobject_cast<OutputWidget *>(ui->outputTabWidget->widget(i));
......
......@@ -52,6 +52,8 @@ class MainWindow : public QMainWindow {
void markDirty(bool unsaved);
void searchCurrent(const QString &);
void searchNext(const QString &);
void searchProject(const QString &);
void clearSearch();
void showTime(Position pos);
void tabChanged(int index);
void closeOtherEditors();
......@@ -65,6 +67,8 @@ class MainWindow : public QMainWindow {
void on_actionExamples_triggered();
void on_actionExit_triggered();
void on_actionFastForward_triggered();
void on_actionFind_in_Project_triggered();
void on_actionFocusFind_triggered();
void on_actionJackConnect_toggled(bool);
void on_actionNewFile_triggered();
void on_actionOpenFile_triggered();
......@@ -82,7 +86,6 @@ class MainWindow : public QMainWindow {
void on_actionUndo_triggered();
void on_actionWebsite_triggered();
void on_tabWidget_customContextMenuRequested(const QPoint &pos);
void on_actionFocusFind_triggered();
private:
ProjectList &projectList;
......@@ -109,6 +112,8 @@ class MainWindow : public QMainWindow {
void loadProject();
bool saveAllTabs();
bool saveOrAbandon(EditorWidget *editor);
QList<EditorLink> searchFile(const QString &term, const QString &path);
void searchFolder(const QString &term, NamedFile &folder);
FolderTreeItem *toTreeFolder(NamedFile &folder);
QMessageBox::StandardButton unsavedChangesDialog(const QString &);
};
......
......@@ -106,6 +106,7 @@
<addaction name="actionComment"/>
<addaction name="separator"/>
<addaction name="actionFocusFind"/>
<addaction name="actionFind_in_Project"/>
</widget>
<widget class="QMenu" name="menuTransport">
<property name="title">
......@@ -529,6 +530,20 @@
<string>Ctrl+F</string>
</property>
</action>
<action name="actionFind_in_Project">
<property name="icon">
<iconset theme="edit-find"/>
</property>
<property name="text">
<string>Find in Project</string>
</property>
<property name="toolTip">
<string>Find in Project</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+F</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
......
......@@ -19,7 +19,7 @@
#include "ui_searchwidget.h"
SearchWidget::SearchWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::SearchWidget), newSearch(true) {
: QWidget(parent), ui(new Ui::SearchWidget), newSearch(true), count(0) {
ui->setupUi(this);
connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
SLOT(resultTreeClicked(QTreeWidgetItem *, int)));
......@@ -30,27 +30,38 @@ void SearchWidget::newFileSearch() {
ui->searchLineEdit->selectAll();
}
void SearchWidget::results(QList<EditorLink> results) {
int count = results.size();
QString label(count == 1 ? "result" : "results");
QString mesg = QString("%1 %2").arg(count).arg(label);
ui->countLabel->setText(mesg);
void SearchWidget::newProjectSearch() {
ui->searchLineEdit->setFocus();
ui->searchLineEdit->selectAll();
ui->projectScopeButton->setChecked(true);
}
void SearchWidget::addResults(const QString &filename, QList<EditorLink> results, bool open) {
QTreeWidgetItem *top = nullptr;
QTreeWidgetItem *parent = nullptr;
QString path;
// header tree node for file name
QString header = QString("%1 (%2)").arg(filename).arg(results.size());
QTreeWidgetItem *parent =
new QTreeWidgetItem(top, QStringList(header), QTreeWidgetItem::UserType);
ui->treeWidget->addTopLevelItem(parent);
if (open) {
parent->setExpanded(true);
}
// child tree nodes for results
foreach (EditorLink link, results) {
EditorLocation &loc = link.location();
QString label = QString("%1").arg(loc.position());
QTreeWidgetItem *item = new SearchTreeItem(top, link);
if (loc.file().path != path) {
path = loc.file().path;
parent =
new QTreeWidgetItem(top, QStringList(loc.file().name), QTreeWidgetItem::UserType);
ui->treeWidget->addTopLevelItem(parent);
parent->setExpanded(true);
}
QTreeWidgetItem *item = new SearchTreeItem(parent, link);
parent->addChild(item);
}
// update counts
count += results.size();
fcount++;
showCount();
}
void SearchWidget::clear() {
ui->searchLineEdit->clear();
ui->treeWidget->clear();
ui->countLabel->clear();
ui->fileScopeButton->setChecked(true);
}
SearchWidget::~SearchWidget() { delete ui; }
......@@ -66,20 +77,43 @@ void SearchWidget::on_searchButton_clicked() { doSearch(); }
void SearchWidget::on_searchLineEdit_returnPressed() { doSearch(); }
void SearchWidget::on_searchLineEdit_textEdited(const QString &) { newSearch = true; }
void SearchWidget::on_refreshButton_clicked() {
newSearch = true;
doSearch();
}
void SearchWidget::doSearch() {
QLineEdit *lineEdit = this->ui->searchLineEdit;
QString term = lineEdit->text();
if (newSearch) {
count = 0;
fcount = 0;
showCount();
ui->treeWidget->clear();
emit searchCurrent(lineEdit->text());
newSearch = false;
if (term.size() == 0) {
emit clearSearch();
} else if (ui->fileScopeButton->isChecked()) {
emit searchCurrent(term);
newSearch = false;
} else if (ui->projectScopeButton->isChecked()) {
emit searchProject(term);
newSearch = false;
}
} else {
emit searchNext(lineEdit->text());
ui->treeWidget->clearSelection();
emit searchNext(term);
}
}
void SearchWidget::on_searchLineEdit_textEdited(const QString &) { newSearch = true; }
void SearchWidget::on_refreshButton_clicked() {
newSearch = true;
doSearch();
void SearchWidget::showCount() {
QString label(count == 1 ? "result" : "results");
QString flabel(fcount == 1 ? "file" : "files");
QString mesg = QString("%1 %2 in %3 %4").arg(count).arg(label).arg(fcount).arg(flabel);
ui->countLabel->setText(mesg);
}
void SearchWidget::on_fileScopeButton_clicked() { newSearch = true; }
void SearchWidget::on_projectScopeButton_clicked() { newSearch = true; }
......@@ -30,13 +30,17 @@ class SearchWidget : public QWidget {
public:
explicit SearchWidget(QWidget *parent = nullptr);
void newFileSearch();
void results(QList<EditorLink> results);
void newProjectSearch();
void addResults(const QString &filename, QList<EditorLink> addResults, bool open);
void clear();
~SearchWidget();
signals:
void searchCurrent(QString);
void searchNext(QString);
void searchProject(QString);
void navigateResult(EditorLocation &);
void clearSearch();
private slots:
void resultTreeClicked(QTreeWidgetItem *, int);
......@@ -44,11 +48,16 @@ class SearchWidget : public QWidget {
void on_searchLineEdit_returnPressed();
void on_searchLineEdit_textEdited(const QString &arg1);
void on_refreshButton_clicked();
void on_fileScopeButton_clicked();
void on_projectScopeButton_clicked();
private:
Ui::SearchWidget *ui;
bool newSearch;
int count;
int fcount;
void doSearch();
void showCount();
};
#endif // SEARCHWIDGET_H
......@@ -29,17 +29,35 @@
</layout>
</item>
<item>
<widget class="QRadioButton" name="radioButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Find in current file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Find in:</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="fileScopeButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Current File</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="projectScopeButton">
<property name="text">
<string>Project</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
......@@ -59,7 +77,8 @@
<string>...</string>
</property>
<property name="icon">
<iconset theme="reload"/>
<iconset theme="reload">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment