mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[log] Group branches in the filter and on the BranchesPanel
Introduce so called expandable groups: * reference in them are displayed inline. * in the filter component they are prefixed with a text separator indicating the group. * on branches panel they are expanded and displayed as separate refs. GitRefManager: * group local branches into expanded group; * group tracked remote branches into expanded group; * group other remote branches into separate groups by the name of remote. BranchesPanel: * draw expanded groups inline. * for true-groups draw the name of the group as if it is a reference. * clicking on the group shows a popup with the list of references. * clicking on the reference navigates to the commit, in the same way as it is done for single-references. Existing problem: multiple-root branches with same names (both on the panel and in the filter).
This commit is contained in:
@@ -2,16 +2,22 @@ package com.intellij.vcs.log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Lets group {@link VcsRef references} to show them accordingly in the UI, for example on the branches panel.
|
||||
* Grouping decision is made by the concrete {@link VcsLogRefManager}.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public interface RefGroup {
|
||||
|
||||
/**
|
||||
* If a group is not-expanded, its references won't be displayed until
|
||||
* Otherwise, if a group is expanded, its references will be displayed immediately,
|
||||
* but they may possibly be somehow visually united to indicated that they are from similar structure.
|
||||
*/
|
||||
boolean isExpanded();
|
||||
|
||||
/**
|
||||
* Returns the name of the reference group. This reference will be displayed on the branches panel.
|
||||
*/
|
||||
@@ -24,4 +30,10 @@ public interface RefGroup {
|
||||
@NotNull
|
||||
List<VcsRef> getRefs();
|
||||
|
||||
/**
|
||||
* Returns the background color of this ref group, which will be used to paint it on the Branches panel.
|
||||
*/
|
||||
@NotNull
|
||||
Color getBgColor();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.vcs.log.impl;
|
||||
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link RefGroup} containing only one {@link VcsRef}.
|
||||
*/
|
||||
public class SingletonRefGroup implements RefGroup {
|
||||
private final VcsRef myRef;
|
||||
|
||||
public SingletonRefGroup(VcsRef ref) {
|
||||
myRef = ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpanded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return myRef.getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<VcsRef> getRefs() {
|
||||
return Collections.singletonList(myRef);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Color getBgColor() {
|
||||
return myRef.getType().getBackgroundColor();
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class VcsLogUI {
|
||||
|
||||
@NotNull private final VcsLogDataHolder myLogDataHolder;
|
||||
@NotNull private final MainFrame myMainFrame;
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final VcsLogColorManager myColorManager;
|
||||
@NotNull private final VcsLogUiProperties myUiProperties;
|
||||
@NotNull private final VcsLogFilterer myFilterer;
|
||||
@@ -47,6 +48,7 @@ public class VcsLogUI {
|
||||
public VcsLogUI(@NotNull VcsLogDataHolder logDataHolder, @NotNull Project project, @NotNull VcsLogSettings settings,
|
||||
@NotNull VcsLogColorManager manager, @NotNull VcsLogUiProperties uiProperties) {
|
||||
myLogDataHolder = logDataHolder;
|
||||
myProject = project;
|
||||
myColorManager = manager;
|
||||
myUiProperties = uiProperties;
|
||||
myFilterer = new VcsLogFilterer(logDataHolder, this);
|
||||
@@ -215,4 +217,9 @@ public class VcsLogUI {
|
||||
public VcsLogUiProperties getUiProperties() {
|
||||
return myUiProperties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
}
|
||||
|
||||
+35
-17
@@ -16,19 +16,18 @@
|
||||
package com.intellij.vcs.log.ui.filter;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.actionSystem.Separator;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
import com.intellij.vcs.log.VcsLogProvider;
|
||||
import com.intellij.vcs.log.VcsLogRefManager;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.data.VcsLogBranchFilter;
|
||||
import com.intellij.vcs.log.VcsLogFilter;
|
||||
import com.intellij.vcs.log.impl.VcsLogUtil;
|
||||
import com.intellij.vcs.log.ui.VcsLogUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -56,22 +55,41 @@ class BranchFilterPopupComponent extends FilterPopupComponent {
|
||||
VcsLogRefManager refManager = provider.getReferenceManager();
|
||||
List<RefGroup> groups = refManager.group(refs);
|
||||
|
||||
for (RefGroup group : groups) {
|
||||
if (group.getRefs().size() == 1) {
|
||||
actionGroup.add(new SetValueAction(group.getRefs().iterator().next().getName(), this));
|
||||
}
|
||||
else {
|
||||
DefaultActionGroup innerGroup = new DefaultActionGroup();
|
||||
for (VcsRef ref : group.getRefs()) {
|
||||
innerGroup.add(new SetValueAction(ref.getName(), this));
|
||||
}
|
||||
actionGroup.add(innerGroup);
|
||||
}
|
||||
}
|
||||
List<AnAction> orderedGroups = orderRefGroups(groups);
|
||||
actionGroup.addAll(orderedGroups);
|
||||
}
|
||||
return actionGroup;
|
||||
}
|
||||
|
||||
private List<AnAction> orderRefGroups(List<RefGroup> groups) {
|
||||
DefaultActionGroup singletonGroup = new DefaultActionGroup();
|
||||
DefaultActionGroup expandedGroup = new DefaultActionGroup();
|
||||
DefaultActionGroup collapsedGroup = new DefaultActionGroup();
|
||||
|
||||
for (RefGroup group : groups) {
|
||||
if (group.getRefs().size() == 1) {
|
||||
singletonGroup.add(new SetValueAction(group.getRefs().iterator().next().getName(), this));
|
||||
}
|
||||
else if (group.isExpanded()) {
|
||||
expandedGroup.addSeparator(group.getName());
|
||||
expandedGroup.add(createActionGroup(group, false));
|
||||
}
|
||||
else {
|
||||
collapsedGroup.add(createActionGroup(group, true));
|
||||
}
|
||||
}
|
||||
|
||||
return Arrays.asList(singletonGroup, expandedGroup, Separator.getInstance(), collapsedGroup);
|
||||
}
|
||||
|
||||
private DefaultActionGroup createActionGroup(RefGroup group, boolean popup) {
|
||||
DefaultActionGroup innerGroup = new DefaultActionGroup(group.getName(), popup);
|
||||
for (VcsRef ref : group.getRefs()) {
|
||||
innerGroup.add(new SetValueAction(ref.getName(), this));
|
||||
}
|
||||
return innerGroup;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VcsLogFilter getFilter() {
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
package com.intellij.vcs.log.ui.frame;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ListUtil;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
import com.intellij.vcs.log.VcsLogProvider;
|
||||
import com.intellij.vcs.log.VcsLogRefManager;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.data.VcsLogDataHolder;
|
||||
import com.intellij.vcs.log.graph.render.PrintParameters;
|
||||
import com.intellij.vcs.log.impl.SingletonRefGroup;
|
||||
import com.intellij.vcs.log.impl.VcsLogUtil;
|
||||
import com.intellij.vcs.log.ui.VcsLogUI;
|
||||
import com.intellij.vcs.log.ui.render.RefPainter;
|
||||
@@ -17,48 +25,60 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.vcs.log.graph.render.PrintParameters.HEIGHT_CELL;
|
||||
|
||||
/**
|
||||
* Panel with branch labels, above the graph.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class BranchesPanel extends JPanel {
|
||||
|
||||
private final VcsLogDataHolder myDataHolder;
|
||||
private final VcsLogUI myUI;
|
||||
|
||||
private List<VcsRef> myRefs;
|
||||
private List<RefGroup> myRefGroups;
|
||||
private final RefPainter myRefPainter;
|
||||
|
||||
private Map<Integer, VcsRef> myRefPositions = new HashMap<Integer, VcsRef>();
|
||||
private Map<Integer, RefGroup> myRefPositions = ContainerUtil.newHashMap();
|
||||
|
||||
public BranchesPanel(@NotNull VcsLogDataHolder dataHolder, @NotNull VcsLogUI UI) {
|
||||
myDataHolder = dataHolder;
|
||||
myUI = UI;
|
||||
myRefs = getRefsToDisplayOnPanel();
|
||||
myRefGroups = getRefsToDisplayOnPanel();
|
||||
myRefPainter = new RefPainter(myUI.getColorManager(), true);
|
||||
|
||||
setPreferredSize(new Dimension(-1, PrintParameters.HEIGHT_CELL + UIUtil.DEFAULT_VGAP));
|
||||
setPreferredSize(new Dimension(-1, HEIGHT_CELL + UIUtil.DEFAULT_VGAP));
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
VcsRef ref = findRef(e);
|
||||
if (ref != null) {
|
||||
final RefGroup group = findRef(e);
|
||||
if (group == null) {
|
||||
return;
|
||||
}
|
||||
if (group.getRefs().size() == 1) {
|
||||
VcsRef ref = group.getRefs().iterator().next();
|
||||
myUI.jumpToCommit(ref.getCommitHash());
|
||||
}
|
||||
else {
|
||||
final RefPopupComponent view = new RefPopupComponent(group, myUI, myRefPainter);
|
||||
JBPopup popup = view.getPopup();
|
||||
popup.show(new RelativePoint(BranchesPanel.this, new Point(e.getX(), BranchesPanel.this.getHeight())));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VcsRef findRef(MouseEvent e) {
|
||||
private RefGroup findRef(MouseEvent e) {
|
||||
List<Integer> sortedPositions = Ordering.natural().sortedCopy(myRefPositions.keySet());
|
||||
int index = Ordering.natural().binarySearch(sortedPositions, e.getX());
|
||||
if (index < 0) {
|
||||
@@ -72,35 +92,190 @@ public class BranchesPanel extends JPanel {
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
myRefPositions = myRefPainter.draw((Graphics2D)g, myRefs, 0, getWidth());
|
||||
myRefPositions = ContainerUtil.newHashMap();
|
||||
int paddingX = 0;
|
||||
for (RefGroup group : myRefGroups) {
|
||||
Rectangle rectangle = myRefPainter.drawLabel((Graphics2D)g, group.getName(), paddingX, group.getBgColor());
|
||||
paddingX += rectangle.width + UIUtil.DEFAULT_HGAP;
|
||||
myRefPositions.put(rectangle.x, group);
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild() {
|
||||
myRefs = getRefsToDisplayOnPanel();
|
||||
myRefGroups = getRefsToDisplayOnPanel();
|
||||
getParent().repaint();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<VcsRef> getRefsToDisplayOnPanel() {
|
||||
private List<RefGroup> getRefsToDisplayOnPanel() {
|
||||
Collection<VcsRef> allRefs = myDataHolder.getDataPack().getRefsModel().getBranches();
|
||||
|
||||
List<VcsRef> refsToShow = new ArrayList<VcsRef>();
|
||||
List<RefGroup> groups = ContainerUtil.newArrayList();
|
||||
for (Map.Entry<VirtualFile, Collection<VcsRef>> entry : VcsLogUtil.groupRefsByRoot(allRefs).entrySet()) {
|
||||
VirtualFile root = entry.getKey();
|
||||
Collection<VcsRef> refs = entry.getValue();
|
||||
VcsLogProvider provider = myDataHolder.getLogProvider(root);
|
||||
VcsLogRefManager refManager = provider.getReferenceManager();
|
||||
List<RefGroup> groups = refManager.group(refs);
|
||||
groups.addAll(expandExpandableGroups(refManager.group(refs)));
|
||||
}
|
||||
|
||||
// TODO draw groups
|
||||
for (RefGroup group : groups) {
|
||||
if (group.getRefs().size() == 1) {
|
||||
refsToShow.add(group.getRefs().iterator().next());
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
private static Collection<RefGroup> expandExpandableGroups(List<RefGroup> refGroups) {
|
||||
Collection<RefGroup> groups = ContainerUtil.newArrayList();
|
||||
for (RefGroup group : refGroups) {
|
||||
if (group.isExpanded()) {
|
||||
groups.addAll(ContainerUtil.map(group.getRefs(), new Function<VcsRef, RefGroup>() {
|
||||
@Override
|
||||
public RefGroup fun(VcsRef ref) {
|
||||
return new SingletonRefGroup(ref);
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
// TODO improve UI for multiple roots case
|
||||
return refsToShow;
|
||||
return groups;
|
||||
}
|
||||
|
||||
private static class RefPopupComponent extends JPanel {
|
||||
|
||||
private final JBPopup myPopup;
|
||||
private final JBList myList;
|
||||
private final VcsLogUI myUi;
|
||||
private final RefPainter myRefPainter;
|
||||
|
||||
private final SingleRefComponent myRendererComponent;
|
||||
|
||||
private final ListCellRenderer myCellRenderer;
|
||||
|
||||
RefPopupComponent(RefGroup group, VcsLogUI ui, RefPainter refPainter) {
|
||||
super(new BorderLayout());
|
||||
myUi = ui;
|
||||
myRefPainter = refPainter;
|
||||
|
||||
myRendererComponent = new SingleRefComponent(myRefPainter);
|
||||
myCellRenderer = new ListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
myRendererComponent.setRef((VcsRef)value);
|
||||
myRendererComponent.setSelected(isSelected);
|
||||
return myRendererComponent;
|
||||
}
|
||||
};
|
||||
|
||||
myList = createList(group);
|
||||
myPopup = createPopup();
|
||||
add(new JBScrollPane(myList));
|
||||
}
|
||||
|
||||
private JBList createList(RefGroup group) {
|
||||
JBList list = new JBList(createListModel(group));
|
||||
list.setCellRenderer(myCellRenderer);
|
||||
ListUtil.installAutoSelectOnMouseMove(list);
|
||||
list.setSelectedIndex(0);
|
||||
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
jumpOnMouseClick(list);
|
||||
jumpOnEnter(list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private void jumpOnMouseClick(JBList list) {
|
||||
list.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
jumpToSelectedRef();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void jumpOnEnter(JBList list) {
|
||||
list.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
jumpToSelectedRef();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JBPopup createPopup() {
|
||||
return JBPopupFactory.getInstance().
|
||||
createComponentPopupBuilder(this, myList).
|
||||
setCancelOnClickOutside(true).
|
||||
setCancelOnWindowDeactivation(true).
|
||||
setFocusable(true).
|
||||
setRequestFocus(true).
|
||||
setResizable(true).
|
||||
setDimensionServiceKey(myUi.getProject(), "Vcs.Log.Branch.Panel.RefGroup.Popup", false).
|
||||
createPopup();
|
||||
}
|
||||
|
||||
private static DefaultListModel createListModel(RefGroup group) {
|
||||
DefaultListModel model = new DefaultListModel();
|
||||
for (final VcsRef vcsRef : group.getRefs()) {
|
||||
model.addElement(vcsRef);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JBPopup getPopup() {
|
||||
return myPopup;
|
||||
}
|
||||
|
||||
private void jumpToSelectedRef() {
|
||||
VcsRef selectedRef = (VcsRef)myList.getSelectedValue();
|
||||
if (selectedRef != null) {
|
||||
myUi.jumpToCommit(selectedRef.getCommitHash());
|
||||
myPopup.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SingleRefComponent extends JPanel {
|
||||
|
||||
private final RefPainter myRefPainter;
|
||||
|
||||
private VcsRef myRef;
|
||||
public boolean mySelected;
|
||||
|
||||
public SingleRefComponent(RefPainter refPainter) {
|
||||
myRefPainter = refPainter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.setColor(mySelected ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
if (myRef != null) {
|
||||
myRefPainter.draw((Graphics2D)g, Collections.singletonList(myRef), 0, calcWidth());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(calcWidth(), HEIGHT_CELL);
|
||||
}
|
||||
|
||||
private int calcWidth() {
|
||||
FontMetrics metrics = getFontMetrics(getFont());
|
||||
return metrics.stringWidth(myRef.getName());
|
||||
}
|
||||
|
||||
public void setRef(@NotNull VcsRef ref) {
|
||||
myRef = ref;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
mySelected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,15 +4,22 @@ import com.intellij.dvcs.repo.RepositoryManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
import com.intellij.vcs.log.VcsLogRefManager;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.VcsRefType;
|
||||
import com.intellij.vcs.log.impl.SingletonRefGroup;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.GitLocalBranch;
|
||||
import git4idea.GitRemoteBranch;
|
||||
import git4idea.branch.GitBranchesCollection;
|
||||
import git4idea.repo.GitBranchTrackInfo;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
@@ -124,27 +131,76 @@ public class GitRefManager implements VcsLogRefManager {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<RefGroup> group(Collection<VcsRef> refs) {
|
||||
// TODO group non-tracking refs into remotes
|
||||
return ContainerUtil.map(sort(refs), new Function<VcsRef, RefGroup>() {
|
||||
@Override
|
||||
public RefGroup fun(final VcsRef ref) {
|
||||
return new RefGroup() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return ref.getName();
|
||||
}
|
||||
List<RefGroup> simpleGroups = ContainerUtil.newArrayList();
|
||||
List<VcsRef> localBranches = ContainerUtil.newArrayList();
|
||||
List<VcsRef> trackedBranches = ContainerUtil.newArrayList();
|
||||
MultiMap<GitRemote, VcsRef> remoteRefGroups = MultiMap.create();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<VcsRef> getRefs() {
|
||||
return Collections.singletonList(ref);
|
||||
for (VcsRef ref : refs) {
|
||||
if (ref.getType() == HEAD) {
|
||||
simpleGroups.add(new SingletonRefGroup(ref));
|
||||
}
|
||||
else {
|
||||
GitRepository repository = myRepositoryManager.getRepositoryForRoot(ref.getRoot());
|
||||
if (repository == null) {
|
||||
LOG.warn("No repository for root: " + ref.getRoot());
|
||||
continue;
|
||||
}
|
||||
Collection<GitBranchTrackInfo> trackInfos = repository.getBranchTrackInfos();
|
||||
GitBranchesCollection branches = repository.getBranches();
|
||||
|
||||
GitLocalBranch localBranch = findBranchByName(ref, branches.getLocalBranches());
|
||||
if (localBranch != null) {
|
||||
localBranches.add(ref);
|
||||
}
|
||||
else {
|
||||
GitRemoteBranch remoteBranch = findBranchByName(ref, branches.getRemoteBranches());
|
||||
if (remoteBranch != null) {
|
||||
if (isTracked(trackInfos, remoteBranch)) {
|
||||
trackedBranches.add(ref);
|
||||
}
|
||||
else {
|
||||
remoteRefGroups.putValue(remoteBranch.getRemote(), ref);
|
||||
}
|
||||
}
|
||||
};
|
||||
else {
|
||||
LOG.warn("Didn't find ref neither in local nor in remote branches: " + ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<RefGroup> result = ContainerUtil.newArrayList();
|
||||
result.addAll(simpleGroups);
|
||||
result.add(new LogicalRefGroup("Local", localBranches));
|
||||
result.add(new LogicalRefGroup("Tracked", trackedBranches));
|
||||
for (Map.Entry<GitRemote, Collection<VcsRef>> entry : remoteRefGroups.entrySet()) {
|
||||
final GitRemote remote = entry.getKey();
|
||||
final Collection<VcsRef> branches = entry.getValue();
|
||||
result.add(new RemoteRefGroup(remote, branches));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T extends GitBranch> T findBranchByName(final VcsRef ref, Collection<T> branches) {
|
||||
return ContainerUtil.find(branches, new Condition<T>() {
|
||||
@Override
|
||||
public boolean value(T branch) {
|
||||
return branch.getName().equals(ref.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isTracked(Collection<GitBranchTrackInfo> trackInfos, final GitRemoteBranch remoteBranch) {
|
||||
return ContainerUtil.find(trackInfos, new Condition<GitBranchTrackInfo>() {
|
||||
@Override
|
||||
public boolean value(GitBranchTrackInfo info) {
|
||||
return info.getRemoteBranch().equals(remoteBranch);
|
||||
}
|
||||
}) != null;
|
||||
}
|
||||
|
||||
private static class SimpleRefType implements VcsRefType {
|
||||
private final boolean myIsBranch;
|
||||
@NotNull private final Color myColor;
|
||||
@@ -166,4 +222,70 @@ public class GitRefManager implements VcsLogRefManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static class LogicalRefGroup implements RefGroup {
|
||||
private final String myGroupName;
|
||||
private final List<VcsRef> myRefs;
|
||||
|
||||
private LogicalRefGroup(String groupName, List<VcsRef> refs) {
|
||||
myGroupName = groupName;
|
||||
myRefs = refs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpanded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return myGroupName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<VcsRef> getRefs() {
|
||||
return myRefs;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Color getBgColor() {
|
||||
return HEAD_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
private class RemoteRefGroup implements RefGroup {
|
||||
private final GitRemote myRemote;
|
||||
private final Collection<VcsRef> myBranches;
|
||||
|
||||
public RemoteRefGroup(GitRemote remote, Collection<VcsRef> branches) {
|
||||
myRemote = remote;
|
||||
myBranches = branches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpanded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return myRemote.getName() + "/...";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<VcsRef> getRefs() {
|
||||
return sort(myBranches);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Color getBgColor() {
|
||||
return REMOTE_BRANCH_COLOR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user