diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp index 57cb7946de6..e89db528d70 100644 --- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp @@ -25,6 +25,59 @@ namespace CMakeProjectManager::Internal { // CMakeTargetLocatorFilter: // -------------------------------------------------------------------- +static LocatorMatcherTasks cmakeMatchers(const CMakeTargetLocatorFilter::BuildAcceptor &acceptor) +{ + using namespace Tasking; + + TreeStorage storage; + + const auto onSetup = [storage, acceptor] { + const QString input = storage->input(); + const QList projects = ProjectManager::projects(); + LocatorFilterEntries entries; + for (Project *project : projects) { + const auto cmakeProject = qobject_cast(project); + if (!cmakeProject || !cmakeProject->activeTarget()) + continue; + const auto bs = qobject_cast( + cmakeProject->activeTarget()->buildSystem()); + if (!bs) + continue; + + const QList buildTargets = bs->buildTargets(); + for (const CMakeBuildTarget &target : buildTargets) { + if (CMakeBuildSystem::filteredOutTarget(target)) + continue; + const int index = target.title.indexOf(input, 0, Qt::CaseInsensitive); + if (index >= 0) { + const FilePath path = target.backtrace.isEmpty() + ? cmakeProject->projectFilePath() + : target.backtrace.last().path; + const int line = target.backtrace.isEmpty() ? 0 : target.backtrace.last().line; + const FilePath projectPath = cmakeProject->projectFilePath(); + const QString displayName = target.title; + LocatorFilterEntry entry; + entry.displayName = displayName; + if (acceptor) { + entry.acceptor = [projectPath, displayName, acceptor] { + acceptor(projectPath, displayName); + return AcceptResult(); + }; + } + entry.linkForEditor = {path, line}; + entry.extraInfo = path.shortNativePath(); + entry.highlightInfo = {index, int(input.length())}; + entry.filePath = cmakeProject->projectFilePath(); + entries.append(entry); + } + } + } + storage->reportOutput(entries); + return true; + }; + return {{Sync(onSetup), storage}}; +} + CMakeTargetLocatorFilter::CMakeTargetLocatorFilter() { connect(ProjectManager::instance(), &ProjectManager::projectAdded, @@ -97,6 +150,33 @@ void CMakeTargetLocatorFilter::projectListUpdated() // BuildCMakeTargetLocatorFilter: // -------------------------------------------------------------------- +static void buildAcceptor(const Utils::FilePath &projectPath, const QString &displayName) +{ + // Get the project containing the target selected + const auto cmakeProject = qobject_cast( + Utils::findOrDefault(ProjectManager::projects(), [projectPath](Project *p) { + return p->projectFilePath() == projectPath; + })); + if (!cmakeProject || !cmakeProject->activeTarget() + || !cmakeProject->activeTarget()->activeBuildConfiguration()) + return; + + // Find the make step + BuildStepList *buildStepList = + cmakeProject->activeTarget()->activeBuildConfiguration()->buildSteps(); + auto buildStep = buildStepList->firstOfType(); + if (!buildStep) + return; + + // Change the make step to build only the given target + QStringList oldTargets = buildStep->buildTargets(); + buildStep->setBuildTargets({displayName}); + + // Build + BuildManager::buildProjectWithDependencies(cmakeProject); + buildStep->setBuildTargets(oldTargets); +} + BuildCMakeTargetLocatorFilter::BuildCMakeTargetLocatorFilter() { setId("Build CMake target"); @@ -104,31 +184,12 @@ BuildCMakeTargetLocatorFilter::BuildCMakeTargetLocatorFilter() setDescription(Tr::tr("Builds a target of any open CMake project.")); setDefaultShortcutString("cm"); setPriority(High); - setBuildAcceptor([](const Utils::FilePath &projectPath, const QString &displayName) { - // Get the project containing the target selected - const auto cmakeProject = qobject_cast( - Utils::findOrDefault(ProjectManager::projects(), [projectPath](Project *p) { - return p->projectFilePath() == projectPath; - })); - if (!cmakeProject || !cmakeProject->activeTarget() - || !cmakeProject->activeTarget()->activeBuildConfiguration()) - return; + setBuildAcceptor(&buildAcceptor); +} - // Find the make step - BuildStepList *buildStepList = - cmakeProject->activeTarget()->activeBuildConfiguration()->buildSteps(); - auto buildStep = buildStepList->firstOfType(); - if (!buildStep) - return; - - // Change the make step to build only the given target - QStringList oldTargets = buildStep->buildTargets(); - buildStep->setBuildTargets({displayName}); - - // Build - BuildManager::buildProjectWithDependencies(cmakeProject); - buildStep->setBuildTargets(oldTargets); - }); +Core::LocatorMatcherTasks BuildCMakeTargetLocatorFilter::matchers() +{ + return cmakeMatchers(&buildAcceptor); } // -------------------------------------------------------------------- @@ -144,4 +205,9 @@ OpenCMakeTargetLocatorFilter::OpenCMakeTargetLocatorFilter() setPriority(Medium); } +Core::LocatorMatcherTasks OpenCMakeTargetLocatorFilter::matchers() +{ + return cmakeMatchers({}); +} + } // CMakeProjectManager::Internal diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h index 4e73b59e4ad..73b3212b3fd 100644 --- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h +++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h @@ -7,6 +7,7 @@ namespace CMakeProjectManager::Internal { +// TODO: Remove the base class class CMakeTargetLocatorFilter : public Core::ILocatorFilter { public: @@ -15,8 +16,8 @@ public: void prepareSearch(const QString &entry) override; QList matchesFor(QFutureInterface &future, const QString &entry) final; -protected: using BuildAcceptor = std::function; +protected: void setBuildAcceptor(const BuildAcceptor &acceptor) { m_acceptor = acceptor; } private: @@ -26,16 +27,24 @@ private: BuildAcceptor m_acceptor; }; +// TODO: Don't derive, flatten the hierarchy class BuildCMakeTargetLocatorFilter : CMakeTargetLocatorFilter { public: BuildCMakeTargetLocatorFilter(); + +private: + Core::LocatorMatcherTasks matchers() final; }; +// TODO: Don't derive, flatten the hierarchy class OpenCMakeTargetLocatorFilter : CMakeTargetLocatorFilter { public: OpenCMakeTargetLocatorFilter(); + +private: + Core::LocatorMatcherTasks matchers() final; }; } // CMakeProjectManager::Internal