Commit 2a480324 authored by con's avatar con
Browse files

Make search panel searchable.

Task-number: QTCREATORBUG-1438
parent edfe3fec
......@@ -44,7 +44,8 @@ enum Roles
ResultLineNumberRole,
SearchTermStartRole,
SearchTermLengthRole,
RowOfItem // The ?-th child of its parent is this this item
RowOfItem, // The ?-th child of its parent is this this item
TextRole // for files == FileNameRole, for results == ResultLineRole
};
} // namespace Internal
......
......@@ -36,6 +36,8 @@
#include <QtGui/QFontMetrics>
#include <QtGui/QColor>
#include <QtGui/QPalette>
#include <QtGui/QTextDocument>
#include <QtGui/QTextCursor>
#include <QtCore/QDir>
#include <QtCore/QDebug>
......@@ -195,6 +197,7 @@ QVariant SearchResultTreeModel::data(const SearchResultTextRow *row, int role) c
case Qt::FontRole:
result = m_textEditorFont;
break;
case ItemDataRoles::TextRole:
case ItemDataRoles::ResultLineRole:
case Qt::DisplayRole:
result = row->rowText();
......@@ -252,6 +255,7 @@ QVariant SearchResultTreeModel::data(const SearchResultFile *file, int role) con
+ QLatin1Char(')');
return QVariant(result);
}
case ItemDataRoles::TextRole:
case ItemDataRoles::FileNameRole:
case Qt::ToolTipRole:
return QVariant(QDir::toNativeSeparators(file->fileName()));
......@@ -349,7 +353,7 @@ void SearchResultTreeModel::clear()
reset();
}
QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
QModelIndex SearchResultTreeModel::next(const QModelIndex &idx, bool includeTopLevel) const
{
QModelIndex parent = idx.parent();
if (parent.isValid()) {
......@@ -367,6 +371,8 @@ QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
// Wrap around
nextParent = index(0,0);
}
if (includeTopLevel)
return nextParent;
return nextParent.child(0, 0);
}
} else {
......@@ -376,7 +382,7 @@ QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
return QModelIndex();
}
QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx, bool includeTopLevel) const
{
QModelIndex parent = idx.parent();
if (parent.isValid()) {
......@@ -385,6 +391,8 @@ QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
// Same parent
return index(row - 1, 0, parent);
} else {
if (includeTopLevel)
return parent;
// Prev parent
int parentRow = parent.row();
QModelIndex prevParent;
......@@ -399,10 +407,56 @@ QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
} else {
// We are on a top level item
int row = idx.row();
QModelIndex prevParent;
if (row > 0) {
QModelIndex prevParent = index(row - 1, 0);
return prevParent.child(rowCount(prevParent) ,0);
prevParent = index(row - 1, 0);
} else {
// wrap around
prevParent = index(rowCount() -1, 0);
}
return prevParent.child(rowCount(prevParent) -1,0);
}
return QModelIndex();
}
QModelIndex SearchResultTreeModel::find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags)
{
QModelIndex resultIndex;
QModelIndex currentIndex = index;
bool backward = (flags & QTextDocument::FindBackward);
do {
if (backward)
currentIndex = prev(currentIndex, true);
else
currentIndex = next(currentIndex, true);
if (currentIndex.isValid()) {
const QString &text = data(currentIndex, ItemDataRoles::TextRole).toString();
if (expr.indexIn(text) != -1)
resultIndex = currentIndex;
}
} while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
return resultIndex;
}
QModelIndex SearchResultTreeModel::find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags)
{
QModelIndex resultIndex;
QModelIndex currentIndex = index;
bool backward = (flags & QTextDocument::FindBackward);
flags = (flags & (~QTextDocument::FindBackward)); // backward is handled by us ourselves
do {
if (backward)
currentIndex = prev(currentIndex, true);
else
currentIndex = next(currentIndex, true);
if (currentIndex.isValid()) {
const QString &text = data(currentIndex, ItemDataRoles::TextRole).toString();
QTextDocument doc(text);
if (!doc.find(term, 0, flags).isNull())
resultIndex = currentIndex;
}
} while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
return resultIndex;
}
......@@ -33,7 +33,9 @@
#include "searchresultwindow.h"
#include <QtCore/QAbstractItemModel>
#include <QtCore/QRegExp>
#include <QtGui/QFont>
#include <QtGui/QTextDocument>
namespace Find {
namespace Internal {
......@@ -62,11 +64,14 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex next(const QModelIndex &idx) const;
QModelIndex prev(const QModelIndex &idx) const;
QModelIndex next(const QModelIndex &idx, bool includeTopLevel = false) const;
QModelIndex prev(const QModelIndex &idx, bool includeTopLevel = false) const;
QList<int> addResultLines(const QList<SearchResultItem> &items);
QModelIndex find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags);
QModelIndex find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags);
signals:
void jumpToSearchResult(const QString &fileName, int lineNumber,
int searchTermStart, int searchTermLength);
......
......@@ -31,7 +31,9 @@
#include "searchresulttreemodel.h"
#include "searchresulttreeitems.h"
#include "searchresulttreeview.h"
#include "ifindsupport.h"
#include <aggregation/aggregate.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
......@@ -52,6 +54,8 @@ static const char SETTINGSKEYEXPANDRESULTS[] = "ExpandResults";
namespace Find {
namespace Internal {
class WideEnoughLineEdit : public QLineEdit {
Q_OBJECT
public:
......@@ -70,31 +74,137 @@ namespace Find {
void updateGeometry() { QLineEdit::updateGeometry(); }
};
class SearchResultFindSupport : public IFindSupport
{
Q_OBJECT
public:
SearchResultFindSupport(SearchResultTreeView *view)
: m_view(view)
{
}
struct SearchResultWindowPrivate {
SearchResultWindowPrivate();
bool supportsReplace() const { return false; }
Internal::SearchResultTreeView *m_searchResultTreeView;
QListWidget *m_noMatchesFoundDisplay;
QToolButton *m_expandCollapseToolButton;
QLabel *m_replaceLabel;
QLineEdit *m_replaceTextEdit;
QToolButton *m_replaceButton;
static const bool m_initiallyExpand = false;
QStackedWidget *m_widget;
SearchResult *m_currentSearch;
QList<SearchResultItem> m_items;
bool m_isShowingReplaceUI;
bool m_focusReplaceEdit;
};
IFindSupport::FindFlags supportedFindFlags() const
{
return IFindSupport::FindBackward | IFindSupport::FindCaseSensitively
| IFindSupport::FindRegularExpression | IFindSupport::FindWholeWords;
}
SearchResultWindowPrivate::SearchResultWindowPrivate()
: m_currentSearch(0),
m_isShowingReplaceUI(false),
m_focusReplaceEdit(false)
{
void resetIncrementalSearch()
{
m_incrementalFindStart = QModelIndex();
}
void clearResults() { }
QString currentFindString() const
{
return QString();
}
QString completedFindString() const
{
return QString();
}
void highlightAll(const QString &txt, IFindSupport::FindFlags findFlags)
{
Q_UNUSED(txt)
Q_UNUSED(findFlags)
return;
}
IFindSupport::Result findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
{
if (!m_incrementalFindStart.isValid())
m_incrementalFindStart = m_view->currentIndex();
m_view->setCurrentIndex(m_incrementalFindStart);
return find(txt, findFlags);
}
IFindSupport::Result findStep(const QString &txt, IFindSupport::FindFlags findFlags)
{
IFindSupport::Result result = find(txt, findFlags);
if (result == IFindSupport::Found)
m_incrementalFindStart = m_view->currentIndex();
return result;
}
IFindSupport::Result find(const QString &txt, IFindSupport::FindFlags findFlags)
{
if (txt.isEmpty())
return IFindSupport::NotFound;
QModelIndex index;
if (findFlags & IFindSupport::FindRegularExpression) {
bool sensitive = (findFlags & IFindSupport::FindCaseSensitively);
index = m_view->model()->find(QRegExp(txt, (sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)),
m_view->currentIndex(),
IFindSupport::textDocumentFlagsForFindFlags(findFlags));
} else {
index = m_view->model()->find(txt, m_view->currentIndex(),
IFindSupport::textDocumentFlagsForFindFlags(findFlags));
}
if (index.isValid()) {
m_view->setCurrentIndex(index);
m_view->scrollTo(index);
if (index.parent().isValid())
m_view->expand(index.parent());
return IFindSupport::Found;
}
return IFindSupport::NotFound;
}
bool replaceStep(const QString &before, const QString &after,
IFindSupport::FindFlags findFlags)
{
Q_UNUSED(before)
Q_UNUSED(after)
Q_UNUSED(findFlags)
return false;
}
int replaceAll(const QString &before, const QString &after,
IFindSupport::FindFlags findFlags)
{
Q_UNUSED(before)
Q_UNUSED(after)
Q_UNUSED(findFlags)
return 0;
}
private:
SearchResultTreeView *m_view;
QModelIndex m_incrementalFindStart;
};
struct SearchResultWindowPrivate {
SearchResultWindowPrivate();
Internal::SearchResultTreeView *m_searchResultTreeView;
QListWidget *m_noMatchesFoundDisplay;
QToolButton *m_expandCollapseToolButton;
QLabel *m_replaceLabel;
QLineEdit *m_replaceTextEdit;
QToolButton *m_replaceButton;
static const bool m_initiallyExpand = false;
QStackedWidget *m_widget;
SearchResult *m_currentSearch;
QList<SearchResultItem> m_items;
bool m_isShowingReplaceUI;
bool m_focusReplaceEdit;
};
SearchResultWindowPrivate::SearchResultWindowPrivate()
: m_currentSearch(0),
m_isShowingReplaceUI(false),
m_focusReplaceEdit(false)
{
}
}
using namespace Find::Internal;
SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
{
d->m_widget = new QStackedWidget;
......@@ -104,6 +214,9 @@ SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
d->m_searchResultTreeView->setFrameStyle(QFrame::NoFrame);
d->m_searchResultTreeView->setAttribute(Qt::WA_MacShowFocusRect, false);
d->m_widget->addWidget(d->m_searchResultTreeView);
Aggregation::Aggregate * agg = new Aggregation::Aggregate;
agg->add(d->m_searchResultTreeView);
agg->add(new SearchResultFindSupport(d->m_searchResultTreeView));
d->m_noMatchesFoundDisplay = new QListWidget(d->m_widget);
d->m_noMatchesFoundDisplay->addItem(tr("No matches found!"));
......
......@@ -43,6 +43,7 @@ QT_END_NAMESPACE
namespace Find {
namespace Internal {
class SearchResultTreeView;
struct SearchResultWindowPrivate;
}
class SearchResultWindow;
......@@ -69,7 +70,6 @@ signals:
friend class SearchResultWindow;
};
struct SearchResultWindowPrivate;
class FIND_EXPORT SearchResultWindow : public Core::IOutputPane
{
Q_OBJECT
......@@ -128,7 +128,7 @@ private:
void writeSettings();
QList<SearchResultItem> checkedItems() const;
SearchResultWindowPrivate *d;
Internal::SearchResultWindowPrivate *d;
};
} // namespace Find
......
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