From 05f0b882360da7def45d4640d1b7edfb04ab5e29 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 23 Aug 2011 16:09:48 +0400 Subject: [PATCH] 'create library from files' action now automatically detects root types --- .../actions/CreateLibraryFromFilesDialog.java | 22 ++++---- .../actions/MarkLibraryRootAction.java | 53 +++++++++++++------ .../DetectedSourceRootsDialog.java | 38 ++++++------- .../libraryEditor/LibraryEditorBase.java | 13 +++++ .../libraryEditor/LibraryRootsComponent.java | 10 +--- .../libraryEditor/RootDetectionUtil.java | 6 ++- .../projectRoot/LibrariesContainer.java | 5 ++ .../LibrariesContainerFactory.java | 12 +++++ .../libraryEditor/LibraryEditor.java | 5 ++ 9 files changed, 102 insertions(+), 62 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java index eb0c692d7b5f..148a4102f3cd 100644 --- a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java +++ b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.roots.ui.configuration.ModulesCombobox; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryNameAndLevelPanel; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; @@ -50,13 +51,13 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper { private final LibraryNameAndLevelPanel myNameAndLevelPanel; private final ModulesCombobox myModulesCombobox; private final Project myProject; - private final List myRoots; + private final List myRoots; private JPanel myPanel; private final LibrariesContainer myLibrariesContainer; private final String myDefaultName; private final ModifiableRootModel myModifiableModel; - public CreateLibraryFromFilesDialog(@NotNull Project project, @NotNull List roots) { + public CreateLibraryFromFilesDialog(@NotNull Project project, @NotNull List roots) { super(project, true); setTitle("Create Library"); myProject = project; @@ -114,15 +115,15 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper { } @Nullable - private Module findModule(List files) { - for (VirtualFile file : files) { + private Module findModule(List roots) { + for (OrderRoot root : roots) { Module module = null; - final VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(file); + final VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(root.getFile()); if (local != null) { module = ModuleUtil.findModuleForFile(local, myProject); } if (module == null) { - module = ModuleUtil.findModuleForFile(file, myProject); + module = ModuleUtil.findModuleForFile(root.getFile(), myProject); } if (module != null) { return module; @@ -136,21 +137,20 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper { return myNameAndLevelPanel.getLibraryNameField(); } - private static String suggestLibraryName(List files) { - if (files.size() >= 1) { - return FileUtil.getNameWithoutExtension(PathUtil.getFileName(files.get(0).getPath())); + private static String suggestLibraryName(List roots) { + if (roots.size() >= 1) { + return FileUtil.getNameWithoutExtension(PathUtil.getFileName(roots.get(0).getFile().getPath())); } return "unnamed"; } @Override protected void doOKAction() { - final VirtualFile[] roots = myRoots.toArray(new VirtualFile[myRoots.size()]); final LibrariesContainer.LibraryLevel level = myNameAndLevelPanel.getLibraryLevel(); AccessToken token = WriteAction.start(); try { final Library library = myLibrariesContainer.createLibrary(myNameAndLevelPanel.getLibraryName(), - level, roots, VirtualFile.EMPTY_ARRAY); + level, myRoots); if (level == LibrariesContainer.LibraryLevel.MODULE) { myModifiableModel.commit(); } diff --git a/java/idea-ui/src/com/intellij/ide/projectView/actions/MarkLibraryRootAction.java b/java/idea-ui/src/com/intellij/ide/projectView/actions/MarkLibraryRootAction.java index 0c7d957eac0d..2b06a222d18f 100644 --- a/java/idea-ui/src/com/intellij/ide/projectView/actions/MarkLibraryRootAction.java +++ b/java/idea-ui/src/com/intellij/ide/projectView/actions/MarkLibraryRootAction.java @@ -21,6 +21,9 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.DefaultLibraryRootsComponentDescriptor; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.RootDetectionUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -38,41 +41,57 @@ public class MarkLibraryRootAction extends AnAction { final Project project = getEventProject(e); if (project == null) return; - final List jars = getJarRoots(e); + final List jars = getRoots(e); if (jars.isEmpty()) return; - new CreateLibraryFromFilesDialog(project, jars).show(); + final List roots = RootDetectionUtil.detectRoots(jars, null, project, new DefaultLibraryRootsComponentDescriptor().getRootDetectors(), true); + new CreateLibraryFromFilesDialog(project, roots).show(); } @NotNull - private static List getJarRoots(AnActionEvent e) { + private static List getRoots(AnActionEvent e) { final Project project = getEventProject(e); final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); if (project == null || files == null || files.length == 0) return Collections.emptyList(); - final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); - List archives = new ArrayList(); + List roots = new ArrayList(); for (VirtualFile file : files) { - addJarRoot(archives, file, fileIndex); if (file.isDirectory()) { - for (VirtualFile child : file.getChildren()) { - addJarRoot(archives, child, fileIndex); + roots.add(file); + } + else { + final VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(file); + if (root != null) { + roots.add(root); } } } - return archives; - } - - private static void addJarRoot(List archives, VirtualFile file, ProjectFileIndex index) { - final VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(file); - if (root != null && !index.isInLibraryClasses(root)) { - archives.add(root); - } + return roots; } @Override public void update(AnActionEvent e) { - boolean visible = !getJarRoots(e).isEmpty(); + final Project project = getEventProject(e); + boolean visible = false; + if (project != null) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + for (VirtualFile root : getRoots(e)) { + if (!root.isInLocalFileSystem() && !fileIndex.isInLibraryClasses(root)) { + visible = true; + break; + } + if (root.isInLocalFileSystem() && root.isDirectory()) { + for (VirtualFile child : root.getChildren()) { + final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(child); + if (jarRoot != null && !fileIndex.isInLibraryClasses(child)) { + visible = true; + break; + } + } + } + } + } + e.getPresentation().setVisible(visible); e.getPresentation().setEnabled(visible); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DetectedSourceRootsDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DetectedSourceRootsDialog.java index 9682d1940b35..ee2814598f7d 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DetectedSourceRootsDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DetectedSourceRootsDialog.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.roots.ui.configuration.libraryEditor; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TitlePanel; import com.intellij.openapi.vfs.VfsUtil; @@ -28,8 +29,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; -import java.util.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * This dialog allows selecting source paths inside selected source archives or directories. @@ -41,7 +43,7 @@ public class DetectedSourceRootsDialog extends DialogWrapper { /** * A tree with paths. The tree relies on the CheckboxTree for selection and unselection policy. */ - private final CheckboxTree myTree; + private CheckboxTree myTree; /** * Root node for the tree. The tree is three-level: *
    @@ -50,37 +52,27 @@ public class DetectedSourceRootsDialog extends DialogWrapper { *
  • The third level are paths with java sources inside pervious selection.
  • *
*/ - private final CheckedTreeNode myRootNode; - /** - * A scrollable pane that contains myTree - */ - private final JScrollPane myPane; + private CheckedTreeNode myRootNode; + private JScrollPane myPane; public DetectedSourceRootsDialog(Component component, List suggestedRoots) { - this(component, createTree(suggestedRoots)); + super(component, true); + init(suggestedRoots); } - /** - * A constructor - * - * @param component a parent component - * @param tree a checkbox tree to use - */ - private DetectedSourceRootsDialog(Component component, CheckedTreeNode tree) { - super(component, true); - myRootNode = tree; + public DetectedSourceRootsDialog(Project project, List suggestedRoots) { + super(project, true); + init(suggestedRoots); + } + + private void init(List suggestedRoots) { + myRootNode = createTree(suggestedRoots); myTree = createCheckboxTree(); myPane = ScrollPaneFactory.createScrollPane(myTree); setTitle("Detected Source Roots"); init(); } - - /** - * Create a checkbox tree component for this dialog - * - * @return a created component - */ private CheckboxTree createCheckboxTree() { CheckboxTree tree = new CheckboxTree(new CheckboxTree.CheckboxTreeCellRenderer(true) { public void customizeRenderer(JTree tree, diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditorBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditorBase.java index ec4c727093dc..a9c62e45dbc2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditorBase.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditorBase.java @@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.LibraryProperties; import com.intellij.openapi.roots.libraries.LibraryType; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -44,4 +45,16 @@ public abstract class LibraryEditorBase implements LibraryEditor { public abstract void setProperties(LibraryProperties properties); public abstract void setType(@NotNull LibraryType type); + + @Override + public void addRoots(Collection roots) { + for (OrderRoot root : roots) { + if (root.isJarDirectory()) { + addJarDirectory(root.getFile(), false, root.getType()); + } + else { + addRoot(root.getFile(), root.getType()); + } + } + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java index f59193cabb2c..7857470d4ed8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java @@ -384,15 +384,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent if (!rootsToAttach.isEmpty()) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { - final LibraryEditor libraryEditor = getLibraryEditor(); - for (OrderRoot root : rootsToAttach) { - if (root.isJarDirectory()) { - libraryEditor.addJarDirectory(root.getFile(), false, root.getType()); - } - else { - libraryEditor.addRoot(root.getFile(), root.getType()); - } - } + getLibraryEditor().addRoots(rootsToAttach); } }); updatePropertiesLabel(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/RootDetectionUtil.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/RootDetectionUtil.java index 33cf4bcfb0eb..803715b7eea2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/RootDetectionUtil.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/RootDetectionUtil.java @@ -41,7 +41,7 @@ public class RootDetectionUtil { } public static List detectRoots(@NotNull final Collection rootCandidates, - @NotNull Component parentComponent, + @Nullable Component parentComponent, @Nullable Project project, @NotNull final List detectors, boolean allowUserToSelectRootTypeIfNothingIsDetected) { @@ -68,7 +68,9 @@ public class RootDetectionUtil { }.queue(); if (!suggestedRoots.isEmpty()) { - final DetectedSourceRootsDialog dialog = new DetectedSourceRootsDialog(parentComponent, suggestedRoots); + final DetectedSourceRootsDialog dialog = parentComponent != null + ? new DetectedSourceRootsDialog(parentComponent, suggestedRoots) + : new DetectedSourceRootsDialog(project, suggestedRoots); dialog.show(); if (!dialog.isOK()) { return Collections.emptyList(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java index acff0d85038e..eccb4ea5e989 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java @@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.util.text.StringUtil; @@ -26,6 +27,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.List; /** @@ -59,6 +61,9 @@ public interface LibrariesContainer { Library createLibrary(@NotNull @NonNls String name, @NotNull LibraryLevel level, @NotNull VirtualFile[] classRoots, @NotNull VirtualFile[] sourceRoots); + Library createLibrary(@NotNull @NonNls String name, @NotNull LibraryLevel level, + @NotNull Collection roots); + Library createLibrary(@NotNull NewLibraryEditor libraryEditor, @NotNull LibraryLevel level); @NotNull diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java index 2ef075fcd9e3..0cf59d85a72f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java @@ -24,6 +24,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; @@ -40,6 +41,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; /** @@ -123,6 +125,16 @@ public class LibrariesContainerFactory { return createLibrary(editor, level); } + @Override + public Library createLibrary(@NotNull @NonNls String name, + @NotNull LibraryLevel level, + @NotNull Collection roots) { + final NewLibraryEditor editor = new NewLibraryEditor(); + editor.setName(name); + editor.addRoots(roots); + return createLibrary(editor, level); + } + @NotNull public Library[] getAllLibraries() { Library[] libraries = getLibraries(LibraryLevel.GLOBAL); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java index 4ff8df0a8df0..ea684851154b 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java @@ -18,9 +18,12 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.LibraryProperties; import com.intellij.openapi.roots.libraries.LibraryType; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + /** * @author nik */ @@ -55,4 +58,6 @@ public interface LibraryEditor { @Nullable LibraryType getType(); + + void addRoots(Collection roots); }