--- a/projectapi/src/org/netbeans/spi/project/ActionProvider.java
+++ a/projectapi/src/org/netbeans/spi/project/ActionProvider.java
@@ -46,6 +46,12 @@
/**
* Ability for a project to have various actions (e.g. Build) invoked on it.
* Should be registered in a project's lookup and will be used by UI infrastructure.
+ *
+ * Implementations supporting single file commands (command constants ending with
+ * {@code _SINGLE}) can also be registered in default lookup. If a provider in project
+ * lookup does not enable the action for a given command on the selected file then
+ * the first implementation found in default lookup that is enabled will be used.
+ *
* @see org.netbeans.api.project.Project#getLookup
* @see ActionUtils
* @see ProjectSensitiveActions.projectCommandAction(...)
--- a/projectui/src/org/netbeans/modules/project/ui/actions/FileCommandAction.java
+++ a/projectui/src/org/netbeans/modules/project/ui/actions/FileCommandAction.java
@@ -41,9 +41,11 @@
package org.netbeans.modules.project.ui.actions;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import javax.swing.Action;
import javax.swing.Icon;
-import javax.swing.ImageIcon;
import org.netbeans.api.project.Project;
import org.netbeans.spi.project.ActionProvider;
import org.openide.awt.Actions;
@@ -56,6 +58,7 @@
public final class FileCommandAction extends ProjectAction {
private String presenterName;
+ private Collection providers = new ArrayList();
public FileCommandAction( String command, String namePattern, String iconResource, Lookup lookup ) {
this( command, namePattern, ImageUtilities.loadImageIcon(iconResource, false), lookup );
@@ -67,6 +70,13 @@
presenterName = ActionsUtil.formatName( getNamePattern(), 0, "" );
setDisplayName( presenterName );
putValue(SHORT_DESCRIPTION, Actions.cutAmpersand(presenterName));
+
+ Collection extends ActionProvider> registeredProviders = Lookup.getDefault().lookupAll(ActionProvider.class);
+ for (ActionProvider p : registeredProviders) {
+ if (Arrays.asList(p.getSupportedActions()).contains(getCommand())) {
+ providers.add(p);
+ }
+ }
}
@Override
@@ -74,8 +84,19 @@
Project[] projects = ActionsUtil.getProjectsFromLookup( context, getCommand() );
if ( projects.length != 1 ) {
- setEnabled( false ); // Zero or more than one projects found or command not supported
- presenterName = ActionsUtil.formatName( getNamePattern(), 0, "" );
+ boolean supportedByProvider = false;
+ for (ActionProvider provider : providers) {
+ if (provider.isActionEnabled(getCommand(), context)) {
+ setEnabled(true);
+ presenterName = ActionsUtil.formatName(getNamePattern(), 0, "");
+ supportedByProvider = true;
+ break;
+ }
+ }
+ if (!supportedByProvider) {
+ setEnabled(false); // Zero or more than one projects found or command not supported
+ presenterName = ActionsUtil.formatName(getNamePattern(), 0, "");
+ }
}
else {
FileObject[] files = ActionsUtil.getFilesFromLookup( context, projects[0] );
@@ -94,8 +115,15 @@
if ( projects.length == 1 ) {
ActionProvider ap = (ActionProvider)projects[0].getLookup().lookup( ActionProvider.class );
ap.invokeAction( getCommand(), context );
+ return;
}
+ for (ActionProvider provider : providers) {
+ if (provider.isActionEnabled(getCommand(), context)) {
+ provider.invokeAction(getCommand(), context);
+ return;
+ }
+ }
}