forked from qt-creator/qt-creator
Port QtCreator over to use filterRegularExpression
QSortFilterProxyModel::filterRegExp is going to go away in Qt6, so port over to use QRegularExpression instead. This required some changes where setFilterWildcard/FixedString() was being used, as those would instantiate QRegExp based filters in Qt 5, and will use QRegularExpression in Qt 6. Use the generic setFilterRegularExpression here, to keep things portable between 5 and 6. Change-Id: I6379be781aa3821b10ba783c088f82c1a0970911 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -25,7 +25,7 @@ https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
|
||||
|
||||
Prerequisites:
|
||||
|
||||
* Qt 5.11.0 or later
|
||||
* Qt 5.12.0 or later
|
||||
* Qt WebEngine module for QtWebEngine based help viewer
|
||||
* On Windows:
|
||||
* ActiveState Active Perl
|
||||
@@ -89,7 +89,7 @@ For detailed information on the supported compilers, see
|
||||
for example, `c:\work`. If you plan to use MinGW and Microsoft Visual
|
||||
Studio simultaneously or mix different Qt versions, we recommend
|
||||
creating a directory structure which reflects that. For example:
|
||||
`C:\work\qt5.11.0-vs15, C:\work\qt5.11.0-mingw`.
|
||||
`C:\work\qt5.12.0-vs15, C:\work\qt5.12.0-mingw`.
|
||||
|
||||
4. Download and install Perl from <https://www.activestate.com/activeperl>
|
||||
and check that perl.exe is added to the path. Run `perl -v` to verify
|
||||
|
@@ -1,9 +1,9 @@
|
||||
include(qtcreator.pri)
|
||||
|
||||
#version check qt
|
||||
!minQtVersion(5, 11, 0) {
|
||||
!minQtVersion(5, 12, 0) {
|
||||
message("Cannot build $$IDE_DISPLAY_NAME with Qt version $${QT_VERSION}.")
|
||||
error("Use at least Qt 5.11.0.")
|
||||
error("Use at least Qt 5.12.0.")
|
||||
}
|
||||
|
||||
include(doc/doc.pri)
|
||||
|
@@ -37,9 +37,9 @@ bool CategorySortFilterModel::filterAcceptsRow(int source_row,
|
||||
{
|
||||
if (!source_parent.isValid()) {
|
||||
// category items should be visible if any of its children match
|
||||
const QRegExp ®exp = filterRegExp();
|
||||
const QRegularExpression ®exp = filterRegularExpression();
|
||||
const QModelIndex &categoryIndex = sourceModel()->index(source_row, 0, source_parent);
|
||||
if (regexp.indexIn(sourceModel()->data(categoryIndex, filterRole()).toString()) != -1)
|
||||
if (regexp.match(sourceModel()->data(categoryIndex, filterRole()).toString()).hasMatch())
|
||||
return true;
|
||||
const int rowCount = sourceModel()->rowCount(categoryIndex);
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
|
@@ -264,30 +264,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class FileFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileFilterModel(QObject *parent = nullptr)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
const int rowCount = sourceModel()->rowCount(index);
|
||||
if (rowCount == 0) // No children -> file node!
|
||||
return sourceModel()->data(index).toString().contains(filterRegExp());
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
if (filterAcceptsRow(row, index))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
|
||||
const FileInfoProviders &fileInfoProviders,
|
||||
int initialProviderIndex)
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
@@ -227,11 +228,11 @@ const QList<Core::IOptionsPage *> Core::IOptionsPage::allOptionsPages()
|
||||
}
|
||||
|
||||
/*!
|
||||
Is used by the \uicontrol Options dialog search filter to match \a searchKeyWord to this options
|
||||
Is used by the \uicontrol Options dialog search filter to match \a regexp to this options
|
||||
page. This defaults to take the widget and then looks for all child labels, check boxes, push
|
||||
buttons, and group boxes. Should return \c true when a match is found.
|
||||
*/
|
||||
bool Core::IOptionsPage::matches(const QString &searchKeyWord) const
|
||||
bool Core::IOptionsPage::matches(const QRegularExpression ®exp) const
|
||||
{
|
||||
if (!m_keywordsInitialized) {
|
||||
auto that = const_cast<IOptionsPage *>(this);
|
||||
@@ -251,7 +252,7 @@ bool Core::IOptionsPage::matches(const QString &searchKeyWord) const
|
||||
m_keywordsInitialized = true;
|
||||
}
|
||||
foreach (const QString &keyword, m_keywords)
|
||||
if (keyword.contains(searchKeyWord, Qt::CaseInsensitive))
|
||||
if (keyword.contains(regexp))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ public:
|
||||
using WidgetCreator = std::function<IOptionsPageWidget *()>;
|
||||
void setWidgetCreator(const WidgetCreator &widgetCreator);
|
||||
|
||||
virtual bool matches(const QString &searchKeyWord) const;
|
||||
virtual bool matches(const QRegularExpression ®exp) const;
|
||||
virtual QWidget *widget();
|
||||
virtual void apply();
|
||||
virtual void finish();
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
QIcon categoryIcon() const;
|
||||
|
||||
virtual QList<IOptionsPage *> pages() const = 0;
|
||||
virtual bool matches(const QString & /* searchKeyWord*/) const = 0;
|
||||
virtual bool matches(const QRegularExpression ®exp) const = 0;
|
||||
|
||||
protected:
|
||||
void setCategory(Id category) { m_category = category; }
|
||||
|
@@ -262,19 +262,18 @@ bool CategoryFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sou
|
||||
if (QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent))
|
||||
return true;
|
||||
|
||||
const QString pattern = filterRegExp().pattern();
|
||||
const QRegularExpression regex = filterRegularExpression();
|
||||
const CategoryModel *cm = static_cast<CategoryModel*>(sourceModel());
|
||||
const Category *category = cm->categories().at(sourceRow);
|
||||
for (const IOptionsPage *page : category->pages) {
|
||||
if (page->displayCategory().contains(pattern, Qt::CaseInsensitive)
|
||||
|| page->displayName().contains(pattern, Qt::CaseInsensitive)
|
||||
|| page->matches(pattern))
|
||||
if (page->displayCategory().contains(regex) || page->displayName().contains(regex)
|
||||
|| page->matches(regex))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!category->providerPagesCreated) {
|
||||
for (const IOptionsPageProvider *provider : category->providers) {
|
||||
if (provider->matches(pattern))
|
||||
if (provider->matches(regex))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -469,8 +468,14 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||
|
||||
// The order of the slot connection matters here, the filter slot
|
||||
// opens the matching page after the model has filtered.
|
||||
connect(m_filterLineEdit, &Utils::FancyLineEdit::filterChanged,
|
||||
&m_proxyModel, &QSortFilterProxyModel::setFilterFixedString);
|
||||
connect(m_filterLineEdit,
|
||||
&Utils::FancyLineEdit::filterChanged,
|
||||
&m_proxyModel,
|
||||
[this](const QString &filter) {
|
||||
m_proxyModel.setFilterRegularExpression(
|
||||
QRegularExpression(QRegularExpression::escape(filter),
|
||||
QRegularExpression::CaseInsensitiveOption));
|
||||
});
|
||||
connect(m_filterLineEdit, &Utils::FancyLineEdit::filterChanged,
|
||||
this, &SettingsDialog::filter);
|
||||
m_categoryList->setFocus();
|
||||
@@ -631,12 +636,12 @@ void SettingsDialog::disconnectTabWidgets()
|
||||
void SettingsDialog::updateEnabledTabs(Category *category, const QString &searchText)
|
||||
{
|
||||
int firstEnabledTab = -1;
|
||||
const QRegularExpression regex(QRegularExpression::escape(searchText),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
for (int i = 0; i < category->pages.size(); ++i) {
|
||||
const IOptionsPage *page = category->pages.at(i);
|
||||
const bool enabled = searchText.isEmpty()
|
||||
|| page->category().toString().contains(searchText, Qt::CaseInsensitive)
|
||||
|| page->displayName().contains(searchText, Qt::CaseInsensitive)
|
||||
|| page->matches(searchText);
|
||||
const bool enabled = searchText.isEmpty() || page->category().toString().contains(regex)
|
||||
|| page->displayName().contains(regex) || page->matches(regex);
|
||||
category->tabWidget->setTabEnabled(i, enabled);
|
||||
if (enabled && firstEnabledTab < 0)
|
||||
firstEnabledTab = i;
|
||||
|
@@ -90,8 +90,8 @@ public:
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
const QRegExp regexp = filterRegExp();
|
||||
if (regexp.isEmpty() || sourceModel()->rowCount(index) > 0)
|
||||
const QRegularExpression regexp = filterRegularExpression();
|
||||
if (regexp.pattern().isEmpty() || sourceModel()->rowCount(index) > 0)
|
||||
return true;
|
||||
|
||||
const QString displayText = index.data(Qt::DisplayRole).toString();
|
||||
@@ -548,7 +548,7 @@ void VariableChooserPrivate::updatePositionAndShow(bool)
|
||||
|
||||
void VariableChooserPrivate::updateFilter(const QString &filterText)
|
||||
{
|
||||
m_sortModel->setFilterWildcard(filterText);
|
||||
m_sortModel->setFilterRegularExpression(QRegularExpression::wildcardToRegularExpression(filterText));
|
||||
m_variableTree->expandAll();
|
||||
}
|
||||
|
||||
|
@@ -85,7 +85,7 @@ QList<Core::IOptionsPage *> SettingsPageProvider::pages() const
|
||||
return FormEditorW::optionsPages();
|
||||
}
|
||||
|
||||
bool SettingsPageProvider::matches(const QString &searchKeyWord) const
|
||||
bool SettingsPageProvider::matches(const QRegularExpression ®ex) const
|
||||
{
|
||||
// to avoid fully initializing designer when typing something in the options' filter edit
|
||||
// we hardcode matching of UI text from the designer pages, which are taken if the designer pages
|
||||
@@ -119,7 +119,7 @@ bool SettingsPageProvider::matches(const QString &searchKeyWord) const
|
||||
m_keywords << Utils::stripAccelerator(QCoreApplication::translate(uitext[i].context, uitext[i].value));
|
||||
}
|
||||
for (const QString &key : qAsConst(m_keywords)) {
|
||||
if (key.contains(searchKeyWord, Qt::CaseInsensitive))
|
||||
if (key.contains(regex))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@@ -63,7 +63,7 @@ public:
|
||||
SettingsPageProvider();
|
||||
|
||||
QList<Core::IOptionsPage *> pages() const override;
|
||||
bool matches(const QString &searchKeyWord) const override;
|
||||
bool matches(const QRegularExpression ®ex) const override;
|
||||
|
||||
private:
|
||||
mutable bool m_initialized = false;
|
||||
|
@@ -106,7 +106,7 @@ BranchView::BranchView() :
|
||||
auto filterEdit = new Utils::FancyLineEdit(this);
|
||||
filterEdit->setFiltering(true);
|
||||
connect(filterEdit, &Utils::FancyLineEdit::textChanged,
|
||||
m_filterModel, QOverload<const QString &>::of(&BranchFilterModel::setFilterRegExp));
|
||||
m_filterModel, QOverload<const QString &>::of(&BranchFilterModel::setFilterRegularExpression));
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->addWidget(filterEdit);
|
||||
layout->addWidget(m_repositoryLabel);
|
||||
|
@@ -154,7 +154,7 @@ AddRunConfigDialog::AddRunConfigDialog(Target *target, QWidget *parent)
|
||||
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
|
||||
|
||||
connect(filterEdit, &QLineEdit::textChanged, this, [proxyModel](const QString &text) {
|
||||
proxyModel->setFilterRegExp(QRegExp(text, Qt::CaseInsensitive));
|
||||
proxyModel->setFilterRegularExpression(QRegularExpression(text, QRegularExpression::CaseInsensitiveOption));
|
||||
});
|
||||
connect(m_view, &TreeView::doubleClicked, this, [this] { accept(); });
|
||||
const auto updateOkButton = [buttonBox, this] {
|
||||
|
@@ -182,10 +182,10 @@ DeviceProcessesDialogPrivate::DeviceProcessesDialogPrivate(KitChooser *chooser,
|
||||
// line->setFrameShape(QFrame::HLine);
|
||||
// line->setFrameShadow(QFrame::Sunken);
|
||||
|
||||
proxyModel.setFilterRegExp(processFilterLineEdit->text());
|
||||
proxyModel.setFilterRegularExpression(processFilterLineEdit->text());
|
||||
|
||||
connect(processFilterLineEdit, QOverload<const QString &>::of(&FancyLineEdit::textChanged),
|
||||
&proxyModel, QOverload<const QString &>::of(&ProcessListFilterModel::setFilterRegExp));
|
||||
&proxyModel, QOverload<const QString &>::of(&ProcessListFilterModel::setFilterRegularExpression));
|
||||
connect(procView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &DeviceProcessesDialogPrivate::updateButtons);
|
||||
connect(updateListButton, &QAbstractButton::clicked,
|
||||
|
@@ -202,7 +202,7 @@ void TodoOutputPane::updateKeywordFilter()
|
||||
int sortColumn = m_todoTreeView->header()->sortIndicatorSection();
|
||||
Qt::SortOrder sortOrder = m_todoTreeView->header()->sortIndicatorOrder();
|
||||
|
||||
m_filteredTodoItemsModel->setFilterRegExp(pattern);
|
||||
m_filteredTodoItemsModel->setFilterRegularExpression(pattern);
|
||||
m_filteredTodoItemsModel->sort(sortColumn, sortOrder);
|
||||
|
||||
updateTodoCount();
|
||||
|
@@ -109,7 +109,7 @@ bool DataProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_
|
||||
return false;
|
||||
|
||||
// if the filter regexp is a non-empty string, ignore our filters
|
||||
if (!filterRegExp().isEmpty())
|
||||
if (!filterRegularExpression().pattern().isEmpty())
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
// check max rows
|
||||
|
@@ -554,7 +554,7 @@ void CallgrindToolPrivate::doClear(bool clearParseData)
|
||||
m_proxyModel.setFilterBaseDir(QString());
|
||||
if (m_searchFilter)
|
||||
m_searchFilter->clear();
|
||||
m_proxyModel.setFilterFixedString(QString());
|
||||
m_proxyModel.setFilterRegularExpression(QRegularExpression());
|
||||
}
|
||||
|
||||
void CallgrindToolPrivate::setBusyCursor(bool busy)
|
||||
@@ -609,7 +609,7 @@ void CallgrindToolPrivate::stackBrowserChanged()
|
||||
|
||||
void CallgrindToolPrivate::updateFilterString()
|
||||
{
|
||||
m_proxyModel.setFilterFixedString(m_searchFilter->text());
|
||||
m_proxyModel.setFilterRegularExpression(QRegularExpression::escape(m_searchFilter->text()));
|
||||
}
|
||||
|
||||
void CallgrindToolPrivate::setCostFormat(CostDelegate::CostFormat format)
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#include <QApplication>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <QHelpEngine>
|
||||
|
||||
@@ -76,8 +77,7 @@ BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title,
|
||||
proxyModel->setDynamicSortFilter(true);
|
||||
proxyModel->setFilterRole(Qt::UserRole + 10);
|
||||
proxyModel->setSourceModel(bookmarkManager->treeBookmarkModel());
|
||||
proxyModel->setFilterRegExp(QRegExp(QLatin1String("Folder"),
|
||||
Qt::CaseSensitive, QRegExp::FixedString));
|
||||
proxyModel->setFilterRegularExpression(QRegularExpression(QLatin1String("Folder")));
|
||||
ui.treeView->setModel(proxyModel);
|
||||
|
||||
ui.treeView->expandAll();
|
||||
@@ -320,14 +320,14 @@ void BookmarkWidget::filterChanged()
|
||||
{
|
||||
bool searchBookmarks = searchField->text().isEmpty();
|
||||
if (!searchBookmarks) {
|
||||
regExp.setPattern(searchField->text());
|
||||
regExp.setPattern(QRegularExpression::escape(searchField->text()));
|
||||
filterBookmarkModel->setSourceModel(bookmarkManager->listBookmarkModel());
|
||||
} else {
|
||||
regExp.setPattern(QString());
|
||||
filterBookmarkModel->setSourceModel(bookmarkManager->treeBookmarkModel());
|
||||
}
|
||||
|
||||
filterBookmarkModel->setFilterRegExp(regExp);
|
||||
filterBookmarkModel->setFilterRegularExpression(regExp);
|
||||
|
||||
const QModelIndex &index = treeView->indexAt(QPoint(1, 1));
|
||||
if (index.isValid())
|
||||
@@ -408,8 +408,7 @@ void BookmarkWidget::customContextMenuRequested(const QPoint &point)
|
||||
|
||||
void BookmarkWidget::setup()
|
||||
{
|
||||
regExp.setPatternSyntax(QRegExp::FixedString);
|
||||
regExp.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||
|
||||
QLayout *vlayout = new QVBoxLayout(this);
|
||||
vlayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
@@ -122,7 +122,7 @@ private:
|
||||
void expandItems();
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
QRegExp regExp;
|
||||
QRegularExpression regExp;
|
||||
TreeView *treeView;
|
||||
Utils::FancyLineEdit *searchField;
|
||||
BookmarkManager *bookmarkManager;
|
||||
|
Reference in New Issue
Block a user