Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix visual enablement and context menu messages for disabled tasks #539

Merged
merged 2 commits into from
Aug 3, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -72,7 +72,7 @@ public static GradleRunConfigurationAttributes getRunConfigurationAttributes(Nod
Preconditions.checkNotNull(selection);
List<String> 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)) {
Expand Down Expand Up @@ -117,7 +117,7 @@ private static String gradleUserHomeExpression(File gradleUserHome) {
}

private static ImmutableList<String> getTaskPathStrings(NodeSelection selection) {
if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnabledFor(selection)) {
if (TaskViewActionStateRules.taskScopedTaskExecutionActionsEnablement(selection).asBoolean()) {
// running the set of project tasks and task selectors
ImmutableList.Builder<String> taskStrings = ImmutableList.builder();
for (TaskNode node : selection.toList(TaskNode.class)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TaskNode> 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<ProjectTaskNode> 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<TaskSelectorNode> 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<TaskNode> nodes) {
Expand Down Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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...
Expand Down