Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.ICommand;
Expand Down Expand Up @@ -114,20 +113,16 @@ public void fillActionBars(IActionBars actionBars) {
@Override
public void fillContextMenu(IMenuManager menu) {
IStructuredSelection selection = (IStructuredSelection) getContext().getSelection();
boolean isProjectSelection = true;
boolean hasOpenProjects = false;
boolean hasClosedProjects = false;
boolean hasBuilder = true; // false if any project is closed or does not
// have builder
boolean hasBuilder = true; // false if any project is closed or does not have builder
List<IProject> projects = selectionToProjects(selection);
boolean selectionContainsNonProject = projects.size() < selection.size();

Iterator<IProject> projects = selectionToProjects(selection).iterator();

while (projects.hasNext() && (!hasOpenProjects || !hasClosedProjects || hasBuilder || isProjectSelection)) {
IProject project = projects.next();

if (project == null) {
isProjectSelection = false;
continue;
for (IProject project : projects) {
if (hasOpenProjects && hasClosedProjects && !hasBuilder) {
// we've set all booleans of interest; no need to loop any further
break;
}
if (project.isOpen()) {
hasOpenProjects = true;
Expand All @@ -139,30 +134,29 @@ public void fillContextMenu(IMenuManager menu) {
hasBuilder = false;
}
}
if (!selection.isEmpty() && isProjectSelection && !ResourcesPlugin.getWorkspace().isAutoBuilding()
if (!selection.isEmpty() && !ResourcesPlugin.getWorkspace().isAutoBuilding()
&& hasBuilder) {
// Allow manual incremental build only if auto build is off.
buildAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, buildAction);
}
// Add the 'refresh' item if any selection is either (a) an open project, or (b)
// a non-project selection (so the 'refresh' item is not shown if all selections
// are closed projects)
if (hasOpenProjects || !isProjectSelection) {
// Add the 'refresh' item if ANY selection is either (a) an open project, or (b)
// a non-project selection.
// Put another way: the 'refresh' item is NOT shown if ALL selections are closed
// projects.
if (hasOpenProjects || selectionContainsNonProject) {
refreshAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, refreshAction);
}
if (isProjectSelection) {
if (hasClosedProjects) {
openProjectAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, openProjectAction);
}
if (hasOpenProjects) {
closeProjectAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeProjectAction);
closeUnrelatedProjectsAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeUnrelatedProjectsAction);
}
if (hasClosedProjects) {
openProjectAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, openProjectAction);
}
if (hasOpenProjects) {
closeProjectAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeProjectAction);
closeUnrelatedProjectsAction.selectionChanged(selection);
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeUnrelatedProjectsAction);
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundlename
Bundle-SymbolicName: org.eclipse.ui.tests.navigator;singleton:=true
Bundle-Version: 3.7.600.qualifier
Bundle-Version: 3.7.700.qualifier
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.resources,
org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.ui.tests.navigator.resources.FoldersAsProjectsContributionTest;
import org.eclipse.ui.tests.navigator.resources.NestedResourcesTests;
import org.eclipse.ui.tests.navigator.resources.PathComparatorTest;
import org.eclipse.ui.tests.navigator.resources.ResourceMgmtActionProviderTests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
Expand All @@ -34,7 +35,7 @@
ProgrammaticOpenTest.class, PipelineTest.class, PipelineChainTest.class, JstPipelineTest.class,
LabelProviderTest.class, SorterTest.class, ViewerTest.class, CdtTest.class, M12Tests.class,
FirstClassM1Tests.class, LinkHelperTest.class, ShowInTest.class, ResourceTransferTest.class,
EvaluationCacheTest.class,
EvaluationCacheTest.class, ResourceMgmtActionProviderTests.class,
NestedResourcesTests.class, PathComparatorTest.class, FoldersAsProjectsContributionTest.class,
GoBackForwardsTest.class
// DnDTest.class, // DnDTest.testSetDragOperation() fails
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*******************************************************************************
* Copyright (c) 2024 Dave Carpeneto 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
*******************************************************************************/
package org.eclipse.ui.tests.navigator.resources;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.internal.navigator.NavigatorContentService;
import org.eclipse.ui.internal.navigator.extensions.CommonActionExtensionSite;
import org.eclipse.ui.internal.navigator.resources.actions.ResourceMgmtActionProvider;
import org.eclipse.ui.navigator.CommonViewerSiteFactory;
import org.eclipse.ui.navigator.ICommonActionExtensionSite;
import org.eclipse.ui.navigator.ICommonMenuConstants;
import org.eclipse.ui.tests.navigator.NavigatorTestBase;
import org.junit.Before;
import org.junit.Test;

public final class ResourceMgmtActionProviderTests extends NavigatorTestBase {

private IMenuManager manager;

public ResourceMgmtActionProviderTests() {
_navigatorInstanceId = TEST_VIEWER;
}

@Override
@Before
public void setUp() {
super.setUp();
manager = new MenuManager();
manager.add(new GroupMarker(ICommonMenuConstants.GROUP_BUILD));
}

/**
* Test for 'no selection' condition - no menu items should be included
*/
@Test
public void testFillContextMenu_noSelection() {
ResourceMgmtActionProvider provider = provider((IResource[]) null);
provider.fillContextMenu(manager);
checkMenuHasCorrectContributions(false, false, false, false, false);
}

/**
* Test for 'folder' condition - only 'refresh' should be included
*/
@Test
public void testFillContextMenu_folderSelection() {

IFolder justAFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path("some/folder"));
ResourceMgmtActionProvider provider = provider(justAFolder);
provider.fillContextMenu(manager);
checkMenuHasCorrectContributions(false, true, false, false, false);
}

/**
* Test for 'closed project' - only 'open project' should be included
*/
@Test
public void testFillContextMenu_closedProjectSelection() {
IProject closedProj = ResourcesPlugin.getWorkspace().getRoot().getProject("closedProj");
ResourceMgmtActionProvider provider = provider(closedProj);
provider.fillContextMenu(manager);
checkMenuHasCorrectContributions(false, false, true, false, false);
}

/**
* Test for 'open project' that doesn't have a builder attached - all but
* 'build' &amp; 'open project' should be enabled
*/
@Test
public void testFillContextMenu_openProjectNoBuilderSelection() {
IProject openProj = ResourcesPlugin.getWorkspace().getRoot().getProject("Test");
boolean autoBuildInitialState = ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding();

try {
if (!autoBuildInitialState) {
// we want to enable auto-building for this test to guarantee that the 'build'
// menu option isn't shown
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
wsd.setAutoBuilding(true);
ResourcesPlugin.getWorkspace().setDescription(wsd);
}
openProj.open(null);
} catch (CoreException e) {
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
}
ResourceMgmtActionProvider provider = provider(openProj);
provider.fillContextMenu(manager);
checkMenuHasCorrectContributions(false, true, false, true, true);

if (!autoBuildInitialState) {
// clean-up: reset autobuild since we changed it
try {
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
wsd.setAutoBuilding(false);
ResourcesPlugin.getWorkspace().setDescription(wsd);
} catch (CoreException e) {
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
}
}
}

/**
* Test for 'open project' that doesn't have a builder attached - only 'open
* project' should be disabled
*/
@Test
public void testFillContextMenu_openProjectWithBuilderSelection() {
IProject openProj = ResourcesPlugin.getWorkspace().getRoot().getProject("Test");
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
boolean autobuildInitialState = wsd.isAutoBuilding();
boolean hasNoInitialBuildCommands = false;
IProjectDescription desc = null;
try {
if (autobuildInitialState) {
wsd.setAutoBuilding(false);
ResourcesPlugin.getWorkspace().setDescription(wsd);
}
openProj.open(null);
desc = openProj.getDescription();
if (desc.getBuildSpec().length == 0) {
hasNoInitialBuildCommands = true;
ICommand cmd = desc.newCommand();
desc.setBuildSpec(new ICommand[] { cmd });
openProj.setDescription(desc, null);
}
} catch (CoreException e) {
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
}
ResourceMgmtActionProvider provider = provider(openProj);
provider.fillContextMenu(manager);
checkMenuHasCorrectContributions(true, true, false, true, true);
try {
// clean-up where needed: reset autobuild if we changed it & remove
// the build config if we added it
if (autobuildInitialState) {
wsd.setAutoBuilding(true);
ResourcesPlugin.getWorkspace().setDescription(wsd);
}
if (desc != null && hasNoInitialBuildCommands) {
desc.setBuildSpec(new ICommand[0]);
openProj.setDescription(desc, null);
}
} catch (CoreException e) {
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
}
}

/*
* Return a provider, given the selected navigator items
*/
private ResourceMgmtActionProvider provider(IResource... selectedElements) {
ICommonActionExtensionSite cfg = new CommonActionExtensionSite("NA", "NA",
CommonViewerSiteFactory.createCommonViewerSite(_commonNavigator.getViewSite()),
(NavigatorContentService) _contentService, _viewer);
ResourceMgmtActionProvider provider = new ResourceMgmtActionProvider();
StructuredSelection selection = null;
if (selectedElements != null && selectedElements.length > 0) {
selection = new StructuredSelection(selectedElements);
} else {
selection = new StructuredSelection();
}
provider.setContext(new ActionContext(selection));
provider.init(cfg);
return provider;
}

/*
* Check the expected menu items (passed in) against what the menu actually has
*/
private void checkMenuHasCorrectContributions(boolean... actions) {
if (actions.length != 5) { // there's 5 menus we check for
fail(String.format("Incorrect number of menu items being checked : %d", actions.length));
}
int index = 0;
for (String thisAction : new String[] { "org.eclipse.ui.BuildAction", "org.eclipse.ui.RefreshAction",
"org.eclipse.ui.OpenResourceAction", "org.eclipse.ui.CloseResourceAction",
"org.eclipse.ui.CloseUnrelatedProjectsAction" }) {
assertTrue(String.format("Unexpected menu membership for %s (%b)", thisAction, !actions[index]),
actions[index] == menuHasContribution(thisAction));
index++;
}
}

/*
* Check the menu for the named entry
*/
private boolean menuHasContribution(String contribution) {
for (IContributionItem thisItem : manager.getItems()) {
if (thisItem.getId().equals(contribution)) {
return true;
}
}
return false;
}

}
Loading