Commit 4ae0f487 authored by René J.V. Bertin's avatar René J.V. Bertin

"Reparse Entire Project" action for the ProjectController

Adds a "Reparse the Entire Project" action to the project controller
context menu. This makes it possible to trigger a full (re)parse
of individual projects without reloading them, or when the option to
"schedule all project files for parsing" is turned off.

Differential Revision: https://phabricator.kde.org/D11934
parent d284d5bb
......@@ -148,8 +148,12 @@ public Q_SLOTS:
virtual void configureProject( IProject* ) = 0;
/// Schedules all files of the @p project for reparsing by @see BackgroundParser
virtual void reparseProject( IProject* project, bool ForceUpdate = false ) = 0;
/**
* Schedules all files of the @p project for reparsing by @see BackgroundParser
* The @p forceAll argument is for triggering a full reparse of the entire project
* after the initial import.
*/
virtual void reparseProject( IProject* project, bool forceUpdate = false, bool forceAll = false ) = 0;
// virtual void changeCurrentProject( KDevelop::ProjectBaseItem* ) = 0;
......
......@@ -41,14 +41,16 @@ using namespace KDevelop;
class KDevelop::ParseProjectJobPrivate
{
public:
ParseProjectJobPrivate(IProject* project, bool forceUpdate)
ParseProjectJobPrivate(IProject* project, bool forceUpdate, bool forceAll)
: forceUpdate(forceUpdate)
, forceAll(forceAll)
, project(project)
{
}
int updated = 0;
bool forceUpdate;
bool forceAll;
KDevelop::IProject* project;
QSet<IndexedString> filesToParse;
};
......@@ -68,12 +70,14 @@ ParseProjectJob::~ParseProjectJob()
ICore::self()->runController()->unregisterJob(this);
}
ParseProjectJob::ParseProjectJob(IProject* project, bool forceUpdate)
: d(new ParseProjectJobPrivate(project, forceUpdate))
ParseProjectJob::ParseProjectJob(IProject* project, bool forceUpdate, bool forceAll)
: d(new ParseProjectJobPrivate(project, forceUpdate, forceAll))
{
connect(project, &IProject::destroyed, this, &ParseProjectJob::deleteNow);
if (!ICore::self()->projectController()->parseAllProjectSources()) {
if (forceAll || ICore::self()->projectController()->parseAllProjectSources()) {
d->filesToParse = project->fileSet();
} else {
// In case we don't want to parse the whole project, still add all currently open files that belong to the project to the background-parser
foreach (auto document, ICore::self()->documentController()->openDocuments()) {
const auto path = IndexedString(document->url());
......@@ -81,8 +85,6 @@ ParseProjectJob::ParseProjectJob(IProject* project, bool forceUpdate)
d->filesToParse.insert(path);
}
}
} else {
d->filesToParse = project->fileSet();
}
setCapabilities(Killable);
......@@ -160,7 +162,7 @@ void ParseProjectJob::start()
}
}
if (!ICore::self()->projectController()->parseAllProjectSources()) {
if (!d->forceAll && !ICore::self()->projectController()->parseAllProjectSources()) {
return;
}
......
......@@ -28,15 +28,21 @@ namespace KDevelop {
class ReferencedTopDUContext;
class IProject;
///A job that parses all project-files in the given project
///Deletes itself as soon as the project is deleted
///A job that parses all project-files in the given project either
///when KDevelop is configured to parse all files at project import
///(see ProjectController:parseAllProjectSources()) or when the
///forceAll argument is true. That forceAll argument allows to
///trigger a full project reparse after the initial import, e.g.
///via the project manager's context menu.
///ParseProjectJob instances delete themselves as soon as the project
///is deleted or when a new job is started.
class KDEVPLATFORMLANGUAGE_EXPORT ParseProjectJob
: public KJob
{
Q_OBJECT
public:
explicit ParseProjectJob(KDevelop::IProject* project, bool forceUpdate = false);
explicit ParseProjectJob(KDevelop::IProject* project, bool forceUpdate = false, bool forceAll = false);
~ParseProjectJob() override;
void start() override;
bool doKill() override;
......
......@@ -263,25 +263,7 @@ public:
m_closeProject->setEnabled(itemCount > 0);
}
void openProjectConfig()
{
// if only one project loaded, this is our target
IProject *project = (m_projects.count() == 1) ? m_projects.at(0) : nullptr;
// otherwise base on selection
if (!project) {
auto* ctx = dynamic_cast<ProjectItemContext*>(ICore::self()->selectionController()->currentSelection());
if (ctx && ctx->items().count() == 1) {
project = ctx->items().at(0)->project();
}
}
if (project) {
q->configureProject(project);
}
}
void closeSelectedProjects()
QSet<IProject*> selectedProjects()
{
QSet<IProject*> projects;
......@@ -290,15 +272,28 @@ public:
projects.insert(m_projects.at(0));
} else {
// otherwise base on selection
auto* ctx = dynamic_cast<ProjectItemContext*>(ICore::self()->selectionController()->currentSelection());
auto* ctx = dynamic_cast<ProjectItemContext*>(ICore::self()->selectionController()->currentSelection());
if (ctx) {
foreach (ProjectBaseItem* item, ctx->items()) {
projects.insert(item->project());
}
}
}
return projects;
}
void openProjectConfig()
{
auto projects = selectedProjects();
if (projects.count() == 1) {
q->configureProject(*projects.constBegin());
}
}
foreach (IProject* project, projects) {
void closeSelectedProjects()
{
foreach (IProject* project, selectedProjects()) {
q->closeProject(project);
}
}
......@@ -1180,12 +1175,26 @@ ContextMenuExtension ProjectController::contextMenuExtension(Context* ctx, QWidg
{
Q_UNUSED(parent);
ContextMenuExtension ext;
if ( ctx->type() != Context::ProjectItemContext || !static_cast<ProjectItemContext*>(ctx)->items().isEmpty() ) {
if ( ctx->type() != Context::ProjectItemContext) {
return ext;
}
if (!static_cast<ProjectItemContext*>(ctx)->items().isEmpty() ) {
auto* action = new QAction(i18n("Reparse the Entire Project"), this);
connect(action, &QAction::triggered, this, [&] {
foreach (auto project, d->selectedProjects()) {
reparseProject(project, true, true);
}
});
ext.addAction(ContextMenuExtension::ProjectGroup, action);
return ext;
}
ext.addAction(ContextMenuExtension::ProjectGroup, d->m_openProject);
ext.addAction(ContextMenuExtension::ProjectGroup, d->m_fetchProject);
ext.addAction(ContextMenuExtension::ProjectGroup, d->m_recentProjectsAction);
return ext;
}
......@@ -1285,13 +1294,13 @@ QString ProjectController::mapSourceBuild( const QString& path_, bool reverse, b
return QString();
}
void ProjectController::reparseProject( IProject* project, bool forceUpdate )
{
void KDevelop::ProjectController::reparseProject(IProject *project, bool forceUpdate, bool forceAll)
{
if (auto job = d->m_parseJobs.value(project)) {
job->kill();
}
d->m_parseJobs[project] = new KDevelop::ParseProjectJob(project, forceUpdate);
d->m_parseJobs[project] = new KDevelop::ParseProjectJob(project, forceUpdate, forceAll);
ICore::self()->runController()->registerJob(d->m_parseJobs[project]);
}
......
......@@ -113,7 +113,7 @@ public Q_SLOTS:
void closeAllProjects() override;
void configureProject( IProject* ) override;
void reparseProject( IProject* project, bool forceUpdate = false ) override;
void reparseProject( IProject* project, bool forceUpdate = false, bool forceAll = false ) override;
void eventuallyOpenProjectFile(KIO::Job* job, const KIO::UDSEntryList& entries);
void openProjectForUrlSlot(bool);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment