jdk step usability
[fedora-idea.git] / source / com / intellij / openapi / roots / ui / configuration / projectRoot / ProjectRootConfigurable.java
blob618013f63d859b21bda08a1847d63f746c098e59
1 /*
2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
3 */
5 package com.intellij.openapi.roots.ui.configuration.projectRoot;
7 import com.intellij.CommonBundle;
8 import com.intellij.find.FindBundle;
9 import com.intellij.ide.projectView.impl.ModuleGroup;
10 import com.intellij.ide.projectView.impl.ModuleGroupUtil;
11 import com.intellij.javaee.serverInstances.ApplicationServersManager;
12 import com.intellij.openapi.actionSystem.*;
13 import com.intellij.openapi.actionSystem.ex.DataConstantsEx;
14 import com.intellij.openapi.application.ApplicationManager;
15 import com.intellij.openapi.components.ProjectComponent;
16 import com.intellij.openapi.module.Module;
17 import com.intellij.openapi.module.ModuleManager;
18 import com.intellij.openapi.options.ConfigurationException;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.project.ProjectBundle;
21 import com.intellij.openapi.projectRoots.ProjectJdk;
22 import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
23 import com.intellij.openapi.roots.*;
24 import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
25 import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil;
26 import com.intellij.openapi.roots.libraries.Library;
27 import com.intellij.openapi.roots.libraries.LibraryTable;
28 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
29 import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider;
30 import com.intellij.openapi.roots.ui.configuration.ModuleEditor;
31 import com.intellij.openapi.roots.ui.configuration.ModulesConfigurable;
32 import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
33 import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor;
34 import com.intellij.openapi.ui.MasterDetailsComponent;
35 import com.intellij.openapi.ui.Messages;
36 import com.intellij.openapi.ui.NamedConfigurable;
37 import com.intellij.openapi.ui.popup.JBPopupFactory;
38 import com.intellij.openapi.ui.popup.ListPopup;
39 import com.intellij.openapi.ui.popup.PopupStep;
40 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
41 import com.intellij.openapi.util.Comparing;
42 import com.intellij.openapi.util.Condition;
43 import com.intellij.openapi.util.Disposer;
44 import com.intellij.openapi.util.IconLoader;
45 import com.intellij.openapi.util.io.FileUtil;
46 import com.intellij.ui.TreeSpeedSearch;
47 import com.intellij.ui.awt.RelativePoint;
48 import com.intellij.ui.popup.list.ListPopupImpl;
49 import com.intellij.util.Consumer;
50 import com.intellij.util.Function;
51 import com.intellij.util.Icons;
52 import com.intellij.util.containers.Convertor;
53 import com.intellij.util.ui.tree.TreeUtil;
54 import org.jetbrains.annotations.NonNls;
55 import org.jetbrains.annotations.NotNull;
56 import org.jetbrains.annotations.Nullable;
58 import javax.swing.*;
59 import javax.swing.tree.DefaultMutableTreeNode;
60 import javax.swing.tree.DefaultTreeModel;
61 import javax.swing.tree.TreeNode;
62 import javax.swing.tree.TreePath;
63 import java.awt.*;
64 import java.util.*;
65 import java.util.List;
67 /**
68 * User: anna
69 * Date: 02-Jun-2006
71 public class ProjectRootConfigurable extends MasterDetailsComponent implements ProjectComponent {
72 private static final Icon ICON = IconLoader.getIcon("/modules/modules.png");
74 private MyNode myJdksNode;
76 private MyNode myGlobalLibrariesNode;
77 private LibrariesModifiableModel myGlobalLibrariesProvider;
79 private LibrariesModifiableModel myProjectLibrariesProvider;
81 private Map<Module, LibrariesModifiableModel> myModule2LibrariesMap = new HashMap<Module, LibrariesModifiableModel>();
83 private MyNode myProjectNode;
84 private MyNode myProjectLibrariesNode;
85 private Project myProject;
87 private ModuleManager myModuleManager;
88 private ModulesConfigurator myModulesConfigurator;
89 private ModulesConfigurable myModulesConfigurable;
90 private ProjectJdksModel myJdksTreeModel = new ProjectJdksModel(this);
92 private MyNode myApplicationServerLibrariesNode;
93 private LibrariesModifiableModel myApplicationServerLibrariesProvider;
95 public ProjectRootConfigurable(Project project, ModuleManager manager) {
96 myProject = project;
97 myModuleManager = manager;
98 addItemsChangeListener(new ItemsChangeListener() {
99 public void itemChanged(@Nullable Object deletedItem) {
100 if (deletedItem instanceof Library) {
101 final Library library = (Library)deletedItem;
102 final MyNode node = findNodeByObject(myRoot, library);
103 if (node != null) {
104 final TreeNode parent = node.getParent();
105 node.removeFromParent();
106 ((DefaultTreeModel)myTree.getModel()).reload(parent);
111 public void itemsExternallyChanged() {
112 //do nothing
115 initTree();
119 protected void initTree() {
120 super.initTree();
121 new TreeSpeedSearch(myTree, new Convertor<TreePath, String>() {
122 public String convert(final TreePath treePath) {
123 return ((MyNode)treePath.getLastPathComponent()).getDisplayName();
129 protected ArrayList<AnAction> getAdditionalActions() {
130 final ArrayList<AnAction> result = new ArrayList<AnAction>();
131 result.add(new MyRenameAction() {
132 @Nullable
133 protected String getRenameTitleSuffix() {
134 final Object selectedObject = getSelectedObject();
135 if (selectedObject instanceof Module){
136 return ProjectBundle.message("add.new.module.text");
137 } else if (selectedObject instanceof Library){
138 return ProjectBundle.message("add.new.library.text");
139 } else if (selectedObject instanceof ProjectJdk){
140 return ProjectBundle.message("add.new.jdk.text");
142 return null;
145 final AnAction findUsages = new AnAction(ProjectBundle.message("find.usages.action.text")) {
146 public void update(AnActionEvent e) {
147 final Presentation presentation = e.getPresentation();
148 final TreePath selectionPath = myTree.getSelectionPath();
149 if (selectionPath != null){
150 final MyNode node = (MyNode)selectionPath.getLastPathComponent();
151 presentation.setEnabled(!node.isDisplayInBold());
152 } else {
153 presentation.setEnabled(false);
157 public void actionPerformed(AnActionEvent e) {
158 showDependencies();
161 findUsages.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES).getShortcutSet(), myTree);
162 result.add(findUsages);
163 result.add(ActionManager.getInstance().getAction(IdeActions.GROUP_MOVE_MODULE_TO_GROUP));
164 return result;
167 protected void reloadTree() {
169 myRoot.removeAllChildren();
171 createProjectNodes();
173 createProjectJdks();
175 myGlobalLibrariesNode = createLibrariesNode(LibraryTablesRegistrar.getInstance().getLibraryTable(), myGlobalLibrariesProvider, getGlobalLibrariesProvider());
177 myApplicationServerLibrariesNode = createLibrariesNode(ApplicationServersManager.getInstance().getLibraryTable(), myApplicationServerLibrariesProvider, getApplicationServerLibrariesProvider());
179 ((DefaultTreeModel)myTree.getModel()).reload();
182 protected void updateSelection(NamedConfigurable configurable) {
183 final String selectedTab = ModuleEditor.getSelectedTab();
184 super.updateSelection(configurable);
185 if (configurable instanceof ModuleConfigurable){
186 final ModuleConfigurable moduleConfigurable = (ModuleConfigurable)configurable;
187 moduleConfigurable.getModuleEditor().setSelectedTabName(selectedTab);
191 private MyNode createLibrariesNode(final LibraryTable table,
192 LibrariesModifiableModel provider,
193 final LibraryTableModifiableModelProvider modelProvider) {
194 provider = new LibrariesModifiableModel(table.getModifiableModel());
195 LibrariesConfigurable librariesConfigurable = new LibrariesConfigurable(table.getTableLevel(), provider);
196 MyNode node = new MyNode(librariesConfigurable, false);
197 final Library[] libraries = provider.getLibraries();
198 for (Library library : libraries) {
199 addNode(new MyNode(new LibraryConfigurable(modelProvider, library, myProject), true), node);
201 myRoot.add(node);
202 return node;
205 private void createProjectJdks() {
206 myJdksNode = new MyNode(new JdksConfigurable(myJdksTreeModel), false);
207 final TreeMap<ProjectJdk, ProjectJdk> sdks = myJdksTreeModel.getProjectJdks();
208 for (ProjectJdk sdk : sdks.keySet()) {
209 final JdkConfigurable configurable = new JdkConfigurable((ProjectJdkImpl)sdks.get(sdk), myJdksTreeModel);
210 addNode(new MyNode(configurable, true), myJdksNode);
212 myRoot.add(myJdksNode);
215 private void createProjectNodes() {
216 myProjectNode = new MyNode(myModulesConfigurable, false);
217 final Map<ModuleGroup, MyNode> moduleGroup2NodeMap = new HashMap<ModuleGroup, MyNode>();
218 final Module[] modules = myModuleManager.getModules();
219 for (final Module module : modules) {
220 ModuleConfigurable configurable = new ModuleConfigurable(myModulesConfigurator, module);
221 final MyNode moduleNode = new MyNode(configurable, true);
222 createModuleLibraries(module, moduleNode);
223 final String[] groupPath = myModulesConfigurator.getModuleModel().getModuleGroupPath(module);
224 if (groupPath == null || groupPath.length == 0){
225 addNode(moduleNode, myProjectNode);
226 } else {
227 final MyNode moduleGroupNode = ModuleGroupUtil
228 .buildModuleGroupPath(new ModuleGroup(groupPath), myProjectNode, moduleGroup2NodeMap,
229 new Consumer<ModuleGroupUtil.ParentChildRelation<MyNode>>() {
230 public void consume(final ModuleGroupUtil.ParentChildRelation<MyNode> parentChildRelation) {
231 addNode(parentChildRelation.getChild(), parentChildRelation.getParent());
234 new Function<ModuleGroup, MyNode>() {
235 public MyNode fun(final ModuleGroup moduleGroup) {
236 final NamedConfigurable moduleGroupConfigurable = new ModuleGroupConfigurable(moduleGroup);
237 return new MyNode(moduleGroupConfigurable, false, true);
240 addNode(moduleNode, moduleGroupNode);
244 final LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
245 myProjectLibrariesProvider = new LibrariesModifiableModel(table.getModifiableModel());
246 final LibrariesConfigurable librariesConfigurable = new LibrariesConfigurable(table.getTableLevel(), myProjectLibrariesProvider);
248 myProjectLibrariesNode = new MyNode(librariesConfigurable, false);
249 final Library[] libraries = myProjectLibrariesProvider.getLibraries();
250 for (Library library1 : libraries) {
251 addNode(new MyNode(new LibraryConfigurable(getProjectLibrariesProvider(), library1, myProject), true), myProjectLibrariesNode);
253 myProjectNode.add(myProjectLibrariesNode);
255 myRoot.add(myProjectNode);
258 public boolean updateProjectTree(final Module[] modules, final ModuleGroup group) {
259 if (myRoot.getChildCount() == 0) return false; //isn't visible
260 final MyNode [] nodes = new MyNode[modules.length];
261 int i = 0;
262 for (Module module : modules) {
263 MyNode node = findNodeByObject(myProjectNode, module);
264 node.removeFromParent();
265 nodes[i ++] = node;
267 for (final MyNode moduleNode : nodes) {
268 final String[] groupPath = group != null ? group.getGroupPath() : null;
269 if (groupPath == null || groupPath.length == 0){
270 addNode(moduleNode, myProjectNode);
271 } else {
272 final MyNode moduleGroupNode = ModuleGroupUtil
273 .updateModuleGroupPath(new ModuleGroup(groupPath), myProjectNode, new Function<ModuleGroup, MyNode>() {
274 public MyNode fun(final ModuleGroup group) {
275 return findNodeByObject(myProjectNode, group);
277 }, new Consumer<ModuleGroupUtil.ParentChildRelation<MyNode>>() {
278 public void consume(final ModuleGroupUtil.ParentChildRelation<MyNode> parentChildRelation) {
279 addNode(parentChildRelation.getChild(), parentChildRelation.getParent());
281 }, new Function<ModuleGroup, MyNode>() {
282 public MyNode fun(final ModuleGroup moduleGroup) {
283 final NamedConfigurable moduleGroupConfigurable = new ModuleGroupConfigurable(moduleGroup);
284 return new MyNode(moduleGroupConfigurable, false, true);
287 addNode(moduleNode, moduleGroupNode);
290 ((DefaultTreeModel)myTree.getModel()).reload(myProjectNode);
291 return true;
294 protected void addNode(MyNode nodeToAdd, MyNode parent) {
295 parent.add(nodeToAdd);
296 TreeUtil.sort(parent, new Comparator() {
297 public int compare(final Object o1, final Object o2) {
298 final MyNode node1 = (MyNode)o1;
299 final MyNode node2 = (MyNode)o2;
300 final Object editableObject1 = node1.getConfigurable().getEditableObject();
301 final Object editableObject2 = node2.getConfigurable().getEditableObject();
302 if (editableObject1.getClass() == editableObject2.getClass()) {
303 return node1.getDisplayName().compareToIgnoreCase(node2.getDisplayName());
306 if (editableObject2 instanceof Module && editableObject1 instanceof ModuleGroup) return -1;
307 if (editableObject1 instanceof Module && editableObject2 instanceof ModuleGroup) return 1;
309 if (editableObject2 instanceof Module && editableObject1 instanceof String) return 1;
310 if (editableObject1 instanceof Module && editableObject2 instanceof String) return -1;
312 if (editableObject2 instanceof ModuleGroup && editableObject1 instanceof String) return 1;
313 if (editableObject1 instanceof ModuleGroup && editableObject2 instanceof String) return -1;
315 return 0;
318 ((DefaultTreeModel)myTree.getModel()).reload(parent);
321 private void createModuleLibraries(final Module module, final MyNode moduleNode) {
322 final LibraryTableModifiableModelProvider libraryTableModelProvider = new LibraryTableModifiableModelProvider() {
323 public LibraryTable.ModifiableModel getModifiableModel() {
324 return myModule2LibrariesMap.get(module);
327 public String getTableLevel() {
328 return LibraryTableImplUtil.MODULE_LEVEL;
332 final OrderEntry[] entries = myModulesConfigurator.getModuleEditor(module).getModifiableRootModel().getOrderEntries();
333 for (OrderEntry entry : entries) {
334 if (entry instanceof LibraryOrderEntry) {
335 final LibraryOrderEntry orderEntry = (LibraryOrderEntry)entry;
336 if (orderEntry.isModuleLevel()) {
337 final Library library = orderEntry.getLibrary();
338 if (library.getName() == null && orderEntry.getPresentableName() == null) continue;
339 final LibraryConfigurable libraryConfigurable =
340 new LibraryConfigurable(libraryTableModelProvider, library, trancateModuleLibraryName(orderEntry), myProject);
341 addNode(new MyNode(libraryConfigurable, false, false), moduleNode);
347 public static String trancateModuleLibraryName(LibraryOrderEntry entry) {
348 final String presentableName = entry.getPresentableName();
349 String independantName = FileUtil.toSystemIndependentName(presentableName);
350 if (independantName.lastIndexOf('/') + 1 == independantName.length() && independantName.length() > 1){
351 independantName = independantName.substring(0, independantName.length() - 2);
353 return independantName.substring(independantName.lastIndexOf("/") + 1);
357 public ProjectJdksModel getProjectJdksModel() {
358 return myJdksTreeModel;
361 public LibraryTableModifiableModelProvider getGlobalLibrariesProvider() {
362 return new LibraryTableModifiableModelProvider() {
363 public LibraryTable.ModifiableModel getModifiableModel() {
364 return myGlobalLibrariesProvider;
367 public String getTableLevel() {
368 return LibraryTablesRegistrar.APPLICATION_LEVEL;
373 public LibraryTableModifiableModelProvider getProjectLibrariesProvider() {
374 return new LibraryTableModifiableModelProvider() {
375 public LibraryTable.ModifiableModel getModifiableModel() {
376 return myProjectLibrariesProvider;
379 public String getTableLevel() {
380 return LibraryTablesRegistrar.PROJECT_LEVEL;
385 public void reset() {
386 myJdksTreeModel.reset();
387 myModulesConfigurator = new ModulesConfigurator(myProject, this);
388 myModulesConfigurator.resetModuleEditors();
389 myModulesConfigurable = myModulesConfigurator.getModulesConfigurable();
390 final LibraryTablesRegistrar tablesRegistrar = LibraryTablesRegistrar.getInstance();
391 myProjectLibrariesProvider = new LibrariesModifiableModel(tablesRegistrar.getLibraryTable(myProject).getModifiableModel());
392 myGlobalLibrariesProvider = new LibrariesModifiableModel(tablesRegistrar.getLibraryTable().getModifiableModel());
393 myApplicationServerLibrariesProvider =
394 new LibrariesModifiableModel(ApplicationServersManager.getInstance().getLibraryTable().getModifiableModel());
395 final Module[] modules = ModuleManager.getInstance(myProject).getModules();
396 for (Module module : modules) {
397 final ModifiableRootModel modelProxy = myModulesConfigurator.getModuleEditor(module).getModifiableRootModelProxy();
398 myModule2LibrariesMap.put(module, new LibrariesModifiableModel(modelProxy.getModuleLibraryTable().getModifiableModel()));
400 reloadTree();
401 super.reset();
405 public void apply() throws ConfigurationException {
406 boolean modifiedJdks = false;
407 for (int i = 0; i < myJdksNode.getChildCount(); i++) {
408 final NamedConfigurable configurable = ((MyNode)myJdksNode.getChildAt(i)).getConfigurable();
409 if (configurable.isModified()) {
410 configurable.apply();
411 modifiedJdks = true;
415 if (myJdksTreeModel.isModified() || modifiedJdks) myJdksTreeModel.apply();
416 myJdksTreeModel.setProjectJdk(ProjectRootManager.getInstance(myProject).getProjectJdk());
417 if (isInitialized(myModulesConfigurable) && myModulesConfigurable.isModified()) myModulesConfigurable.apply();
418 if (myModulesConfigurator.isModified()) myModulesConfigurator.apply();
419 ApplicationManager.getApplication().runWriteAction(new Runnable() {
420 public void run() {
421 myProjectLibrariesProvider.deferredCommit();
422 myGlobalLibrariesProvider.deferredCommit();
423 myApplicationServerLibrariesProvider.deferredCommit();
424 for (Module module : myModule2LibrariesMap.keySet()) {
425 if (!module.isDisposed()){ //do not update deleted modules
426 myModule2LibrariesMap.get(module).deferredCommit();
432 //cleanup
433 disposeUIResources();
434 reset();
437 public boolean isModified() {
438 boolean isModified = myModulesConfigurator.isModified();
439 for (LibrariesModifiableModel model : myModule2LibrariesMap.values()) {
440 final Library[] libraries = model.getLibraries();
441 for (Library library : libraries) {
442 if (model.hasLibraryEditor(library) && model.getLibraryEditor(library).hasChanges()) return true;
445 for (int i = 0; i < myJdksNode.getChildCount(); i++) {
446 final NamedConfigurable configurable = ((MyNode)myJdksNode.getChildAt(i)).getConfigurable();
447 if (configurable.isModified()) {
448 return true;
451 isModified |= isInitialized(myModulesConfigurable) && myModulesConfigurable.isModified();
452 isModified |= myJdksTreeModel.isModified();
453 isModified |= myGlobalLibrariesProvider.isChanged();
454 isModified |= myApplicationServerLibrariesProvider.isChanged();
455 isModified |= myProjectLibrariesProvider.isChanged();
456 return isModified;
459 public void disposeUIResources() {
460 myJdksTreeModel.disposeUIResources();
461 myModulesConfigurator.disposeUIResources();
462 myModule2LibrariesMap.clear();
463 myProjectLibrariesProvider = null;
464 myGlobalLibrariesProvider = null;
465 myApplicationServerLibrariesProvider = null;
466 super.disposeUIResources();
470 public JComponent createComponent() {
471 return new MyDataProviderWrapper();
474 protected void processRemovedItems() {
475 // do nothing
478 protected boolean wasObjectStored(Object editableObject) {
479 return false;
482 public String getDisplayName() {
483 return ProjectBundle.message("project.roots.display.name");
486 public Icon getIcon() {
487 return ICON;
490 @Nullable
491 @NonNls
492 public String getHelpTopic() {
493 final TreePath selectionPath = myTree.getSelectionPath();
494 if (selectionPath != null) {
495 MyNode node = (MyNode)selectionPath.getLastPathComponent();
496 final NamedConfigurable configurable = node.getConfigurable();
497 if (configurable != null) {
498 return configurable.getHelpTopic();
501 return "root.settings";
504 public void projectOpened() {
507 public void projectClosed() {
511 protected ArrayList<AnAction> createActions() {
512 final ArrayList<AnAction> result = new ArrayList<AnAction>();
513 result.add(new MyAddAction());
514 result.add(new MyRemoveAction(new Condition<Object>() {
515 public boolean value(final Object object) {
516 if (object instanceof MyNode) {
517 final NamedConfigurable namedConfigurable = ((MyNode)object).getConfigurable();
518 final Object editableObject = namedConfigurable.getEditableObject();
519 if (editableObject instanceof ProjectJdk ||
520 editableObject instanceof Module) return true;
521 if (editableObject instanceof Library){
522 return true;
525 return false;
527 }));
528 return result;
531 @NonNls
532 @NotNull
533 public String getComponentName() {
534 return "com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable";
537 public void initComponent() {
540 public void disposeComponent() {
543 public static ProjectRootConfigurable getInstance(final Project project) {
544 return project.getComponent(ProjectRootConfigurable.class);
547 public void createNode(final NamedConfigurable<ProjectJdk> configurable, final MyNode parentNode) {
548 final MyNode node = new MyNode(configurable, true);
549 addNode(node, parentNode);
550 selectNodeInTree(node);
553 public MyNode createLibraryNode(Library library, String presentableName) {
554 final LibraryTable table = library.getTable();
555 if (table != null){
556 final String level = table.getTableLevel();
557 if (level == LibraryTablesRegistrar.APPLICATION_LEVEL) {
558 final LibraryConfigurable configurable = new LibraryConfigurable(getGlobalLibrariesProvider(), library, myProject);
559 final MyNode node = new MyNode(configurable, true);
560 addNode(node, myGlobalLibrariesNode);
561 return node;
563 else if (level == LibraryTablesRegistrar.PROJECT_LEVEL) {
564 final LibraryConfigurable configurable = new LibraryConfigurable(getProjectLibrariesProvider(), library, myProject);
565 final MyNode node = new MyNode(configurable, true);
566 addNode(node, myProjectLibrariesNode);
567 return node;
569 else {
570 final LibraryConfigurable configurable = new LibraryConfigurable(getApplicationServerLibrariesProvider(), library, myProject);
571 final MyNode node = new MyNode(configurable, true);
572 addNode(node, myApplicationServerLibrariesNode);
573 return node;
575 } else { //module library
576 Module module = (Module)getSelectedObject();
577 final LibraryConfigurable configurable = new LibraryConfigurable(getModifiableModelProvider(myModulesConfigurator.getModuleEditor(module).getModifiableRootModelProxy()), library, presentableName, myProject);
578 final MyNode node = new MyNode(configurable, true);
579 addNode(node, (MyNode)myTree.getSelectionPath().getLastPathComponent());
580 return node;
584 private void showDependencies() {
585 final List<String> dependencies = getDependencies();
586 if (dependencies == null || dependencies.size() == 0){
587 Messages.showInfoMessage(myTree, FindBundle.message("find.usage.view.no.usages.text"), FindBundle.message("find.pointcut.applications.not.found.title"));
588 return;
590 final int selectedRow = myTree.getSelectionRows()[0];
591 final Rectangle rowBounds = myTree.getRowBounds(selectedRow);
592 final Point location = rowBounds.getLocation();
593 location.x += rowBounds.width;
594 JBPopupFactory.getInstance().createWizardStep(new BaseListPopupStep<String>(ProjectBundle.message("dependencies.used.in.popup.title"), dependencies) {
596 public PopupStep onChosen(final String nameToSelect, final boolean finalChoice) {
597 selectNodeInTree(nameToSelect);
598 return PopupStep.FINAL_CHOICE;
601 public Icon getIconFor(String selection){
602 return myModulesConfigurator.getModule(selection).getModuleType().getNodeIcon(false);
605 }).show(new RelativePoint(myTree, location));
608 @Nullable
609 private List<String> getDependencies() {
610 final Object selectedObject = getSelectedObject();
611 if (selectedObject instanceof Module) {
612 return getDependencies(new Condition<OrderEntry>() {
613 public boolean value(final OrderEntry orderEntry) {
614 return orderEntry instanceof ModuleOrderEntry && Comparing.equal(((ModuleOrderEntry)orderEntry).getModule(), selectedObject);
618 else if (selectedObject instanceof Library) {
619 if (((Library)selectedObject).getTable() == null) { //module library navigation
620 final MyNode node = (MyNode)myTree.getSelectionPath().getLastPathComponent();
621 final List<String> list = new ArrayList<String>();
622 list.add(((MyNode)node.getParent()).getDisplayName());
623 return list;
625 return getDependencies(new Condition<OrderEntry>() {
626 public boolean value(final OrderEntry orderEntry) {
627 if (orderEntry instanceof LibraryOrderEntry){
628 final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary();
629 return library != null && Comparing.equal(library.getSource(), selectedObject);
631 return false;
635 else if (selectedObject instanceof ProjectJdk) {
636 return getDependencies(new Condition<OrderEntry>() {
637 public boolean value(final OrderEntry orderEntry) {
638 return orderEntry instanceof JdkOrderEntry && Comparing.equal(((JdkOrderEntry)orderEntry).getJdk(), selectedObject);
642 return null;
645 private List<String> getDependencies(Condition<OrderEntry> condition) {
646 final List<String> result = new ArrayList<String>();
647 final Module[] modules = myModulesConfigurator.getModules();
648 for (Module module : modules) {
649 final ModifiableRootModel rootModel = myModulesConfigurator.getModuleEditor(module).getModifiableRootModel();
650 final OrderEntry[] entries = rootModel.getOrderEntries();
651 for (OrderEntry entry : entries) {
652 if (condition.value(entry)) {
653 result.add(module.getName());
654 break;
658 return result;
661 @Nullable
662 public ProjectJdk getSelectedJdk() {
663 final Object object = getSelectedObject();
664 if (object instanceof ProjectJdk){
665 return myJdksTreeModel.findSdk((ProjectJdk)object);
667 return null;
670 public void setStartModuleWizard(final boolean show) {
671 myModulesConfigurator.getModulesConfigurable().setStartModuleWizardOnShow(show);
674 public LibraryTableModifiableModelProvider getApplicationServerLibrariesProvider() {
675 return new LibraryTableModifiableModelProvider() {
676 public LibraryTable.ModifiableModel getModifiableModel() {
677 return myApplicationServerLibrariesProvider;
680 public String getTableLevel() {
681 return ApplicationServersManager.APPLICATION_SERVER_MODULE_LIBRARIES;
686 public DefaultMutableTreeNode createLibraryNode(final LibraryOrderEntry libraryOrderEntry, final ModifiableRootModel model) {
687 final LibraryConfigurable configurable = new LibraryConfigurable(getModifiableModelProvider(model), libraryOrderEntry.getLibrary(), trancateModuleLibraryName(libraryOrderEntry), myProject);
688 final MyNode node = new MyNode(configurable, true);
689 addNode(node, findNodeByObject(myProjectNode, libraryOrderEntry.getOwnerModule()));
690 return node;
693 public void deleteLibraryNode(LibraryOrderEntry libraryOrderEntry) {
694 final MyNode node = findNodeByObject(myProjectNode, libraryOrderEntry.getLibrary());
695 if (node != null) {
696 final TreeNode parent = node.getParent();
697 node.removeFromParent();
698 ((DefaultTreeModel)myTree.getModel()).reload(parent);
699 final Module module = libraryOrderEntry.getOwnerModule();
700 myModule2LibrariesMap.get(module).removeLibrary(libraryOrderEntry.getLibrary());
704 public Project getProject() {
705 return myProject;
708 @Nullable
709 public Library getLibrary(final Library library) {
710 final String level = library.getTable().getTableLevel();
711 if (level == LibraryTablesRegistrar.PROJECT_LEVEL) {
712 return findLibraryModel(library, myProjectLibrariesProvider);
714 else if (level == LibraryTablesRegistrar.APPLICATION_LEVEL) {
715 return findLibraryModel(library, myGlobalLibrariesProvider);
717 return findLibraryModel(library, myApplicationServerLibrariesProvider);
720 @Nullable
721 private static Library findLibraryModel(final Library library, LibrariesModifiableModel tableModel) {
722 if (tableModel == null) return library;
723 if (tableModel.wasLibraryRemoved(library)) return null;
724 return tableModel.hasLibraryEditor(library) ? (Library)tableModel.getLibraryEditor(library).getModel() : library;
727 public void selectModuleTab(final String moduleName, final String tabName) {
728 final MyNode node = findNodeByObject(myProjectNode, ModuleManager.getInstance(myProject).findModuleByName(moduleName));
729 if (node != null) {
730 selectNodeInTree(node);
731 SwingUtilities.invokeLater(new Runnable() {
732 public void run() {
733 ModuleConfigurable moduleConfigurable = (ModuleConfigurable)node.getConfigurable();
734 moduleConfigurable.getModuleEditor().setSelectedTabName(tabName);
740 public void addJdkNode(final ProjectJdk jdk) {
741 addNode(new MyNode(new JdkConfigurable((ProjectJdkImpl)jdk, myJdksTreeModel), true), myJdksNode);
744 private class MyDataProviderWrapper extends JPanel implements DataProvider {
745 public MyDataProviderWrapper() {
746 super(new BorderLayout());
747 add(myWholePanel, BorderLayout.CENTER);
750 @Nullable
751 public Object getData(@NonNls String dataId) {
752 if (DataConstants.MODULE_CONTEXT_ARRAY.equals(dataId)){
753 final Object o = getSelectedObject();
754 if (o instanceof Module){
755 return new Module[]{(Module)o};
758 if (DataConstantsEx.MODIFIABLE_MODULE_MODEL.equals(dataId)){
759 return myModulesConfigurator.getModuleModel();
761 return null;
765 private class MyRemoveAction extends MyDeleteAction {
766 public MyRemoveAction(final Condition<Object> availableCondition) {
767 super(availableCondition);
770 public void actionPerformed(AnActionEvent e) {
771 final TreePath selectionPath = myTree.getSelectionPath();
772 final MyNode node = (MyNode)selectionPath.getLastPathComponent();
773 final NamedConfigurable configurable = node.getConfigurable();
774 final Object editableObject = configurable.getEditableObject();
775 if (editableObject instanceof ProjectJdk) {
776 myJdksTreeModel.removeJdk((ProjectJdk)editableObject);
778 else if (editableObject instanceof Module) {
779 if (!myModulesConfigurator.deleteModule((Module)editableObject)){
780 //wait for confirmation
781 return;
784 else if (editableObject instanceof Library) {
785 final Library library = (Library)editableObject;
786 final LibraryTable table = library.getTable();
787 if (table != null) {
788 final String level = table.getTableLevel();
789 if (level == LibraryTablesRegistrar.APPLICATION_LEVEL) {
790 myGlobalLibrariesProvider.removeLibrary(library);
792 else if (level == LibraryTablesRegistrar.PROJECT_LEVEL) {
793 myProjectLibrariesProvider.removeLibrary(library);
795 else {
796 myApplicationServerLibrariesProvider.removeLibrary(library);
799 else {
800 Module module = (Module)((MyNode)node.getParent()).getConfigurable().getEditableObject();
801 myModule2LibrariesMap.get(module).removeLibrary(library);
802 myModulesConfigurator.getModuleEditor(module).updateOrderEntriesInEditors(); //in order to update classpath panel
805 super.actionPerformed(e);
809 public DefaultActionGroup createAddJdksGroup(){
810 DefaultActionGroup group = new DefaultActionGroup();
811 myJdksTreeModel.createAddActions(group, myTree, new Consumer<ProjectJdk>() {
812 public void consume(final ProjectJdk projectJdk) {
813 addJdkNode(projectJdk);
816 return group;
819 private PopupStep createJdksStep(DataContext dataContext) {
820 DefaultActionGroup group = new DefaultActionGroup();
821 myJdksTreeModel.createAddActions(group, myTree, new Consumer<ProjectJdk>() {
822 public void consume(final ProjectJdk projectJdk) {
823 addJdkNode(projectJdk);
826 final JBPopupFactory popupFactory = JBPopupFactory.getInstance();
827 return popupFactory.createActionsStep(group, dataContext, false, false, ProjectBundle.message("add.new.jdk.title"), myTree, true);
830 private PopupStep createLibrariesStep(AnActionEvent e) {
831 DefaultActionGroup group = new DefaultActionGroup();
832 group.add(new AnAction(ProjectBundle.message("add.new.global.library.text")) {
833 public void actionPerformed(AnActionEvent e) {
834 final LibraryTableEditor editor = LibraryTableEditor.editLibraryTable(getGlobalLibrariesProvider(), myProject);
835 editor.createAddLibraryAction(true, myWholePanel).actionPerformed(null);
836 Disposer.dispose(editor);
839 group.add(new AnAction(ProjectBundle.message("add.new.project.library.text")) {
840 public void actionPerformed(AnActionEvent e) {
841 LibraryTableEditor.editLibraryTable(getProjectLibrariesProvider(), myProject).createAddLibraryAction(true, myWholePanel).actionPerformed(null);
844 public void update(AnActionEvent e) {
845 e.getPresentation().setEnabled(!myProject.isDefault());
848 group.add(new AnAction(ProjectBundle.message("add.new.application.server.library.text")) {
849 public void actionPerformed(AnActionEvent e) {
850 LibraryTableEditor.editLibraryTable(getApplicationServerLibrariesProvider(), myProject).createAddLibraryAction(true, myWholePanel)
851 .actionPerformed(null);
854 group.add(new AnAction(ProjectBundle.message("add.new.module.library.text")) {
855 public void actionPerformed(AnActionEvent e) {
856 Module module = (Module)getSelectedObject();
857 final LibraryTableModifiableModelProvider modifiableModelProvider = getModifiableModelProvider(myModulesConfigurator.getModuleEditor(module).getModifiableRootModelProxy());
858 LibraryTableEditor.editLibraryTable(modifiableModelProvider, myProject).createAddLibraryAction(true, myWholePanel).actionPerformed(null);
861 public void update(AnActionEvent e) {
862 e.getPresentation().setEnabled(getSelectedObject() instanceof Module);
865 final JBPopupFactory popupFactory = JBPopupFactory.getInstance();
866 final int defaultOptionIndex;
867 final Object selectedObject = getSelectedObject();
868 if (selectedObject instanceof String){
869 final String libraryTable = (String)selectedObject;
870 defaultOptionIndex = Comparing.strEqual(libraryTable, LibraryTablesRegistrar.APPLICATION_LEVEL)
872 : Comparing.strEqual(libraryTable, LibraryTablesRegistrar.PROJECT_LEVEL) ? 1 : 2;
873 } else {
874 defaultOptionIndex = 1; //do not create too many module libraries ;)
876 return popupFactory.createActionsStep(group, e.getDataContext(), false, false, ProjectBundle.message("add.new.library.title"), myTree, true, defaultOptionIndex);
879 private LibraryTableModifiableModelProvider getModifiableModelProvider(final ModifiableRootModel model) {
880 return new LibraryTableModifiableModelProvider() {
881 public LibraryTable.ModifiableModel getModifiableModel() {
882 final LibraryTable.ModifiableModel modifiableModel = model.getModuleLibraryTable().getModifiableModel();
883 myModule2LibrariesMap.put(model.getModule(), new LibrariesModifiableModel(modifiableModel));
884 return modifiableModel;
887 public String getTableLevel() {
888 return LibraryTableImplUtil.MODULE_LEVEL;
893 private class MyAddAction extends AnAction {
895 public MyAddAction() {
896 super(CommonBundle.message("button.add"), CommonBundle.message("button.add"), Icons.ADD_ICON);
897 registerCustomShortcutSet(CommonShortcuts.INSERT, myTree);
900 public void actionPerformed(final AnActionEvent e) {
901 JBPopupFactory jbPopupFactory = JBPopupFactory.getInstance();
902 List<String> actions = new ArrayList<String>();
903 final String libraryChoice = ProjectBundle.message("add.new.library.text");
904 actions.add(libraryChoice);
905 final String jdkChoice = ProjectBundle.message("add.new.jdk.text");
906 actions.add(jdkChoice);
907 final String moduleChoice = ProjectBundle.message("add.new.module.text");
908 if (!myProject.isDefault()) {
909 actions.add(moduleChoice);
911 List<Icon> icons = new ArrayList<Icon>();
912 final ListPopup listPopup = jbPopupFactory.createWizardStep(new BaseListPopupStep<String>(ProjectBundle.message("add.action.name"), actions, icons) {
913 public boolean hasSubstep(final String selectedValue) {
914 return selectedValue.compareTo(moduleChoice) != 0;
917 public PopupStep onChosen(final String selectedValue, final boolean finalChoice) {
918 if (selectedValue.compareTo(libraryChoice) == 0) {
919 return createLibrariesStep(e);
921 else if (selectedValue.compareTo(jdkChoice) == 0) {
922 return createJdksStep(e.getDataContext());
924 SwingUtilities.invokeLater(new Runnable() {
925 public void run() {
926 final Module module = myModulesConfigurator.addModule(myTree);
927 if (module != null) {
928 final MyNode node = new MyNode(new ModuleConfigurable(myModulesConfigurator, module), true);
929 addNode(node, myProjectNode);
930 selectNodeInTree(node);
934 return PopupStep.FINAL_CHOICE;
937 public int getDefaultOptionIndex() {
938 final Object selectedObject = getSelectedObject();
939 if (selectedObject instanceof Library || selectedObject instanceof String){
940 return 0;
941 } else if (selectedObject instanceof ProjectJdk || selectedObject instanceof ProjectJdksModel){
942 return 1;
943 } else if (selectedObject instanceof Module){
944 return 2;
946 return 0;
949 listPopup.showUnderneathOf(myNorthPanel);
950 final int defaultOptionIndex = listPopup.getListStep().getDefaultOptionIndex();
951 if (defaultOptionIndex == 0 || defaultOptionIndex == 1) {
952 SwingUtilities.invokeLater(new Runnable() {
953 public void run() {
954 ((ListPopupImpl)listPopup).handleSelect(true);