| /* |
| * 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.lang.ant.config.explorer; |
| |
| import com.intellij.execution.*; |
| import com.intellij.execution.impl.RunDialog; |
| import com.intellij.execution.impl.RunManagerImpl; |
| import com.intellij.icons.AllIcons; |
| import com.intellij.ide.CommonActionsManager; |
| import com.intellij.ide.DataManager; |
| import com.intellij.ide.TreeExpander; |
| import com.intellij.ide.actions.ContextHelpAction; |
| import com.intellij.ide.dnd.FileCopyPasteUtil; |
| import com.intellij.lang.ant.AntBundle; |
| import com.intellij.lang.ant.config.*; |
| import com.intellij.lang.ant.config.actions.AntBuildFilePropertiesAction; |
| import com.intellij.lang.ant.config.actions.RemoveBuildFileAction; |
| import com.intellij.lang.ant.config.execution.AntRunConfiguration; |
| import com.intellij.lang.ant.config.execution.AntRunConfigurationType; |
| import com.intellij.lang.ant.config.execution.ExecutionHandler; |
| import com.intellij.lang.ant.config.impl.*; |
| import com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel; |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.actionSystem.*; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.fileChooser.FileChooser; |
| import com.intellij.openapi.fileChooser.FileChooserDescriptor; |
| import com.intellij.openapi.fileEditor.OpenFileDescriptor; |
| import com.intellij.openapi.fileTypes.StdFileTypes; |
| import com.intellij.openapi.keymap.Keymap; |
| import com.intellij.openapi.keymap.KeymapManagerListener; |
| import com.intellij.openapi.keymap.ex.KeymapManagerEx; |
| import com.intellij.openapi.keymap.impl.ui.EditKeymapsDialog; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.ui.SimpleToolWindowPanel; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.openapi.vfs.VfsUtil; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.ui.*; |
| import com.intellij.ui.treeStructure.Tree; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.IconUtil; |
| import com.intellij.util.StringBuilderSpinAllocator; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.ui.tree.TreeUtil; |
| import com.intellij.util.xml.DomEventListener; |
| import com.intellij.util.xml.DomManager; |
| import com.intellij.util.xml.events.DomEvent; |
| import icons.AntIcons; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.tree.DefaultMutableTreeNode; |
| import javax.swing.tree.DefaultTreeModel; |
| import javax.swing.tree.TreePath; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.KeyEvent; |
| import java.awt.event.MouseEvent; |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, Disposable { |
| private Project myProject; |
| private AntExplorerTreeBuilder myBuilder; |
| private Tree myTree; |
| private KeymapListener myKeymapListener; |
| private final AntBuildFilePropertiesAction myAntBuildFilePropertiesAction; |
| private AntConfiguration myConfig; |
| |
| private final TreeExpander myTreeExpander = new TreeExpander() { |
| public void expandAll() { |
| myBuilder.expandAll(); |
| } |
| |
| public boolean canExpand() { |
| final AntConfiguration config = myConfig; |
| return config != null && config.getBuildFiles().length != 0; |
| } |
| |
| public void collapseAll() { |
| myBuilder.collapseAll(); |
| } |
| |
| public boolean canCollapse() { |
| return canExpand(); |
| } |
| }; |
| |
| public AntExplorer(final Project project) { |
| super(true, true); |
| setTransferHandler(new MyTransferHandler()); |
| myProject = project; |
| myConfig = AntConfiguration.getInstance(project); |
| final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode()); |
| myTree = new Tree(model); |
| myTree.setRootVisible(false); |
| myTree.setShowsRootHandles(true); |
| myTree.setCellRenderer(new NodeRenderer()); |
| myBuilder = new AntExplorerTreeBuilder(project, myTree, model); |
| myBuilder.setTargetsFiltered(AntConfigurationBase.getInstance(project).isFilterTargets()); |
| TreeUtil.installActions(myTree); |
| new TreeSpeedSearch(myTree); |
| myTree.addMouseListener(new PopupHandler() { |
| public void invokePopup(final Component comp, final int x, final int y) { |
| popupInvoked(comp, x, y); |
| } |
| }); |
| |
| new DoubleClickListener() { |
| @Override |
| protected boolean onDoubleClick(MouseEvent e) { |
| final int eventY = e.getY(); |
| final int row = myTree.getClosestRowForLocation(e.getX(), eventY); |
| if (row >= 0) { |
| final Rectangle bounds = myTree.getRowBounds(row); |
| if (bounds != null && eventY > bounds.getY() && eventY < bounds.getY() + bounds.getHeight()) { |
| runSelection(DataManager.getInstance().getDataContext(myTree)); |
| return true; |
| } |
| } |
| return false; |
| } |
| }.installOn(myTree); |
| |
| myTree.registerKeyboardAction(new AbstractAction() { |
| public void actionPerformed(ActionEvent e) { |
| runSelection(DataManager.getInstance().getDataContext(myTree)); |
| } |
| }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), WHEN_FOCUSED); |
| myTree.setLineStyleAngled(); |
| myAntBuildFilePropertiesAction = new AntBuildFilePropertiesAction(this); |
| setToolbar(createToolbarPanel()); |
| setContent(ScrollPaneFactory.createScrollPane(myTree)); |
| ToolTipManager.sharedInstance().registerComponent(myTree); |
| myKeymapListener = new KeymapListener(); |
| |
| DomManager.getDomManager(project).addDomEventListener(new DomEventListener() { |
| public void eventOccured(DomEvent event) { |
| myBuilder.queueUpdate(); |
| } |
| }, this); |
| RunManagerEx.getInstanceEx(myProject).addRunManagerListener(new RunManagerAdapter() { |
| public void beforeRunTasksChanged() { |
| myBuilder.queueUpdate(); |
| } |
| }); |
| } |
| |
| public void dispose() { |
| final KeymapListener listener = myKeymapListener; |
| if (listener != null) { |
| myKeymapListener = null; |
| listener.stopListen(); |
| } |
| |
| final AntExplorerTreeBuilder builder = myBuilder; |
| if (builder != null) { |
| Disposer.dispose(builder); |
| myBuilder = null; |
| } |
| |
| final Tree tree = myTree; |
| if (tree != null) { |
| ToolTipManager.sharedInstance().unregisterComponent(tree); |
| for (KeyStroke keyStroke : tree.getRegisteredKeyStrokes()) { |
| tree.unregisterKeyboardAction(keyStroke); |
| } |
| myTree = null; |
| } |
| |
| myProject = null; |
| myConfig = null; |
| } |
| |
| private JPanel createToolbarPanel() { |
| final DefaultActionGroup group = new DefaultActionGroup(); |
| group.add(new AddAction()); |
| group.add(new RemoveAction()); |
| group.add(new RunAction()); |
| group.add(new ShowAllTargetsAction()); |
| AnAction action = CommonActionsManager.getInstance().createExpandAllAction(myTreeExpander, this); |
| action.getTemplatePresentation().setDescription(AntBundle.message("ant.explorer.expand.all.nodes.action.description")); |
| group.add(action); |
| action = CommonActionsManager.getInstance().createCollapseAllAction(myTreeExpander, this); |
| action.getTemplatePresentation().setDescription(AntBundle.message("ant.explorer.collapse.all.nodes.action.description")); |
| group.add(action); |
| group.add(myAntBuildFilePropertiesAction); |
| group.add(new ContextHelpAction(HelpID.ANT)); |
| |
| final ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.ANT_EXPLORER_TOOLBAR, group, true); |
| final JPanel buttonsPanel = new JPanel(new BorderLayout()); |
| buttonsPanel.add(actionToolBar.getComponent(), BorderLayout.CENTER); |
| return buttonsPanel; |
| } |
| |
| private void addBuildFile() { |
| final FileChooserDescriptor descriptor = createXmlDescriptor(); |
| descriptor.setTitle(AntBundle.message("select.ant.build.file.dialog.title")); |
| descriptor.setDescription(AntBundle.message("select.ant.build.file.dialog.description")); |
| final VirtualFile[] files = FileChooser.chooseFiles(descriptor, myProject, null); |
| addBuildFile(files); |
| } |
| |
| private void addBuildFile(final VirtualFile[] files) { |
| if (files.length == 0) { |
| return; |
| } |
| ApplicationManager.getApplication().invokeLater(new Runnable() { |
| public void run() { |
| final AntConfiguration antConfiguration = myConfig; |
| if (antConfiguration == null) { |
| return; |
| } |
| final List<VirtualFile> ignoredFiles = new ArrayList<VirtualFile>(); |
| for (VirtualFile file : files) { |
| try { |
| antConfiguration.addBuildFile(file); |
| } |
| catch (AntNoFileException e) { |
| ignoredFiles.add(e.getFile()); |
| } |
| } |
| if (ignoredFiles.size() != 0) { |
| String messageText; |
| final StringBuilder message = StringBuilderSpinAllocator.alloc(); |
| try { |
| String separator = ""; |
| for (final VirtualFile virtualFile : ignoredFiles) { |
| message.append(separator); |
| message.append(virtualFile.getPresentableUrl()); |
| separator = "\n"; |
| } |
| messageText = message.toString(); |
| } |
| finally { |
| StringBuilderSpinAllocator.dispose(message); |
| } |
| Messages.showWarningDialog(myProject, messageText, AntBundle.message("cannot.add.ant.files.dialog.title")); |
| } |
| } |
| }); |
| } |
| |
| public void removeBuildFile() { |
| final AntBuildFile buildFile = getCurrentBuildFile(); |
| if (buildFile == null) { |
| return; |
| } |
| final String fileName = buildFile.getPresentableUrl(); |
| final int result = Messages.showYesNoDialog(myProject, AntBundle.message("remove.the.reference.to.file.confirmation.text", fileName), |
| AntBundle.message("confirm.remove.dialog.title"), Messages.getQuestionIcon()); |
| if (result != Messages.YES) { |
| return; |
| } |
| myConfig.removeBuildFile(buildFile); |
| } |
| |
| public void setBuildFileProperties() { |
| final AntBuildFileBase buildFile = getCurrentBuildFile(); |
| if (buildFile != null && BuildFilePropertiesPanel.editBuildFile(buildFile, myProject)) { |
| myConfig.updateBuildFile(buildFile); |
| myBuilder.queueUpdate(); |
| myTree.repaint(); |
| } |
| } |
| |
| private void runSelection(final DataContext dataContext) { |
| if (!canRunSelection()) { |
| return; |
| } |
| final AntBuildFileBase buildFile = getCurrentBuildFile(); |
| if (buildFile != null) { |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| final String[] targets = getTargetNamesFromPaths(paths); |
| ExecutionHandler.runBuild(buildFile, targets, null, dataContext, Collections.<BuildFileProperty>emptyList(), AntBuildListener.NULL); |
| } |
| } |
| |
| private boolean canRunSelection() { |
| if (myTree == null) { |
| return false; |
| } |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| if (paths == null) { |
| return false; |
| } |
| final AntBuildFile buildFile = getCurrentBuildFile(); |
| if (buildFile == null || !buildFile.exists()) { |
| return false; |
| } |
| for (final TreePath path : paths) { |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); |
| final Object userObject = node.getUserObject(); |
| final AntBuildFileNodeDescriptor buildFileNodeDescriptor; |
| if (userObject instanceof AntTargetNodeDescriptor) { |
| buildFileNodeDescriptor = (AntBuildFileNodeDescriptor)((DefaultMutableTreeNode)node.getParent()).getUserObject(); |
| } |
| else if (userObject instanceof AntBuildFileNodeDescriptor){ |
| buildFileNodeDescriptor = (AntBuildFileNodeDescriptor)userObject; |
| } |
| else { |
| buildFileNodeDescriptor = null; |
| } |
| if (buildFileNodeDescriptor == null || buildFileNodeDescriptor.getBuildFile() != buildFile) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private static String[] getTargetNamesFromPaths(TreePath[] paths) { |
| final List<String> targets = new ArrayList<String>(); |
| for (final TreePath path : paths) { |
| final Object userObject = ((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject(); |
| if (!(userObject instanceof AntTargetNodeDescriptor)) { |
| continue; |
| } |
| final AntBuildTarget target = ((AntTargetNodeDescriptor)userObject).getTarget(); |
| if (target instanceof MetaTarget) { |
| ContainerUtil.addAll(targets, ((MetaTarget)target).getTargetNames()); |
| } |
| else { |
| targets.add(target.getName()); |
| } |
| } |
| return ArrayUtil.toStringArray(targets); |
| } |
| |
| private static AntBuildTarget[] getTargetObjectsFromPaths(TreePath[] paths) { |
| final List<AntBuildTargetBase> targets = new ArrayList<AntBuildTargetBase>(); |
| for (final TreePath path : paths) { |
| final Object userObject = ((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject(); |
| if (!(userObject instanceof AntTargetNodeDescriptor)) { |
| continue; |
| } |
| final AntBuildTargetBase target = ((AntTargetNodeDescriptor)userObject).getTarget(); |
| targets.add(target); |
| |
| } |
| return targets.toArray(new AntBuildTargetBase[targets.size()]); |
| } |
| |
| public boolean isBuildFileSelected() { |
| if( myProject == null) return false; |
| final AntBuildFileBase file = getCurrentBuildFile(); |
| return file != null && file.exists(); |
| } |
| |
| @Nullable |
| private AntBuildFileBase getCurrentBuildFile() { |
| final AntBuildFileNodeDescriptor descriptor = getCurrentBuildFileNodeDescriptor(); |
| return (AntBuildFileBase)((descriptor == null) ? null : descriptor.getBuildFile()); |
| } |
| |
| @Nullable |
| private AntBuildFileNodeDescriptor getCurrentBuildFileNodeDescriptor() { |
| if (myTree == null) { |
| return null; |
| } |
| final TreePath path = myTree.getSelectionPath(); |
| if (path == null) { |
| return null; |
| } |
| DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); |
| while (node != null) { |
| final Object userObject = node.getUserObject(); |
| if (userObject instanceof AntBuildFileNodeDescriptor) { |
| return (AntBuildFileNodeDescriptor)userObject; |
| } |
| node = (DefaultMutableTreeNode)node.getParent(); |
| } |
| return null; |
| } |
| |
| private void popupInvoked(final Component comp, final int x, final int y) { |
| Object userObject = null; |
| final TreePath path = myTree.getSelectionPath(); |
| if (path != null) { |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); |
| if (node != null) { |
| userObject = node.getUserObject(); |
| } |
| } |
| final DefaultActionGroup group = new DefaultActionGroup(); |
| group.add(new RunAction()); |
| group.add(new CreateMetaTargetAction()); |
| group.add(new MakeAntRunConfigurationAction()); |
| group.add(new RemoveMetaTargetsOrBuildFileAction()); |
| group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); |
| if (userObject instanceof AntBuildFileNodeDescriptor) { |
| group.add(new RemoveBuildFileAction(this)); |
| } |
| if (userObject instanceof AntTargetNodeDescriptor) { |
| final AntBuildTargetBase target = ((AntTargetNodeDescriptor)userObject).getTarget(); |
| final DefaultActionGroup executeOnGroup = |
| new DefaultActionGroup(AntBundle.message("ant.explorer.execute.on.action.group.name"), true); |
| executeOnGroup.add(new ExecuteOnEventAction(target, ExecuteBeforeCompilationEvent.getInstance())); |
| executeOnGroup.add(new ExecuteOnEventAction(target, ExecuteAfterCompilationEvent.getInstance())); |
| executeOnGroup.addSeparator(); |
| executeOnGroup.add(new ExecuteBeforeRunAction(target)); |
| group.add(executeOnGroup); |
| group.add(new AssignShortcutAction(target.getActionId())); |
| } |
| group.add(myAntBuildFilePropertiesAction); |
| final ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.ANT_EXPLORER_POPUP, group); |
| popupMenu.getComponent().show(comp, x, y); |
| } |
| |
| @Nullable |
| public Object getData(@NonNls String dataId) { |
| if (CommonDataKeys.NAVIGATABLE.is(dataId)) { |
| final AntBuildFile buildFile = getCurrentBuildFile(); |
| if (buildFile == null) { |
| return null; |
| } |
| final VirtualFile file = buildFile.getVirtualFile(); |
| if (file == null) { |
| return null; |
| } |
| final TreePath treePath = myTree.getLeadSelectionPath(); |
| if (treePath == null) { |
| return null; |
| } |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent(); |
| if (node == null) { |
| return null; |
| } |
| if (node.getUserObject() instanceof AntTargetNodeDescriptor) { |
| final AntTargetNodeDescriptor targetNodeDescriptor = (AntTargetNodeDescriptor)node.getUserObject(); |
| final AntBuildTargetBase buildTarget = targetNodeDescriptor.getTarget(); |
| final OpenFileDescriptor descriptor = buildTarget.getOpenFileDescriptor(); |
| if (descriptor != null) { |
| final VirtualFile descriptorFile = descriptor.getFile(); |
| if (descriptorFile.isValid()) { |
| return descriptor; |
| } |
| } |
| } |
| if (file.isValid()) { |
| return new OpenFileDescriptor(myProject, file); |
| } |
| } |
| else if (PlatformDataKeys.HELP_ID.is(dataId)) { |
| return HelpID.ANT; |
| } |
| else if (PlatformDataKeys.TREE_EXPANDER.is(dataId)) { |
| return myProject != null? myTreeExpander : null; |
| } |
| else if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| if (paths == null) { |
| return null; |
| } |
| final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(); |
| for (final TreePath path : paths) { |
| for (DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); |
| node != null; |
| node = (DefaultMutableTreeNode)node.getParent()) { |
| final Object userObject = node.getUserObject(); |
| if (!(userObject instanceof AntBuildFileNodeDescriptor)) { |
| continue; |
| } |
| final AntBuildFile buildFile = ((AntBuildFileNodeDescriptor)userObject).getBuildFile(); |
| if (buildFile != null) { |
| final VirtualFile virtualFile = buildFile.getVirtualFile(); |
| if (virtualFile != null && virtualFile.isValid()) { |
| result.add(virtualFile); |
| } |
| } |
| break; |
| } |
| } |
| if (result.size() == 0) { |
| return null; |
| } |
| return VfsUtil.toVirtualFileArray(result); |
| } |
| return super.getData(dataId); |
| } |
| |
| public static FileChooserDescriptor createXmlDescriptor() { |
| return new FileChooserDescriptor(true, false, false, false, false, true){ |
| public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { |
| boolean b = super.isFileVisible(file, showHiddenFiles); |
| if (!file.isDirectory()) { |
| b &= StdFileTypes.XML.equals(file.getFileType()); |
| } |
| return b; |
| } |
| }; |
| } |
| |
| private static final class NodeRenderer extends ColoredTreeCellRenderer { |
| public void customizeCellRenderer(JTree tree, |
| Object value, |
| boolean selected, |
| boolean expanded, |
| boolean leaf, |
| int row, |
| boolean hasFocus) { |
| final Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); |
| if (userObject instanceof AntNodeDescriptor) { |
| final AntNodeDescriptor descriptor = (AntNodeDescriptor)userObject; |
| descriptor.customize(this); |
| } |
| else { |
| append(tree.convertValueToText(value, selected, expanded, leaf, row, hasFocus), SimpleTextAttributes.REGULAR_ATTRIBUTES); |
| } |
| } |
| } |
| |
| private final class AddAction extends AnAction { |
| public AddAction() { |
| super(AntBundle.message("add.ant.file.action.name"), AntBundle.message("add.ant.file.action.description"), IconUtil.getAddIcon()); |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| addBuildFile(); |
| } |
| } |
| |
| private final class RemoveAction extends AnAction { |
| public RemoveAction() { |
| super(AntBundle.message("remove.ant.file.action.name"), AntBundle.message("remove.ant.file.action.description"), |
| IconUtil.getRemoveIcon()); |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| removeBuildFile(); |
| } |
| |
| public void update(AnActionEvent event) { |
| event.getPresentation().setEnabled(getCurrentBuildFile() != null); |
| } |
| } |
| |
| private final class RunAction extends AnAction { |
| public RunAction() { |
| super(AntBundle.message("run.ant.file.or.target.action.name"), AntBundle.message("run.ant.file.or.target.action.description"), |
| AllIcons.Actions.Execute); |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| runSelection(e.getDataContext()); |
| } |
| |
| public void update(AnActionEvent event) { |
| final Presentation presentation = event.getPresentation(); |
| final String place = event.getPlace(); |
| if (ActionPlaces.ANT_EXPLORER_TOOLBAR.equals(place)) { |
| presentation.setText(AntBundle.message("run.ant.file.or.target.action.name")); |
| } |
| else { |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| if (paths != null && paths.length == 1 && |
| ((DefaultMutableTreeNode)paths[0].getLastPathComponent()).getUserObject() instanceof AntBuildFileNodeDescriptor) { |
| presentation.setText(AntBundle.message("run.ant.build.action.name")); |
| } |
| else { |
| if (paths == null || paths.length == 1) { |
| presentation.setText(AntBundle.message("run.ant.target.action.name")); |
| } |
| else { |
| presentation.setText(AntBundle.message("run.ant.targets.action.name")); |
| } |
| } |
| } |
| |
| presentation.setEnabled(canRunSelection()); |
| } |
| } |
| private final class MakeAntRunConfigurationAction extends AnAction { |
| public MakeAntRunConfigurationAction() { |
| super(AntBundle.message("make.ant.runconfiguration.name"), null, AntIcons.Build); |
| } |
| |
| @Override |
| public void update(AnActionEvent e) { |
| super.update(e); |
| |
| final Presentation presentation = e.getPresentation(); |
| presentation.setEnabled(myTree.getSelectionCount() == 1 && canRunSelection()); |
| } |
| |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| final AntBuildFile buildFile = getCurrentBuildFile(); |
| if (buildFile == null || !buildFile.exists()) { |
| return; |
| } |
| |
| TreePath selectionPath = myTree.getSelectionPath(); |
| if (selectionPath == null) return; |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent(); |
| final Object userObject = node.getUserObject(); |
| AntBuildTarget target = null; |
| if (userObject instanceof AntTargetNodeDescriptor) { |
| AntTargetNodeDescriptor targetNodeDescriptor = (AntTargetNodeDescriptor)userObject; |
| target = targetNodeDescriptor.getTarget(); |
| } |
| else if (userObject instanceof AntBuildFileNodeDescriptor){ |
| AntBuildModel model = ((AntBuildFileNodeDescriptor)userObject).getBuildFile().getModel(); |
| target = model.findTarget(model.getDefaultTargetName()); |
| } |
| String name = target != null ? target.getDisplayName() : null; |
| if (target == null || name == null) { |
| return; |
| } |
| |
| RunManagerImpl runManager = (RunManagerImpl)RunManager.getInstance(e.getProject()); |
| RunnerAndConfigurationSettings settings = |
| runManager.createRunConfiguration(name, AntRunConfigurationType.getInstance().getFactory()); |
| AntRunConfiguration configuration = (AntRunConfiguration)settings.getConfiguration(); |
| configuration.acceptSettings(target); |
| if (RunDialog.editConfiguration(e.getProject(), settings, ExecutionBundle |
| .message("create.run.configuration.for.item.dialog.title", configuration.getName()))) { |
| runManager.addConfiguration(settings, |
| runManager.isConfigurationShared(settings), |
| runManager.getBeforeRunTasks(settings.getConfiguration()), false); |
| runManager.setSelectedConfiguration(settings); |
| } |
| } |
| } |
| |
| |
| private final class ShowAllTargetsAction extends ToggleAction { |
| public ShowAllTargetsAction() { |
| super(AntBundle.message("filter.ant.targets.action.name"), AntBundle.message("filter.ant.targets.action.description"), |
| AllIcons.General.Filter); |
| } |
| |
| public boolean isSelected(AnActionEvent event) { |
| final Project project = myProject; |
| return project != null? AntConfigurationBase.getInstance(project).isFilterTargets() : false; |
| } |
| |
| public void setSelected(AnActionEvent event, boolean flag) { |
| setTargetsFiltered(flag); |
| } |
| } |
| |
| private void setTargetsFiltered(boolean value) { |
| myBuilder.setTargetsFiltered(value); |
| AntConfigurationBase.getInstance(myProject).setFilterTargets(value); |
| } |
| |
| private final class ExecuteOnEventAction extends ToggleAction { |
| private final AntBuildTargetBase myTarget; |
| private final ExecutionEvent myExecutionEvent; |
| |
| public ExecuteOnEventAction(final AntBuildTargetBase target, final ExecutionEvent executionEvent) { |
| super(executionEvent.getPresentableName()); |
| myTarget = target; |
| myExecutionEvent = executionEvent; |
| } |
| |
| public boolean isSelected(AnActionEvent e) { |
| return myTarget.equals(AntConfigurationBase.getInstance(myProject).getTargetForEvent(myExecutionEvent)); |
| } |
| |
| public void setSelected(AnActionEvent event, boolean state) { |
| final AntConfigurationBase antConfiguration = AntConfigurationBase.getInstance(myProject); |
| if (state) { |
| final AntBuildFileBase buildFile = |
| (AntBuildFileBase)((myTarget instanceof MetaTarget) ? ((MetaTarget)myTarget).getBuildFile() : myTarget.getModel().getBuildFile()); |
| antConfiguration.setTargetForEvent(buildFile, myTarget.getName(), myExecutionEvent); |
| } |
| else { |
| antConfiguration.clearTargetForEvent(myExecutionEvent); |
| } |
| myBuilder.queueUpdate(); |
| } |
| |
| public void update(AnActionEvent e) { |
| super.update(e); |
| final AntBuildFile buildFile = myTarget.getModel().getBuildFile(); |
| e.getPresentation().setEnabled(buildFile != null && buildFile.exists()); |
| } |
| } |
| |
| private final class ExecuteBeforeRunAction extends AnAction { |
| private final AntBuildTarget myTarget; |
| |
| public ExecuteBeforeRunAction(final AntBuildTarget target) { |
| super(AntBundle.message("executes.before.run.debug.acton.name")); |
| myTarget = target; |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| final AntExecuteBeforeRunDialog dialog = new AntExecuteBeforeRunDialog(myProject, myTarget); |
| dialog.show(); |
| } |
| |
| public void update(AnActionEvent e) { |
| e.getPresentation().setEnabled(myTarget.getModel().getBuildFile().exists()); |
| } |
| } |
| |
| private final class CreateMetaTargetAction extends AnAction { |
| |
| public CreateMetaTargetAction() { |
| super(AntBundle.message("ant.create.meta.target.action.name"), AntBundle.message("ant.create.meta.target.action.description"), null |
| /*IconLoader.getIcon("/actions/execute.png")*/); |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| final AntBuildFile buildFile = getCurrentBuildFile(); |
| final String[] targets = getTargetNamesFromPaths(myTree.getSelectionPaths()); |
| final ExecuteCompositeTargetEvent event = new ExecuteCompositeTargetEvent(targets); |
| final SaveMetaTargetDialog dialog = new SaveMetaTargetDialog(myTree, event, AntConfigurationBase.getInstance(myProject), buildFile); |
| dialog.setTitle(e.getPresentation().getText()); |
| dialog.show(); |
| if (dialog.isOK()) { |
| myBuilder.queueUpdate(); |
| myTree.repaint(); |
| } |
| } |
| |
| public void update(AnActionEvent e) { |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| e.getPresentation().setEnabled(paths != null && paths.length > 1 && canRunSelection()); |
| } |
| } |
| |
| private final class RemoveMetaTargetsOrBuildFileAction extends AnAction { |
| |
| public RemoveMetaTargetsOrBuildFileAction() { |
| super(AntBundle.message("remove.meta.targets.action.name"), AntBundle.message("remove.meta.targets.action.description"), null); |
| registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree); |
| Disposer.register(AntExplorer.this, new Disposable() { |
| public void dispose() { |
| RemoveMetaTargetsOrBuildFileAction.this.unregisterCustomShortcutSet(myTree); |
| } |
| }); |
| myTree.registerKeyboardAction(new AbstractAction() { |
| public void actionPerformed(ActionEvent e) { |
| doAction(); |
| } |
| }, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| doAction(); |
| } |
| |
| private void doAction() { |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| if (paths == null) { |
| return; |
| } |
| try { |
| // try to remove build file |
| if (paths.length == 1) { |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode)paths[0].getLastPathComponent(); |
| if (node.getUserObject() instanceof AntBuildFileNodeDescriptor) { |
| final AntBuildFileNodeDescriptor descriptor = (AntBuildFileNodeDescriptor)node.getUserObject(); |
| if (descriptor.getBuildFile().equals(getCurrentBuildFile())) { |
| removeBuildFile(); |
| return; |
| } |
| } |
| } |
| // try to remove meta targets |
| final AntBuildTarget[] targets = getTargetObjectsFromPaths(paths); |
| final AntConfigurationBase antConfiguration = AntConfigurationBase.getInstance(myProject); |
| for (final AntBuildTarget buildTarget : targets) { |
| if (buildTarget instanceof MetaTarget) { |
| for (final ExecutionEvent event : antConfiguration.getEventsForTarget(buildTarget)) { |
| if (event instanceof ExecuteCompositeTargetEvent) { |
| antConfiguration.clearTargetForEvent(event); |
| } |
| } |
| } |
| } |
| } |
| finally { |
| myBuilder.queueUpdate(); |
| myTree.repaint(); |
| } |
| } |
| |
| public void update(AnActionEvent e) { |
| final Presentation presentation = e.getPresentation(); |
| final TreePath[] paths = myTree.getSelectionPaths(); |
| if (paths == null) { |
| presentation.setEnabled(false); |
| return; |
| } |
| |
| if (paths.length == 1) { |
| String text = AntBundle.message("remove.meta.target.action.name"); |
| boolean enabled = false; |
| final DefaultMutableTreeNode node = (DefaultMutableTreeNode)paths[0].getLastPathComponent(); |
| if (node.getUserObject() instanceof AntBuildFileNodeDescriptor) { |
| final AntBuildFileNodeDescriptor descriptor = (AntBuildFileNodeDescriptor)node.getUserObject(); |
| if (descriptor.getBuildFile().equals(getCurrentBuildFile())) { |
| text = AntBundle.message("remove.selected.build.file.action.name"); |
| enabled = true; |
| } |
| } |
| else { |
| if (node.getUserObject() instanceof AntTargetNodeDescriptor) { |
| final AntTargetNodeDescriptor descr = (AntTargetNodeDescriptor)node.getUserObject(); |
| final AntBuildTargetBase target = descr.getTarget(); |
| if (target instanceof MetaTarget) { |
| enabled = true; |
| } |
| } |
| } |
| presentation.setText(text); |
| presentation.setEnabled(enabled); |
| } |
| else { |
| presentation.setText(AntBundle.message("remove.selected.meta.targets.action.name")); |
| final AntBuildTarget[] targets = getTargetObjectsFromPaths(paths); |
| boolean enabled = targets.length > 0; |
| for (final AntBuildTarget buildTarget : targets) { |
| if (!(buildTarget instanceof MetaTarget)) { |
| enabled = false; |
| break; |
| } |
| } |
| presentation.setEnabled(enabled); |
| } |
| } |
| } |
| |
| private final class AssignShortcutAction extends AnAction { |
| private final String myActionId; |
| |
| public AssignShortcutAction(String actionId) { |
| super(AntBundle.message("ant.explorer.assign.shortcut.action.name")); |
| myActionId = actionId; |
| } |
| |
| public void actionPerformed(AnActionEvent e) { |
| new EditKeymapsDialog(myProject, myActionId).show(); |
| } |
| |
| public void update(AnActionEvent e) { |
| e.getPresentation().setEnabled(myActionId != null && ActionManager.getInstance().getAction(myActionId) != null); |
| } |
| } |
| |
| private class KeymapListener implements KeymapManagerListener, Keymap.Listener { |
| private Keymap myCurrentKeymap = null; |
| |
| public KeymapListener() { |
| final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx(); |
| final Keymap activeKeymap = keymapManager.getActiveKeymap(); |
| listenTo(activeKeymap); |
| keymapManager.addKeymapManagerListener(this); |
| } |
| |
| public void activeKeymapChanged(Keymap keymap) { |
| listenTo(keymap); |
| updateTree(); |
| } |
| |
| private void listenTo(Keymap keymap) { |
| if (myCurrentKeymap != null) { |
| myCurrentKeymap.removeShortcutChangeListener(this); |
| } |
| myCurrentKeymap = keymap; |
| if (myCurrentKeymap != null) { |
| myCurrentKeymap.addShortcutChangeListener(this); |
| } |
| } |
| |
| private void updateTree() { |
| myBuilder.updateFromRoot(); |
| } |
| |
| public void onShortcutChanged(String actionId) { |
| updateTree(); |
| } |
| |
| public void stopListen() { |
| listenTo(null); |
| KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this); |
| } |
| } |
| |
| private final class MyTransferHandler extends TransferHandler { |
| |
| @Override |
| public boolean importData(final TransferSupport support) { |
| if (canImport(support)) { |
| addBuildFile(getAntFiles(support)); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean canImport(final TransferSupport support) { |
| return FileCopyPasteUtil.isFileListFlavorAvailable(support.getDataFlavors()); |
| } |
| |
| private VirtualFile[] getAntFiles(final TransferSupport support) { |
| List<VirtualFile> virtualFileList = new ArrayList<VirtualFile>(); |
| final List<File> fileList = FileCopyPasteUtil.getFileList(support.getTransferable()); |
| if (fileList != null) { |
| for (File file : fileList ) { |
| ContainerUtil.addIfNotNull(virtualFileList, VfsUtil.findFileByIoFile(file, true)); |
| } |
| } |
| |
| return VfsUtil.toVirtualFileArray(virtualFileList); |
| } |
| } |
| } |