diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index 9aac275b99c..178d9267284 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -496,6 +496,8 @@ SearchUnresolvedIncludes.name=Search for Unresolved Includes
SearchUnresolvedIncludes.label=Search for Unresolved &Includes
CreateParserLog.name=Create Parser Log File
CreateParserLog.label=Create Parser &Log File
+wsselection.command.name=Manage Working Sets
+ManageConfigs.command.name=Manage Build Configurations
indexerPage.name = Indexer Page
proposalFilter.name = Code Completion Proposal Filter
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index ee0a5873c7d..103e3a96954 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -1750,6 +1750,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
@@ -4719,6 +4777,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
projects = findProjects();
+
+ SortedSet configNames = new TreeSet<>();
+ String sCurrentConfig = null;
+ boolean bCurrentConfig = true;
+ for (IProject prj : projects) {
+ ICConfigurationDescription[] cfgDescs = getCfgs(prj);
+
+ String sActiveConfig = null;
+ // Store names and detect active configuration
+ for (ICConfigurationDescription cfgDesc : cfgDescs) {
+ String s = cfgDesc.getName();
+ if (!configNames.contains(s))
+ configNames.add(s);
+ if (cfgDesc.isActive())
+ sActiveConfig = s;
+ }
+
+ // Check whether all projects have the same active configuration
+ if (bCurrentConfig) {
+ if (sCurrentConfig == null)
+ sCurrentConfig = sActiveConfig;
+ else {
+ if (!sCurrentConfig.equals(sActiveConfig))
+ bCurrentConfig = false;
+ }
+ }
+ }
+
+ List actions = new ArrayList<>();
+ int accel = 0;
+ for (String sName : configNames) {
+ String sDesc = null;
+ boolean commonName = true;
+ boolean commonDesc = true;
+ boolean firstProj = true;
+ for (IProject prj : projects) {
+ ICConfigurationDescription[] cfgDescs = getCfgs(prj);
+ int i = 0;
+ for (; i < cfgDescs.length; i++) {
+ if (cfgDescs[i].getName().equals(sName)) {
+ String sNewDesc = cfgDescs[i].getDescription();
+ if (sNewDesc != null && sNewDesc.length() == 0) {
+ sNewDesc = null;
+ }
+ if (commonDesc) {
+ if (firstProj) {
+ sDesc = sNewDesc;
+ firstProj = false;
+ } else if (sNewDesc == null && sDesc != null
+ || sNewDesc != null && !sNewDesc.equals(sDesc)) {
+ commonDesc = false;
+ }
+ }
+ break;
+ }
+ }
+ if (i == cfgDescs.length) {
+ commonName = false;
+ break;
+ }
+ }
+ if (commonName) {
+ StringBuffer builder = new StringBuffer(sName);
+ if (commonDesc) {
+ if (sDesc != null) {
+ builder.append(" ("); //$NON-NLS-1$
+ builder.append(sDesc);
+ builder.append(")"); //$NON-NLS-1$
+ }
+ } else {
+ builder.append(" (...)"); //$NON-NLS-1$
+ }
+
+ IAction action = new ChangeConfigAction(projects, sName, builder.toString(), accel + 1);
+ if (bCurrentConfig && sCurrentConfig != null && sCurrentConfig.equals(sName)) {
+ action.setChecked(true);
+ }
+ ActionContributionItem item = new ActionContributionItem(action);
+ actions.add(item);
+ accel++;
+ }
+ }
+ return actions.toArray(new IContributionItem[0]);
+ }
+
+ private static HashSet findProjects() {
+ HashSet fProjects = new LinkedHashSet<>();
+ ISelection selection = CUIPlugin.getActivePage().getSelection();
+ boolean badObject = addProjectsFromSelection(selection, fProjects);
+
+ if (badObject || fProjects.isEmpty()) {
+ // Check for lone CDT project in workspace
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ if (projects != null && projects.length == 1) {
+ IProject project = projects[0];
+ if (CoreModel.getDefault().isNewStyleProject(project) && (getCfgs(project).length > 0)) {
+ fProjects.add(project);
+ }
+ }
+
+ // Check the three supported views
+ IWorkbenchPage page = CUIPlugin.getActivePage();
+ int viewCount = 0;
+ if (page != null) {
+ IViewReference theViewRef = null;
+ IViewReference viewRef = null;
+
+ theViewRef = page.findViewReference("org.eclipse.cdt.ui.CView"); //$NON-NLS-1$
+ viewCount += (theViewRef != null) ? 1 : 0;
+
+ viewRef = page.findViewReference("org.eclipse.ui.navigator.ProjectExplorer"); //$NON-NLS-1$
+ viewCount += (viewRef != null) ? 1 : 0;
+ theViewRef = (theViewRef == null) ? viewRef : theViewRef;
+
+ viewRef = page.findViewReference("org.eclipse.ui.views.ResourceNavigator"); //$NON-NLS-1$
+ viewCount += (viewRef != null) ? 1 : 0;
+ theViewRef = (theViewRef == null) ? viewRef : theViewRef;
+
+ if (theViewRef != null && viewCount == 1) {
+ IViewPart view = theViewRef.getView(false);
+ if (view != null) {
+ ISelection cdtSelection = view.getSite().getSelectionProvider().getSelection();
+ if (cdtSelection != null) {
+ if (!cdtSelection.isEmpty()) {
+ if (!cdtSelection.equals(selection)) {
+ addProjectsFromSelection(cdtSelection, fProjects);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return fProjects;
+ }
+
+ private static boolean addProjectsFromSelection(ISelection selection, HashSet fProjects) {
+ boolean badObject = false;
+ if (selection != null) {
+ if (selection instanceof IStructuredSelection) {
+ if (selection.isEmpty()) {
+ // could be a form editor or something. try to get the project from the active part
+ IWorkbenchPage page = CUIPlugin.getActivePage();
+ if (page != null) {
+ IWorkbenchPart part = page.getActivePart();
+ if (part != null) {
+ Object o = part.getAdapter(IResource.class);
+ if (o != null && o instanceof IResource) {
+ fProjects.add(((IResource) o).getProject());
+ }
+ }
+ }
+ }
+ Iterator> iter = ((IStructuredSelection) selection).iterator();
+ while (iter.hasNext()) {
+ Object selItem = iter.next();
+ IProject project = null;
+ if (selItem instanceof ICElement) {
+ ICProject cproject = ((ICElement) selItem).getCProject();
+ if (cproject != null)
+ project = cproject.getProject();
+ } else if (selItem instanceof IResource) {
+ project = ((IResource) selItem).getProject();
+ } else if (selItem instanceof IncludeRefContainer) {
+ ICProject fCProject = ((IncludeRefContainer) selItem).getCProject();
+ if (fCProject != null)
+ project = fCProject.getProject();
+ } else if (selItem instanceof IncludeReferenceProxy) {
+ IncludeRefContainer irc = ((IncludeReferenceProxy) selItem).getIncludeRefContainer();
+ if (irc != null) {
+ ICProject fCProject = irc.getCProject();
+ if (fCProject != null)
+ project = fCProject.getProject();
+ }
+ } else if (selItem instanceof IAdaptable) {
+ Object adapter = ((IAdaptable) selItem).getAdapter(IProject.class);
+ if (adapter != null && adapter instanceof IProject) {
+ project = (IProject) adapter;
+ }
+ }
+ // Check whether the project is CDT project
+ if (project != null) {
+ if (!CoreModel.getDefault().isNewStyleProject(project))
+ project = null;
+ else {
+ ICConfigurationDescription[] tmp = getCfgs(project);
+ if (tmp.length == 0)
+ project = null;
+ }
+ }
+ if (project != null) {
+ fProjects.add(project);
+ } else {
+ badObject = true;
+ break;
+ }
+ }
+ } else if (selection instanceof ITextSelection) {
+ // If a text selection check the selected part to see if we can find
+ // an editor part that we can adapt to a resource and then
+ // back to a project.
+ IWorkbenchWindow window = CUIPlugin.getActiveWorkbenchWindow();
+ if (window != null) {
+ IWorkbenchPage page = window.getActivePage();
+ if (page != null) {
+ IWorkbenchPart part = page.getActivePart();
+ if (part instanceof IEditorPart) {
+ IEditorPart epart = (IEditorPart) part;
+ IResource resource = epart.getEditorInput().getAdapter(IResource.class);
+ if (resource != null) {
+ IProject project = resource.getProject();
+ badObject = !(project != null && CoreModel.getDefault().isNewStyleProject(project));
+
+ if (!badObject) {
+ fProjects.add(project);
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+ return badObject;
+ }
+
+ private static ICConfigurationDescription[] getCfgs(IProject prj) {
+ ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(prj, false);
+ if (prjd != null) {
+ ICConfigurationDescription[] cfgs = prjd.getConfigurations();
+ if (cfgs != null) {
+ return cfgs;
+ }
+ }
+
+ return new ICConfigurationDescription[0];
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/HasManagedCdtProjectSelection.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/HasManagedCdtProjectSelection.java
new file mode 100644
index 00000000000..cc1f4800539
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/HasManagedCdtProjectSelection.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.workingsets;
+
+import java.util.Collection;
+
+import org.eclipse.cdt.ui.newui.ManageConfigSelector;
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IProject;
+
+/**
+ * Property tester for the enablement of the command handled by {@link org.eclipse.cdt.internal.ui.actions.ManageConfigsHandler}.
+ * Will evaluate {@code true} if the current selection is a managed CDT project, contains a managed CDT project, or belongs to a managed CDT project.
+ */
+public class HasManagedCdtProjectSelection extends PropertyTester {
+
+ private static final String PROPERTY_HAS_MANAGED_CDT_PROJECT_SELECTION = "hasManagedCdtProjectSelection"; //$NON-NLS-1$
+
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (PROPERTY_HAS_MANAGED_CDT_PROJECT_SELECTION.equals(property)) {
+ boolean hasNonEmptyWorksets = hasManagedCdtProjectSelection(receiver);
+ return hasNonEmptyWorksets;
+ }
+ return false;
+ }
+
+ private static boolean hasManagedCdtProjectSelection(Object receiver) {
+ if (receiver instanceof Collection) {
+ Collection> selection = (Collection>) receiver;
+ if (!selection.isEmpty()) {
+ IProject[] obs = ManageConfigSelector.getProjects(selection.toArray());
+ return ManageConfigSelector.getManager(obs) != null;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/NonEmptyWorkingSetPropertyTester.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/NonEmptyWorkingSetPropertyTester.java
new file mode 100644
index 00000000000..2944480388d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/NonEmptyWorkingSetPropertyTester.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.workingsets;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Property tester for the enablement of the command handled by {@link org.eclipse.cdt.internal.ui.actions.WorkingSetConfigHandler}.
+ * Will evaluate {@code true} if there is a non-empty working set in the workspace.
+ */
+public class NonEmptyWorkingSetPropertyTester extends PropertyTester {
+
+ private static final String PROPERTY_HAS_NON_EMPTY_WORKING_SET = "hasNonEmptyWorkingSet"; //$NON-NLS-1$
+
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (PROPERTY_HAS_NON_EMPTY_WORKING_SET.equals(property)) {
+ boolean hasNonEmptyWorksets = hasNonEmptyWorksets();
+ return hasNonEmptyWorksets;
+ }
+ return false;
+ }
+
+ private static boolean hasNonEmptyWorksets() {
+ IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet[] workingSets = workingSetManager.getWorkingSets();
+ if (workingSets != null) {
+ for (IWorkingSet workingSet : workingSets) {
+ if (!workingSet.isEmpty()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ChangeBuildConfigMenuAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ChangeBuildConfigMenuAction.java
index 06b6fea382e..aae36101f0d 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ChangeBuildConfigMenuAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ChangeBuildConfigMenuAction.java
@@ -30,7 +30,10 @@ import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
/**
* Action which changes active build configuration of the current project
+ *
+ * @deprecated Replaced with menu contribution {@link org.eclipse.cdt.internal.ui.workingsets.ChangeBuildConfigContribution}.
*/
+@Deprecated(forRemoval = true)
public class ChangeBuildConfigMenuAction extends ChangeBuildConfigActionBase
implements IWorkbenchWindowPulldownDelegate2 {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ManageConfigsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ManageConfigsAction.java
index 2027fd369fa..0a09b297c1c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ManageConfigsAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/ManageConfigsAction.java
@@ -28,7 +28,10 @@ import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
/**
* Action which lets to manage (add/remove etc.) build configurations of the project.
+ *
+ * @deprecated Replaced with a command and handler {@link org.eclipse.cdt.internal.ui.actions.ManageConfigsHandler}.
*/
+@Deprecated(forRemoval = true)
public class ManageConfigsAction implements IWorkbenchWindowPulldownDelegate2, IObjectActionDelegate {
IProject[] obs = null;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/WorkingSetConfigAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/WorkingSetConfigAction.java
index d238c84c8d3..df549077886 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/WorkingSetConfigAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/WorkingSetConfigAction.java
@@ -27,7 +27,9 @@ import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
/**
+ * @deprecated Replaced with a command and handler {@link org.eclipse.cdt.internal.ui.actions.WorkingSetConfigHandler}.
*/
+@Deprecated(forRemoval = true)
public class WorkingSetConfigAction implements IWorkbenchWindowActionDelegate, IPropertyChangeListener {
private static final IWorkingSetManager wsm = PlatformUI.getWorkbench().getWorkingSetManager();