vcs: Refactored "ChangesTreeList" (and inheritors) - used tree component with flat model (corresponding model with no hierarchy is provided by "buildTreeModel()" implementations) instead of separate list component for displaying data in flat mode

This commit is contained in:
Konstantin Kolosovsky
2016-03-29 16:25:27 +03:00
parent 0f7ed20fb0
commit 16ea48a76a
7 changed files with 54 additions and 375 deletions
@@ -16,6 +16,7 @@
package com.intellij.history.integration.ui.views;
import com.intellij.diff.DiffDialogHints;
import com.intellij.history.core.LocalHistoryFacade;
import com.intellij.history.core.revisions.Difference;
import com.intellij.history.integration.IdeaGateway;
@@ -25,7 +26,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.diff.DiffDialogHints;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction;
import com.intellij.openapi.vcs.changes.actions.diff.ShowDiffContext;
@@ -141,7 +141,7 @@ public class DirectoryHistoryDialog extends HistoryDialog<DirectoryHistoryDialog
return new ChangesTreeList<Change>(myProject, Collections.<Change>emptyList(), false, false, null, null) {
@Override
protected DefaultTreeModel buildTreeModel(List<Change> cc, ChangeNodeDecorator changeNodeDecorator) {
return new TreeModelBuilder(myProject, false).buildModel(cc, changeNodeDecorator);
return new TreeModelBuilder(myProject, isShowFlatten()).buildModel(cc, changeNodeDecorator);
}
@Override
@@ -49,7 +49,7 @@ public class MoveChangesDialog extends DialogWrapper {
@Override
protected DefaultTreeModel buildTreeModel(List<Change> changes, ChangeNodeDecorator changeNodeDecorator) {
TreeModelBuilder builder = new TreeModelBuilder(project, false);
TreeModelBuilder builder = new TreeModelBuilder(project, isShowFlatten());
return builder.buildModel(new ArrayList<ChangeList>(changeLists));
}
@@ -507,7 +507,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
@Override
protected DefaultTreeModel buildTreeModel(List<AbstractFilePatchInProgress.PatchChange> changes,
ChangeNodeDecorator changeNodeDecorator) {
TreeModelBuilder builder = new TreeModelBuilder(myProject, false);
TreeModelBuilder builder = new TreeModelBuilder(myProject, isShowFlatten());
return builder.buildModel(ObjectsConvertor.convert(changes,
new Convertor<AbstractFilePatchInProgress.PatchChange, Change>() {
public Change convert(AbstractFilePatchInProgress.PatchChange o) {
@@ -90,7 +90,7 @@ public class ChangesBrowser extends JPanel implements TypeSafeDataProvider {
myViewer = new ChangesTreeList<Change>(myProject, changes, capableOfExcludingChanges, highlightProblems, inclusionListener, decorator) {
protected DefaultTreeModel buildTreeModel(final List<Change> changes, ChangeNodeDecorator changeNodeDecorator) {
TreeModelBuilder builder = new TreeModelBuilder(myProject, false);
TreeModelBuilder builder = new TreeModelBuilder(myProject, isShowFlatten());
return builder.buildModel(changes, changeNodeDecorator);
}
@@ -22,12 +22,10 @@ import com.intellij.ide.util.treeView.TreeState;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
@@ -36,24 +34,19 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.ui.treeStructure.actions.CollapseAllAction;
import com.intellij.ui.treeStructure.actions.ExpandAllAction;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import gnu.trove.THashSet;
import gnu.trove.TIntArrayList;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -61,13 +54,10 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
import java.util.*;
import java.util.List;
@@ -77,9 +67,7 @@ import java.util.List;
*/
public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataProvider {
private final Tree myTree;
private final JBList myList;
private final JScrollPane myTreeScrollPane;
private final JScrollPane myListScrollPane;
protected final Project myProject;
private final boolean myShowCheckboxes;
private final boolean myHighlightProblems;
@@ -89,10 +77,10 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
@NotNull private Runnable myDoubleClickHandler = EmptyRunnable.getInstance();
private boolean myAlwaysExpandList;
@NonNls private static final String TREE_CARD = "Tree";
@NonNls private static final String LIST_CARD = "List";
@NotNull private final TreeCellRenderer myNodeRenderer;
@NotNull private final TreeCellRenderer myShowFlattenNodeRenderer;
@NonNls private static final String ROOT = "root";
private final CardLayout myCards;
@NonNls private final static String FLATTEN_OPTION_KEY = "ChangesBrowser.SHOW_FLATTEN";
@@ -100,7 +88,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
@Nullable private ChangeNodeDecorator myChangeDecorator;
private Runnable myGenericSelectionListener;
@NotNull private final CopyProvider myTreeCopyProvider;
@NotNull private final ChangesBrowserNodeListCopyProvider myListCopyProvider;
public ChangesTreeList(@NotNull final Project project,
@NotNull Collection<T> initiallyIncluded,
@@ -115,10 +102,10 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
myChangeDecorator = decorator;
myIncludedChanges = new HashSet<T>(initiallyIncluded);
myAlwaysExpandList = true;
myNodeRenderer = new MyTreeCellRenderer(new ChangesBrowserNodeRenderer(myProject, false, myHighlightProblems));
myShowFlattenNodeRenderer = new MyTreeCellRenderer(new ChangesBrowserNodeRenderer(myProject, true, myHighlightProblems));
myCards = new CardLayout();
setLayout(myCards);
setLayout(new BorderLayout());
final int checkboxWidth = new JCheckBox().getPreferredSize().width;
myTree = new MyTree(project, checkboxWidth);
@@ -126,7 +113,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
myTree.setRootVisible(false);
myTree.setShowsRootHandles(true);
myTree.setOpaque(false);
myTree.setCellRenderer(new MyTreeCellRenderer());
new TreeSpeedSearch(myTree, new Convertor<TreePath, String>() {
@Override
public String convert(TreePath o) {
@@ -135,23 +121,7 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
});
myList = new JBList(new DefaultListModel());
myList.setVisibleRowCount(10);
add(myListScrollPane = ScrollPaneFactory.createScrollPane(myList), LIST_CARD);
add(myTreeScrollPane = ScrollPaneFactory.createScrollPane(myTree), TREE_CARD);
new ListSpeedSearch(myList) {
@Override
protected String getElementText(Object element) {
if (element instanceof Change) {
return ChangesUtil.getFilePath((Change)element).getName();
}
return super.getElementText(element);
}
};
myList.setCellRenderer(new MyListCellRenderer());
add(myTreeScrollPane = ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER);
new MyToggleSelectionAction().registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), this);
if (myShowCheckboxes) {
@@ -198,29 +168,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
});
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
if (!myList.isEnabled()) return false;
final int idx = myList.locationToIndex(e.getPoint());
if (idx >= 0) {
if (myShowCheckboxes) {
final Rectangle baseRect = myList.getCellBounds(idx, idx);
baseRect.setSize(checkboxWidth, baseRect.height);
if (baseRect.contains(e.getPoint())) {
toggleSelection();
return true;
}
}
if (clickCount == 2) {
myDoubleClickHandler.run();
return true;
}
}
return false;
}
}.installOn(myList);
new DoubleClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent e) {
@@ -249,23 +196,14 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
setEmptyText(emptyText);
myTreeCopyProvider = new ChangesBrowserNodeCopyProvider(myTree);
myListCopyProvider = new ChangesBrowserNodeListCopyProvider(myProject, myList);
}
public void setEmptyText(@NotNull String emptyText) {
myTree.getEmptyText().setText(emptyText);
myList.getEmptyText().setText(emptyText);
}
// generic, both for tree and list
public void addSelectionListener(final Runnable runnable) {
myGenericSelectionListener = runnable;
myList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
myGenericSelectionListener.run();
}
});
myTree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
@@ -283,12 +221,11 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
public void installPopupHandler(ActionGroup group) {
PopupHandler.installUnknownPopupHandler(myList, group, ActionManager.getInstance());
PopupHandler.installUnknownPopupHandler(myTree, group, ActionManager.getInstance());
}
public JComponent getPreferredFocusedComponent() {
return myShowFlatten ? myList : myTree;
return myTree;
}
@Override
@@ -301,34 +238,21 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
public void setScrollPaneBorder(Border border) {
myListScrollPane.setBorder(border);
myTreeScrollPane.setBorder(border);
}
public void setShowFlatten(final boolean showFlatten) {
final List<T> wasSelected = getSelectedChanges();
myShowFlatten = showFlatten;
myCards.show(this, myShowFlatten ? LIST_CARD : TREE_CARD);
setChangesToDisplay(getChanges());
myTree.setCellRenderer(myShowFlatten ? myShowFlattenNodeRenderer : myNodeRenderer);
select(wasSelected);
if (myList.hasFocus() || myTree.hasFocus()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
requestFocus();
}
});
}
}
@Override
public void requestFocus() {
if (myShowFlatten) {
myList.requestFocus();
}
else {
myTree.requestFocus();
}
myTree.requestFocus();
}
public void setChangesToDisplay(final List<T> changes) {
@@ -336,48 +260,15 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
public void setChangesToDisplay(final List<T> changes, @Nullable final VirtualFile toSelect) {
final boolean wasEmpty = myList.isEmpty();
final List<T> sortedChanges = new ArrayList<T>(changes);
Collections.sort(sortedChanges, new Comparator<T>() {
@Override
public int compare(final T o1, final T o2) {
return TreeModelBuilder.getPathForObject(o1).getName().compareToIgnoreCase(TreeModelBuilder.getPathForObject(o2).getName());
}
});
@SuppressWarnings("deprecation")
final Set<Object> wasSelected = new THashSet<Object>(Arrays.asList(myList.getSelectedValues()));
//noinspection unchecked
myList.setModel(new AbstractListModel() {
@Override
public int getSize() {
return sortedChanges.size();
}
@Override
public Object getElementAt(int index) {
return sortedChanges.get(index);
}
});
final DefaultTreeModel model = buildTreeModel(changes, myChangeDecorator);
TreeState state = null;
if (! myAlwaysExpandList && ! wasEmpty) {
state = TreeState.createOn(myTree, (DefaultMutableTreeNode) myTree.getModel().getRoot());
if (!myAlwaysExpandList) {
state = TreeState.createOn(myTree, (DefaultMutableTreeNode)myTree.getModel().getRoot());
}
myTree.setModel(model);
if (! myAlwaysExpandList && ! wasEmpty) {
if (!myAlwaysExpandList) {
//noinspection ConstantConditions
state.applyTo(myTree, (DefaultMutableTreeNode) myTree.getModel().getRoot());
final TIntArrayList indices = new TIntArrayList();
for (int i = 0; i < sortedChanges.size(); i++) {
T t = sortedChanges.get(i);
if (wasSelected.contains(t)) {
indices.add(i);
}
}
myList.setSelectedIndices(indices.toNativeArray());
state.applyTo(myTree, (DefaultMutableTreeNode)myTree.getModel().getRoot());
return;
}
@@ -387,19 +278,10 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
if (myProject.isDisposed()) return;
TreeUtil.expandAll(myTree);
int selectedListRow = 0;
int selectedTreeRow = -1;
if (myShowCheckboxes) {
if (myIncludedChanges.size() > 0) {
for (int i = 0; i < sortedChanges.size(); i++) {
T t = sortedChanges.get(i);
if (myIncludedChanges.contains(t)) {
selectedListRow = i;
break;
}
}
ChangesBrowserNode root = (ChangesBrowserNode)model.getRoot();
Enumeration enumeration = root.depthFirstEnumeration();
@@ -429,17 +311,10 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
if (rowInTree > -1) {
selectedTreeRow = rowInTree;
}
int rowInList = findRowContainingFile(myList.getModel(), toSelect);
if (rowInList > -1) {
selectedListRow = rowInList;
}
}
}
if (changes.size() > 0) {
myList.setSelectedIndex(selectedListRow);
myList.ensureIndexIsVisible(selectedListRow);
if (changes.size() > 0) {
if (selectedTreeRow >= 0) {
myTree.setSelectionRow(selectedTreeRow);
}
@@ -454,16 +329,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
}
private static int findRowContainingFile(@NotNull ListModel listModel, @NotNull final VirtualFile toSelect) {
for (int i = 0; i < listModel.getSize(); i++) {
Object item = listModel.getElementAt(i);
if (item instanceof Change && matches((Change)item, toSelect)) {
return i;
}
}
return -1;
}
private int findRowContainingFile(@NotNull TreeNode root, @NotNull final VirtualFile toSelect) {
final Ref<Integer> row = Ref.create(-1);
TreeUtil.traverse(root, new TreeUtil.Traverse() {
@@ -504,57 +369,34 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
public List<T> getChanges() {
if (myShowFlatten) {
ListModel m = myList.getModel();
int size = m.getSize();
List<T> result = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
//noinspection unchecked
result.add((T)m.getElementAt(i));
}
return result;
}
else {
final LinkedHashSet<T> result = new LinkedHashSet<T>();
TreeUtil.traverseDepth((ChangesBrowserNode)myTree.getModel().getRoot(), new TreeUtil.Traverse() {
@Override
public boolean accept(Object node) {
ChangesBrowserNode changeNode = (ChangesBrowserNode)node;
if (changeNode.isLeaf()) {
//noinspection unchecked
result.addAll(changeNode.getAllChangesUnder());
}
return true;
final LinkedHashSet<T> result = new LinkedHashSet<T>();
TreeUtil.traverseDepth((ChangesBrowserNode)myTree.getModel().getRoot(), new TreeUtil.Traverse() {
@Override
public boolean accept(Object node) {
ChangesBrowserNode changeNode = (ChangesBrowserNode)node;
if (changeNode.isLeaf()) {
//noinspection unchecked
result.addAll(changeNode.getAllChangesUnder());
}
});
return new ArrayList<T>(result);
}
return true;
}
});
return new ArrayList<T>(result);
}
@NotNull
public List<T> getSelectedChanges() {
if (myShowFlatten) {
final List<T> changes = new ArrayList<T>();
//noinspection deprecation
for (Object anO : myList.getSelectedValues()) {
//noinspection unchecked
changes.add((T)anO);
}
return changes;
final TreePath[] paths = myTree.getSelectionPaths();
if (paths == null) {
return Collections.emptyList();
}
else {
final TreePath[] paths = myTree.getSelectionPaths();
if (paths == null) {
return Collections.emptyList();
}
else {
LinkedHashSet<T> changes = ContainerUtil.newLinkedHashSet();
for (TreePath path : paths) {
//noinspection unchecked
changes.addAll(getSelectedObjects((ChangesBrowserNode)path.getLastPathComponent()));
}
return ContainerUtil.newArrayList(changes);
LinkedHashSet<T> changes = ContainerUtil.newLinkedHashSet();
for (TreePath path : paths) {
//noinspection unchecked
changes.addAll(getSelectedObjects((ChangesBrowserNode)path.getLastPathComponent()));
}
return ContainerUtil.newArrayList(changes);
}
}
@@ -572,36 +414,19 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
@Nullable
public T getHighestLeadSelection() {
if (myShowFlatten) {
final int index = myList.getLeadSelectionIndex();
ListModel listModel = myList.getModel();
if (index < 0 || index >= listModel.getSize()) return null;
//noinspection unchecked
return (T)listModel.getElementAt(index);
}
else {
final TreePath path = myTree.getSelectionPath();
if (path == null) {
return null;
}
//noinspection unchecked
return getLeadSelectedObject((ChangesBrowserNode<T>)path.getLastPathComponent());
final TreePath path = myTree.getSelectionPath();
if (path == null) {
return null;
}
//noinspection unchecked
return getLeadSelectedObject((ChangesBrowserNode<T>)path.getLastPathComponent());
}
@Nullable
public T getLeadSelection() {
if (myShowFlatten) {
final int index = myList.getLeadSelectionIndex();
ListModel listModel = myList.getModel();
//noinspection unchecked
return index < 0 || index >= listModel.getSize() ? null : (T)listModel.getElementAt(index);
}
else {
final TreePath path = myTree.getSelectionPath();
//noinspection unchecked
return path == null ? null : ContainerUtil.getFirstItem(getSelectedObjects(((ChangesBrowserNode<T>)path.getLastPathComponent())));
}
final TreePath path = myTree.getSelectionPath();
//noinspection unchecked
return path == null ? null : ContainerUtil.getFirstItem(getSelectedObjects(((ChangesBrowserNode<T>)path.getLastPathComponent())));
}
private void notifyInclusionListener() {
@@ -615,35 +440,30 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
myIncludedChanges.clear();
myIncludedChanges.addAll(changes);
myTree.repaint();
myList.repaint();
}
public void includeChange(final T change) {
myIncludedChanges.add(change);
notifyInclusionListener();
myTree.repaint();
myList.repaint();
}
public void includeChanges(final Collection<T> changes) {
myIncludedChanges.addAll(changes);
notifyInclusionListener();
myTree.repaint();
myList.repaint();
}
public void excludeChange(final T change) {
myIncludedChanges.remove(change);
notifyInclusionListener();
myTree.repaint();
myList.repaint();
}
public void excludeChanges(final Collection<T> changes) {
myIncludedChanges.removeAll(changes);
notifyInclusionListener();
myTree.repaint();
myList.repaint();
}
private void toggleChanges(final Collection<T> changes) {
@@ -703,7 +523,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
}
public void setSelectionMode(@JdkConstants.ListSelectionMode int mode) {
myList.setSelectionMode(mode);
myTree.getSelectionModel().setSelectionMode(getTreeSelectionModeFromListSelectionMode(mode));
}
@@ -722,10 +541,10 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
private final JCheckBox myCheckBox;
public MyTreeCellRenderer() {
public MyTreeCellRenderer(@NotNull ChangesBrowserNodeRenderer textRenderer) {
super(new BorderLayout());
myCheckBox = new JCheckBox();
myTextRenderer = new ChangesBrowserNodeRenderer(myProject, false, myHighlightProblems);
myTextRenderer = textRenderer;
if (myShowCheckboxes) {
add(myCheckBox, BorderLayout.WEST);
@@ -790,89 +609,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
return CheckboxTree.NodeState.CLEAR;
}
private class MyListCellRenderer extends JPanel implements ListCellRenderer {
private final ColoredListCellRenderer myTextRenderer;
public final JCheckBox myCheckbox;
public MyListCellRenderer() {
super(new BorderLayout());
myCheckbox = new JCheckBox();
myTextRenderer = new VirtualFileListCellRenderer(myProject) {
@Override
protected void putParentPath(Object value, FilePath path, FilePath self) {
super.putParentPath(value, path, self);
final boolean applyChangeDecorator = (value instanceof Change) && myChangeDecorator != null;
if (applyChangeDecorator) {
myChangeDecorator.decorate((Change) value, this, isShowFlatten());
}
}
@Override
protected void putParentPathImpl(Object value, String parentPath, FilePath self) {
final boolean applyChangeDecorator = (value instanceof Change) && myChangeDecorator != null;
List<Pair<String,ChangeNodeDecorator.Stress>> parts = null;
if (applyChangeDecorator) {
parts = myChangeDecorator.stressPartsOfFileName((Change)value, parentPath);
}
if (parts == null) {
super.putParentPathImpl(value, parentPath, self);
return;
}
for (Pair<String, ChangeNodeDecorator.Stress> part : parts) {
append(part.getFirst(), part.getSecond().derive(SimpleTextAttributes.GRAYED_ATTRIBUTES));
}
}
@Override
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean selected,
boolean hasFocus) {
final Component component = super.getListCellRendererComponent(list, value, index, selected, hasFocus);
final FileColorManager colorManager = FileColorManager.getInstance(myProject);
if (!selected) {
if (Registry.is("file.colors.in.commit.dialog") && colorManager.isEnabled() && colorManager.isEnabledForProjectView()) {
if (value instanceof Change) {
final VirtualFile file = ((Change)value).getVirtualFile();
if (file != null) {
final Color color = colorManager.getFileColor(file);
if (color != null) {
component.setBackground(color);
}
}
}
}
}
return component;
}
};
myCheckbox.setBackground(null);
setBackground(null);
if (myShowCheckboxes) {
add(myCheckbox, BorderLayout.WEST);
}
add(myTextRenderer, BorderLayout.CENTER);
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
myTextRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (myShowCheckboxes) {
//noinspection SuspiciousMethodCalls
myCheckbox.setSelected(myIncludedChanges.contains(value));
myCheckbox.setEnabled(list.isEnabled());
return this;
}
else {
return myTextRenderer;
}
}
}
private class MyToggleSelectionAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -916,30 +652,6 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
});
myTree.setSelectionPaths(treeSelection.toArray(new TreePath[treeSelection.size()]));
if (treeSelection.size() == 1) myTree.scrollPathToVisible(treeSelection.get(0));
// list
final ListModel model = myList.getModel();
final int size = model.getSize();
final List<Integer> listSelection = new ArrayList<Integer>(changes.size());
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
final T el = (T) model.getElementAt(i);
if (changes.contains(el)) {
listSelection.add(i);
}
}
myList.setSelectedIndices(int2int(listSelection));
if (listSelection.size() == 1) myList.ensureIndexIsVisible(listSelection.get(0));
}
private static int[] int2int(List<Integer> treeSelection) {
final int[] toPass = new int[treeSelection.size()];
int i = 0;
for (Integer integer : treeSelection) {
toPass[i] = integer;
++ i;
}
return toPass;
}
public void setAlwaysExpandList(boolean alwaysExpandList) {
@@ -948,13 +660,12 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
public void setPaintBusy(final boolean value) {
myTree.setPaintBusy(value);
myList.setPaintBusy(value);
}
@Override
public void calcData(DataKey key, DataSink sink) {
if (PlatformDataKeys.COPY_PROVIDER == key) {
sink.put(PlatformDataKeys.COPY_PROVIDER, myShowFlatten ? myListCopyProvider : myTreeCopyProvider);
sink.put(PlatformDataKeys.COPY_PROVIDER, myTreeCopyProvider);
}
}
@@ -1033,36 +744,4 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
ChangesTreeList.this.calcData(key, sink);
}
}
private static class ChangesBrowserNodeListCopyProvider implements CopyProvider {
@NotNull private final Project myProject;
@NotNull private final JList myList;
ChangesBrowserNodeListCopyProvider(@NotNull Project project, @NotNull JList list) {
myProject = project;
myList = list;
}
@Override
public void performCopy(@NotNull DataContext dataContext) {
CopyPasteManager.getInstance().setContents(new StringSelection(StringUtil.join(myList.getSelectedValues(),
new Function<Object, String>() {
@Override
public String fun(Object object) {
return ChangesBrowserNode.create(myProject, object).getTextPresentation();
}
}, "\n")));
}
@Override
public boolean isCopyEnabled(@NotNull DataContext dataContext) {
return !myList.isSelectionEmpty();
}
@Override
public boolean isCopyVisible(@NotNull DataContext dataContext) {
return true;
}
}
}
@@ -32,7 +32,7 @@ public class FilePathChangesTreeList extends ChangesTreeList<FilePath> {
}
protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
return new TreeModelBuilder(myProject, false).buildModelFromFilePaths(changes);
return new TreeModelBuilder(myProject, isShowFlatten()).buildModelFromFilePaths(changes);
}
protected List<FilePath> getSelectedObjects(final ChangesBrowserNode<FilePath> node) {
@@ -116,7 +116,7 @@ public class SelectFilesDialog extends AbstractSelectFilesDialog<VirtualFile> {
}
protected DefaultTreeModel buildTreeModel(final List<VirtualFile> changes, ChangeNodeDecorator changeNodeDecorator) {
return new TreeModelBuilder(myProject, false).buildModelFromFiles(changes);
return new TreeModelBuilder(myProject, isShowFlatten()).buildModelFromFiles(changes);
}
protected List<VirtualFile> getSelectedObjects(final ChangesBrowserNode node) {