From a27d9238f4bea73a3ed56e9b89159c0b742c7170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Mon, 3 Nov 2025 06:27:10 +0100 Subject: [PATCH] Add support for nested problems display for hierarchical projects Currently if one select in Project Explorer to display projects not only flat but hierarchical and choose the "Problems on selected Project" filtering (but other filters are affected as well) the following happens: - We have Project P with nested projects X, Y, Z - Y has a compile problem and X has warnings - Now P shows a red icon because it has problems of type error inherited - I select P but Problems View remains empty - One has to first expand P, then locate Y and select it - To see the warning I have to locate X and select it so there is an inconsistency (P shows problems icon but problems view is empty) and an inconvenience (I need to select individual childs to see all problems/warnings). This now enhances the ExtendedMarkersView by a method isProjectNestingActive (returns false by default) to allow view extensions to decide if they want to enable discovery of nested projects or not. The ProblemsView is further enhanced to detect the situation and returns true for this particular case. --- .../views/markers/ExtendedMarkersView.java | 24 ++++++++++- .../views/markers/MarkerResourceUtil.java | 40 +++++++++++++++++++ .../internal/views/markers/ProblemsView.java | 12 ++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ExtendedMarkersView.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ExtendedMarkersView.java index 2a3fdb661a0..af74d82ab88 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ExtendedMarkersView.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ExtendedMarkersView.java @@ -24,11 +24,14 @@ import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.eclipse.core.commands.operations.IUndoContext; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.Assert; @@ -1642,16 +1645,35 @@ public void selectionChanged(IWorkbenchPart part, ISelection selection) { } // try to adapt them in resources and add it to the // selectedElements - List selectedElements = new ArrayList<>(); + Set selectedElements = new LinkedHashSet<>(); for (Object object : objectsToAdapt) { Object resElement = MarkerResourceUtil.adapt2ResourceElement(object); if (resElement != null) { selectedElements.add(resElement); } } + if (isProjectNestingActive(part)) { + List selectedProjects = selectedElements.stream().filter(IProject.class::isInstance) + .map(IProject.class::cast).toList(); + if (!selectedProjects.isEmpty()) { + selectedElements.addAll(MarkerResourceUtil.getNestedChildProjects(selectedProjects)); + } + } MarkerContentGenerator gen = view.getGenerator(); gen.updateSelectedResource(selectedElements.toArray(), part == null); } + + } + + /** + * Check if project nesting is active for this marker view + * + * @param part the currently selected part + * @return true if nesting should be performed, false + * otherwise + */ + protected boolean isProjectNestingActive(IWorkbenchPart part) { + return false; } /** diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/MarkerResourceUtil.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/MarkerResourceUtil.java index 93a5062e156..ce8b6890125 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/MarkerResourceUtil.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/MarkerResourceUtil.java @@ -31,6 +31,7 @@ import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.ui.internal.ide.Policy; import org.eclipse.ui.internal.util.Util; @@ -286,6 +287,45 @@ static Collection getProjectsAsCollection(Object[] elements) { return projects; } + /** + * Returns all nested child projects of the given projects. A project is + * considered a nested child if its location is a descendant of the parent + * project's location. This supports the hierarchical project display feature. + * + * @param parentProjects + * the projects to find nested children for + * @return collection of all nested child projects (does not include the parent + * projects themselves) + */ + static Collection getNestedChildProjects(Collection parentProjects) { + if (parentProjects == null || parentProjects.isEmpty()) { + return Set.of(); + } + Set nestedChildren = new HashSet<>(); + + for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { + if (!project.exists() || !project.isAccessible()) { + continue; + } + IPath projectLocation = project.getLocation(); + if (projectLocation == null) { + continue; + } + // Check if this project is nested under any of the parent projects + for (IProject parentProject : parentProjects) { + if (parentProject.equals(project)) { + continue; // Skip the project itself + } + IPath parentLocation = parentProject.getLocation(); + if (parentLocation != null && parentLocation.isPrefixOf(projectLocation)) { + nestedChildren.add(project); + break; + } + } + } + return nestedChildren; + } + /** * Add the resources in resourceMapping to the resourceCollection */ diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ProblemsView.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ProblemsView.java index b6c0a4e1227..d48dc04316e 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ProblemsView.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/views/markers/ProblemsView.java @@ -17,9 +17,11 @@ import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.Assert; import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages; +import org.eclipse.ui.navigator.CommonNavigator; import org.eclipse.ui.views.markers.MarkerSupportView; import org.eclipse.ui.views.markers.internal.MarkerMessages; import org.eclipse.ui.views.markers.internal.MarkerSupportRegistry; @@ -64,4 +66,14 @@ protected String getDeleteOperationName(IMarker[] markers) { return markers.length == 1 ? MarkerMessages.deleteProblemMarker_operationName : MarkerMessages.deleteProblemMarkers_operationName; } + @Override + protected boolean isProjectNestingActive(IWorkbenchPart part) { + if (part instanceof CommonNavigator navigator) { + return navigator.getNavigatorContentService().getActivationService().isNavigatorExtensionActive( + "org.eclipse.ui.navigator.resources.nested.nestedProjectContentProvider"); //$NON-NLS-1$ + + } + return false; + } + }