blob: 2530fc98f8c42b8d42782d999869236bdbce9777 [file] [log] [blame]
/*
* 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);
}
}