forked from qt-creator/qt-creator
ILocatorFilter: Replace refresh() with refreshRecipe()
Most of refresh overrides were running synchronous method in main thread, however, it was really convoluted: we were starting asynchronous call and from inside the method running in separate thread we were scheduling the call back to main thread. Use Tasking::Sync for these cases instead. The only subclass that is doing the real asynchronous refresh is DirectoryFilter. Simplify the async call internals and pass data to the async call explicitly. Move the refresh method outside of DirectoryFilter class (to make it clear we shouldn't touch private members). Change-Id: I6af788611bdc49db1ff812f91202ac40a280fbc8 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -7,12 +7,12 @@
|
|||||||
#include "../coreplugintr.h"
|
#include "../coreplugintr.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/asynctask.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/filesearch.h>
|
#include <utils/filesearch.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
@@ -60,8 +60,6 @@ DirectoryFilter::DirectoryFilter(Id id)
|
|||||||
|
|
||||||
void DirectoryFilter::saveState(QJsonObject &object) const
|
void DirectoryFilter::saveState(QJsonObject &object) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_lock); // m_files is modified in other thread
|
|
||||||
|
|
||||||
if (displayName() != defaultDisplayName())
|
if (displayName() != defaultDisplayName())
|
||||||
object.insert(kDisplayNameKey, displayName());
|
object.insert(kDisplayNameKey, displayName());
|
||||||
if (!m_directories.isEmpty()) {
|
if (!m_directories.isEmpty()) {
|
||||||
@@ -92,7 +90,6 @@ static FilePaths toFilePaths(const QJsonArray &array)
|
|||||||
|
|
||||||
void DirectoryFilter::restoreState(const QJsonObject &object)
|
void DirectoryFilter::restoreState(const QJsonObject &object)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
setDisplayName(object.value(kDisplayNameKey).toString(defaultDisplayName()));
|
setDisplayName(object.value(kDisplayNameKey).toString(defaultDisplayName()));
|
||||||
m_directories = toFilePaths(object.value(kDirectoriesKey).toArray());
|
m_directories = toFilePaths(object.value(kDirectoriesKey).toArray());
|
||||||
m_filters = toStringList(
|
m_filters = toStringList(
|
||||||
@@ -107,8 +104,6 @@ void DirectoryFilter::restoreState(const QByteArray &state)
|
|||||||
{
|
{
|
||||||
if (isOldSetting(state)) {
|
if (isOldSetting(state)) {
|
||||||
// TODO read old settings, remove some time after Qt Creator 4.15
|
// TODO read old settings, remove some time after Qt Creator 4.15
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
QStringList directories;
|
QStringList directories;
|
||||||
QString shortcut;
|
QString shortcut;
|
||||||
@@ -136,8 +131,6 @@ void DirectoryFilter::restoreState(const QByteArray &state)
|
|||||||
setDisplayName(name);
|
setDisplayName(name);
|
||||||
setShortcutString(shortcut);
|
setShortcutString(shortcut);
|
||||||
setIncludedByDefault(defaultFilter);
|
setIncludedByDefault(defaultFilter);
|
||||||
|
|
||||||
locker.unlock();
|
|
||||||
} else {
|
} else {
|
||||||
ILocatorFilter::restoreState(state);
|
ILocatorFilter::restoreState(state);
|
||||||
}
|
}
|
||||||
@@ -263,8 +256,6 @@ bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
|||||||
&DirectoryFilter::updateOptionButtons,
|
&DirectoryFilter::updateOptionButtons,
|
||||||
Qt::DirectConnection);
|
Qt::DirectConnection);
|
||||||
m_dialog->directoryList->clear();
|
m_dialog->directoryList->clear();
|
||||||
// Note: assuming we only change m_directories in the Gui thread,
|
|
||||||
// we don't need to protect it here with mutex
|
|
||||||
m_dialog->directoryList->addItems(Utils::transform(m_directories, &FilePath::toString));
|
m_dialog->directoryList->addItems(Utils::transform(m_directories, &FilePath::toString));
|
||||||
m_dialog->nameLabel->setVisible(m_isCustomFilter);
|
m_dialog->nameLabel->setVisible(m_isCustomFilter);
|
||||||
m_dialog->nameEdit->setVisible(m_isCustomFilter);
|
m_dialog->nameEdit->setVisible(m_isCustomFilter);
|
||||||
@@ -276,14 +267,10 @@ bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
|||||||
m_dialog->filePatternLabel->setText(Utils::msgFilePatternLabel());
|
m_dialog->filePatternLabel->setText(Utils::msgFilePatternLabel());
|
||||||
m_dialog->filePatternLabel->setBuddy(m_dialog->filePattern);
|
m_dialog->filePatternLabel->setBuddy(m_dialog->filePattern);
|
||||||
m_dialog->filePattern->setToolTip(Utils::msgFilePatternToolTip());
|
m_dialog->filePattern->setToolTip(Utils::msgFilePatternToolTip());
|
||||||
// Note: assuming we only change m_filters in the Gui thread,
|
|
||||||
// we don't need to protect it here with mutex
|
|
||||||
m_dialog->filePattern->setText(Utils::transform(m_filters, &QDir::toNativeSeparators).join(','));
|
m_dialog->filePattern->setText(Utils::transform(m_filters, &QDir::toNativeSeparators).join(','));
|
||||||
m_dialog->exclusionPatternLabel->setText(Utils::msgExclusionPatternLabel());
|
m_dialog->exclusionPatternLabel->setText(Utils::msgExclusionPatternLabel());
|
||||||
m_dialog->exclusionPatternLabel->setBuddy(m_dialog->exclusionPattern);
|
m_dialog->exclusionPatternLabel->setBuddy(m_dialog->exclusionPattern);
|
||||||
m_dialog->exclusionPattern->setToolTip(Utils::msgFilePatternToolTip());
|
m_dialog->exclusionPattern->setToolTip(Utils::msgFilePatternToolTip());
|
||||||
// Note: assuming we only change m_exclusionFilters in the Gui thread,
|
|
||||||
// we don't need to protect it here with mutex
|
|
||||||
m_dialog->exclusionPattern->setText(
|
m_dialog->exclusionPattern->setText(
|
||||||
Utils::transform(m_exclusionFilters, &QDir::toNativeSeparators).join(','));
|
Utils::transform(m_exclusionFilters, &QDir::toNativeSeparators).join(','));
|
||||||
m_dialog->shortcutEdit->setText(shortcutString());
|
m_dialog->shortcutEdit->setText(shortcutString());
|
||||||
@@ -291,7 +278,6 @@ bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
|||||||
updateOptionButtons();
|
updateOptionButtons();
|
||||||
dialog.adjustSize();
|
dialog.adjustSize();
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
bool directoriesChanged = false;
|
bool directoriesChanged = false;
|
||||||
const FilePaths oldDirectories = m_directories;
|
const FilePaths oldDirectories = m_directories;
|
||||||
const QStringList oldFilters = m_filters;
|
const QStringList oldFilters = m_filters;
|
||||||
@@ -353,53 +339,9 @@ void DirectoryFilter::updateOptionButtons()
|
|||||||
|
|
||||||
void DirectoryFilter::updateFileIterator()
|
void DirectoryFilter::updateFileIterator()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
setFileIterator(new BaseFileFilter::ListIterator(m_files));
|
setFileIterator(new BaseFileFilter::ListIterator(m_files));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectoryFilter::refresh(QFutureInterface<void> &future)
|
|
||||||
{
|
|
||||||
FilePaths directories;
|
|
||||||
QStringList filters, exclusionFilters;
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
if (m_directories.isEmpty()) {
|
|
||||||
m_files.clear();
|
|
||||||
QMetaObject::invokeMethod(this, &DirectoryFilter::updateFileIterator,
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
future.setProgressRange(0, 1);
|
|
||||||
future.setProgressValueAndText(1, Tr::tr("%1 filter update: 0 files").arg(displayName()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
directories = m_directories;
|
|
||||||
filters = m_filters;
|
|
||||||
exclusionFilters = m_exclusionFilters;
|
|
||||||
}
|
|
||||||
Utils::SubDirFileIterator subDirIterator(directories, filters, exclusionFilters);
|
|
||||||
future.setProgressRange(0, subDirIterator.maxProgress());
|
|
||||||
Utils::FilePaths filesFound;
|
|
||||||
auto end = subDirIterator.end();
|
|
||||||
for (auto it = subDirIterator.begin(); it != end; ++it) {
|
|
||||||
if (future.isCanceled())
|
|
||||||
break;
|
|
||||||
filesFound << (*it).filePath;
|
|
||||||
if (future.isProgressUpdateNeeded()
|
|
||||||
|| future.progressValue() == 0 /*workaround for regression in Qt*/) {
|
|
||||||
future.setProgressValueAndText(subDirIterator.currentProgress(),
|
|
||||||
Tr::tr("%1 filter update: %n files", nullptr, filesFound.size()).arg(displayName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!future.isCanceled()) {
|
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
m_files = filesFound;
|
|
||||||
QMetaObject::invokeMethod(this, &DirectoryFilter::updateFileIterator, Qt::QueuedConnection);
|
|
||||||
future.setProgressValue(subDirIterator.maxProgress());
|
|
||||||
} else {
|
|
||||||
future.setProgressValueAndText(subDirIterator.currentProgress(), Tr::tr("%1 filter update: canceled").arg(displayName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirectoryFilter::setIsCustomFilter(bool value)
|
void DirectoryFilter::setIsCustomFilter(bool value)
|
||||||
{
|
{
|
||||||
m_isCustomFilter = value;
|
m_isCustomFilter = value;
|
||||||
@@ -409,10 +351,7 @@ void DirectoryFilter::setDirectories(const FilePaths &directories)
|
|||||||
{
|
{
|
||||||
if (directories == m_directories)
|
if (directories == m_directories)
|
||||||
return;
|
return;
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
m_directories = directories;
|
m_directories = directories;
|
||||||
}
|
|
||||||
Internal::Locator::instance()->refresh({this});
|
Internal::Locator::instance()->refresh({this});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,14 +374,54 @@ FilePaths DirectoryFilter::directories() const
|
|||||||
|
|
||||||
void DirectoryFilter::setFilters(const QStringList &filters)
|
void DirectoryFilter::setFilters(const QStringList &filters)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
m_filters = filters;
|
m_filters = filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectoryFilter::setExclusionFilters(const QStringList &exclusionFilters)
|
void DirectoryFilter::setExclusionFilters(const QStringList &exclusionFilters)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_lock);
|
|
||||||
m_exclusionFilters = exclusionFilters;
|
m_exclusionFilters = exclusionFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void refresh(QFutureInterface<FilePaths> &future, const FilePaths &directories,
|
||||||
|
const QStringList &filters, const QStringList &exclusionFilters,
|
||||||
|
const QString &displayName)
|
||||||
|
{
|
||||||
|
if (directories.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SubDirFileIterator subDirIterator(directories, filters, exclusionFilters);
|
||||||
|
future.setProgressRange(0, subDirIterator.maxProgress());
|
||||||
|
FilePaths files;
|
||||||
|
const auto end = subDirIterator.end();
|
||||||
|
for (auto it = subDirIterator.begin(); it != end; ++it) {
|
||||||
|
if (future.isCanceled()) {
|
||||||
|
future.setProgressValueAndText(subDirIterator.currentProgress(),
|
||||||
|
Tr::tr("%1 filter update: canceled").arg(displayName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
files << (*it).filePath;
|
||||||
|
if (future.isProgressUpdateNeeded() || future.progressValue() == 0) {
|
||||||
|
future.setProgressValueAndText(subDirIterator.currentProgress(),
|
||||||
|
Tr::tr("%1 filter update: %n files", nullptr, files.size()).arg(displayName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
future.setProgressValue(subDirIterator.maxProgress());
|
||||||
|
future.reportResult(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> DirectoryFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
const auto setup = [this](AsyncTask<FilePaths> &async) {
|
||||||
|
async.setAsyncCallData(&refresh, m_directories, m_filters, m_exclusionFilters,
|
||||||
|
displayName());
|
||||||
|
};
|
||||||
|
const auto done = [this](const AsyncTask<FilePaths> &async) {
|
||||||
|
m_files = async.isResultAvailable() ? async.result() : FilePaths();
|
||||||
|
updateFileIterator();
|
||||||
|
};
|
||||||
|
return Async<FilePaths>(setup, done);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@@ -7,10 +7,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/core_global.h>
|
#include <coreplugin/core_global.h>
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QFutureInterface>
|
|
||||||
#include <QMutex>
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
@@ -22,7 +19,6 @@ public:
|
|||||||
DirectoryFilter(Utils::Id id);
|
DirectoryFilter(Utils::Id id);
|
||||||
void restoreState(const QByteArray &state) override;
|
void restoreState(const QByteArray &state) override;
|
||||||
bool openConfigDialog(QWidget *parent, bool &needsRefresh) override;
|
bool openConfigDialog(QWidget *parent, bool &needsRefresh) override;
|
||||||
void refresh(QFutureInterface<void> &future) override;
|
|
||||||
|
|
||||||
void setIsCustomFilter(bool value);
|
void setIsCustomFilter(bool value);
|
||||||
void setDirectories(const Utils::FilePaths &directories);
|
void setDirectories(const Utils::FilePaths &directories);
|
||||||
@@ -42,6 +38,7 @@ private:
|
|||||||
void handleRemoveDirectory();
|
void handleRemoveDirectory();
|
||||||
void updateOptionButtons();
|
void updateOptionButtons();
|
||||||
void updateFileIterator();
|
void updateFileIterator();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
|
|
||||||
Utils::FilePaths m_directories;
|
Utils::FilePaths m_directories;
|
||||||
QStringList m_filters;
|
QStringList m_filters;
|
||||||
@@ -49,7 +46,6 @@ private:
|
|||||||
// Our config dialog, uses in addDirectory and editDirectory
|
// Our config dialog, uses in addDirectory and editDirectory
|
||||||
// to give their dialogs the right parent
|
// to give their dialogs the right parent
|
||||||
class DirectoryFilterOptions *m_dialog = nullptr;
|
class DirectoryFilterOptions *m_dialog = nullptr;
|
||||||
mutable QMutex m_lock;
|
|
||||||
Utils::FilePaths m_files;
|
Utils::FilePaths m_files;
|
||||||
bool m_isCustomFilter = true;
|
bool m_isCustomFilter = true;
|
||||||
};
|
};
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "../editormanager/editormanager.h"
|
#include "../editormanager/editormanager.h"
|
||||||
|
|
||||||
#include <utils/fuzzymatcher.h>
|
#include <utils/fuzzymatcher.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
@@ -99,6 +100,15 @@ void ILocatorFilter::prepareSearch(const QString &entry)
|
|||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns refresh recipe for refreshing cached data. By default, no recipe is returned, so
|
||||||
|
that the filter won't be refreshed.
|
||||||
|
*/
|
||||||
|
std::optional<Tasking::TaskItem> ILocatorFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Called with the entry specified by \a selection when the user activates it
|
Called with the entry specified by \a selection when the user activates it
|
||||||
in the result list.
|
in the result list.
|
||||||
@@ -220,13 +230,13 @@ void ILocatorFilter::restoreState(const QByteArray &state)
|
|||||||
various aspects of the filter. Called when the user requests to configure
|
various aspects of the filter. Called when the user requests to configure
|
||||||
the filter.
|
the filter.
|
||||||
|
|
||||||
Set \a needsRefresh to \c true, if a refresh() should be done after
|
Set \a needsRefresh to \c true, if a refresh should be done after
|
||||||
closing the dialog. Return \c false if the user canceled the dialog.
|
closing the dialog. Return \c false if the user canceled the dialog.
|
||||||
|
|
||||||
The default implementation allows changing the shortcut and whether the
|
The default implementation allows changing the shortcut and whether the
|
||||||
filter is included by default.
|
filter is included by default.
|
||||||
|
|
||||||
\sa refresh()
|
\sa refreshRecipe()
|
||||||
*/
|
*/
|
||||||
bool ILocatorFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
bool ILocatorFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
|
||||||
{
|
{
|
||||||
@@ -616,14 +626,6 @@ bool ILocatorFilter::isOldSetting(const QByteArray &state)
|
|||||||
\sa caseSensitivity()
|
\sa caseSensitivity()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn void Core::ILocatorFilter::refresh(QFutureInterface<void> &future)
|
|
||||||
|
|
||||||
Refreshes cached data asynchronously.
|
|
||||||
|
|
||||||
If \a future is \c canceled, the refresh should be aborted.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\enum Core::ILocatorFilter::Priority
|
\enum Core::ILocatorFilter::Priority
|
||||||
|
|
||||||
|
@@ -17,8 +17,12 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
namespace Utils::Tasking { class TaskItem; }
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
namespace Internal { class Locator; }
|
||||||
|
|
||||||
class ILocatorFilter;
|
class ILocatorFilter;
|
||||||
|
|
||||||
class LocatorFilterEntry
|
class LocatorFilterEntry
|
||||||
@@ -157,8 +161,6 @@ public:
|
|||||||
virtual void accept(const LocatorFilterEntry &selection, QString *newText,
|
virtual void accept(const LocatorFilterEntry &selection, QString *newText,
|
||||||
int *selectionStart, int *selectionLength) const;
|
int *selectionStart, int *selectionLength) const;
|
||||||
|
|
||||||
virtual void refresh(QFutureInterface<void> &future) { Q_UNUSED(future) };
|
|
||||||
|
|
||||||
virtual QByteArray saveState() const;
|
virtual QByteArray saveState() const;
|
||||||
virtual void restoreState(const QByteArray &state);
|
virtual void restoreState(const QByteArray &state);
|
||||||
|
|
||||||
@@ -202,6 +204,9 @@ protected:
|
|||||||
static bool isOldSetting(const QByteArray &state);
|
static bool isOldSetting(const QByteArray &state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Internal::Locator;
|
||||||
|
virtual std::optional<Utils::Tasking::TaskItem> refreshRecipe();
|
||||||
|
|
||||||
Utils::Id m_id;
|
Utils::Id m_id;
|
||||||
QString m_shortcut;
|
QString m_shortcut;
|
||||||
Priority m_priority = Medium;
|
Priority m_priority = Medium;
|
||||||
|
@@ -382,14 +382,16 @@ void Locator::refresh(const QList<ILocatorFilter *> &filters)
|
|||||||
using namespace Tasking;
|
using namespace Tasking;
|
||||||
QList<TaskItem> tasks{parallel};
|
QList<TaskItem> tasks{parallel};
|
||||||
for (ILocatorFilter *filter : std::as_const(m_refreshingFilters)) {
|
for (ILocatorFilter *filter : std::as_const(m_refreshingFilters)) {
|
||||||
const auto setupRefresh = [filter](AsyncTask<void> &async) {
|
const auto task = filter->refreshRecipe();
|
||||||
async.setAsyncCallData(&ILocatorFilter::refresh, filter);
|
if (!task.has_value())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const Group group {
|
||||||
|
optional,
|
||||||
|
*task,
|
||||||
|
OnGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); })
|
||||||
};
|
};
|
||||||
const auto onRefreshDone = [this, filter](const AsyncTask<void> &async) {
|
tasks.append(group);
|
||||||
Q_UNUSED(async)
|
|
||||||
m_refreshingFilters.removeOne(filter);
|
|
||||||
};
|
|
||||||
tasks.append(Async<void>(setupRefresh, onRefreshDone));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_taskTree.reset(new TaskTree{tasks});
|
m_taskTree.reset(new TaskTree{tasks});
|
||||||
|
@@ -28,8 +28,6 @@ public:
|
|||||||
{
|
{
|
||||||
setFileIterator(new BaseFileFilter::ListIterator(theFiles));
|
setFileIterator(new BaseFileFilter::ListIterator(theFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh(QFutureInterface<void> &) override {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReferenceData
|
class ReferenceData
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
#include <utils/link.h>
|
#include <utils/link.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
@@ -115,4 +116,22 @@ QList<OpenDocumentsFilter::Entry> OpenDocumentsFilter::editors() const
|
|||||||
return m_editors;
|
return m_editors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenDocumentsFilter::refreshInternally()
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_mutex);
|
||||||
|
m_editors.clear();
|
||||||
|
const QList<DocumentModel::Entry *> documentEntries = DocumentModel::entries();
|
||||||
|
// create copy with only the information relevant to use
|
||||||
|
// to avoid model deleting entries behind our back
|
||||||
|
for (DocumentModel::Entry *e : documentEntries)
|
||||||
|
m_editors.append({e->filePath(), e->displayName()});
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> OpenDocumentsFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return Sync([this] { refreshInternally(); return true; });
|
||||||
|
}
|
||||||
|
|
||||||
} // Core::Internal
|
} // Core::Internal
|
||||||
|
@@ -7,10 +7,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/editormanager/documentmodel.h>
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
|
|
||||||
#include <QFutureInterface>
|
|
||||||
#include <QList>
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -38,6 +35,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
QList<Entry> editors() const;
|
QList<Entry> editors() const;
|
||||||
|
void refreshInternally();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
|
|
||||||
mutable QMutex m_mutex;
|
mutable QMutex m_mutex;
|
||||||
QList<Entry> m_editors;
|
QList<Entry> m_editors;
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -109,19 +111,19 @@ CppIncludesFilter::CppIncludesFilter()
|
|||||||
setPriority(ILocatorFilter::Low);
|
setPriority(ILocatorFilter::Low);
|
||||||
|
|
||||||
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged,
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(CppModelManager::instance(), &CppModelManager::documentUpdated,
|
connect(CppModelManager::instance(), &CppModelManager::documentUpdated,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(CppModelManager::instance(), &CppModelManager::aboutToRemoveFiles,
|
connect(CppModelManager::instance(), &CppModelManager::aboutToRemoveFiles,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(DocumentModel::model(), &QAbstractItemModel::rowsInserted,
|
connect(DocumentModel::model(), &QAbstractItemModel::rowsInserted,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(DocumentModel::model(), &QAbstractItemModel::rowsRemoved,
|
connect(DocumentModel::model(), &QAbstractItemModel::rowsRemoved,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(DocumentModel::model(), &QAbstractItemModel::dataChanged,
|
connect(DocumentModel::model(), &QAbstractItemModel::dataChanged,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
connect(DocumentModel::model(), &QAbstractItemModel::modelReset,
|
connect(DocumentModel::model(), &QAbstractItemModel::modelReset,
|
||||||
this, &CppIncludesFilter::markOutdated);
|
this, &CppIncludesFilter::invalidateCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppIncludesFilter::prepareSearch(const QString &entry)
|
void CppIncludesFilter::prepareSearch(const QString &entry)
|
||||||
@@ -146,16 +148,17 @@ void CppIncludesFilter::prepareSearch(const QString &entry)
|
|||||||
BaseFileFilter::prepareSearch(entry);
|
BaseFileFilter::prepareSearch(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppIncludesFilter::refresh(QFutureInterface<void> &future)
|
void CppIncludesFilter::invalidateCache()
|
||||||
{
|
|
||||||
Q_UNUSED(future)
|
|
||||||
QMetaObject::invokeMethod(this, &CppIncludesFilter::markOutdated, Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppIncludesFilter::markOutdated()
|
|
||||||
{
|
{
|
||||||
m_needsUpdate = true;
|
m_needsUpdate = true;
|
||||||
setFileIterator(nullptr); // clean up
|
setFileIterator(nullptr); // clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> CppIncludesFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return Sync([this] { invalidateCache(); return true; });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CppEditor::Internal
|
} // namespace CppEditor::Internal
|
||||||
|
@@ -15,10 +15,10 @@ public:
|
|||||||
// ILocatorFilter interface
|
// ILocatorFilter interface
|
||||||
public:
|
public:
|
||||||
void prepareSearch(const QString &entry) override;
|
void prepareSearch(const QString &entry) override;
|
||||||
void refresh(QFutureInterface<void> &future) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void markOutdated();
|
void invalidateCache();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
|
|
||||||
bool m_needsUpdate = true;
|
bool m_needsUpdate = true;
|
||||||
};
|
};
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <coreplugin/helpmanager.h>
|
#include <coreplugin/helpmanager.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
#include <QHelpEngine>
|
#include <QHelpEngine>
|
||||||
#include <QHelpFilterEngine>
|
#include <QHelpFilterEngine>
|
||||||
@@ -105,12 +106,6 @@ void HelpIndexFilter::accept(const LocatorFilterEntry &selection,
|
|||||||
emit linksActivated(links, key);
|
emit linksActivated(links, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelpIndexFilter::refresh(QFutureInterface<void> &future)
|
|
||||||
{
|
|
||||||
Q_UNUSED(future)
|
|
||||||
invalidateCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList HelpIndexFilter::allIndices() const
|
QStringList HelpIndexFilter::allIndices() const
|
||||||
{
|
{
|
||||||
LocalHelpManager::setupGuiHelpEngine();
|
LocalHelpManager::setupGuiHelpEngine();
|
||||||
@@ -121,3 +116,10 @@ void HelpIndexFilter::invalidateCache()
|
|||||||
{
|
{
|
||||||
m_needsUpdate = true;
|
m_needsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> HelpIndexFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return Sync([this] { invalidateCache(); return true; });
|
||||||
|
}
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QMultiMap>
|
#include <QMultiMap>
|
||||||
#include <QSet>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@@ -28,7 +27,6 @@ public:
|
|||||||
const QString &entry) override;
|
const QString &entry) override;
|
||||||
void accept(const Core::LocatorFilterEntry &selection,
|
void accept(const Core::LocatorFilterEntry &selection,
|
||||||
QString *newText, int *selectionStart, int *selectionLength) const override;
|
QString *newText, int *selectionStart, int *selectionLength) const override;
|
||||||
void refresh(QFutureInterface<void> &future) override;
|
|
||||||
|
|
||||||
QStringList allIndices() const;
|
QStringList allIndices() const;
|
||||||
|
|
||||||
@@ -36,10 +34,10 @@ signals:
|
|||||||
void linksActivated(const QMultiMap<QString, QUrl> &links, const QString &key) const;
|
void linksActivated(const QMultiMap<QString, QUrl> &links, const QString &key) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void invalidateCache();
|
|
||||||
|
|
||||||
bool updateCache(QFutureInterface<Core::LocatorFilterEntry> &future,
|
bool updateCache(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||||
const QStringList &cache, const QString &entry);
|
const QStringList &cache, const QString &entry);
|
||||||
|
void invalidateCache();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
|
|
||||||
QStringList m_allIndicesCache;
|
QStringList m_allIndicesCache;
|
||||||
QStringList m_lastIndicesCache;
|
QStringList m_lastIndicesCache;
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "projectmanager.h"
|
#include "projectmanager.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
@@ -25,12 +26,7 @@ AllProjectsFilter::AllProjectsFilter()
|
|||||||
setDefaultIncludedByDefault(true);
|
setDefaultIncludedByDefault(true);
|
||||||
|
|
||||||
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged,
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged,
|
||||||
this, &AllProjectsFilter::markFilesAsOutOfDate);
|
this, &AllProjectsFilter::invalidateCache);
|
||||||
}
|
|
||||||
|
|
||||||
void AllProjectsFilter::markFilesAsOutOfDate()
|
|
||||||
{
|
|
||||||
setFileIterator(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllProjectsFilter::prepareSearch(const QString &entry)
|
void AllProjectsFilter::prepareSearch(const QString &entry)
|
||||||
@@ -46,10 +42,16 @@ void AllProjectsFilter::prepareSearch(const QString &entry)
|
|||||||
BaseFileFilter::prepareSearch(entry);
|
BaseFileFilter::prepareSearch(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllProjectsFilter::refresh(QFutureInterface<void> &future)
|
void AllProjectsFilter::invalidateCache()
|
||||||
{
|
{
|
||||||
Q_UNUSED(future)
|
setFileIterator(nullptr);
|
||||||
QMetaObject::invokeMethod(this, &AllProjectsFilter::markFilesAsOutOfDate, Qt::QueuedConnection);
|
}
|
||||||
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> AllProjectsFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return Sync([this] { invalidateCache(); return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // ProjectExplorer::Internal
|
} // ProjectExplorer::Internal
|
||||||
|
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#include <coreplugin/locator/basefilefilter.h>
|
#include <coreplugin/locator/basefilefilter.h>
|
||||||
|
|
||||||
#include <QFutureInterface>
|
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -16,11 +14,11 @@ class AllProjectsFilter : public Core::BaseFileFilter
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AllProjectsFilter();
|
AllProjectsFilter();
|
||||||
void refresh(QFutureInterface<void> &future) override;
|
|
||||||
void prepareSearch(const QString &entry) override;
|
void prepareSearch(const QString &entry) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void markFilesAsOutOfDate();
|
void invalidateCache();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "projecttree.h"
|
#include "projecttree.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/tasktree.h>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -28,11 +29,6 @@ CurrentProjectFilter::CurrentProjectFilter()
|
|||||||
this, &CurrentProjectFilter::currentProjectChanged);
|
this, &CurrentProjectFilter::currentProjectChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurrentProjectFilter::markFilesAsOutOfDate()
|
|
||||||
{
|
|
||||||
setFileIterator(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CurrentProjectFilter::prepareSearch(const QString &entry)
|
void CurrentProjectFilter::prepareSearch(const QString &entry)
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
@@ -52,19 +48,24 @@ void CurrentProjectFilter::currentProjectChanged()
|
|||||||
return;
|
return;
|
||||||
if (m_project)
|
if (m_project)
|
||||||
disconnect(m_project, &Project::fileListChanged,
|
disconnect(m_project, &Project::fileListChanged,
|
||||||
this, &CurrentProjectFilter::markFilesAsOutOfDate);
|
this, &CurrentProjectFilter::invalidateCache);
|
||||||
|
|
||||||
if (project)
|
if (project)
|
||||||
connect(project, &Project::fileListChanged,
|
connect(project, &Project::fileListChanged,
|
||||||
this, &CurrentProjectFilter::markFilesAsOutOfDate);
|
this, &CurrentProjectFilter::invalidateCache);
|
||||||
|
|
||||||
m_project = project;
|
m_project = project;
|
||||||
markFilesAsOutOfDate();
|
invalidateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurrentProjectFilter::refresh(QFutureInterface<void> &future)
|
void CurrentProjectFilter::invalidateCache()
|
||||||
{
|
{
|
||||||
Q_UNUSED(future)
|
setFileIterator(nullptr);
|
||||||
QMetaObject::invokeMethod(this, &CurrentProjectFilter::markFilesAsOutOfDate,
|
}
|
||||||
Qt::QueuedConnection);
|
|
||||||
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
std::optional<TaskItem> CurrentProjectFilter::refreshRecipe()
|
||||||
|
{
|
||||||
|
return Sync([this] { invalidateCache(); return true; });
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#include <coreplugin/locator/basefilefilter.h>
|
#include <coreplugin/locator/basefilefilter.h>
|
||||||
|
|
||||||
#include <QFutureInterface>
|
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
class Project;
|
class Project;
|
||||||
@@ -19,12 +17,12 @@ class CurrentProjectFilter : public Core::BaseFileFilter
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CurrentProjectFilter();
|
CurrentProjectFilter();
|
||||||
void refresh(QFutureInterface<void> &future) override;
|
|
||||||
void prepareSearch(const QString &entry) override;
|
void prepareSearch(const QString &entry) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void currentProjectChanged();
|
void currentProjectChanged();
|
||||||
void markFilesAsOutOfDate();
|
void invalidateCache();
|
||||||
|
std::optional<Utils::Tasking::TaskItem> refreshRecipe() override;
|
||||||
|
|
||||||
Project *m_project = nullptr;
|
Project *m_project = nullptr;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user