Commit ebb9e252 authored by con's avatar con
Browse files

Fix searching search result window and add wrap indicator.

When searching the search result window the current item was ignored in
the search instead of potentially being the first match.

Task-number: QTCREATORBUG-2753
parent b5c6a687
......@@ -185,8 +185,7 @@ IFindSupport::Result BaseTextFind::findIncremental(const QString &txt, Find::Fin
bool found = find(txt, findFlags, cursor, &wrapped);
if (wrapped != d->m_incrementalWrappedState) {
d->m_incrementalWrappedState = wrapped;
if (found)
showWrapIndicator(d->m_widget);
showWrapIndicator(d->m_widget);
}
if (found)
emit highlightAll(txt, findFlags);
......
......@@ -422,8 +422,10 @@ void SearchResultTreeModel::clear()
reset();
}
QModelIndex SearchResultTreeModel::nextIndex(const QModelIndex &idx) const
QModelIndex SearchResultTreeModel::nextIndex(const QModelIndex &idx, bool *wrapped) const
{
if (wrapped)
*wrapped = false;
// pathological
if (!idx.isValid())
return index(0, 0);
......@@ -444,6 +446,9 @@ QModelIndex SearchResultTreeModel::nextIndex(const QModelIndex &idx) const
} else {
// go up one parent
if (!current.isValid()) {
// we start from the beginning
if (wrapped)
*wrapped = true;
nextIndex = index(0, 0);
}
}
......@@ -451,17 +456,19 @@ QModelIndex SearchResultTreeModel::nextIndex(const QModelIndex &idx) const
return nextIndex;
}
QModelIndex SearchResultTreeModel::next(const QModelIndex &idx, bool includeGenerated) const
QModelIndex SearchResultTreeModel::next(const QModelIndex &idx, bool includeGenerated, bool *wrapped) const
{
QModelIndex value = idx;
do {
value = nextIndex(value);
value = nextIndex(value, wrapped);
} while (value != idx && !includeGenerated && treeItemAtIndex(value)->isGenerated());
return value;
}
QModelIndex SearchResultTreeModel::prevIndex(const QModelIndex &idx) const
QModelIndex SearchResultTreeModel::prevIndex(const QModelIndex &idx, bool *wrapped) const
{
if (wrapped)
*wrapped = false;
QModelIndex current = idx;
bool checkForChildren = true;
if (current.isValid()) {
......@@ -471,6 +478,10 @@ QModelIndex SearchResultTreeModel::prevIndex(const QModelIndex &idx) const
} else {
current = current.parent();
checkForChildren = !current.isValid();
if (checkForChildren && wrapped) {
// we start from the end
*wrapped = true;
}
}
}
if (checkForChildren) {
......@@ -482,53 +493,69 @@ QModelIndex SearchResultTreeModel::prevIndex(const QModelIndex &idx) const
return current;
}
QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx, bool includeGenerated) const
QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx, bool includeGenerated, bool *wrapped) const
{
QModelIndex value = idx;
do {
value = prevIndex(value);
value = prevIndex(value, wrapped);
} while (value != idx && !includeGenerated && treeItemAtIndex(value)->isGenerated());
return value;
}
QModelIndex SearchResultTreeModel::find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags)
QModelIndex SearchResultTreeModel::find(const QRegExp &expr, const QModelIndex &index,
QTextDocument::FindFlags flags, bool *wrapped)
{
QModelIndex resultIndex;
QModelIndex currentIndex = index;
bool backward = (flags & QTextDocument::FindBackward);
if (wrapped)
*wrapped = false;
bool anyWrapped = false;
bool stepWrapped = false;
do {
if (backward)
currentIndex = prev(currentIndex, true);
else
currentIndex = next(currentIndex, true);
anyWrapped |= stepWrapped; // update wrapped state if we actually stepped to next/prev item
if (currentIndex.isValid()) {
const QString &text = data(currentIndex, ItemDataRoles::ResultLineRole).toString();
if (expr.indexIn(text) != -1)
resultIndex = currentIndex;
}
if (backward)
currentIndex = prev(currentIndex, true, &stepWrapped);
else
currentIndex = next(currentIndex, true, &stepWrapped);
} while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
if (resultIndex.isValid() && wrapped)
*wrapped = anyWrapped;
return resultIndex;
}
QModelIndex SearchResultTreeModel::find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags)
QModelIndex SearchResultTreeModel::find(const QString &term, const QModelIndex &index,
QTextDocument::FindFlags flags, bool *wrapped)
{
QModelIndex resultIndex;
QModelIndex currentIndex = index;
bool backward = (flags & QTextDocument::FindBackward);
flags = (flags & (~QTextDocument::FindBackward)); // backward is handled by us ourselves
if (wrapped)
*wrapped = false;
bool anyWrapped = false;
bool stepWrapped = false;
do {
if (backward)
currentIndex = prev(currentIndex, true);
else
currentIndex = next(currentIndex, true);
anyWrapped |= stepWrapped; // update wrapped state if we actually stepped to next/prev item
if (currentIndex.isValid()) {
const QString &text = data(currentIndex, ItemDataRoles::ResultLineRole).toString();
QTextDocument doc(text);
if (!doc.find(term, 0, flags).isNull())
resultIndex = currentIndex;
}
if (backward)
currentIndex = prev(currentIndex, true, &stepWrapped);
else
currentIndex = next(currentIndex, true, &stepWrapped);
} while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
if (resultIndex.isValid() && wrapped)
*wrapped = anyWrapped;
return resultIndex;
}
......@@ -66,13 +66,15 @@ 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, bool includeGenerated = false) const;
QModelIndex prev(const QModelIndex &idx, bool includeGenerated = false) const;
QModelIndex next(const QModelIndex &idx, bool includeGenerated = false, bool *wrapped = 0) const;
QModelIndex prev(const QModelIndex &idx, bool includeGenerated = false, bool *wrapped = 0) const;
QList<QModelIndex> addResults(const QList<SearchResultItem> &items, SearchResultWindow::AddMode mode);
QModelIndex find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags);
QModelIndex find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags);
QModelIndex find(const QRegExp &expr, const QModelIndex &index,
QTextDocument::FindFlags flags, bool *wrapped = 0);
QModelIndex find(const QString &term, const QModelIndex &index,
QTextDocument::FindFlags flags, bool *wrapped = 0);
signals:
void jumpToSearchResult(const QString &fileName, int lineNumber,
......@@ -87,8 +89,8 @@ private:
QSet<SearchResultTreeItem *> addPath(const QStringList &path);
QVariant data(const SearchResultTreeItem *row, int role) const;
bool setCheckState(const QModelIndex &idx, Qt::CheckState checkState, bool firstCall = true);
QModelIndex nextIndex(const QModelIndex &idx) const;
QModelIndex prevIndex(const QModelIndex &idx) const;
QModelIndex nextIndex(const QModelIndex &idx, bool *wrapped = 0) const;
QModelIndex prevIndex(const QModelIndex &idx, bool *wrapped = 0) const;
SearchResultTreeItem *treeItemAtIndex(const QModelIndex &idx) const;
SearchResultTreeItem *m_rootItem;
......
......@@ -89,7 +89,8 @@ namespace Internal {
Q_OBJECT
public:
SearchResultFindSupport(SearchResultTreeView *view)
: m_view(view)
: m_view(view),
m_incrementalWrappedState(false)
{
}
......@@ -104,6 +105,7 @@ namespace Internal {
void resetIncrementalSearch()
{
m_incrementalFindStart = QModelIndex();
m_incrementalWrappedState = false;
}
void clearResults() { }
......@@ -127,33 +129,51 @@ namespace Internal {
IFindSupport::Result findIncremental(const QString &txt, Find::FindFlags findFlags)
{
if (!m_incrementalFindStart.isValid())
if (!m_incrementalFindStart.isValid()) {
m_incrementalFindStart = m_view->currentIndex();
m_incrementalWrappedState = false;
}
m_view->setCurrentIndex(m_incrementalFindStart);
return find(txt, findFlags);
bool wrapped = false;
IFindSupport::Result result = find(txt, findFlags, &wrapped);
if (wrapped != m_incrementalWrappedState) {
m_incrementalWrappedState = wrapped;
showWrapIndicator(m_view);
}
return result;
}
IFindSupport::Result findStep(const QString &txt, Find::FindFlags findFlags)
{
IFindSupport::Result result = find(txt, findFlags);
if (result == IFindSupport::Found)
bool wrapped = false;
IFindSupport::Result result = find(txt, findFlags, &wrapped);
if (wrapped)
showWrapIndicator(m_view);
if (result == IFindSupport::Found) {
m_incrementalFindStart = m_view->currentIndex();
m_incrementalWrappedState = false;
}
return result;
}
IFindSupport::Result find(const QString &txt, Find::FindFlags findFlags)
IFindSupport::Result find(const QString &txt, Find::FindFlags findFlags, bool *wrapped)
{
if (wrapped)
*wrapped = false;
if (txt.isEmpty())
return IFindSupport::NotFound;
QModelIndex index;
if (findFlags & Find::FindRegularExpression) {
bool sensitive = (findFlags & Find::FindCaseSensitively);
index = m_view->model()->find(QRegExp(txt, (sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)),
m_view->currentIndex(),
Find::textDocumentFlagsForFindFlags(findFlags));
m_view->currentIndex(),
Find::textDocumentFlagsForFindFlags(findFlags),
wrapped);
} else {
index = m_view->model()->find(txt, m_view->currentIndex(),
Find::textDocumentFlagsForFindFlags(findFlags));
index = m_view->model()->find(txt,
m_view->currentIndex(),
Find::textDocumentFlagsForFindFlags(findFlags),
wrapped);
}
if (index.isValid()) {
m_view->setCurrentIndex(index);
......@@ -194,6 +214,7 @@ namespace Internal {
private:
SearchResultTreeView *m_view;
QModelIndex m_incrementalFindStart;
bool m_incrementalWrappedState;
};
struct SearchResultWindowPrivate {
......
Supports Markdown
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