forked from qt-creator/qt-creator
Locator: Allow to filter for path in BaseFileFilter
If the input contains a path separator, the input is matched against the file path. Otherwise, as before, the input is matched against the file name. This affects AllProjectsFilter, CurrentProjectFilter and DirectoryFilter. Usage Examples: "src/*main.cpp" "cppedtior/" Change-Id: I8bc55642b388a8f8e1d7a949f80bbe1abc41ae3c Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -56,10 +56,16 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn
|
|||||||
QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
||||||
if (!regexp.isValid())
|
if (!regexp.isValid())
|
||||||
return betterEntries;
|
return betterEntries;
|
||||||
|
const QChar pathSeparator = QDir::separator();
|
||||||
|
const bool hasPathSeparator = needle.contains(pathSeparator);
|
||||||
const bool hasWildcard = needle.contains(asterisk) || needle.contains(QLatin1Char('?'));
|
const bool hasWildcard = needle.contains(asterisk) || needle.contains(QLatin1Char('?'));
|
||||||
QStringList searchListPaths;
|
QStringList searchListPaths;
|
||||||
QStringList searchListNames;
|
QStringList searchListNames;
|
||||||
if (!m_previousEntry.isEmpty() && !m_forceNewSearchList && needle.contains(m_previousEntry)) {
|
const bool containsPreviousEntry = !m_previousEntry.isEmpty()
|
||||||
|
&& needle.contains(m_previousEntry);
|
||||||
|
const bool pathSeparatorAdded = !m_previousEntry.contains(pathSeparator)
|
||||||
|
&& needle.contains(pathSeparator);
|
||||||
|
if (!m_forceNewSearchList && containsPreviousEntry && !pathSeparatorAdded) {
|
||||||
searchListPaths = m_previousResultPaths;
|
searchListPaths = m_previousResultPaths;
|
||||||
searchListNames = m_previousResultNames;
|
searchListNames = m_previousResultNames;
|
||||||
} else {
|
} else {
|
||||||
@@ -79,13 +85,14 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn
|
|||||||
|
|
||||||
QString path = paths.next();
|
QString path = paths.next();
|
||||||
QString name = names.next();
|
QString name = names.next();
|
||||||
if ((hasWildcard && regexp.exactMatch(name))
|
QString matchText = hasPathSeparator ? path : name;
|
||||||
|| (!hasWildcard && matcher.indexIn(name) != -1)) {
|
if ((hasWildcard && regexp.exactMatch(matchText))
|
||||||
|
|| (!hasWildcard && matcher.indexIn(matchText) != -1)) {
|
||||||
QFileInfo fi(path);
|
QFileInfo fi(path);
|
||||||
FilterEntry entry(this, fi.fileName(), QString(path + lineNoSuffix));
|
FilterEntry entry(this, fi.fileName(), QString(path + lineNoSuffix));
|
||||||
entry.extraInfo = FileUtils::shortNativePath(FileName(fi));
|
entry.extraInfo = FileUtils::shortNativePath(FileName(fi));
|
||||||
entry.fileName = path;
|
entry.fileName = path;
|
||||||
if (name.startsWith(needle, caseSensitivityForPrefix))
|
if (matchText.startsWith(needle, caseSensitivityForPrefix))
|
||||||
betterEntries.append(entry);
|
betterEntries.append(entry);
|
||||||
else
|
else
|
||||||
goodEntries.append(entry);
|
goodEntries.append(entry);
|
||||||
|
@@ -36,5 +36,8 @@ RESOURCES += locator.qrc
|
|||||||
|
|
||||||
equals(TEST, 1) {
|
equals(TEST, 1) {
|
||||||
HEADERS += locatorfiltertest.h
|
HEADERS += locatorfiltertest.h
|
||||||
SOURCES += locatorfiltertest.cpp
|
SOURCES += \
|
||||||
|
locatorfiltertest.cpp \
|
||||||
|
locator_test.cpp
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD\\\"
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import qbs.base 1.0
|
import qbs.base 1.0
|
||||||
|
import qbs.FileInfo
|
||||||
|
|
||||||
import "../QtcPlugin.qbs" as QtcPlugin
|
import "../QtcPlugin.qbs" as QtcPlugin
|
||||||
import "../../../qbs/defaults.js" as Defaults
|
import "../../../qbs/defaults.js" as Defaults
|
||||||
@@ -59,6 +60,9 @@ QtcPlugin {
|
|||||||
files: [
|
files: [
|
||||||
"locatorfiltertest.cpp",
|
"locatorfiltertest.cpp",
|
||||||
"locatorfiltertest.h",
|
"locatorfiltertest.h",
|
||||||
|
"locator_test.cpp"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
cpp.defines: outer.concat(['SRCDIR="' + FileInfo.path(filePath) + '"'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
178
src/plugins/locator/locator_test.cpp
Normal file
178
src/plugins/locator/locator_test.cpp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** 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
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "locatorplugin.h"
|
||||||
|
|
||||||
|
#include "basefilefilter.h"
|
||||||
|
#include "locatorfiltertest.h"
|
||||||
|
|
||||||
|
#include <coreplugin/testdatadir.h>
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
using namespace Locator::Internal::Tests;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MyTestDataDir : public Core::Internal::Tests::TestDataDir
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyTestDataDir(const QString &testDataDirectory)
|
||||||
|
: TestDataDir(QLatin1String(SRCDIR "/../../../tests/locators/") + testDataDirectory) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MyBaseFileFilter : public Locator::BaseFileFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyBaseFileFilter(const QStringList &theFiles)
|
||||||
|
{
|
||||||
|
files().clear();
|
||||||
|
files().append(theFiles);
|
||||||
|
BaseFileFilter::generateFileNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh(QFutureInterface<void> &) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateFiles() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); }
|
||||||
|
|
||||||
|
class ReferenceData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReferenceData() {}
|
||||||
|
ReferenceData(const QString &searchText, const ResultDataList &results)
|
||||||
|
: searchText(searchText), results(results) {}
|
||||||
|
|
||||||
|
QString searchText;
|
||||||
|
ResultDataList results;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ReferenceData)
|
||||||
|
Q_DECLARE_METATYPE(QList<ReferenceData>)
|
||||||
|
|
||||||
|
void Locator::Internal::LocatorPlugin::test_basefilefilter()
|
||||||
|
{
|
||||||
|
QFETCH(QStringList, testFiles);
|
||||||
|
QFETCH(QList<ReferenceData>, referenceDataList);
|
||||||
|
|
||||||
|
MyBaseFileFilter filter(testFiles);
|
||||||
|
BasicLocatorFilterTest test(&filter);
|
||||||
|
|
||||||
|
foreach (const ReferenceData &reference, referenceDataList) {
|
||||||
|
const QList<FilterEntry> filterEntries = test.matchesFor(reference.searchText);
|
||||||
|
const ResultDataList results = ResultData::fromFilterEntryList(filterEntries);
|
||||||
|
// QTextStream(stdout) << "----" << endl;
|
||||||
|
// ResultData::printFilterEntries(results);
|
||||||
|
QCOMPARE(results, reference.results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Locator::Internal::LocatorPlugin::test_basefilefilter_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QStringList>("testFiles");
|
||||||
|
QTest::addColumn<QList<ReferenceData> >("referenceDataList");
|
||||||
|
|
||||||
|
const QChar pathSeparator = QDir::separator();
|
||||||
|
const MyTestDataDir testDir(QLatin1String("testdata_basic"));
|
||||||
|
const QStringList testFiles = QStringList()
|
||||||
|
<< testDir.file(QLatin1String("file.cpp"))
|
||||||
|
<< testDir.file(QLatin1String("main.cpp"))
|
||||||
|
<< testDir.file(QLatin1String("subdir/main.cpp"));
|
||||||
|
QStringList testFilesShort;
|
||||||
|
foreach (const QString &file, testFiles)
|
||||||
|
testFilesShort << Utils::FileUtils::shortNativePath(Utils::FileName::fromString(file));
|
||||||
|
|
||||||
|
QTest::newRow("BaseFileFilter-EmptyInput")
|
||||||
|
<< testFiles
|
||||||
|
<< (QList<ReferenceData>()
|
||||||
|
<< ReferenceData(
|
||||||
|
QString(),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("file.cpp"), testFilesShort.at(0))
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(1))
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
);
|
||||||
|
|
||||||
|
QTest::newRow("BaseFileFilter-InputIsFileName")
|
||||||
|
<< testFiles
|
||||||
|
<< (QList<ReferenceData>()
|
||||||
|
<< ReferenceData(
|
||||||
|
_("main.cpp"),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(1))
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
);
|
||||||
|
|
||||||
|
QTest::newRow("BaseFileFilter-InputIsFilePath")
|
||||||
|
<< testFiles
|
||||||
|
<< (QList<ReferenceData>()
|
||||||
|
<< ReferenceData(
|
||||||
|
QString(_("subdir") + pathSeparator + _("main.cpp")),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
);
|
||||||
|
|
||||||
|
QTest::newRow("BaseFileFilter-InputIsDirIsPath")
|
||||||
|
<< testFiles
|
||||||
|
<< (QList<ReferenceData>()
|
||||||
|
<< ReferenceData( _("subdir"), QList<ResultData>())
|
||||||
|
<< ReferenceData(
|
||||||
|
QString(_("subdir") + pathSeparator + _("main.cpp")),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
);
|
||||||
|
|
||||||
|
QTest::newRow("BaseFileFilter-InputIsFileNameFilePathFileName")
|
||||||
|
<< testFiles
|
||||||
|
<< (QList<ReferenceData>()
|
||||||
|
<< ReferenceData(
|
||||||
|
_("main.cpp"),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(1))
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
<< ReferenceData(
|
||||||
|
QString(_("subdir") + pathSeparator + _("main.cpp")),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
<< ReferenceData(
|
||||||
|
_("main.cpp"),
|
||||||
|
(QList<ResultData>()
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(1))
|
||||||
|
<< ResultData(_("main.cpp"), testFilesShort.at(2))))
|
||||||
|
);
|
||||||
|
}
|
@@ -57,6 +57,18 @@ QList<FilterEntry> BasicLocatorFilterTest::matchesFor(const QString &searchText)
|
|||||||
return locatorSearch.results();
|
return locatorSearch.results();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace QTest {
|
||||||
|
|
||||||
|
template<> char *toString(const Locator::Internal::Tests::ResultData &data)
|
||||||
|
{
|
||||||
|
QByteArray ba = "\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8() + "\"";
|
||||||
|
return qstrdup(ba.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QTest
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
ResultData::ResultData()
|
ResultData::ResultData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -83,16 +83,4 @@ typedef ResultData::ResultDataList ResultDataList;
|
|||||||
Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultData)
|
Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultData)
|
||||||
Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultDataList)
|
Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultDataList)
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
namespace QTest {
|
|
||||||
|
|
||||||
template<> char *toString(const Locator::Internal::Tests::ResultData &data)
|
|
||||||
{
|
|
||||||
QByteArray ba = "\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8() + "\"";
|
|
||||||
return qstrdup(ba.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace QTest
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // LOCATORFILTERTEST_H
|
#endif // LOCATORFILTERTEST_H
|
||||||
|
@@ -81,6 +81,11 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void updatePlaceholderText(Core::Command *command = 0);
|
void updatePlaceholderText(Core::Command *command = 0);
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void test_basefilefilter();
|
||||||
|
void test_basefilefilter_data();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
|
|
||||||
|
1
tests/locators/testdata_basic/file.cpp
Normal file
1
tests/locators/testdata_basic/file.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// Copyright header
|
1
tests/locators/testdata_basic/main.cpp
Normal file
1
tests/locators/testdata_basic/main.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// Copyright header
|
1
tests/locators/testdata_basic/subdir/main.cpp
Normal file
1
tests/locators/testdata_basic/subdir/main.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// Copyright header
|
Reference in New Issue
Block a user