mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ScopeView: hide modules and content roots if ShowModules is false
This commit is contained in:
@@ -74,6 +74,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.ide.projectView.impl.ProjectRootsUtil.findSourceFolder;
|
||||
import static com.intellij.ide.projectView.impl.ShowModulesAction.hasModules;
|
||||
import static com.intellij.openapi.roots.ui.configuration.SourceRootPresentation.getSourceRootIcon;
|
||||
import static com.intellij.openapi.util.io.FileUtil.getLocationRelativeToUserHome;
|
||||
import static com.intellij.openapi.vfs.VfsUtilCore.VFS_SEPARATOR_CHAR;
|
||||
@@ -215,6 +216,7 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
model.onValidThread(() -> {
|
||||
root.childrenValid = false;
|
||||
LOG.debug("whole structure changed");
|
||||
model.setShowModules(hasModules() && root.getSettings().isShowModules());
|
||||
treeStructureChanged(null, null, null);
|
||||
if (onDone != null) onDone.run();
|
||||
});
|
||||
@@ -534,13 +536,7 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
model.getChildren(model.getRoot()).forEach(child -> newRoots.put(child, mapper.apply(this, child)));
|
||||
roots = newRoots;
|
||||
if (newRoots.isEmpty()) return emptyList();
|
||||
ModuleManager manager = getModuleManager(getProject());
|
||||
if (manager == null) return emptyList();
|
||||
boolean hidden = !getSettings().isShowModules();
|
||||
if (!hidden && manager.getModules().length <= 1) hidden = true;
|
||||
boolean flatten = hidden || getSettings().isFlattenModules();
|
||||
if (!flatten && !manager.hasModuleGroups() && !Registry.is("project.qualified.module.names")) flatten = true;
|
||||
return new Group(newRoots.values(), hidden, flatten).createChildren(this, old);
|
||||
return new Group(newRoots.values(), getSettings().isFlattenModules() || !hasModuleGroups(getProject())).createChildren(this, old);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -666,13 +662,21 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
|
||||
@Override
|
||||
protected void update(PresentationData presentation) {
|
||||
VirtualFile file = getVirtualFile();
|
||||
String title = getTitle();
|
||||
presentation.setPresentableText(title != null ? title : toString());
|
||||
SimpleTextAttributes attributes = SimpleTextAttributes.REGULAR_ATTRIBUTES;
|
||||
if (node.getRootID() instanceof VirtualFile) {
|
||||
ProjectFileIndex index = getProjectFileIndex(getProject());
|
||||
if (index != null && file.equals(index.getContentRootForFile(file))) {
|
||||
attributes = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
presentation.addText(title != null ? title : toString(), attributes);
|
||||
Icon icon = getIcon();
|
||||
if (icon == null && getVirtualFile().isValid()) {
|
||||
icon = getVirtualFile().isDirectory()
|
||||
if (icon == null && file.isValid()) {
|
||||
icon = file.isDirectory()
|
||||
? getFolderIcon(node, null)
|
||||
: getVirtualFile().getFileType().getIcon();
|
||||
: file.getFileType().getIcon();
|
||||
}
|
||||
presentation.setIcon(icon);
|
||||
decorate(presentation);
|
||||
@@ -956,38 +960,33 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
id = module;
|
||||
}
|
||||
|
||||
Group(@NotNull Collection<RootNode> nodes, boolean hidden, boolean flatten) {
|
||||
Group(@NotNull Collection<RootNode> nodes, boolean flatten) {
|
||||
id = null;
|
||||
if (!nodes.isEmpty()) {
|
||||
if (hidden) {
|
||||
roots.addAll(nodes);
|
||||
}
|
||||
else {
|
||||
HashMap<Module, Group> map = new HashMap<>();
|
||||
nodes.forEach(node -> {
|
||||
Object id = node.node.getRootID();
|
||||
if (id instanceof Module) {
|
||||
Module module = (Module)id;
|
||||
Group group = map.get(module);
|
||||
if (group == null) {
|
||||
group = new Group(module);
|
||||
map.put(module, group);
|
||||
}
|
||||
group.roots.add(node);
|
||||
HashMap<Module, Group> map = new HashMap<>();
|
||||
nodes.forEach(node -> {
|
||||
Object id = node.node.getRootID();
|
||||
if (id instanceof Module) {
|
||||
Module module = (Module)id;
|
||||
Group group = map.get(module);
|
||||
if (group == null) {
|
||||
group = new Group(module);
|
||||
map.put(module, group);
|
||||
}
|
||||
else {
|
||||
roots.add(node);
|
||||
}
|
||||
});
|
||||
if (flatten) {
|
||||
groups.putAll(map);
|
||||
group.roots.add(node);
|
||||
}
|
||||
else {
|
||||
map.forEach((module, group) -> {
|
||||
List<String> path = getModuleNameAsList(module, Registry.is("project.qualified.module.names"));
|
||||
group.roots.forEach(node -> add(node, path, 0));
|
||||
});
|
||||
roots.add(node);
|
||||
}
|
||||
});
|
||||
if (flatten) {
|
||||
groups.putAll(map);
|
||||
}
|
||||
else {
|
||||
map.forEach((module, group) -> {
|
||||
List<String> path = getModuleNameAsList(module, Registry.is("project.qualified.module.names"));
|
||||
group.roots.forEach(node -> add(node, path, 0));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1149,6 +1148,7 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
return index == null ? null : index.getModuleForFile(file);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPackageName(@Nullable PsiElement element) {
|
||||
if (element instanceof PsiDirectory && element.isValid()) {
|
||||
PsiDirectoryFactory factory = PsiDirectoryFactory.getInstance(element.getProject());
|
||||
@@ -1160,6 +1160,12 @@ public final class ScopeViewTreeModel extends BaseTreeModel<AbstractTreeNode> im
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean hasModuleGroups(@Nullable Project project) {
|
||||
if (Registry.is("project.qualified.module.names")) return true;
|
||||
ModuleManager manager = getModuleManager(project);
|
||||
return manager != null && manager.hasModuleGroups();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> getModuleNameAsList(@NotNull Module module, boolean split) {
|
||||
String name = module.getName();
|
||||
|
||||
@@ -125,10 +125,13 @@ public abstract class ProjectFileListener {
|
||||
@Nullable
|
||||
public static AreaInstance findArea(@NotNull VirtualFile file, @Nullable Project project) {
|
||||
if (project == null || project.isDisposed()) return null;
|
||||
Module module = ProjectFileIndex.getInstance(project).getModuleForFile(file);
|
||||
Module module = ProjectFileIndex.getInstance(project).getModuleForFile(file, false);
|
||||
if (module != null) return module.isDisposed() ? null : module;
|
||||
VirtualFile ancestor = project.getBaseDir();
|
||||
// file does not belong to any content root, but it is located under the project directory
|
||||
return ancestor == null || !isAncestor(ancestor, file, false) ? null : project;
|
||||
if (ancestor == null || !isAncestor(ancestor, file, false)) return null;
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
PsiElement element = file.isDirectory() ? manager.findDirectory(file) : manager.findFile(file);
|
||||
return element == null ? null : project; // ensure that the corresponding file can be shown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.VFileProperty;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileFilter;
|
||||
import com.intellij.ui.tree.BaseTreeModel;
|
||||
import com.intellij.ui.tree.TreeCollector;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.concurrency.Invoker;
|
||||
@@ -30,6 +30,7 @@ import java.util.function.Predicate;
|
||||
|
||||
import static com.intellij.openapi.vfs.VfsUtilCore.isAncestor;
|
||||
import static com.intellij.ui.tree.TreePathUtil.pathToCustomNode;
|
||||
import static com.intellij.ui.tree.project.ProjectFileListener.findArea;
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> implements InvokerSupplier {
|
||||
@@ -120,10 +121,6 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
return visible;
|
||||
}
|
||||
|
||||
private static boolean isExpectedModule(@Nullable Module module, @NotNull VirtualFile file, @NotNull Project project) {
|
||||
return file.isValid() && !project.isDisposed() && module == ProjectFileIndex.getInstance(project).getModuleForFile(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Module[] getModules(@NotNull Project project) {
|
||||
ModuleManager manager = ModuleManager.getInstance(project);
|
||||
@@ -145,6 +142,15 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
});
|
||||
}
|
||||
|
||||
public void setShowModules(boolean showModules) {
|
||||
onValidThread(() -> {
|
||||
if (root.showModules == showModules) return;
|
||||
root.showModules = showModules;
|
||||
root.valid = false; // need to reload content roots
|
||||
pathChanged(null);
|
||||
});
|
||||
}
|
||||
|
||||
private void pathChanged(@Nullable TreePath path) {
|
||||
onValidThread(() -> treeStructureChanged(path, null, null));
|
||||
}
|
||||
@@ -211,6 +217,7 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
|
||||
private static class ProjectNode extends Node<RootNode> {
|
||||
volatile VirtualFileFilter filter;
|
||||
volatile boolean showModules;
|
||||
final Project project;
|
||||
|
||||
ProjectNode(@NotNull Project project) {
|
||||
@@ -227,15 +234,27 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
List<RootNode> getChildren(@NotNull List<RootNode> oldList) {
|
||||
List<RootNode> list = new SmartList<>();
|
||||
Mapper<RootNode> mapper = new Mapper<>(oldList, RootNode::new);
|
||||
TreeCollector<VirtualFile> collector = showModules ? null : TreeCollector.createFileRootsCollector();
|
||||
VirtualFile ancestor = project.getBaseDir();
|
||||
if (ancestor != null && isExpectedModule(null, ancestor, project)) {
|
||||
list.add(mapper.apply(ancestor, project));
|
||||
if (ancestor != null && project == findArea(ancestor, project)) {
|
||||
if (collector != null) {
|
||||
collector.add(ancestor);
|
||||
}
|
||||
else {
|
||||
list.add(mapper.apply(ancestor, project));
|
||||
}
|
||||
}
|
||||
for (Module module: getModules(project)) {
|
||||
for (VirtualFile file: getContentRoots(module)) {
|
||||
list.add(mapper.apply(file, module));
|
||||
if (collector != null) {
|
||||
collector.add(file);
|
||||
}
|
||||
else {
|
||||
list.add(mapper.apply(file, module));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (collector != null) collector.get().forEach(file -> list.add(mapper.apply(file, file)));
|
||||
// invalidate all changed file nodes without notifications
|
||||
list.forEach(node -> node.invalidateNow(null));
|
||||
return list;
|
||||
@@ -276,6 +295,9 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
VirtualFile file = getVirtualFile();
|
||||
if (!file.isValid()) return emptyList();
|
||||
|
||||
ProjectNode parent = findParent(ProjectNode.class);
|
||||
if (parent == null) return emptyList();
|
||||
|
||||
visibility = ThreeState.UNSURE;
|
||||
|
||||
VirtualFile[] children = file.getChildren();
|
||||
@@ -288,20 +310,10 @@ public final class ProjectFileTreeModel extends BaseTreeModel<ProjectFileNode> i
|
||||
continue; // ignore invalid symlink
|
||||
}
|
||||
Object id = getRootID();
|
||||
if (id instanceof VirtualFile) {
|
||||
AreaInstance area = findArea(child, parent.project);
|
||||
if (area != null && (id instanceof VirtualFile || area.equals(id))) {
|
||||
list.add(mapper.apply(child, id));
|
||||
}
|
||||
else if (id instanceof Project) {
|
||||
if (isExpectedModule(null, child, (Project)id)) {
|
||||
list.add(mapper.apply(child, id));
|
||||
}
|
||||
}
|
||||
else if (id instanceof Module) {
|
||||
Module module = (Module)id;
|
||||
if (!module.isDisposed() && isExpectedModule(module, child, module.getProject())) {
|
||||
list.add(mapper.apply(child, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user