From 90f61a95464cf6ec3a99b37bc2c56d2e2bef6aa6 Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Mon, 1 Oct 2018 12:17:41 +0300 Subject: [PATCH] Ignore Multiple External Projects Ability to ignore multiple projects at once Related to IDEA-198453 --- .../i18n/ExternalSystemBundle.properties | 8 +- .../action/IgnoreExternalProjectAction.java | 89 ++++++++++++------- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index 9595b1e6a666..82e301d0d544 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -55,10 +55,10 @@ action.attach.external.project.text=Attach {0} project action.attach.external.project.description=Attach {0} project to the current ide project action.detach.external.project.text=Detach {0} project action.detach.external.project.description=Detach selected external project -action.ignore.external.project.text=Ignore {0} project -action.ignore.external.project.description=Ignore selected {0} project -action.unignore.external.project.text=Unignore {0} project -action.unignore.external.project.description=Unignore selected {0} project +action.ignore.external.projects.text=Ignore {0} {1} +action.ignore.external.projects.description=Ignore selected {0} {1} +action.unignore.external.projects.text=Unignore {0} {1} +action.unignore.external.projects.description=Unignore selected {0} {1} action.open.config.text=Open {0} config action.open.config.description=Allows to open project file of the linked {0} project at the editor diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/IgnoreExternalProjectAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/IgnoreExternalProjectAction.java index 0702103c2ca8..86531075c255 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/IgnoreExternalProjectAction.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/IgnoreExternalProjectAction.java @@ -30,11 +30,19 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.externalSystem.view.ExternalSystemNode; import com.intellij.openapi.externalSystem.view.ModuleNode; import com.intellij.openapi.externalSystem.view.ProjectNode; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; /** * @author Vladislav.Soroka @@ -45,32 +53,48 @@ public class IgnoreExternalProjectAction extends ExternalSystemToggleAction { private static final Logger LOG = Logger.getInstance(IgnoreExternalProjectAction.class); public IgnoreExternalProjectAction() { - getTemplatePresentation().setText(ExternalSystemBundle.message("action.ignore.external.project.text", "external")); - getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.ignore.external.project.description", "external")); + getTemplatePresentation().setText(ExternalSystemBundle.message("action.ignore.external.projects.text", "external", "project")); + getTemplatePresentation() + .setDescription(ExternalSystemBundle.message("action.ignore.external.projects.description", "external", "project")); } @Override public void setSelected(@NotNull AnActionEvent e, boolean state) { final ProjectSystemId projectSystemId = getSystemId(e); - final ExternalSystemNode projectNode = getProjectNode(e); - if (projectSystemId == null || projectNode == null || projectNode.getData() == null) return; - - projectNode.setIgnored(state); + final List> projectNodes = getProjectNodes(e); + if (projectNodes.isEmpty()) return; final Project project = getProject(e); - final String externalProjectPath = projectNode.getData().getLinkedExternalProjectPath(); - final ExternalProjectInfo externalProjectInfo = - ExternalSystemUtil.getExternalProjectInfo(project, projectSystemId, externalProjectPath); - if (externalProjectInfo == null || externalProjectInfo.getExternalProjectStructure() == null) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("external project data not found, path: %s, data: %s", externalProjectPath, externalProjectInfo)); - } - return; - } + projectNodes.forEach(projectNode -> projectNode.setIgnored(state)); - final DataNode projectDataNode = externalProjectInfo.getExternalProjectStructure(); - ServiceManager.getService(ProjectDataManager.class).importData(projectDataNode, project, true); + Set> uniqueExternalProjects = projectNodes.stream() + .map( + projectNode -> { + final String externalProjectPath = projectNode.getData().getLinkedExternalProjectPath(); + final ExternalProjectInfo externalProjectInfo = + ExternalSystemUtil.getExternalProjectInfo(project, projectSystemId, externalProjectPath); + final DataNode projectDataNode = + externalProjectInfo == null ? null : externalProjectInfo.getExternalProjectStructure(); + + if (projectDataNode == null && LOG.isDebugEnabled()) { + LOG.debug(String.format("external project data not found, path: %s, data: %s", externalProjectPath, externalProjectInfo)); + } + return projectDataNode; + } + ) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // async import to not block UI on big projects + ProgressManager.getInstance().run(new Task.Backgroundable(project, e.getPresentation().getText(), false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + uniqueExternalProjects.forEach( + externalProjectInfo -> ServiceManager.getService(ProjectDataManager.class).importData(externalProjectInfo, project, true) + ); + } + }); } @Override @@ -78,13 +102,14 @@ public class IgnoreExternalProjectAction extends ExternalSystemToggleAction { boolean selected = super.isSelected(e); ProjectSystemId systemId = getSystemId(e); final String systemIdName = systemId != null ? systemId.getReadableName() : "external"; + final String pluralizedProjects = StringUtil.pluralize("project", getProjectNodes(e).size()); if (selected) { - setText(e, ExternalSystemBundle.message("action.unignore.external.project.text", systemIdName)); - setDescription(e, ExternalSystemBundle.message("action.unignore.external.project.description", systemIdName)); + setText(e, ExternalSystemBundle.message("action.unignore.external.projects.text", systemIdName, pluralizedProjects)); + setDescription(e, ExternalSystemBundle.message("action.unignore.external.projects.description", systemIdName, pluralizedProjects)); } else { - setText(e, ExternalSystemBundle.message("action.ignore.external.project.text", systemIdName)); - setDescription(e, ExternalSystemBundle.message("action.ignore.external.project.description", systemIdName)); + setText(e, ExternalSystemBundle.message("action.ignore.external.projects.text", systemIdName, pluralizedProjects)); + setDescription(e, ExternalSystemBundle.message("action.ignore.external.projects.description", systemIdName, pluralizedProjects)); } return selected; } @@ -92,22 +117,22 @@ public class IgnoreExternalProjectAction extends ExternalSystemToggleAction { @Override protected boolean isEnabled(@NotNull AnActionEvent e) { if (!super.isEnabled(e)) return false; - return getProjectNode(e) != null; + return !getProjectNodes(e).isEmpty(); } @Override protected boolean doIsSelected(@NotNull AnActionEvent e) { - final ExternalSystemNode projectNode = getProjectNode(e); - if (projectNode == null) return false; - return projectNode.isIgnored(); + return ContainerUtil.exists(getProjectNodes(e), projectNode -> projectNode.isIgnored()); } - @Nullable - private static ExternalSystemNode getProjectNode(@NotNull AnActionEvent e) { + @NotNull + private static List> getProjectNodes(@NotNull AnActionEvent e) { final List selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext()); - if (selectedNodes == null || selectedNodes.size() != 1) return null; - final ExternalSystemNode node = selectedNodes.get(0); - //noinspection unchecked - return (node instanceof ModuleNode || node instanceof ProjectNode) ? (ExternalSystemNode)node : null; + if (selectedNodes == null || selectedNodes.isEmpty()) return Collections.emptyList(); + + return selectedNodes.stream() + .map(node -> (node instanceof ModuleNode || node instanceof ProjectNode) ? (ExternalSystemNode)node : null) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } }