forked from qt-creator/qt-creator
Locator: Add highlighting of the search text
Change-Id: Ia166e9667076e46770a754b626ceb28080139e79 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -116,6 +116,7 @@ SplitterColor=ff313131
|
|||||||
TextColorDisabled=textDisabled
|
TextColorDisabled=textDisabled
|
||||||
TextColorError=ffff4040
|
TextColorError=ffff4040
|
||||||
TextColorHighlight=ffff0000
|
TextColorHighlight=ffff0000
|
||||||
|
TextColorHighlightBackground=555500
|
||||||
TextColorLink=textColorLink
|
TextColorLink=textColorLink
|
||||||
TextColorLinkVisited=textColorLinkVisited
|
TextColorLinkVisited=textColorLinkVisited
|
||||||
TextColorNormal=text
|
TextColorNormal=text
|
||||||
|
@@ -108,6 +108,7 @@ SplitterColor=ff151515
|
|||||||
TextColorDisabled=ff000000
|
TextColorDisabled=ff000000
|
||||||
TextColorError=ffff0000
|
TextColorError=ffff0000
|
||||||
TextColorHighlight=ffa0a0a4
|
TextColorHighlight=ffa0a0a4
|
||||||
|
TextColorHighlightBackground=ffef0b
|
||||||
TextColorLink=ff0057ae
|
TextColorLink=ff0057ae
|
||||||
TextColorLinkVisited=ff644a9b
|
TextColorLinkVisited=ff644a9b
|
||||||
TextColorNormal=ff000000
|
TextColorNormal=ff000000
|
||||||
|
@@ -121,6 +121,7 @@ SplitterColor=splitter
|
|||||||
TextColorDisabled=textDisabled
|
TextColorDisabled=textDisabled
|
||||||
TextColorError=ffff4040
|
TextColorError=ffff4040
|
||||||
TextColorHighlight=ffff0000
|
TextColorHighlight=ffff0000
|
||||||
|
TextColorHighlightBackground=8a7f2c
|
||||||
TextColorLink=textColorLink
|
TextColorLink=textColorLink
|
||||||
TextColorLinkVisited=textColorLinkVisited
|
TextColorLinkVisited=textColorLinkVisited
|
||||||
TextColorNormal=text
|
TextColorNormal=text
|
||||||
|
@@ -119,6 +119,7 @@ SplitterColor=splitter
|
|||||||
TextColorDisabled=textDisabled
|
TextColorDisabled=textDisabled
|
||||||
TextColorError=ffff4040
|
TextColorError=ffff4040
|
||||||
TextColorHighlight=ffff0000
|
TextColorHighlight=ffff0000
|
||||||
|
TextColorHighlightBackground=ffef0b
|
||||||
TextColorLink=ff007af4
|
TextColorLink=ff007af4
|
||||||
TextColorLinkVisited=ffa57aff
|
TextColorLinkVisited=ffa57aff
|
||||||
TextColorNormal=text
|
TextColorNormal=text
|
||||||
|
@@ -117,6 +117,7 @@ SplitterColor=splitter
|
|||||||
TextColorDisabled=textDisabled
|
TextColorDisabled=textDisabled
|
||||||
TextColorError=ffff4040
|
TextColorError=ffff4040
|
||||||
TextColorHighlight=ffff0000
|
TextColorHighlight=ffff0000
|
||||||
|
TextColorHighlightBackground=ffef0b
|
||||||
TextColorLink=ff007af4
|
TextColorLink=ff007af4
|
||||||
TextColorLinkVisited=ffa57aff
|
TextColorLinkVisited=ffa57aff
|
||||||
TextColorNormal=text
|
TextColorNormal=text
|
||||||
|
@@ -116,6 +116,7 @@ public:
|
|||||||
TextColorDisabled,
|
TextColorDisabled,
|
||||||
TextColorError,
|
TextColorError,
|
||||||
TextColorHighlight,
|
TextColorHighlight,
|
||||||
|
TextColorHighlightBackground,
|
||||||
TextColorLink,
|
TextColorLink,
|
||||||
TextColorLinkVisited,
|
TextColorLinkVisited,
|
||||||
TextColorNormal,
|
TextColorNormal,
|
||||||
|
@@ -65,10 +65,12 @@ void CMakeLocatorFilter::prepareSearch(const QString &entry)
|
|||||||
if (!cmakeProject)
|
if (!cmakeProject)
|
||||||
continue;
|
continue;
|
||||||
foreach (const QString &title, cmakeProject->buildTargetTitles()) {
|
foreach (const QString &title, cmakeProject->buildTargetTitles()) {
|
||||||
if (title.contains(entry)) {
|
const int index = title.indexOf(entry);
|
||||||
Core::LocatorFilterEntry entry(this, title, cmakeProject->projectFilePath().toString());
|
if (index >= 0) {
|
||||||
entry.extraInfo = FileUtils::shortNativePath(cmakeProject->projectFilePath());
|
Core::LocatorFilterEntry filterEntry(this, title, cmakeProject->projectFilePath().toString());
|
||||||
m_result.append(entry);
|
filterEntry.extraInfo = FileUtils::shortNativePath(cmakeProject->projectFilePath());
|
||||||
|
filterEntry.highlightInfo = {index, entry.length()};
|
||||||
|
m_result.append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -98,18 +98,18 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
|
|||||||
{
|
{
|
||||||
QList<LocatorFilterEntry> betterEntries;
|
QList<LocatorFilterEntry> betterEntries;
|
||||||
QList<LocatorFilterEntry> goodEntries;
|
QList<LocatorFilterEntry> goodEntries;
|
||||||
const QString trimmed = trimWildcards(QDir::fromNativeSeparators(origEntry));
|
const QString entry = QDir::fromNativeSeparators(origEntry);
|
||||||
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(trimmed);
|
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
|
||||||
QStringMatcher matcher(fp.filePath, Qt::CaseInsensitive);
|
const Qt::CaseSensitivity cs = caseSensitivity(fp.filePath);
|
||||||
const QChar asterisk = QLatin1Char('*');
|
QStringMatcher matcher(fp.filePath, cs);
|
||||||
QRegExp regexp(asterisk + fp.filePath+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
QRegExp regexp(fp.filePath, cs, QRegExp::Wildcard);
|
||||||
if (!regexp.isValid()) {
|
if (!regexp.isValid()) {
|
||||||
d->m_current.clear(); // free memory
|
d->m_current.clear(); // free memory
|
||||||
return betterEntries;
|
return betterEntries;
|
||||||
}
|
}
|
||||||
const QChar pathSeparator(QLatin1Char('/'));
|
const QChar pathSeparator(QLatin1Char('/'));
|
||||||
const bool hasPathSeparator = fp.filePath.contains(pathSeparator);
|
const bool hasPathSeparator = fp.filePath.contains(pathSeparator);
|
||||||
const bool hasWildcard = fp.filePath.contains(asterisk) || fp.filePath.contains(QLatin1Char('?'));
|
const bool hasWildcard = containsWildcard(fp.filePath);
|
||||||
const bool containsPreviousEntry = !d->m_current.previousEntry.isEmpty()
|
const bool containsPreviousEntry = !d->m_current.previousEntry.isEmpty()
|
||||||
&& fp.filePath.contains(d->m_current.previousEntry);
|
&& fp.filePath.contains(d->m_current.previousEntry);
|
||||||
const bool pathSeparatorAdded = !d->m_current.previousEntry.contains(pathSeparator)
|
const bool pathSeparatorAdded = !d->m_current.previousEntry.contains(pathSeparator)
|
||||||
@@ -124,7 +124,6 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
|
|||||||
d->m_current.previousResultPaths.clear();
|
d->m_current.previousResultPaths.clear();
|
||||||
d->m_current.previousResultNames.clear();
|
d->m_current.previousResultNames.clear();
|
||||||
d->m_current.previousEntry = fp.filePath;
|
d->m_current.previousEntry = fp.filePath;
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(fp.filePath);
|
|
||||||
d->m_current.iterator->toFront();
|
d->m_current.iterator->toFront();
|
||||||
bool canceled = false;
|
bool canceled = false;
|
||||||
while (d->m_current.iterator->hasNext()) {
|
while (d->m_current.iterator->hasNext()) {
|
||||||
@@ -137,16 +136,32 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
|
|||||||
QString path = d->m_current.iterator->filePath();
|
QString path = d->m_current.iterator->filePath();
|
||||||
QString name = d->m_current.iterator->fileName();
|
QString name = d->m_current.iterator->fileName();
|
||||||
QString matchText = hasPathSeparator ? path : name;
|
QString matchText = hasPathSeparator ? path : name;
|
||||||
if ((hasWildcard && regexp.exactMatch(matchText))
|
int index = hasWildcard ? regexp.indexIn(matchText) : matcher.indexIn(matchText);
|
||||||
|| (!hasWildcard && matcher.indexIn(matchText) != -1)) {
|
|
||||||
|
if (index >= 0) {
|
||||||
QFileInfo fi(path);
|
QFileInfo fi(path);
|
||||||
LocatorFilterEntry entry(this, fi.fileName(), QString(path + fp.postfix));
|
LocatorFilterEntry filterEntry(this, fi.fileName(), QString(path + fp.postfix));
|
||||||
entry.extraInfo = FileUtils::shortNativePath(FileName(fi));
|
filterEntry.fileName = path;
|
||||||
entry.fileName = path;
|
filterEntry.extraInfo = FileUtils::shortNativePath(FileName(fi));
|
||||||
if (matchText.startsWith(fp.filePath, caseSensitivityForPrefix))
|
|
||||||
betterEntries.append(entry);
|
LocatorFilterEntry::HighlightInfo::DataType hDataType = LocatorFilterEntry::HighlightInfo::DisplayName;
|
||||||
|
int length = hasWildcard ? regexp.matchedLength() : fp.filePath.length();
|
||||||
|
const bool betterMatch = index == 0;
|
||||||
|
if (hasPathSeparator) {
|
||||||
|
const int indexCandidate = index + filterEntry.extraInfo.length() - path.length();
|
||||||
|
const int cutOff = indexCandidate < 0 ? -indexCandidate : 0;
|
||||||
|
index = qMax(indexCandidate, 0);
|
||||||
|
length = qMax(length - cutOff, 1);
|
||||||
|
hDataType = LocatorFilterEntry::HighlightInfo::ExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
filterEntry.highlightInfo = LocatorFilterEntry::HighlightInfo(index, length, hDataType);
|
||||||
|
|
||||||
|
if (betterMatch)
|
||||||
|
betterEntries.append(filterEntry);
|
||||||
else
|
else
|
||||||
goodEntries.append(entry);
|
goodEntries.append(filterEntry);
|
||||||
d->m_current.previousResultPaths.append(path);
|
d->m_current.previousResultPaths.append(path);
|
||||||
d->m_current.previousResultNames.append(name);
|
d->m_current.previousResultNames.append(name);
|
||||||
}
|
}
|
||||||
|
@@ -67,20 +67,27 @@ QList<LocatorFilterEntry> CommandLocator::matchesFor(QFutureInterface<LocatorFil
|
|||||||
// Get active, enabled actions matching text, store in list.
|
// Get active, enabled actions matching text, store in list.
|
||||||
// Reference via index in extraInfo.
|
// Reference via index in extraInfo.
|
||||||
const QChar ampersand = QLatin1Char('&');
|
const QChar ampersand = QLatin1Char('&');
|
||||||
const Qt::CaseSensitivity caseSensitivity_ = caseSensitivity(entry);
|
const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry);
|
||||||
const int count = d->commands.size();
|
const int count = d->commands.size();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
if (d->commands.at(i)->isActive()) {
|
if (!d->commands.at(i)->isActive())
|
||||||
if (QAction *action = d->commands.at(i)->action())
|
continue;
|
||||||
if (action->isEnabled()) {
|
|
||||||
QString text = action->text();
|
QAction *action = d->commands.at(i)->action();
|
||||||
text.remove(ampersand);
|
if (action && action->isEnabled()) {
|
||||||
if (text.startsWith(entry, caseSensitivity_))
|
QString text = action->text();
|
||||||
betterEntries.append(LocatorFilterEntry(this, text, QVariant(i)));
|
text.remove(ampersand);
|
||||||
else if (text.contains(entry, caseSensitivity_))
|
const int index = text.indexOf(entry, 0, entryCaseSensitivity);
|
||||||
goodEntries.append(LocatorFilterEntry(this, text, QVariant(i)));
|
if (index >= 0) {
|
||||||
|
LocatorFilterEntry filterEntry(this, text, QVariant(i));
|
||||||
|
filterEntry.highlightInfo = {index, entry.length()};
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
betterEntries.append(filterEntry);
|
||||||
|
else
|
||||||
|
goodEntries.append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,16 +60,20 @@ QList<LocatorFilterEntry> ExecuteFilter::matchesFor(QFutureInterface<LocatorFilt
|
|||||||
if (!entry.isEmpty()) // avoid empty entry
|
if (!entry.isEmpty()) // avoid empty entry
|
||||||
value.append(LocatorFilterEntry(this, entry, QVariant()));
|
value.append(LocatorFilterEntry(this, entry, QVariant()));
|
||||||
QList<LocatorFilterEntry> others;
|
QList<LocatorFilterEntry> others;
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
|
const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry);
|
||||||
foreach (const QString &i, m_commandHistory) {
|
foreach (const QString &cmd, m_commandHistory) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
if (i == entry) // avoid repeated entry
|
if (cmd == entry) // avoid repeated entry
|
||||||
continue;
|
continue;
|
||||||
if (i.startsWith(entry, caseSensitivityForPrefix))
|
LocatorFilterEntry filterEntry(this, cmd, QVariant());
|
||||||
value.append(LocatorFilterEntry(this, i, QVariant()));
|
const int index = cmd.indexOf(entry, 0, entryCaseSensitivity);
|
||||||
else
|
if (index >= 0) {
|
||||||
others.append(LocatorFilterEntry(this, i, QVariant()));
|
filterEntry.highlightInfo = {index, entry.length()};
|
||||||
|
value.append(filterEntry);
|
||||||
|
} else {
|
||||||
|
others.append(filterEntry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
value.append(others);
|
value.append(others);
|
||||||
return value;
|
return value;
|
||||||
|
@@ -64,17 +64,23 @@ void ExternalToolsFilter::refresh(QFutureInterface<void> &)
|
|||||||
void ExternalToolsFilter::prepareSearch(const QString &entry)
|
void ExternalToolsFilter::prepareSearch(const QString &entry)
|
||||||
{
|
{
|
||||||
m_results.clear();
|
m_results.clear();
|
||||||
|
const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry);
|
||||||
Qt::CaseSensitivity useCaseSensitivity = caseSensitivity(entry);
|
|
||||||
const QMap<QString, ExternalTool *> externalToolsById = ExternalToolManager::toolsById();
|
const QMap<QString, ExternalTool *> externalToolsById = ExternalToolManager::toolsById();
|
||||||
auto end = externalToolsById.cend();
|
auto end = externalToolsById.cend();
|
||||||
for (auto it = externalToolsById.cbegin(); it != end; ++it) {
|
for (auto it = externalToolsById.cbegin(); it != end; ++it) {
|
||||||
ExternalTool *tool = *it;
|
ExternalTool *tool = *it;
|
||||||
if (tool->description().contains(entry, useCaseSensitivity) ||
|
|
||||||
tool->displayName().contains(entry, useCaseSensitivity)) {
|
|
||||||
|
|
||||||
|
int index = tool->displayName().indexOf(entry, 0, entryCaseSensitivity);
|
||||||
|
LocatorFilterEntry::HighlightInfo::DataType hDataType = LocatorFilterEntry::HighlightInfo::DisplayName;
|
||||||
|
if (index < 0) {
|
||||||
|
index = tool->description().indexOf(entry, 0, entryCaseSensitivity);
|
||||||
|
hDataType = LocatorFilterEntry::HighlightInfo::ExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= 0) {
|
||||||
LocatorFilterEntry filterEntry(this, tool->displayName(), QVariant::fromValue(tool));
|
LocatorFilterEntry filterEntry(this, tool->displayName(), QVariant::fromValue(tool));
|
||||||
filterEntry.extraInfo = tool->description();
|
filterEntry.extraInfo = tool->description();
|
||||||
|
filterEntry.highlightInfo = LocatorFilterEntry::HighlightInfo(index, entry.length(), hDataType);
|
||||||
m_results.append(filterEntry);
|
m_results.append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,11 +41,16 @@ namespace {
|
|||||||
|
|
||||||
QList<LocatorFilterEntry> *categorize(const QString &entry, const QString &candidate,
|
QList<LocatorFilterEntry> *categorize(const QString &entry, const QString &candidate,
|
||||||
Qt::CaseSensitivity caseSensitivity,
|
Qt::CaseSensitivity caseSensitivity,
|
||||||
QList<LocatorFilterEntry> *betterEntries, QList<LocatorFilterEntry> *goodEntries)
|
QList<LocatorFilterEntry> *betterEntries, QList<LocatorFilterEntry> *goodEntries,
|
||||||
|
int *index)
|
||||||
{
|
{
|
||||||
if (entry.isEmpty() || candidate.startsWith(entry, caseSensitivity))
|
const int position = candidate.indexOf(entry, 0, caseSensitivity);
|
||||||
|
if (index)
|
||||||
|
*index = position;
|
||||||
|
|
||||||
|
if (entry.isEmpty() || position == 0)
|
||||||
return betterEntries;
|
return betterEntries;
|
||||||
else if (candidate.contains(entry, caseSensitivity))
|
else if (position >= 0)
|
||||||
return goodEntries;
|
return goodEntries;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -99,11 +104,15 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
|
|||||||
foreach (const QString &dir, dirs) {
|
foreach (const QString &dir, dirs) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
if (QList<LocatorFilterEntry> *category = categorize(entryFileName, dir, caseSensitivity_, &betterEntries,
|
int index = -1;
|
||||||
&goodEntries)) {
|
if (QList<LocatorFilterEntry> *category = categorize(entryFileName, dir, caseSensitivity_,
|
||||||
|
&betterEntries, &goodEntries, &index)) {
|
||||||
const QString fullPath = dirInfo.filePath(dir);
|
const QString fullPath = dirInfo.filePath(dir);
|
||||||
LocatorFilterEntry filterEntry(this, dir, QVariant());
|
LocatorFilterEntry filterEntry(this, dir, QVariant());
|
||||||
filterEntry.fileName = fullPath;
|
filterEntry.fileName = fullPath;
|
||||||
|
if (index >= 0)
|
||||||
|
filterEntry.highlightInfo = {index, entryFileName.length()};
|
||||||
|
|
||||||
category->append(filterEntry);
|
category->append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,11 +122,15 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
|
|||||||
foreach (const QString &file, files) {
|
foreach (const QString &file, files) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
if (QList<LocatorFilterEntry> *category = categorize(fileName, file, caseSensitivity_, &betterEntries,
|
int index = -1;
|
||||||
&goodEntries)) {
|
if (QList<LocatorFilterEntry> *category = categorize(fileName, file, caseSensitivity_,
|
||||||
|
&betterEntries, &goodEntries, &index)) {
|
||||||
const QString fullPath = dirInfo.filePath(file);
|
const QString fullPath = dirInfo.filePath(file);
|
||||||
LocatorFilterEntry filterEntry(this, file, QString(fullPath + fp.postfix));
|
LocatorFilterEntry filterEntry(this, file, QString(fullPath + fp.postfix));
|
||||||
filterEntry.fileName = fullPath;
|
filterEntry.fileName = fullPath;
|
||||||
|
if (index >= 0)
|
||||||
|
filterEntry.highlightInfo = {index, fileName.length()};
|
||||||
|
|
||||||
category->append(filterEntry);
|
category->append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -118,27 +118,16 @@ bool ILocatorFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ILocatorFilter::trimWildcards(const QString &str)
|
|
||||||
{
|
|
||||||
if (str.isEmpty())
|
|
||||||
return str;
|
|
||||||
int first = 0, last = str.size() - 1;
|
|
||||||
const QChar asterisk = QLatin1Char('*');
|
|
||||||
const QChar question = QLatin1Char('?');
|
|
||||||
while (first < str.size() && (str.at(first) == asterisk || str.at(first) == question))
|
|
||||||
++first;
|
|
||||||
while (last >= 0 && (str.at(last) == asterisk || str.at(last) == question))
|
|
||||||
--last;
|
|
||||||
if (first > last)
|
|
||||||
return QString();
|
|
||||||
return str.mid(first, last - first + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::CaseSensitivity ILocatorFilter::caseSensitivity(const QString &str)
|
Qt::CaseSensitivity ILocatorFilter::caseSensitivity(const QString &str)
|
||||||
{
|
{
|
||||||
return str == str.toLower() ? Qt::CaseInsensitive : Qt::CaseSensitive;
|
return str == str.toLower() ? Qt::CaseInsensitive : Qt::CaseSensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ILocatorFilter::containsWildcard(const QString &str)
|
||||||
|
{
|
||||||
|
return str.contains(QLatin1Char('*')) || str.contains(QLatin1Char('?'));
|
||||||
|
}
|
||||||
|
|
||||||
QString ILocatorFilter::msgConfigureDialogTitle()
|
QString ILocatorFilter::msgConfigureDialogTitle()
|
||||||
{
|
{
|
||||||
return tr("Filter Configuration");
|
return tr("Filter Configuration");
|
||||||
|
@@ -37,6 +37,23 @@ class ILocatorFilter;
|
|||||||
|
|
||||||
struct LocatorFilterEntry
|
struct LocatorFilterEntry
|
||||||
{
|
{
|
||||||
|
struct HighlightInfo {
|
||||||
|
enum DataType {
|
||||||
|
DisplayName,
|
||||||
|
ExtraInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
HighlightInfo(int startIndex, int length, DataType type = DataType::DisplayName)
|
||||||
|
: startIndex(startIndex)
|
||||||
|
, length(length)
|
||||||
|
, dataType(type)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int startIndex;
|
||||||
|
int length;
|
||||||
|
DataType dataType;
|
||||||
|
};
|
||||||
|
|
||||||
LocatorFilterEntry() = default;
|
LocatorFilterEntry() = default;
|
||||||
|
|
||||||
LocatorFilterEntry(ILocatorFilter *fromFilter, const QString &name, const QVariant &data,
|
LocatorFilterEntry(ILocatorFilter *fromFilter, const QString &name, const QVariant &data,
|
||||||
@@ -67,6 +84,14 @@ struct LocatorFilterEntry
|
|||||||
QString fileName;
|
QString fileName;
|
||||||
/* internal */
|
/* internal */
|
||||||
bool fileIconResolved = false;
|
bool fileIconResolved = false;
|
||||||
|
/* highlighting support */
|
||||||
|
HighlightInfo highlightInfo{0, 0};
|
||||||
|
|
||||||
|
static bool compareLexigraphically(const Core::LocatorFilterEntry &lhs,
|
||||||
|
const Core::LocatorFilterEntry &rhs)
|
||||||
|
{
|
||||||
|
return lhs.displayName < rhs.displayName;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CORE_EXPORT ILocatorFilter : public QObject
|
class CORE_EXPORT ILocatorFilter : public QObject
|
||||||
@@ -134,8 +159,8 @@ public:
|
|||||||
/* Returns whether the filter should be enabled and used in menus. */
|
/* Returns whether the filter should be enabled and used in menus. */
|
||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
|
|
||||||
static QString trimWildcards(const QString &str);
|
|
||||||
static Qt::CaseSensitivity caseSensitivity(const QString &str);
|
static Qt::CaseSensitivity caseSensitivity(const QString &str);
|
||||||
|
static bool containsWildcard(const QString &str);
|
||||||
|
|
||||||
static QString msgConfigureDialogTitle();
|
static QString msgConfigureDialogTitle();
|
||||||
static QString msgPrefixLabel();
|
static QString msgPrefixLabel();
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
#include <coreplugin/modemanager.h>
|
#include <coreplugin/modemanager.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/fileiconprovider.h>
|
#include <coreplugin/fileiconprovider.h>
|
||||||
|
#include <coreplugin/find/searchresulttreeitemdelegate.h>
|
||||||
|
#include <coreplugin/find/searchresulttreeitemroles.h>
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
#include <coreplugin/mainwindow.h>
|
#include <coreplugin/mainwindow.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -69,8 +71,16 @@ namespace Internal {
|
|||||||
class LocatorModel : public QAbstractListModel
|
class LocatorModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum Columns {
|
||||||
|
DisplayNameColumn,
|
||||||
|
ExtraInfoColumn,
|
||||||
|
ColumnCount
|
||||||
|
};
|
||||||
|
|
||||||
LocatorModel(QObject *parent = 0)
|
LocatorModel(QObject *parent = 0)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
|
, mBackgroundColor(Utils::creatorTheme()->color(Utils::Theme::TextColorHighlightBackground).name())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
@@ -83,6 +93,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
mutable QList<LocatorFilterEntry> mEntries;
|
mutable QList<LocatorFilterEntry> mEntries;
|
||||||
bool hasExtraInfo = false;
|
bool hasExtraInfo = false;
|
||||||
|
QColor mBackgroundColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompletionList : public QTreeView
|
class CompletionList : public QTreeView
|
||||||
@@ -144,7 +155,7 @@ int LocatorModel::columnCount(const QModelIndex &parent) const
|
|||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
return hasExtraInfo ? 2 : 1;
|
return hasExtraInfo ? ColumnCount : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant LocatorModel::data(const QModelIndex &index, int role) const
|
QVariant LocatorModel::data(const QModelIndex &index, int role) const
|
||||||
@@ -154,9 +165,9 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
if (index.column() == 0)
|
if (index.column() == DisplayNameColumn)
|
||||||
return mEntries.at(index.row()).displayName;
|
return mEntries.at(index.row()).displayName;
|
||||||
else if (index.column() == 1)
|
else if (index.column() == ExtraInfoColumn)
|
||||||
return mEntries.at(index.row()).extraInfo;
|
return mEntries.at(index.row()).extraInfo;
|
||||||
break;
|
break;
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
@@ -167,7 +178,8 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const
|
|||||||
+ QLatin1String("\n\n") + mEntries.at(index.row()).extraInfo);
|
+ QLatin1String("\n\n") + mEntries.at(index.row()).extraInfo);
|
||||||
break;
|
break;
|
||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
if (index.column() == 0) {
|
case ItemDataRoles::ResultIconRole:
|
||||||
|
if (index.column() == DisplayNameColumn) {
|
||||||
LocatorFilterEntry &entry = mEntries[index.row()];
|
LocatorFilterEntry &entry = mEntries[index.row()];
|
||||||
if (!entry.fileIconResolved && !entry.fileName.isEmpty() && entry.displayIcon.isNull()) {
|
if (!entry.fileIconResolved && !entry.fileName.isEmpty() && entry.displayIcon.isNull()) {
|
||||||
entry.fileIconResolved = true;
|
entry.fileIconResolved = true;
|
||||||
@@ -177,11 +189,25 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::ForegroundRole:
|
case Qt::ForegroundRole:
|
||||||
if (index.column() == 1)
|
if (index.column() == ExtraInfoColumn)
|
||||||
return QColor(Qt::darkGray);
|
return QColor(Qt::darkGray);
|
||||||
break;
|
break;
|
||||||
case Qt::UserRole:
|
case ItemDataRoles::ResultItemRole:
|
||||||
return qVariantFromValue(mEntries.at(index.row()));
|
return qVariantFromValue(mEntries.at(index.row()));
|
||||||
|
case ItemDataRoles::ResultBeginColumnNumberRole:
|
||||||
|
case ItemDataRoles::SearchTermLengthRole: {
|
||||||
|
LocatorFilterEntry &entry = mEntries[index.row()];
|
||||||
|
const int highlightColumn = entry.highlightInfo.dataType == LocatorFilterEntry::HighlightInfo::DisplayName
|
||||||
|
? DisplayNameColumn
|
||||||
|
: ExtraInfoColumn;
|
||||||
|
if (highlightColumn == index.column()) {
|
||||||
|
const bool startIndexRole = role == ItemDataRoles::ResultBeginColumnNumberRole;
|
||||||
|
return startIndexRole ? entry.highlightInfo.startIndex : entry.highlightInfo.length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ItemDataRoles::ResultHighlightBackgroundColor:
|
||||||
|
return mBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -202,6 +228,7 @@ void LocatorModel::addEntries(const QList<LocatorFilterEntry> &entries)
|
|||||||
CompletionList::CompletionList(QWidget *parent)
|
CompletionList::CompletionList(QWidget *parent)
|
||||||
: QTreeView(parent)
|
: QTreeView(parent)
|
||||||
{
|
{
|
||||||
|
setItemDelegate(new SearchResultTreeItemDelegate(0, this));
|
||||||
setRootIsDecorated(false);
|
setRootIsDecorated(false);
|
||||||
setUniformRowHeights(true);
|
setUniformRowHeights(true);
|
||||||
header()->hide();
|
header()->hide();
|
||||||
@@ -611,9 +638,10 @@ void LocatorWidget::acceptCurrentEntry()
|
|||||||
const QModelIndex index = m_completionList->currentIndex();
|
const QModelIndex index = m_completionList->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
const LocatorFilterEntry entry = m_locatorModel->data(index, Qt::UserRole).value<LocatorFilterEntry>();
|
const LocatorFilterEntry entry = m_locatorModel->data(index, ItemDataRoles::ResultItemRole).value<LocatorFilterEntry>();
|
||||||
m_completionList->hide();
|
m_completionList->hide();
|
||||||
m_fileLineEdit->clearFocus();
|
m_fileLineEdit->clearFocus();
|
||||||
|
Q_ASSERT(entry.filter != nullptr);
|
||||||
entry.filter->accept(entry);
|
entry.filter->accept(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,19 +55,16 @@ OpenDocumentsFilter::OpenDocumentsFilter()
|
|||||||
this, &OpenDocumentsFilter::refreshInternally);
|
this, &OpenDocumentsFilter::refreshInternally);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry)
|
QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
|
||||||
|
const QString &entry)
|
||||||
{
|
{
|
||||||
QList<LocatorFilterEntry> goodEntries;
|
QList<LocatorFilterEntry> goodEntries;
|
||||||
QList<LocatorFilterEntry> betterEntries;
|
QList<LocatorFilterEntry> betterEntries;
|
||||||
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
|
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
|
||||||
const QChar asterisk = QLatin1Char('*');
|
QRegExp regexp(fp.filePath, caseSensitivity(fp.filePath), QRegExp::Wildcard);
|
||||||
QString pattern = QString(asterisk);
|
|
||||||
pattern += fp.filePath;
|
|
||||||
pattern += asterisk;
|
|
||||||
QRegExp regexp(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
|
|
||||||
if (!regexp.isValid())
|
if (!regexp.isValid())
|
||||||
return goodEntries;
|
return goodEntries;
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(fp.filePath);
|
|
||||||
foreach (const Entry &editorEntry, editors()) {
|
foreach (const Entry &editorEntry, editors()) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
@@ -75,13 +72,16 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat
|
|||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
QString displayName = editorEntry.displayName;
|
QString displayName = editorEntry.displayName;
|
||||||
if (regexp.exactMatch(displayName)) {
|
const int index = regexp.indexIn(displayName);
|
||||||
LocatorFilterEntry fiEntry(this, displayName, QString(fileName + fp.postfix));
|
if (index >= 0) {
|
||||||
fiEntry.extraInfo = FileUtils::shortNativePath(FileName::fromString(fileName));
|
LocatorFilterEntry filterEntry(this, displayName, QString(fileName + fp.postfix));
|
||||||
fiEntry.fileName = fileName;
|
filterEntry.extraInfo = FileUtils::shortNativePath(FileName::fromString(fileName));
|
||||||
QList<LocatorFilterEntry> &category = displayName.startsWith(fp.filePath, caseSensitivityForPrefix)
|
filterEntry.fileName = fileName;
|
||||||
? betterEntries : goodEntries;
|
filterEntry.highlightInfo = {index, regexp.matchedLength()};
|
||||||
category.append(fiEntry);
|
if (index == 0)
|
||||||
|
betterEntries.append(filterEntry);
|
||||||
|
else
|
||||||
|
goodEntries.append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
betterEntries.append(goodEntries);
|
betterEntries.append(goodEntries);
|
||||||
|
@@ -62,18 +62,16 @@ CppCurrentDocumentFilter::CppCurrentDocumentFilter(CppTools::CppModelManager *ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor(
|
QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor(
|
||||||
QFutureInterface<Core::LocatorFilterEntry> &future, const QString & origEntry)
|
QFutureInterface<Core::LocatorFilterEntry> &future, const QString & entry)
|
||||||
{
|
{
|
||||||
QString entry = trimWildcards(origEntry);
|
|
||||||
QList<Core::LocatorFilterEntry> goodEntries;
|
QList<Core::LocatorFilterEntry> goodEntries;
|
||||||
QList<Core::LocatorFilterEntry> betterEntries;
|
QList<Core::LocatorFilterEntry> betterEntries;
|
||||||
QStringMatcher matcher(entry, Qt::CaseInsensitive);
|
const Qt::CaseSensitivity cs = caseSensitivity(entry);
|
||||||
const QChar asterisk = QLatin1Char('*');
|
QStringMatcher matcher(entry, cs);
|
||||||
QRegExp regexp(asterisk + entry + asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
QRegExp regexp(entry, cs, QRegExp::Wildcard);
|
||||||
if (!regexp.isValid())
|
if (!regexp.isValid())
|
||||||
return goodEntries;
|
return goodEntries;
|
||||||
bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?')));
|
bool hasWildcard = containsWildcard(entry);
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
|
|
||||||
|
|
||||||
foreach (IndexItem::Ptr info, itemsOfCurrentDocument()) {
|
foreach (IndexItem::Ptr info, itemsOfCurrentDocument()) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
@@ -85,20 +83,30 @@ QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor(
|
|||||||
else if (info->type() == IndexItem::Function)
|
else if (info->type() == IndexItem::Function)
|
||||||
matchString += info->symbolType();
|
matchString += info->symbolType();
|
||||||
|
|
||||||
if ((hasWildcard && regexp.exactMatch(matchString))
|
int index = hasWildcard ? regexp.indexIn(matchString) : matcher.indexIn(matchString);
|
||||||
|| (!hasWildcard && matcher.indexIn(matchString) != -1))
|
if (index >= 0) {
|
||||||
{
|
const bool betterMatch = index == 0;
|
||||||
QVariant id = qVariantFromValue(info);
|
QVariant id = qVariantFromValue(info);
|
||||||
QString name = matchString;
|
QString name = matchString;
|
||||||
QString extraInfo = info->symbolScope();
|
QString extraInfo = info->symbolScope();
|
||||||
if (info->type() == IndexItem::Function) {
|
if (info->type() == IndexItem::Function) {
|
||||||
if (info->unqualifiedNameAndScope(matchString, &name, &extraInfo))
|
if (info->unqualifiedNameAndScope(matchString, &name, &extraInfo)) {
|
||||||
name += info->symbolType();
|
name += info->symbolType();
|
||||||
|
index = hasWildcard ? regexp.indexIn(name) : matcher.indexIn(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::LocatorFilterEntry filterEntry(this, name, id, info->icon());
|
Core::LocatorFilterEntry filterEntry(this, name, id, info->icon());
|
||||||
filterEntry.extraInfo = extraInfo;
|
filterEntry.extraInfo = extraInfo;
|
||||||
|
if (index < 0) {
|
||||||
if (matchString.startsWith(entry, caseSensitivityForPrefix))
|
index = hasWildcard ? regexp.indexIn(extraInfo) : matcher.indexIn(extraInfo);
|
||||||
|
filterEntry.highlightInfo.dataType = Core::LocatorFilterEntry::HighlightInfo::ExtraInfo;
|
||||||
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
filterEntry.highlightInfo.startIndex = index;
|
||||||
|
filterEntry.highlightInfo.length = hasWildcard ? regexp.matchedLength() : entry.length();
|
||||||
|
}
|
||||||
|
if (betterMatch)
|
||||||
betterEntries.append(filterEntry);
|
betterEntries.append(filterEntry);
|
||||||
else
|
else
|
||||||
goodEntries.append(filterEntry);
|
goodEntries.append(filterEntry);
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QStringMatcher>
|
#include <QStringMatcher>
|
||||||
@@ -66,26 +67,18 @@ void CppLocatorFilter::refresh(QFutureInterface<void> &future)
|
|||||||
Q_UNUSED(future)
|
Q_UNUSED(future)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compareLexigraphically(const Core::LocatorFilterEntry &a,
|
|
||||||
const Core::LocatorFilterEntry &b)
|
|
||||||
{
|
|
||||||
return a.displayName < b.displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
|
QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
|
||||||
QFutureInterface<Core::LocatorFilterEntry> &future, const QString &origEntry)
|
QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
|
||||||
{
|
{
|
||||||
QString entry = trimWildcards(origEntry);
|
|
||||||
QList<Core::LocatorFilterEntry> goodEntries;
|
QList<Core::LocatorFilterEntry> goodEntries;
|
||||||
QList<Core::LocatorFilterEntry> betterEntries;
|
QList<Core::LocatorFilterEntry> betterEntries;
|
||||||
const QChar asterisk = QLatin1Char('*');
|
const Qt::CaseSensitivity cs = caseSensitivity(entry);
|
||||||
QStringMatcher matcher(entry, Qt::CaseInsensitive);
|
QStringMatcher matcher(entry, cs);
|
||||||
QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
QRegExp regexp(entry, cs, QRegExp::Wildcard);
|
||||||
if (!regexp.isValid())
|
if (!regexp.isValid())
|
||||||
return goodEntries;
|
return goodEntries;
|
||||||
bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?')));
|
bool hasWildcard = containsWildcard(entry);
|
||||||
bool hasColonColon = entry.contains(QLatin1String("::"));
|
bool hasColonColon = entry.contains(QLatin1String("::"));
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
|
|
||||||
const IndexItem::ItemType wanted = matchTypes();
|
const IndexItem::ItemType wanted = matchTypes();
|
||||||
|
|
||||||
m_data->filterAllFiles([&](const IndexItem::Ptr &info) -> IndexItem::VisitorResult {
|
m_data->filterAllFiles([&](const IndexItem::Ptr &info) -> IndexItem::VisitorResult {
|
||||||
@@ -93,10 +86,20 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
|
|||||||
return IndexItem::Break;
|
return IndexItem::Break;
|
||||||
if (info->type() & wanted) {
|
if (info->type() & wanted) {
|
||||||
const QString matchString = hasColonColon ? info->scopedSymbolName() : info->symbolName();
|
const QString matchString = hasColonColon ? info->scopedSymbolName() : info->symbolName();
|
||||||
if ((hasWildcard && regexp.exactMatch(matchString)) ||
|
int index = hasWildcard ? regexp.indexIn(matchString) : matcher.indexIn(matchString);
|
||||||
(!hasWildcard && matcher.indexIn(matchString) != -1)) {
|
if (index >= 0) {
|
||||||
const Core::LocatorFilterEntry filterEntry = filterEntryFromIndexItem(info);
|
const bool betterMatch = index == 0;
|
||||||
if (matchString.startsWith(entry, caseSensitivityForPrefix))
|
Core::LocatorFilterEntry filterEntry = filterEntryFromIndexItem(info);
|
||||||
|
|
||||||
|
if (matchString != filterEntry.displayName) {
|
||||||
|
index = hasWildcard ? regexp.indexIn(filterEntry.displayName)
|
||||||
|
: matcher.indexIn(filterEntry.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
filterEntry.highlightInfo = {index, (hasWildcard ? regexp.matchedLength() : entry.length())};
|
||||||
|
|
||||||
|
if (betterMatch)
|
||||||
betterEntries.append(filterEntry);
|
betterEntries.append(filterEntry);
|
||||||
else
|
else
|
||||||
goodEntries.append(filterEntry);
|
goodEntries.append(filterEntry);
|
||||||
@@ -110,9 +113,9 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (goodEntries.size() < 1000)
|
if (goodEntries.size() < 1000)
|
||||||
std::stable_sort(goodEntries.begin(), goodEntries.end(), compareLexigraphically);
|
Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
|
||||||
if (betterEntries.size() < 1000)
|
if (betterEntries.size() < 1000)
|
||||||
std::stable_sort(betterEntries.begin(), betterEntries.end(), compareLexigraphically);
|
Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
|
||||||
|
|
||||||
betterEntries += goodEntries;
|
betterEntries += goodEntries;
|
||||||
return betterEntries;
|
return betterEntries;
|
||||||
|
@@ -127,8 +127,12 @@ QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFi
|
|||||||
keywords << unsortedKeywords;
|
keywords << unsortedKeywords;
|
||||||
m_keywordCache = allresults;
|
m_keywordCache = allresults;
|
||||||
m_searchTermCache = entry;
|
m_searchTermCache = entry;
|
||||||
foreach (const QString &keyword, keywords)
|
foreach (const QString &keyword, keywords) {
|
||||||
entries.append(LocatorFilterEntry(this, keyword, QVariant(), m_icon));
|
const int index = keyword.indexOf(entry, 0, cs);
|
||||||
|
LocatorFilterEntry filterEntry(this, keyword, QVariant(), m_icon);
|
||||||
|
filterEntry.highlightInfo = {index, entry.length()};
|
||||||
|
entries.append(filterEntry);
|
||||||
|
}
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
@@ -129,15 +129,16 @@ RemoteHelpFilter::~RemoteHelpFilter()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Core::LocatorFilterEntry> RemoteHelpFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &pattern)
|
QList<Core::LocatorFilterEntry> RemoteHelpFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
|
||||||
{
|
{
|
||||||
QList<Core::LocatorFilterEntry> entries;
|
QList<Core::LocatorFilterEntry> entries;
|
||||||
foreach (const QString &url, remoteUrls()) {
|
foreach (const QString &url, remoteUrls()) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
|
const QString name = url.arg(entry);
|
||||||
entries.append(Core::LocatorFilterEntry(this, url.arg(pattern), QVariant(),
|
Core::LocatorFilterEntry filterEntry(this, name, QVariant(), m_icon);
|
||||||
m_icon));
|
filterEntry.highlightInfo = {name.lastIndexOf(entry), entry.length()};
|
||||||
|
entries.append(filterEntry);
|
||||||
}
|
}
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
@@ -54,26 +54,32 @@ QList<Core::LocatorFilterEntry> MacroLocatorFilter::matchesFor(QFutureInterface<
|
|||||||
QList<Core::LocatorFilterEntry> goodEntries;
|
QList<Core::LocatorFilterEntry> goodEntries;
|
||||||
QList<Core::LocatorFilterEntry> betterEntries;
|
QList<Core::LocatorFilterEntry> betterEntries;
|
||||||
|
|
||||||
const Qt::CaseSensitivity caseSensitivity_ = caseSensitivity(entry);
|
const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry);
|
||||||
|
|
||||||
const QMap<QString, Macro*> ¯os = MacroManager::macros();
|
const QMap<QString, Macro*> ¯os = MacroManager::macros();
|
||||||
QMapIterator<QString, Macro*> it(macros);
|
QMapIterator<QString, Macro*> it(macros);
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
QString name = it.key();
|
const QString displayName = it.key();
|
||||||
|
const QString description = it.value()->description();
|
||||||
|
|
||||||
QList<Core::LocatorFilterEntry> *category = 0;
|
int index = displayName.indexOf(entry, 0, entryCaseSensitivity);
|
||||||
if (name.startsWith(entry, caseSensitivity_))
|
Core::LocatorFilterEntry::HighlightInfo::DataType hDataType = Core::LocatorFilterEntry::HighlightInfo::DisplayName;
|
||||||
category = &betterEntries;
|
if (index < 0) {
|
||||||
else if (name.contains(entry, caseSensitivity_))
|
index = description.indexOf(entry, 0, entryCaseSensitivity);
|
||||||
category = &goodEntries;
|
hDataType = Core::LocatorFilterEntry::HighlightInfo::ExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
if (category) {
|
if (index >= 0) {
|
||||||
QVariant id;
|
Core::LocatorFilterEntry filterEntry(this, displayName, QVariant(), m_icon);
|
||||||
Core::LocatorFilterEntry entry(this, it.key(), id, m_icon);
|
filterEntry.extraInfo = description;
|
||||||
entry.extraInfo = it.value()->description();
|
filterEntry.highlightInfo = Core::LocatorFilterEntry::HighlightInfo(index, entry.length(), hDataType);
|
||||||
category->append(entry);
|
|
||||||
|
if (index == 0)
|
||||||
|
betterEntries.append(filterEntry);
|
||||||
|
else
|
||||||
|
goodEntries.append(filterEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
betterEntries.append(goodEntries);
|
betterEntries.append(goodEntries);
|
||||||
|
@@ -53,24 +53,18 @@ void FunctionFilter::refresh(QFutureInterface<void> &)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compareLexigraphically(const Core::LocatorFilterEntry &a,
|
QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
|
||||||
const Core::LocatorFilterEntry &b)
|
QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||||
|
const QString &entry)
|
||||||
{
|
{
|
||||||
return a.displayName < b.displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &origEntry)
|
|
||||||
{
|
|
||||||
QString entry = trimWildcards(origEntry);
|
|
||||||
QList<Core::LocatorFilterEntry> goodEntries;
|
QList<Core::LocatorFilterEntry> goodEntries;
|
||||||
QList<Core::LocatorFilterEntry> betterEntries;
|
QList<Core::LocatorFilterEntry> betterEntries;
|
||||||
const QChar asterisk = QLatin1Char('*');
|
const Qt::CaseSensitivity cs = caseSensitivity(entry);
|
||||||
QStringMatcher matcher(entry, Qt::CaseInsensitive);
|
QStringMatcher matcher(entry, cs);
|
||||||
QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
QRegExp regexp(entry, cs, QRegExp::Wildcard);
|
||||||
if (!regexp.isValid())
|
if (!regexp.isValid())
|
||||||
return goodEntries;
|
return goodEntries;
|
||||||
bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?')));
|
bool hasWildcard = containsWildcard(entry);
|
||||||
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
|
|
||||||
|
|
||||||
QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries());
|
QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries());
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
@@ -83,14 +77,17 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(QFutureInterface<Core
|
|||||||
foreach (const LocatorData::Entry &info, items) {
|
foreach (const LocatorData::Entry &info, items) {
|
||||||
if (info.type != LocatorData::Function)
|
if (info.type != LocatorData::Function)
|
||||||
continue;
|
continue;
|
||||||
if ((hasWildcard && regexp.exactMatch(info.symbolName))
|
|
||||||
|| (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) {
|
|
||||||
|
|
||||||
|
const int index = hasWildcard ? regexp.indexIn(info.symbolName)
|
||||||
|
: matcher.indexIn(info.symbolName);
|
||||||
|
if (index >= 0) {
|
||||||
QVariant id = qVariantFromValue(info);
|
QVariant id = qVariantFromValue(info);
|
||||||
Core::LocatorFilterEntry filterEntry(this, info.displayName, id/*, info.icon*/);
|
Core::LocatorFilterEntry filterEntry(this, info.displayName, id/*, info.icon*/);
|
||||||
filterEntry.extraInfo = info.extraInfo;
|
filterEntry.extraInfo = info.extraInfo;
|
||||||
|
const int length = hasWildcard ? regexp.matchedLength() : entry.length();
|
||||||
|
filterEntry.highlightInfo = {index, length};
|
||||||
|
|
||||||
if (info.symbolName.startsWith(entry, caseSensitivityForPrefix))
|
if (index == 0)
|
||||||
betterEntries.append(filterEntry);
|
betterEntries.append(filterEntry);
|
||||||
else
|
else
|
||||||
goodEntries.append(filterEntry);
|
goodEntries.append(filterEntry);
|
||||||
@@ -99,9 +96,9 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(QFutureInterface<Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (goodEntries.size() < 1000)
|
if (goodEntries.size() < 1000)
|
||||||
Utils::sort(goodEntries, compareLexigraphically);
|
Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
|
||||||
if (betterEntries.size() < 1000)
|
if (betterEntries.size() < 1000)
|
||||||
Utils::sort(betterEntries, compareLexigraphically);
|
Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
|
||||||
|
|
||||||
betterEntries += goodEntries;
|
betterEntries += goodEntries;
|
||||||
return betterEntries;
|
return betterEntries;
|
||||||
|
Reference in New Issue
Block a user