gradle tool window rework initial commit

This commit is contained in:
Vladislav.Soroka
2014-12-08 12:00:14 +03:00
parent 88e63beda9
commit 6d4fd2e1a2
78 changed files with 5698 additions and 1004 deletions
@@ -32,7 +32,9 @@ error.resolve.generic=Resolve error
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
@@ -46,14 +48,29 @@ action.detach.external.project.description=Detach selected external project
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
@@ -53,7 +53,7 @@ public class DataNode<T> implements Serializable {
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;
@@ -176,6 +176,8 @@ public class DataNode<T> implements Serializable {
};
myData = (T)oIn.readObject();
myRawData = null;
assert myData != null;
}
catch (IOException e) {
throw new IllegalStateException(
@@ -239,18 +241,32 @@ public class DataNode<T> implements Serializable {
}
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();
@@ -285,4 +301,19 @@ public class DataNode<T> implements Serializable {
}
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();
}
}
@@ -33,6 +33,7 @@ public class TaskData extends AbstractExternalEntityData implements ExternalConf
@NotNull private final String myName;
@NotNull private final String myLinkedExternalProjectPath;
@Nullable private String myGroup;
@Nullable private final String myDescription;
@@ -58,12 +59,22 @@ public class TaskData extends AbstractExternalEntityData implements ExternalConf
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;
}
@@ -76,6 +87,7 @@ public class TaskData extends AbstractExternalEntityData implements ExternalConf
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;
@@ -24,6 +24,7 @@ import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
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;
@@ -73,6 +74,10 @@ public abstract class AbstractExternalSystemLocalSettings {
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;
@@ -189,6 +194,16 @@ public abstract class AbstractExternalSystemLocalSettings {
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();
@@ -201,6 +216,7 @@ public abstract class AbstractExternalSystemLocalSettings {
state.availableTasks = myAvailableTasks.get();
state.modificationStamps = myExternalConfigModificationStamps.get();
state.projectBuildClasspath = myProjectBuildClasspath.get();
state.externalProjectsViewState = myExternalProjectsViewState.get();
}
public void loadState(@NotNull State state) {
@@ -209,6 +225,7 @@ public abstract class AbstractExternalSystemLocalSettings {
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) {
@@ -270,5 +287,6 @@ public abstract class AbstractExternalSystemLocalSettings {
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;
}
}
@@ -23,15 +23,14 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.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;
@@ -46,9 +45,12 @@ import com.intellij.openapi.util.text.StringUtil;
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;
@@ -361,6 +363,84 @@ public class ExternalSystemApiUtil {
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);
}
@@ -682,8 +762,20 @@ public class ExternalSystemApiUtil {
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);
}
}
@@ -0,0 +1,33 @@
/*
* 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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

@@ -16,31 +16,28 @@
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;
@@ -49,63 +46,71 @@ 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);
}
}
});
}
}
}
@@ -0,0 +1,56 @@
/*
* 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();
}
}
@@ -1,89 +0,0 @@
/*
* 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;
}
}
}
@@ -0,0 +1,62 @@
/*
* 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;
}
}
@@ -0,0 +1,179 @@
/*
* 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);
}
}
@@ -0,0 +1,101 @@
/*
* 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;
}
}
@@ -0,0 +1,94 @@
/*
* 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);
}
}
}
@@ -0,0 +1,68 @@
/*
* 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());
}
}
@@ -0,0 +1,63 @@
/*
* 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);
}
}
}
}
@@ -0,0 +1,63 @@
/*
* 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;
}
}
@@ -1,92 +1,59 @@
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;
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);
}
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;
}
}
}
return toOpen.isDirectory() ? null : toOpen;
}
}
@@ -1,28 +1,33 @@
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
@@ -31,44 +36,43 @@ import java.util.Collections;
* @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) {
@@ -0,0 +1,59 @@
/*
* 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);
}
}
}
@@ -0,0 +1,59 @@
/*
* 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());
}
}
@@ -0,0 +1,80 @@
/*
* 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());
}
}
@@ -0,0 +1,64 @@
/*
* 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();
}
}
}
@@ -0,0 +1,49 @@
/*
* 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();
}
}
}
@@ -0,0 +1,36 @@
/*
* 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);
}
}
@@ -0,0 +1,63 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,28 @@
/*
* 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);
}
}
@@ -0,0 +1,112 @@
/*
* 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();
}
}
@@ -17,27 +17,29 @@ package com.intellij.openapi.externalSystem.model;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentTasksList;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import 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");
@@ -21,6 +21,7 @@ import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
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;
@@ -45,6 +46,8 @@ public class ExternalSystemStartupActivity implements StartupActivity {
@SuppressWarnings("unchecked")
@Override
public void run() {
ExternalProjectsManager.getInstance(project).init();
for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) {
if (manager instanceof StartupActivity) {
((StartupActivity)manager).runActivity(project);
@@ -52,7 +55,8 @@ public class ExternalSystemStartupActivity implements StartupActivity {
}
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())
);
@@ -5,27 +5,23 @@ 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.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.
@@ -133,35 +129,16 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
@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;
@@ -171,24 +148,23 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
}
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();
}
@@ -1,15 +1,12 @@
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;
@@ -81,4 +78,23 @@ public class ProjectStructureHelper {
}
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;
}
}
@@ -15,21 +15,39 @@
*/
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
@@ -38,11 +56,14 @@ import java.util.Map;
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);
@@ -52,16 +73,50 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent {
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();
@@ -88,10 +143,172 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent {
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();
}
}
@@ -0,0 +1,239 @@
/*
* 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);
}
}
@@ -0,0 +1,100 @@
/*
* 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);
}
}
}
@@ -0,0 +1,276 @@
/*
* 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;
}
}
}
@@ -0,0 +1,143 @@
/*
* 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));
}
}
}
@@ -0,0 +1,149 @@
/*
* 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);
}
}
@@ -0,0 +1,259 @@
/*
* 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();
}
}
@@ -24,6 +24,8 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
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;
@@ -72,11 +74,6 @@ public class ProjectDataManager {
};
}
@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);
@@ -86,7 +83,7 @@ public class ProjectDataManager {
@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()) {
@@ -101,9 +98,9 @@ public class ProjectDataManager {
@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(
@@ -124,22 +121,33 @@ public class ProjectDataManager {
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);
}
}
@@ -152,13 +160,21 @@ public class ProjectDataManager {
}
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();
}
}
@@ -47,7 +47,7 @@ public class ProjectDataServiceImpl implements ProjectDataService<ProjectData, P
}
DataNode<ProjectData> node = toImport.iterator().next();
ProjectData projectData = node.getData();
if (!ExternalSystemApiUtil.isNewProjectConstruction() && !ExternalSystemUtil.isOneToOneMapping(project, node)) {
return;
}
@@ -0,0 +1,68 @@
/*
* 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();
}
}
}
@@ -42,18 +42,13 @@ public abstract class AbstractToolWindowService<T extends ExternalEntityData> im
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) {
@@ -23,7 +23,6 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
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;
@@ -32,7 +31,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -62,8 +60,7 @@ public class ToolWindowModuleService extends AbstractToolWindowService<ModuleDat
@Override
protected void processData(@NotNull final Collection<DataNode<ModuleData>> nodes,
@NotNull Project project,
@Nullable final ExternalSystemTasksTreeModel model)
@NotNull Project project)
{
if (nodes.isEmpty()) {
return;
@@ -24,11 +24,9 @@ import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware
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;
@@ -74,8 +72,7 @@ public class ToolWindowTaskService extends AbstractToolWindowService<TaskData> {
@Override
protected void processData(@NotNull Collection<DataNode<TaskData>> nodes,
@NotNull Project project,
@Nullable final ExternalSystemTasksTreeModel model)
@NotNull Project project)
{
if (nodes.isEmpty()) {
return;
@@ -94,9 +91,5 @@ public class ToolWindowTaskService extends AbstractToolWindowService<TaskData> {
Map<String, Collection<ExternalTaskPojo>> availableTasks = ContainerUtilRt.newHashMap(settings.getAvailableTasks());
availableTasks.putAll(data);
settings.setAvailableTasks(availableTasks);
if (model != null) {
ExternalSystemUiUtil.apply(settings, model);
}
}
}
@@ -15,45 +15,38 @@
*/
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);
}
}
@@ -1,113 +0,0 @@
/*
* 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 {
}
}
@@ -1,195 +0,0 @@
/*
* 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);
}
}
}
}
@@ -1,204 +0,0 @@
/*
* 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);
}
}
@@ -105,28 +105,6 @@ public class ExternalSystemUiUtil {
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()) {
@@ -39,7 +39,6 @@ import com.intellij.openapi.externalSystem.importing.ImportSpec;
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;
@@ -55,14 +54,14 @@ import com.intellij.openapi.externalSystem.service.notification.NotificationSour
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;
@@ -142,7 +141,6 @@ public class ExternalSystemUtil {
}
}
@SuppressWarnings("unchecked")
@Nullable
public static <T> T getToolWindowElement(@NotNull Class<T> clazz,
@NotNull Project project,
@@ -170,6 +168,7 @@ public class ExternalSystemUtil {
if (component instanceof DataProvider) {
final Object data = ((DataProvider)component).getData(key.getName());
if (data != null && clazz.isInstance(data)) {
//noinspection unchecked
return (T)data;
}
}
@@ -300,6 +299,13 @@ public class ExternalSystemUtil {
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:
@@ -317,7 +323,8 @@ public class ExternalSystemUtil {
*/
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
@@ -356,6 +363,7 @@ public class ExternalSystemUtil {
}
};
boolean ok = dialog.showAndGet();
result.consume(ok);
if (!ok) {
return;
}
@@ -700,6 +708,16 @@ public class ExternalSystemUtil {
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;
@@ -713,7 +731,7 @@ public class ExternalSystemUtil {
runConfiguration.getSettings().setScriptParameters(taskSettings.getScriptParameters());
runConfiguration.getSettings().setExecutionName(taskSettings.getExecutionName());
return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
return settings;
}
@Nullable
@@ -729,32 +747,6 @@ public class ExternalSystemUtil {
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);
@@ -904,6 +896,26 @@ public class ExternalSystemUtil {
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);
}
@@ -0,0 +1,253 @@
/*
* 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;
}
}
@@ -0,0 +1,611 @@
/*
* 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()]);
}
}
@@ -0,0 +1,379 @@
/*
* 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);
}
}
@@ -0,0 +1,40 @@
/*
* 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);
}
@@ -0,0 +1,243 @@
/*
* 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);
}
}
}
@@ -0,0 +1,98 @@
/*
* 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);
}
}
@@ -0,0 +1,145 @@
/*
* 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";
}
}
@@ -0,0 +1,132 @@
/*
* 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;
}
};
}
}
@@ -0,0 +1,94 @@
/*
* 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);
}
}
@@ -0,0 +1,81 @@
/*
* 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;
}
}
@@ -0,0 +1,110 @@
/*
* 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;
}
}
@@ -29,4 +29,5 @@ public class ExternalSystemIcons {
}
public static final Icon Task = load("/icons/task.png"); // 16x16
public static final Icon TaskGroup = load("/icons/taskGroup.png"); // 16x16
}
@@ -1,77 +0,0 @@
/*
* 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());
}
}
@@ -11,5 +11,6 @@
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>
@@ -2,6 +2,8 @@
<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"/>
@@ -20,6 +22,7 @@
<!--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"/>
@@ -31,6 +34,7 @@
<!--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"/>
@@ -1,7 +1,6 @@
<component>
<actions>
<action id="ExternalSystem.RefreshAllProjects"
class="com.intellij.openapi.externalSystem.action.RefreshAllExternalProjectsAction"
icon="AllIcons.Actions.Refresh"/>
@@ -16,22 +15,134 @@
<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>
<!--Tool window actions-->
<group id="ExternalSystem.ToolWindow.Toolbar">
<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>
<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="RunContextGroup"/>
<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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

+19
View File
@@ -111,6 +111,7 @@
<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"/>
@@ -147,10 +148,28 @@
<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>
@@ -33,5 +33,6 @@ public class GradleIcons {
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
}
@@ -0,0 +1,37 @@
/*
* 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);
}
}
@@ -330,6 +330,23 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
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)) {
@@ -641,7 +658,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
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, " ");
@@ -669,6 +686,13 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
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());
}
}
}
}
@@ -101,7 +101,7 @@ class ExternalProjectBuilderImpl implements ModelBuilderService {
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)
}