vcs: move specific tree building logic into diff navigation popup

This commit is contained in:
Aleksey Pivovarov
2018-12-17 15:43:55 +03:00
parent cab1947abc
commit e687da4fb5
4 changed files with 73 additions and 99 deletions
@@ -8,6 +8,7 @@ import com.intellij.diff.chains.DiffRequestProducer;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.changes.actions.diff.ChangeGoToChangePopupAction;
@@ -19,9 +20,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.DefaultTreeModel;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import static com.intellij.util.containers.ContainerUtil.sorted;
import static java.util.Comparator.comparing;
public class ChangeDiffRequestChain extends DiffRequestChainBase implements GoToChangePopupBuilder.Chain {
private static final Logger LOG = Logger.getInstance(ChangeDiffRequestChain.class);
@NotNull private final List<? extends Producer> myProducers;
@@ -57,7 +62,7 @@ public class ChangeDiffRequestChain extends DiffRequestChainBase implements GoTo
@NotNull
@Override
protected DefaultTreeModel buildTreeModel(@NotNull Project project, @NotNull ChangesGroupingPolicyFactory grouping) {
MultiMap<Object, TreeModelBuilder.GenericNodeData> groups = new MultiMap<>();
MultiMap<Object, GenericChangesBrowserNode> groups = new MultiMap<>();
List<? extends DiffRequestProducer> producers = chain.getRequests();
for (int i = 0; i < producers.size(); i++) {
Producer producer = ObjectUtils.tryCast(producers.get(i), Producer.class);
@@ -66,10 +71,10 @@ public class ChangeDiffRequestChain extends DiffRequestChainBase implements GoTo
FilePath filePath = producer.getFilePath();
FileStatus fileStatus = producer.getFileStatus();
Object tag = producer.getPopupTag();
groups.putValue(tag, new TreeModelBuilder.GenericNodeData(filePath, fileStatus, i));
groups.putValue(tag, new GenericChangesBrowserNode(filePath, fileStatus, i));
}
TreeModelBuilder builder = new TreeModelBuilder(project, grouping);
MyTreeModelBuilder builder = new MyTreeModelBuilder(project, grouping);
for (Object tag : groups.keySet()) {
builder.setGenericNodes(groups.get(tag), tag);
}
@@ -95,4 +100,69 @@ public class ChangeDiffRequestChain extends DiffRequestChainBase implements GoTo
return null;
}
}
private static class MyTreeModelBuilder extends TreeModelBuilder {
MyTreeModelBuilder(@NotNull Project project, @NotNull ChangesGroupingPolicyFactory grouping) {
super(project, grouping);
}
public void setGenericNodes(@NotNull Collection<GenericChangesBrowserNode> nodes, @Nullable Object tag) {
ChangesBrowserNode<?> parentNode = createTagNode(tag);
for (GenericChangesBrowserNode node : sorted(nodes, comparing(data -> data.myFilePath, PATH_COMPARATOR))) {
insertChangeNode(node.myFilePath, parentNode, node);
}
}
}
private static class GenericChangesBrowserNode extends ChangesBrowserNode<Object> implements Comparable<GenericChangesBrowserNode> {
@NotNull private final FilePath myFilePath;
@NotNull private final FileStatus myFileStatus;
protected GenericChangesBrowserNode(@NotNull FilePath filePath, @NotNull FileStatus fileStatus, @NotNull Object userObject) {
super(userObject);
myFilePath = filePath;
myFileStatus = fileStatus;
}
@Override
protected boolean isFile() {
return !isDirectory();
}
@Override
protected boolean isDirectory() {
return myFilePath.isDirectory();
}
@Override
public void render(@NotNull ChangesBrowserNodeRenderer renderer, boolean selected, boolean expanded, boolean hasFocus) {
renderer.appendFileName(myFilePath.getVirtualFile(), myFilePath.getName(), myFileStatus.getColor());
if (renderer.isShowFlatten()) {
appendParentPath(renderer, myFilePath.getParentPath());
}
if (!renderer.isShowFlatten() && getFileCount() != 1 || getDirectoryCount() != 0) {
appendCount(renderer);
}
renderer.setIcon(myFilePath.getFileType(), myFilePath.isDirectory() || !isLeaf());
}
@Override
public String getTextPresentation() {
return myFilePath.getName();
}
@Override
public String toString() {
return FileUtil.toSystemDependentName(myFilePath.getPath());
}
@Override
public int compareTo(@NotNull GenericChangesBrowserNode o) {
return myFilePath.getPath().compareToIgnoreCase(o.myFilePath.getPath());
}
}
}
@@ -1,68 +0,0 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes.ui;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import org.jetbrains.annotations.NotNull;
public class ChangesBrowserGenericNode extends ChangesBrowserNode<Object> implements Comparable<ChangesBrowserGenericNode> {
@NotNull private final FilePath myFilePath;
@NotNull private final FileStatus myFileStatus;
protected ChangesBrowserGenericNode(@NotNull FilePath filePath, @NotNull FileStatus fileStatus, @NotNull Object userObject) {
super(userObject);
myFilePath = filePath;
myFileStatus = fileStatus;
}
@Override
protected boolean isFile() {
return !isDirectory();
}
@Override
protected boolean isDirectory() {
return myFilePath.isDirectory();
}
@Override
public void render(@NotNull ChangesBrowserNodeRenderer renderer, boolean selected, boolean expanded, boolean hasFocus) {
renderer.appendFileName(myFilePath.getVirtualFile(), myFilePath.getName(), myFileStatus.getColor());
if (renderer.isShowFlatten()) {
appendParentPath(renderer, myFilePath.getParentPath());
}
if (!renderer.isShowFlatten() && getFileCount() != 1 || getDirectoryCount() != 0) {
appendCount(renderer);
}
renderer.setIcon(myFilePath.getFileType(), myFilePath.isDirectory() || !isLeaf());
}
public String getTooltip() {
return null;
}
@Override
public String getTextPresentation() {
return myFilePath.getName();
}
@Override
public String toString() {
return FileUtil.toSystemDependentName(myFilePath.getPath());
}
@Override
public int getSortWeight() {
return GENERIC_FILE_PATH_SORT_WEIGHT;
}
@Override
public int compareTo(@NotNull ChangesBrowserGenericNode o) {
return myFilePath.getPath().compareToIgnoreCase(o.myFilePath.getPath());
}
}
@@ -7,7 +7,6 @@ import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListOwner;
@@ -50,7 +49,6 @@ public class ChangesBrowserNode<T> extends DefaultMutableTreeNode implements Use
protected static final int REPOSITORY_SORT_WEIGHT = 3;
protected static final int DIRECTORY_PATH_SORT_WEIGHT = 4;
protected static final int FILE_PATH_SORT_WEIGHT = 5;
protected static final int GENERIC_FILE_PATH_SORT_WEIGHT = 6;
protected static final int CHANGE_SORT_WEIGHT = 7;
protected static final int VIRTUAL_FILE_SORT_WEIGHT = 8;
protected static final int UNVERSIONED_SORT_WEIGHT = 9;
@@ -109,11 +107,6 @@ public class ChangesBrowserNode<T> extends DefaultMutableTreeNode implements Use
return new ChangesBrowserLocallyDeletedNode(change);
}
@NotNull
public static ChangesBrowserNode createGeneric(@NotNull FilePath filePath, @NotNull FileStatus fileStatus, @NotNull Object userObject) {
return new ChangesBrowserGenericNode(filePath, fileStatus, userObject);
}
@NotNull
public static ChangesBrowserNode createObject(@NotNull Object userObject) {
return new ChangesBrowserNode<>(userObject);
@@ -296,15 +296,6 @@ public class TreeModelBuilder {
return this;
}
public void setGenericNodes(@NotNull Collection<GenericNodeData> nodesData, @Nullable Object tag) {
ChangesBrowserNode<?> parentNode = createTagNode(tag);
for (GenericNodeData data : sorted(nodesData, comparing(data -> data.myFilePath, PATH_COMPARATOR))) {
ChangesBrowserNode node = ChangesBrowserNode.createGeneric(data.myFilePath, data.myStatus, data.myUserData);
insertChangeNode(data.myFilePath, parentNode, node);
}
}
@NotNull
public TreeModelBuilder setSwitchedRoots(@Nullable Map<VirtualFile, String> switchedRoots) {
if (ContainerUtil.isEmpty(switchedRoots)) return this;
@@ -525,16 +516,4 @@ public class TreeModelBuilder {
public DefaultTreeModel buildModel(@NotNull List<Change> changes, @Nullable ChangeNodeDecorator changeNodeDecorator) {
return setChanges(changes, changeNodeDecorator).build();
}
public static class GenericNodeData {
@NotNull private final FilePath myFilePath;
@NotNull private final FileStatus myStatus;
@NotNull private final Object myUserData;
public GenericNodeData(@NotNull FilePath filePath, @NotNull FileStatus status, @NotNull Object userData) {
myFilePath = filePath;
myStatus = status;
myUserData = userData;
}
}
}