IDEA-108938 External system: Provide ability to detach linked external project appcode/130.913 idea/130.914 phpstorm/130.909 pycharm/130.910 rubymine/130.912 webstorm/130.911
authorDenis.Zhdanov <Denis.Zhdanov@jetbrains.com>
Thu, 13 Jun 2013 19:35:21 +0000 (23:35 +0400)
committerDenis.Zhdanov <Denis.Zhdanov@jetbrains.com>
Thu, 13 Jun 2013 19:38:46 +0000 (23:38 +0400)
Corresponding action is added to the external system tool window. Recent tasks, regular tasks and (sub-)project nodes are removed as well

22 files changed:
java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
platform/external-system-api/resources/i18n/ExternalSystemBundle.properties
platform/external-system-api/src/com/intellij/openapi/externalSystem/model/Key.java
platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectKeys.java
platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java
platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemSettings.java
platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListener.java
platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java [new file with mode: 0644]
platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java [new file with mode: 0644]
platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemRecentTaskListModel.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemRecentTasksList.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
platform/platform-resources/src/idea/ExternalSystemActions.xml
plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettingsListenerAdapter.java
plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleLocalSettings.java

index 29f991c8871296b5446d3c5a038ec1df993a6276..9deea918441a9803cef619fbcc94ff8dfd008e78 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.externalSystem;
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -33,9 +34,9 @@ import java.util.regex.Pattern;
  * @since 4/12/13 12:27 PM
  */
 public class JavaProjectData extends AbstractExternalEntityData {
-  
-  @NotNull public static final Key<JavaProjectData> KEY = Key.create(JavaProjectData.class);
-  
+
+  @NotNull public static final Key<JavaProjectData> KEY = Key.create(JavaProjectData.class, ProjectKeys.PROJECT.getProcessingWeight() + 1);
+
   private static final Logger LOG = Logger.getInstance("#" + JavaProjectData.class.getName());
 
   private static final long serialVersionUID = 1L;
@@ -47,7 +48,7 @@ public class JavaProjectData extends AbstractExternalEntityData {
   @NotNull private JavaSdkVersion myJdkVersion    = DEFAULT_JDK_VERSION;
   @NotNull private LanguageLevel  myLanguageLevel = DEFAULT_LANGUAGE_LEVEL;
 
-  @NotNull private  String myCompileOutputPath;
+  @NotNull private String myCompileOutputPath;
 
   public JavaProjectData(@NotNull ProjectSystemId owner, @NotNull String compileOutputPath) {
     super(owner);
index b84076080db0fd9edc57800068657abaa0885326..58e2981cdff949ff050fb700aac8fe8ac1152996 100644 (file)
@@ -31,8 +31,8 @@ tool.window.title.tasks=tasks
 # Action.
 action.refresh.all.projects.text=Refresh all {0} projects
 action.refresh.all.projects.description=Force refresh all linked {0} projects
-action.task.run.text=Run
-action.task.run.description=Run selected task
+action.detach.external.project.text=Detach
+action.detach.external.project.description=Detach selected external project
 
 # Notification
 notification.project.refresh.fail.description={0} ''{1}'' project refresh failed:\n{2}
index dacc4654e092282dce9d5553fc93363c6943066a..3e25602cb54632f931998446c3db61e84cf9e4f4 100644 (file)
@@ -31,19 +31,45 @@ import java.io.Serializable;
  * @since 4/12/13 11:49 AM
  * @param <T>  data class
  */
-public class Key<T> implements Serializable {
+@SuppressWarnings("UnusedDeclaration")
+public class Key<T> implements Serializable, Comparable<Key<?>> {
 
   private static final long serialVersionUID = 1L;
   
   @NotNull private final String myDataClass;
+  
+  private final int myProcessingWeight;
 
-  public Key(@NotNull String dataClass) {
+  /**
+   * Creates new <code>Key</code> object.
+   * 
+   * @param dataClass         class of the payload data which will be associated with the current key
+   * @param processingWeight  there is a possible case that when a {@link DataNode} object has children of more than on type (children
+   *                          with more than one different {@link Key} we might want to process one type of children before another.
+   *                          That's why we need a way to define that processing order. This parameter serves exactly for that -
+   *                          lower value means that key's payload should be processed <b>before</b> payload of the key with a greater
+   *                          value
+   */
+  public Key(@NotNull String dataClass, int processingWeight) {
     myDataClass = dataClass;
+    myProcessingWeight = processingWeight;
   }
 
   @NotNull
-  public static <T> Key<T> create(@NotNull Class<T> dataClass) {
-    return new Key<T>(dataClass.getName());
+  public static <T> Key<T> create(@NotNull Class<T> dataClass, int processingWeight) {
+    return new Key<T>(dataClass.getName(), processingWeight);
+  }
+
+  /**
+   * There is a possible case that when a {@link DataNode} object has children of more than on type (children with more than
+   * one different {@link Key} we might want to process one type of children before another. That's why we need a way to define
+   * that processing order. This property serves exactly for that - lower value means that key's payload should be processed
+   * <b>before</b> payload of the key with a greater value.
+   * 
+   * @return    processing weight for data associated with the current key
+   */
+  public int getProcessingWeight() {
+    return myProcessingWeight;
   }
 
   @Override
@@ -64,6 +90,11 @@ public class Key<T> implements Serializable {
   }
 
   @Override
+  public int compareTo(@NotNull Key<?> that) {
+    return myProcessingWeight - that.myProcessingWeight;
+  }
+
+  @Override
   public String toString() {
     int i = myDataClass.lastIndexOf('.');
     return i > 0 ? myDataClass.substring(i + 1) : myDataClass;
index 77d9df8c9151c2f6aebde89d5291c9cdfec1a9eb..64c6e6dd652d75ed213c995a5483d3b1c42bdf31 100644 (file)
@@ -27,14 +27,14 @@ import org.jetbrains.annotations.NotNull;
  */
 public class ProjectKeys {
 
-  @NotNull public static final Key<ProjectData>           PROJECT            = Key.create(ProjectData.class);
-  @NotNull public static final Key<ModuleData>            MODULE             = Key.create(ModuleData.class);
-  @NotNull public static final Key<LibraryData>           LIBRARY            = Key.create(LibraryData.class);
-  @NotNull public static final Key<ContentRootData>       CONTENT_ROOT       = Key.create(ContentRootData.class);
-  @NotNull public static final Key<ModuleDependencyData>  MODULE_DEPENDENCY  = Key.create(ModuleDependencyData.class);
-  @NotNull public static final Key<LibraryDependencyData> LIBRARY_DEPENDENCY = Key.create(LibraryDependencyData.class);
+  @NotNull public static final Key<ProjectData>           PROJECT            = Key.create(ProjectData.class, 50);
+  @NotNull public static final Key<ModuleData>            MODULE             = Key.create(ModuleData.class, 70);
+  @NotNull public static final Key<LibraryData>           LIBRARY            = Key.create(LibraryData.class, 90);
+  @NotNull public static final Key<ContentRootData>       CONTENT_ROOT       = Key.create(ContentRootData.class, 110);
+  @NotNull public static final Key<ModuleDependencyData>  MODULE_DEPENDENCY  = Key.create(ModuleDependencyData.class, 130);
+  @NotNull public static final Key<LibraryDependencyData> LIBRARY_DEPENDENCY = Key.create(LibraryDependencyData.class, 150);
 
-  @NotNull public static final Key<TaskData> TASK = Key.create(TaskData.class);
+  @NotNull public static final Key<TaskData> TASK = Key.create(TaskData.class, 250);
 
   private ProjectKeys() {
   }
index 88dca13e0e0ab963e2b8a6ee527a2ab3368cd9dd..eecd5540f5a7208d80d925ff966327b66b46e8b6 100644 (file)
  */
 package com.intellij.openapi.externalSystem.settings;
 
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
-import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.project.Project;
 import com.intellij.util.SystemProperties;
 import com.intellij.util.containers.ContainerUtilRt;
 import org.jetbrains.annotations.NotNull;
@@ -58,6 +61,48 @@ public abstract class AbstractExternalSystemLocalSettings {
       ContainerUtilRt.<String, Collection<ExternalTaskPojo>>newHashMap()
     );
 
+  @NotNull private final ProjectSystemId myExternalSystemId;
+  @NotNull private final Project         myProject;
+
+  protected AbstractExternalSystemLocalSettings(@NotNull ProjectSystemId externalSystemId, @NotNull Project project) {
+    myExternalSystemId = externalSystemId;
+    myProject = project;
+  }
+
+  /**
+   * Asks current settings to drop all information related to external project which root config is located at the given path.
+   * 
+   * @param linkedProjectPathsToForget  target root external project's path
+   */
+  public void forgetExternalProject(@NotNull Set<String> linkedProjectPathsToForget) {
+    Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> projects = myAvailableProjects.get();
+    for (Iterator<Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>>> it = projects.entrySet().iterator(); it.hasNext(); ) {
+      Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry = it.next();
+      if (linkedProjectPathsToForget.contains(entry.getKey().getPath())) {
+        it.remove();
+      }
+    }
+
+    for (Iterator<Map.Entry<String, Collection<ExternalTaskPojo>>> it = myAvailableTasks.get().entrySet().iterator(); it.hasNext(); ) {
+      Map.Entry<String, Collection<ExternalTaskPojo>> entry = it.next();
+      if (linkedProjectPathsToForget.contains(entry.getKey())
+          || linkedProjectPathsToForget.contains(ExternalSystemApiUtil.getRootProjectPath(entry.getKey(), myExternalSystemId, myProject)))
+      {
+        it.remove();
+      }
+    }
+
+    for (Iterator<ExternalTaskExecutionInfo> it = myRecentTasks.get().iterator(); it.hasNext(); ) {
+      ExternalTaskExecutionInfo taskInfo = it.next();
+      String path = taskInfo.getSettings().getExternalProjectPath();
+      if (linkedProjectPathsToForget.contains(path) ||
+          linkedProjectPathsToForget.contains(ExternalSystemApiUtil.getRootProjectPath(path, myExternalSystemId, myProject)))
+      {
+        it.remove();
+      }
+    }
+  }
+
   @SuppressWarnings("UnusedDeclaration")
   @NotNull
   public Map<String, Boolean> getExpandStates() { // Necessary for the serialization.
index ba6fc15044963fe1be534fe5051167d49cb14329..aff17a8e8aa74adb9801741681ca0cf26da1cb24 100644 (file)
@@ -55,6 +55,24 @@ public abstract class AbstractExternalSystemSettings<S extends ExternalProjectSe
     return myLinkedProjectsSettings.get(linkedProjectPath);
   }
 
+  /**
+   * Un-links given external project from the current ide project.
+   * 
+   * @param linkedProjectPath  path of external project to be unlinked
+   * @return                   <code>true</code> if there was an external project with the given config path linked to the current
+   *                           ide project;
+   *                           <code>false</code> otherwise
+   */
+  public boolean unlinkExternalProject(@NotNull String linkedProjectPath) {
+    S removed = myLinkedProjectsSettings.remove(linkedProjectPath);
+    if (removed == null) {
+      return false;
+    }
+    
+    getPublisher().onProjectsUnlinked(Collections.singleton(linkedProjectPath));
+    return true;
+  }
+
   public void setLinkedProjectsSettings(@NotNull Collection<S> settings) {
     List<S> added = ContainerUtilRt.newArrayList();
     Map<String, S> removed = ContainerUtilRt.newHashMap(myLinkedProjectsSettings);
index 8f9514c2921a5c79dac00da18d5ca6c1301868da..c15c384e29f60685823afd4de1d00e2020784383 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.openapi.externalSystem.settings;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collection;
+import java.util.Set;
 
 /**
  * Defines callback for external system settings change.
@@ -31,7 +32,7 @@ public interface ExternalSystemSettingsListener<S extends ExternalProjectSetting
   
   void onProjectsLinked(@NotNull Collection<S> settings);
 
-  void onProjectsUnlinked(@NotNull Collection<String> linkedProjectPaths);
+  void onProjectsUnlinked(@NotNull Set<String> linkedProjectPaths);
   
   void onUseAutoImportChange(boolean currentValue, @NotNull String linkedProjectPath);
 
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java
new file mode 100644 (file)
index 0000000..a20bae9
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.settings;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @author Denis Zhdanov
+ * @since 6/13/13 7:37 PM
+ */
+public class ExternalSystemSettingsListenerAdapter<S extends ExternalProjectSettings> implements ExternalSystemSettingsListener<S> {
+
+  @Override
+  public void onProjectsLinked(@NotNull Collection<S> settings) {
+  }
+
+  @Override
+  public void onProjectsUnlinked(@NotNull Set<String> linkedProjectPaths) {
+  }
+
+  @Override
+  public void onUseAutoImportChange(boolean currentValue, @NotNull String linkedProjectPath) {
+  }
+
+  @Override
+  public void onBulkChangeStart() {
+  }
+
+  @Override
+  public void onBulkChangeEnd() {
+  }
+}
index de2129f05aa2d6d00e2d7b94be5d2c7c0b0d7bbe..3e41f1e290bff3c932f1977d3fdc4f0c3037fc16 100644 (file)
@@ -19,11 +19,13 @@ import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
 import com.intellij.openapi.externalSystem.ExternalSystemManager;
 import com.intellij.openapi.externalSystem.model.DataNode;
 import com.intellij.openapi.externalSystem.model.Key;
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.roots.libraries.Library;
@@ -53,7 +55,8 @@ import java.util.regex.Pattern;
  */
 public class ExternalSystemApiUtil {
 
-  private static final Logger LOG = Logger.getInstance("#" + ExternalSystemApiUtil.class.getName());
+  private static final Logger LOG                           =
+    Logger.getInstance("#" + ExternalSystemApiUtil.class.getName());
   private static final String LAST_USED_PROJECT_PATH_PREFIX = "LAST_EXTERNAL_PROJECT_PATH_";
 
   @NotNull public static final String PATH_SEPARATOR = "/";
@@ -74,6 +77,7 @@ public class ExternalSystemApiUtil {
     };
 
   @NotNull public static final Comparator<Object> ORDER_AWARE_COMPARATOR = new Comparator<Object>() {
+
     @Override
     public int compare(Object o1, Object o2) {
       int order1 = getOrder(o1);
@@ -100,6 +104,20 @@ public class ExternalSystemApiUtil {
     }
   };
 
+  @NotNull private static final Function<DataNode<?>, Key<?>> GROUPER = new Function<DataNode<?>, Key<?>>() {
+    @Override
+    public Key<?> fun(DataNode<?> node) {
+      return node.getKey();
+    }
+  };
+
+  @NotNull private static final Comparator<Object> COMPARABLE_GLUE = new Comparator<Object>() {
+    @SuppressWarnings("unchecked")
+    @Override
+    public int compare(Object o1, Object o2) {
+      return ((Comparable)o1).compareTo(o2);
+    }
+  };
 
   private ExternalSystemApiUtil() {
   }
@@ -192,18 +210,7 @@ public class ExternalSystemApiUtil {
 
   @NotNull
   public static Map<Key<?>, List<DataNode<?>>> group(@NotNull Collection<DataNode<?>> nodes) {
-    if (nodes.isEmpty()) {
-      return Collections.emptyMap();
-    }
-    Map<Key<?>, List<DataNode<?>>> result = ContainerUtilRt.newHashMap();
-    for (DataNode<?> node : nodes) {
-      List<DataNode<?>> n = result.get(node.getKey());
-      if (n == null) {
-        result.put(node.getKey(), n = ContainerUtilRt.newArrayList());
-      }
-      n.add(node);
-    }
-    return result;
+    return groupBy(nodes, GROUPER);
   }
 
   @NotNull
@@ -236,9 +243,19 @@ public class ExternalSystemApiUtil {
       }
       grouped.add(data);
     }
+
+    if (!result.isEmpty() && result.keySet().iterator().next() instanceof Comparable) {
+      List<K> ordered = ContainerUtilRt.newArrayList(result.keySet());
+      Collections.sort(ordered, COMPARABLE_GLUE);
+      Map<K, List<V>> orderedResult = ContainerUtilRt.newLinkedHashMap();
+      for (K k : ordered) {
+        orderedResult.put(k, result.get(k));
+      }
+      return orderedResult;
+    }
     return result;
   }
-
+  
   @SuppressWarnings("unchecked")
   @NotNull
   public static <T> Collection<DataNode<T>> getChildren(@NotNull DataNode<?> node, @NotNull Key<T> key) {
@@ -388,4 +405,32 @@ public class ExternalSystemApiUtil {
     buffer.insert(0, rootProjectDir.getName());
     return buffer.toString();
   }
+
+  /**
+   * There is a possible case that external project linked to an ide project is a multi-project, i.e. contains more than one
+   * module.
+   * <p/>
+   * This method tries to find root project's config path assuming that given path points to a sub-project's config path.
+   * 
+   * @param externalProjectPath  external sub-project's config path
+   * @param externalSystemId     target external system
+   * @param project              target ide project
+   * @return                     root external project's path if given path is considered to point to a known sub-project's config;
+   *                             <code>null</code> if it's not possible to find a root project's config path on the basis of the
+   *                             given path
+   */
+  @Nullable
+  public static String getRootProjectPath(@NotNull String externalProjectPath,
+                                          @NotNull ProjectSystemId externalSystemId,
+                                          @NotNull Project project)
+  {
+    ExternalSystemManager<?, ?, ?, ?, ?> manager = getManager(externalSystemId);
+    if (manager == null) {
+      return null;
+    }
+    if (manager instanceof ExternalSystemAutoImportAware) {
+      return ((ExternalSystemAutoImportAware)manager).getAffectedExternalProjectPath(externalProjectPath, project);
+    }
+    return null;
+  }
 }
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java
new file mode 100644 (file)
index 0000000..dfd9c2e
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.action;
+
+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.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.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.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collections;
+
+/**
+ * @author Denis Zhdanov
+ * @since 6/13/13 5:42 PM
+ */
+public class DetachExternalProjectAction extends AnAction implements DumbAware {
+
+  public DetachExternalProjectAction() {
+    getTemplatePresentation().setText(ExternalSystemBundle.message("action.detach.external.project.text"));
+    getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.detach.external.project.description"));
+  }
+
+  @Override
+  public void update(AnActionEvent e) {
+    MyInfo info = getProcessingInfo(e.getDataContext());
+    if (info.icon != null) {
+      e.getPresentation().setIcon(info.icon);
+    }
+    e.getPresentation().setVisible(info.externalProject != null);
+  }
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    MyInfo info = getProcessingInfo(e.getDataContext());
+    if (info.settings == null || info.localSettings == null || info.externalProject == null) {
+      return;
+    }
+
+    ExternalSystemTasksTreeModel allTasksModel = ExternalSystemDataKeys.ALL_TASKS_MODEL.getData(e.getDataContext());
+    if (allTasksModel != null) {
+      allTasksModel.pruneNodes(info.externalProject);
+    }
+
+    ExternalSystemRecentTasksList recentTasksList = ExternalSystemDataKeys.RECENT_TASKS_LIST.getData(e.getDataContext());
+    if (recentTasksList != null) {
+      recentTasksList.getModel().forgetTasksFrom(info.externalProject.getPath());
+    }
+    
+    info.localSettings.forgetExternalProject(Collections.singleton(info.externalProject.getPath()));
+    info.settings.unlinkExternalProject(info.externalProject.getPath());
+  }
+
+  @NotNull
+  private static MyInfo getProcessingInfo(@NotNull DataContext context) {
+    ExternalProjectPojo externalProject = ExternalSystemDataKeys.SELECTED_PROJECT.getData(context);
+    if (externalProject == null) {
+      return MyInfo.EMPTY;
+    }
+    
+    ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(context);
+    if (externalSystemId == null) {
+      return MyInfo.EMPTY;
+    }
+
+    Project ideProject = PlatformDataKeys.PROJECT.getData(context);
+    if (ideProject == null) {
+      return MyInfo.EMPTY;
+    }
+
+    ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
+    assert manager != null;
+    AbstractExternalSystemSettings<?, ?> settings = manager.getSettingsProvider().fun(ideProject);
+    ExternalProjectSettings externalProjectSettings = settings.getLinkedProjectSettings(externalProject.getPath());
+    AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(ideProject);
+    Icon icon = ExternalSystemUiUtil.getUiAware(externalSystemId).getProjectIcon();
+    return new MyInfo(externalProjectSettings == null ? null : settings,
+                      localSettings == null ? null : localSettings,
+                      externalProjectSettings == null ? null : externalProject,
+                      icon);
+  }
+  
+  private static class MyInfo {
+
+    public static final MyInfo EMPTY = new MyInfo(null, null, null, null);
+
+    @Nullable public final AbstractExternalSystemSettings<?, ?> settings;
+    @Nullable public final AbstractExternalSystemLocalSettings  localSettings;
+    @Nullable public final ExternalProjectPojo                  externalProject;
+    @Nullable public final Icon                                 icon;
+
+    MyInfo(@Nullable AbstractExternalSystemSettings<?, ?> settings,
+           @Nullable AbstractExternalSystemLocalSettings localSettings,
+           @Nullable ExternalProjectPojo externalProject,
+           @Nullable Icon icon)
+    {
+      this.settings = settings;
+      this.localSettings = localSettings;
+      this.externalProject = externalProject;
+      this.icon = icon;
+    }
+  }
+}
index 4d4359940111c13529a3e17c8b489ee8a6ef0df2..cb485c326396445b9eb1791282287b2fefcdf3e2 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.openapi.externalSystem.model;
 import com.intellij.notification.NotificationGroup;
 import com.intellij.openapi.actionSystem.DataKey;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
 import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentTasksList;
 import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
 import org.jetbrains.annotations.NotNull;
@@ -32,6 +33,7 @@ public class ExternalSystemDataKeys {
   @NotNull public static final DataKey<NotificationGroup>            NOTIFICATION_GROUP = DataKey.create("external.system.notification");
   @NotNull public static final DataKey<ExternalSystemTasksTreeModel> ALL_TASKS_MODEL    = DataKey.create("external.system.all.tasks.model");
   @NotNull public static final DataKey<ExternalTaskPojo>             SELECTED_TASK      = DataKey.create("external.system.selected.task");
+  @NotNull public static final DataKey<ExternalProjectPojo>          SELECTED_PROJECT   = DataKey.create("external.system.selected.project");
 
   @NotNull public static final DataKey<ExternalSystemRecentTasksList> RECENT_TASKS_LIST
     = DataKey.create("external.system.recent.tasks.list");
index 6f6902654429790b1181160828f3a1457403fb8e..266b3bb5d33bcf53a871aaa36f23492931c9a7b0 100644 (file)
@@ -69,8 +69,9 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings
 
   @Override
   public void fillUi(@NotNull final PaintAwarePanel canvas, int indentLevel) {
-    myProjectPathLabel =
-      new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.project", myExternalSystemId.getReadableName()));
+    myProjectPathLabel = new JBLabel(ExternalSystemBundle.message(
+      "run.configuration.settings.label.project", myExternalSystemId.getReadableName()
+    ));
     ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(myExternalSystemId);
     FileChooserDescriptor projectPathChooserDescriptor = null;
     if (manager instanceof ExternalSystemUiAware) {
index e82d4bbc790f09e32ccb8f06802b714aaf9e0492..5e739ba1227aab643724dbe0fc055d0aa1ecb08e 100644 (file)
  */
 package com.intellij.openapi.externalSystem.service.task.ui;
 
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.project.Project;
 import com.intellij.util.containers.ContainerUtilRt;
 import org.jetbrains.annotations.NotNull;
 
@@ -28,6 +32,16 @@ import java.util.List;
  */
 public class ExternalSystemRecentTaskListModel extends DefaultListModel {
 
+  @NotNull private final ProjectSystemId myExternalSystemId;
+  @NotNull private final Project         myProject;
+
+  public ExternalSystemRecentTaskListModel(@NotNull ProjectSystemId externalSystemId, @NotNull Project project) {
+    myExternalSystemId = externalSystemId;
+    myProject = project;
+    ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
+  }
+
+  @SuppressWarnings("unchecked")
   public void setTasks(@NotNull List<ExternalTaskExecutionInfo> tasks) {
     clear();
     List<ExternalTaskExecutionInfo> tasksToUse = ContainerUtilRt.newArrayList(tasks);
@@ -36,6 +50,7 @@ public class ExternalSystemRecentTaskListModel extends DefaultListModel {
     }
   }
 
+  @SuppressWarnings("unchecked")
   public void setFirst(@NotNull ExternalTaskExecutionInfo task) {
     insertElementAt(task, 0);
     if (size() > 1) {
@@ -44,9 +59,10 @@ public class ExternalSystemRecentTaskListModel extends DefaultListModel {
     for (int i = 1; i < size(); i++) {
       if (task.equals(getElementAt(i))) {
         remove(i);
-        return;
+        break;
       }
     }
+    ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
   }
 
   @NotNull
@@ -61,6 +77,7 @@ public class ExternalSystemRecentTaskListModel extends DefaultListModel {
     return result;
   }
 
+  @SuppressWarnings("unchecked")
   public void ensureSize(int elementsNumber) {
     int toAdd = elementsNumber - size();
     if (toAdd <= 0) {
@@ -71,6 +88,26 @@ public class ExternalSystemRecentTaskListModel extends DefaultListModel {
     }
   }
 
+  /**
+   * Asks current model to remove all 'recent task info' entries which point to tasks from external project with the given path.
+   * 
+   * @param externalProjectPath  target external project's path
+   */
+  public void forgetTasksFrom(@NotNull String externalProjectPath) {
+    for (int i = size() - 1; i >= 0; i--) {
+      Object e = getElementAt(i);
+      if (e instanceof ExternalTaskExecutionInfo) {
+        String path = ((ExternalTaskExecutionInfo)e).getSettings().getExternalProjectPath();
+        if (externalProjectPath.equals(path)
+            || externalProjectPath.equals(ExternalSystemApiUtil.getRootProjectPath(path, myExternalSystemId, myProject)))
+        {
+          removeElementAt(i);
+        }
+      }
+    }
+    ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
+  }
+
   static class MyEmptyDescriptor {
   }
 }
index cc179911266b9f01261ef6e4e4535f5f996fd9b0..9dd416f0b72e267d6419d78349071abd3486314e 100644 (file)
@@ -66,7 +66,6 @@ public class ExternalSystemRecentTasksList extends JBList implements Producer<Ex
     }
     setCellRenderer(new MyRenderer(project, icon, ExternalSystemUtil.findConfigurationType(externalSystemId)));
     setVisibleRowCount(ExternalSystemConstants.RECENT_TASKS_NUMBER);
-    model.ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
     
     addMouseListener(new MouseAdapter() {
       @Override
@@ -94,7 +93,6 @@ public class ExternalSystemRecentTasksList extends JBList implements Producer<Ex
     ExternalTaskExecutionInfo selected = produce();
     ExternalSystemRecentTaskListModel model = getModel();
     model.setFirst(task);
-    model.ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
     clearSelection();
     if (selected == null) {
       return;
index 29643bbbd3ef9af26bbb98b6263a31d1fa80cd26..5e8ae40e4855583f674e035973fc4217c64b98dc 100644 (file)
@@ -26,6 +26,7 @@ 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.execution.ExternalTaskExecutionInfo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
 import com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskLocation;
 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -79,7 +80,7 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D
     assert manager != null;
     AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
 
-    ExternalSystemRecentTaskListModel recentTasksModel = new ExternalSystemRecentTaskListModel();
+    ExternalSystemRecentTaskListModel recentTasksModel = new ExternalSystemRecentTaskListModel(externalSystemId, project);
     recentTasksModel.setTasks(settings.getRecentTasks());
     myRecentTasksList = new ExternalSystemRecentTasksList(recentTasksModel, externalSystemId, project) {
       @Override
@@ -144,6 +145,18 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D
     else if (ExternalSystemDataKeys.SELECTED_TASK.is(dataId)) {
       return mySelectedTaskProvider == null ? null : mySelectedTaskProvider.produce();
     }
+    else if (ExternalSystemDataKeys.SELECTED_PROJECT.is(dataId)) {
+      if (mySelectedTaskProvider != myAllTasksTree) {
+        return null;
+      }
+      else {
+        Object component = myAllTasksTree.getLastSelectedPathComponent();
+        if (component instanceof ExternalSystemNode) {
+          Object element = ((ExternalSystemNode)component).getDescriptor().getElement();
+          return element instanceof ExternalProjectPojo ? element : null;
+        }
+      }
+    }
     else if (Location.DATA_KEY.is(dataId)) {
       Location location = buildLocation();
       return location == null ? super.getData(dataId) : location;
index 3eeda23e6c71bc0c165856ba3dbca5469e5a25ad..41d99e20bb224a6539f014cf295f5f620f470983 100644 (file)
 package com.intellij.openapi.externalSystem.service.task.ui;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.externalSystem.ExternalSystemManager;
 import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
 import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
-import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
-import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
 import com.intellij.openapi.wm.ToolWindowId;
 import com.intellij.util.containers.ContainerUtilRt;
@@ -78,13 +75,7 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
   public ExternalSystemTasksTreeModel(@NotNull ProjectSystemId externalSystemId) {
     super(new ExternalSystemNode<String>(new ExternalSystemNodeDescriptor<String>("", "", null)));
     myExternalSystemId = externalSystemId;
-    ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
-    if (manager instanceof ExternalSystemUiAware) {
-      myUiAware = (ExternalSystemUiAware)manager;
-    }
-    else {
-      myUiAware = DefaultExternalSystemUiAware.INSTANCE;
-    }
+    myUiAware = ExternalSystemUiUtil.getUiAware(externalSystemId);
   }
 
   private static String getTaskName(@NotNull ExternalTaskExecutionInfo taskInfo) {
@@ -120,6 +111,27 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
     return result;
   }
 
+  /**
+   * Asks current model to remove all nodes which have given data as a {@link ExternalSystemNodeDescriptor#getElement() payload}.
+   *
+   * @param payload  target payload
+   */
+  public void pruneNodes(@NotNull Object payload) {
+    Deque<ExternalSystemNode<?>> toProcess = new ArrayDeque<ExternalSystemNode<?>>();
+    toProcess.addFirst(getRoot());
+    while (!toProcess.isEmpty()) {
+      ExternalSystemNode<?> node = toProcess.removeLast();
+      if (payload.equals(node.getDescriptor().getElement())) {
+        removeNodeFromParent(node);
+      }
+      else {
+        for (int i = 0; i < node.getChildCount(); i++) {
+          toProcess.addFirst(node.getChildAt(i));
+        }
+      }
+    }
+  }
+
   public void ensureSubProjectsStructure(@NotNull ExternalProjectPojo topLevelProject,
                                          @NotNull Collection<ExternalProjectPojo> subProjects)
   {
@@ -162,6 +174,9 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
   }
 
   public void ensureTasks(@NotNull String externalProjectConfigPath, @NotNull Collection<ExternalTaskPojo> tasks) {
+    if (tasks.isEmpty()) {
+      return;
+    }
     ExternalSystemNode<ExternalProjectPojo> moduleNode = findProjectNode(externalProjectConfigPath);
     if (moduleNode == null) {
       LOG.warn(String.format(
@@ -186,7 +201,7 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
         }
       }
     }
-    
+
     if (!toAdd.isEmpty()) {
       for (ExternalTaskExecutionInfo taskInfo : toAdd) {
         moduleNode.add(new ExternalSystemNode<ExternalTaskExecutionInfo>(descriptor(taskInfo, myUiAware.getTaskIcon())));
index a7c1ca2e20138ab53475a886b99cca38589e6c7a..4e8e245f34334bfdb77bcd8891d28752a2d91bb3 100644 (file)
@@ -31,6 +31,7 @@ import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTr
 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
 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.fileChooser.FileChooser;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 import com.intellij.openapi.project.Project;
@@ -166,13 +167,7 @@ public class ExternalProjectPathField extends ComponentWithBrowseButton<External
     ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
     assert manager != null;
     final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
-    final ExternalSystemUiAware uiAware;
-    if (manager instanceof ExternalSystemUiAware) {
-      uiAware = (ExternalSystemUiAware)manager;
-    }
-    else {
-      uiAware = DefaultExternalSystemUiAware.INSTANCE;
-    }
+    final ExternalSystemUiAware uiAware = ExternalSystemUiUtil.getUiAware(externalSystemId);
     TextFieldCompletionProvider provider = new TextFieldCompletionProviderDumbAware() {
       @Override
       protected void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result) {
@@ -224,13 +219,7 @@ public class ExternalProjectPathField extends ComponentWithBrowseButton<External
     ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
     assert manager != null;
     final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
-    final ExternalSystemUiAware uiAware;
-    if (manager instanceof ExternalSystemUiAware) {
-      uiAware = (ExternalSystemUiAware)manager;
-    }
-    else {
-      uiAware = DefaultExternalSystemUiAware.INSTANCE;
-    }
+    final ExternalSystemUiAware uiAware = ExternalSystemUiUtil.getUiAware(externalSystemId);
 
     String rawText = editor.getDocument().getText();
     for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : settings.getAvailableProjects().entrySet()) {
index 7e90a3828002c6b5750d4e76f14dd14c2ea5c973..80f482fe994a03cbbb360120488e8e4abaf1f3bc 100644 (file)
 package com.intellij.openapi.externalSystem.util;
 
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
 import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
+import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
 import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.ui.popup.Balloon;
@@ -179,4 +183,10 @@ public class ExternalSystemUiUtil {
       }
     }
   }
+
+  @NotNull
+  public static ExternalSystemUiAware getUiAware(@NotNull ProjectSystemId externalSystemId) {
+    ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
+    return manager instanceof ExternalSystemUiAware ? (ExternalSystemUiAware)manager : DefaultExternalSystemUiAware.INSTANCE;
+  }
 }
index bfe6fe7ebeebf3c66e4dd590c45f48f01fa5254a..8c96e3f5fd7195418c5c8e84c7960e89bdc00a14 100644 (file)
@@ -12,6 +12,8 @@
 
     <!--Context menu action-->
     <group id="ExternalSystem.Tree.Context" popup="true">
+      <action id="ExternalSystem.DetachProject"
+              class="com.intellij.openapi.externalSystem.action.DetachExternalProjectAction"/>
       <reference ref="RunContextGroup"/>
     </group>
     
index 33f2ae9344816d202bbeeb3e4b0b990011a265f8..b0aa3664a3840b7cb94f9682e4398e222afe5d90 100644 (file)
@@ -1,17 +1,18 @@
 package org.jetbrains.plugins.gradle.config;
 
+import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
 import org.jetbrains.plugins.gradle.settings.GradleSettingsListener;
 
-import java.util.Collection;
-
 /**
  * @author Denis Zhdanov
  * @since 3/13/12 3:53 PM
  */
-public abstract class GradleSettingsListenerAdapter implements GradleSettingsListener {
+public abstract class GradleSettingsListenerAdapter extends ExternalSystemSettingsListenerAdapter<GradleProjectSettings>
+  implements GradleSettingsListener
+{
 
   @Override
   public void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath, @NotNull String linkedProjectPath) {
@@ -24,24 +25,4 @@ public abstract class GradleSettingsListenerAdapter implements GradleSettingsLis
   @Override
   public void onServiceDirectoryPathChange(@Nullable String oldPath, @Nullable String newPath) {
   }
-
-  @Override
-  public void onProjectsLinked(@NotNull Collection<GradleProjectSettings> settings) {
-  }
-
-  @Override
-  public void onProjectsUnlinked(@NotNull Collection<String> linkedProjectPaths) {
-  }
-
-  @Override
-  public void onUseAutoImportChange(boolean currentValue, @NotNull String linkedProjectPath) {
-  }
-
-  @Override
-  public void onBulkChangeStart() {
-  }
-
-  @Override
-  public void onBulkChangeEnd() {
-  }
 }
index 4d5b8032cf044bc4da53bdcfc80c3428b1fe444a..9db445ce7313c619176ecef956cff4e7927a677a 100644 (file)
@@ -5,14 +5,12 @@ import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.ActionToolbar;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.SimpleToolWindowPanel;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.ui.SideBorder;
 import com.intellij.util.messages.MessageBusConnection;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.settings.GradleSettings;
 import org.jetbrains.plugins.gradle.settings.GradleSettingsListener;
 import org.jetbrains.plugins.gradle.ui.RichTextControlBuilder;
index d4dd83dd8d8e522dbd19fb04466958afb7d2f49f..3da23b6c2c46f6ff2be39a5e5a7b587834a92592 100644 (file)
@@ -5,6 +5,7 @@ import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalS
 import com.intellij.openapi.project.Project;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
 
 /**
  * @author Denis Zhdanov
@@ -15,6 +16,10 @@ public class GradleLocalSettings extends AbstractExternalSystemLocalSettings
   implements PersistentStateComponent<AbstractExternalSystemLocalSettings.State>
 {
 
+  public GradleLocalSettings(@NotNull Project project) {
+    super(GradleConstants.SYSTEM_ID, project);
+  }
+
   @NotNull
   public static GradleLocalSettings getInstance(@NotNull Project project) {
     return ServiceManager.getService(project, GradleLocalSettings.class);