error.resolve.already.running=Another 'refresh project' task is currently running for the project: {0}
# Tool window
+tool.window.title.projects=projects
tool.window.title.tasks=tasks
+external.system.view.nodes.run_configurations.name = Run Configurations
# Action.
action.refresh.all.projects.text=Refresh all {0} projects
action.open.config.text=Open {0} config
action.open.config.description=Allows to open project file of the linked {0} project at the editor
+action.refresh.project.auto.text=Auto-import
+action.refresh.project.auto.description=Enable/disable project auto-import
+
+action.open.settings.text={0} Settings
+action.open.settings.description=Edit {0} settings for the current project
+
# Notification
notification.project.refresh.fail.title={0} ''{1}'' project refresh failed
notification.messages.project.sync.tab.name={0} Sync
+notification.messages.task.execution.tab.name={0} Task
# Tasks.
tasks.recent.title=Recent tasks
tasks.all.title=All tasks
+external.system.keymap.group=External Build Systems
+external.system.task.after.sync=After Import
+external.system.task.before.compile=Before Make
+external.system.task.after.compile=After Make
+external.system.task.before.rebuild=Before Rebuild
+external.system.task.after.rebuild=After Rebuild
+external.system.task.before.run=Before Run
+
# Execution
run.configuration.description={0} build
run.configuration.tooltip.choose.registered.project=Choose one of registered {0} projects
private transient T myData;
private byte[] myRawData;
- @Nullable private final DataNode<?> myParent;
+ @Nullable private DataNode<?> myParent;
public DataNode(@NotNull Key<T> key, @NotNull T data, @Nullable DataNode<?> parent) {
myKey = key;
};
myData = (T)oIn.readObject();
myRawData = null;
+
+ assert myData != null;
}
catch (IOException e) {
throw new IllegalStateException(
}
private void writeObject(ObjectOutputStream out) throws IOException {
+ try {
+ myRawData = getDataBytes();
+ }
+ catch (IOException e) {
+ LOG.warn("Unable to serialize the data node - " + toString());
+ throw e;
+ }
+ out.defaultWriteObject();
+ }
+
+ public byte[] getDataBytes() throws IOException {
+ if (myRawData != null) return myRawData;
+
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ObjectOutputStream oOut = new ObjectOutputStream(bOut);
try {
oOut.writeObject(myData);
+ final byte[] bytes = bOut.toByteArray();
+ myRawData = bytes;
+ return bytes;
}
finally {
oOut.close();
}
- myRawData = bOut.toByteArray();
- out.defaultWriteObject();
}
-
+
@Override
public int hashCode() {
int result = myChildren.hashCode();
}
return String.format("%s: %s", myKey, dataDescription);
}
+
+ public void clear(boolean removeFromGraph) {
+ if (removeFromGraph && myParent != null) {
+ for (Iterator<DataNode<?>> iterator = myParent.getChildren().iterator(); iterator.hasNext(); ) {
+ DataNode<?> dataNode = iterator.next();
+ if (System.identityHashCode(dataNode) == System.identityHashCode(this)) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ myParent = null;
+ myRawData = null;
+ myChildren.clear();
+ }
}
@NotNull private final String myName;
@NotNull private final String myLinkedExternalProjectPath;
+ @Nullable private String myGroup;
@Nullable private final String myDescription;
return myDescription;
}
+ @Nullable
+ public String getGroup() {
+ return myGroup;
+ }
+
+ public void setGroup(@Nullable String group) {
+ myGroup = group;
+ }
+
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myName.hashCode();
result = 31 * result + myLinkedExternalProjectPath.hashCode();
result = 31 * result + (myDescription != null ? myDescription.hashCode() : 0);
+ result = 31 * result + (myGroup != null ? myGroup.hashCode() : 0);
return result;
}
TaskData data = (TaskData)o;
if (myDescription != null ? !myDescription.equals(data.myDescription) : data.myDescription != null) return false;
+ if (myGroup != null ? !myGroup.equals(data.myGroup) : data.myGroup != null) return false;
if (!myLinkedExternalProjectPath.equals(data.myLinkedExternalProjectPath)) return false;
if (!myName.equals(data.myName)) return false;
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsViewState;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.util.SystemProperties;
myExternalConfigModificationStamps =
new AtomicReference<Map<String, Long>>(ContainerUtilRt.<String, Long>newHashMap());
+ private final AtomicReference<ExternalProjectsViewState> myExternalProjectsViewState = new AtomicReference<ExternalProjectsViewState>(
+ new ExternalProjectsViewState()
+ );
+
@NotNull private final ProjectSystemId myExternalSystemId;
@NotNull private final Project myProject;
@NotNull private final PlatformFacade myPlatformFacade;
myProjectBuildClasspath.set(projectsBuildClasspath);
}
+ public ExternalProjectsViewState getExternalProjectsViewState() {
+ return myExternalProjectsViewState.get();
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setExternalProjectsViewState(ExternalProjectsViewState externalProjectsViewState) {
+ // Required for IJ serialization.
+ myExternalProjectsViewState.set(externalProjectsViewState);
+ }
+
public void fillState(@NotNull State state) {
if (PRESERVE_EXPAND_STATE) {
state.tasksExpandState = myExpandStates.get();
state.availableTasks = myAvailableTasks.get();
state.modificationStamps = myExternalConfigModificationStamps.get();
state.projectBuildClasspath = myProjectBuildClasspath.get();
+ state.externalProjectsViewState = myExternalProjectsViewState.get();
}
public void loadState(@NotNull State state) {
setIfNotNull(myAvailableTasks, state.availableTasks);
setIfNotNull(myExternalConfigModificationStamps, state.modificationStamps);
setIfNotNull(myProjectBuildClasspath, state.projectBuildClasspath);
+ myExternalProjectsViewState.set(state.externalProjectsViewState);
if (state.recentTasks != null) {
List<ExternalTaskExecutionInfo> recentTasks = myRecentTasks.get();
if (recentTasks != state.recentTasks) {
public Map<String/* linked project path */, Long/* last config modification stamp */> modificationStamps
= ContainerUtilRt.newHashMap();
public Map<String/* linked project path */, ExternalProjectBuildClasspathPojo> projectBuildClasspath = ContainerUtilRt.newHashMap();
+ public ExternalProjectsViewState externalProjectsViewState;
}
}
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.ExternalSystemException;
-import com.intellij.openapi.externalSystem.model.Key;
-import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.project.LibraryData;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
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.settings.ExternalSystemSettingsListener;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.*;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
+import com.intellij.util.containers.Stack;
import com.intellij.util.containers.TransferToEDTQueue;
import com.intellij.util.lang.UrlClassLoader;
+import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
return result == null ? Collections.<DataNode<T>>emptyList() : result;
}
+ public static void visit(@Nullable DataNode node, @NotNull Consumer<DataNode> consumer) {
+ if(node == null) return;
+
+ Stack<DataNode> toProcess = ContainerUtil.newStack(node);
+ while (!toProcess.isEmpty()) {
+ DataNode<?> node0 = toProcess.pop();
+ consumer.consume(node0);
+ for (DataNode<?> child : node0.getChildren()) {
+ toProcess.push(child);
+ }
+ }
+ }
+
+ @NotNull
+ public static <T> Collection<DataNode<T>> findAllRecursively(@Nullable final DataNode<?> node,
+ @NotNull final Key<T> key) {
+ if (node == null) return Collections.emptyList();
+
+ final Collection<DataNode<?>> nodes = findAllRecursively(node.getChildren(), new BooleanFunction<DataNode<?>>() {
+ @Override
+ public boolean fun(DataNode<?> node) {
+ return node.getKey().equals(key);
+ }
+ });
+ //noinspection unchecked
+ return new SmartList(nodes);
+ }
+
+ public static Collection<DataNode<?>> findAllRecursively(@NotNull Collection<DataNode<?>> nodes) {
+ return findAllRecursively(nodes, null);
+ }
+
+ @NotNull
+ public static Collection<DataNode<?>> findAllRecursively(@Nullable DataNode<?> node,
+ @Nullable BooleanFunction<DataNode<?>> predicate) {
+ if (node == null) return Collections.emptyList();
+ return findAllRecursively(node.getChildren(), predicate);
+ }
+
+ public static Collection<DataNode<?>> findAllRecursively(@NotNull Collection<DataNode<?>> nodes,
+ @Nullable BooleanFunction<DataNode<?>> predicate) {
+ SmartList<DataNode<?>> result = new SmartList<DataNode<?>>();
+ for (DataNode<?> node : nodes) {
+ if (predicate == null || predicate.fun(node)) {
+ result.add(node);
+ }
+ }
+ for (DataNode<?> node : nodes) {
+ result.addAll(findAllRecursively(node.getChildren(), predicate));
+ }
+ return result;
+ }
+
+ public static DataNode<?> findFirstRecursively(@NotNull DataNode<?> parentNode,
+ @NotNull BooleanFunction<DataNode<?>> predicate) {
+ Queue<DataNode<?>> queue = new LinkedList<DataNode<?>>();
+ queue.add(parentNode);
+ return findInQueue(queue, predicate);
+ }
+
+ public static DataNode<?> findFirstRecursively(@NotNull Collection<DataNode<?>> nodes,
+ @NotNull BooleanFunction<DataNode<?>> predicate) {
+ return findInQueue(new LinkedList<DataNode<?>>(nodes), predicate);
+ }
+
+ private static DataNode<?> findInQueue(@NotNull Queue<DataNode<?>> queue,
+ @NotNull BooleanFunction<DataNode<?>> predicate) {
+ while (!queue.isEmpty()) {
+ DataNode node = (DataNode)queue.remove();
+ if (predicate.fun(node)) {
+ return node;
+ }
+ //noinspection unchecked
+ queue.addAll(node.getChildren());
+ }
+ return null;
+ }
+
public static void executeProjectChangeAction(@NotNull final DisposeAwareProjectChange task) {
executeProjectChangeAction(false, task);
}
return module != null && !module.isDisposed() ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : null;
}
+ @Nullable
+ public static String getExternalRootProjectPath(@Nullable Module module) {
+ return module != null && !module.isDisposed() ? module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY) : null;
+ }
+
@Nullable
public static String getExternalProjectId(@Nullable Module module) {
return module != null && !module.isDisposed() ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_ID_KEY) : null;
}
+
+ public static void subscribe(@NotNull Project project,
+ @NotNull ProjectSystemId systemId,
+ @NotNull ExternalSystemSettingsListener listener) {
+ MessageBusConnection connection = project.getMessageBus().connect(project);
+ connection.subscribe(getSettings(project, systemId).getChangesTopic(), listener);
+ }
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.util.xmlb.annotations.Property;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jdom.Element;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 9/26/2014
+ */
+@Tag("projects_view")
+public class ExternalProjectsViewState {
+ public boolean groupTasks = true;
+ @Tag("tree_state")
+ public Element treeState;
+}
package com.intellij.openapi.externalSystem.action;
import com.intellij.icons.AllIcons;
-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.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
-import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
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.service.project.manage.ExternalProjectsManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
-import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.ProjectNode;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfoRt;
+import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
* @author Denis Zhdanov
* @since 6/13/13 5:42 PM
*/
-public class DetachExternalProjectAction extends AnAction implements DumbAware {
+public class DetachExternalProjectAction extends ExternalSystemNodeAction<AbstractExternalEntityData> implements DumbAware {
public DetachExternalProjectAction() {
+ super(AbstractExternalEntityData.class);
getTemplatePresentation().setText(ExternalSystemBundle.message("action.detach.external.project.text", "external"));
getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.detach.external.project.description"));
getTemplatePresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Remove : AllIcons.ToolbarDecorator.Remove);
}
@Override
- public void update(AnActionEvent e) {
- ExternalActionUtil.MyInfo info = ExternalActionUtil.getProcessingInfo(e.getDataContext());
- e.getPresentation().setEnabled(info.externalProject != null);
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1) return false;
+ final Object externalData = selectedNodes.get(0).getData();
+ return (externalData instanceof ProjectData || externalData instanceof ModuleData);
}
@Override
- public void actionPerformed(AnActionEvent e) {
- ExternalActionUtil.MyInfo info = ExternalActionUtil.getProcessingInfo(e.getDataContext());
- if (info.settings == null || info.localSettings == null || info.externalProject == null || info.ideProject == null
- || info.externalSystemId == null)
- {
- return;
- }
-
+ public void perform(@NotNull final Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull AbstractExternalEntityData entityData,
+ @NotNull AnActionEvent e) {
+
e.getPresentation().setText(
- ExternalSystemBundle.message("action.detach.external.project.text",info.externalSystemId.getReadableName())
+ ExternalSystemBundle.message("action.detach.external.project.text", projectSystemId.getReadableName())
);
- 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.forgetExternalProjects(Collections.singleton(info.externalProject.getPath()));
- info.settings.unlinkExternalProject(info.externalProject.getPath());
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ final ExternalSystemNode<?> externalSystemNode = ContainerUtil.getFirstItem(selectedNodes);
+ assert externalSystemNode != null;
+ final ProjectNode projectNode =
+ externalSystemNode instanceof ProjectNode ? (ProjectNode)externalSystemNode : externalSystemNode.findParent(ProjectNode.class);
+ assert projectNode != null;
+
+ final ProjectData projectData = projectNode.getData();
+ assert projectData != null;
+ ExternalSystemApiUtil.getLocalSettings(project, projectSystemId).
+ forgetExternalProjects(Collections.singleton(projectData.getLinkedExternalProjectPath()));
+ ExternalSystemApiUtil.getSettings(project, projectSystemId).unlinkExternalProject(projectData.getLinkedExternalProjectPath());
+
+ ExternalProjectsManager.getInstance(project).forgetExternalProjectData(projectSystemId, projectData.getLinkedExternalProjectPath());
// 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)) {
+ for (Module module : platformFacade.getModules(project)) {
+ if (!ExternalSystemApiUtil.isExternalSystemAwareModule(projectSystemId, module)) continue;
+
+ String path = ExternalSystemApiUtil.getExternalRootProjectPath(module);
+ if (projectData.getLinkedExternalProjectPath().equals(path)) {
orphanModules.add(module);
}
}
if (!orphanModules.isEmpty()) {
- ExternalSystemUtil.ruleOrphanModules(orphanModules, info.ideProject, info.externalSystemId);
+ ExternalSystemUtil.ruleOrphanModules(orphanModules, project, projectSystemId, new Consumer<Boolean>() {
+ @Override
+ public void consume(Boolean result) {
+ if (result != null && result) {
+ projectNode.getGroup().remove(projectNode);
+ }
+ }
+ });
}
}
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.impl.EditConfigurationsDialog;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/13/2014
+ */
+public class EditExternalSystemRunConfigurationAction extends ExternalSystemAction {
+
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1) return false;
+ return selectedNodes.get(0) instanceof RunConfigurationNode;
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Project project = getProject(e);
+ assert project != null;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1 || !(selectedNodes.get(0) instanceof RunConfigurationNode)) return;
+
+ RunnerAndConfigurationSettings settings = ((RunConfigurationNode)selectedNodes.get(0)).getSettings();
+ assert settings != null;
+ RunManager.getInstance(project).setSelectedConfiguration(settings);
+ EditConfigurationsDialog dialog = new EditConfigurationsDialog(project);
+ dialog.show();
+ }
+}
+++ /dev/null
-/*
- * 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.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-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.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.project.Project;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author Vladislav.Soroka
- * @since 9/18/13
- */
-public class ExternalActionUtil {
- @NotNull
- public 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 = CommonDataKeys.PROJECT.getData(context);
- if (ideProject == null) {
- return MyInfo.EMPTY;
- }
-
- AbstractExternalSystemSettings<?, ?, ?> settings = ExternalSystemApiUtil.getSettings(ideProject, externalSystemId);
- ExternalProjectSettings externalProjectSettings = settings.getLinkedProjectSettings(externalProject.getPath());
- AbstractExternalSystemLocalSettings localSettings = ExternalSystemApiUtil.getLocalSettings(ideProject, externalSystemId);
-
- return new MyInfo(externalProjectSettings == null ? null : settings,
- localSettings == null ? null : localSettings,
- externalProjectSettings == null ? null : externalProject,
- ideProject,
- externalSystemId);
- }
-
- public static class MyInfo {
-
- public static final MyInfo EMPTY = new MyInfo(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;
-
- MyInfo(@Nullable AbstractExternalSystemSettings<?, ?, ?> settings,
- @Nullable AbstractExternalSystemLocalSettings localSettings,
- @Nullable ExternalProjectPojo externalProject,
- @Nullable Project ideProject,
- @Nullable ProjectSystemId externalSystemId)
- {
- this.settings = settings;
- this.localSettings = localSettings;
- this.externalProject = externalProject;
- this.ideProject = ideProject;
- this.externalSystemId = externalSystemId;
- }
- }
-}
-
--- /dev/null
+/*
+ * Copyright 2000-2014 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.CommonDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public abstract class ExternalSystemAction extends AnAction implements DumbAware {
+
+ @Override
+ public void update(@NotNull AnActionEvent e) {
+ super.update(e);
+ Presentation p = e.getPresentation();
+ final boolean visible = isVisible(e);
+ p.setVisible(visible);
+ p.setEnabled(visible && isEnabled(e));
+ }
+
+ protected boolean isEnabled(AnActionEvent e) {
+ return hasProject(e) && getSystemId(e) != null;
+ }
+
+ protected boolean isVisible(AnActionEvent e) {
+ return true;
+ }
+
+ protected Project getProject(AnActionEvent e) {
+ return CommonDataKeys.PROJECT.getData(e.getDataContext());
+ }
+
+ protected ProjectSystemId getSystemId(AnActionEvent e) {
+ return ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
+ }
+
+ protected boolean hasProject(AnActionEvent e) {
+ return getProject(e) != null;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2014 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.execution.executors.DefaultRunExecutor;
+import com.intellij.ide.DataManager;
+import com.intellij.ide.util.ElementsChooser;
+import com.intellij.openapi.actionSystem.*;
+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.task.TaskData;
+import com.intellij.openapi.module.Module;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 9/18/13
+ */
+public class ExternalSystemActionUtil {
+
+ public static void executeAction(final String actionId, final InputEvent e) {
+ final ActionManager actionManager = ActionManager.getInstance();
+ final AnAction action = actionManager.getAction(actionId);
+ if (action != null) {
+ final Presentation presentation = new Presentation();
+ final AnActionEvent event =
+ new AnActionEvent(e, DataManager.getInstance().getDataContext(e.getComponent()), "", presentation, actionManager, 0);
+ action.update(event);
+ if (presentation.isEnabled()) {
+ action.actionPerformed(event);
+ }
+ }
+ }
+
+ @Nullable
+ public static Module getModule(DataContext context) {
+ final Module module = LangDataKeys.MODULE.getData(context);
+ return module != null ? module : LangDataKeys.MODULE_CONTEXT.getData(context);
+ }
+
+ public static <E> void setElements(ElementsChooser<E> chooser, Collection<E> all, Collection<E> selected, Comparator<E> comparator) {
+ List<E> selection = chooser.getSelectedElements();
+ chooser.clear();
+ Collection<E> sorted = new TreeSet<E>(comparator);
+ sorted.addAll(all);
+ for (E element : sorted) {
+ chooser.addElement(element, selected.contains(element));
+ }
+ chooser.selectElements(selection);
+ }
+
+ public static void installCheckboxRenderer(final SimpleTree tree, final CheckboxHandler handler) {
+ final JCheckBox checkbox = new JCheckBox();
+
+ final JPanel panel = new JPanel(new BorderLayout());
+ panel.add(checkbox, BorderLayout.WEST);
+
+ final TreeCellRenderer baseRenderer = tree.getCellRenderer();
+ tree.setCellRenderer(new TreeCellRenderer() {
+ public Component getTreeCellRendererComponent(final JTree tree,
+ final Object value,
+ final boolean selected,
+ final boolean expanded,
+ final boolean leaf,
+ final int row,
+ final boolean hasFocus) {
+ final Component baseComponent = baseRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
+
+ final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
+ if (!handler.isVisible(userObject)) {
+ return baseComponent;
+ }
+
+ final Color foreground = selected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeTextForeground();
+
+ Color background = selected ? UIUtil.getTreeSelectionBackground(hasFocus) : UIUtil.getTreeTextBackground();
+
+ panel.add(baseComponent, BorderLayout.CENTER);
+ panel.setBackground(background);
+ panel.setForeground(foreground);
+
+ CheckBoxState state = handler.getState(userObject);
+ checkbox.setSelected(state != CheckBoxState.UNCHECKED);
+ checkbox.setEnabled(state != CheckBoxState.PARTIAL);
+ checkbox.setBackground(background);
+ checkbox.setForeground(foreground);
+
+ return panel;
+ }
+ });
+
+ tree.addMouseListener(new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ int row = tree.getRowForLocation(e.getX(), e.getY());
+ if (row >= 0) {
+ TreePath path = tree.getPathForRow(row);
+ if (!isCheckboxEnabledFor(path, handler)) return;
+
+ Rectangle checkBounds = checkbox.getBounds();
+ checkBounds.setLocation(tree.getRowBounds(row).getLocation());
+ if (checkBounds.contains(e.getPoint())) {
+ handler.toggle(path, e);
+ e.consume();
+ tree.setSelectionRow(row);
+ }
+ }
+ }
+ });
+
+ tree.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_SPACE) {
+ TreePath[] treePaths = tree.getSelectionPaths();
+ if (treePaths != null) {
+ for (TreePath treePath : treePaths) {
+ if (!isCheckboxEnabledFor(treePath, handler)) continue;
+ handler.toggle(treePath, e);
+ }
+ e.consume();
+ }
+ }
+ }
+ });
+ }
+
+ private static boolean isCheckboxEnabledFor(TreePath path, CheckboxHandler handler) {
+ Object userObject = ((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject();
+ return handler.isVisible(userObject);
+ }
+
+ public interface CheckboxHandler {
+ void toggle(TreePath treePath, final InputEvent e);
+
+ boolean isVisible(Object userObject);
+
+ CheckBoxState getState(Object userObject);
+ }
+
+ public enum CheckBoxState {
+ CHECKED, UNCHECKED, PARTIAL
+ }
+
+ @NotNull
+ public static ExternalTaskExecutionInfo buildTaskInfo(@NotNull TaskData task) {
+ ExternalSystemTaskExecutionSettings settings = new ExternalSystemTaskExecutionSettings();
+ settings.setExternalProjectPath(task.getLinkedExternalProjectPath());
+ settings.setTaskNames(Collections.singletonList(task.getName()));
+ settings.setTaskDescriptions(Collections.singletonList(task.getDescription()));
+ settings.setExternalSystemIdString(task.getOwner().toString());
+ return new ExternalTaskExecutionInfo(settings, DefaultRunExecutor.EXECUTOR_ID);
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware;
+import com.intellij.openapi.externalSystem.service.settings.ExternalSystemConfigLocator;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/17/2014
+ */
+public abstract class ExternalSystemNodeAction<T> extends ExternalSystemAction {
+
+ private final Class<T> myExternalDataClazz;
+
+ public ExternalSystemNodeAction(Class<T> externalDataClazz) {
+ super();
+ myExternalDataClazz = externalDataClazz;
+ }
+
+ protected boolean isEnabled(AnActionEvent e) {
+ return super.isEnabled(e) && getSystemId(e) != null && getExternalData(e, myExternalDataClazz) != null;
+ }
+
+ protected abstract void perform(@NotNull Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull T externalData,
+ @NotNull AnActionEvent e);
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ final Project project = getProject(e);
+ if (project == null) return;
+
+ ProjectSystemId projectSystemId = getSystemId(e);
+ if (projectSystemId == null) return;
+
+ final T data = getExternalData(e, myExternalDataClazz);
+ if (data == null) return;
+
+ perform(project, projectSystemId, data, e);
+ }
+
+ @Nullable
+ protected ExternalSystemUiAware getExternalSystemUiAware(AnActionEvent e) {
+ return ExternalSystemDataKeys.UI_AWARE.getData(e.getDataContext());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Nullable
+ protected <T> T getExternalData(AnActionEvent e, Class<T> dataClass) {
+ ExternalSystemNode node = ContainerUtil.getFirstItem(ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext()));
+ return node != null && dataClass.isInstance(node.getData()) ? (T)node.getData() : null;
+ }
+
+ @Nullable
+ protected VirtualFile getExternalConfig(@NotNull ExternalConfigPathAware data, ProjectSystemId externalSystemId) {
+ String path = data.getLinkedExternalProjectPath();
+ LocalFileSystem fileSystem = LocalFileSystem.getInstance();
+ VirtualFile externalSystemConfigPath = fileSystem.refreshAndFindFileByPath(path);
+ if (externalSystemConfigPath == null) {
+ return null;
+ }
+
+ VirtualFile toOpen = externalSystemConfigPath;
+ for (ExternalSystemConfigLocator locator : ExternalSystemConfigLocator.EP_NAME.getExtensions()) {
+ if (externalSystemId.equals(locator.getTargetExternalSystemId())) {
+ toOpen = locator.adjust(toOpen);
+ if (toOpen == null) {
+ return null;
+ }
+ break;
+ }
+ }
+ return toOpen.isDirectory() ? null : toOpen;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2014 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.execution.*;
+import com.intellij.execution.runners.ProgramRunner;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/20/2014
+ */
+public class ExternalSystemRunConfigurationMenu extends DefaultActionGroup implements DumbAware {
+ @Override
+ public void update(AnActionEvent e) {
+ for (AnAction action : getChildActionsOrStubs()) {
+ if (action instanceof ExecuteExternalSystemRunConfigurationAction) {
+ remove(action);
+ }
+ }
+
+ final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1 || !(selectedNodes.get(0) instanceof RunConfigurationNode)) return;
+
+ final RunnerAndConfigurationSettings settings = ((RunConfigurationNode)selectedNodes.get(0)).getSettings();
+
+ if (settings == null || project == null) return;
+
+ Executor[] executors = ExecutorRegistry.getInstance().getRegisteredExecutors();
+ for (int i = executors.length; --i >= 0; ) {
+ final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executors[i].getId(), settings.getConfiguration());
+ AnAction action = new ExecuteExternalSystemRunConfigurationAction(executors[i], runner != null, project, settings);
+ addAction(action, Constraints.FIRST);
+ }
+
+ super.update(e);
+ }
+
+ private static class ExecuteExternalSystemRunConfigurationAction extends AnAction {
+ private final Executor myExecutor;
+ private final boolean myEnabled;
+ private final Project myProject;
+ private final RunnerAndConfigurationSettings mySettings;
+
+ public ExecuteExternalSystemRunConfigurationAction(Executor executor,
+ boolean enabled,
+ Project project,
+ RunnerAndConfigurationSettings settings) {
+ super(executor.getActionName(), null, executor.getIcon());
+ myExecutor = executor;
+ myEnabled = enabled;
+ myProject = project;
+ mySettings = settings;
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent event) {
+ if (myEnabled) {
+ ProgramRunnerUtil.executeConfiguration(myProject, mySettings, myExecutor);
+ final RunManagerEx runManagerEx = RunManagerEx.getInstanceEx(myProject);
+ runManagerEx.setSelectedConfiguration(mySettings);
+ }
+ }
+
+ @Override
+ public void update(@NotNull AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setEnabled(myEnabled);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.ToggleAction;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public abstract class ExternalSystemToggleAction extends ToggleAction implements DumbAware {
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ Presentation p = e.getPresentation();
+ final boolean visible = isVisible(e);
+ p.setVisible(visible);
+ p.setEnabled(visible && isEnabled(e));
+ }
+
+ protected boolean isEnabled(AnActionEvent e) {
+ return hasProject(e);
+ }
+
+ protected boolean isVisible(AnActionEvent e) {
+ return true;
+ }
+
+ @Override
+ public final boolean isSelected(AnActionEvent e) {
+ if (!isEnabled(e)) return false;
+ return doIsSelected(e);
+ }
+
+ protected abstract boolean doIsSelected(AnActionEvent e);
+
+ protected Project getProject(AnActionEvent e) {
+ return CommonDataKeys.PROJECT.getData(e.getDataContext());
+ }
+
+ protected boolean hasProject(AnActionEvent e) {
+ return getProject(e) != null;
+ }
+
+ protected ProjectSystemId getSystemId(AnActionEvent e) {
+ return ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public abstract class ExternalSystemTreeAction extends ExternalSystemAction {
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ return super.isEnabled(e) && getTree(e) != null;
+ }
+
+ @Nullable
+ protected static JTree getTree(AnActionEvent e) {
+ return ExternalSystemDataKeys.PROJECTS_TREE.getData(e.getDataContext());
+ }
+
+ public static class CollapseAll extends ExternalSystemTreeAction {
+ public void actionPerformed(AnActionEvent e) {
+ JTree tree = getTree(e);
+ if (tree == null) return;
+
+ int row = tree.getRowCount() - 1;
+ while (row >= 0) {
+ tree.collapseRow(row);
+ row--;
+ }
+ }
+ }
+
+ public static class ExpandAll extends ExternalSystemTreeAction {
+ public void actionPerformed(AnActionEvent e) {
+ JTree tree = getTree(e);
+ if (tree == null) return;
+
+ for (int i = 0; i < tree.getRowCount(); i++) {
+ tree.expandRow(i);
+ }
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/31/2014
+ */
+public abstract class ExternalSystemViewGearAction extends ExternalSystemToggleAction {
+
+ private ExternalProjectsView myView;
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ return getView() != null;
+ }
+
+ @Override
+ protected boolean doIsSelected(AnActionEvent e) {
+ final ExternalProjectsView view = getView();
+ return view != null && isSelected(view);
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ final ExternalProjectsView view = getView();
+ if (view != null){
+ setSelected(view, state);
+ }
+ }
+
+ protected abstract boolean isSelected(@NotNull ExternalProjectsView view);
+
+ protected abstract void setSelected(@NotNull ExternalProjectsView view, boolean value);
+
+ @Nullable
+ protected ExternalProjectsView getView() {
+ return myView;
+ }
+
+ public void setView(ExternalProjectsView view) {
+ myView = view;
+ }
+}
package com.intellij.openapi.externalSystem.action;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+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.service.settings.ExternalSystemConfigLocator;
+import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware;
+import com.intellij.openapi.externalSystem.model.project.ExternalEntityData;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
-import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
-import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
- * @author Denis Zhdanov
- * @since 7/16/13 2:19 PM
+ * @author Vladislav.Soroka
+ * @since 10/17/2014
*/
-public class OpenExternalConfigAction extends AnAction implements DumbAware {
+public class OpenExternalConfigAction extends ExternalSystemNodeAction<ExternalConfigPathAware> {
public OpenExternalConfigAction() {
+ super(ExternalConfigPathAware.class);
getTemplatePresentation().setText(ExternalSystemBundle.message("action.open.config.text", "external"));
getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.open.config.description", "external"));
}
@Override
- public void update(AnActionEvent e) {
- ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
- if (externalSystemId == null) {
- e.getPresentation().setEnabled(false);
- return;
- }
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+
+ final ExternalEntityData externalData = getExternalData(e, ExternalEntityData.class);
+ if (!(externalData instanceof ExternalConfigPathAware)) return false;
+ VirtualFile config = getExternalConfig((ExternalConfigPathAware)externalData, externalData.getOwner());
+ if (config == null) return false;
+
+ ProjectSystemId externalSystemId = getSystemId(e);
e.getPresentation().setText(ExternalSystemBundle.message("action.open.config.text", externalSystemId.getReadableName()));
e.getPresentation().setDescription(ExternalSystemBundle.message("action.open.config.description", externalSystemId.getReadableName()));
- e.getPresentation().setIcon(ExternalSystemUiUtil.getUiAware(externalSystemId).getProjectIcon());
+ final ExternalSystemUiAware uiAware = getExternalSystemUiAware(e);
+ if (uiAware != null) {
+ e.getPresentation().setIcon(uiAware.getProjectIcon());
+ }
- VirtualFile config = getExternalConfig(e.getDataContext());
- e.getPresentation().setEnabled(config != null);
+ return true;
}
@Override
- public void actionPerformed(AnActionEvent e) {
- Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
- if (project == null) {
- return;
- }
-
- VirtualFile configFile = getExternalConfig(e.getDataContext());
- if (configFile == null) {
- return;
- }
-
- OpenFileDescriptor descriptor = new OpenFileDescriptor(project, configFile);
- FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
- }
-
- @Nullable
- private static VirtualFile getExternalConfig(@NotNull DataContext context) {
- ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(context);
- if (externalSystemId == null) {
- return null;
- }
-
- ExternalProjectPojo projectPojo = ExternalSystemDataKeys.SELECTED_PROJECT.getData(context);
- if (projectPojo == null) {
- return null;
- }
-
- String path = projectPojo.getPath();
- LocalFileSystem fileSystem = LocalFileSystem.getInstance();
- VirtualFile externalSystemConfigPath = fileSystem.refreshAndFindFileByPath(path);
- if (externalSystemConfigPath == null) {
- return null;
- }
-
- VirtualFile toOpen = externalSystemConfigPath;
- for (ExternalSystemConfigLocator locator : ExternalSystemConfigLocator.EP_NAME.getExtensions()) {
- if (externalSystemId.equals(locator.getTargetExternalSystemId())) {
- toOpen = locator.adjust(toOpen);
- if (toOpen == null) {
- return null;
- }
- }
+ protected void perform(@NotNull Project project,
+ @NotNull ProjectSystemId systemId,
+ @NotNull ExternalConfigPathAware configPathAware,
+ @NotNull AnActionEvent e) {
+ VirtualFile configFile = getExternalConfig(configPathAware, systemId);
+ if (configFile != null) {
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(project, configFile);
+ FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
- return toOpen.isDirectory() ? null : toOpen;
}
}
package com.intellij.openapi.externalSystem.action;
-import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
+import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
-import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.ProjectNode;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
+import java.util.List;
/**
* * Forces the ide to retrieve the most up-to-date info about the linked external project and updates project state if necessary
* @author Vladislav.Soroka
* @since 9/18/13
*/
-public class RefreshExternalProjectAction extends AnAction implements DumbAware, AnAction.TransparentUpdate {
+public class RefreshExternalProjectAction extends ExternalSystemNodeAction<AbstractExternalEntityData> implements DumbAware {
public RefreshExternalProjectAction() {
+ super(AbstractExternalEntityData.class);
getTemplatePresentation().setText(ExternalSystemBundle.message("action.refresh.project.text", "external"));
getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.refresh.project.description", "external"));
}
@Override
- public void update(AnActionEvent e) {
- ExternalActionUtil.MyInfo info = ExternalActionUtil.getProcessingInfo(e.getDataContext());
- e.getPresentation().setEnabled(info.externalProject != null);
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1) return false;
+ final Object externalData = selectedNodes.get(0).getData();
+ return (externalData instanceof ProjectData || externalData instanceof ModuleData);
}
@Override
- public void actionPerformed(AnActionEvent e) {
- ExternalActionUtil.MyInfo info = ExternalActionUtil.getProcessingInfo(e.getDataContext());
- if (info.settings == null || info.localSettings == null || info.externalProject == null || info.ideProject == null
- || info.externalSystemId == null)
- {
- return;
- }
- ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
- if (externalSystemId == null) {
- return;
- }
-
- final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
- if (project == null) {
- e.getPresentation().setEnabled(false);
- return;
- }
+ public void perform(@NotNull final Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull AbstractExternalEntityData externalEntityData,
+ @NotNull AnActionEvent e) {
+
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ final ExternalSystemNode<?> externalSystemNode = ContainerUtil.getFirstItem(selectedNodes);
+ assert externalSystemNode != null;
+
+ final ExternalConfigPathAware externalConfigPathAware =
+ externalSystemNode.getData() instanceof ExternalConfigPathAware ? (ExternalConfigPathAware)externalSystemNode.getData() : null;
+ assert externalConfigPathAware != null;
// We save all documents because there is a possible case that there is an external system config file changed inside the ide.
FileDocumentManager.getInstance().saveAllDocuments();
final ProjectDataManager projectDataManager = ServiceManager.getService(ProjectDataManager.class);
ExternalSystemUtil.refreshProject(
- project, externalSystemId, info.externalProject.getPath(),
+ project, projectSystemId, externalConfigPathAware.getLinkedExternalProjectPath(),
new ExternalProjectRefreshCallback() {
@Override
public void onSuccess(@Nullable final DataNode<ProjectData> externalProject) {
--- /dev/null
+/*
+ * Copyright 2000-2014 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.execution.RunManager;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/13/2014
+ */
+public class RemoveExternalSystemRunConfigurationAction extends ExternalSystemAction {
+
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1) return false;
+ return selectedNodes.get(0) instanceof RunConfigurationNode;
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Project project = getProject(e);
+ assert project != null;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1 || !(selectedNodes.get(0) instanceof RunConfigurationNode)) return;
+
+ RunnerAndConfigurationSettings settings = ((RunConfigurationNode)selectedNodes.get(0)).getSettings();
+ assert settings != null;
+
+ int res = Messages.showYesNoDialog(project, "Delete \"" + settings.getName() + "\"?", "Confirmation", Messages.getQuestionIcon());
+ if (res == Messages.YES) {
+ ((RunManagerEx)RunManager.getInstance(project)).removeConfiguration(settings);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public class ShowExternalSystemSettingsAction extends ExternalSystemAction {
+
+ public ShowExternalSystemSettingsAction() {
+ getTemplatePresentation().setText(ExternalSystemBundle.message("action.open.settings.text", "external"));
+ getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.open.settings.description", "external"));
+ }
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+
+ ProjectSystemId systemId = getSystemId(e);
+ if (systemId == null) return false;
+
+ e.getPresentation().setText(ExternalSystemBundle.message("action.open.settings.text", systemId.getReadableName()));
+ e.getPresentation().setDescription(ExternalSystemBundle.message("action.open.settings.description", systemId.getReadableName()));
+ return true;
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final ProjectSystemId systemId = getSystemId(e);
+ if (systemId != null) {
+ showSettingsFor(getProject(e), systemId);
+ }
+ }
+
+ protected static void showSettingsFor(Project project, @NotNull ProjectSystemId systemId) {
+ ShowSettingsUtil.getInstance().showSettingsDialog(project, systemId.getReadableName());
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+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.view.ProjectNode;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public class ToggleAutoImportAction extends ExternalSystemToggleAction {
+
+ public ToggleAutoImportAction() {
+ getTemplatePresentation().setText(ExternalSystemBundle.message("action.refresh.project.auto.text"));
+ getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.refresh.project.auto.description"));
+ }
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ if (getSystemId(e) == null) return false;
+
+ return ExternalSystemDataKeys.SELECTED_PROJECT_NODE.getData(e.getDataContext()) != null;
+ }
+
+ @Override
+ protected boolean isVisible(AnActionEvent e) {
+ if (!super.isVisible(e)) return false;
+ if (getSystemId(e) == null) return false;
+
+ return ExternalSystemDataKeys.SELECTED_PROJECT_NODE.getData(e.getDataContext()) != null;
+ }
+
+ @Override
+ protected boolean doIsSelected(AnActionEvent e) {
+ final ExternalProjectSettings projectSettings = getProjectSettings(e);
+
+ return projectSettings != null && projectSettings.isUseAutoImport();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ final ExternalProjectSettings projectSettings = getProjectSettings(e);
+ if (projectSettings != null) {
+ if (state != projectSettings.isUseAutoImport()) {
+ projectSettings.setUseAutoImport(state);
+ ExternalSystemApiUtil.getSettings(getProject(e), getSystemId(e)).getPublisher()
+ .onUseAutoImportChange(state, projectSettings.getExternalProjectPath());
+ }
+ }
+ }
+
+ @Nullable
+ private ExternalProjectSettings getProjectSettings(AnActionEvent e) {
+ final ProjectNode projectNode = ExternalSystemDataKeys.SELECTED_PROJECT_NODE.getData(e.getDataContext());
+ if (projectNode == null || projectNode.getData() == null) return null;
+ final AbstractExternalSystemSettings externalSystemSettings = ExternalSystemApiUtil.getSettings(getProject(e), getSystemId(e));
+ return externalSystemSettings.getLinkedProjectSettings(projectNode.getData().getLinkedExternalProjectPath());
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.action.ExternalSystemAction;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
+import com.intellij.openapi.keymap.impl.ui.EditKeymapsDialog;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+import static com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemKeymapExtension.getActionPrefix;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/28/2014
+ */
+public class AssignRunConfigurationShortcutAction extends ExternalSystemAction {
+
+ protected boolean isEnabled(AnActionEvent e) {
+ if (!super.isEnabled(e)) return false;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1) return false;
+ return selectedNodes.get(0) instanceof RunConfigurationNode;
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Project project = getProject(e);
+ assert project != null;
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null || selectedNodes.size() != 1 || !(selectedNodes.get(0) instanceof RunConfigurationNode)) return;
+
+ RunnerAndConfigurationSettings settings = ((RunConfigurationNode)selectedNodes.get(0)).getSettings();
+ assert settings != null;
+
+ ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)settings.getConfiguration();
+ String actionIdPrefix = getActionPrefix(project, runConfiguration.getSettings().getExternalProjectPath());
+ String actionId = actionIdPrefix + settings.getName();
+ if (ActionManager.getInstance().getAction(actionId) != null) {
+ new EditKeymapsDialog(project, actionId).show();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.action.ExternalSystemNodeAction;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemShortcutsManager;
+import com.intellij.openapi.keymap.impl.ui.EditKeymapsDialog;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/28/2014
+ */
+public class AssignShortcutAction extends ExternalSystemNodeAction<TaskData> {
+
+ public AssignShortcutAction() {
+ super(TaskData.class);
+ }
+
+ @Override
+ protected void perform(@NotNull Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull TaskData taskData,
+ @NotNull AnActionEvent e) {
+ final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManager.getInstance(project).getShortcutsManager();
+ String actionId = shortcutsManager.getActionId(taskData.getLinkedExternalProjectPath(), taskData.getName());
+ if (actionId != null) {
+ new EditKeymapsDialog(project, actionId).show();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.action.ExternalSystemViewGearAction;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/31/2014
+ */
+public class GroupTasksAction extends ExternalSystemViewGearAction {
+ @Override
+ protected boolean isSelected(@NotNull ExternalProjectsView view) {
+ return view.getGroupTasks();
+ }
+
+ @Override
+ protected void setSelected(@NotNull ExternalProjectsView view, boolean value) {
+ view.setGroupTasks(value);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.externalSystem.action.ExternalSystemActionUtil;
+import com.intellij.openapi.externalSystem.action.ExternalSystemNodeAction;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/27/2014
+ */
+public class RunExternalSystemTaskAction extends ExternalSystemNodeAction<TaskData> {
+
+ public RunExternalSystemTaskAction() {
+ super(TaskData.class);
+ }
+
+ @Override
+ protected void perform(@NotNull Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull TaskData taskData,
+ @NotNull AnActionEvent e) {
+ final ExternalTaskExecutionInfo taskExecutionInfo = ExternalSystemActionUtil.buildTaskInfo(taskData);
+ ExternalSystemUtil.runTask(taskExecutionInfo.getSettings(), taskExecutionInfo.getExecutorId(), project, projectSystemId);
+
+ final DataContext dataContext = e.getDataContext();
+ final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext);
+ RunnerAndConfigurationSettings configuration = context.findExisting();
+ RunManagerEx runManager = (RunManagerEx)context.getRunManager();
+ if (configuration == null) {
+ configuration = context.getConfiguration();
+ if (configuration == null) {
+ return;
+ }
+ runManager.setTemporaryConfiguration(configuration);
+ }
+ runManager.setSelectedConfiguration(configuration);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleAfterCompileTasksAction extends ToggleTaskActivationAction {
+ protected ToggleAfterCompileTasksAction() {
+ super(ExternalSystemTaskActivator.Phase.AFTER_COMPILE);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleAfterRebuildTasksAction extends ToggleTaskActivationAction {
+ protected ToggleAfterRebuildTasksAction() {
+ super(ExternalSystemTaskActivator.Phase.AFTER_REBUILD);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleAfterSyncTaskAction extends ToggleTaskActivationAction {
+ protected ToggleAfterSyncTaskAction() {
+ super(ExternalSystemTaskActivator.Phase.AFTER_SYNC);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleBeforeCompileTasksAction extends ToggleTaskActivationAction {
+ protected ToggleBeforeCompileTasksAction() {
+ super(ExternalSystemTaskActivator.Phase.BEFORE_COMPILE);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleBeforeRebuildTasksAction extends ToggleTaskActivationAction {
+ protected ToggleBeforeRebuildTasksAction() {
+ super(ExternalSystemTaskActivator.Phase.BEFORE_REBUILD);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/29/2014
+ */
+public class ToggleBeforeRunTaskAction extends ToggleTaskActivationAction {
+ protected ToggleBeforeRunTaskAction() {
+ super(null);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.task;
+
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.action.ExternalSystemToggleAction;
+import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
+import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
+import com.intellij.openapi.externalSystem.view.TaskNode;
+import com.intellij.util.SmartList;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+import static com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator.RUN_CONFIGURATION_TASK_PREFIX;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/28/2014
+ */
+public abstract class ToggleTaskActivationAction extends ExternalSystemToggleAction {
+
+ private final ExternalSystemTaskActivator.Phase myPhase;
+
+ protected ToggleTaskActivationAction(ExternalSystemTaskActivator.Phase phase) {
+ myPhase = phase;
+ }
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ return super.isEnabled(e) && !getTasks(e).isEmpty();
+ }
+
+ @Override
+ protected boolean doIsSelected(AnActionEvent e) {
+ return hasTask(getTaskActivator(e), getTasks(e).get(0));
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ List<TaskData> tasks = getTasks(e);
+ if (state) {
+ addTasks(getTaskActivator(e), tasks);
+ }
+ else {
+ removeTasks(getTaskActivator(e), tasks);
+ }
+ }
+
+ @NotNull
+ private static List<TaskData> getTasks(AnActionEvent e) {
+ final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext());
+ if (selectedNodes == null) return Collections.emptyList();
+
+ List<TaskData> tasks = new SmartList<TaskData>();
+ for (ExternalSystemNode node : selectedNodes) {
+ if (node instanceof TaskNode) {
+ tasks.add((TaskData)node.getData());
+ }
+ else if (node instanceof RunConfigurationNode) {
+ final RunnerAndConfigurationSettings configurationSettings = ((RunConfigurationNode)node).getSettings();
+ final ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)configurationSettings.getConfiguration();
+ final ExternalSystemTaskExecutionSettings taskExecutionSettings = runConfiguration.getSettings();
+ tasks.add(new TaskData(taskExecutionSettings.getExternalSystemId(), RUN_CONFIGURATION_TASK_PREFIX + configurationSettings.getName(),
+ taskExecutionSettings.getExternalProjectPath(), null));
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+ return tasks;
+ }
+
+ protected boolean hasTask(ExternalSystemTaskActivator manager, TaskData taskData) {
+ if (taskData == null) return false;
+ return manager.isTaskOfPhase(taskData, myPhase);
+ }
+
+ private void addTasks(ExternalSystemTaskActivator taskActivator, List<TaskData> tasks) {
+ taskActivator.addTasks(tasks, myPhase);
+ }
+
+ private void removeTasks(ExternalSystemTaskActivator taskActivator, List<TaskData> tasks) {
+ taskActivator.removeTasks(tasks, myPhase);
+ }
+
+
+ private ExternalSystemTaskActivator getTaskActivator(AnActionEvent e) {
+ return ExternalProjectsManager.getInstance(getProject(e)).getTaskActivator();
+ }
+}
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 com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
+import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
+import com.intellij.openapi.externalSystem.view.ProjectNode;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
+import java.util.List;
+
/**
* @author Denis Zhdanov
* @since 2/7/12 11:19 AM
*/
public class ExternalSystemDataKeys {
- @NotNull public static final DataKey<ProjectSystemId> EXTERNAL_SYSTEM_ID = DataKey.create("external.system.id");
- @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");
+ @NotNull public static final DataKey<ProjectSystemId> EXTERNAL_SYSTEM_ID = DataKey.create("external.system.id");
+ @NotNull public static final DataKey<NotificationGroup> NOTIFICATION_GROUP = DataKey.create("external.system.notification");
+ @NotNull public static final DataKey<ExternalProjectsView> VIEW = DataKey.create("external.system.view");
+ @NotNull public static final DataKey<ProjectNode> SELECTED_PROJECT_NODE = DataKey.create("external.system.selected.project.node");
+ @NotNull public static final DataKey<List<ExternalSystemNode>> SELECTED_NODES = DataKey.create("external.system.selected.nodes");
+ @NotNull public static final DataKey<ExternalSystemUiAware> UI_AWARE = DataKey.create("external.system.ui.aware");
+ @NotNull public static final DataKey<JTree> PROJECTS_TREE = DataKey.create("external.system.tree");
@NotNull public static final Key<Boolean> NEWLY_IMPORTED_PROJECT = new Key<Boolean>("external.system.newly.imported");
@NotNull public static final Key<Boolean> NEWLY_CREATED_PROJECT = new Key<Boolean>("external.system.newly.created");
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.service.project.ProjectRenameAware;
import com.intellij.openapi.externalSystem.service.project.autoimport.ExternalSystemAutoImporter;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
import com.intellij.openapi.externalSystem.service.ui.ExternalToolWindowManager;
import com.intellij.openapi.externalSystem.service.vcs.ExternalSystemVcsRegistrar;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@SuppressWarnings("unchecked")
@Override
public void run() {
+ ExternalProjectsManager.getInstance(project).init();
+
for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) {
if (manager instanceof StartupActivity) {
((StartupActivity)manager).runActivity(project);
}
if (project.getUserData(ExternalSystemDataKeys.NEWLY_IMPORTED_PROJECT) != Boolean.TRUE) {
for (ExternalSystemManager manager : ExternalSystemManager.EP_NAME.getExtensions()) {
- if (project.getUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT) == Boolean.TRUE) {
+ final boolean isNewProject = project.getUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT) == Boolean.TRUE;
+ if (isNewProject) {
ExternalSystemUtil.refreshProjects(
new ImportSpecBuilder(project, manager.getSystemId())
);
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
-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.ExternalSystemUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.io.File;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
/**
* Basic run configuration type for external system tasks.
@Nullable String externalProjectPath,
@NotNull List<String> taskNames,
@Nullable String executionName) {
- ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
- assert manager != null;
- AbstractExternalSystemSettings<?, ?,?> s = manager.getSettingsProvider().fun(project);
- Map<String/* project dir path */, String/* project file path */> rootProjectPaths = ContainerUtilRt.newHashMap();
- for (ExternalProjectSettings projectSettings : s.getLinkedProjectsSettings()) {
- String path = projectSettings.getExternalProjectPath();
- if(path == null) continue;
- final File rootProjectPathFile = new File(path).getParentFile();
- if(rootProjectPathFile == null) continue;
- rootProjectPaths.put(rootProjectPathFile.getAbsolutePath(), path);
- }
-
+
String rootProjectPath = null;
if (externalProjectPath != null) {
- if (!rootProjectPaths.containsKey(externalProjectPath)) {
- for (File f = new File(externalProjectPath), prev = null;
- f != null && !FileUtil.filesEqual(f, prev);
- prev = f, f = f.getParentFile())
- {
- rootProjectPath = rootProjectPaths.get(f.getAbsolutePath());
- if (rootProjectPath != null) {
- break;
- }
- }
+ final ExternalProjectInfo projectInfo = ExternalSystemUtil.getExternalProjectInfo(project, externalSystemId, externalProjectPath);
+ if (projectInfo != null) {
+ rootProjectPath = projectInfo.getExternalProjectPath();
}
}
-
+
StringBuilder buffer = new StringBuilder();
-
final String projectName;
if (rootProjectPath == null) {
projectName = null;
}
if (!StringUtil.isEmptyOrSpaces(projectName)) {
buffer.append(projectName);
- buffer.append(" ");
+ buffer.append(' ');
} else {
buffer.append(externalProjectPath);
- buffer.append(" ");
+ buffer.append(' ');
}
- buffer.append("[");
+ buffer.append('[');
if (!StringUtil.isEmpty(executionName)) {
buffer.append(executionName);
}
else if (!taskNames.isEmpty()) {
for (String taskName : taskNames) {
- buffer.append(taskName).append(" ");
+ buffer.append(taskName).append(' ');
}
buffer.setLength(buffer.length() - 1);
}
-
- buffer.append("]");
+ buffer.append(']');
return buffer.toString();
}
package com.intellij.openapi.externalSystem.service.project;
-import com.intellij.openapi.externalSystem.model.project.LibraryData;
-import com.intellij.openapi.externalSystem.model.project.ModuleData;
-import com.intellij.openapi.externalSystem.model.project.ModuleDependencyData;
+import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
-import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
}
return null;
}
+
+ @Nullable
+ public OrderEntry findIdeModuleOrderEntry(LibraryDependencyData data, Project project) {
+ Module ownerIdeModule = findIdeModule(data.getOwnerModule(), project);
+ if (ownerIdeModule == null) return null;
+
+ ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(ownerIdeModule);
+
+ for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
+ if (entry instanceof LibraryOrderEntry) {
+ if (((LibraryOrderEntry)entry).isModuleLevel() && data.getLevel() != LibraryLevel.MODULE) continue;
+ }
+
+ if (data.getInternalName().equals(entry.getPresentableName())) {
+ return entry;
+ }
+ }
+ return null;
+ }
}
*/
package com.intellij.openapi.externalSystem.service.project.manage;
+import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.SettingsSavingComponent;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.internal.InternalExternalProjectInfo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.module.ModuleTypeId;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.Consumer;
+import com.intellij.util.Function;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.*;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Vladislav.Soroka
public class ExternalProjectsDataStorage implements SettingsSavingComponent {
private static final Logger LOG = Logger.getInstance(ExternalProjectsDataStorage.class);
+ private static final String STORAGE_VERSION = ExternalProjectsDataStorage.class.getSimpleName() + ".1";
+
@NotNull
private final Project myProject;
@NotNull
- private final Map<Pair<ProjectSystemId, String>, InternalExternalProjectInfo> myExternalRootProjects =
- ContainerUtil.newConcurrentMap();
+ private final Map<Pair<ProjectSystemId, String>, InternalExternalProjectInfo> myExternalRootProjects = ContainerUtil.newConcurrentMap();
+
+ private final AtomicBoolean changed = new AtomicBoolean();
public static ExternalProjectsDataStorage getInstance(@NotNull Project project) {
return ServiceManager.getService(project, ExternalProjectsDataStorage.class);
myProject = project;
}
- public void load() {
- // TODO [Vlad] load data for the opened project
+ public synchronized void load() {
+ myExternalRootProjects.clear();
+ try {
+ final Collection<InternalExternalProjectInfo> projectInfos = load(myProject);
+ for (InternalExternalProjectInfo projectInfo : projectInfos) {
+ if (validate(projectInfo)) {
+ myExternalRootProjects.put(Pair.create(projectInfo.getProjectSystemId(), projectInfo.getExternalProjectPath()), projectInfo);
+ }
+ }
+ }
+ catch (IOException e) {
+ LOG.debug(e);
+ }
+
+ mergeLocalSettings();
+ }
+
+ private static boolean validate(InternalExternalProjectInfo externalProjectInfo) {
+ try {
+ final DataNode<ProjectData> projectStructure = externalProjectInfo.getExternalProjectStructure();
+ if (projectStructure == null) return false;
+
+ ProjectDataManager.getInstance().ensureTheDataIsReadyToUse(projectStructure);
+ return externalProjectInfo.getExternalProjectPath().equals(projectStructure.getData().getLinkedExternalProjectPath());
+ }
+ catch (Exception e) {
+ LOG.warn(e);
+ }
+ return false;
}
@Override
- public void save() {
- // TODO [Vlad] save data if changed
+ public synchronized void save() {
+ if (!changed.compareAndSet(true, false)) return;
+
+ try {
+ doSave(myProject, myExternalRootProjects.values());
+ }
+ catch (IOException e) {
+ LOG.debug(e);
+ }
}
- void add(@NotNull ExternalProjectInfo externalProjectInfo) {
+ synchronized void update(@NotNull ExternalProjectInfo externalProjectInfo) {
final ProjectSystemId projectSystemId = externalProjectInfo.getProjectSystemId();
final String projectPath = externalProjectInfo.getExternalProjectPath();
DataNode<ProjectData> externalProjectStructure = externalProjectInfo.getExternalProjectStructure();
merged.setLastImportTimestamp(lastImportTimestamp);
merged.setLastSuccessfulImportTimestamp(lastSuccessfulImportTimestamp);
myExternalRootProjects.put(key, merged);
+
+ changed.set(true);
}
@Nullable
- ExternalProjectInfo get(@NotNull ProjectSystemId projectSystemId, @NotNull String externalProjectPath) {
+ synchronized ExternalProjectInfo get(@NotNull ProjectSystemId projectSystemId, @NotNull String externalProjectPath) {
return myExternalRootProjects.get(Pair.create(projectSystemId, externalProjectPath));
}
+
+ synchronized void remove(@NotNull ProjectSystemId projectSystemId, @NotNull String externalProjectPath) {
+ final InternalExternalProjectInfo removed = myExternalRootProjects.remove(Pair.create(projectSystemId, externalProjectPath));
+ if(removed != null) {
+ changed.set(true);
+ }
+ }
+
+ @NotNull
+ synchronized Collection<ExternalProjectInfo> list(@NotNull final ProjectSystemId projectSystemId) {
+ return ContainerUtil.mapNotNull(myExternalRootProjects.values(), new Function<InternalExternalProjectInfo, ExternalProjectInfo>() {
+ @Override
+ public ExternalProjectInfo fun(InternalExternalProjectInfo info) {
+ return projectSystemId.equals(info.getProjectSystemId()) ? info : null;
+ }
+ });
+ }
+
+ private void mergeLocalSettings() {
+ for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) {
+ final ProjectSystemId systemId = manager.getSystemId();
+
+ AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(myProject);
+ final Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> availableProjects = settings.getAvailableProjects();
+ final Map<String, Collection<ExternalTaskPojo>> availableTasks = settings.getAvailableTasks();
+
+ for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : availableProjects.entrySet()) {
+ final ExternalProjectPojo projectPojo = entry.getKey();
+ final String externalProjectPath = projectPojo.getPath();
+ final Pair<ProjectSystemId, String> key = Pair.create(systemId, externalProjectPath);
+ InternalExternalProjectInfo externalProjectInfo = myExternalRootProjects.get(key);
+ if (externalProjectInfo == null) {
+ final DataNode<ProjectData> dataNode = convert(systemId, projectPojo, entry.getValue(), availableTasks);
+ externalProjectInfo = new InternalExternalProjectInfo(systemId, externalProjectPath, dataNode);
+ myExternalRootProjects.put(key, externalProjectInfo);
+
+ changed.set(true);
+ }
+ }
+ }
+ }
+
+ private static DataNode<ProjectData> convert(@NotNull ProjectSystemId systemId,
+ @NotNull ExternalProjectPojo rootProject,
+ @NotNull Collection<ExternalProjectPojo> childProjects,
+ @NotNull Map<String, Collection<ExternalTaskPojo>> availableTasks) {
+ ProjectData projectData = new ProjectData(systemId, rootProject.getName(), rootProject.getPath(), rootProject.getPath());
+ DataNode<ProjectData> projectDataNode = new DataNode<ProjectData>(ProjectKeys.PROJECT, projectData, null);
+
+ for (ExternalProjectPojo childProject : childProjects) {
+ String moduleConfigPath = childProject.getPath();
+ ModuleData moduleData = new ModuleData(childProject.getName(), systemId,
+ ModuleTypeId.JAVA_MODULE, childProject.getName(),
+ moduleConfigPath, moduleConfigPath);
+ final DataNode<ModuleData> moduleDataNode = projectDataNode.createChild(ProjectKeys.MODULE, moduleData);
+
+ final Collection<ExternalTaskPojo> moduleTasks = availableTasks.get(moduleConfigPath);
+ if (moduleTasks != null) {
+ for (ExternalTaskPojo moduleTask : moduleTasks) {
+ TaskData taskData = new TaskData(systemId, moduleTask.getName(), moduleConfigPath, moduleTask.getDescription());
+ moduleDataNode.createChild(ProjectKeys.TASK, taskData);
+ }
+ }
+ }
+
+ return projectDataNode;
+ }
+
+ private static void doSave(@NotNull Project project, @NotNull Collection<InternalExternalProjectInfo> externalProjects) throws IOException {
+ final File projectConfigurationFile = getProjectConfigurationFile(project);
+ if (!FileUtil.createParentDirs(projectConfigurationFile)) {
+ throw new IOException("Unable to save " + projectConfigurationFile);
+ }
+
+ for (Iterator<InternalExternalProjectInfo> iterator = externalProjects.iterator(); iterator.hasNext(); ) {
+ InternalExternalProjectInfo externalProject = iterator.next();
+ if (!validate(externalProject)) {
+ iterator.remove();
+ continue;
+ }
+
+ ExternalSystemApiUtil.visit(externalProject.getExternalProjectStructure(), new Consumer<DataNode>() {
+ @Override
+ public void consume(DataNode dataNode) {
+ try {
+ dataNode.getDataBytes();
+ }
+ catch (IOException e) {
+ dataNode.clear(true);
+ }
+ }
+ });
+ }
+
+ DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(projectConfigurationFile)));
+ try {
+ out.writeUTF(STORAGE_VERSION);
+ out.writeInt(externalProjects.size());
+ ObjectOutputStream os = new ObjectOutputStream(out);
+ try {
+ for (InternalExternalProjectInfo externalProject : externalProjects) {
+ os.writeObject(externalProject);
+ }
+ }
+ finally {
+ os.close();
+ }
+ }
+ finally {
+ out.close();
+ }
+ }
+
+ @NotNull
+ private static Collection<InternalExternalProjectInfo> load(@NotNull Project project) throws IOException {
+ SmartList<InternalExternalProjectInfo> projects = new SmartList<InternalExternalProjectInfo>();
+ final File configurationFile = getProjectConfigurationFile(project);
+ if (!configurationFile.isFile()) return projects;
+
+ DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(configurationFile)));
+
+ try {
+ final String storage_version = in.readUTF();
+ if (!STORAGE_VERSION.equals(storage_version)) return projects;
+ final int size = in.readInt();
+
+ ObjectInputStream os = new ObjectInputStream(in);
+ try {
+ for (int i = 0; i < size; i++) {
+ //noinspection unchecked
+ InternalExternalProjectInfo projectDataDataNode = (InternalExternalProjectInfo)os.readObject();
+ projects.add(projectDataDataNode);
+ }
+ }
+ catch (ClassNotFoundException e) {
+ IOException ioException = new IOException();
+ ioException.initCause(e);
+ throw ioException;
+ }
+ finally {
+ os.close();
+ }
+ }
+ finally {
+ in.close();
+ }
+ return projects;
+ }
+
+ private static File getProjectConfigurationFile(@NotNull Project project) {
+ return new File(getProjectConfigurationDir(), project.getLocationHash() + "/project.dat");
+ }
+
+ private static File getProjectConfigurationDir() {
+ return getExternalBuildSystemDir("Projects");
+ }
+
+ private static File getExternalBuildSystemDir(String folder) {
+ return new File(PathManager.getSystemPath(), "external_build_system" + "/" + folder).getAbsoluteFile();
+ }
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsViewState;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.Function;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.intellij.openapi.externalSystem.model.ProjectKeys.TASK;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/23/2014
+ */
+@State(name = "ExternalProjectsManager", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)})
+public class ExternalProjectsManager implements PersistentStateComponent<ExternalProjectsState>, Disposable {
+
+ private final AtomicBoolean isInitialized = new AtomicBoolean();
+ @NotNull
+ private ExternalProjectsState myState = new ExternalProjectsState();
+
+ @NotNull
+ private final Project myProject;
+ private final ExternalSystemRunManagerListener myRunManagerListener;
+ private final ExternalSystemTaskActivator myTaskActivator;
+ private final ExternalSystemShortcutsManager myShortcutsManager;
+ private final List<ExternalProjectsView> myProjectsViews = new SmartList<ExternalProjectsView>();
+
+
+ public static ExternalProjectsManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, ExternalProjectsManager.class);
+ }
+
+ public ExternalProjectsManager(@NotNull Project project) {
+ myProject = project;
+ Disposer.register(project, this);
+ myShortcutsManager = new ExternalSystemShortcutsManager(project);
+ Disposer.register(this, myShortcutsManager);
+ myTaskActivator = new ExternalSystemTaskActivator(project);
+ myRunManagerListener = new ExternalSystemRunManagerListener(this);
+ }
+
+ @NotNull
+ public Project getProject() {
+ return myProject;
+ }
+
+ public ExternalSystemShortcutsManager getShortcutsManager() {
+ return myShortcutsManager;
+ }
+
+ public ExternalSystemTaskActivator getTaskActivator() {
+ return myTaskActivator;
+ }
+
+ public void registerView(@NotNull ExternalProjectsView externalProjectsView) {
+ init();
+ myProjectsViews.add(externalProjectsView);
+ externalProjectsView.loadState(
+ myState.getExternalSystemsState().get(externalProjectsView.getSystemId().getId()).getProjectsViewState());
+ externalProjectsView.init();
+ }
+
+ @Nullable
+ public ExternalProjectsView getExternalProjectsView(@NotNull ProjectSystemId systemId) {
+ for (ExternalProjectsView projectsView : myProjectsViews) {
+ if(projectsView.getSystemId().equals(systemId)) return projectsView;
+ }
+ return null;
+ }
+
+ public void init() {
+ synchronized (isInitialized) {
+ if (isInitialized.getAndSet(true)) return;
+
+ // load external projects data
+ ExternalProjectsDataStorage.getInstance(myProject).load();
+ myRunManagerListener.attach();
+
+ // init shortcuts manager
+ myShortcutsManager.init();
+ for (ExternalSystemManager<?, ?, ?, ?, ?> systemManager : ExternalSystemApiUtil.getAllManagers()) {
+ final Collection<ExternalProjectInfo> externalProjects =
+ ExternalProjectsDataStorage.getInstance(myProject).list(systemManager.getSystemId());
+ for (ExternalProjectInfo externalProject : externalProjects) {
+ if (externalProject.getExternalProjectStructure() == null) continue;
+ Collection<DataNode<TaskData>> taskData =
+ ExternalSystemApiUtil.findAllRecursively(externalProject.getExternalProjectStructure(), TASK);
+ myShortcutsManager.scheduleKeymapUpdate(taskData);
+ }
+
+ if (!externalProjects.isEmpty()) {
+ myShortcutsManager.scheduleRunConfigurationKeymapUpdate(systemManager.getSystemId());
+ }
+ }
+ // init task activation info
+ myTaskActivator.init();
+ }
+ }
+
+ public void updateExternalProjectData(ExternalProjectInfo externalProject) {
+ // update external projects data
+ ExternalProjectsDataStorage.getInstance(myProject).update(externalProject);
+
+ // update shortcuts manager
+ if (externalProject.getExternalProjectStructure() != null) {
+ final ProjectData projectData = externalProject.getExternalProjectStructure().getData();
+
+ ExternalSystemUtil.scheduleExternalViewStructureUpdate(myProject, projectData.getOwner());
+
+ Collection<DataNode<TaskData>> taskData =
+ ExternalSystemApiUtil.findAllRecursively(externalProject.getExternalProjectStructure(), TASK);
+ myShortcutsManager.scheduleKeymapUpdate(taskData);
+ myShortcutsManager.scheduleRunConfigurationKeymapUpdate(projectData.getOwner());
+ }
+ }
+
+ public void forgetExternalProjectData(@NotNull ProjectSystemId projectSystemId, @NotNull String linkedProjectPath) {
+ ExternalProjectsDataStorage.getInstance(myProject).remove(projectSystemId, linkedProjectPath);
+ }
+
+ @NotNull
+ @Override
+ public ExternalProjectsState getState() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ for (ExternalProjectsView externalProjectsView : myProjectsViews) {
+ final ExternalProjectsViewState externalProjectsViewState = externalProjectsView.getState();
+ final ExternalProjectsState.State state = myState.getExternalSystemsState().get(externalProjectsView.getSystemId().getId());
+ assert state != null;
+ state.setProjectsViewState(externalProjectsViewState);
+ }
+ return myState;
+ }
+
+ @NotNull
+ public ExternalProjectsStateProvider getStateProvider() {
+ return new ExternalProjectsStateProvider() {
+ @Override
+ public List<TasksActivation> getAllTasksActivation() {
+ List<TasksActivation> result = new SmartList<TasksActivation>();
+ for (Map.Entry<String, ExternalProjectsState.State> systemState : myState.getExternalSystemsState().entrySet()) {
+ ProjectSystemId systemId = new ProjectSystemId(systemState.getKey());
+ for (Map.Entry<String, TaskActivationState> activationStateEntry : systemState.getValue().getExternalSystemsTaskActivation()
+ .entrySet()) {
+ result.add(new TasksActivation(systemId, activationStateEntry.getKey(), activationStateEntry.getValue()));
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<TasksActivation> getTasksActivation(@NotNull final ProjectSystemId systemId) {
+ final Set<Map.Entry<String, TaskActivationState>> entries =
+ myState.getExternalSystemsState().get(systemId.getId()).getExternalSystemsTaskActivation().entrySet();
+ return ContainerUtil.map(entries, new Function<Map.Entry<String, TaskActivationState>, TasksActivation>() {
+ @Override
+ public TasksActivation fun(Map.Entry<String, TaskActivationState> entry) {
+ return new TasksActivation(systemId, entry.getKey(), entry.getValue());
+ }
+ });
+ }
+
+ @Override
+ public TaskActivationState getTasksActivation(@NotNull ProjectSystemId systemId, @NotNull String projectPath) {
+ return myState.getExternalSystemsState().get(systemId.getId()).getExternalSystemsTaskActivation().get(projectPath);
+ }
+ };
+ }
+
+ @Override
+ public void loadState(ExternalProjectsState state) {
+ myState = state == null ? new ExternalProjectsState() : state;
+ }
+
+ @Override
+ public void dispose() {
+ myProjectsViews.clear();
+ myRunManagerListener.detach();
+ }
+
+ public interface ExternalProjectsStateProvider {
+ class TasksActivation {
+ public final ProjectSystemId systemId;
+ public final String projectPath;
+ public final TaskActivationState state;
+
+ public TasksActivation(ProjectSystemId systemId,
+ String projectPath,
+ TaskActivationState state) {
+ this.systemId = systemId;
+ this.projectPath = projectPath;
+ this.state = state;
+ }
+ }
+
+ List<TasksActivation> getAllTasksActivation();
+
+ List<TasksActivation> getTasksActivation(@NotNull ProjectSystemId systemId);
+
+ TaskActivationState getTasksActivation(@NotNull ProjectSystemId systemId, @NotNull String projectPath);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.openapi.externalSystem.view.ExternalProjectsViewState;
+import com.intellij.util.containers.FactoryMap;
+import com.intellij.util.xmlb.annotations.MapAnnotation;
+import com.intellij.util.xmlb.annotations.Property;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/23/2014
+ */
+public class ExternalProjectsState {
+
+
+ private final Map<String, State> myExternalSystemsState = new NullSafeMap<String, State>() {
+ @Nullable
+ @Override
+ protected State create(String key) {
+ return new State();
+ }
+ };
+
+ @Property(surroundWithTag = false)
+ @MapAnnotation(surroundWithTag = false, surroundValueWithTag = false, surroundKeyWithTag = false,
+ keyAttributeName = "id", entryTagName = "system")
+ public Map<String, State> getExternalSystemsState() {
+ return myExternalSystemsState;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setExternalSystemsState(Map<String, State> externalSystemsState) {
+ }
+
+
+ @Tag("state")
+ public static class State {
+ private ExternalProjectsViewState projectsViewState = new ExternalProjectsViewState();
+
+ private final Map<String, TaskActivationState> myExternalSystemsTaskActivation = new FactoryMap<String, TaskActivationState>() {
+ @Nullable
+ @Override
+ protected TaskActivationState create(String key) {
+ return new TaskActivationState();
+ }
+
+ @Override
+ public TaskActivationState put(String key, TaskActivationState value) {
+ if(value == null) return null;
+ return super.put(key, value);
+ }
+ };
+
+ @Property(surroundWithTag = false)
+ @MapAnnotation(surroundWithTag = false, surroundValueWithTag = false, surroundKeyWithTag = false,
+ keyAttributeName = "path", entryTagName = "task", sortBeforeSave = false)
+ public Map<String, TaskActivationState> getExternalSystemsTaskActivation() {
+ return myExternalSystemsTaskActivation;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setExternalSystemsTaskActivation(Map<String, TaskActivationState> externalSystemsTaskActivation) {
+ }
+
+ @Property(surroundWithTag = false)
+ public ExternalProjectsViewState getProjectsViewState() {
+ return projectsViewState;
+ }
+
+ public void setProjectsViewState(ExternalProjectsViewState projectsViewState) {
+ this.projectsViewState = projectsViewState;
+ }
+ }
+
+ public static abstract class NullSafeMap<K,V> extends FactoryMap<K,V> {
+ @Override
+ public V put(K key, V value) {
+ if(value == null) return null;
+ return super.put(key, value);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.execution.ProgramRunnerUtil;
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.action.ExternalSystemAction;
+import com.intellij.openapi.externalSystem.action.ExternalSystemActionUtil;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+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.ExternalSystemUtil;
+import com.intellij.openapi.keymap.KeymapExtension;
+import com.intellij.openapi.keymap.KeymapGroup;
+import com.intellij.openapi.keymap.KeymapGroupFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import gnu.trove.THashSet;
+import icons.ExternalSystemIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/27/2014
+ */
+public class ExternalSystemKeymapExtension implements KeymapExtension {
+
+ public KeymapGroup createGroup(Condition<AnAction> condition, Project project) {
+ KeymapGroup result = KeymapGroupFactory.getInstance().createGroup(
+ ExternalSystemBundle.message("external.system.keymap.group"), ExternalSystemIcons.TaskGroup);
+ if (project == null) return result;
+
+ MultiMap<Pair<ProjectSystemId, String>, String> projectToActionsMapping = MultiMap.create();
+
+ ActionManager actionManager = ActionManager.getInstance();
+ for (String eachId : actionManager.getActionIds(getActionPrefix(project, null))) {
+ AnAction eachAction = actionManager.getAction(eachId);
+
+ if (!(eachAction instanceof MyExternalSystemAction)) continue;
+ if (condition != null && !condition.value(actionManager.getActionOrStub(eachId))) continue;
+
+ MyExternalSystemAction taskAction = (MyExternalSystemAction)eachAction;
+ projectToActionsMapping.putValue(Pair.create(taskAction.getSystemId(), taskAction.getGroup()), eachId);
+ }
+
+ Map<ProjectSystemId, KeymapGroup> keymapGroupMap = ContainerUtil.newHashMap();
+ for (Pair<ProjectSystemId, String> pair : projectToActionsMapping.keySet()) {
+ if (!keymapGroupMap.containsKey(pair.first)) {
+ final Icon projectIcon = ExternalSystemUiUtil.getUiAware(pair.first).getProjectIcon();
+ KeymapGroup group = KeymapGroupFactory.getInstance().createGroup(pair.first.getReadableName(), projectIcon);
+ result.addGroup(group);
+ keymapGroupMap.put(pair.first, group);
+ }
+ }
+
+
+ for (Map.Entry<Pair<ProjectSystemId, String>, Collection<String>> each : projectToActionsMapping.entrySet()) {
+ String groupName = each.getKey().second;
+ Collection<String> tasks = each.getValue();
+ if (tasks.isEmpty()) continue;
+ KeymapGroup group = KeymapGroupFactory.getInstance().createGroup(groupName, ExternalSystemIcons.TaskGroup);
+
+ final KeymapGroup systemGroup = keymapGroupMap.get(each.getKey().first);
+ if (systemGroup != null) {
+ systemGroup.addGroup(group);
+ }
+ else {
+ result.addGroup(group);
+ }
+ for (String actionId : tasks) {
+ group.addActionId(actionId);
+ }
+ }
+
+ return result;
+ }
+
+ public static void updateActions(Project project, Collection<DataNode<TaskData>> taskData) {
+ clearActions(project, taskData);
+ createActions(project, taskData);
+ }
+
+ private static void createActions(Project project, Collection<DataNode<TaskData>> taskData) {
+ ActionManager manager = ActionManager.getInstance();
+ for (DataNode<TaskData> each : taskData) {
+ final DataNode<ModuleData> moduleData = ExternalSystemApiUtil.findParent(each, ProjectKeys.MODULE);
+ if (moduleData == null) continue;
+ ExternalSystemTaskAction eachAction = new ExternalSystemTaskAction(project, moduleData.getData().getInternalName(), each.getData());
+
+ manager.unregisterAction(eachAction.getId());
+ manager.registerAction(eachAction.getId(), eachAction);
+ }
+ }
+
+ public static void clearActions(Project project) {
+ ActionManager manager = ActionManager.getInstance();
+ for (String each : manager.getActionIds(getActionPrefix(project, null))) {
+ manager.unregisterAction(each);
+ }
+ }
+
+ public static void clearActions(Project project, Collection<DataNode<TaskData>> taskData) {
+ ActionManager manager = ActionManager.getInstance();
+ for (DataNode<TaskData> each : taskData) {
+ for (String eachAction : manager.getActionIds(getActionPrefix(project, each.getData().getLinkedExternalProjectPath()))) {
+ manager.unregisterAction(eachAction);
+ }
+ }
+ }
+
+ public static String getActionPrefix(@NotNull Project project, @Nullable String path) {
+ return ExternalProjectsManager.getInstance(project).getShortcutsManager().getActionId(path, null);
+ }
+
+ public static void updateRunConfigurationActions(Project project, ProjectSystemId systemId) {
+ final AbstractExternalSystemTaskConfigurationType configurationType = ExternalSystemUtil.findConfigurationType(systemId);
+ if (configurationType == null) return;
+
+ Set<RunnerAndConfigurationSettings> settings = new THashSet<RunnerAndConfigurationSettings>(
+ RunManager.getInstance(project).getConfigurationSettingsList(configurationType));
+
+ ActionManager manager = ActionManager.getInstance();
+ for (RunnerAndConfigurationSettings configurationSettings : settings) {
+ ExternalSystemRunConfigurationAction runConfigurationAction =
+ new ExternalSystemRunConfigurationAction(project, configurationSettings);
+ String id = runConfigurationAction.getId();
+ manager.unregisterAction(id);
+ manager.registerAction(id, runConfigurationAction);
+ }
+ }
+
+ private abstract static class MyExternalSystemAction extends ExternalSystemAction {
+ public abstract String getId();
+
+ public abstract String getGroup();
+
+ public abstract ProjectSystemId getSystemId();
+ }
+
+ private static class ExternalSystemTaskAction extends MyExternalSystemAction {
+ private final String myId;
+ private final String myGroup;
+ private final TaskData myTaskData;
+
+ public ExternalSystemTaskAction(Project project, String group, TaskData taskData) {
+ myGroup = group;
+ myTaskData = taskData;
+ myId = getActionPrefix(project, taskData.getLinkedExternalProjectPath()) + taskData.getName();
+
+ Presentation template = getTemplatePresentation();
+ template.setText(myTaskData.getName(), false);
+ template.setIcon(ExternalSystemIcons.Task);
+ }
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ return hasProject(e);
+ }
+
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ final ExternalTaskExecutionInfo taskExecutionInfo = ExternalSystemActionUtil.buildTaskInfo(myTaskData);
+ ExternalSystemUtil.runTask(
+ taskExecutionInfo.getSettings(), taskExecutionInfo.getExecutorId(), getProject(e), myTaskData.getOwner());
+ }
+
+ public TaskData getTaskData() {
+ return myTaskData;
+ }
+
+ public String toString() {
+ return myTaskData.toString();
+ }
+
+ @Override
+ public String getGroup() {
+ return myGroup;
+ }
+
+ @Override
+ public ProjectSystemId getSystemId() {
+ return myTaskData.getOwner();
+ }
+
+ @Override
+ public String getId() {
+ return myId;
+ }
+ }
+
+ private static class ExternalSystemRunConfigurationAction extends MyExternalSystemAction {
+ private final String myId;
+ private final String myGroup;
+ private final RunnerAndConfigurationSettings myConfigurationSettings;
+ private final ProjectSystemId systemId;
+
+ public ExternalSystemRunConfigurationAction(Project project, RunnerAndConfigurationSettings configurationSettings) {
+ myConfigurationSettings = configurationSettings;
+ ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)configurationSettings.getConfiguration();
+ systemId = runConfiguration.getSettings().getExternalSystemId();
+
+ ExternalSystemUiAware uiAware = ExternalSystemUiUtil.getUiAware(systemId);
+ myGroup = uiAware.getProjectRepresentationName(runConfiguration.getSettings().getExternalProjectPath(), null);
+ String actionIdPrefix = getActionPrefix(project, runConfiguration.getSettings().getExternalProjectPath());
+ myId = actionIdPrefix + configurationSettings.getName();
+
+ Presentation template = getTemplatePresentation();
+ template.setText(myConfigurationSettings.getName(), false);
+ template.setIcon(runConfiguration.getIcon());
+ }
+
+ @Override
+ protected boolean isEnabled(AnActionEvent e) {
+ return hasProject(e);
+ }
+
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ ProgramRunnerUtil.executeConfiguration(getProject(e), myConfigurationSettings, DefaultRunExecutor.getRunExecutorInstance());
+ }
+
+ public String toString() {
+ return myConfigurationSettings.toString();
+ }
+
+ @Override
+ public String getGroup() {
+ return myGroup;
+ }
+
+ @Override
+ public ProjectSystemId getSystemId() {
+ return systemId;
+ }
+
+ public String getId() {
+ return myId;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunManagerAdapter;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
+import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator.*;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/14/2014
+ */
+class ExternalSystemRunManagerListener extends RunManagerAdapter {
+
+ private ExternalProjectsManager myManager;
+ private final Map<Integer, Pair<String, RunnerAndConfigurationSettings>> myMap;
+
+ public ExternalSystemRunManagerListener(ExternalProjectsManager manager) {
+ myManager = manager;
+ myMap = ContainerUtil.newConcurrentMap();
+ }
+
+ @Override
+ public void runConfigurationAdded(@NotNull RunnerAndConfigurationSettings settings) {
+ add(myMap, settings);
+ }
+
+ @Override
+ public void runConfigurationRemoved(@NotNull RunnerAndConfigurationSettings settings) {
+ if (settings.getConfiguration() instanceof ExternalSystemRunConfiguration) {
+ final Pair<String, RunnerAndConfigurationSettings> pair = myMap.remove(System.identityHashCode(settings));
+ if (pair == null) return;
+
+ final ExternalProjectsManager.ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
+ final ExternalSystemTaskExecutionSettings taskExecutionSettings =
+ ((ExternalSystemRunConfiguration)settings.getConfiguration()).getSettings();
+
+ if(taskExecutionSettings.getExternalProjectPath() == null) return;
+
+ final TaskActivationState activation =
+ stateProvider.getTasksActivation(taskExecutionSettings.getExternalSystemId(), taskExecutionSettings.getExternalProjectPath());
+
+ for (Phase phase : Phase.values()) {
+ for (Iterator<String> iterator = activation.getTasks(phase).iterator(); iterator.hasNext(); ) {
+ String task = iterator.next();
+ if (pair.first.equals(task)) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void runConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings) {
+ if (settings.getConfiguration() instanceof ExternalSystemRunConfiguration) {
+ final Pair<String, RunnerAndConfigurationSettings> pair = myMap.get(System.identityHashCode(settings));
+ if (pair != null) {
+ final ExternalProjectsManager.ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
+ final ExternalSystemTaskExecutionSettings taskExecutionSettings =
+ ((ExternalSystemRunConfiguration)settings.getConfiguration()).getSettings();
+
+ if(taskExecutionSettings.getExternalProjectPath() == null) return;
+
+ final TaskActivationState activation =
+ stateProvider.getTasksActivation(taskExecutionSettings.getExternalSystemId(), taskExecutionSettings.getExternalProjectPath());
+
+ for (Phase phase : Phase.values()) {
+ final Set<String> modifiableActivationTasks = activation.getTasks(phase);
+ for (String task : ContainerUtil.newTroveSet(modifiableActivationTasks)) {
+ if (pair.first.equals(task)) {
+ modifiableActivationTasks.remove(task);
+ final String runConfigurationActivationTaskName = getRunConfigurationActivationTaskName(settings);
+ modifiableActivationTasks.add(runConfigurationActivationTaskName);
+ myMap.put(System.identityHashCode(settings), Pair.create(runConfigurationActivationTaskName, settings));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void attach() {
+ myMap.clear();
+
+ for (ExternalSystemManager<?, ?, ?, ?, ?> systemManager : ExternalSystemApiUtil.getAllManagers()) {
+ final AbstractExternalSystemTaskConfigurationType configurationType =
+ ExternalSystemUtil.findConfigurationType(systemManager.getSystemId());
+ if (configurationType == null) continue;
+ final List<RunnerAndConfigurationSettings> configurationSettingsList =
+ RunManager.getInstance(myManager.getProject()).getConfigurationSettingsList(configurationType);
+ for (RunnerAndConfigurationSettings configurationSettings : configurationSettingsList) {
+ add(myMap, configurationSettings);
+ }
+ }
+
+ ((RunManagerEx)RunManager.getInstance(myManager.getProject())).addRunManagerListener(this);
+ }
+
+ public void detach() {
+ myMap.clear();
+ ((RunManagerEx)RunManager.getInstance(myManager.getProject())).removeRunManagerListener(this);
+ }
+
+ private static void add(@NotNull Map<Integer, Pair<String, RunnerAndConfigurationSettings>> map,
+ @NotNull RunnerAndConfigurationSettings settings) {
+ if (settings.getConfiguration() instanceof ExternalSystemRunConfiguration) {
+ map.put(System.identityHashCode(settings), Pair.create(getRunConfigurationActivationTaskName(settings), settings));
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.Shortcut;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.keymap.Keymap;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.keymap.KeymapManagerListener;
+import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.openapi.keymap.ex.KeymapManagerEx;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/27/2014
+ */
+public class ExternalSystemShortcutsManager implements Disposable {
+
+ private static final String ACTION_ID_PREFIX = "ExternalSystem_";
+ @NotNull
+ private final Project myProject;
+ private ExternalSystemKeyMapListener myKeyMapListener;
+ private final List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+
+ public ExternalSystemShortcutsManager(@NotNull Project project) {
+ myProject = project;
+ }
+
+ public void init() {
+ myKeyMapListener = new ExternalSystemKeyMapListener();
+ }
+
+ public String getActionId(@Nullable String projectPath, @Nullable String taskName) {
+ StringBuilder result = new StringBuilder(ACTION_ID_PREFIX);
+ result.append(myProject.getLocationHash());
+
+ if (projectPath != null) {
+ String portablePath = FileUtil.toSystemIndependentName(projectPath);
+ result.append(new File(portablePath).getParentFile().getName());
+ result.append(Integer.toHexString(portablePath.hashCode()));
+
+ if (taskName != null) result.append(taskName);
+ }
+
+ return result.toString();
+ }
+
+ public String getDescription(@Nullable String projectPath, @Nullable String taskName) {
+ String actionId = getActionId(projectPath, taskName);
+ if (actionId == null) return "";
+
+ Keymap activeKeymap = KeymapManager.getInstance().getActiveKeymap();
+ Shortcut[] shortcuts = activeKeymap.getShortcuts(actionId);
+ if (shortcuts == null || shortcuts.length == 0) return "";
+
+ return KeymapUtil.getShortcutsText(shortcuts);
+ }
+
+ private void fireShortcutsUpdated() {
+ for (Listener listener : myListeners) {
+ listener.shortcutsUpdated();
+ }
+ }
+
+ public void addListener(Listener listener) {
+ myListeners.add(listener);
+ }
+
+ public interface Listener {
+ void shortcutsUpdated();
+ }
+
+ private class ExternalSystemKeyMapListener implements KeymapManagerListener, Keymap.Listener {
+ private Keymap myCurrentKeymap = null;
+
+ public ExternalSystemKeyMapListener() {
+ KeymapManager keymapManager = KeymapManager.getInstance();
+ listenTo(keymapManager.getActiveKeymap());
+ keymapManager.addKeymapManagerListener(this);
+ }
+
+ @Override
+ public void activeKeymapChanged(Keymap keymap) {
+ listenTo(keymap);
+ fireShortcutsUpdated();
+ }
+
+ private void listenTo(Keymap keymap) {
+ if (myCurrentKeymap != null) {
+ myCurrentKeymap.removeShortcutChangeListener(this);
+ }
+ myCurrentKeymap = keymap;
+ if (myCurrentKeymap != null) {
+ myCurrentKeymap.addShortcutChangeListener(this);
+ }
+ }
+
+ @Override
+ public void onShortcutChanged(String actionId) {
+ fireShortcutsUpdated();
+ }
+
+ public void stopListen() {
+ listenTo(null);
+ KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this);
+ }
+ }
+
+ public void scheduleKeymapUpdate(Collection<DataNode<TaskData>> taskData) {
+ ExternalSystemKeymapExtension.updateActions(myProject, taskData);
+ }
+
+ public void scheduleRunConfigurationKeymapUpdate(@NotNull ProjectSystemId externalSystemId) {
+ ExternalSystemKeymapExtension.updateRunConfigurationActions(myProject, externalSystemId);
+ }
+
+ @Override
+ public void dispose() {
+ if (myKeyMapListener != null) {
+ myKeyMapListener.stopListen();
+ }
+ ExternalSystemKeymapExtension.clearActions(myProject);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileTask;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager.ExternalProjectsStateProvider;
+import com.intellij.openapi.externalSystem.task.TaskCallback;
+import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Function;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/28/2014
+ */
+public class ExternalSystemTaskActivator {
+
+ public static final String RUN_CONFIGURATION_TASK_PREFIX = "run: ";
+ @NotNull private final Project myProject;
+ private final List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+
+ public ExternalSystemTaskActivator(@NotNull Project project) {
+ myProject = project;
+ }
+
+ @NotNull
+ public static String getRunConfigurationActivationTaskName(@NotNull RunnerAndConfigurationSettings settings) {
+ return RUN_CONFIGURATION_TASK_PREFIX + settings.getName();
+ }
+
+ public void init() {
+ CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+
+ class MyCompileTask implements CompileTask {
+ private final boolean myBefore;
+
+ MyCompileTask(boolean before) {
+ myBefore = before;
+ }
+
+ @Override
+ public boolean execute(CompileContext context) {
+ return doExecute(myBefore, context);
+ }
+ }
+
+ compilerManager.addBeforeTask(new MyCompileTask(true));
+ compilerManager.addAfterTask(new MyCompileTask(false));
+
+ fireTasksChanged();
+ }
+
+ public String getDescription(ProjectSystemId systemId, String projectPath, String taskName) {
+ List<String> result = new ArrayList<String>();
+ final ExternalProjectsStateProvider stateProvider =
+ ExternalProjectsManager.getInstance(myProject).getStateProvider();
+ final TaskActivationState taskActivationState = stateProvider.getTasksActivation(systemId, projectPath);
+ if (taskActivationState == null) return null;
+
+ for (Phase phase : Phase.values()) {
+ if (taskActivationState.getTasks(phase).contains(taskName)) {
+ result.add(ExternalSystemBundle.message(phase.myMessageKey));
+ }
+ }
+ return StringUtil.join(result, ", ");
+ }
+
+ private boolean doExecute(boolean before, CompileContext context) {
+
+ final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
+
+ final Queue<Pair<ProjectSystemId, ExternalSystemTaskExecutionSettings>> tasksQueue =
+ new LinkedList<Pair<ProjectSystemId, ExternalSystemTaskExecutionSettings>>();
+
+ //noinspection MismatchedQueryAndUpdateOfCollection
+ Map<ProjectSystemId, Map<String, RunnerAndConfigurationSettings>> lazyConfigurationsMap =
+ new FactoryMap<ProjectSystemId, Map<String, RunnerAndConfigurationSettings>>() {
+ @Nullable
+ @Override
+ protected Map<String, RunnerAndConfigurationSettings> create(ProjectSystemId key) {
+ final AbstractExternalSystemTaskConfigurationType configurationType =
+ ExternalSystemUtil.findConfigurationType(key);
+ if (configurationType == null) return null;
+ return ContainerUtil.map2Map(RunManager.getInstance(myProject).getConfigurationSettingsList(configurationType),
+ new Function<RunnerAndConfigurationSettings, Pair<String, RunnerAndConfigurationSettings>>() {
+ @Override
+ public Pair<String, RunnerAndConfigurationSettings> fun(RunnerAndConfigurationSettings configurationSettings) {
+ return Pair.create(configurationSettings.getName(), configurationSettings);
+ }
+ });
+ }
+ };
+
+ for (final ExternalProjectsStateProvider.TasksActivation activation : stateProvider.getAllTasksActivation()) {
+ Set<String> tasks = ContainerUtil.newTroveSet(activation.state.getTasks(before ? Phase.BEFORE_COMPILE : Phase.AFTER_COMPILE));
+ if (context.isRebuild()) {
+ tasks = ContainerUtil.union(tasks, (before ? activation.state.beforeRebuildTask : activation.state.afterRebuildTask));
+ }
+ if (tasks.isEmpty()) continue;
+
+ for (Iterator<String> iterator = tasks.iterator(); iterator.hasNext(); ) {
+ String task = iterator.next();
+ if (task.length() > RUN_CONFIGURATION_TASK_PREFIX.length() && task.startsWith(RUN_CONFIGURATION_TASK_PREFIX)) {
+ iterator.remove();
+ final String configurationName = task.substring(RUN_CONFIGURATION_TASK_PREFIX.length());
+
+ Map<String, RunnerAndConfigurationSettings> settings = lazyConfigurationsMap.get(activation.systemId);
+ if (settings == null) continue;
+
+ RunnerAndConfigurationSettings configurationSettings = settings.get(configurationName);
+ if (configurationSettings == null) continue;
+
+ final RunConfiguration runConfiguration = configurationSettings.getConfiguration();
+ if (configurationName.equals(configurationSettings.getName()) && runConfiguration instanceof ExternalSystemRunConfiguration) {
+ tasksQueue.add(Pair.create(activation.systemId, ((ExternalSystemRunConfiguration)runConfiguration).getSettings()));
+ }
+ }
+ }
+
+ if (tasks.isEmpty()) continue;
+
+ ExternalSystemTaskExecutionSettings executionSettings = new ExternalSystemTaskExecutionSettings();
+ executionSettings.setExternalSystemIdString(activation.systemId.toString());
+ executionSettings.setExternalProjectPath(activation.projectPath);
+ executionSettings.getTaskNames().addAll(tasks);
+ tasksQueue.add(Pair.create(activation.systemId, executionSettings));
+ }
+
+ return runTasksQueue(tasksQueue);
+ }
+
+ private boolean runTasksQueue(final Queue<Pair<ProjectSystemId, ExternalSystemTaskExecutionSettings>> tasksQueue) {
+ final Pair<ProjectSystemId, ExternalSystemTaskExecutionSettings> pair = tasksQueue.poll();
+ if (pair == null) return true;
+
+ final ProjectSystemId systemId = pair.first;
+ final ExternalSystemTaskExecutionSettings executionSettings = pair.getSecond();
+
+ final Semaphore targetDone = new Semaphore();
+ targetDone.down();
+ final Ref<Boolean> result = new Ref<Boolean>(false);
+ ExternalSystemUtil.runTask(executionSettings, DefaultRunExecutor.EXECUTOR_ID, myProject, systemId,
+ new TaskCallback() {
+ @Override
+ public void onSuccess() {
+ result.set(runTasksQueue(tasksQueue));
+ targetDone.up();
+ }
+
+ @Override
+ public void onFailure() {
+ targetDone.up();
+ }
+ },
+ ProgressExecutionMode.IN_BACKGROUND_ASYNC);
+ targetDone.waitFor();
+ return result.get();
+ }
+
+ public void addListener(Listener l) {
+ myListeners.add(l);
+ }
+
+ public boolean isTaskOfPhase(@NotNull TaskData taskData, @NotNull Phase phase) {
+ final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
+ final TaskActivationState taskActivationState =
+ stateProvider.getTasksActivation(taskData.getOwner(), taskData.getLinkedExternalProjectPath());
+ if (taskActivationState == null) return false;
+
+ return taskActivationState.getTasks(phase).contains(taskData.getName());
+ }
+
+ public void addTasks(List<TaskData> tasks, Phase phase) {
+ if (tasks.isEmpty()) return;
+
+ final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
+ for (TaskData task : tasks) {
+ final TaskActivationState taskActivationState = stateProvider.getTasksActivation(task.getOwner(),
+ task.getLinkedExternalProjectPath());
+ taskActivationState.getTasks(phase).add(task.getName());
+ }
+
+ fireTasksChanged();
+ }
+
+ public void removeTasks(List<TaskData> tasks, Phase phase) {
+ if (tasks.isEmpty()) return;
+
+ final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
+
+ for (TaskData task : tasks) {
+ final TaskActivationState taskActivationState = stateProvider.getTasksActivation(task.getOwner(),
+ task.getLinkedExternalProjectPath());
+ taskActivationState.getTasks(phase).remove(task.getName());
+ }
+
+ fireTasksChanged();
+ }
+
+ public void fireTasksChanged() {
+ for (Listener each : myListeners) {
+ each.tasksActivationChanged();
+ }
+ }
+
+ public enum Phase {
+ AFTER_SYNC("external.system.task.after.sync"),
+ BEFORE_COMPILE("external.system.task.before.compile"),
+ AFTER_COMPILE("external.system.task.after.compile"),
+ BEFORE_REBUILD("external.system.task.before.rebuild"),
+ AFTER_REBUILD("external.system.task.after.rebuild");
+
+ public final String myMessageKey;
+
+ Phase(String messageKey) {
+ myMessageKey = messageKey;
+ }
+ }
+
+ public interface Listener {
+ void tasksActivationChanged();
+ }
+}
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.util.Consumer;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
};
}
- @Nullable
- public List<ProjectDataService<?, ?>> getDataServices(Key<?> key) {
- return myServices.getValue().get(key);
- }
-
@Nullable
public ProjectDataService<?, ?> getDataService(Key<?> key) {
final List<ProjectDataService<?, ?>> dataServices = myServices.getValue().get(key);
@SuppressWarnings("unchecked")
public <T> void importData(@NotNull Collection<DataNode<?>> nodes, @NotNull Project project, boolean synchronous) {
- if(project.isDisposed()) return;
+ if (project.isDisposed()) return;
Map<Key<?>, List<DataNode<?>>> grouped = ExternalSystemApiUtil.group(nodes);
for (Map.Entry<Key<?>, List<DataNode<?>>> entry : grouped.entrySet()) {
@SuppressWarnings("unchecked")
public <T> void importData(@NotNull Key<T> key, @NotNull Collection<DataNode<T>> nodes, @NotNull Project project, boolean synchronous) {
- if(project.isDisposed()) return;
+ if (project.isDisposed()) return;
- ensureTheDataIsReadyToUse(nodes);
+ ensureTheDataIsReadyToUse((Collection)nodes);
List<ProjectDataService<?, ?>> services = myServices.getValue().get(key);
if (services == null) {
LOG.warn(String.format(
importData(children, project, synchronous);
}
- @SuppressWarnings("unchecked")
- private <T> void ensureTheDataIsReadyToUse(@NotNull Collection<DataNode<T>> nodes) {
- Map<Key<?>, List<ProjectDataService<?, ?>>> servicesByKey = myServices.getValue();
- Stack<DataNode<T>> toProcess = ContainerUtil.newStack(nodes);
- while (!toProcess.isEmpty()) {
- DataNode<T> node = toProcess.pop();
- List<ProjectDataService<?, ?>> services = servicesByKey.get(node.getKey());
- if (services != null) {
- for (ProjectDataService<?, ?> service : services) {
- node.prepareData(service.getClass().getClassLoader());
+ public void ensureTheDataIsReadyToUse(DataNode dataNode) {
+ final Map<Key<?>, List<ProjectDataService<?, ?>>> servicesByKey = myServices.getValue();
+ ExternalSystemApiUtil.visit(dataNode, new Consumer<DataNode>() {
+ @Override
+ public void consume(DataNode dataNode) {
+ List<ProjectDataService<?, ?>> services = servicesByKey.get(dataNode.getKey());
+ if (services != null) {
+ try {
+ dataNode.prepareData(ContainerUtil.map2Array(services, ClassLoader.class, new Function<ProjectDataService<?, ?>, ClassLoader>() {
+ @Override
+ public ClassLoader fun(ProjectDataService<?, ?> service) {
+ return service.getClass().getClassLoader();
+ }
+ }));
+ }
+ catch (Exception e) {
+ LOG.debug(e);
+ dataNode.clear(true);
+ }
}
}
+ });
+ }
- for (DataNode<?> dataNode : node.getChildren()) {
- toProcess.push((DataNode<T>)dataNode);
- }
+ private void ensureTheDataIsReadyToUse(@NotNull Collection<DataNode<?>> nodes) {
+ for (DataNode<?> node : nodes) {
+ ensureTheDataIsReadyToUse(node);
}
}
}
public void updateExternalProjectData(@NotNull Project project, @NotNull ExternalProjectInfo externalProjectInfo) {
- if(!project.isDisposed()) {
- ExternalProjectsDataStorage.getInstance(project).add(externalProjectInfo);
+ if (!project.isDisposed()) {
+ ExternalProjectsManager.getInstance(project).updateExternalProjectData(externalProjectInfo);
}
}
@Nullable
- public ExternalProjectInfo getExternalProjectData(@NotNull Project project, @NotNull ProjectSystemId projectSystemId, @NotNull String externalProjectPath) {
+ public ExternalProjectInfo getExternalProjectData(@NotNull Project project,
+ @NotNull ProjectSystemId projectSystemId,
+ @NotNull String externalProjectPath) {
return !project.isDisposed() ? ExternalProjectsDataStorage.getInstance(project).get(projectSystemId, externalProjectPath) : null;
}
+
+ @NotNull
+ public Collection<ExternalProjectInfo> getExternalProjectsData(@NotNull Project project, @NotNull ProjectSystemId projectSystemId) {
+ return !project.isDisposed() ?
+ ExternalProjectsDataStorage.getInstance(project).list(projectSystemId) : ContainerUtil.<ExternalProjectInfo>emptyList();
+ }
}
}
DataNode<ProjectData> node = toImport.iterator().next();
ProjectData projectData = node.getData();
-
+
if (!ExternalSystemApiUtil.isNewProjectConstruction() && !ExternalSystemUtil.isOneToOneMapping(project, node)) {
return;
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.service.project.manage;
+
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+* @author Vladislav.Soroka
+* @since 10/30/2014
+*/
+@Tag("activation")
+public class TaskActivationState {
+ @Tag("after_sync")
+ @AbstractCollection(surroundWithTag = false, elementTag = "task", elementValueAttribute = "name")
+ public Set<String> afterSyncTasks = new TreeSet<String>();
+
+ @Tag("before_compile")
+ @AbstractCollection(surroundWithTag = false, elementTag = "task", elementValueAttribute = "name")
+ public Set<String> beforeCompileTasks = new TreeSet<String>();
+
+ @Tag("after_compile")
+ @AbstractCollection(surroundWithTag = false, elementTag = "task", elementValueAttribute = "name")
+ public Set<String> afterCompileTasks = new TreeSet<String>();
+
+ @Tag("after_rebuild")
+ @AbstractCollection(surroundWithTag = false, elementTag = "task", elementValueAttribute = "name")
+ public Set<String> afterRebuildTask = new TreeSet<String>();
+
+ @Tag("before_rebuild")
+ @AbstractCollection(surroundWithTag = false, elementTag = "task", elementValueAttribute = "name")
+ public Set<String> beforeRebuildTask = new TreeSet<String>();
+
+ @NotNull
+ public Set<String> getTasks(@NotNull ExternalSystemTaskActivator.Phase phase) {
+ switch (phase) {
+ case AFTER_COMPILE:
+ return afterCompileTasks;
+ case AFTER_SYNC:
+ return afterSyncTasks;
+ case BEFORE_COMPILE:
+ return beforeCompileTasks;
+ case AFTER_REBUILD:
+ return afterRebuildTask;
+ case BEFORE_REBUILD:
+ return beforeRebuildTask;
+ default:
+ throw new RuntimeException();
+ }
+ }
+}
ExternalSystemApiUtil.executeOnEdt(false, new Runnable() {
@Override
public void run() {
- ExternalSystemTasksTreeModel model = ExternalSystemUtil.getToolWindowElement(ExternalSystemTasksTreeModel.class,
- project,
- ExternalSystemDataKeys.ALL_TASKS_MODEL,
- toImport.iterator().next().getData().getOwner());
- processData(toImport, project, model);
+ processData(toImport, project);
}
});
}
protected abstract void processData(@NotNull Collection<DataNode<T>> nodes,
- @NotNull Project project,
- @Nullable ExternalSystemTasksTreeModel model);
+ @NotNull Project project);
@Override
public void removeData(@NotNull Collection<? extends Void> toRemove, @NotNull Project project, boolean synchronous) {
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
-import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.*;
@Override
protected void processData(@NotNull final Collection<DataNode<ModuleData>> nodes,
- @NotNull Project project,
- @Nullable final ExternalSystemTasksTreeModel model)
+ @NotNull Project project)
{
if (nodes.isEmpty()) {
return;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.task.TaskData;
-import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
-import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.project.Project;
import com.intellij.util.Function;
@Override
protected void processData(@NotNull Collection<DataNode<TaskData>> nodes,
- @NotNull Project project,
- @Nullable final ExternalSystemTasksTreeModel model)
+ @NotNull Project project)
{
if (nodes.isEmpty()) {
return;
Map<String, Collection<ExternalTaskPojo>> availableTasks = ContainerUtilRt.newHashMap(settings.getAvailableTasks());
availableTasks.putAll(data);
settings.setAvailableTasks(availableTasks);
-
- if (model != null) {
- ExternalSystemUiUtil.apply(settings, model);
- }
}
}
*/
package com.intellij.openapi.externalSystem.service.task.ui;
-import com.intellij.notification.NotificationGroup;
-import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
-import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
+import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.impl.ContentImpl;
import org.jetbrains.annotations.NotNull;
-import java.util.Locale;
-
/**
* @author Denis Zhdanov
* @since 5/13/13 4:15 PM
*/
public abstract class AbstractExternalSystemToolWindowFactory implements ToolWindowFactory, DumbAware {
- @NotNull private final ProjectSystemId myExternalSystemId;
- @NotNull private final NotificationGroup myNotificationGroup;
+ @NotNull private final ProjectSystemId myExternalSystemId;
protected AbstractExternalSystemToolWindowFactory(@NotNull ProjectSystemId id) {
myExternalSystemId = id;
- myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(Locale.ENGLISH),
- myExternalSystemId.getReadableName());
}
@Override
public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) {
toolWindow.setTitle(myExternalSystemId.getReadableName());
ContentManager contentManager = toolWindow.getContentManager();
- String tasksTitle = ExternalSystemBundle.message("tool.window.title.tasks");
- ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(myExternalSystemId);
- assert manager != null;
- ExternalSystemTasksPanel panel = new ExternalSystemTasksPanel(project, myExternalSystemId, myNotificationGroup);
- ContentImpl tasksContent = new ContentImpl(panel, tasksTitle, true);
+ final ExternalProjectsView projectsView = new ExternalProjectsView(project, (ToolWindowEx)toolWindow, myExternalSystemId);
+ ExternalProjectsManager.getInstance(project).registerView(projectsView);
+ ContentImpl tasksContent = new ContentImpl(projectsView, ExternalSystemBundle.message("tool.window.title.projects"), true);
contentManager.addContent(tasksContent);
}
}
+++ /dev/null
-/*
- * 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.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;
-
-import javax.swing.*;
-import java.util.List;
-
-/**
- * @author Denis Zhdanov
- * @since 6/7/13 3:28 PM
- */
-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);
- for (ExternalTaskExecutionInfo task : tasksToUse) {
- addElement(task);
- }
- }
-
- @SuppressWarnings("unchecked")
- public void setFirst(@NotNull ExternalTaskExecutionInfo task) {
- insertElementAt(task, 0);
- for (int i = 1; i < size(); i++) {
- if (task.equals(getElementAt(i))) {
- remove(i);
- break;
- }
- }
- ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
- }
-
- @NotNull
- public List<ExternalTaskExecutionInfo> getTasks() {
- List<ExternalTaskExecutionInfo> result = ContainerUtilRt.newArrayList();
- for (int i = 0; i < size(); i++) {
- Object e = getElementAt(i);
- if (e instanceof ExternalTaskExecutionInfo) {
- result.add((ExternalTaskExecutionInfo)e);
- }
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
- public void ensureSize(int elementsNumber) {
- int toAdd = elementsNumber - size();
- if (toAdd == 0) {
- return;
- }
- if(toAdd < 0) {
- removeRange(elementsNumber, size() - 1);
- }
- while (--toAdd >= 0) {
- addElement(new MyEmptyDescriptor());
- }
- }
-
- /**
- * 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 {
- }
-}
+++ /dev/null
-/*
- * 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.service.task.ui;
-
-import com.intellij.execution.Executor;
-import com.intellij.execution.ExecutorRegistry;
-import com.intellij.execution.RunManager;
-import com.intellij.execution.configurations.ConfigurationType;
-import com.intellij.execution.configurations.RunConfiguration;
-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.ExternalTaskExecutionInfo;
-import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
-import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
-import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
-import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
-import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
-import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.components.JBList;
-import com.intellij.util.Producer;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.util.List;
-
-/**
- * @author Denis Zhdanov
- * @since 6/7/13 2:40 PM
- */
-public class ExternalSystemRecentTasksList extends JBList implements Producer<ExternalTaskExecutionInfo> {
-
- @NotNull private static final JLabel EMPTY_RENDERER = new JLabel(" ");
-
- public ExternalSystemRecentTasksList(@NotNull ExternalSystemRecentTaskListModel model,
- @NotNull final ProjectSystemId externalSystemId,
- @NotNull final Project project)
- {
- super(model);
- setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
- Icon icon = null;
- if (manager instanceof ExternalSystemUiAware) {
- icon = ((ExternalSystemUiAware)manager).getTaskIcon();
- }
- if (icon == null) {
- icon = DefaultExternalSystemUiAware.INSTANCE.getTaskIcon();
- }
- setCellRenderer(new MyRenderer(project, icon, ExternalSystemUtil.findConfigurationType(externalSystemId)));
- setVisibleRowCount(ExternalSystemConstants.RECENT_TASKS_NUMBER);
-
- registerKeyboardAction(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- ExternalTaskExecutionInfo task = produce();
- if (task == null) {
- return;
- }
- ExternalSystemUtil.runTask(task.getSettings(), task.getExecutorId(), project, externalSystemId);
- }
- }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
-
- addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getClickCount() < 2) {
- return;
- }
-
- ExternalTaskExecutionInfo task = produce();
- if (task == null) {
- return;
- }
-
- ExternalSystemUtil.runTask(task.getSettings(), task.getExecutorId(), project, externalSystemId);
- }
- });
- }
-
- @Override
- public ExternalSystemRecentTaskListModel getModel() {
- return (ExternalSystemRecentTaskListModel)super.getModel();
- }
-
- public void setFirst(@NotNull ExternalTaskExecutionInfo task) {
- ExternalTaskExecutionInfo selected = produce();
- ExternalSystemRecentTaskListModel model = getModel();
- model.setFirst(task);
- clearSelection();
- if (selected == null) {
- return;
- }
- for (int i = 0; i < model.size(); i++) {
- //noinspection SuspiciousMethodCalls
- if (selected.equals(model.getElementAt(i))) {
- addSelectionInterval(i, i);
- return;
- }
- }
- }
-
- @Nullable
- @Override
- public ExternalTaskExecutionInfo produce() {
- int[] indices = getSelectedIndices();
- if (indices == null || indices.length != 1) {
- return null;
- }
- Object e = getModel().getElementAt(indices[0]);
- return e instanceof ExternalTaskExecutionInfo ? (ExternalTaskExecutionInfo)e : null;
- }
-
- private static class MyRenderer extends DefaultListCellRenderer {
-
- @NotNull private final Icon myGenericTaskIcon;
- @NotNull private final Project myProject;
- @Nullable private ConfigurationType myConfigurationType;
-
- MyRenderer(@NotNull Project project, @NotNull Icon genericTaskIcon, @Nullable ConfigurationType configurationType) {
- myProject = project;
- myGenericTaskIcon = genericTaskIcon;
- myConfigurationType = configurationType;
- }
-
- @Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
- Component renderer = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
- if (value instanceof ExternalSystemRecentTaskListModel.MyEmptyDescriptor) {
- return EMPTY_RENDERER;
- }
- else if (value instanceof ExternalTaskExecutionInfo) {
- ExternalTaskExecutionInfo taskInfo = (ExternalTaskExecutionInfo)value;
- String text = null;
- if (myConfigurationType != null) {
- List<RunConfiguration> configurations = RunManager.getInstance(myProject).getConfigurationsList(myConfigurationType);
- for (RunConfiguration configuration : configurations) {
- if (!(configuration instanceof ExternalSystemRunConfiguration)) {
- continue;
- }
- ExternalSystemRunConfiguration c = (ExternalSystemRunConfiguration)configuration;
- if (c.getSettings().equals(taskInfo.getSettings())) {
- text = c.getName();
- }
- }
- }
- if (StringUtil.isEmpty(text)) {
- text = AbstractExternalSystemTaskConfigurationType.generateName(myProject, taskInfo.getSettings());
- }
-
- setText(text);
- Icon icon = null;
- String executorId = taskInfo.getExecutorId();
- if (!StringUtil.isEmpty(executorId)) {
- Executor executor = ExecutorRegistry.getInstance().getExecutorById(executorId);
- if (executor != null) {
- icon = executor.getIcon();
- }
- }
-
- if (icon == null) {
- icon = myGenericTaskIcon;
- }
- setIcon(icon);
- }
-
- return renderer;
- }
-
- @Override
- public void setIcon(Icon icon) {
- if (icon != null) {
- // Don't allow to reset icon.
- super.setIcon(icon);
- }
- }
- }
-}
+++ /dev/null
-/*
- * 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.service.task.ui;
-
-import com.intellij.execution.Location;
-import com.intellij.execution.executors.DefaultRunExecutor;
-import com.intellij.ide.ui.customization.CustomizationUtil;
-import com.intellij.notification.NotificationGroup;
-import com.intellij.openapi.actionSystem.ActionGroup;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.ActionToolbar;
-import com.intellij.openapi.actionSystem.DataProvider;
-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;
-import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
-import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
-import com.intellij.openapi.fileTypes.PlainTextFileType;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.SimpleToolWindowPanel;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiFileFactory;
-import com.intellij.ui.IdeBorderFactory;
-import com.intellij.ui.components.JBScrollPane;
-import com.intellij.util.Producer;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-
-import static com.intellij.openapi.externalSystem.util.ExternalSystemConstants.*;
-
-/**
- * @author Denis Zhdanov
- * @since 5/12/13 10:18 PM
- */
-public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements DataProvider {
-
- @NotNull private final ExternalSystemRecentTasksList myRecentTasksList;
- @NotNull private final ExternalSystemTasksTreeModel myAllTasksModel;
- @NotNull private final ExternalSystemTasksTree myAllTasksTree;
- @NotNull private final ProjectSystemId myExternalSystemId;
- @NotNull private final NotificationGroup myNotificationGroup;
- @NotNull private final Project myProject;
-
- @Nullable private Producer<ExternalTaskExecutionInfo> mySelectedTaskProvider;
-
- public ExternalSystemTasksPanel(@NotNull Project project,
- @NotNull ProjectSystemId externalSystemId,
- @NotNull NotificationGroup notificationGroup)
- {
- super(true);
- myExternalSystemId = externalSystemId;
- myNotificationGroup = notificationGroup;
- myProject = project;
-
- ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
- assert manager != null;
- AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
-
- ExternalSystemRecentTaskListModel recentTasksModel = new ExternalSystemRecentTaskListModel(externalSystemId, project);
- recentTasksModel.setTasks(settings.getRecentTasks());
- myRecentTasksList = new ExternalSystemRecentTasksList(recentTasksModel, externalSystemId, project) {
- @Override
- protected void processMouseEvent(MouseEvent e) {
- if (e.getClickCount() > 0) {
- mySelectedTaskProvider = myRecentTasksList;
- myAllTasksTree.getSelectionModel().clearSelection();
- }
- super.processMouseEvent(e);
- }
- };
-
- myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId);
- myAllTasksTree = new ExternalSystemTasksTree(myAllTasksModel, settings.getExpandStates(), project, externalSystemId) {
- @Override
- protected void processMouseEvent(MouseEvent e) {
- if (e.getClickCount() > 0) {
- mySelectedTaskProvider = myAllTasksTree;
- myRecentTasksList.getSelectionModel().clearSelection();
- }
- super.processMouseEvent(e);
- }
- };
- final String actionIdToUseForDoubleClick = DefaultRunExecutor.getRunExecutorInstance().getContextActionId();
- myAllTasksTree.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getClickCount() >= 2 && !e.isPopupTrigger()) {
- ExternalSystemUiUtil.executeAction(actionIdToUseForDoubleClick, e);
- }
- }
- });
- ExternalSystemUiUtil.apply(settings, myAllTasksModel);
- CustomizationUtil.installPopupHandler(myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_CONTEXT_MENU_PLACE);
-
- ActionManager actionManager = ActionManager.getInstance();
- ActionGroup group = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID);
- ActionToolbar toolbar = actionManager.createActionToolbar(TOOL_WINDOW_PLACE, group, true);
- toolbar.setTargetComponent(this);
- setToolbar(toolbar.getComponent());
-
- JPanel content = new JPanel(new GridBagLayout());
- content.setOpaque(true);
- content.setBackground(UIUtil.getListBackground());
- JComponent recentTasksWithTitle = wrap(myRecentTasksList, ExternalSystemBundle.message("tasks.recent.title"));
- content.add(recentTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0));
- JBScrollPane scrollPane = new JBScrollPane(myAllTasksTree);
- scrollPane.setBorder(null);
- JComponent allTasksWithTitle = wrap(scrollPane, ExternalSystemBundle.message("tasks.all.title"));
- content.add(allTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0).weighty(1).fillCell());
- setContent(content);
- }
-
- private static JComponent wrap(@NotNull JComponent content, @NotNull String title) {
- JPanel result = new JPanel(new BorderLayout());
- result.setOpaque(false);
- result.setBorder(IdeBorderFactory.createTitledBorder(title, false));
- result.add(content, BorderLayout.CENTER);
- return result;
- }
-
- @Nullable
- @Override
- public Object getData(@NonNls String dataId) {
- if (ExternalSystemDataKeys.RECENT_TASKS_LIST.is(dataId)) {
- return myRecentTasksList;
- }
- else if (ExternalSystemDataKeys.ALL_TASKS_MODEL.is(dataId)) {
- return myAllTasksModel;
- }
- else if (ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.is(dataId)) {
- return myExternalSystemId;
- }
- else if (ExternalSystemDataKeys.NOTIFICATION_GROUP.is(dataId)) {
- return myNotificationGroup;
- }
- 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;
- }
- return null;
- }
-
- @Nullable
- private Location buildLocation() {
- if (mySelectedTaskProvider == null) {
- return null;
- }
- ExternalTaskExecutionInfo task = mySelectedTaskProvider.produce();
- if (task == null) {
- return null;
- }
-
- String projectPath = task.getSettings().getExternalProjectPath();
- String name = myExternalSystemId.getReadableName() + projectPath + StringUtil.join(task.getSettings().getTaskNames(), " ");
- // We create a dummy text file instead of re-using external system file in order to avoid clashing with other configuration producers.
- // For example gradle files are enhanced groovy scripts but we don't want to run them via regular IJ groovy script runners.
- // Gradle tooling api should be used for running gradle tasks instead. IJ execution sub-system operates on Location objects
- // which encapsulate PsiElement and groovy runners are automatically applied if that PsiElement IS-A GroovyFile.
- PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name, PlainTextFileType.INSTANCE, "nichts");
-
- return new ExternalSystemTaskLocation(myProject, file, task);
- }
-}
component.add(Box.createVerticalGlue(), new GridBag().weightx(1).weighty(1).fillCell().coverLine());
}
- /**
- * Applies data from the given settings object to the given model.
- *
- * @param settings target settings to use
- * @param model UI model to be synced with the given settings
- */
- public static void apply(@NotNull final AbstractExternalSystemLocalSettings settings, @NotNull final ExternalSystemTasksTreeModel model) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- Map<ExternalProjectPojo,Collection<ExternalProjectPojo>> projects = settings.getAvailableProjects();
- for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : projects.entrySet()) {
- model.ensureSubProjectsStructure(entry.getKey(), entry.getValue());
- }
- Map<String, Collection<ExternalTaskPojo>> tasks = settings.getAvailableTasks();
- for (Map.Entry<String, Collection<ExternalTaskPojo>> entry : tasks.entrySet()) {
- model.ensureTasks(entry.getKey(), entry.getValue());
- }
- }
- });
- }
-
public static void showUi(@NotNull Object o, boolean show) {
for (Class<?> clazz = o.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
for (Field field : clazz.getDeclaredFields()) {
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
-import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
import com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
import com.intellij.openapi.externalSystem.service.project.manage.ModuleDataService;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.service.settings.ExternalSystemConfigLocator;
-import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentTasksList;
-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.task.TaskCallback;
+import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
}
}
- @SuppressWarnings("unchecked")
@Nullable
public static <T> T getToolWindowElement(@NotNull Class<T> clazz,
@NotNull Project project,
if (component instanceof DataProvider) {
final Object data = ((DataProvider)component).getData(key.getName());
if (data != null && clazz.isInstance(data)) {
+ //noinspection unchecked
return (T)data;
}
}
return timeStamp;
}
+ public static void ruleOrphanModules(@NotNull final List<Module> orphanModules,
+ @NotNull final Project project,
+ @NotNull final ProjectSystemId externalSystemId) {
+ //noinspection unchecked
+ ruleOrphanModules(orphanModules, project, externalSystemId, Consumer.EMPTY_CONSUMER);
+ }
+
/**
* 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:
*/
public static void ruleOrphanModules(@NotNull final List<Module> orphanModules,
@NotNull final Project project,
- @NotNull final ProjectSystemId externalSystemId)
+ @NotNull final ProjectSystemId externalSystemId,
+ @NotNull final Consumer<Boolean> result)
{
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
}
};
boolean ok = dialog.showAndGet();
+ result.consume(ok);
if (!ok) {
return;
}
ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(runnerId);
if (runner == null) return null;
+ RunnerAndConfigurationSettings settings = createExternalSystemRunnerAndConfigurationSettings(taskSettings, project, externalSystemId);
+ if (settings == null) return null;
+
+ return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
+ }
+
+ @Nullable
+ public static RunnerAndConfigurationSettings createExternalSystemRunnerAndConfigurationSettings(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
+ @NotNull Project project,
+ @NotNull ProjectSystemId externalSystemId) {
AbstractExternalSystemTaskConfigurationType configurationType = findConfigurationType(externalSystemId);
if (configurationType == null) return null;
runConfiguration.getSettings().setScriptParameters(taskSettings.getScriptParameters());
runConfiguration.getSettings().setExecutionName(taskSettings.getExecutionName());
- return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
+ return settings;
}
@Nullable
return null;
}
- /**
- * Is expected to be called when given task info is about to be executed.
- * <p/>
- * Basically, this method updates recent tasks list at the corresponding external system tool window and
- * persists new recent tasks state.
- *
- * @param taskInfo task which is about to be executed
- * @param project target project
- */
- public static void updateRecentTasks(@NotNull ExternalTaskExecutionInfo taskInfo, @NotNull Project project) {
- ProjectSystemId externalSystemId = taskInfo.getSettings().getExternalSystemId();
- ExternalSystemRecentTasksList recentTasksList = getToolWindowElement(ExternalSystemRecentTasksList.class,
- project,
- ExternalSystemDataKeys.RECENT_TASKS_LIST,
- externalSystemId);
- if (recentTasksList == null) {
- return;
- }
- recentTasksList.setFirst(taskInfo);
-
- ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
- assert manager != null;
- AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
- settings.setRecentTasks(recentTasksList.getModel().getTasks());
- }
-
@Nullable
public static String getRunnerId(@NotNull String executorId) {
return RUNNER_IDS.get(executorId);
return file[0];
}
+ public static void scheduleExternalViewStructureUpdate(final Project project, final ProjectSystemId systemId) {
+ ExternalProjectsView externalProjectsView = ExternalProjectsManager.getInstance(project).getExternalProjectsView(systemId);
+ if (externalProjectsView != null) {
+ externalProjectsView.scheduleStructureUpdate();
+ }
+ }
+
+ @Nullable
+ public static ExternalProjectInfo getExternalProjectInfo(@NotNull final Project project,
+ @NotNull final ProjectSystemId projectSystemId,
+ @NotNull final String externalProjectPath) {
+ final ExternalProjectSettings linkedProjectSettings =
+ ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectSettings(externalProjectPath);
+ if (linkedProjectSettings == null) return null;
+
+ return ProjectDataManager.getInstance().getExternalProjectData(
+ project, projectSystemId, linkedProjectSettings.getExternalProjectPath());
+ }
+
+
private interface TaskUnderProgress {
void execute(@NotNull ProgressIndicator indicator);
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.ui.treeStructure.SimpleTreeBuilder;
+import com.intellij.ui.treeStructure.SimpleTreeStructure;
+import com.intellij.util.Consumer;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 9/22/2014
+ */
+public class ExternalProjectsStructure extends SimpleTreeStructure {
+ private final Project myProject;
+ private final ExternalProjectsView myExternalProjectsView;
+ private final SimpleTreeBuilder myTreeBuilder;
+ private final RootNode myRoot;
+
+ private final Map<String, ExternalSystemNode> myNodeMapping = new THashMap<String, ExternalSystemNode>();
+
+ public ExternalProjectsStructure(Project project, ExternalProjectsView externalProjectsView, SimpleTree tree) {
+ myProject = project;
+ myExternalProjectsView = externalProjectsView;
+
+ configureTree(tree);
+
+ myTreeBuilder = new SimpleTreeBuilder(tree, (DefaultTreeModel)tree.getModel(), this, null);
+ Disposer.register(myProject, myTreeBuilder);
+
+ myRoot = new RootNode();
+ myTreeBuilder.initRoot();
+ myTreeBuilder.expand(myRoot, null);
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ void updateFrom(SimpleNode node) {
+ myTreeBuilder.addSubtreeToUpdateByElement(node);
+ }
+
+ void updateUpTo(SimpleNode node) {
+ SimpleNode each = node;
+ while (each != null) {
+ updateFrom(each);
+ each = each.getParent();
+ }
+ }
+
+ @Override
+ public Object getRootElement() {
+ return myRoot;
+ }
+
+ private static void configureTree(final SimpleTree tree) {
+ tree.setRootVisible(false);
+ tree.setShowsRootHandles(true);
+ }
+
+ public void updateProjects(Collection<DataNode<ProjectData>> toImport) {
+ for (DataNode<ProjectData> each : toImport) {
+ final ProjectData projectData = each.getData();
+ ExternalSystemNode projectNode = findNodeFor(projectData.getLinkedExternalProjectPath());
+
+ if (projectNode instanceof ProjectNode) {
+ doMergeChildrenChanges(projectNode, each, new ProjectNode(myExternalProjectsView, each));
+ }
+ else {
+ ExternalSystemNode node = myNodeMapping.remove(projectData.getLinkedExternalProjectPath());
+ if (node != null) {
+ SimpleNode parent = node.getParent();
+ if (parent instanceof ExternalSystemNode) {
+ ((ExternalSystemNode)parent).remove(projectNode);
+ }
+ }
+
+ projectNode = new ProjectNode(myExternalProjectsView, each);
+ myNodeMapping.put(projectData.getLinkedExternalProjectPath(), projectNode);
+ }
+ if (toImport.size() == 0) {
+ myTreeBuilder.expand(projectNode, null);
+ }
+ doUpdateProject((ProjectNode)projectNode);
+ }
+ }
+
+ private void doMergeChildrenChanges(ExternalSystemNode currentNode, DataNode<?> newDataNode, ExternalSystemNode newNode) {
+ final ExternalSystemNode[] cached = currentNode.getCached();
+ if (cached != null) {
+ Map<Object, ExternalSystemNode> oldDataMap = ContainerUtil.newLinkedHashMap();
+ for (ExternalSystemNode node : cached) {
+ Object key = node.getData() != null ? node.getData() : node.getName();
+ oldDataMap.put(key, node);
+ }
+
+ Map<Object, ExternalSystemNode> newDataMap = ContainerUtil.newLinkedHashMap();
+ Map<Object, ExternalSystemNode> unchangedNewDataMap = ContainerUtil.newLinkedHashMap();
+ for (ExternalSystemNode node : newNode.getChildren()) {
+ Object key = node.getData() != null ? node.getData() : node.getName();
+ if (oldDataMap.remove(key) == null) {
+ newDataMap.put(key, node);
+ }
+ else {
+ unchangedNewDataMap.put(key, node);
+ }
+ }
+
+ currentNode.removeAll(oldDataMap.values());
+
+ for (ExternalSystemNode node : currentNode.getChildren()) {
+ Object key = node.getData() != null ? node.getData() : node.getName();
+ final ExternalSystemNode unchangedNewNode = unchangedNewDataMap.get(key);
+ if (unchangedNewNode != null) {
+ doMergeChildrenChanges(node, unchangedNewNode.myDataNode, unchangedNewNode);
+ }
+ }
+
+ updateFrom(currentNode);
+ currentNode.addAll(newDataMap.values());
+ }
+ //noinspection unchecked
+ currentNode.setDataNode(newDataNode);
+ }
+
+ private void doUpdateProject(ProjectNode node) {
+ ExternalSystemNode newParentNode = myRoot;
+ node.updateProject();
+ reconnectNode(node, newParentNode);
+ }
+
+ private static void reconnectNode(ProjectNode node, ExternalSystemNode newParentNode) {
+ ExternalSystemNode oldParentNode = node.getGroup();
+ if (oldParentNode == null || !oldParentNode.equals(newParentNode)) {
+ if (oldParentNode != null) {
+ oldParentNode.remove(node);
+ }
+ newParentNode.add(node);
+ }
+ }
+
+ @SuppressWarnings("SuspiciousMethodCalls")
+ private ExternalSystemNode findNodeFor(String projectPath) {
+ return myNodeMapping.get(projectPath);
+ }
+
+ public <T extends ExternalSystemNode> void updateNodes(@NotNull Class<T> nodeClass) {
+ for (T node : getNodes(nodeClass)) {
+ updateFrom(node);
+ }
+ }
+
+ public <T extends ExternalSystemNode> void visitNodes(@NotNull Class<T> nodeClass, @NotNull Consumer<T> consumer) {
+ for (T node : getNodes(nodeClass)) {
+ consumer.consume(node);
+ }
+ }
+
+ public class RootNode<T> extends ExternalSystemNode<T> {
+ public RootNode() {
+ super(myExternalProjectsView, null, null);
+ }
+
+ @Override
+ public boolean isVisible() {
+ return true;
+ }
+ }
+
+ public enum ErrorLevel {
+ NONE, ERROR
+ }
+
+ enum DisplayKind {
+ ALWAYS, NEVER, NORMAL
+ }
+
+ @NotNull
+ public <T extends ExternalSystemNode> List<T> getNodes(@NotNull Class<T> nodeClass) {
+ return doGetNodes(nodeClass, myRoot.getChildren(), new SmartList<T>());
+ }
+
+ @NotNull
+ private static <T extends ExternalSystemNode> List<T> doGetNodes(@NotNull Class<T> nodeClass,
+ SimpleNode[] nodes,
+ @NotNull List<T> result) {
+ if (nodes == null) return result;
+
+ for (SimpleNode node : nodes) {
+ if (nodeClass.isInstance(node)) {
+ //noinspection unchecked
+ result.add((T)node);
+ }
+ doGetNodes(nodeClass, node.getChildren(), result);
+ }
+ return result;
+ }
+
+ @NotNull
+ public <T extends ExternalSystemNode> List<T> getSelectedNodes(SimpleTree tree, Class<T> nodeClass) {
+ final List<T> filtered = new ArrayList<T>();
+ for (SimpleNode node : getSelectedNodes(tree)) {
+ if ((nodeClass != null) && (!nodeClass.isInstance(node))) {
+ filtered.clear();
+ break;
+ }
+ //noinspection unchecked
+ filtered.add((T)node);
+ }
+ return filtered;
+ }
+
+ private static List<SimpleNode> getSelectedNodes(SimpleTree tree) {
+ List<SimpleNode> nodes = new ArrayList<SimpleNode>();
+ TreePath[] treePaths = tree.getSelectionPaths();
+ if (treePaths != null) {
+ for (TreePath treePath : treePaths) {
+ nodes.add(tree.getNodeFor(treePath));
+ }
+ }
+ return nodes;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.execution.*;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.treeView.TreeState;
+import com.intellij.lang.Language;
+import com.intellij.notification.NotificationGroup;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.action.ExternalSystemViewGearAction;
+import com.intellij.openapi.externalSystem.model.*;
+import com.intellij.openapi.externalSystem.model.Key;
+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.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskLocation;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemShortcutsManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener;
+import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter;
+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.fileTypes.PlainTextFileType;
+import com.intellij.openapi.module.ModuleTypeId;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.SimpleToolWindowPanel;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ex.ToolWindowEx;
+import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
+import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
+import com.intellij.openapi.wm.impl.ToolWindowImpl;
+import com.intellij.pom.Navigatable;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.source.DummyHolderFactory;
+import com.intellij.ui.PopupHandler;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.util.Consumer;
+import com.intellij.util.DisposeAwareRunnable;
+import com.intellij.util.Function;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.tree.TreeSelectionModel;
+import java.awt.*;
+import java.net.URL;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 9/19/2014
+ */
+public class ExternalProjectsView extends SimpleToolWindowPanel implements DataProvider {
+ public static final Logger LOG = Logger.getInstance(ExternalProjectsView.class);
+
+ @NotNull
+ private final Project myProject;
+ @NotNull
+ private final ExternalProjectsManager myProjectsManager;
+ @NotNull
+ private final ToolWindowEx myToolWindow;
+ @NotNull
+ private final ProjectSystemId myExternalSystemId;
+ @NotNull
+ private final ExternalSystemUiAware myUiAware;
+
+ @Nullable
+ private ExternalProjectsStructure myStructure;
+ private SimpleTree myTree;
+ @NotNull
+ private final NotificationGroup myNotificationGroup;
+
+ private ExternalProjectsViewState myState = new ExternalProjectsViewState();
+
+ public ExternalProjectsView(@NotNull Project project, @NotNull ToolWindowEx toolWindow, @NotNull ProjectSystemId externalSystemId) {
+ super(true, true);
+ myProject = project;
+ myToolWindow = toolWindow;
+ myExternalSystemId = externalSystemId;
+ myUiAware = ExternalSystemUiUtil.getUiAware(externalSystemId);
+ myProjectsManager = ExternalProjectsManager.getInstance(myProject);
+
+ String toolWindowId =
+ toolWindow instanceof ToolWindowImpl ? ((ToolWindowImpl)toolWindow).getId() : myExternalSystemId.getReadableName();
+
+ myNotificationGroup = NotificationGroup.toolWindowGroup(
+ "notification.group.id." + externalSystemId.getId().toLowerCase(Locale.ENGLISH), toolWindowId);
+ }
+
+ @Nullable
+ @Override
+ public Object getData(@NonNls String dataId) {
+ if (ExternalSystemDataKeys.VIEW.is(dataId)) return this;
+
+ if (PlatformDataKeys.HELP_ID.is(dataId)) return "reference.toolwindows.gradle";
+ if (CommonDataKeys.PROJECT.is(dataId)) return myProject;
+ if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) return extractVirtualFile();
+ if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return extractVirtualFiles();
+ if (Location.DATA_KEY.is(dataId)) {
+ return extractLocation();
+ }
+ if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) return extractNavigatables();
+
+ if (ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.is(dataId)) return myExternalSystemId;
+ if (ExternalSystemDataKeys.UI_AWARE.is(dataId)) return myUiAware;
+ if (ExternalSystemDataKeys.SELECTED_PROJECT_NODE.is(dataId)) return getSelectedProjectNode();
+ if (ExternalSystemDataKeys.SELECTED_NODES.is(dataId)) return getSelectedNodes(ExternalSystemNode.class);
+ if (ExternalSystemDataKeys.PROJECTS_TREE.is(dataId)) return myTree;
+ if (ExternalSystemDataKeys.NOTIFICATION_GROUP.is(dataId)) return myNotificationGroup;
+
+ return super.getData(dataId);
+ }
+
+ @NotNull
+ public Project getProject() {
+ return myProject;
+ }
+
+ @NotNull
+ public ExternalSystemUiAware getUiAware() {
+ return myUiAware;
+ }
+
+ public ExternalSystemShortcutsManager getShortcutsManager() {
+ return myProjectsManager.getShortcutsManager();
+ }
+
+ public ExternalSystemTaskActivator getTaskActivator() {
+ return myProjectsManager.getTaskActivator();
+ }
+
+ @NotNull
+ public ProjectSystemId getSystemId() {
+ return myExternalSystemId;
+ }
+
+ @NotNull
+ public NotificationGroup getNotificationGroup() {
+ return myNotificationGroup;
+ }
+
+ public void init() {
+ initTree();
+
+ final ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(myProject);
+
+ final ToolWindowManagerAdapter listener = new ToolWindowManagerAdapter() {
+ boolean wasVisible = false;
+
+ @Override
+ public void stateChanged() {
+ if (myToolWindow.isDisposed()) return;
+ boolean visible = myToolWindow.isVisible();
+ if (!visible || wasVisible) {
+ wasVisible = visible;
+ return;
+ }
+ scheduleStructureUpdate();
+ wasVisible = true;
+ }
+ };
+ manager.addToolWindowManagerListener(listener);
+
+ Disposer.register(myProject, new Disposable() {
+ public void dispose() {
+ manager.removeToolWindowManagerListener(listener);
+ }
+ });
+
+ getShortcutsManager().addListener(new ExternalSystemShortcutsManager.Listener() {
+ @Override
+ public void shortcutsUpdated() {
+ scheduleTasksUpdate();
+
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ myStructure.updateNodes(RunConfigurationNode.class);
+ }
+ });
+ }
+ });
+
+ getTaskActivator().addListener(new ExternalSystemTaskActivator.Listener() {
+ @Override
+ public void tasksActivationChanged() {
+ scheduleTasksUpdate();
+
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ myStructure.updateNodes(RunConfigurationNode.class);
+ }
+ });
+ }
+ });
+
+ ((RunManagerEx)RunManager.getInstance(myProject)).addRunManagerListener(new RunManagerAdapter() {
+ private void changed() {
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ myStructure.visitNodes(ModuleNode.class, new Consumer<ModuleNode>() {
+ @Override
+ public void consume(ModuleNode node) {
+ node.updateRunConfigurations();
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ public void runConfigurationAdded(@NotNull RunnerAndConfigurationSettings settings) {
+ changed();
+ }
+
+ @Override
+ public void runConfigurationRemoved(@NotNull RunnerAndConfigurationSettings settings) {
+ changed();
+ }
+
+ @Override
+ public void runConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings) {
+ changed();
+ }
+ });
+
+ ExternalSystemApiUtil.subscribe(myProject, myExternalSystemId, new ExternalSystemSettingsListenerAdapter(){
+ @Override
+ public void onUseAutoImportChange(boolean currentValue, @NotNull final String linkedProjectPath) {
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ final List<ProjectNode> projectNodes = myStructure.getNodes(ProjectNode.class);
+ for (ProjectNode projectNode : projectNodes) {
+ final ProjectData projectData = projectNode.getData();
+ if(projectData != null && projectData.getLinkedExternalProjectPath().equals(linkedProjectPath)) {
+ projectNode.updateProject();
+ break;
+ }
+ }
+ }
+ });
+ }
+ });
+
+ ActionManager actionManager = ActionManager.getInstance();
+
+ DefaultActionGroup group = new DefaultActionGroup();
+ final AnAction gearAction = actionManager.getAction("ExternalSystem.GroupTasks");
+ if(gearAction instanceof ExternalSystemViewGearAction) {
+ ((ExternalSystemViewGearAction)gearAction).setView(this);
+ group.add(gearAction);
+ }
+
+ myToolWindow.setAdditionalGearActions(group);
+
+ scheduleStructureUpdate();
+ }
+
+ private void initStructure() {
+ myStructure = new ExternalProjectsStructure(myProject, this, myTree);
+ }
+
+ private void initTree() {
+ myTree = new SimpleTree();
+ myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+
+ final ActionManager actionManager = ActionManager.getInstance();
+ ActionToolbar actionToolbar = actionManager.createActionToolbar(myExternalSystemId.getReadableName() + " View Toolbar",
+ (DefaultActionGroup)actionManager
+ .getAction("ExternalSystemView.ActionsToolbar"), true);
+
+ actionToolbar.setTargetComponent(myTree);
+ setToolbar(actionToolbar.getComponent());
+ setContent(ScrollPaneFactory.createScrollPane(myTree));
+
+ myTree.addMouseListener(new PopupHandler() {
+ public void invokePopup(final Component comp, final int x, final int y) {
+ final String id = getMenuId(getSelectedNodes(ExternalSystemNode.class));
+ if (id != null) {
+ final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(id);
+ if (actionGroup != null) {
+ actionManager.createActionPopupMenu("", actionGroup).getComponent().show(comp, x, y);
+ }
+ }
+ }
+
+ @Nullable
+ private String getMenuId(Collection<? extends ExternalSystemNode> nodes) {
+ String id = null;
+ for (ExternalSystemNode node : nodes) {
+ String menuId = node.getMenuId();
+ if (menuId == null) {
+ return null;
+ }
+ if (id == null) {
+ id = menuId;
+ }
+ else if (!id.equals(menuId)) {
+ return null;
+ }
+ }
+ return id;
+ }
+ });
+ }
+
+ public void scheduleStructureUpdate() {
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ final Collection<ExternalProjectInfo> projectsData =
+ ProjectDataManager.getInstance().getExternalProjectsData(myProject, myExternalSystemId);
+
+ final List<DataNode<ProjectData>> toImport =
+ ContainerUtil.mapNotNull(projectsData, new Function<ExternalProjectInfo, DataNode<ProjectData>>() {
+ @Override
+ public DataNode<ProjectData> fun(ExternalProjectInfo info) {
+ return info.getExternalProjectStructure();
+ }
+ });
+
+ assert myStructure != null;
+ myStructure.updateProjects(toImport);
+ }
+ });
+ }
+
+ protected boolean isUnitTestMode() {
+ return ApplicationManager.getApplication().isUnitTestMode();
+ }
+
+ public static void invokeLater(Project p, Runnable r) {
+ invokeLater(p, ModalityState.defaultModalityState(), r);
+ }
+
+ public static void invokeLater(final Project p, final ModalityState state, final Runnable r) {
+ if (isNoBackgroundMode()) {
+ r.run();
+ }
+ else {
+ ApplicationManager.getApplication().invokeLater(DisposeAwareRunnable.create(r, p), state);
+ }
+ }
+
+ public static boolean isNoBackgroundMode() {
+ return (ApplicationManager.getApplication().isUnitTestMode()
+ || ApplicationManager.getApplication().isHeadlessEnvironment());
+ }
+
+ public void updateUpTo(ExternalSystemNode node) {
+ if (myStructure != null) {
+ myStructure.updateUpTo(node);
+ }
+ }
+
+ @Nullable
+ protected ExternalProjectsStructure getStructure() {
+ return myStructure;
+ }
+
+ @NotNull
+ public List<ExternalSystemNode<?>> createNodes(@Nullable ExternalSystemNode<?> parent, @NotNull DataNode<?> dataNode) {
+ final List<ExternalSystemNode<?>> result = new SmartList<ExternalSystemNode<?>>();
+ final Map<Key<?>, List<DataNode<?>>> groups = ExternalSystemApiUtil.group(dataNode.getChildren());
+ for (ExternalSystemViewContributor contributor : ExternalSystemViewContributor.EP_NAME.getExtensions()) {
+ List<Key<?>> keys = contributor.getKeys();
+
+ final MultiMap<Key<?>, DataNode<?>> dataNodes = MultiMap.create();
+ for (Key<?> key : keys) {
+ final List<DataNode<?>> values = groups.get(key);
+ if(key != null && values != null) {
+ dataNodes.put(key, values);
+ }
+ }
+
+ if (dataNodes.isEmpty()) continue;
+
+ final List<ExternalSystemNode<?>> childNodes = contributor.createNodes(this, dataNodes);
+ result.addAll(childNodes);
+
+ if (parent == null) continue;
+
+ for (ExternalSystemNode childNode : childNodes) {
+ childNode.setParent(parent);
+ }
+ }
+
+ return result;
+ }
+
+ @Nullable
+ public ExternalProjectsViewState getState() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (myStructure != null) {
+ try {
+ myState.treeState = new Element("root");
+ TreeState.createOn(myTree).writeExternal(myState.treeState);
+ }
+ catch (WriteExternalException e) {
+ LOG.warn(e);
+ }
+ }
+ return myState;
+ }
+
+ public void loadState(ExternalProjectsViewState state) {
+ myState = state;
+ }
+
+ public boolean getGroupTasks() {
+ return myState.groupTasks;
+ }
+
+ public void setGroupTasks(boolean value) {
+ if (myState.groupTasks != value) {
+ myState.groupTasks = value;
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ final List<TasksNode> tasksNodes = myStructure.getNodes(TasksNode.class);
+ for (TasksNode tasksNode : tasksNodes) {
+ tasksNode.cleanUpCache();
+ updateUpTo(tasksNode);
+ }
+ }
+ });
+ }
+ }
+
+ private void scheduleTasksUpdate() {
+ scheduleStructureRequest(new Runnable() {
+ public void run() {
+ assert myStructure != null;
+ myStructure.updateNodes(TaskNode.class);
+ }
+ });
+ }
+
+ private void scheduleStructureRequest(final Runnable r) {
+ if (isUnitTestMode()) {
+ r.run();
+ return;
+ }
+
+ invokeLater(myProject, new Runnable() {
+ public void run() {
+ if (!myToolWindow.isVisible()) return;
+
+ boolean shouldCreate = myStructure == null;
+ if (shouldCreate) {
+ initStructure();
+ }
+
+ myTree.setPaintBusy(true);
+ try {
+ r.run();
+ if (shouldCreate) {
+ restoreTreeState();
+ }
+ }
+ finally {
+ myTree.setPaintBusy(false);
+ }
+ }
+ });
+ }
+
+ private void restoreTreeState() {
+ if (myState.treeState != null) {
+ TreeState treeState = new TreeState();
+ try {
+ treeState.readExternal(myState.treeState);
+ treeState.applyTo(myTree);
+ }
+ catch (InvalidDataException e) {
+ LOG.info(e);
+ }
+ }
+ }
+
+ private <T extends ExternalSystemNode> List<T> getSelectedNodes(Class<T> aClass) {
+ return myStructure != null ? myStructure.getSelectedNodes(myTree, aClass) : ContainerUtil.<T>emptyList();
+ }
+
+ private List<ProjectNode> getSelectedProjectNodes() {
+ return getSelectedNodes(ProjectNode.class);
+ }
+
+ @Nullable
+ private ProjectNode getSelectedProjectNode() {
+ final List<ProjectNode> projectNodes = getSelectedProjectNodes();
+ return projectNodes.size() == 1 ? projectNodes.get(0) : null;
+ }
+
+ @Nullable
+ private Location extractLocation() {
+ final List<ExternalSystemNode> selectedNodes = getSelectedNodes(ExternalSystemNode.class);
+ if (selectedNodes.isEmpty()) return null;
+
+ List<TaskData> tasks = ContainerUtil.newSmartList();
+
+ ExternalTaskExecutionInfo taskExecutionInfo = new ExternalTaskExecutionInfo();
+
+ String projectPath = null;
+
+ for (ExternalSystemNode node : selectedNodes) {
+ final Object data = node.getData();
+ if (data instanceof TaskData) {
+ final TaskData taskData = (TaskData)data;
+ if (projectPath == null) {
+ projectPath = taskData.getLinkedExternalProjectPath();
+ }
+ else if (!taskData.getLinkedExternalProjectPath().equals(projectPath)) {
+ return null;
+ }
+
+ taskExecutionInfo.getSettings().getTaskNames().add(taskData.getName());
+ taskExecutionInfo.getSettings().getTaskDescriptions().add(taskData.getDescription());
+ tasks.add(taskData);
+ }
+ }
+
+ if(tasks.isEmpty()) return null;
+
+ taskExecutionInfo.getSettings().setExternalSystemIdString(myExternalSystemId.toString());
+ taskExecutionInfo.getSettings().setExternalProjectPath(projectPath);
+
+ String name = myExternalSystemId.getReadableName() + projectPath + StringUtil.join(taskExecutionInfo.getSettings().getTaskNames(), " ");
+ // We create a dummy text file instead of re-using external system file in order to avoid clashing with other configuration producers.
+ // For example gradle files are enhanced groovy scripts but we don't want to run them via regular IJ groovy script runners.
+ // Gradle tooling api should be used for running gradle tasks instead. IJ execution sub-system operates on Location objects
+ // which encapsulate PsiElement and groovy runners are automatically applied if that PsiElement IS-A GroovyFile.
+ PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name, PlainTextFileType.INSTANCE, "");
+ return new ExternalSystemTaskLocation(myProject, file, taskExecutionInfo);
+ }
+
+ private VirtualFile extractVirtualFile() {
+ for (ExternalSystemNode each : getSelectedNodes(ExternalSystemNode.class)) {
+ VirtualFile file = each.getVirtualFile();
+ if (file != null && file.isValid()) return file;
+ }
+
+ final ProjectNode projectNode = getSelectedProjectNode();
+ if (projectNode == null) return null;
+ VirtualFile file = projectNode.getVirtualFile();
+ if (file == null || !file.isValid()) return null;
+ return file;
+ }
+
+ private Object extractVirtualFiles() {
+ final List<VirtualFile> files = new ArrayList<VirtualFile>();
+ for (ExternalSystemNode each : getSelectedNodes(ExternalSystemNode.class)) {
+ VirtualFile file = each.getVirtualFile();
+ if (file != null && file.isValid()) files.add(file);
+ }
+ return files.isEmpty() ? null : VfsUtilCore.toVirtualFileArray(files);
+ }
+
+ private Object extractNavigatables() {
+ final List<Navigatable> navigatables = new ArrayList<Navigatable>();
+ for (ExternalSystemNode each : getSelectedNodes(ExternalSystemNode.class)) {
+ Navigatable navigatable = each.getNavigatable();
+ if (navigatable != null) navigatables.add(navigatable);
+ }
+ return navigatables.isEmpty() ? null : navigatables.toArray(new Navigatable[navigatables.size()]);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
+import com.intellij.openapi.externalSystem.action.ExternalSystemActionUtil;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemShortcutsManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
+import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/15/2014
+ */
+public abstract class ExternalSystemNode<T> extends SimpleNode implements Comparable<ExternalSystemNode> {
+
+
+ @NotNull public static final Comparator<ExternalSystemNode> ORDER_AWARE_COMPARATOR = new Comparator<ExternalSystemNode>() {
+
+ @Override
+ public int compare(@NotNull ExternalSystemNode o1, @NotNull ExternalSystemNode o2) {
+ int order1 = getOrder(o1);
+ int order2 = getOrder(o2);
+ if (order1 == order2) return o1.compareTo(o2);
+ return order1 < order2 ? -1 : 1;
+ }
+
+ private int getOrder(@NotNull Comparable o) {
+ Order annotation = o.getClass().getAnnotation(Order.class);
+ if (annotation != null) {
+ return annotation.value();
+ }
+ return 0;
+ }
+ };
+
+
+ protected static final ExternalSystemNode[] NO_CHILDREN = new ExternalSystemNode[0];
+
+ private final ExternalProjectsView myExternalProjectsView;
+ private final List<ExternalSystemNode<?>> myChildrenList = ContainerUtil.newArrayList();
+ protected DataNode<T> myDataNode;
+ @Nullable
+ private ExternalSystemNode myParent;
+ private ExternalSystemNode[] myChildren;
+ private ExternalProjectsStructure.ErrorLevel myErrorLevel = ExternalProjectsStructure.ErrorLevel.NONE;
+ private ExternalProjectsStructure.ErrorLevel myTotalErrorLevel = null;
+
+ public ExternalSystemNode(@NotNull ExternalProjectsView externalProjectsView,
+ @Nullable ExternalSystemNode parent) {
+ this(externalProjectsView, parent, null);
+ }
+
+ public ExternalSystemNode(@NotNull ExternalProjectsView externalProjectsView,
+ @Nullable ExternalSystemNode parent,
+ @Nullable DataNode<T> dataNode) {
+ super(externalProjectsView.getProject(), null);
+ myExternalProjectsView = externalProjectsView;
+ myDataNode = dataNode;
+ myParent = parent;
+ }
+
+ public void setParent(@Nullable ExternalSystemNode parent) {
+ myParent = parent;
+ }
+
+ @Nullable
+ public T getData() {
+ return myDataNode != null ? myDataNode.getData() : null;
+ }
+
+ @Override
+ public NodeDescriptor getParentDescriptor() {
+ return myParent;
+ }
+
+ protected ExternalProjectsView getExternalProjectsView() {
+ return myExternalProjectsView;
+ }
+
+ protected ExternalSystemUiAware getUiAware() {
+ return myExternalProjectsView.getUiAware();
+ }
+
+ protected ExternalProjectsStructure getStructure() {
+ return myExternalProjectsView.getStructure();
+ }
+
+ protected ExternalSystemShortcutsManager getShortcutsManager() {
+ return myExternalProjectsView.getShortcutsManager();
+ }
+
+ protected ExternalSystemTaskActivator getTaskActivator() {
+ return myExternalProjectsView.getTaskActivator();
+ }
+
+ @Nullable
+ public <T extends ExternalSystemNode> T findParent(Class<T> parentClass) {
+ ExternalSystemNode node = this;
+ while (true) {
+ node = node.myParent;
+ if (node == null || parentClass.isInstance(node)) {
+ //noinspection unchecked
+ return (T)node;
+ }
+ }
+ }
+
+ @Nullable
+ public <DataType> DataType findParentData(Class<DataType> parentDataClass) {
+ ExternalSystemNode node = this;
+ while (true) {
+ node = node.myParent;
+ if (node == null) return null;
+ if (node.getData() != null && parentDataClass.isInstance(node.getData())) {
+ //noinspection unchecked
+ return (DataType)node.getData();
+ }
+ }
+ }
+
+ public boolean isVisible() {
+ return getDisplayKind() != ExternalProjectsStructure.DisplayKind.NEVER;
+ }
+
+ public ExternalProjectsStructure.DisplayKind getDisplayKind() {
+ return ExternalProjectsStructure.DisplayKind.NORMAL;
+ }
+
+ @NotNull
+ public final ExternalSystemNode[] getChildren() {
+ if (myChildren == null) {
+ myChildren = buildChildren();
+ onChildrenBuilt();
+ }
+ return myChildren;
+ }
+
+ protected void onChildrenBuilt() {
+ }
+
+ @NotNull
+ private ExternalSystemNode[] buildChildren() {
+ List<? extends ExternalSystemNode> newChildrenCandidates = doBuildChildren();
+ if (newChildrenCandidates.isEmpty()) return NO_CHILDREN;
+
+ addAll(newChildrenCandidates, true);
+ sort(myChildrenList);
+ List<ExternalSystemNode> visibleNodes = new ArrayList<ExternalSystemNode>();
+ for (ExternalSystemNode each : myChildrenList) {
+ if (each.isVisible()) visibleNodes.add(each);
+ }
+ return visibleNodes.toArray(new ExternalSystemNode[visibleNodes.size()]);
+ }
+
+ public void cleanUpCache() {
+ myChildren = null;
+ myChildrenList.clear();
+ myTotalErrorLevel = null;
+ }
+
+ @Nullable
+ protected ExternalSystemNode[] getCached() {
+ return myChildren;
+ }
+
+ protected void sort(List<? extends ExternalSystemNode> list) {
+ Collections.sort(list, ORDER_AWARE_COMPARATOR);
+ }
+
+ protected boolean addAll(Collection<? extends ExternalSystemNode> externalSystemNodes) {
+ return addAll(externalSystemNodes, false);
+ }
+
+ private boolean addAll(Collection<? extends ExternalSystemNode> externalSystemNodes, boolean silently) {
+ if (externalSystemNodes.isEmpty()) return false;
+
+ for (ExternalSystemNode externalSystemNode : externalSystemNodes) {
+ externalSystemNode.setParent(this);
+ myChildrenList.add(externalSystemNode);
+ }
+ if (!silently) {
+ childrenChanged();
+ }
+
+ return true;
+ }
+
+ protected boolean add(ExternalSystemNode externalSystemNode) {
+ return addAll(ContainerUtil.list(externalSystemNode));
+ }
+
+ protected boolean removeAll(Collection<ExternalSystemNode> externalSystemNodes) {
+ return removeAll(externalSystemNodes, false);
+ }
+
+ private boolean removeAll(Collection<ExternalSystemNode> externalSystemNodes, boolean silently) {
+ if (externalSystemNodes.isEmpty()) return false;
+
+ for (ExternalSystemNode externalSystemNode : externalSystemNodes) {
+ externalSystemNode.setParent(null);
+ myChildrenList.remove(externalSystemNode);
+ }
+ if (!silently) {
+ childrenChanged();
+ }
+
+ return true;
+ }
+
+ public void remove(ExternalSystemNode externalSystemNode) {
+ removeAll(ContainerUtil.list(externalSystemNode));
+ }
+
+ protected void childrenChanged() {
+ ExternalSystemNode each = this;
+ while (each != null) {
+ each.myTotalErrorLevel = null;
+ each = (ExternalSystemNode)each.getParent();
+ }
+
+ sort(myChildrenList);
+ final List<ExternalSystemNode<?>> visibleNodes = ContainerUtil.filter(myChildrenList, new Condition<ExternalSystemNode<?>>() {
+ @Override
+ public boolean value(ExternalSystemNode<?> node) {
+ return node.isVisible();
+ }
+ });
+ myChildren = visibleNodes.toArray(new ExternalSystemNode[visibleNodes.size()]);
+ myExternalProjectsView.updateUpTo(this);
+ }
+
+ public boolean hasChildren() {
+ return getChildren().length > 0;
+ }
+
+ @NotNull
+ protected List<? extends ExternalSystemNode> doBuildChildren() {
+ if (myDataNode != null && !myDataNode.getChildren().isEmpty()) {
+ return getExternalProjectsView().createNodes(this, myDataNode);
+ }
+ else {
+ return myChildrenList;
+ }
+ }
+
+ public void setDataNode(DataNode<T> dataNode) {
+ myDataNode = dataNode;
+ }
+
+ public ExternalProjectsStructure.ErrorLevel getTotalErrorLevel() {
+ if (myTotalErrorLevel == null) {
+ myTotalErrorLevel = calcTotalErrorLevel();
+ }
+ return myTotalErrorLevel;
+ }
+
+ private ExternalProjectsStructure.ErrorLevel calcTotalErrorLevel() {
+ ExternalProjectsStructure.ErrorLevel childrenErrorLevel = getChildrenErrorLevel();
+ return childrenErrorLevel.compareTo(myErrorLevel) > 0 ? childrenErrorLevel : myErrorLevel;
+ }
+
+ public ExternalProjectsStructure.ErrorLevel getChildrenErrorLevel() {
+ ExternalProjectsStructure.ErrorLevel result = ExternalProjectsStructure.ErrorLevel.NONE;
+ for (SimpleNode each : getChildren()) {
+ ExternalProjectsStructure.ErrorLevel eachLevel = ((ExternalSystemNode)each).getTotalErrorLevel();
+ if (eachLevel.compareTo(result) > 0) result = eachLevel;
+ }
+ return result;
+ }
+
+ public void setErrorLevel(ExternalProjectsStructure.ErrorLevel level) {
+ if (myErrorLevel == level) return;
+ myErrorLevel = level;
+ myExternalProjectsView.updateUpTo(this);
+ }
+
+ @Override
+ protected void doUpdate() {
+ setNameAndTooltip(getName(), null);
+ }
+
+ protected void setNameAndTooltip(String name, @Nullable String tooltip) {
+ setNameAndTooltip(name, tooltip, (String)null);
+ }
+
+ protected void setNameAndTooltip(String name, @Nullable String tooltip, @Nullable String hint) {
+ setNameAndTooltip(name, tooltip, getPlainAttributes());
+ if (!StringUtil.isEmptyOrSpaces(hint)) {
+ addColoredFragment(" (" + hint + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+ }
+
+ protected void setNameAndTooltip(String name, @Nullable String tooltip, SimpleTextAttributes attributes) {
+ clearColoredText();
+ addColoredFragment(name, prepareAttributes(attributes));
+ getTemplatePresentation().setTooltip(tooltip);
+ }
+
+ private SimpleTextAttributes prepareAttributes(SimpleTextAttributes from) {
+ ExternalProjectsStructure.ErrorLevel level = getTotalErrorLevel();
+ Color waveColor = level == ExternalProjectsStructure.ErrorLevel.NONE ? null : JBColor.RED;
+ int style = from.getStyle();
+ if (waveColor != null) style |= SimpleTextAttributes.STYLE_WAVED;
+ return new SimpleTextAttributes(from.getBgColor(), from.getFgColor(), waveColor, style);
+ }
+
+ @Nullable
+ @NonNls
+ protected String getActionId() {
+ return null;
+ }
+
+ @Nullable
+ @NonNls
+ protected String getMenuId() {
+ return null;
+ }
+
+ protected String message(@NotNull String key, @NotNull Object... params) {
+ return ExternalSystemBundle.message(key);
+ }
+
+ @Nullable
+ public VirtualFile getVirtualFile() {
+ return null;
+ }
+
+ @Nullable
+ public Navigatable getNavigatable() {
+ return null;
+ }
+
+ @Override
+ public void handleDoubleClickOrEnter(SimpleTree tree, InputEvent inputEvent) {
+ String actionId = getActionId();
+ if (actionId != null) {
+ ExternalSystemActionUtil.executeAction(actionId, inputEvent);
+ }
+ }
+
+ @Override
+ public int compareTo(@NotNull ExternalSystemNode node) {
+ return StringUtil.compare(this.getName(), node.getName(), true);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/10/2014
+ */
+public abstract class ExternalSystemViewContributor {
+ public static final ExtensionPointName<ExternalSystemViewContributor> EP_NAME =
+ ExtensionPointName.create("com.intellij.externalSystemViewContributor");
+
+ @NotNull
+ public abstract List<Key<?>> getKeys();
+
+ @NotNull
+ public abstract List<ExternalSystemNode<?>> createNodes(
+ ExternalProjectsView externalProjectsView, MultiMap<Key<?>, DataNode<?>> dataNodes);
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.project.LibraryDependencyData;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ModuleDependencyData;
+import com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper;
+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.Order;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
+import com.intellij.pom.Navigatable;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/10/2014
+ */
+public class ExternalSystemViewDefaultContributor extends ExternalSystemViewContributor {
+
+ private static final Key<?>[] KEYS = new Key[]{
+ ProjectKeys.MODULE,
+ ProjectKeys.MODULE_DEPENDENCY,
+ ProjectKeys.LIBRARY_DEPENDENCY,
+ ProjectKeys.TASK
+ };
+
+
+ @NotNull
+ @Override
+ public List<Key<?>> getKeys() {
+ return Arrays.asList(KEYS);
+ }
+
+ @Override
+ @NotNull
+ public List<ExternalSystemNode<?>> createNodes(final ExternalProjectsView externalProjectsView,
+ final MultiMap<Key<?>, DataNode<?>> dataNodes) {
+ final List<ExternalSystemNode<?>> result = new SmartList<ExternalSystemNode<?>>();
+
+ addModuleNodes(externalProjectsView, dataNodes, result);
+ // add tasks
+ result.add(new TasksNode(externalProjectsView, dataNodes.get(ProjectKeys.TASK)));
+ addDependenciesNode(externalProjectsView, dataNodes, result);
+
+ return result;
+ }
+
+ private static void addDependenciesNode(@NotNull ExternalProjectsView externalProjectsView,
+ @NotNull MultiMap<Key<?>, DataNode<?>> dataNodes,
+ @NotNull List<ExternalSystemNode<?>> result) {
+ final Collection<DataNode<?>> moduleDeps = dataNodes.get(ProjectKeys.MODULE_DEPENDENCY);
+ final Collection<DataNode<?>> libDeps = dataNodes.get(ProjectKeys.LIBRARY_DEPENDENCY);
+
+ if (!moduleDeps.isEmpty() || !libDeps.isEmpty()) {
+ final ExternalSystemNode depNode = new MyDependenciesNode(externalProjectsView);
+
+ for (DataNode<?> dataNode : moduleDeps) {
+ if (!(dataNode.getData() instanceof ModuleDependencyData)) continue;
+ //noinspection unchecked
+ depNode.add(new ModuleDependencyDataExternalSystemNode(externalProjectsView, (DataNode<ModuleDependencyData>)dataNode));
+ }
+
+ for (DataNode<?> dataNode : libDeps) {
+ if (!(dataNode.getData() instanceof LibraryDependencyData)) continue;
+ //noinspection unchecked
+ final ExternalSystemNode<LibraryDependencyData> libraryDependencyDataExternalSystemNode =
+ new LibraryDependencyDataExternalSystemNode(externalProjectsView, (DataNode<LibraryDependencyData>)dataNode);
+
+ depNode.add(libraryDependencyDataExternalSystemNode);
+ libraryDependencyDataExternalSystemNode.setErrorLevel(((LibraryDependencyData)dataNode.getData()).getTarget().isUnresolved()
+ ? ExternalProjectsStructure.ErrorLevel.ERROR
+ : ExternalProjectsStructure.ErrorLevel.NONE);
+ }
+
+ result.add(depNode);
+ }
+ }
+
+ private static void addModuleNodes(@NotNull ExternalProjectsView externalProjectsView,
+ @NotNull MultiMap<Key<?>, DataNode<?>> dataNodes,
+ @NotNull List<ExternalSystemNode<?>> result) {
+ final Collection<DataNode<?>> moduleDataNodes = dataNodes.get(ProjectKeys.MODULE);
+ if (!moduleDataNodes.isEmpty()) {
+ final AbstractExternalSystemSettings systemSettings =
+ ExternalSystemApiUtil.getSettings(externalProjectsView.getProject(), externalProjectsView.getSystemId());
+
+ for (DataNode<?> dataNode : moduleDataNodes) {
+ final ModuleData data = (ModuleData)dataNode.getData();
+
+ final ExternalProjectSettings projectSettings = systemSettings.getLinkedProjectSettings(data.getLinkedExternalProjectPath());
+ final boolean isRoot =
+ projectSettings != null && data.getLinkedExternalProjectPath().equals(projectSettings.getExternalProjectPath());
+ //noinspection unchecked
+ final ModuleNode moduleNode = new ModuleNode(externalProjectsView, (DataNode<ModuleData>)dataNode, isRoot);
+ result.add(moduleNode);
+ }
+ }
+ }
+
+ @Order(2)
+ private static class MyDependenciesNode extends ExternalSystemNode {
+ public MyDependenciesNode(ExternalProjectsView externalProjectsView) {
+ //noinspection unchecked
+ super(externalProjectsView, null, null);
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(AllIcons.Nodes.PpLibFolder);
+ }
+
+ @Override
+ public String getName() {
+ return "Dependencies";
+ }
+ }
+
+ private static class ModuleDependencyDataExternalSystemNode extends ExternalSystemNode<ModuleDependencyData> {
+
+ public ModuleDependencyDataExternalSystemNode(ExternalProjectsView externalProjectsView, DataNode<ModuleDependencyData> dataNode) {
+ super(externalProjectsView, null, dataNode);
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(getUiAware().getProjectIcon());
+
+ final ModuleDependencyData data = getData();
+ if (data != null) {
+ setNameAndTooltip(getName(), null, data.getScope().getDisplayName());
+ }
+ }
+
+ @Override
+ public String getName() {
+ final ModuleDependencyData data = getData();
+ return data != null ? data.getExternalName() : "";
+ }
+
+ @Override
+ public boolean isAlwaysLeaf() {
+ return true;
+ }
+ }
+
+ private static class LibraryDependencyDataExternalSystemNode extends ExternalSystemNode<LibraryDependencyData> {
+
+ public LibraryDependencyDataExternalSystemNode(ExternalProjectsView externalProjectsView, DataNode<LibraryDependencyData> dataNode) {
+ super(externalProjectsView, null, dataNode);
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(AllIcons.Nodes.PpLib);
+
+ final LibraryDependencyData data = getData();
+ if (data != null) {
+ setNameAndTooltip(getName(), null, data.getScope().getDisplayName());
+ }
+ }
+
+ @Override
+ public String getName() {
+ final LibraryDependencyData data = getData();
+ return data != null ? data.getExternalName() : "";
+ }
+
+ @Override
+ public boolean isAlwaysLeaf() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Navigatable getNavigatable() {
+ return new Navigatable() {
+ @Nullable
+ private OrderEntry myOrderEntry;
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ if (myOrderEntry != null) {
+ ProjectSettingsService.getInstance(myProject).openLibraryOrSdkSettings(myOrderEntry);
+ }
+ }
+
+ @Override
+ public boolean canNavigate() {
+ myOrderEntry = getOrderEntry();
+ return myOrderEntry != null;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return true;
+ }
+ };
+ }
+
+ @Nullable
+ private OrderEntry getOrderEntry() {
+ final LibraryDependencyData data = getData();
+ if (data == null) return null;
+ final Project project = getProject();
+ if (project == null) return null;
+ return ServiceManager.getService(ProjectStructureHelper.class).findIdeModuleOrderEntry(data, project);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/7/2014
+ */
+@Order(1)
+public class ModuleNode extends ExternalSystemNode<ModuleData> {
+ private final boolean myIsRoot;
+ private final ModuleData myData;
+ private final RunConfigurationsNode myRunConfigurationsNode;
+
+ public ModuleNode(ExternalProjectsView externalProjectsView,
+ DataNode<ModuleData> dataNode,
+ boolean isRoot) {
+ super(externalProjectsView, null, dataNode);
+ myIsRoot = isRoot;
+ myData = dataNode.getData();
+ myRunConfigurationsNode = new RunConfigurationsNode(externalProjectsView, this);
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(getUiAware().getProjectIcon());
+
+ String hint = null;
+ if (myIsRoot) {
+ hint = "root";
+ }
+
+ setNameAndTooltip(getName(), myData.toString(), hint);
+ }
+
+ @NotNull
+ @Override
+ protected List<? extends ExternalSystemNode> doBuildChildren() {
+ List<ExternalSystemNode<?>> myChildNodes = ContainerUtil.newArrayList();
+ //noinspection unchecked
+ myChildNodes.addAll((Collection<? extends ExternalSystemNode<?>>)super.doBuildChildren());
+ myChildNodes.add(myRunConfigurationsNode);
+ return myChildNodes;
+ }
+
+ @Override
+ public String getName() {
+ return myData.getId();
+ }
+
+ @Nullable
+ @Override
+ protected String getMenuId() {
+ return "ExternalSystemView.ProjectMenu";
+ }
+
+ @Override
+ public boolean isVisible() {
+ return true;
+ }
+
+ @Override
+ public int compareTo(@NotNull ExternalSystemNode node) {
+ return myIsRoot ? -1 : (node instanceof ModuleNode && ((ModuleNode)node).myIsRoot) ? 1 : super.compareTo(node);
+ }
+
+ public void updateRunConfigurations() {
+ myRunConfigurationsNode.updateRunConfigurations();
+ childrenChanged();
+ getExternalProjectsView().updateUpTo(this);
+ getExternalProjectsView().updateUpTo(myRunConfigurationsNode);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+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.util.Condition;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/15/2014
+ */
+public class ProjectNode extends ExternalSystemNode<ProjectData> {
+ private String myTooltipCache;
+
+ public ProjectNode(ExternalProjectsView externalProjectsView, DataNode<ProjectData> projectDataNode) {
+ super(externalProjectsView, null, projectDataNode);
+ updateProject();
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(getUiAware().getProjectIcon());
+ }
+
+ public ExternalSystemNode getGroup() {
+ return (ExternalSystemNode)getParent();
+ }
+
+ @NotNull
+ @Override
+ protected List<? extends ExternalSystemNode> doBuildChildren() {
+ final List<? extends ExternalSystemNode> children = super.doBuildChildren();
+ final List<ExternalSystemNode> visibleChildren = ContainerUtil.filter(children, new Condition<ExternalSystemNode>() {
+ @Override
+ public boolean value(ExternalSystemNode node) {
+ return node.isVisible();
+ }
+ });
+ //noinspection unchecked
+ return visibleChildren.size() == 1 ? children.get(0).doBuildChildren() : children;
+ }
+
+ void updateProject() {
+ myTooltipCache = makeDescription();
+ getStructure().updateFrom(getParent());
+ }
+
+ @Override
+ public String getName() {
+ final ProjectData projectData = getData();
+ return projectData != null ? projectData.getExternalName() : "unspecified";
+ }
+
+ @Override
+ protected void doUpdate() {
+ String autoImportHint = null;
+ final ProjectData projectData = getData();
+ if (projectData != null) {
+ final AbstractExternalSystemSettings externalSystemSettings =
+ ExternalSystemApiUtil.getSettings(getExternalProjectsView().getProject(), getData().getOwner());
+ final ExternalProjectSettings projectSettings =
+ externalSystemSettings.getLinkedProjectSettings(projectData.getLinkedExternalProjectPath());
+ if (projectSettings != null && projectSettings.isUseAutoImport()) autoImportHint = "auto-import enabled";
+ }
+
+ setNameAndTooltip(getName(), myTooltipCache, autoImportHint);
+ }
+
+ @Override
+ protected SimpleTextAttributes getPlainAttributes() {
+ return super.getPlainAttributes();
+ }
+
+ private String makeDescription() {
+ StringBuilder desc = new StringBuilder();
+ final ProjectData projectData = getData();
+ desc.append("<html>" +
+ "<table>" +
+ "<tr>" +
+ "<td nowrap>" +
+ "<table>" +
+ "<tr>" +
+ "<td nowrap>Project:</td>" +
+ "<td nowrap>").append(getName())
+ .append("</td>" +
+ "</tr>")
+ .append(projectData != null ?
+ "<tr>" +
+ "<td nowrap>Location:</td>" +
+ "<td nowrap>" + projectData.getLinkedExternalProjectPath() : "")
+ .append("</td>" +
+ "</tr>" +
+ "</table>" +
+ "</td>" +
+ "</tr>");
+
+ appendProblems(desc);
+
+ desc.append("</table></html>");
+
+ return desc.toString();
+ }
+
+ private void appendProblems(StringBuilder desc) {
+ // TBD
+ }
+
+ @Override
+ protected void setNameAndTooltip(String name, @Nullable String tooltip, SimpleTextAttributes attributes) {
+ super.setNameAndTooltip(name, tooltip, attributes);
+ }
+
+ @Override
+ @Nullable
+ @NonNls
+ protected String getMenuId() {
+ return "ExternalSystemView.ProjectMenu";
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.execution.ProgramRunnerUtil;
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.execution.impl.EditConfigurationsDialog;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.pom.Navigatable;
+import com.intellij.ui.treeStructure.SimpleTree;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.event.InputEvent;
+
+import static com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator.getRunConfigurationActivationTaskName;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/7/2014
+ */
+public class RunConfigurationNode extends ExternalSystemNode {
+ private final RunnerAndConfigurationSettings mySettings;
+
+ public RunConfigurationNode(@NotNull ExternalProjectsView externalProjectsView,
+ RunConfigurationsNode parent,
+ @NotNull RunnerAndConfigurationSettings settings) {
+ super(externalProjectsView, parent);
+ mySettings = settings;
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(ProgramRunnerUtil.getConfigurationIcon(mySettings, false));
+
+ final ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)mySettings.getConfiguration();
+ final ExternalSystemTaskExecutionSettings taskExecutionSettings = runConfiguration.getSettings();
+ final String shortcutHint = StringUtil.nullize(getShortcutsManager().getDescription(
+ taskExecutionSettings.getExternalProjectPath(), mySettings.getName()));
+ final String activatorHint = StringUtil.nullize(getTaskActivator().getDescription(
+ taskExecutionSettings.getExternalSystemId(), taskExecutionSettings.getExternalProjectPath(),
+ getRunConfigurationActivationTaskName(mySettings)));
+
+ String hint;
+ if (shortcutHint == null) {
+ hint = activatorHint;
+ }
+ else if (activatorHint == null) {
+ hint = shortcutHint;
+ }
+ else {
+ hint = shortcutHint + ", " + activatorHint;
+ }
+
+ setNameAndTooltip(getName(), StringUtil.join(taskExecutionSettings.getTaskNames(), " "), hint);
+ }
+
+ public RunnerAndConfigurationSettings getSettings() {
+ return mySettings;
+ }
+
+ @Override
+ public String getName() {
+ return mySettings.getName();
+ }
+
+ public boolean isAlwaysLeaf() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ protected String getMenuId() {
+ return "ExternalSystemView.RunConfigurationMenu";
+ }
+
+ public void updateRunConfiguration() {
+ }
+
+ @Override
+ public void handleDoubleClickOrEnter(SimpleTree tree, InputEvent inputEvent) {
+ final Project project = getExternalProjectsView().getProject();
+ ProgramRunnerUtil.executeConfiguration(project, mySettings, DefaultRunExecutor.getRunExecutorInstance());
+ final RunManagerEx runManagerEx = RunManagerEx.getInstanceEx(project);
+ runManagerEx.setSelectedConfiguration(mySettings);
+ }
+
+ @Nullable
+ @Override
+ public Navigatable getNavigatable() {
+ return new Navigatable() {
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ RunManager.getInstance(myProject).setSelectedConfiguration(mySettings);
+ EditConfigurationsDialog dialog = new EditConfigurationsDialog(myProject);
+ dialog.show();
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return true;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return false;
+ }
+ };
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.util.PathUtil;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
+import icons.ExternalSystemIcons;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/7/2014
+ */
+@Order(3)
+public class RunConfigurationsNode extends ExternalSystemNode<Void> {
+
+ private final ModuleData myModuleData;
+
+ public RunConfigurationsNode(@NotNull ExternalProjectsView externalProjectsView, ModuleNode parent) {
+ super(externalProjectsView, parent, null);
+ myModuleData = parent.getData();
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(ExternalSystemIcons.TaskGroup);
+ }
+
+ @Override
+ public String getName() {
+ return message("external.system.view.nodes.run_configurations.name");
+ }
+
+ @Override
+ public boolean isVisible() {
+ return hasChildren() && super.isVisible();
+ }
+
+ @NotNull
+ @Override
+ protected List<? extends ExternalSystemNode> doBuildChildren() {
+ List<ExternalSystemNode> runConfigurationNodes = ContainerUtil.newArrayList();
+ final AbstractExternalSystemTaskConfigurationType configurationType = ExternalSystemUtil.findConfigurationType(myModuleData.getOwner());
+ if (configurationType == null) return Collections.emptyList();
+
+ Set<RunnerAndConfigurationSettings> settings = new THashSet<RunnerAndConfigurationSettings>(
+ RunManager.getInstance(myProject).getConfigurationSettingsList(configurationType));
+
+
+ String directory = PathUtil.getCanonicalPath(myModuleData.getLinkedExternalProjectPath());
+
+ for (RunnerAndConfigurationSettings cfg : settings) {
+ ExternalSystemRunConfiguration externalSystemRunConfiguration = (ExternalSystemRunConfiguration)cfg.getConfiguration();
+
+ if (directory.equals(PathUtil.getCanonicalPath(externalSystemRunConfiguration.getSettings().getExternalProjectPath()))) {
+ runConfigurationNodes.add(new RunConfigurationNode(getExternalProjectsView(), this, cfg));
+ }
+ }
+
+ return runConfigurationNodes;
+ }
+
+ public void updateRunConfigurations() {
+ cleanUpCache();
+ getExternalProjectsView().updateUpTo(this);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/28/2014
+ */
+public class TaskNode extends ExternalSystemNode<TaskData> {
+ private TaskData myTaskData;
+
+ public TaskNode(@NotNull ExternalProjectsView externalProjectsView, @NotNull DataNode<TaskData> dataNode) {
+ super(externalProjectsView, null, dataNode);
+ myTaskData = dataNode.getData();
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(getUiAware().getTaskIcon());
+
+ final String shortcutHint = StringUtil.nullize(getShortcutsManager().getDescription(myTaskData.getLinkedExternalProjectPath(), myTaskData.getName()));
+ final String activatorHint = StringUtil.nullize(getTaskActivator().getDescription(
+ myTaskData.getOwner(), myTaskData.getLinkedExternalProjectPath(), myTaskData.getName()));
+
+ String hint;
+ if (shortcutHint == null) {
+ hint = activatorHint;
+ }
+ else if (activatorHint == null) {
+ hint = shortcutHint;
+ }
+ else {
+ hint = shortcutHint + ", " + activatorHint;
+ }
+
+ setNameAndTooltip(getName(), myTaskData.getDescription(), hint);
+ }
+
+ @Override
+ public String getName() {
+ return myTaskData.getName();
+ }
+
+ @Nullable
+ @Override
+ protected String getMenuId() {
+ return "ExternalSystemView.TaskMenu";
+ }
+
+ @Nullable
+ @Override
+ protected String getActionId() {
+ return "ExternalSystem.RunTask";
+ }
+
+ @Override
+ public boolean isAlwaysLeaf() {
+ return true;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.view;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import icons.ExternalSystemIcons;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/6/2014
+ */
+@Order(1)
+public class TasksNode extends ExternalSystemNode {
+
+ private final MultiMap<String, TaskNode> myTasksMap = new MultiMap<String, TaskNode>();
+
+ @SuppressWarnings("unchecked")
+ public TasksNode(ExternalProjectsView externalProjectsView, final Collection<DataNode<?>> dataNodes) {
+ super(externalProjectsView, null, null);
+
+ if (dataNodes != null && !dataNodes.isEmpty()) {
+ for (DataNode<?> dataNode : dataNodes) {
+ if (!(dataNode.getData() instanceof TaskData)) continue;
+ if (dataNode.getParent() != null && ProjectKeys.PROJECT.equals(dataNode.getParent().getKey())) break;
+ String group = ((TaskData)dataNode.getData()).getGroup();
+ if (group == null) group = "other";
+ myTasksMap.putValue(StringUtil.toLowerCase(group), new TaskNode(externalProjectsView, (DataNode<TaskData>)dataNode));
+ }
+ }
+ }
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(ExternalSystemIcons.TaskGroup);
+ }
+
+ @Override
+ public String getName() {
+ return "Tasks";
+ }
+
+ @Override
+ public boolean isVisible() {
+ return hasChildren() && super.isVisible();
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ @Override
+ protected List<? extends ExternalSystemNode> doBuildChildren() {
+ final List<ExternalSystemNode<?>> result = ContainerUtil.newArrayList();
+ final boolean isGroup = getExternalProjectsView().getGroupTasks();
+ if (isGroup) {
+ for (Map.Entry<String, Collection<TaskNode>> collectionEntry : myTasksMap.entrySet()) {
+ final String group = ObjectUtils.notNull(collectionEntry.getKey(), "other");
+ final ExternalSystemNode tasksGroupNode = new ExternalSystemNode(getExternalProjectsView(), null, null) {
+
+ @Override
+ protected void update(PresentationData presentation) {
+ super.update(presentation);
+ presentation.setIcon(ExternalSystemIcons.TaskGroup);
+ }
+
+ @Override
+ public String getName() {
+ return group;
+ }
+
+ @Override
+ public int compareTo(@NotNull ExternalSystemNode node) {
+ return "other".equals(group) ? 1 : super.compareTo(node);
+ }
+ };
+ tasksGroupNode.addAll(collectionEntry.getValue());
+ result.add(tasksGroupNode);
+ }
+ }
+ else {
+ result.addAll(myTasksMap.values());
+ }
+ return result;
+ }
+}
}
public static final Icon Task = load("/icons/task.png"); // 16x16
+ public static final Icon TaskGroup = load("/icons/taskGroup.png"); // 16x16
}
+++ /dev/null
-/*
- * 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.service.task.ui;
-
-import com.intellij.openapi.command.impl.DummyProject;
-import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
-import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
-import com.intellij.openapi.externalSystem.test.ExternalSystemTestUtil;
-import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
-import com.intellij.util.containers.ContainerUtilRt;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-
-/**
- * @author Vladislav Soroka
- * @since 8/13/13
- */
-public class ExternalSystemRecentTaskListModelTest {
-
- private ExternalSystemRecentTaskListModel myModel;
-
- @Before
- public void setUp() {
- myModel = new ExternalSystemRecentTaskListModel(ExternalSystemTestUtil.TEST_EXTERNAL_SYSTEM_ID, DummyProject.getInstance());
- }
-
- @Test
- public void testSetFirst() throws Exception {
- List<ExternalTaskExecutionInfo> tasks = ContainerUtilRt.newArrayList();
- for (int i = 0; i <= ExternalSystemConstants.RECENT_TASKS_NUMBER; i++) {
- new ExternalTaskExecutionInfo(new ExternalSystemTaskExecutionSettings(), "task" + i);
- }
- myModel.setTasks(tasks);
-
- myModel.setFirst(new ExternalTaskExecutionInfo(new ExternalSystemTaskExecutionSettings(), "newTask"));
-
- Assert.assertEquals(ExternalSystemConstants.RECENT_TASKS_NUMBER, myModel.getSize());
- myModel.setFirst(new ExternalTaskExecutionInfo(new ExternalSystemTaskExecutionSettings(), "task1"));
- Assert.assertEquals(ExternalSystemConstants.RECENT_TASKS_NUMBER, myModel.getSize());
- }
-
- @Test
- public void testEnsureSize() throws Exception {
- List<ExternalTaskExecutionInfo> tasks = ContainerUtilRt.newArrayList();
-
- // test task list widening
- myModel.setTasks(tasks);
- myModel.ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
- Assert.assertEquals("task list widening failed", ExternalSystemConstants.RECENT_TASKS_NUMBER, myModel.getSize());
-
- // test task list reduction
- for (int i = 0; i < ExternalSystemConstants.RECENT_TASKS_NUMBER + 1; i++) {
- tasks.add(new ExternalTaskExecutionInfo(new ExternalSystemTaskExecutionSettings(), "task" + i));
- }
- myModel.setTasks(tasks);
- Assert.assertEquals(ExternalSystemConstants.RECENT_TASKS_NUMBER + 1, myModel.getSize());
-
- myModel.ensureSize(ExternalSystemConstants.RECENT_TASKS_NUMBER);
- Assert.assertEquals("task list reduction failed", ExternalSystemConstants.RECENT_TASKS_NUMBER, myModel.getSize());
- }
-}
interface="com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener"/>
<extensionPoint name="externalSystemExecutionConsoleManager"
interface="com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager"/>
+ <extensionPoint name="externalSystemViewContributor" interface="com.intellij.openapi.externalSystem.view.ExternalSystemViewContributor"/>
</extensionPoints>
</idea-plugin>
\ No newline at end of file
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="com.intellij.openapi.externalSystem.service.ExternalSystemStartupActivity"/>
+
+ <keymapExtension implementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemKeymapExtension"/>
<!--Generic services-->
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager"/>
<!--Project structure management services-->
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager"/>
+ <projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager" order="first"/>
<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsDataStorage"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataServiceImpl"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.LibraryDataService"/>
<!--Tool window services-->
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.task.ToolWindowModuleService"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.task.ToolWindowTaskService"/>
+ <externalSystemViewContributor implementation="com.intellij.openapi.externalSystem.view.ExternalSystemViewDefaultContributor"/>
<!--Execution-->
<programRunner implementation="com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskRunner"/>
<component>
<actions>
-
-
+
<action id="ExternalSystem.RefreshAllProjects"
class="com.intellij.openapi.externalSystem.action.RefreshAllExternalProjectsAction"
icon="AllIcons.Actions.Refresh"/>
<action id="ExternalSystem.OpenConfig"
class="com.intellij.openapi.externalSystem.action.OpenExternalConfigAction"
use-shortcut-of="EditSource"/>
+ <action id="ExternalSystem.ShowSettings"
+ class="com.intellij.openapi.externalSystem.action.ShowExternalSystemSettingsAction"
+ icon="AllIcons.General.ProjectSettings">
+ </action>
+
+ <action id="ExternalSystem.ToggleAutoImport"
+ class="com.intellij.openapi.externalSystem.action.ToggleAutoImportAction">
+ </action>
+
+ <action id="ExternalSystem.ExpandAll" class="com.intellij.openapi.externalSystem.action.ExternalSystemTreeAction$ExpandAll"
+ text="Expand All"
+ icon="AllIcons.Actions.Expandall"
+ use-shortcut-of="ExpandAll"/>
+ <action id="ExternalSystem.CollapseAll" class="com.intellij.openapi.externalSystem.action.ExternalSystemTreeAction$CollapseAll"
+ text="Collapse All"
+ icon="AllIcons.Actions.Collapseall"
+ use-shortcut-of="CollapseAll"/>
+
+ <action id="ExternalSystem.RunTask"
+ class="com.intellij.openapi.externalSystem.action.task.RunExternalSystemTaskAction"
+ text="_Run Task"
+ description="Execute selected tasks"
+ icon="AllIcons.Actions.Execute">
+ </action>
+ <action id="ExternalSystem.AssignShortcut"
+ class="com.intellij.openapi.externalSystem.action.task.AssignShortcutAction" text="Assign Shortcut..."
+ description="Assign shortcut to the selected task">
+ </action>
+ <action id="ExternalSystem.AssignRunConfigurationShortcut"
+ class="com.intellij.openapi.externalSystem.action.task.AssignRunConfigurationShortcutAction" text="Assign Shortcut..."
+ description="Assign shortcut to the selected Run Configuration">
+ </action>
+
+ <action id="ExternalSystem.BeforeCompile"
+ class="com.intellij.openapi.externalSystem.action.task.ToggleBeforeCompileTasksAction" text="Execute Before Make"
+ description="Execute selected task before Make">
+ </action>
+ <action id="ExternalSystem.AfterCompile"
+ class="com.intellij.openapi.externalSystem.action.task.ToggleAfterCompileTasksAction" text="Execute After Make"
+ description="Execute selected task after Make">
+ </action>
+ <action id="ExternalSystem.BeforeRebuild"
+ class="com.intellij.openapi.externalSystem.action.task.ToggleBeforeRebuildTasksAction" text="Execute Before Rebuild"
+ description="Execute selected task before full rebuild">
+ </action>
+ <action id="ExternalSystem.AfterRebuild"
+ class="com.intellij.openapi.externalSystem.action.task.ToggleAfterRebuildTasksAction" text="Execute After Rebuild"
+ description="Execute selected task after full rebuild">
+ </action>
+ <action id="ExternalSystem.BeforeRun"
+ class="com.intellij.openapi.externalSystem.action.task.ToggleBeforeRunTaskAction" text="Execute Before Run/Debug..."
+ description="Execute selected task before launching Run/Debug configuration">
+ </action>
+
+ <action id="ExternalSystem.GroupTasks"
+ class="com.intellij.openapi.externalSystem.action.task.GroupTasksAction" text="Group Tasks">
+ </action>
+
+ <group id="ExternalSystemView.BaseProjectMenu">
+ <reference ref="ExternalSystem.OpenConfig"/>
+ <separator/>
+ <reference id="ExternalSystem.RefreshProject"/>
+ <reference id="ExternalSystem.DetachProject"/>
+
+ </group>
- <!--Tool window actions-->
- <group id="ExternalSystem.ToolWindow.Toolbar">
+ <group id="ExternalSystemView.ProjectMenu" popup="true">
+ <reference ref="ExternalSystemView.BaseProjectMenu"/>
+ <separator/>
+ <reference id="ExternalSystem.ToggleAutoImport"/>
+ </group>
+
+ <group id="ExternalSystemView.ActionsToolbar.LeftPanel">
<reference id="ExternalSystem.RefreshAllProjects"/>
<reference id="ExternalSystem.AttachProject"/>
<reference ref="ExternalSystem.DetachProject"/>
+ <!--<reference id="ExternalSystem.Run/>-->
+ </group>
+ <group id="ExternalSystemView.ActionsToolbar.CenterPanel">
+ <separator/>
+ <reference id="ExternalSystem.ExpandAll"/>
+ <reference id="ExternalSystem.CollapseAll"/>
+ </group>
+ <group id="ExternalSystemView.ActionsToolbar.RightPanel">
</group>
- <!--Context menu action-->
- <group id="ExternalSystem.Tree.Context" popup="true">
- <reference ref="ExternalSystem.OpenConfig"/>
- <reference id="ExternalSystem.RefreshProject"/>
- <reference ref="ExternalSystem.DetachProject"/>
+ <group id="ExternalSystemView.ActionsToolbar">
+ <reference ref="ExternalSystemView.ActionsToolbar.LeftPanel"/>
+ <separator/>
+ <reference ref="ExternalSystemView.ActionsToolbar.CenterPanel"/>
+ <separator/>
+ <reference ref="ExternalSystemView.ActionsToolbar.RightPanel"/>
<separator/>
+ <reference id="ExternalSystem.ShowSettings" order="last"/>
+ </group>
+
+ <group id="ExternalSystemView.TaskMenu" popup="true">
<reference ref="RunContextGroup"/>
+ <separator/>
+ <reference id="EditSource"/>
+ <separator/>
+ <reference id="ExternalSystem.BeforeCompile"/>
+ <reference id="ExternalSystem.AfterCompile"/>
+ <reference id="ExternalSystem.BeforeRebuild"/>
+ <reference id="ExternalSystem.AfterRebuild"/>
+ <!--<reference id="ExternalSystem.BeforeRun"/>-->
+ <separator/>
+ <reference id="ExternalSystem.AssignShortcut"/>
+ </group>
+
+ <group id="ExternalSystemView.RunConfigurationMenu" popup="true" class="com.intellij.openapi.externalSystem.action.ExternalSystemRunConfigurationMenu">
+ <separator/>
+ <action id="ExternalSystem.EditRunConfiguration"
+ text="Edit Run Configuration..." icon="AllIcons.Actions.Edit"
+ class="com.intellij.openapi.externalSystem.action.EditExternalSystemRunConfigurationAction" />
+ <action id="ExternalSystem.RemoveRunConfiguration"
+ text="Remove Run Configuration" icon="AllIcons.General.Remove"
+ class="com.intellij.openapi.externalSystem.action.RemoveExternalSystemRunConfigurationAction" />
+ <separator/>
+ <reference id="ExternalSystem.BeforeCompile"/>
+ <reference id="ExternalSystem.AfterCompile"/>
+ <reference id="ExternalSystem.BeforeRebuild"/>
+ <reference id="ExternalSystem.AfterRebuild"/>
+ <!--<reference id="ExternalSystem.BeforeRun"/>-->
+ <separator/>
+ <reference id="ExternalSystem.AssignRunConfigurationShortcut"/>
</group>
-
+
+
</actions>
</component>
\ No newline at end of file
<projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleLocalSettings"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.project.GradleNotification"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager"/>
+ <projectService serviceImplementation="org.jetbrains.plugins.gradle.service.task.ExecuteGradleTaskHistoryService"/>
<stepsBeforeRunProvider implementation="org.jetbrains.plugins.gradle.execution.GradleBeforeRunTaskProvider" />
<configurationProducer implementation="org.jetbrains.plugins.gradle.service.execution.GradleRuntimeConfigurationProducer"/>
<actions>
+ <action id="Gradle.ExecuteTask" class="org.jetbrains.plugins.gradle.action.GradleExecuteTaskAction" text="Execute Gradle Task"
+ icon="GradleIcons.Gradle">
+ </action>
+ <action id="Gradle.ToggleOfflineAction" class="org.jetbrains.plugins.gradle.action.ToggleOfflineAction"
+ text="Toggle Offline Mode" description="Toggle offline mode for Gradle builds"
+ icon="GradleIcons.OfflineMode"/>
+
<group id="Gradle.GenerateGroup">
<action id="AddGradleDslPluginAction" class="org.jetbrains.plugins.gradle.codeInsight.actions.AddGradleDslPluginAction"/>
<add-to-group group-id="GenerateGroup" anchor="first"/>
</group>
+ <group>
+ <separator/>
+ <reference id="Gradle.ExecuteTask"/>
+ <add-to-group group-id="ExternalSystemView.ActionsToolbar.LeftPanel"/>
+ </group>
+
+ <group>
+ <reference id="Gradle.ToggleOfflineAction"/>
+ <add-to-group group-id="ExternalSystemView.ActionsToolbar.RightPanel"/>
+ </group>
+
</actions>
</idea-plugin>
public static final Icon GradleNavigate = load("/icons/gradleNavigate.png"); // 16x16
public static final Icon GradlePlugin = load("/icons/gradlePlugin.png"); // 16x16
public static final Icon GradleSync = load("/icons/gradleSync.png"); // 16x16
+ public static final Icon OfflineMode = load("/icons/offlineMode.png"); // 16x16
public static final Icon ToolWindowGradle = load("/icons/toolWindowGradle.png"); // 13x13
}
--- /dev/null
+/*
+ * Copyright 2000-2014 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 org.jetbrains.plugins.gradle.action;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.action.ExternalSystemToggleAction;
+import org.jetbrains.plugins.gradle.settings.GradleSettings;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 10/20/2014
+ */
+public class ToggleOfflineAction extends ExternalSystemToggleAction {
+
+ @Override
+ protected boolean doIsSelected(AnActionEvent e) {
+ return GradleSettings.getInstance(getProject(e)).isOfflineWork();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ GradleSettings.getInstance(getProject(e)).setOfflineWork(state);
+ }
+}
final Collection<TaskData> tasks = ContainerUtil.newArrayList();
final String moduleConfigPath = ideModule.getData().getLinkedExternalProjectPath();
+ ExternalProject externalProject = resolverCtx.getExtraProject(gradleModule, ExternalProject.class);
+
+ if (externalProject != null) {
+ for (ExternalTask task : externalProject.getTasks().values()) {
+ String taskName = task.getName();
+ if (taskName.trim().isEmpty() || isIdeaTask(taskName)) {
+ continue;
+ }
+ TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, taskName, moduleConfigPath, task.getDescription());
+ taskData.setGroup(task.getGroup());
+ ideModule.createChild(ProjectKeys.TASK, taskData);
+ tasks.add(taskData);
+ }
+
+ return tasks;
+ }
+
for (GradleTask task : gradleModule.getGradleProject().getTasks()) {
String taskName = task.getName();
if (taskName == null || taskName.trim().isEmpty() || isIdeaTask(taskName)) {
if (unresolved) {
// Gradle uses names like 'unresolved dependency - commons-collections commons-collections 3.2' for unresolved dependencies.
- libraryName = binaryPath.getName().substring(UNRESOLVED_DEPENDENCY_PREFIX.length());
+ libraryName = binaryPath.getPath().substring(UNRESOLVED_DEPENDENCY_PREFIX.length());
int i = libraryName.indexOf(' ');
if (i >= 0) {
i = CharArrayUtil.shiftForward(libraryName, i + 1, " ");
final String classifier = matcher.group(1);
libraryName += (":" + classifier);
}
+ else {
+ final String artifactId = StringUtil.trimEnd(StringUtil.trimEnd(libraryFileName, moduleVersion.getVersion()), "-");
+ libraryName = String.format("%s:%s:%s",
+ moduleVersion.getGroup(),
+ artifactId,
+ moduleVersion.getVersion());
+ }
}
}
}
ExternalTask externalTask = new DefaultExternalTask()
externalTask.name = task.name
externalTask.description = task.description
- externalTask.group = task.group
+ externalTask.group = task.group ?: "other"
externalTask.QName = task.path
result.put(externalTask.QName, externalTask)
}