diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/util/nodeselection/NodeSelection.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/util/nodeselection/NodeSelection.java index f656f29fa..872084991 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/util/nodeselection/NodeSelection.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/util/nodeselection/NodeSelection.java @@ -177,6 +177,10 @@ public static NodeSelection empty() { return EMPTY; } + public static NodeSelection single(Object object) { + return new NodeSelection(ImmutableList.of(object)); + } + /** * Creates a new instance reflecting the given {@link IStructuredSelection} instance. * diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/CreateRunConfigurationAction.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/CreateRunConfigurationAction.java index e430a6fca..b726370a9 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/CreateRunConfigurationAction.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/CreateRunConfigurationAction.java @@ -40,7 +40,7 @@ public boolean isVisibleFor(NodeSelection selection) { @Override public boolean isEnabledFor(NodeSelection selection) { - return (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection) || + return (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean() || TaskViewActionStateRules.projectScopedTaskExecutionActionsEnabledFor(selection)) && isValidSelection(selection); } diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/OpenRunConfigurationAction.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/OpenRunConfigurationAction.java index 86b351578..20f242d7d 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/OpenRunConfigurationAction.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/OpenRunConfigurationAction.java @@ -40,7 +40,7 @@ public boolean isVisibleFor(NodeSelection selection) { @Override public boolean isEnabledFor(NodeSelection selection) { - return (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection) || + return (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean() || TaskViewActionStateRules.projectScopedTaskExecutionActionsEnabledFor(selection)) && isValidSelection(selection); } diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/RunTasksAction.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/RunTasksAction.java index fe8116e5c..b688452be 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/RunTasksAction.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/RunTasksAction.java @@ -16,6 +16,7 @@ import org.eclipse.buildship.ui.util.nodeselection.NodeSelection; import org.eclipse.buildship.ui.util.nodeselection.SelectionSpecificAction; import org.eclipse.buildship.ui.view.CommandBackedAction; +import org.eclipse.buildship.ui.view.task.TaskViewActionStateRules.TaskScopedActionEnablement; /** * Runs the selected Gradle tasks. @@ -38,20 +39,30 @@ public boolean isVisibleFor(NodeSelection selection) { @Override public boolean isEnabledFor(NodeSelection selection) { - return TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection); + return TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean(); } @Override public void setEnabledFor(NodeSelection selection) { - boolean isEnabled = isEnabledFor(selection); + TaskScopedActionEnablement enablement = TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection); + + boolean isEnabled = enablement.asBoolean(); setEnabled(isEnabled); - if (isEnabled) { - setText(TaskViewMessages.Action_RunTasks_Text); - setImageDescriptor(PluginImages.RUN_TASKS.withState(PluginImage.ImageState.ENABLED).getImageDescriptor()); - } else { - setText(TaskViewMessages.Action_RunTasks_Text_Disabled); - setImageDescriptor(PluginImages.RUN_TASKS.withState(PluginImage.ImageState.DISABLED).getImageDescriptor()); + setImageDescriptor(PluginImages.RUN_TASKS.withState(isEnabled ? PluginImages.ImageState.ENABLED : PluginImage.ImageState.DISABLED).getImageDescriptor()); + + switch (enablement) { + case ENABLED: + setText(TaskViewMessages.Action_RunTasks_Text); + break; + case DISABLED_INCLUDED_BUILD: + setText(TaskViewMessages.Action_RunTasks_Text_Disabled_Included); + break; + case DISABLED_NO_ROOT_PROJECT: + setText(TaskViewMessages.Action_RunTasks_Text_Disabled_NonStandard_layout); + break; + default: + setText(TaskViewMessages.Action_RunTasks_Text_Disabled_Other); + break; } } - } diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNameLabelProvider.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNameLabelProvider.java index 0c8f0e669..0d15002b7 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNameLabelProvider.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNameLabelProvider.java @@ -26,6 +26,7 @@ import org.eclipse.buildship.ui.PluginImage; import org.eclipse.buildship.ui.PluginImage.ImageState; import org.eclipse.buildship.ui.PluginImages; +import org.eclipse.buildship.ui.util.nodeselection.NodeSelection; /** * Styled label provider for the task name column in the TaskView. @@ -138,6 +139,6 @@ private Image getTaskSelectorImage(TaskSelectorNode taskSelector) { } private ImageState getImageState(TaskNode taskNode) { - return taskNode.getParentProjectNode().isIncludedProject() ? ImageState.DISABLED : ImageState.ENABLED; + return TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(NodeSelection.single(taskNode)).asBoolean() ? ImageState.ENABLED: ImageState.DISABLED; } } diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNodeSelectionUtils.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNodeSelectionUtils.java index dc1a0c347..e5b901c11 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNodeSelectionUtils.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskNodeSelectionUtils.java @@ -43,7 +43,7 @@ private TaskNodeSelectionUtils() { * @return {@code true} if the the selection can be mapped to a run configuration */ public static boolean isValidRunConfiguration(NodeSelection selection) { - return TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection) || + return TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean() || TaskViewActionStateRules.projectScopedTaskExecutionActionsEnabledFor(selection); } @@ -72,7 +72,7 @@ public static GradleRunConfigurationAttributes getRunConfigurationAttributes(Nod Preconditions.checkNotNull(selection); List tasks = getTaskPathStrings(selection); - if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection)) { + if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean()) { TaskNode taskNode = selection.getFirstElement(TaskNode.class); return getRunConfigurationAttributes(taskNode.getParentProjectNode(), tasks); } else if (TaskViewActionStateRules.projectScopedTaskExecutionActionsEnabledFor(selection)) { @@ -117,7 +117,7 @@ private static String gradleUserHomeExpression(File gradleUserHome) { } private static ImmutableList getTaskPathStrings(NodeSelection selection) { - if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection)) { + if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean()) { // running the set of project tasks and task selectors ImmutableList.Builder taskStrings = ImmutableList.builder(); for (TaskNode node : selection.toList(TaskNode.class)) { diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewActionStateRules.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewActionStateRules.java index b6f71fd24..ab10cf6b6 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewActionStateRules.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewActionStateRules.java @@ -55,35 +55,40 @@ public static boolean taskScopedTaskExecutionActionsVisibleFor(NodeSelection nod * Determines whether the actions related to task execution should be enabled or disabled. * * @param nodeSelection the node selection based on which to make the decision - * @return {@code true} if actions related to task execution should be enabled + * @return a classification whether and why the action should be disabled or enabled */ - public static boolean taskScopedTaskExecutionActionsEnabledFor(NodeSelection nodeSelection) { + public static TaskScopedActionEnablement taskScopedTaskExecutionActionsEnablement(NodeSelection nodeSelection) { // short-circuit in case the selection is empty if (nodeSelection.isEmpty()) { - return false; + return TaskScopedActionEnablement.DISABLED_DEFAULT; } // execution is enabled only if no tasks from included builds are selected and each task is from the same project List elements = nodeSelection.toList(); List taskNodes = FluentIterable.from(elements).filter(TaskNode.class).toList(); - if (elements.size() != taskNodes.size() || hasMultipleOrIncludedParentProject(taskNodes)) { - return false; + if (elements.size() != taskNodes.size()) { + return TaskScopedActionEnablement.DISABLED_DEFAULT; + } + + if (hasMultipleOrIncludedParentProject(taskNodes)) { + return TaskScopedActionEnablement.DISABLED_INCLUDED_BUILD; } // if project tasks are selected only then the execution should be permitted List projectNodes = FluentIterable.from(elements).filter(ProjectTaskNode.class).toList(); if (projectNodes.size() == taskNodes.size()) { - return true; + return TaskScopedActionEnablement.ENABLED; } // if task selectors are selected only then the execution should be permitted if the root project can be found List taskSelectorNodes = FluentIterable.from(elements).filter(TaskSelectorNode.class).toList(); if (taskSelectorNodes.size() == taskNodes.size()) { - return canFindRootProjects(taskSelectorNodes); + boolean hasRootProjects = canFindRootProjects(taskSelectorNodes); + return hasRootProjects ? TaskScopedActionEnablement.ENABLED : TaskScopedActionEnablement.DISABLED_NO_ROOT_PROJECT; } // as a default disable the execution - return false; + return TaskScopedActionEnablement.DISABLED_DEFAULT; } private static boolean hasMultipleOrIncludedParentProject(List nodes) { @@ -148,4 +153,14 @@ public static boolean projectScopedTaskExecutionActionsEnabledFor(NodeSelection return nodeSelection.hasAllNodesOfType(ProjectNode.class) && nodeSelection.isSingleSelection() && !nodeSelection.getFirstElement(ProjectNode.class).isIncludedProject(); } + /** + * Possible statuses that {@link #taskScopedTaskExecutionActionsEnablement(NodeSelection)} can return. + */ + public enum TaskScopedActionEnablement { + ENABLED, DISABLED_DEFAULT, DISABLED_INCLUDED_BUILD, DISABLED_NO_ROOT_PROJECT; + + public boolean asBoolean() { + return this == ENABLED; + } + } } diff --git a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewMessages.java b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewMessages.java index e36ba9f44..402467c10 100644 --- a/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewMessages.java +++ b/org.eclipse.buildship.ui/src/main/java/org/eclipse/buildship/ui/view/task/TaskViewMessages.java @@ -29,7 +29,9 @@ public final class TaskViewMessages extends NLS { // context menu entries public static String Action_RunTasks_Text; - public static String Action_RunTasks_Text_Disabled; + public static String Action_RunTasks_Text_Disabled_Included; + public static String Action_RunTasks_Text_Disabled_NonStandard_layout; + public static String Action_RunTasks_Text_Disabled_Other; public static String Action_RunDefaultTasks_Text; public static String Action_CreateRunConfiguration_Text; public static String Action_OpenRunConfiguration_Text; diff --git a/org.eclipse.buildship.ui/src/main/resources/org/eclipse/buildship/ui/view/task/TaskViewMessages.properties b/org.eclipse.buildship.ui/src/main/resources/org/eclipse/buildship/ui/view/task/TaskViewMessages.properties index 42e24c97f..002544513 100644 --- a/org.eclipse.buildship.ui/src/main/resources/org/eclipse/buildship/ui/view/task/TaskViewMessages.properties +++ b/org.eclipse.buildship.ui/src/main/resources/org/eclipse/buildship/ui/view/task/TaskViewMessages.properties @@ -16,7 +16,9 @@ Tree_Column_Name_Text=Name Tree_Column_Description_Text=Description Action_RunTasks_Text=Run Gradle Tasks -Action_RunTasks_Text_Disabled=Cannot run tasks for included builds +Action_RunTasks_Text_Disabled_Included=Cannot run tasks for included builds +Action_RunTasks_Text_Disabled_NonStandard_layout=Cannot run task selectors in non-standard project layouts +Action_RunTasks_Text_Disabled_Other=Cannot run tasks Action_RunDefaultTasks_Text=Run Default Gradle Tasks Action_CreateRunConfiguration_Text=Create Gradle Run Configuration... Action_OpenRunConfiguration_Text=Open Gradle Run Configuration...