IDEA-108938 External system: Provide ability to detach linked external project

Offer to remove corresponding orphan ide module which correspond to external project being un-linked
This commit is contained in:
Denis.Zhdanov
2013-06-14 13:20:00 +04:00
parent 0fc5653156
commit 7b9eca0450
3 changed files with 64 additions and 14 deletions
@@ -1,6 +1,6 @@
# Import.
import.title=Import {0} Projects
orphan.modules.text=<html>The modules below have been removed from {0} structure.<br/>Check those to be removed from the project too:
orphan.modules.text=<html>The modules below are not backed by {0} anymore.<br/>Check those to be removed from the ide project too:
# Settings.
setting.type.location.deduced={0} location is deduced
@@ -19,25 +19,28 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentTasksList;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.externalSystem.util.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import java.util.List;
/**
* @author Denis Zhdanov
@@ -62,7 +65,9 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
MyInfo info = getProcessingInfo(e.getDataContext());
if (info.settings == null || info.localSettings == null || info.externalProject == null) {
if (info.settings == null || info.localSettings == null || info.externalProject == null || info.ideProject == null
|| info.externalSystemId == null)
{
return;
}
@@ -78,6 +83,25 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware {
info.localSettings.forgetExternalProject(Collections.singleton(info.externalProject.getPath()));
info.settings.unlinkExternalProject(info.externalProject.getPath());
// Process orphan modules.
PlatformFacade platformFacade = ServiceManager.getService(PlatformFacade.class);
String externalSystemIdAsString = info.externalSystemId.toString();
List<Module> orphanModules = ContainerUtilRt.newArrayList();
for (Module module : platformFacade.getModules(info.ideProject)) {
String systemId = module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY);
if (!externalSystemIdAsString.equals(systemId)) {
continue;
}
String path = module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY);
if (info.externalProject.getPath().equals(path)) {
orphanModules.add(module);
}
}
if (!orphanModules.isEmpty()) {
ExternalSystemUtil.ruleOrphanModules(orphanModules, info.ideProject, info.externalSystemId);
}
}
@NotNull
@@ -106,26 +130,34 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware {
return new MyInfo(externalProjectSettings == null ? null : settings,
localSettings == null ? null : localSettings,
externalProjectSettings == null ? null : externalProject,
ideProject,
externalSystemId,
icon);
}
private static class MyInfo {
public static final MyInfo EMPTY = new MyInfo(null, null, null, null);
public static final MyInfo EMPTY = new MyInfo(null, null, null, null, null, null);
@Nullable public final AbstractExternalSystemSettings<?, ?> settings;
@Nullable public final AbstractExternalSystemLocalSettings localSettings;
@Nullable public final ExternalProjectPojo externalProject;
@Nullable public final Project ideProject;
@Nullable public final ProjectSystemId externalSystemId;
@Nullable public final Icon icon;
MyInfo(@Nullable AbstractExternalSystemSettings<?, ?> settings,
@Nullable AbstractExternalSystemLocalSettings localSettings,
@Nullable ExternalProjectPojo externalProject,
@Nullable Project ideProject,
@Nullable ProjectSystemId externalSystemId,
@Nullable Icon icon)
{
this.settings = settings;
this.localSettings = localSettings;
this.externalProject = externalProject;
this.ideProject = ideProject;
this.externalSystemId = externalSystemId;
this.icon = icon;
}
}
@@ -55,6 +55,7 @@ import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.impl.ToolWindowImpl;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
@@ -221,18 +222,33 @@ public class ExternalSystemUtil {
}
}
private static void ruleOrphanModules(@NotNull final List<Module> orphanModules,
@NotNull final Project project,
@NotNull final ProjectSystemId externalSystemId)
/**
* There is a possible case that an external module has been un-linked from ide project. There are two ways to process
* ide modules which correspond to that external project:
* <pre>
* <ol>
* <li>Remove them from ide project as well;</li>
* <li>Keep them at ide project as well;</li>
* </ol>
* </pre>
* This method handles that situation, i.e. it asks a user what should be done and acts accordingly.
*
* @param orphanModules modules which correspond to the un-linked external project
* @param project current ide project
* @param externalSystemId id of the external system which project has been un-linked from ide project
*/
public static void ruleOrphanModules(@NotNull final List<Module> orphanModules,
@NotNull final Project project,
@NotNull final ProjectSystemId externalSystemId)
{
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final JPanel content = new JPanel(new GridBagLayout());
content.add(new JLabel(ExternalSystemBundle.message("orphan.modules.text", externalSystemId.getReadableName())),
ExternalSystemUiUtil.getFillLineConstraints(0));
final CheckBoxList<Module> orphanModulesList = new CheckBoxList<Module>();
orphanModulesList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
orphanModulesList.setItems(orphanModules, new Function<Module, String>() {
@@ -244,15 +260,17 @@ public class ExternalSystemUtil {
for (Module module : orphanModules) {
orphanModulesList.setItemSelected(module, true);
}
orphanModulesList.setBorder(IdeBorderFactory.createEmptyBorder(8));
content.add(orphanModulesList, ExternalSystemUiUtil.getFillLineConstraints(0));
content.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 8, 0));
DialogWrapper dialog = new DialogWrapper(project) {
{
setTitle(ExternalSystemBundle.message("import.title", externalSystemId.getReadableName()));
init();
}
@Nullable
@Override
protected JComponent createCenterPanel() {
@@ -263,7 +281,7 @@ public class ExternalSystemUtil {
if (!ok) {
return;
}
List<Module> toRemove = ContainerUtilRt.newArrayList();
for (int i = 0; i < orphanModules.size(); i++) {
Module module = orphanModules.get(i);