2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.lang
.ant
.config
.explorer
;
18 import com
.intellij
.execution
.RunManagerEx
;
19 import com
.intellij
.execution
.RunManagerListener
;
20 import com
.intellij
.ide
.CommonActionsManager
;
21 import com
.intellij
.ide
.DataManager
;
22 import com
.intellij
.ide
.TreeExpander
;
23 import com
.intellij
.ide
.actions
.ContextHelpAction
;
24 import com
.intellij
.lang
.ant
.AntBundle
;
25 import com
.intellij
.lang
.ant
.config
.*;
26 import com
.intellij
.lang
.ant
.config
.actions
.AntBuildFilePropertiesAction
;
27 import com
.intellij
.lang
.ant
.config
.actions
.RemoveBuildFileAction
;
28 import com
.intellij
.lang
.ant
.config
.execution
.ExecutionHandler
;
29 import com
.intellij
.lang
.ant
.config
.impl
.*;
30 import com
.intellij
.lang
.ant
.config
.impl
.configuration
.BuildFilePropertiesPanel
;
31 import com
.intellij
.openapi
.Disposable
;
32 import com
.intellij
.openapi
.actionSystem
.*;
33 import com
.intellij
.openapi
.application
.ApplicationManager
;
34 import com
.intellij
.openapi
.diagnostic
.Logger
;
35 import com
.intellij
.openapi
.fileChooser
.FileChooser
;
36 import com
.intellij
.openapi
.fileChooser
.FileChooserDescriptor
;
37 import com
.intellij
.openapi
.fileEditor
.OpenFileDescriptor
;
38 import com
.intellij
.openapi
.fileTypes
.FileTypeManager
;
39 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
40 import com
.intellij
.openapi
.keymap
.Keymap
;
41 import com
.intellij
.openapi
.keymap
.KeymapManagerListener
;
42 import com
.intellij
.openapi
.keymap
.ex
.KeymapManagerEx
;
43 import com
.intellij
.openapi
.keymap
.impl
.ui
.EditKeymapsDialog
;
44 import com
.intellij
.openapi
.project
.Project
;
45 import com
.intellij
.openapi
.ui
.Messages
;
46 import com
.intellij
.openapi
.ui
.SimpleToolWindowPanel
;
47 import com
.intellij
.openapi
.util
.Disposer
;
48 import com
.intellij
.openapi
.util
.IconLoader
;
49 import com
.intellij
.openapi
.vfs
.VfsUtil
;
50 import com
.intellij
.openapi
.vfs
.VirtualFile
;
51 import com
.intellij
.ui
.*;
52 import com
.intellij
.ui
.treeStructure
.Tree
;
53 import com
.intellij
.util
.ArrayUtil
;
54 import com
.intellij
.util
.StringBuilderSpinAllocator
;
55 import com
.intellij
.util
.ui
.tree
.TreeUtil
;
56 import org
.jetbrains
.annotations
.NonNls
;
57 import org
.jetbrains
.annotations
.Nullable
;
60 import javax
.swing
.tree
.DefaultMutableTreeNode
;
61 import javax
.swing
.tree
.DefaultTreeModel
;
62 import javax
.swing
.tree
.TreePath
;
64 import java
.awt
.event
.ActionEvent
;
65 import java
.awt
.event
.KeyEvent
;
66 import java
.awt
.event
.MouseAdapter
;
67 import java
.awt
.event
.MouseEvent
;
68 import java
.util
.ArrayList
;
69 import java
.util
.Arrays
;
70 import java
.util
.List
;
72 public class AntExplorer
extends SimpleToolWindowPanel
implements DataProvider
{
74 private static final Logger LOG
= Logger
.getInstance("#com.intellij.lang.ant.config.explorer.AntExplorer");
76 private Project myProject
;
77 private AntExplorerTreeBuilder myBuilder
;
79 private KeymapListener myKeymapListener
;
80 private final List
<Disposable
> myDisposables
= new ArrayList
<Disposable
>();
81 private final AntBuildFilePropertiesAction myAntBuildFilePropertiesAction
;
83 private final TreeExpander myTreeExpander
= new TreeExpander() {
84 public void expandAll() {
85 myBuilder
.expandAll();
88 public boolean canExpand() {
89 return AntConfiguration
.getInstance(myProject
).getBuildFiles().length
!= 0;
92 public void collapseAll() {
93 myBuilder
.collapseAll();
96 public boolean canCollapse() {
100 private static final Icon ICON_RUN
= IconLoader
.getIcon("/actions/execute.png");
101 private static final Icon ICON_REMOVE
= IconLoader
.getIcon("/general/remove.png");
102 private static final Icon ICON_ADD
= IconLoader
.getIcon("/general/add.png");
103 private static final Icon ICON_FILTER
= IconLoader
.getIcon("/ant/filter.png");
105 public AntExplorer(final Project project
) {
108 final DefaultTreeModel model
= new DefaultTreeModel(new DefaultMutableTreeNode());
109 myTree
= new Tree(model
);
110 myTree
.setRootVisible(false);
111 myTree
.setShowsRootHandles(true);
112 myTree
.setCellRenderer(new NodeRenderer());
113 myBuilder
= new AntExplorerTreeBuilder(project
, myTree
, model
);
114 myBuilder
.setTargetsFiltered(AntConfigurationBase
.getInstance(project
).isFilterTargets());
115 TreeToolTipHandler
.install(myTree
);
116 TreeUtil
.installActions(myTree
);
117 new TreeSpeedSearch(myTree
);
118 myTree
.addMouseListener(new PopupHandler() {
119 public void invokePopup(final Component comp
, final int x
, final int y
) {
120 popupInvoked(comp
, x
, y
);
123 myTree
.addMouseListener(new MouseAdapter() {
124 public void mouseClicked(MouseEvent e
) {
125 if (e
.getClickCount() == 2) {
126 final TreePath path
= myTree
.getPathForLocation(e
.getX(), e
.getY());
128 runSelection(DataManager
.getInstance().getDataContext(myTree
));
133 myTree
.registerKeyboardAction(new AbstractAction() {
134 public void actionPerformed(ActionEvent e
) {
135 runSelection(DataManager
.getInstance().getDataContext(myTree
));
137 }, KeyStroke
.getKeyStroke(KeyEvent
.VK_ENTER
, 0), WHEN_FOCUSED
);
139 myTree
.setLineStyleAngled();
140 myAntBuildFilePropertiesAction
= new AntBuildFilePropertiesAction(this);
141 setToolbar(createToolbarPanel());
142 setContent(new JScrollPane(myTree
));
143 ToolTipManager
.sharedInstance().registerComponent(myTree
);
144 myKeymapListener
= new KeymapListener();
146 RunManagerEx
.getInstanceEx(myProject
).addRunManagerListener(new RunManagerListener() {
147 public void beforeRunTasksChanged() {
153 public void dispose() {
154 for (final Disposable disposable
: myDisposables
) {
155 disposable
.dispose();
157 myDisposables
.clear();
159 if (myKeymapListener
!= null) {
160 myKeymapListener
.stopListen();
161 myKeymapListener
= null;
164 LOG
.error("already disposed");
166 if (myBuilder
!= null) {
167 Disposer
.dispose(myBuilder
);
170 if (myTree
!= null) {
171 ToolTipManager
.sharedInstance().unregisterComponent(myTree
);
172 final KeyStroke
[] strokes
= myTree
.getRegisteredKeyStrokes();
173 for (KeyStroke keyStroke
: strokes
) {
174 myTree
.unregisterKeyboardAction(keyStroke
);
180 private JPanel
createToolbarPanel() {
181 final DefaultActionGroup group
= new DefaultActionGroup();
182 group
.add(new AddAction());
183 group
.add(new RemoveAction());
184 group
.add(new RunAction());
185 group
.add(new ShowAllTargetsAction());
186 AnAction action
= CommonActionsManager
.getInstance().createExpandAllAction(myTreeExpander
, this);
187 action
.getTemplatePresentation().setDescription(AntBundle
.message("ant.explorer.expand.all.nodes.action.description"));
189 action
= CommonActionsManager
.getInstance().createCollapseAllAction(myTreeExpander
, this);
190 action
.getTemplatePresentation().setDescription(AntBundle
.message("ant.explorer.collapse.all.nodes.action.description"));
192 group
.add(myAntBuildFilePropertiesAction
);
193 group
.add(new ContextHelpAction(HelpID
.ANT
));
195 final ActionToolbar actionToolBar
= ActionManager
.getInstance().createActionToolbar(ActionPlaces
.ANT_EXPLORER_TOOLBAR
, group
, true);
196 final JPanel buttonsPanel
= new JPanel(new BorderLayout());
197 buttonsPanel
.add(actionToolBar
.getComponent(), BorderLayout
.CENTER
);
201 private void addBuildFile() {
202 final FileChooserDescriptor descriptor
= createXmlDescriptor();
203 descriptor
.setTitle(AntBundle
.message("select.ant.build.file.dialog.title"));
204 descriptor
.setDescription(AntBundle
.message("select.ant.build.file.dialog.description"));
205 final VirtualFile
[] files
= FileChooser
.chooseFiles(myProject
, descriptor
);
206 if (files
.length
== 0) {
209 ApplicationManager
.getApplication().invokeLater(new Runnable() {
211 final AntConfiguration antConfiguration
= AntConfiguration
.getInstance(myProject
);
212 final ArrayList
<VirtualFile
> ignoredFiles
= new ArrayList
<VirtualFile
>();
213 for (VirtualFile file
: files
) {
215 antConfiguration
.addBuildFile(file
);
217 catch (AntNoFileException e
) {
218 ignoredFiles
.add(e
.getFile());
221 if (ignoredFiles
.size() != 0) {
223 final StringBuilder message
= StringBuilderSpinAllocator
.alloc();
225 String separator
= "";
226 for (final VirtualFile virtualFile
: ignoredFiles
) {
227 message
.append(separator
);
228 message
.append(virtualFile
.getPresentableUrl());
231 messageText
= message
.toString();
234 StringBuilderSpinAllocator
.dispose(message
);
236 Messages
.showWarningDialog(myProject
, messageText
, AntBundle
.message("cannot.add.ant.files.dialog.title"));
242 public void removeBuildFile() {
243 final AntBuildFile buildFile
= getCurrentBuildFile();
244 if (buildFile
== null) {
247 final String fileName
= buildFile
.getPresentableUrl();
248 final int result
= Messages
.showYesNoDialog(myProject
, AntBundle
.message("remove.the.reference.to.file.confirmation.text", fileName
),
249 AntBundle
.message("confirm.remove.dialog.title"), Messages
.getQuestionIcon());
253 AntConfiguration
.getInstance(myProject
).removeBuildFile(buildFile
);
256 public void setBuildFileProperties(DataContext dataContext
) {
257 final AntBuildFile buildFile
= getCurrentBuildFile();
258 if (BuildFilePropertiesPanel
.editBuildFile(getCurrentBuildFile())) {
259 final AntConfiguration antConfiguration
= AntConfiguration
.getInstance(myProject
);
260 antConfiguration
.updateBuildFile(buildFile
);
266 private void runSelection(final DataContext dataContext
) {
267 if (!canRunSelection()) {
270 final AntBuildFileBase buildFile
= getCurrentBuildFile();
271 final TreePath
[] paths
= myTree
.getSelectionPaths();
272 final String
[] targets
= getTargetNamesFromPaths(paths
);
273 ExecutionHandler
.runBuild(buildFile
, targets
, null, dataContext
, AntBuildListener
.NULL
);
276 private boolean canRunSelection() {
277 if (myTree
== null) {
280 final TreePath
[] paths
= myTree
.getSelectionPaths();
284 final AntBuildFile buildFile
= getCurrentBuildFile();
285 if (buildFile
== null || !buildFile
.exists()) {
288 for (final TreePath path
: paths
) {
289 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
290 final Object userObject
= node
.getUserObject();
291 final AntBuildFileNodeDescriptor buildFileNodeDescriptor
;
292 if (userObject
instanceof AntTargetNodeDescriptor
) {
293 buildFileNodeDescriptor
= (AntBuildFileNodeDescriptor
)((DefaultMutableTreeNode
)node
.getParent()).getUserObject();
295 else if (userObject
instanceof AntBuildFileNodeDescriptor
){
296 buildFileNodeDescriptor
= (AntBuildFileNodeDescriptor
)userObject
;
299 buildFileNodeDescriptor
= null;
301 if (buildFileNodeDescriptor
== null || buildFileNodeDescriptor
.getBuildFile() != buildFile
) {
308 private static String
[] getTargetNamesFromPaths(TreePath
[] paths
) {
309 final List
<String
> targets
= new ArrayList
<String
>();
310 for (final TreePath path
: paths
) {
311 final Object userObject
= ((DefaultMutableTreeNode
)path
.getLastPathComponent()).getUserObject();
312 if (!(userObject
instanceof AntTargetNodeDescriptor
)) {
315 final AntBuildTarget target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
316 if (target
instanceof MetaTarget
) {
317 targets
.addAll(Arrays
.asList(((MetaTarget
)target
).getTargetNames()));
320 targets
.add(target
.getName());
323 return ArrayUtil
.toStringArray(targets
);
326 private static AntBuildTarget
[] getTargetObjectsFromPaths(TreePath
[] paths
) {
327 final List
<AntBuildTargetBase
> targets
= new ArrayList
<AntBuildTargetBase
>();
328 for (final TreePath path
: paths
) {
329 final Object userObject
= ((DefaultMutableTreeNode
)path
.getLastPathComponent()).getUserObject();
330 if (!(userObject
instanceof AntTargetNodeDescriptor
)) {
333 final AntBuildTargetBase target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
337 return targets
.toArray(new AntBuildTargetBase
[targets
.size()]);
340 public boolean isBuildFileSelected() {
341 if( myProject
== null) return false;
342 final AntBuildFileBase file
= getCurrentBuildFile();
343 return file
!= null && file
.exists();
347 private AntBuildFileBase
getCurrentBuildFile() {
348 final AntBuildFileNodeDescriptor descriptor
= getCurrentBuildFileNodeDescriptor();
349 return (AntBuildFileBase
)((descriptor
== null) ?
null : descriptor
.getBuildFile());
353 private AntBuildFileNodeDescriptor
getCurrentBuildFileNodeDescriptor() {
354 if (myTree
== null) {
357 final TreePath path
= myTree
.getSelectionPath();
361 DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
362 while (node
!= null) {
363 final Object userObject
= node
.getUserObject();
364 if (userObject
instanceof AntBuildFileNodeDescriptor
) {
365 return (AntBuildFileNodeDescriptor
)userObject
;
367 node
= (DefaultMutableTreeNode
)node
.getParent();
372 private void popupInvoked(final Component comp
, final int x
, final int y
) {
373 Object userObject
= null;
374 final TreePath path
= myTree
.getSelectionPath();
376 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
378 userObject
= node
.getUserObject();
381 final DefaultActionGroup group
= new DefaultActionGroup();
382 group
.add(new RunAction());
383 group
.add(new CreateMetaTargetAction());
384 group
.add(new RemoveMetaTargetsOrBuildFileAction());
385 group
.add(ActionManager
.getInstance().getAction(IdeActions
.ACTION_EDIT_SOURCE
));
386 if (userObject
instanceof AntBuildFileNodeDescriptor
) {
387 group
.add(new RemoveBuildFileAction(this));
389 if (userObject
instanceof AntTargetNodeDescriptor
) {
390 final AntBuildTargetBase target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
391 final DefaultActionGroup executeOnGroup
=
392 new DefaultActionGroup(AntBundle
.message("ant.explorer.execute.on.action.group.name"), true);
393 executeOnGroup
.add(new ExecuteOnEventAction(target
, ExecuteBeforeCompilationEvent
.getInstance()));
394 executeOnGroup
.add(new ExecuteOnEventAction(target
, ExecuteAfterCompilationEvent
.getInstance()));
395 executeOnGroup
.addSeparator();
396 executeOnGroup
.add(new ExecuteBeforeRunAction(target
));
397 group
.add(executeOnGroup
);
398 group
.add(new AssignShortcutAction(target
.getActionId()));
400 group
.add(myAntBuildFilePropertiesAction
);
401 final ActionPopupMenu popupMenu
= ActionManager
.getInstance().createActionPopupMenu(ActionPlaces
.ANT_EXPLORER_POPUP
, group
);
402 popupMenu
.getComponent().show(comp
, x
, y
);
406 public Object
getData(@NonNls String dataId
) {
407 if (PlatformDataKeys
.NAVIGATABLE
.is(dataId
)) {
408 final AntBuildFile buildFile
= getCurrentBuildFile();
409 if (buildFile
== null) {
412 final VirtualFile file
= buildFile
.getVirtualFile();
416 final TreePath treePath
= myTree
.getLeadSelectionPath();
417 if (treePath
== null) {
420 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)treePath
.getLastPathComponent();
424 if (node
.getUserObject() instanceof AntTargetNodeDescriptor
) {
425 final AntTargetNodeDescriptor targetNodeDescriptor
= (AntTargetNodeDescriptor
)node
.getUserObject();
426 final AntBuildTargetBase buildTarget
= targetNodeDescriptor
.getTarget();
427 final OpenFileDescriptor descriptor
= buildTarget
.getOpenFileDescriptor();
428 if (descriptor
!= null) {
429 final VirtualFile descriptorFile
= descriptor
.getFile();
430 if (descriptorFile
.isValid()) {
435 if (file
.isValid()) {
436 return new OpenFileDescriptor(myProject
, file
);
439 else if (PlatformDataKeys
.HELP_ID
.is(dataId
)) {
442 else if (PlatformDataKeys
.TREE_EXPANDER
.is(dataId
)) {
443 return myTreeExpander
;
445 else if (PlatformDataKeys
.VIRTUAL_FILE_ARRAY
.is(dataId
)) {
446 final TreePath
[] paths
= myTree
.getSelectionPaths();
450 final ArrayList
<VirtualFile
> result
= new ArrayList
<VirtualFile
>();
451 for (final TreePath path
: paths
) {
452 for (DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
454 node
= (DefaultMutableTreeNode
)node
.getParent()) {
455 final Object userObject
= node
.getUserObject();
456 if (!(userObject
instanceof AntBuildFileNodeDescriptor
)) {
459 final AntBuildFile buildFile
= ((AntBuildFileNodeDescriptor
)userObject
).getBuildFile();
460 if (buildFile
!= null) {
461 final VirtualFile virtualFile
= buildFile
.getVirtualFile();
462 if (virtualFile
!= null && virtualFile
.isValid()) {
463 result
.add(virtualFile
);
469 if (result
.size() == 0) {
472 return VfsUtil
.toVirtualFileArray(result
);
477 public static FileChooserDescriptor
createXmlDescriptor() {
478 return new FileChooserDescriptor(true, false, false, false, false, true){
479 public boolean isFileVisible(VirtualFile file
, boolean showHiddenFiles
) {
480 boolean b
= super.isFileVisible(file
, showHiddenFiles
);
481 if (!file
.isDirectory()) {
482 b
&= StdFileTypes
.XML
.equals(FileTypeManager
.getInstance().getFileTypeByFile(file
));
489 private static final class NodeRenderer
extends ColoredTreeCellRenderer
{
490 public void customizeCellRenderer(JTree tree
,
497 final Object userObject
= ((DefaultMutableTreeNode
)value
).getUserObject();
498 if (userObject
instanceof AntNodeDescriptor
) {
499 final AntNodeDescriptor descriptor
= (AntNodeDescriptor
)userObject
;
500 descriptor
.customize(this);
503 append(tree
.convertValueToText(value
, selected
, expanded
, leaf
, row
, hasFocus
), SimpleTextAttributes
.REGULAR_ATTRIBUTES
);
508 private final class AddAction
extends AnAction
{
510 super(AntBundle
.message("add.ant.file.action.name"), AntBundle
.message("add.ant.file.action.description"), ICON_ADD
);
513 public void actionPerformed(AnActionEvent e
) {
518 private final class RemoveAction
extends AnAction
{
519 public RemoveAction() {
520 super(AntBundle
.message("remove.ant.file.action.name"), AntBundle
.message("remove.ant.file.action.description"), ICON_REMOVE
);
523 public void actionPerformed(AnActionEvent e
) {
527 public void update(AnActionEvent event
) {
528 event
.getPresentation().setEnabled(getCurrentBuildFile() != null);
532 private final class RunAction
extends AnAction
{
534 super(AntBundle
.message("run.ant.file.or.target.action.name"), AntBundle
.message("run.ant.file.or.target.action.description"), ICON_RUN
);
537 public void actionPerformed(AnActionEvent e
) {
538 runSelection(e
.getDataContext());
541 public void update(AnActionEvent event
) {
542 final Presentation presentation
= event
.getPresentation();
543 final String place
= event
.getPlace();
544 if (ActionPlaces
.ANT_EXPLORER_TOOLBAR
.equals(place
)) {
545 presentation
.setText(AntBundle
.message("run.ant.file.or.target.action.name"));
548 final TreePath
[] paths
= myTree
.getSelectionPaths();
549 if (paths
!= null && paths
.length
== 1 &&
550 ((DefaultMutableTreeNode
)paths
[0].getLastPathComponent()).getUserObject() instanceof AntBuildFileNodeDescriptor
) {
551 presentation
.setText(AntBundle
.message("run.ant.build.action.name"));
554 if (paths
== null || paths
.length
== 1) {
555 presentation
.setText(AntBundle
.message("run.ant.target.action.name"));
558 presentation
.setText(AntBundle
.message("run.ant.targets.action.name"));
563 presentation
.setEnabled(canRunSelection());
567 private final class ShowAllTargetsAction
extends ToggleAction
{
568 public ShowAllTargetsAction() {
569 super(AntBundle
.message("filter.ant.targets.action.name"), AntBundle
.message("filter.ant.targets.action.description"), ICON_FILTER
);
572 public boolean isSelected(AnActionEvent event
) {
573 final Project project
= myProject
;
574 return project
!= null? AntConfigurationBase
.getInstance(project
).isFilterTargets() : false;
577 public void setSelected(AnActionEvent event
, boolean flag
) {
578 setTargetsFiltered(flag
);
582 private void setTargetsFiltered(boolean value
) {
583 myBuilder
.setTargetsFiltered(value
);
584 AntConfigurationBase
.getInstance(myProject
).setFilterTargets(value
);
587 private final class ExecuteOnEventAction
extends ToggleAction
{
588 private final AntBuildTargetBase myTarget
;
589 private final ExecutionEvent myExecutionEvent
;
591 public ExecuteOnEventAction(final AntBuildTargetBase target
, final ExecutionEvent executionEvent
) {
592 super(executionEvent
.getPresentableName());
594 myExecutionEvent
= executionEvent
;
597 public boolean isSelected(AnActionEvent e
) {
598 return myTarget
.equals(AntConfigurationBase
.getInstance(myProject
).getTargetForEvent(myExecutionEvent
));
601 public void setSelected(AnActionEvent event
, boolean state
) {
602 final AntConfigurationBase antConfiguration
= AntConfigurationBase
.getInstance(myProject
);
604 final AntBuildFileBase buildFile
=
605 (AntBuildFileBase
)((myTarget
instanceof MetaTarget
) ?
((MetaTarget
)myTarget
).getBuildFile() : myTarget
.getModel().getBuildFile());
606 antConfiguration
.setTargetForEvent(buildFile
, myTarget
.getName(), myExecutionEvent
);
609 antConfiguration
.clearTargetForEvent(myExecutionEvent
);
614 public void update(AnActionEvent e
) {
616 final AntBuildFile buildFile
= myTarget
.getModel().getBuildFile();
617 e
.getPresentation().setEnabled(buildFile
!= null && buildFile
.exists());
621 private final class ExecuteBeforeRunAction
extends AnAction
{
622 private final AntBuildTarget myTarget
;
624 public ExecuteBeforeRunAction(final AntBuildTarget target
) {
625 super(AntBundle
.message("executes.before.run.debug.acton.name"));
629 public void actionPerformed(AnActionEvent e
) {
630 final AntExecuteBeforeRunDialog dialog
= new AntExecuteBeforeRunDialog(myProject
, myTarget
);
634 public void update(AnActionEvent e
) {
635 e
.getPresentation().setEnabled(myTarget
.getModel().getBuildFile().exists());
639 private final class CreateMetaTargetAction
extends AnAction
{
641 public CreateMetaTargetAction() {
642 super(AntBundle
.message("ant.create.meta.target.action.name"), AntBundle
.message("ant.create.meta.target.action.description"), null
643 /*IconLoader.getIcon("/actions/execute.png")*/);
646 public void actionPerformed(AnActionEvent e
) {
647 final AntBuildFile buildFile
= getCurrentBuildFile();
648 final String
[] targets
= getTargetNamesFromPaths(myTree
.getSelectionPaths());
649 final ExecuteCompositeTargetEvent event
= new ExecuteCompositeTargetEvent(targets
);
650 final SaveMetaTargetDialog dialog
= new SaveMetaTargetDialog(myTree
, event
, AntConfigurationBase
.getInstance(myProject
), buildFile
);
651 dialog
.setTitle(e
.getPresentation().getText());
659 public void update(AnActionEvent e
) {
660 final TreePath
[] paths
= myTree
.getSelectionPaths();
661 e
.getPresentation().setEnabled(paths
!= null && paths
.length
> 1 && canRunSelection());
665 private final class RemoveMetaTargetsOrBuildFileAction
extends AnAction
{
667 public RemoveMetaTargetsOrBuildFileAction() {
668 super(AntBundle
.message("remove.meta.targets.action.name"), AntBundle
.message("remove.meta.targets.action.description"), null);
669 registerCustomShortcutSet(new CustomShortcutSet(KeyStroke
.getKeyStroke(KeyEvent
.VK_DELETE
, 0)), myTree
);
670 myDisposables
.add(new Disposable() {
671 public void dispose() {
672 RemoveMetaTargetsOrBuildFileAction
.this.unregisterCustomShortcutSet(myTree
);
675 myTree
.registerKeyboardAction(new AbstractAction() {
676 public void actionPerformed(ActionEvent e
) {
679 }, KeyStroke
.getKeyStroke(KeyEvent
.VK_DELETE
, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
);
682 public void actionPerformed(AnActionEvent e
) {
686 private void doAction() {
687 final TreePath
[] paths
= myTree
.getSelectionPaths();
692 // try to remove build file
693 if (paths
.length
== 1) {
694 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)paths
[0].getLastPathComponent();
695 if (node
.getUserObject() instanceof AntBuildFileNodeDescriptor
) {
696 final AntBuildFileNodeDescriptor descriptor
= (AntBuildFileNodeDescriptor
)node
.getUserObject();
697 if (descriptor
.getBuildFile().equals(getCurrentBuildFile())) {
703 // try to remove meta targets
704 final AntBuildTarget
[] targets
= getTargetObjectsFromPaths(paths
);
705 final AntConfigurationBase antConfiguration
= AntConfigurationBase
.getInstance(myProject
);
706 for (final AntBuildTarget buildTarget
: targets
) {
707 if (buildTarget
instanceof MetaTarget
) {
708 for (final ExecutionEvent event
: antConfiguration
.getEventsForTarget(buildTarget
)) {
709 if (event
instanceof ExecuteCompositeTargetEvent
) {
710 antConfiguration
.clearTargetForEvent(event
);
722 public void update(AnActionEvent e
) {
723 final Presentation presentation
= e
.getPresentation();
724 final TreePath
[] paths
= myTree
.getSelectionPaths();
726 presentation
.setEnabled(false);
730 if (paths
.length
== 1) {
731 String text
= AntBundle
.message("remove.meta.target.action.name");
732 boolean enabled
= false;
733 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)paths
[0].getLastPathComponent();
734 if (node
.getUserObject() instanceof AntBuildFileNodeDescriptor
) {
735 final AntBuildFileNodeDescriptor descriptor
= (AntBuildFileNodeDescriptor
)node
.getUserObject();
736 if (descriptor
.getBuildFile().equals(getCurrentBuildFile())) {
737 text
= AntBundle
.message("remove.selected.build.file.action.name");
742 if (node
.getUserObject() instanceof AntTargetNodeDescriptor
) {
743 final AntTargetNodeDescriptor descr
= (AntTargetNodeDescriptor
)node
.getUserObject();
744 final AntBuildTargetBase target
= descr
.getTarget();
745 if (target
instanceof MetaTarget
) {
750 presentation
.setText(text
);
751 presentation
.setEnabled(enabled
);
754 presentation
.setText(AntBundle
.message("remove.selected.meta.targets.action.name"));
755 final AntBuildTarget
[] targets
= getTargetObjectsFromPaths(paths
);
756 boolean enabled
= targets
.length
> 0;
757 for (final AntBuildTarget buildTarget
: targets
) {
758 if (!(buildTarget
instanceof MetaTarget
)) {
763 presentation
.setEnabled(enabled
);
768 private final class AssignShortcutAction
extends AnAction
{
769 private final String myActionId
;
771 public AssignShortcutAction(String actionId
) {
772 super(AntBundle
.message("ant.explorer.assign.shortcut.action.name"));
773 myActionId
= actionId
;
776 public void actionPerformed(AnActionEvent e
) {
777 new EditKeymapsDialog(myProject
, myActionId
).show();
780 public void update(AnActionEvent e
) {
781 e
.getPresentation().setEnabled(myActionId
!= null && ActionManager
.getInstance().getAction(myActionId
) != null);
785 private class KeymapListener
implements KeymapManagerListener
, Keymap
.Listener
{
786 private Keymap myCurrentKeymap
= null;
788 public KeymapListener() {
789 final KeymapManagerEx keymapManager
= KeymapManagerEx
.getInstanceEx();
790 final Keymap activeKeymap
= keymapManager
.getActiveKeymap();
791 listenTo(activeKeymap
);
792 keymapManager
.addKeymapManagerListener(this);
795 public void activeKeymapChanged(Keymap keymap
) {
800 private void listenTo(Keymap keymap
) {
801 if (myCurrentKeymap
!= null) {
802 myCurrentKeymap
.removeShortcutChangeListener(this);
804 myCurrentKeymap
= keymap
;
805 if (myCurrentKeymap
!= null) {
806 myCurrentKeymap
.addShortcutChangeListener(this);
810 private void updateTree() {
811 myBuilder
.updateFromRoot();
814 public void onShortcutChanged(String actionId
) {
818 public void stopListen() {
820 KeymapManagerEx
.getInstanceEx().removeKeymapManagerListener(this);