cpplocatorfilter.cpp 5.06 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
con's avatar
con committed
2
**
3
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
con's avatar
con committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
con's avatar
con committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15
**
16
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
#include "cpplocatorfilter.h"
31
#include "cppmodelmanager.h"
con's avatar
con committed
32

33
#include <QStringMatcher>
Robert Loehning's avatar
Robert Loehning committed
34

35
using namespace CppTools;
con's avatar
con committed
36 37
using namespace CppTools::Internal;

38 39
CppLocatorFilter::CppLocatorFilter(CppLocatorData *locatorData)
    : m_data(locatorData)
con's avatar
con committed
40
{
hjk's avatar
hjk committed
41
    setId("Classes and Methods");
42
    setDisplayName(tr("C++ Classes, Enums and Functions"));
43
    setShortcutString(QString(QLatin1Char(':')));
con's avatar
con committed
44 45 46
    setIncludedByDefault(false);
}

con's avatar
con committed
47
CppLocatorFilter::~CppLocatorFilter()
con's avatar
con committed
48 49 50
{
}

51
Core::LocatorFilterEntry CppLocatorFilter::filterEntryFromModelItemInfo(ModelItemInfo::Ptr info)
52 53
{
    const QVariant id = qVariantFromValue(info);
54 55 56 57 58
    Core::LocatorFilterEntry filterEntry(this, info->scopedSymbolName(), id, info->icon());
    if (info->type() == ModelItemInfo::Class || info->type() == ModelItemInfo::Enum)
        filterEntry.extraInfo = info->shortNativeFilePath();
    else
        filterEntry.extraInfo = info->symbolType();
59 60 61 62

    return filterEntry;
}

con's avatar
con committed
63
void CppLocatorFilter::refresh(QFutureInterface<void> &future)
con's avatar
con committed
64
{
65
    Q_UNUSED(future)
con's avatar
con committed
66 67
}

68
QList<QList<CppTools::ModelItemInfo::Ptr> > CppLocatorFilter::itemsToMatchUserInputAgainst() const
69
{
70
    return QList<QList<CppTools::ModelItemInfo::Ptr> >()
71 72 73 74 75
        << m_data->classes()
        << m_data->functions()
        << m_data->enums();
}

76 77
static bool compareLexigraphically(const Core::LocatorFilterEntry &a,
                                   const Core::LocatorFilterEntry &b)
78 79 80 81
{
    return a.displayName < b.displayName;
}

82 83
QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
        QFutureInterface<Core::LocatorFilterEntry> &future, const QString &origEntry)
con's avatar
con committed
84 85
{
    QString entry = trimWildcards(origEntry);
86 87
    QList<Core::LocatorFilterEntry> goodEntries;
    QList<Core::LocatorFilterEntry> betterEntries;
88
    const QChar asterisk = QLatin1Char('*');
con's avatar
con committed
89
    QStringMatcher matcher(entry, Qt::CaseInsensitive);
90
    QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
con's avatar
con committed
91
    if (!regexp.isValid())
92
        return goodEntries;
93
    bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?')));
94
    bool hasColonColon = entry.contains(QLatin1String("::"));
95
    const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
con's avatar
con committed
96

97 98 99
    const QList<QList<CppTools::ModelItemInfo::Ptr> > itemLists = itemsToMatchUserInputAgainst();
    foreach (const QList<CppTools::ModelItemInfo::Ptr> &items, itemLists) {
        foreach (ModelItemInfo::Ptr info, items) {
100 101
            if (future.isCanceled())
                break;
102 103
            const QString matchString = hasColonColon ? info->scopedSymbolName()
                                                      : info->symbolName();
104
            if ((hasWildcard && regexp.exactMatch(matchString))
105
                || (!hasWildcard && matcher.indexIn(matchString) != -1)) {
106
                const Core::LocatorFilterEntry filterEntry = filterEntryFromModelItemInfo(info);
107
                if (matchString.startsWith(entry, caseSensitivityForPrefix))
108 109 110
                    betterEntries.append(filterEntry);
                else
                    goodEntries.append(filterEntry);
con's avatar
con committed
111 112 113 114
            }
        }
    }

115
    if (goodEntries.size() < 1000)
116
        qStableSort(goodEntries.begin(), goodEntries.end(), compareLexigraphically);
117
    if (betterEntries.size() < 1000)
118
        qStableSort(betterEntries.begin(), betterEntries.end(), compareLexigraphically);
119

120 121
    betterEntries += goodEntries;
    return betterEntries;
con's avatar
con committed
122 123
}

124
void CppLocatorFilter::accept(Core::LocatorFilterEntry selection) const
con's avatar
con committed
125
{
126 127
    ModelItemInfo::Ptr info = qvariant_cast<CppTools::ModelItemInfo::Ptr>(selection.internalData);
    Core::EditorManager::openEditorAt(info->fileName(), info->line(), info->column());
con's avatar
con committed
128
}