Skip to content

Commit b019337

Browse files
DaveCarpenetomerks
authored andcommitted
Refresh option not available for some resources that are not closed projects #2538
Change made since the fix to #1438 unintentionally removed the "refresh" contextual menu for resources that are not projects. With this change the "refresh" contextual menu is shown if ANY navigator selection is either (A) an open project, or (B) a non-project resource. Put another way: the 'refresh' item is NOT shown if ALL selections are closed projects. Fixes #2538
1 parent 0060e04 commit b019337

File tree

4 files changed

+246
-30
lines changed

4 files changed

+246
-30
lines changed

bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java

+22-28
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.lang.reflect.InvocationTargetException;
1919
import java.util.ArrayList;
2020
import java.util.Collections;
21-
import java.util.Iterator;
2221
import java.util.List;
2322

2423
import org.eclipse.core.resources.ICommand;
@@ -114,20 +113,16 @@ public void fillActionBars(IActionBars actionBars) {
114113
@Override
115114
public void fillContextMenu(IMenuManager menu) {
116115
IStructuredSelection selection = (IStructuredSelection) getContext().getSelection();
117-
boolean isProjectSelection = true;
118116
boolean hasOpenProjects = false;
119117
boolean hasClosedProjects = false;
120-
boolean hasBuilder = true; // false if any project is closed or does not
121-
// have builder
118+
boolean hasBuilder = true; // false if any project is closed or does not have builder
119+
List<IProject> projects = selectionToProjects(selection);
120+
boolean selectionContainsNonProject = projects.size() < selection.size();
122121

123-
Iterator<IProject> projects = selectionToProjects(selection).iterator();
124-
125-
while (projects.hasNext() && (!hasOpenProjects || !hasClosedProjects || hasBuilder || isProjectSelection)) {
126-
IProject project = projects.next();
127-
128-
if (project == null) {
129-
isProjectSelection = false;
130-
continue;
122+
for (IProject project : projects) {
123+
if (hasOpenProjects && hasClosedProjects && !hasBuilder) {
124+
// we've set all booleans of interest; no need to loop any further
125+
break;
131126
}
132127
if (project.isOpen()) {
133128
hasOpenProjects = true;
@@ -139,30 +134,29 @@ public void fillContextMenu(IMenuManager menu) {
139134
hasBuilder = false;
140135
}
141136
}
142-
if (!selection.isEmpty() && isProjectSelection && !ResourcesPlugin.getWorkspace().isAutoBuilding()
137+
if (!selection.isEmpty() && !ResourcesPlugin.getWorkspace().isAutoBuilding()
143138
&& hasBuilder) {
144139
// Allow manual incremental build only if auto build is off.
145140
buildAction.selectionChanged(selection);
146141
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, buildAction);
147142
}
148-
// Add the 'refresh' item if any selection is either (a) an open project, or (b)
149-
// a non-project selection (so the 'refresh' item is not shown if all selections
150-
// are closed projects)
151-
if (hasOpenProjects || !isProjectSelection) {
143+
// Add the 'refresh' item if ANY selection is either (a) an open project, or (b)
144+
// a non-project selection.
145+
// Put another way: the 'refresh' item is NOT shown if ALL selections are closed
146+
// projects.
147+
if (hasOpenProjects || selectionContainsNonProject) {
152148
refreshAction.selectionChanged(selection);
153149
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, refreshAction);
154150
}
155-
if (isProjectSelection) {
156-
if (hasClosedProjects) {
157-
openProjectAction.selectionChanged(selection);
158-
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, openProjectAction);
159-
}
160-
if (hasOpenProjects) {
161-
closeProjectAction.selectionChanged(selection);
162-
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeProjectAction);
163-
closeUnrelatedProjectsAction.selectionChanged(selection);
164-
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeUnrelatedProjectsAction);
165-
}
151+
if (hasClosedProjects) {
152+
openProjectAction.selectionChanged(selection);
153+
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, openProjectAction);
154+
}
155+
if (hasOpenProjects) {
156+
closeProjectAction.selectionChanged(selection);
157+
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeProjectAction);
158+
closeUnrelatedProjectsAction.selectionChanged(selection);
159+
menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, closeUnrelatedProjectsAction);
166160
}
167161
}
168162

tests/org.eclipse.ui.tests.navigator/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %bundlename
44
Bundle-SymbolicName: org.eclipse.ui.tests.navigator;singleton:=true
5-
Bundle-Version: 3.7.600.qualifier
5+
Bundle-Version: 3.7.700.qualifier
66
Bundle-Localization: plugin
77
Require-Bundle: org.eclipse.core.resources,
88
org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)",

tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestSuite.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.eclipse.ui.tests.navigator.resources.FoldersAsProjectsContributionTest;
2525
import org.eclipse.ui.tests.navigator.resources.NestedResourcesTests;
2626
import org.eclipse.ui.tests.navigator.resources.PathComparatorTest;
27+
import org.eclipse.ui.tests.navigator.resources.ResourceMgmtActionProviderTests;
2728
import org.junit.runner.RunWith;
2829
import org.junit.runners.Suite;
2930
import org.junit.runners.Suite.SuiteClasses;
@@ -34,7 +35,7 @@
3435
ProgrammaticOpenTest.class, PipelineTest.class, PipelineChainTest.class, JstPipelineTest.class,
3536
LabelProviderTest.class, SorterTest.class, ViewerTest.class, CdtTest.class, M12Tests.class,
3637
FirstClassM1Tests.class, LinkHelperTest.class, ShowInTest.class, ResourceTransferTest.class,
37-
EvaluationCacheTest.class,
38+
EvaluationCacheTest.class, ResourceMgmtActionProviderTests.class,
3839
NestedResourcesTests.class, PathComparatorTest.class, FoldersAsProjectsContributionTest.class,
3940
GoBackForwardsTest.class
4041
// DnDTest.class, // DnDTest.testSetDragOperation() fails
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Dave Carpeneto and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.ui.tests.navigator.resources;
12+
13+
import static org.junit.Assert.assertTrue;
14+
import static org.junit.Assert.fail;
15+
16+
import org.eclipse.core.resources.ICommand;
17+
import org.eclipse.core.resources.IFolder;
18+
import org.eclipse.core.resources.IProject;
19+
import org.eclipse.core.resources.IProjectDescription;
20+
import org.eclipse.core.resources.IResource;
21+
import org.eclipse.core.resources.IWorkspaceDescription;
22+
import org.eclipse.core.resources.ResourcesPlugin;
23+
import org.eclipse.core.runtime.CoreException;
24+
import org.eclipse.core.runtime.Path;
25+
import org.eclipse.jface.action.GroupMarker;
26+
import org.eclipse.jface.action.IContributionItem;
27+
import org.eclipse.jface.action.IMenuManager;
28+
import org.eclipse.jface.action.MenuManager;
29+
import org.eclipse.jface.viewers.StructuredSelection;
30+
import org.eclipse.ui.actions.ActionContext;
31+
import org.eclipse.ui.internal.navigator.NavigatorContentService;
32+
import org.eclipse.ui.internal.navigator.extensions.CommonActionExtensionSite;
33+
import org.eclipse.ui.internal.navigator.resources.actions.ResourceMgmtActionProvider;
34+
import org.eclipse.ui.navigator.CommonViewerSiteFactory;
35+
import org.eclipse.ui.navigator.ICommonActionExtensionSite;
36+
import org.eclipse.ui.navigator.ICommonMenuConstants;
37+
import org.eclipse.ui.tests.navigator.NavigatorTestBase;
38+
import org.junit.Before;
39+
import org.junit.Test;
40+
41+
public final class ResourceMgmtActionProviderTests extends NavigatorTestBase {
42+
43+
private IMenuManager manager;
44+
45+
public ResourceMgmtActionProviderTests() {
46+
_navigatorInstanceId = TEST_VIEWER;
47+
}
48+
49+
@Override
50+
@Before
51+
public void setUp() {
52+
super.setUp();
53+
manager = new MenuManager();
54+
manager.add(new GroupMarker(ICommonMenuConstants.GROUP_BUILD));
55+
}
56+
57+
/**
58+
* Test for 'no selection' condition - no menu items should be included
59+
*/
60+
@Test
61+
public void testFillContextMenu_noSelection() {
62+
ResourceMgmtActionProvider provider = provider((IResource[]) null);
63+
provider.fillContextMenu(manager);
64+
checkMenuHasCorrectContributions(false, false, false, false, false);
65+
}
66+
67+
/**
68+
* Test for 'folder' condition - only 'refresh' should be included
69+
*/
70+
@Test
71+
public void testFillContextMenu_folderSelection() {
72+
73+
IFolder justAFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path("some/folder"));
74+
ResourceMgmtActionProvider provider = provider(justAFolder);
75+
provider.fillContextMenu(manager);
76+
checkMenuHasCorrectContributions(false, true, false, false, false);
77+
}
78+
79+
/**
80+
* Test for 'closed project' - only 'open project' should be included
81+
*/
82+
@Test
83+
public void testFillContextMenu_closedProjectSelection() {
84+
IProject closedProj = ResourcesPlugin.getWorkspace().getRoot().getProject("closedProj");
85+
ResourceMgmtActionProvider provider = provider(closedProj);
86+
provider.fillContextMenu(manager);
87+
checkMenuHasCorrectContributions(false, false, true, false, false);
88+
}
89+
90+
/**
91+
* Test for 'open project' that doesn't have a builder attached - all but
92+
* 'build' &amp; 'open project' should be enabled
93+
*/
94+
@Test
95+
public void testFillContextMenu_openProjectNoBuilderSelection() {
96+
IProject openProj = ResourcesPlugin.getWorkspace().getRoot().getProject("Test");
97+
boolean autoBuildInitialState = ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding();
98+
99+
try {
100+
if (!autoBuildInitialState) {
101+
// we want to enable auto-building for this test to guarantee that the 'build'
102+
// menu option isn't shown
103+
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
104+
wsd.setAutoBuilding(true);
105+
ResourcesPlugin.getWorkspace().setDescription(wsd);
106+
}
107+
openProj.open(null);
108+
} catch (CoreException e) {
109+
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
110+
}
111+
ResourceMgmtActionProvider provider = provider(openProj);
112+
provider.fillContextMenu(manager);
113+
checkMenuHasCorrectContributions(false, true, false, true, true);
114+
115+
if (!autoBuildInitialState) {
116+
// clean-up: reset autobuild since we changed it
117+
try {
118+
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
119+
wsd.setAutoBuilding(false);
120+
ResourcesPlugin.getWorkspace().setDescription(wsd);
121+
} catch (CoreException e) {
122+
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
123+
}
124+
}
125+
}
126+
127+
/**
128+
* Test for 'open project' that doesn't have a builder attached - only 'open
129+
* project' should be disabled
130+
*/
131+
@Test
132+
public void testFillContextMenu_openProjectWithBuilderSelection() {
133+
IProject openProj = ResourcesPlugin.getWorkspace().getRoot().getProject("Test");
134+
IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription();
135+
boolean autobuildInitialState = wsd.isAutoBuilding();
136+
boolean hasNoInitialBuildCommands = false;
137+
IProjectDescription desc = null;
138+
try {
139+
if (autobuildInitialState) {
140+
wsd.setAutoBuilding(false);
141+
ResourcesPlugin.getWorkspace().setDescription(wsd);
142+
}
143+
openProj.open(null);
144+
desc = openProj.getDescription();
145+
if (desc.getBuildSpec().length == 0) {
146+
hasNoInitialBuildCommands = true;
147+
ICommand cmd = desc.newCommand();
148+
desc.setBuildSpec(new ICommand[] { cmd });
149+
openProj.setDescription(desc, null);
150+
}
151+
} catch (CoreException e) {
152+
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
153+
}
154+
ResourceMgmtActionProvider provider = provider(openProj);
155+
provider.fillContextMenu(manager);
156+
checkMenuHasCorrectContributions(true, true, false, true, true);
157+
try {
158+
// clean-up where needed: reset autobuild if we changed it & remove
159+
// the build config if we added it
160+
if (autobuildInitialState) {
161+
wsd.setAutoBuilding(true);
162+
ResourcesPlugin.getWorkspace().setDescription(wsd);
163+
}
164+
if (desc != null && hasNoInitialBuildCommands) {
165+
desc.setBuildSpec(new ICommand[0]);
166+
openProj.setDescription(desc, null);
167+
}
168+
} catch (CoreException e) {
169+
fail(e.getClass().getSimpleName() + " thrown: " + e.getLocalizedMessage());
170+
}
171+
}
172+
173+
/*
174+
* Return a provider, given the selected navigator items
175+
*/
176+
private ResourceMgmtActionProvider provider(IResource... selectedElements) {
177+
ICommonActionExtensionSite cfg = new CommonActionExtensionSite("NA", "NA",
178+
CommonViewerSiteFactory.createCommonViewerSite(_commonNavigator.getViewSite()),
179+
(NavigatorContentService) _contentService, _viewer);
180+
ResourceMgmtActionProvider provider = new ResourceMgmtActionProvider();
181+
StructuredSelection selection = null;
182+
if (selectedElements != null && selectedElements.length > 0) {
183+
selection = new StructuredSelection(selectedElements);
184+
} else {
185+
selection = new StructuredSelection();
186+
}
187+
provider.setContext(new ActionContext(selection));
188+
provider.init(cfg);
189+
return provider;
190+
}
191+
192+
/*
193+
* Check the expected menu items (passed in) against what the menu actually has
194+
*/
195+
private void checkMenuHasCorrectContributions(boolean... actions) {
196+
if (actions.length != 5) { // there's 5 menus we check for
197+
fail(String.format("Incorrect number of menu items being checked : %d", actions.length));
198+
}
199+
int index = 0;
200+
for (String thisAction : new String[] { "org.eclipse.ui.BuildAction", "org.eclipse.ui.RefreshAction",
201+
"org.eclipse.ui.OpenResourceAction", "org.eclipse.ui.CloseResourceAction",
202+
"org.eclipse.ui.CloseUnrelatedProjectsAction" }) {
203+
assertTrue(String.format("Unexpected menu membership for %s (%b)", thisAction, !actions[index]),
204+
actions[index] == menuHasContribution(thisAction));
205+
index++;
206+
}
207+
}
208+
209+
/*
210+
* Check the menu for the named entry
211+
*/
212+
private boolean menuHasContribution(String contribution) {
213+
for (IContributionItem thisItem : manager.getItems()) {
214+
if (thisItem.getId().equals(contribution)) {
215+
return true;
216+
}
217+
}
218+
return false;
219+
}
220+
221+
}

0 commit comments

Comments
 (0)