blob: b230162ce68fc582a0848b9557df5dfcaac23412 [file] [log] [blame]
/*
* Copyright 2000-2012 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 git4idea.update;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.PanelWithActionsAndCloseButton;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.annotate.ShowAllAffectedGenericAction;
import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ContentsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.vcsUtil.VcsUtil;
import git4idea.GitFileRevision;
import git4idea.rebase.GitRebaseUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
/**
* The panel that displays list of skipped commits during update
*/
public class GitSkippedCommits extends PanelWithActionsAndCloseButton {
/**
* The current project
*/
private final Project myProject;
/**
* Tree control
*/
private final Tree myTree;
/**
* Get center component
*/
private JBScrollPane myCenterComponent;
/**
* The constructor
*
* @param contentManager content manager
* @param project the context project
* @param skippedCommits the map with skipped commits
*/
public GitSkippedCommits(@NotNull ContentManager contentManager,
Project project, SortedMap<VirtualFile, List<GitRebaseUtils.CommitInfo>> skippedCommits) {
super(contentManager, null);
myProject = project;
DefaultMutableTreeNode treeRoot = new DefaultMutableTreeNode("ROOT", true);
for (Map.Entry<VirtualFile, List<GitRebaseUtils.CommitInfo>> e : skippedCommits.entrySet()) {
DefaultMutableTreeNode vcsRoot = new DefaultMutableTreeNode(new VcsRoot(e.getKey()));
int missed = 0;
for (GitRebaseUtils.CommitInfo c : e.getValue()) {
if (c != null) {
vcsRoot.add(new DefaultMutableTreeNode(new Commit(e.getKey(), c)));
}
else {
missed++;
}
}
treeRoot.add(vcsRoot);
if (missed > 0) {
vcsRoot.add(new DefaultMutableTreeNode("The " + missed + " commit(s) were not parsed due to unsupported rebase directory format"));
}
}
myTree = new Tree(treeRoot);
myTree.setCellRenderer(createTreeCellRenderer());
myTree.setRootVisible(false);
myCenterComponent = new JBScrollPane(myTree);
init();
TreeUtil.expandAll(myTree);
}
/**
* @return new cell renderer
*/
private DefaultTreeCellRenderer createTreeCellRenderer() {
return new DefaultTreeCellRenderer() {
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
Component r = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
hasFocus);
Object o = value instanceof DefaultMutableTreeNode ? ((DefaultMutableTreeNode)value).getUserObject() : null;
if (o instanceof VcsRoot) {
r.setFont(tree.getFont().deriveFont(Font.BOLD));
r.setForeground(sel ? textSelectionColor : textNonSelectionColor);
}
else if (o instanceof String) {
r.setForeground(sel ? textSelectionColor : JBColor.RED);
r.setFont(tree.getFont());
}
else {
r.setForeground(sel ? textSelectionColor : textNonSelectionColor);
r.setFont(tree.getFont());
}
return r;
}
};
}
@Override
protected JComponent createCenterPanel() {
return myCenterComponent;
}
@Override
protected void addActionsTo(DefaultActionGroup group) {
super.addActionsTo(group);
ShowAllAffectedGenericAction showCommit = ShowAllAffectedGenericAction.getInstance();
showCommit.registerCustomShortcutSet(new CustomShortcutSet(
CommonShortcuts.DOUBLE_CLICK_1.getShortcuts()[0]), myTree);
group.addAction(showCommit);
}
@Override
public Object getData(String dataId) {
if (CommonDataKeys.PROJECT.is(dataId)) {
return myProject;
}
TreePath selectionPath = myTree.getSelectionPath();
DefaultMutableTreeNode node = selectionPath == null ? null : (DefaultMutableTreeNode)selectionPath.getLastPathComponent();
Object o = node == null ? null : node.getUserObject();
if (o instanceof Commit) {
Commit c = (Commit)o;
if (VcsDataKeys.VCS_VIRTUAL_FILE.is(dataId)) {
return c.root;
}
if (VcsDataKeys.VCS_FILE_REVISION.is(dataId)) {
return new GitFileRevision(myProject, VcsUtil.getFilePath(c.root.getPath()), c.commitInfo.revision);
}
}
return super.getData(dataId);
}
/**
* Show skipped commits
*
* @param project the context project
* @param skippedCommits the skipped commits
*/
public static void showSkipped(final Project project, final SortedMap<VirtualFile, List<GitRebaseUtils.CommitInfo>> skippedCommits) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(project).getContentManager();
if (contentManager == null) {
return;
}
GitSkippedCommits skipped = new GitSkippedCommits(contentManager, project, skippedCommits);
Content content = ContentFactory.SERVICE.getInstance().createContent(skipped, "Skipped Commits", true);
ContentsUtil.addContent(contentManager, content, true);
ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS).activate(null);
}
});
}
/**
* Wrapper for vcs root
*/
private static class VcsRoot {
final VirtualFile root;
public VcsRoot(VirtualFile root) {
this.root = root;
}
@Override
public String toString() {
return root.getPath();
}
}
/**
* Wrapper for commit
*/
private static class Commit {
final VirtualFile root;
final GitRebaseUtils.CommitInfo commitInfo;
public Commit(VirtualFile root, GitRebaseUtils.CommitInfo commitInfo) {
this.root = root;
this.commitInfo = commitInfo;
}
@Override
public String toString() {
return commitInfo.revision.asString().substring(0, 8) + ": " + commitInfo.subject;
}
}
}