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
.ide
.CommonActionsManager
;
19 import com
.intellij
.ide
.DataManager
;
20 import com
.intellij
.ide
.TreeExpander
;
21 import com
.intellij
.ide
.actions
.ContextHelpAction
;
22 import com
.intellij
.lang
.ant
.AntBundle
;
23 import com
.intellij
.lang
.ant
.config
.*;
24 import com
.intellij
.lang
.ant
.config
.actions
.AntBuildFilePropertiesAction
;
25 import com
.intellij
.lang
.ant
.config
.actions
.RemoveBuildFileAction
;
26 import com
.intellij
.lang
.ant
.config
.execution
.ExecutionHandler
;
27 import com
.intellij
.lang
.ant
.config
.impl
.*;
28 import com
.intellij
.lang
.ant
.config
.impl
.configuration
.BuildFilePropertiesPanel
;
29 import com
.intellij
.openapi
.Disposable
;
30 import com
.intellij
.openapi
.actionSystem
.*;
31 import com
.intellij
.openapi
.application
.ApplicationManager
;
32 import com
.intellij
.openapi
.diagnostic
.Logger
;
33 import com
.intellij
.openapi
.fileChooser
.FileChooser
;
34 import com
.intellij
.openapi
.fileChooser
.FileChooserDescriptor
;
35 import com
.intellij
.openapi
.fileEditor
.OpenFileDescriptor
;
36 import com
.intellij
.openapi
.fileTypes
.FileTypeManager
;
37 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
38 import com
.intellij
.openapi
.keymap
.Keymap
;
39 import com
.intellij
.openapi
.keymap
.KeymapManagerListener
;
40 import com
.intellij
.openapi
.keymap
.ex
.KeymapManagerEx
;
41 import com
.intellij
.openapi
.keymap
.impl
.ui
.EditKeymapsDialog
;
42 import com
.intellij
.openapi
.project
.Project
;
43 import com
.intellij
.openapi
.ui
.Messages
;
44 import com
.intellij
.openapi
.ui
.SimpleToolWindowPanel
;
45 import com
.intellij
.openapi
.util
.Disposer
;
46 import com
.intellij
.openapi
.util
.IconLoader
;
47 import com
.intellij
.openapi
.vfs
.VfsUtil
;
48 import com
.intellij
.openapi
.vfs
.VirtualFile
;
49 import com
.intellij
.ui
.*;
50 import com
.intellij
.ui
.treeStructure
.Tree
;
51 import com
.intellij
.util
.ArrayUtil
;
52 import com
.intellij
.util
.StringBuilderSpinAllocator
;
53 import com
.intellij
.util
.ui
.tree
.TreeUtil
;
54 import org
.jetbrains
.annotations
.NonNls
;
55 import org
.jetbrains
.annotations
.Nullable
;
58 import javax
.swing
.tree
.DefaultMutableTreeNode
;
59 import javax
.swing
.tree
.DefaultTreeModel
;
60 import javax
.swing
.tree
.TreePath
;
62 import java
.awt
.event
.ActionEvent
;
63 import java
.awt
.event
.KeyEvent
;
64 import java
.awt
.event
.MouseAdapter
;
65 import java
.awt
.event
.MouseEvent
;
66 import java
.util
.ArrayList
;
67 import java
.util
.Arrays
;
68 import java
.util
.List
;
70 public class AntExplorer
extends SimpleToolWindowPanel
implements DataProvider
{
72 private static final Logger LOG
= Logger
.getInstance("#com.intellij.lang.ant.config.explorer.AntExplorer");
74 private Project myProject
;
75 private AntExplorerTreeBuilder myBuilder
;
77 private KeymapListener myKeymapListener
;
78 private final List
<Disposable
> myDisposables
= new ArrayList
<Disposable
>();
79 private final AntBuildFilePropertiesAction myAntBuildFilePropertiesAction
;
81 private final TreeExpander myTreeExpander
= new TreeExpander() {
82 public void expandAll() {
83 myBuilder
.expandAll();
86 public boolean canExpand() {
87 return AntConfiguration
.getInstance(myProject
).getBuildFiles().length
!= 0;
90 public void collapseAll() {
91 myBuilder
.collapseAll();
94 public boolean canCollapse() {
98 private static final Icon ICON_RUN
= IconLoader
.getIcon("/actions/execute.png");
99 private static final Icon ICON_REMOVE
= IconLoader
.getIcon("/general/remove.png");
100 private static final Icon ICON_ADD
= IconLoader
.getIcon("/general/add.png");
101 private static final Icon ICON_FILTER
= IconLoader
.getIcon("/ant/filter.png");
103 public AntExplorer(final Project project
) {
106 final DefaultTreeModel model
= new DefaultTreeModel(new DefaultMutableTreeNode());
107 myTree
= new Tree(model
);
108 myTree
.setRootVisible(false);
109 myTree
.setShowsRootHandles(true);
110 myTree
.setCellRenderer(new NodeRenderer());
111 myBuilder
= new AntExplorerTreeBuilder(project
, myTree
, model
);
112 myBuilder
.setTargetsFiltered(AntConfigurationBase
.getInstance(project
).isFilterTargets());
113 TreeToolTipHandler
.install(myTree
);
114 TreeUtil
.installActions(myTree
);
115 new TreeSpeedSearch(myTree
);
116 myTree
.addMouseListener(new PopupHandler() {
117 public void invokePopup(final Component comp
, final int x
, final int y
) {
118 popupInvoked(comp
, x
, y
);
121 myTree
.addMouseListener(new MouseAdapter() {
122 public void mouseClicked(MouseEvent e
) {
123 if (e
.getClickCount() == 2) {
124 final TreePath path
= myTree
.getPathForLocation(e
.getX(), e
.getY());
126 runSelection(DataManager
.getInstance().getDataContext(myTree
));
131 myTree
.registerKeyboardAction(new AbstractAction() {
132 public void actionPerformed(ActionEvent e
) {
133 runSelection(DataManager
.getInstance().getDataContext(myTree
));
135 }, KeyStroke
.getKeyStroke(KeyEvent
.VK_ENTER
, 0), WHEN_FOCUSED
);
137 myTree
.setLineStyleAngled();
138 myAntBuildFilePropertiesAction
= new AntBuildFilePropertiesAction(this);
139 setToolbar(createToolbarPanel());
140 setContent(new JScrollPane(myTree
));
141 ToolTipManager
.sharedInstance().registerComponent(myTree
);
142 myKeymapListener
= new KeymapListener();
145 public void dispose() {
146 for (final Disposable disposable
: myDisposables
) {
147 disposable
.dispose();
149 myDisposables
.clear();
151 if (myKeymapListener
!= null) {
152 myKeymapListener
.stopListen();
153 myKeymapListener
= null;
156 LOG
.error("already disposed");
158 if (myBuilder
!= null) {
159 Disposer
.dispose(myBuilder
);
162 if (myTree
!= null) {
163 ToolTipManager
.sharedInstance().unregisterComponent(myTree
);
164 final KeyStroke
[] strokes
= myTree
.getRegisteredKeyStrokes();
165 for (KeyStroke keyStroke
: strokes
) {
166 myTree
.unregisterKeyboardAction(keyStroke
);
172 private JPanel
createToolbarPanel() {
173 final DefaultActionGroup group
= new DefaultActionGroup();
174 group
.add(new AddAction());
175 group
.add(new RemoveAction());
176 group
.add(new RunAction());
177 group
.add(new ShowAllTargetsAction());
178 AnAction action
= CommonActionsManager
.getInstance().createExpandAllAction(myTreeExpander
, this);
179 action
.getTemplatePresentation().setDescription(AntBundle
.message("ant.explorer.expand.all.nodes.action.description"));
181 action
= CommonActionsManager
.getInstance().createCollapseAllAction(myTreeExpander
, this);
182 action
.getTemplatePresentation().setDescription(AntBundle
.message("ant.explorer.collapse.all.nodes.action.description"));
184 group
.add(myAntBuildFilePropertiesAction
);
185 group
.add(new ContextHelpAction(HelpID
.ANT
));
187 final ActionToolbar actionToolBar
= ActionManager
.getInstance().createActionToolbar(ActionPlaces
.ANT_EXPLORER_TOOLBAR
, group
, true);
188 final JPanel buttonsPanel
= new JPanel(new BorderLayout());
189 buttonsPanel
.add(actionToolBar
.getComponent(), BorderLayout
.CENTER
);
193 private void addBuildFile() {
194 final FileChooserDescriptor descriptor
= createXmlDescriptor();
195 descriptor
.setTitle(AntBundle
.message("select.ant.build.file.dialog.title"));
196 descriptor
.setDescription(AntBundle
.message("select.ant.build.file.dialog.description"));
197 final VirtualFile
[] files
= FileChooser
.chooseFiles(myProject
, descriptor
);
198 if (files
.length
== 0) {
201 ApplicationManager
.getApplication().invokeLater(new Runnable() {
203 final AntConfiguration antConfiguration
= AntConfiguration
.getInstance(myProject
);
204 final ArrayList
<VirtualFile
> ignoredFiles
= new ArrayList
<VirtualFile
>();
205 for (VirtualFile file
: files
) {
207 antConfiguration
.addBuildFile(file
);
209 catch (AntNoFileException e
) {
210 ignoredFiles
.add(e
.getFile());
213 if (ignoredFiles
.size() != 0) {
215 final StringBuilder message
= StringBuilderSpinAllocator
.alloc();
217 String separator
= "";
218 for (final VirtualFile virtualFile
: ignoredFiles
) {
219 message
.append(separator
);
220 message
.append(virtualFile
.getPresentableUrl());
223 messageText
= message
.toString();
226 StringBuilderSpinAllocator
.dispose(message
);
228 Messages
.showWarningDialog(myProject
, messageText
, AntBundle
.message("cannot.add.ant.files.dialog.title"));
234 public void removeBuildFile() {
235 final AntBuildFile buildFile
= getCurrentBuildFile();
236 if (buildFile
== null) {
239 final String fileName
= buildFile
.getPresentableUrl();
240 final int result
= Messages
.showYesNoDialog(myProject
, AntBundle
.message("remove.the.reference.to.file.confirmation.text", fileName
),
241 AntBundle
.message("confirm.remove.dialog.title"), Messages
.getQuestionIcon());
245 AntConfiguration
.getInstance(myProject
).removeBuildFile(buildFile
);
248 public void setBuildFileProperties(DataContext dataContext
) {
249 final AntBuildFile buildFile
= getCurrentBuildFile();
250 if (BuildFilePropertiesPanel
.editBuildFile(getCurrentBuildFile())) {
251 final AntConfiguration antConfiguration
= AntConfiguration
.getInstance(myProject
);
252 antConfiguration
.updateBuildFile(buildFile
);
258 private void runSelection(final DataContext dataContext
) {
259 if (!canRunSelection()) {
262 final AntBuildFileBase buildFile
= getCurrentBuildFile();
263 final TreePath
[] paths
= myTree
.getSelectionPaths();
264 final String
[] targets
= getTargetNamesFromPaths(paths
);
265 ExecutionHandler
.runBuild(buildFile
, targets
, null, dataContext
, AntBuildListener
.NULL
);
268 private boolean canRunSelection() {
269 if (myTree
== null) {
272 final TreePath
[] paths
= myTree
.getSelectionPaths();
276 final AntBuildFile buildFile
= getCurrentBuildFile();
277 if (buildFile
== null || !buildFile
.exists()) {
280 for (final TreePath path
: paths
) {
281 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
282 final Object userObject
= node
.getUserObject();
283 final AntBuildFileNodeDescriptor buildFileNodeDescriptor
;
284 if (userObject
instanceof AntTargetNodeDescriptor
) {
285 buildFileNodeDescriptor
= (AntBuildFileNodeDescriptor
)((DefaultMutableTreeNode
)node
.getParent()).getUserObject();
287 else if (userObject
instanceof AntBuildFileNodeDescriptor
){
288 buildFileNodeDescriptor
= (AntBuildFileNodeDescriptor
)userObject
;
291 buildFileNodeDescriptor
= null;
293 if (buildFileNodeDescriptor
== null || buildFileNodeDescriptor
.getBuildFile() != buildFile
) {
300 private static String
[] getTargetNamesFromPaths(TreePath
[] paths
) {
301 final List
<String
> targets
= new ArrayList
<String
>();
302 for (final TreePath path
: paths
) {
303 final Object userObject
= ((DefaultMutableTreeNode
)path
.getLastPathComponent()).getUserObject();
304 if (!(userObject
instanceof AntTargetNodeDescriptor
)) {
307 final AntBuildTarget target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
308 if (target
instanceof MetaTarget
) {
309 targets
.addAll(Arrays
.asList(((MetaTarget
)target
).getTargetNames()));
312 targets
.add(target
.getName());
315 return ArrayUtil
.toStringArray(targets
);
318 private static AntBuildTarget
[] getTargetObjectsFromPaths(TreePath
[] paths
) {
319 final List
<AntBuildTargetBase
> targets
= new ArrayList
<AntBuildTargetBase
>();
320 for (final TreePath path
: paths
) {
321 final Object userObject
= ((DefaultMutableTreeNode
)path
.getLastPathComponent()).getUserObject();
322 if (!(userObject
instanceof AntTargetNodeDescriptor
)) {
325 final AntBuildTargetBase target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
329 return targets
.toArray(new AntBuildTargetBase
[targets
.size()]);
332 public boolean isBuildFileSelected() {
333 if( myProject
== null) return false;
334 final AntBuildFileBase file
= getCurrentBuildFile();
335 return file
!= null && file
.exists();
339 private AntBuildFileBase
getCurrentBuildFile() {
340 final AntBuildFileNodeDescriptor descriptor
= getCurrentBuildFileNodeDescriptor();
341 return (AntBuildFileBase
)((descriptor
== null) ?
null : descriptor
.getBuildFile());
345 private AntBuildFileNodeDescriptor
getCurrentBuildFileNodeDescriptor() {
346 if (myTree
== null) {
349 final TreePath path
= myTree
.getSelectionPath();
353 DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
354 while (node
!= null) {
355 final Object userObject
= node
.getUserObject();
356 if (userObject
instanceof AntBuildFileNodeDescriptor
) {
357 return (AntBuildFileNodeDescriptor
)userObject
;
359 node
= (DefaultMutableTreeNode
)node
.getParent();
364 private void popupInvoked(final Component comp
, final int x
, final int y
) {
365 Object userObject
= null;
366 final TreePath path
= myTree
.getSelectionPath();
368 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
370 userObject
= node
.getUserObject();
373 final DefaultActionGroup group
= new DefaultActionGroup();
374 group
.add(new RunAction());
375 group
.add(new CreateMetaTargetAction());
376 group
.add(new RemoveMetaTargetsOrBuildFileAction());
377 group
.add(ActionManager
.getInstance().getAction(IdeActions
.ACTION_EDIT_SOURCE
));
378 if (userObject
instanceof AntBuildFileNodeDescriptor
) {
379 group
.add(new RemoveBuildFileAction(this));
381 if (userObject
instanceof AntTargetNodeDescriptor
) {
382 final AntBuildTargetBase target
= ((AntTargetNodeDescriptor
)userObject
).getTarget();
383 final DefaultActionGroup executeOnGroup
=
384 new DefaultActionGroup(AntBundle
.message("ant.explorer.execute.on.action.group.name"), true);
385 executeOnGroup
.add(new ExecuteOnEventAction(target
, ExecuteBeforeCompilationEvent
.getInstance()));
386 executeOnGroup
.add(new ExecuteOnEventAction(target
, ExecuteAfterCompilationEvent
.getInstance()));
387 executeOnGroup
.addSeparator();
388 executeOnGroup
.add(new ExecuteBeforeRunAction(target
, getCurrentBuildFile()));
389 group
.add(executeOnGroup
);
390 group
.add(new AssignShortcutAction(target
.getActionId()));
392 group
.add(myAntBuildFilePropertiesAction
);
393 final ActionPopupMenu popupMenu
= ActionManager
.getInstance().createActionPopupMenu(ActionPlaces
.ANT_EXPLORER_POPUP
, group
);
394 popupMenu
.getComponent().show(comp
, x
, y
);
398 public Object
getData(@NonNls String dataId
) {
399 if (PlatformDataKeys
.NAVIGATABLE
.is(dataId
)) {
400 final AntBuildFile buildFile
= getCurrentBuildFile();
401 if (buildFile
== null) {
404 final VirtualFile file
= buildFile
.getVirtualFile();
408 final TreePath treePath
= myTree
.getLeadSelectionPath();
409 if (treePath
== null) {
412 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)treePath
.getLastPathComponent();
416 if (node
.getUserObject() instanceof AntTargetNodeDescriptor
) {
417 final AntTargetNodeDescriptor targetNodeDescriptor
= (AntTargetNodeDescriptor
)node
.getUserObject();
418 final AntBuildTargetBase buildTarget
= targetNodeDescriptor
.getTarget();
419 final OpenFileDescriptor descriptor
= buildTarget
.getOpenFileDescriptor();
420 if (descriptor
!= null) {
421 final VirtualFile descriptorFile
= descriptor
.getFile();
422 if (descriptorFile
.isValid()) {
427 if (file
.isValid()) {
428 return new OpenFileDescriptor(myProject
, file
);
431 else if (PlatformDataKeys
.HELP_ID
.is(dataId
)) {
434 else if (PlatformDataKeys
.TREE_EXPANDER
.is(dataId
)) {
435 return myTreeExpander
;
437 else if (PlatformDataKeys
.VIRTUAL_FILE_ARRAY
.is(dataId
)) {
438 final TreePath
[] paths
= myTree
.getSelectionPaths();
442 final ArrayList
<VirtualFile
> result
= new ArrayList
<VirtualFile
>();
443 for (final TreePath path
: paths
) {
444 for (DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)path
.getLastPathComponent();
446 node
= (DefaultMutableTreeNode
)node
.getParent()) {
447 final Object userObject
= node
.getUserObject();
448 if (!(userObject
instanceof AntBuildFileNodeDescriptor
)) {
451 final AntBuildFile buildFile
= ((AntBuildFileNodeDescriptor
)userObject
).getBuildFile();
452 if (buildFile
!= null) {
453 final VirtualFile virtualFile
= buildFile
.getVirtualFile();
454 if (virtualFile
!= null && virtualFile
.isValid()) {
455 result
.add(virtualFile
);
461 if (result
.size() == 0) {
464 return VfsUtil
.toVirtualFileArray(result
);
469 public static FileChooserDescriptor
createXmlDescriptor() {
470 return new FileChooserDescriptor(true, false, false, false, false, true){
471 public boolean isFileVisible(VirtualFile file
, boolean showHiddenFiles
) {
472 boolean b
= super.isFileVisible(file
, showHiddenFiles
);
473 if (!file
.isDirectory()) {
474 b
&= StdFileTypes
.XML
.equals(FileTypeManager
.getInstance().getFileTypeByFile(file
));
481 private static final class NodeRenderer
extends ColoredTreeCellRenderer
{
482 public void customizeCellRenderer(JTree tree
,
489 final Object userObject
= ((DefaultMutableTreeNode
)value
).getUserObject();
490 if (userObject
instanceof AntNodeDescriptor
) {
491 final AntNodeDescriptor descriptor
= (AntNodeDescriptor
)userObject
;
492 descriptor
.customize(this);
495 append(tree
.convertValueToText(value
, selected
, expanded
, leaf
, row
, hasFocus
), SimpleTextAttributes
.REGULAR_ATTRIBUTES
);
500 private final class AddAction
extends AnAction
{
502 super(AntBundle
.message("add.ant.file.action.name"), AntBundle
.message("add.ant.file.action.description"), ICON_ADD
);
505 public void actionPerformed(AnActionEvent e
) {
510 private final class RemoveAction
extends AnAction
{
511 public RemoveAction() {
512 super(AntBundle
.message("remove.ant.file.action.name"), AntBundle
.message("remove.ant.file.action.description"), ICON_REMOVE
);
515 public void actionPerformed(AnActionEvent e
) {
519 public void update(AnActionEvent event
) {
520 event
.getPresentation().setEnabled(getCurrentBuildFile() != null);
524 private final class RunAction
extends AnAction
{
526 super(AntBundle
.message("run.ant.file.or.target.action.name"), AntBundle
.message("run.ant.file.or.target.action.description"), ICON_RUN
);
529 public void actionPerformed(AnActionEvent e
) {
530 runSelection(e
.getDataContext());
533 public void update(AnActionEvent event
) {
534 final Presentation presentation
= event
.getPresentation();
535 final String place
= event
.getPlace();
536 if (ActionPlaces
.ANT_EXPLORER_TOOLBAR
.equals(place
)) {
537 presentation
.setText(AntBundle
.message("run.ant.file.or.target.action.name"));
540 final TreePath
[] paths
= myTree
.getSelectionPaths();
541 if (paths
!= null && paths
.length
== 1 &&
542 ((DefaultMutableTreeNode
)paths
[0].getLastPathComponent()).getUserObject() instanceof AntBuildFileNodeDescriptor
) {
543 presentation
.setText(AntBundle
.message("run.ant.build.action.name"));
546 if (paths
== null || paths
.length
== 1) {
547 presentation
.setText(AntBundle
.message("run.ant.target.action.name"));
550 presentation
.setText(AntBundle
.message("run.ant.targets.action.name"));
555 presentation
.setEnabled(canRunSelection());
559 private final class ShowAllTargetsAction
extends ToggleAction
{
560 public ShowAllTargetsAction() {
561 super(AntBundle
.message("filter.ant.targets.action.name"), AntBundle
.message("filter.ant.targets.action.description"), ICON_FILTER
);
564 public boolean isSelected(AnActionEvent event
) {
565 final Project project
= myProject
;
566 return project
!= null? AntConfigurationBase
.getInstance(project
).isFilterTargets() : false;
569 public void setSelected(AnActionEvent event
, boolean flag
) {
570 setTargetsFiltered(flag
);
574 private void setTargetsFiltered(boolean value
) {
575 myBuilder
.setTargetsFiltered(value
);
576 AntConfigurationBase
.getInstance(myProject
).setFilterTargets(value
);
579 private final class ExecuteOnEventAction
extends ToggleAction
{
580 private final AntBuildTargetBase myTarget
;
581 private final ExecutionEvent myExecutionEvent
;
583 public ExecuteOnEventAction(final AntBuildTargetBase target
, final ExecutionEvent executionEvent
) {
584 super(executionEvent
.getPresentableName());
586 myExecutionEvent
= executionEvent
;
589 public boolean isSelected(AnActionEvent e
) {
590 return myTarget
.equals(AntConfigurationBase
.getInstance(myProject
).getTargetForEvent(myExecutionEvent
));
593 public void setSelected(AnActionEvent event
, boolean state
) {
594 final AntConfigurationBase antConfiguration
= AntConfigurationBase
.getInstance(myProject
);
596 final AntBuildFileBase buildFile
=
597 (AntBuildFileBase
)((myTarget
instanceof MetaTarget
) ?
((MetaTarget
)myTarget
).getBuildFile() : myTarget
.getModel().getBuildFile());
598 antConfiguration
.setTargetForEvent(buildFile
, myTarget
.getName(), myExecutionEvent
);
601 antConfiguration
.clearTargetForEvent(myExecutionEvent
);
606 public void update(AnActionEvent e
) {
608 final AntBuildFile buildFile
= myTarget
.getModel().getBuildFile();
609 e
.getPresentation().setEnabled(buildFile
!= null && buildFile
.exists());
613 private final class ExecuteBeforeRunAction
extends AnAction
{
614 private final AntBuildTarget myTarget
;
615 private final AntBuildFile myBuildFile
;
617 public ExecuteBeforeRunAction(final AntBuildTarget target
, final AntBuildFile buildFile
) {
618 super(AntBundle
.message("executes.before.run.debug.acton.name"));
620 myBuildFile
= buildFile
;
623 public void actionPerformed(AnActionEvent e
) {
624 final ExecuteOnRunDialog dialog
= new ExecuteOnRunDialog(myProject
, myTarget
, myBuildFile
);
629 public void update(AnActionEvent e
) {
630 e
.getPresentation().setEnabled(myBuildFile
.exists());
634 private final class CreateMetaTargetAction
extends AnAction
{
636 public CreateMetaTargetAction() {
637 super(AntBundle
.message("ant.create.meta.target.action.name"), AntBundle
.message("ant.create.meta.target.action.description"), null
638 /*IconLoader.getIcon("/actions/execute.png")*/);
641 public void actionPerformed(AnActionEvent e
) {
642 final AntBuildFile buildFile
= getCurrentBuildFile();
643 final String
[] targets
= getTargetNamesFromPaths(myTree
.getSelectionPaths());
644 final ExecuteCompositeTargetEvent event
= new ExecuteCompositeTargetEvent(targets
);
645 final SaveMetaTargetDialog dialog
= new SaveMetaTargetDialog(myTree
, event
, AntConfigurationBase
.getInstance(myProject
), buildFile
);
646 dialog
.setTitle(e
.getPresentation().getText());
654 public void update(AnActionEvent e
) {
655 final TreePath
[] paths
= myTree
.getSelectionPaths();
656 e
.getPresentation().setEnabled(paths
!= null && paths
.length
> 1 && canRunSelection());
660 private final class RemoveMetaTargetsOrBuildFileAction
extends AnAction
{
662 public RemoveMetaTargetsOrBuildFileAction() {
663 super(AntBundle
.message("remove.meta.targets.action.name"), AntBundle
.message("remove.meta.targets.action.description"), null);
664 registerCustomShortcutSet(new CustomShortcutSet(KeyStroke
.getKeyStroke(KeyEvent
.VK_DELETE
, 0)), myTree
);
665 myDisposables
.add(new Disposable() {
666 public void dispose() {
667 RemoveMetaTargetsOrBuildFileAction
.this.unregisterCustomShortcutSet(myTree
);
670 myTree
.registerKeyboardAction(new AbstractAction() {
671 public void actionPerformed(ActionEvent e
) {
674 }, KeyStroke
.getKeyStroke(KeyEvent
.VK_DELETE
, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
);
677 public void actionPerformed(AnActionEvent e
) {
681 private void doAction() {
682 final TreePath
[] paths
= myTree
.getSelectionPaths();
687 // try to remove build file
688 if (paths
.length
== 1) {
689 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)paths
[0].getLastPathComponent();
690 if (node
.getUserObject() instanceof AntBuildFileNodeDescriptor
) {
691 final AntBuildFileNodeDescriptor descriptor
= (AntBuildFileNodeDescriptor
)node
.getUserObject();
692 if (descriptor
.getBuildFile().equals(getCurrentBuildFile())) {
698 // try to remove meta targets
699 final AntBuildTarget
[] targets
= getTargetObjectsFromPaths(paths
);
700 final AntConfigurationBase antConfiguration
= AntConfigurationBase
.getInstance(myProject
);
701 for (final AntBuildTarget buildTarget
: targets
) {
702 if (buildTarget
instanceof MetaTarget
) {
703 for (final ExecutionEvent event
: antConfiguration
.getEventsForTarget(buildTarget
)) {
704 if (event
instanceof ExecuteCompositeTargetEvent
) {
705 antConfiguration
.clearTargetForEvent(event
);
717 public void update(AnActionEvent e
) {
718 final Presentation presentation
= e
.getPresentation();
719 final TreePath
[] paths
= myTree
.getSelectionPaths();
721 presentation
.setEnabled(false);
725 if (paths
.length
== 1) {
726 String text
= AntBundle
.message("remove.meta.target.action.name");
727 boolean enabled
= false;
728 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
)paths
[0].getLastPathComponent();
729 if (node
.getUserObject() instanceof AntBuildFileNodeDescriptor
) {
730 final AntBuildFileNodeDescriptor descriptor
= (AntBuildFileNodeDescriptor
)node
.getUserObject();
731 if (descriptor
.getBuildFile().equals(getCurrentBuildFile())) {
732 text
= AntBundle
.message("remove.selected.build.file.action.name");
737 if (node
.getUserObject() instanceof AntTargetNodeDescriptor
) {
738 final AntTargetNodeDescriptor descr
= (AntTargetNodeDescriptor
)node
.getUserObject();
739 final AntBuildTargetBase target
= descr
.getTarget();
740 if (target
instanceof MetaTarget
) {
745 presentation
.setText(text
);
746 presentation
.setEnabled(enabled
);
749 presentation
.setText(AntBundle
.message("remove.selected.meta.targets.action.name"));
750 final AntBuildTarget
[] targets
= getTargetObjectsFromPaths(paths
);
751 boolean enabled
= targets
.length
> 0;
752 for (final AntBuildTarget buildTarget
: targets
) {
753 if (!(buildTarget
instanceof MetaTarget
)) {
758 presentation
.setEnabled(enabled
);
763 private final class AssignShortcutAction
extends AnAction
{
764 private final String myActionId
;
766 public AssignShortcutAction(String actionId
) {
767 super(AntBundle
.message("ant.explorer.assign.shortcut.action.name"));
768 myActionId
= actionId
;
771 public void actionPerformed(AnActionEvent e
) {
772 new EditKeymapsDialog(myProject
, myActionId
).show();
775 public void update(AnActionEvent e
) {
776 e
.getPresentation().setEnabled(myActionId
!= null && ActionManager
.getInstance().getAction(myActionId
) != null);
780 private class KeymapListener
implements KeymapManagerListener
, Keymap
.Listener
{
781 private Keymap myCurrentKeymap
= null;
783 public KeymapListener() {
784 final KeymapManagerEx keymapManager
= KeymapManagerEx
.getInstanceEx();
785 final Keymap activeKeymap
= keymapManager
.getActiveKeymap();
786 listenTo(activeKeymap
);
787 keymapManager
.addKeymapManagerListener(this);
790 public void activeKeymapChanged(Keymap keymap
) {
795 private void listenTo(Keymap keymap
) {
796 if (myCurrentKeymap
!= null) {
797 myCurrentKeymap
.removeShortcutChangeListener(this);
799 myCurrentKeymap
= keymap
;
800 if (myCurrentKeymap
!= null) {
801 myCurrentKeymap
.addShortcutChangeListener(this);
805 private void updateTree() {
806 myBuilder
.updateFromRoot();
809 public void onShortcutChanged(String actionId
) {
813 public void stopListen() {
815 KeymapManagerEx
.getInstanceEx().removeKeymapManagerListener(this);