VCS: show diff from annotate, not completed jet, but usable

This commit is contained in:
irengrig
2010-08-09 19:24:54 +04:00
parent 11a955317b
commit 4f4cfd42a4
21 changed files with 402 additions and 114 deletions
@@ -65,7 +65,7 @@ public interface TextAnnotationGutterProvider {
/***
* enables annotation view modifications
*/
List<AnAction> getPopupActions(final Editor editor);
List<AnAction> getPopupActions(final int line, final Editor editor);
/**
* Called when the annotations are removed from the editor gutter.
@@ -1176,8 +1176,12 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
DefaultActionGroup actionGroup = new DefaultActionGroup(EditorBundle.message("editor.annotations.action.group.name"), true);
actionGroup.add(new CloseAnnotationsAction());
final List<AnAction> addActions = new ArrayList<AnAction>();
final Point p = e.getPoint();
int line = myEditor.xyToLogicalPosition(new Point(0, (int)p.getY())).line;
if (line >= myEditor.getDocument().getLineCount()) return;
for (TextAnnotationGutterProvider gutterProvider : myTextAnnotationGutters) {
final List<AnAction> list = gutterProvider.getPopupActions(myEditor);
final List<AnAction> list = gutterProvider.getPopupActions(line, myEditor);
if (list != null) {
for (AnAction action : list) {
if (! addActions.contains(action)) {
@@ -72,7 +72,7 @@ public abstract class AbstractVcsHelper {
showErrors(Arrays.asList(e), s);
}
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file);
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs);
public abstract void showDifferences(final VcsFileRevision cvsVersionOn, final VcsFileRevision cvsVersionOn1, final File file);
@@ -19,6 +19,7 @@ package com.intellij.openapi.vcs;
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
@@ -55,4 +56,7 @@ public interface CommittedChangesProvider<T extends CommittedChangeList, U exten
* since may be different for different VCSs
*/
int getUnlimitedCountValue();
@Nullable
T getOneList(final RepositoryLocation location, final VcsRevisionNumber number) throws VcsException;
}
@@ -15,9 +15,7 @@
*/
package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.ColorKey;
@@ -36,23 +34,32 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.annotate.*;
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.actions.ShowDiffAction;
import com.intellij.openapi.vcs.changes.ui.ChangesComparator;
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.BackgroundableActionEnabledHandler;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vcs.impl.UpToDateLineNumberProviderImpl;
import com.intellij.openapi.vcs.impl.VcsBackgroundableActions;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
@@ -152,7 +159,7 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
final VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
if (project == null) return;
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(project);
AbstractVcs vcs = plVcsManager.getVcsFor(file);
final AbstractVcs vcs = plVcsManager.getVcsFor(file);
if (vcs == null) return;
final AnnotationProvider annotationProvider = vcs.getAnnotationProvider();
@@ -188,12 +195,16 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
}
if (fileAnnotationRef.isNull()) return;
doAnnotate(editor, project, file, fileAnnotationRef.get());
doAnnotate(editor, project, file, fileAnnotationRef.get(), vcs);
}
});
}
public static void doAnnotate(final Editor editor, final Project project, final VirtualFile file, final FileAnnotation fileAnnotation) {
public static void doAnnotate(final Editor editor,
final Project project,
final VirtualFile file,
final FileAnnotation fileAnnotation,
final AbstractVcs vcs) {
String upToDateContent = fileAnnotation.getAnnotatedContent();
final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(
@@ -214,7 +225,14 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
final HighlightAnnotationsActions highlighting = new HighlightAnnotationsActions(project, file, fileAnnotation, editorGutterComponentEx);
final List<AnnotationFieldGutter> gutters = new ArrayList<AnnotationFieldGutter>();
final AnnotationSourceSwitcher switcher = fileAnnotation.getAnnotationSourceSwitcher();
final MyAnnotationPresentation presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters);
final MyAnnotationPresentation presentation;
if (vcs.getCommittedChangesProvider() != null) {
final ShowDiffFromAnnotation showDiff = new ShowDiffFromAnnotation(getUpToDateLineNumber, fileAnnotation, vcs, file);
presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters, showDiff);
presentation.addLineNumberListener(showDiff);
} else {
presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters);
}
if (switcher != null) {
@@ -375,15 +393,25 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
private final List<AnnotationFieldGutter> myGutters;
private final List<AnAction> myActions;
private MySwitchAnnotationSourceAction mySwitchAction;
private final List<Consumer<Integer>> myPopupLineNumberListeners;
public MyAnnotationPresentation(@NotNull final HighlightAnnotationsActions highlighting, @Nullable final AnnotationSourceSwitcher switcher,
final EditorGutterComponentEx gutter,
List<AnnotationFieldGutter> gutters) {
final EditorGutterComponentEx gutter, final List<AnnotationFieldGutter> gutters, final AnAction... actions) {
myHighlighting = highlighting;
mySwitcher = switcher;
myGutters = gutters;
myPopupLineNumberListeners = new LinkedList<Consumer<Integer>>();
myActions = new ArrayList<AnAction>(myHighlighting.getList());
myActions = new ArrayList<AnAction>();
myActions.add(Separator.getInstance());
if (actions != null) {
final List<AnAction> actionsList = Arrays.<AnAction>asList(actions);
if (! actionsList.isEmpty()) {
myActions.addAll(actionsList);
myActions.add(new Separator());
}
}
myActions.addAll(myHighlighting.getList());
if (mySwitcher != null) {
mySwitchAction = new MySwitchAnnotationSourceAction(mySwitcher, gutter);
myActions.add(mySwitchAction);
@@ -391,6 +419,10 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
myActions.add(new ShowHideColorsAction(myGutters, gutter));
}
public void addLineNumberListener(final Consumer<Integer> listener) {
myPopupLineNumberListeners.add(listener);
}
public EditorFontType getFontType(final int line) {
return myHighlighting.isLineBold(line) ? EditorFontType.BOLD : EditorFontType.PLAIN;
}
@@ -400,7 +432,10 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
return mySwitcher.getAnnotationSource(line).getColor();
}
public List<AnAction> getActions() {
public List<AnAction> getActions(int line) {
for (Consumer<Integer> listener : myPopupLineNumberListeners) {
listener.consume(line);
}
return myActions;
}
@@ -443,4 +478,108 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
myGutter.revalidateMarkup();
}
}
private static class ShowDiffFromAnnotation extends AnAction implements Consumer<Integer> {
private final UpToDateLineNumberProvider myLineNumberProvider;
private final FileAnnotation myFileAnnotation;
private final AbstractVcs myVcs;
private final VirtualFile myFile;
private RepositoryLocation myLocationFor;
private int currentLine;
private ShowDiffFromAnnotation(final UpToDateLineNumberProvider lineNumberProvider,
final FileAnnotation fileAnnotation, final AbstractVcs vcs, final VirtualFile file) {
super(VcsBundle.message("updated.info.tree.show.diff.text"), VcsBundle.message("updated.info.tree.show.diff.text"), IconLoader.getIcon("/actions/diff.png"));
myLineNumberProvider = lineNumberProvider;
myFileAnnotation = fileAnnotation;
myVcs = vcs;
myFile = file;
final CommittedChangesProvider provider = myVcs.getCommittedChangesProvider();
final VirtualFile root = ProjectLevelVcsManager.getInstance(vcs.getProject()).getVcsRootFor(file);
myLocationFor = provider.getLocationFor(new FilePathImpl(root));
currentLine = -1;
}
@Override
public void consume(Integer integer) {
currentLine = integer;
}
@Override
public void update(AnActionEvent e) {
e.getPresentation().setVisible(getActualLineNumber(e) >= 0);
}
private int getActualLineNumber(final AnActionEvent e) {
final DataContext dc = e.getDataContext();
if (currentLine < 0) return -1;
return myLineNumberProvider.getLineNumber(currentLine);
}
@Override
public void actionPerformed(AnActionEvent e) {
final int actualNumber = getActualLineNumber(e);
if (actualNumber < 0) return;
final VcsRevisionNumber revisionNumber = myFileAnnotation.getLineRevisionNumber(actualNumber);
if (revisionNumber != null) {
final VcsException[] exc = new VcsException[1];
final List<Change> changes = new LinkedList<Change>();
ProgressManager.getInstance().run(new Task.Backgroundable(myVcs.getProject(),
"Loading revision " + revisionNumber.asString() + " contents", true, BackgroundFromStartOption.getInstance()) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final CommittedChangesProvider provider = myVcs.getCommittedChangesProvider();
try {
final CommittedChangeList cl = provider.getOneList(myLocationFor, revisionNumber);
if (cl == null) {
ChangesViewBalloonProblemNotifier.showMe(myVcs.getProject(), "Can not load data for show diff", MessageType.ERROR);
return;
}
changes.addAll(cl.getChanges());
Collections.sort(changes, ChangesComparator.getInstance());
}
catch (VcsException e1) {
exc[0] = e1;
}
}
@Override
public void onSuccess() {
if (exc[0] != null) {
ChangesViewBalloonProblemNotifier.showMe(myVcs.getProject(), "Can not show diff: " + exc[0].getMessage(), MessageType.ERROR);
} else if (! changes.isEmpty()) {
int idx = findSelfInList(changes);
ShowDiffAction.showDiffForChange(changes.toArray(new Change[changes.size()]), idx, myVcs.getProject());
}
}
});
}
}
private int findSelfInList(List<Change> changes) {
int idx = -1;
final File ioFile = new File(myFile.getPath());
for (int i = 0; i < changes.size(); i++) {
final Change change = changes.get(i);
if ((change.getAfterRevision() != null) && (change.getAfterRevision().getFile().getIOFile().equals(ioFile))) {
idx = i;
break;
}
}
if (idx >= 0) return idx;
idx = 0;
// try to use name only
final String name = ioFile.getName();
for (int i = 0; i < changes.size(); i++) {
final Change change = changes.get(i);
if ((change.getAfterRevision() != null) && (change.getAfterRevision().getFile().getName().equals(name))) {
idx = i;
break;
}
}
return idx;
}
}
}
@@ -99,8 +99,8 @@ class AnnotationFieldGutter implements ActiveAnnotationGutter {
return myPresentation.getColor(line);
}
public List<AnAction> getPopupActions(final Editor editor) {
return myPresentation.getActions();
public List<AnAction> getPopupActions(int line, final Editor editor) {
return myPresentation.getActions(line);
}
public void gutterClosed() {
@@ -68,8 +68,8 @@ public class AnnotationGutterLineConvertorProxy implements ActiveAnnotationGutte
return myDelegate.getBgColor(currentLine, editor);
}
public List<AnAction> getPopupActions(Editor editor) {
return myDelegate.getPopupActions(editor);
public List<AnAction> getPopupActions(int line, Editor editor) {
return myDelegate.getPopupActions(line, editor);
}
public void gutterClosed() {
@@ -1,51 +0,0 @@
/*
* Copyright 2000-2009 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.openapi.vcs.annotate;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
import com.intellij.openapi.vfs.VirtualFile;
public class Annotater {
private final Project myProject;
private final VirtualFile myVirtualFile;
private final FileAnnotation myFileAnnotation;
public Annotater(FileAnnotation fileAnnotation, Project project, VirtualFile virtualFile) {
myFileAnnotation = fileAnnotation;
myProject = project;
myVirtualFile = virtualFile;
}
public void showAnnotation() {
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, myVirtualFile);
Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(openFileDescriptor, true);
if (editor == null) {
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.open.editor", myVirtualFile.getPresentableUrl()),
VcsBundle.message("message.title.cannot.open.editor"), Messages.getInformationIcon());
return;
}
AnnotateToggleAction.doAnnotate(editor, myProject, myVirtualFile, myFileAnnotation);
}
}
@@ -18,10 +18,11 @@ package com.intellij.openapi.vcs.annotate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.editor.colors.ColorKey;
import com.intellij.openapi.editor.colors.EditorFontType;
import java.util.List;
public interface TextAnnotationPresentation {
EditorFontType getFontType(int line);
ColorKey getColor(int line);
List<AnAction> getActions();
List<AnAction> getActions(int line);
}
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes.committed;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsType;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
@@ -29,10 +30,10 @@ public class CommittedChangesVisibilityPredicate implements NotNullFunction<Proj
public Boolean fun(final Project project) {
final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
for(AbstractVcs vcs: abstractVcses) {
if (vcs.getCommittedChangesProvider() != null) {
if (vcs.getCommittedChangesProvider() != null && VcsType.centralized.equals(vcs.getType())) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
}
}
@@ -19,6 +19,7 @@ package com.intellij.openapi.vcs.changes.committed;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
@@ -151,6 +152,11 @@ public class CompositeCommittedChangesProvider implements CommittedChangesProvid
throw new UnsupportedOperationException();
}
@Override
public CommittedChangeList getOneList(RepositoryLocation location, VcsRevisionNumber number) {
throw new UnsupportedOperationException();
}
public static class CompositeChangeBrowserSettings extends ChangeBrowserSettings {
private final Map<AbstractVcs, ChangeBrowserSettings> myMap;
private final Set<AbstractVcs> myEnabledVcs = new HashSet<AbstractVcs>();
@@ -16,9 +16,10 @@
package com.intellij.openapi.vcs.changes.committed;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.CachingCommittedChangesProvider;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsType;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
@@ -30,7 +31,7 @@ public class IncomingChangesVisibilityPredicate implements NotNullFunction<Proje
public Boolean fun(final Project project) {
final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
for(AbstractVcs vcs: abstractVcses) {
if (vcs.getCommittedChangesProvider() instanceof CachingCommittedChangesProvider) {
if (vcs.getCommittedChangesProvider() instanceof CachingCommittedChangesProvider && VcsType.centralized.equals(vcs.getType())) {
return Boolean.TRUE;
}
}
@@ -111,7 +111,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
private String myOriginalComment = "";
private final DefaultActionGroup myPopupActions;
private final Project myProject;
private final AbstractVcs myVcs;
private final VcsHistoryProvider myProvider;
private final AnnotationProvider myAnnotationProvider;
private VcsHistorySession myHistorySession;
@@ -265,20 +265,20 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
private static final DateFormat DATE_FORMAT = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);
private final Map<VcsFileRevision, VirtualFile> myRevisionToVirtualFile = new HashMap<VcsFileRevision, VirtualFile>();
public FileHistoryPanelImpl(Project project,
FilePath filePath, final String repositoryPath, VcsHistorySession session,
public FileHistoryPanelImpl(AbstractVcs vcs,
FilePath filePath, VcsHistorySession session,
VcsHistoryProvider provider,
AnnotationProvider annotationProvider,
ContentManager contentManager, final Runnable refresher) {
super(contentManager, provider.getHelpId() != null ? provider.getHelpId() : "reference.versionControl.toolwindow.history");
myVcs = vcs;
myProvider = provider;
myAnnotationProvider = annotationProvider;
myProject = project;
myRefresher = refresher;
myHistorySession = session;
myFilePath = filePath;
COLUMNS = createColumnList(project, provider, session);
COLUMNS = createColumnList(myVcs.getProject(), provider, session);
myComments = new JEditorPane(UIUtil.HTML_MIME, "");
myComments.setPreferredSize(new Dimension(150, 100));
@@ -298,11 +298,11 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
@NonNls String storageKey = "FileHistory." + provider.getClass().getName();
if (treeHistoryProvider != null) {
myDualView = new DualView(new TreeNodeOnVcsRevision(null, treeHistoryProvider.createTreeOn(myHistorySession.getRevisionList())),
COLUMNS, storageKey, project);
COLUMNS, storageKey, myVcs.getProject());
}
else {
myDualView = new DualView(new TreeNodeOnVcsRevision(null, wrapWithTreeElements(myHistorySession.getRevisionList())), COLUMNS,
storageKey, project);
storageKey, myVcs.getProject());
myDualView.switchToTheFlatMode();
}
final TableLinkMouseListener listener = new TableLinkMouseListener();
@@ -330,7 +330,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
// todo react to event?
myUpdateAlarm.addRequest(new Runnable() {
public void run() {
if (myProject.isDisposed()) {
if (myVcs.getProject().isDisposed()) {
return;
}
final boolean refresh = (! myInRefresh) && myHistorySession.shouldBeRefreshed();
@@ -556,7 +556,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
revision = getFirstSelectedRevision();
final String message = revision.getCommitMessage();
myOriginalComment = message;
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(myProject, message);
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(myVcs.getProject(), message);
myComments.setText(text);
myComments.setCaretPosition(0);
}
@@ -584,7 +584,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
if (content2 == null) throw new VcsException("Failed to load content for revision " + right.getRevisionNumber().asString());
SimpleDiffRequest diffData = new SimpleDiffRequest(myProject, myFilePath.getPresentableUrl());
SimpleDiffRequest diffData = new SimpleDiffRequest(myVcs.getProject(), myFilePath.getPresentableUrl());
diffData.addHint(DiffTool.HINT_SHOW_FRAME);
@@ -693,7 +693,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
}
private VcsConfiguration getConfiguration() {
return VcsConfiguration.getInstance(myProject);
return VcsConfiguration.getInstance(myVcs.getProject());
}
private DefaultActionGroup createPopupActions() {
@@ -757,7 +757,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
}
private void refreshImpl() {
new AbstractCalledLater(myProject, ModalityState.NON_MODAL) {
new AbstractCalledLater(myVcs.getProject(), ModalityState.NON_MODAL) {
public void run() {
if (myInRefresh) return;
myInRefresh = true;
@@ -806,12 +806,12 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
int selectionSize = sel.size();
if (selectionSize > 1) {
showDifferences(myProject, sel.get(0), sel.get(sel.size() - 1));
showDifferences(myVcs.getProject(), sel.get(0), sel.get(sel.size() - 1));
}
else if (selectionSize == 1) {
final VcsRevisionNumber currentRevisionNumber = myHistorySession.getCurrentRevisionNumber();
if (currentRevisionNumber != null) {
showDifferences(myProject, getFirstSelectedRevision(), new CurrentRevision(myFilePath.getVirtualFile(), currentRevisionNumber));
showDifferences(myVcs.getProject(), getFirstSelectedRevision(), new CurrentRevision(myFilePath.getVirtualFile(), currentRevisionNumber));
}
}
}
@@ -880,7 +880,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
protected void actionPerformed() {
final VcsFileRevision revision = getFirstSelectedRevision();
if (getVirtualFile() != null) {
if (!new ReplaceFileConfirmationDialog(myProject, VcsBundle.message("acton.name.get.revision"))
if (!new ReplaceFileConfirmationDialog(myVcs.getProject(), VcsBundle.message("acton.name.get.revision"))
.confirmFor(new VirtualFile[]{getVirtualFile()})) {
return;
}
@@ -926,14 +926,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
};
}
if (refresh != null) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(refresh, "Refreshing files...", false, myProject);
ProgressManager.getInstance().runProcessWithProgressSynchronously(refresh, "Refreshing files...", false, myVcs.getProject());
}
}
private void getVersion(final VcsFileRevision revision) {
final VirtualFile file = getVirtualFile();
if ((file != null) && !file.isWritable()) {
if (ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(file).hasReadonlyFiles()) {
if (ReadonlyStatusHandler.getInstance(myVcs.getProject()).ensureFilesWritable(file).hasReadonlyFiles()) {
return;
}
}
@@ -961,7 +961,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
try {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
CommandProcessor.getInstance().executeCommand(myVcs.getProject(), new Runnable() {
public void run() {
try {
write(finalRevisionContent);
@@ -975,7 +975,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
}
});
if (file != null) {
VcsDirtyScopeManager.getInstance(myProject).fileDirty(file);
VcsDirtyScopeManager.getInstance(myVcs.getProject()).fileDirty(file);
}
}
finally {
@@ -1027,7 +1027,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
private void writeContentToDocument(final Document document, byte[] revisionContent) throws IOException {
final String content = StringUtil.convertLineSeparators(new String(revisionContent, myFilePath.getCharset().name()));
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
CommandProcessor.getInstance().executeCommand(myVcs.getProject(), new Runnable() {
public void run() {
document.replaceString(0, document.getTextLength(), content);
}
@@ -1053,7 +1053,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
boolean enabled = revision != null && revVFile != null && !fileType.isBinary();
if (enabled) {
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myProject);
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myVcs.getProject());
enabled &= (! (((ProjectLevelVcsManagerImpl) plVcsManager).getBackgroundableActionHandler(
VcsBackgroundableActions.ANNOTATE).isInProgress(key(revVFile, revision))));
}
@@ -1070,14 +1070,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE);
if ((revision == null) || (revisionVirtualFile == null)) return;
final BackgroundableActionEnabledHandler handler = ((ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myProject)).
final BackgroundableActionEnabledHandler handler = ((ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myVcs.getProject())).
getBackgroundableActionHandler(VcsBackgroundableActions.ANNOTATE);
handler.register(key(revisionVirtualFile, revision));
final Ref<FileAnnotation> fileAnnotationRef = new Ref<FileAnnotation>();
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, VcsBundle.message("retrieving.annotations"), true,
ProgressManager.getInstance().run(new Task.Backgroundable(myVcs.getProject(), VcsBundle.message("retrieving.annotations"), true,
BackgroundFromStartOption.getInstance()) {
public void run(@NotNull ProgressIndicator indicator) {
try {
@@ -1102,7 +1102,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
}
if (fileAnnotationRef.isNull()) return;
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), revisionVirtualFile);
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), revisionVirtualFile, myVcs);
}
});
}
@@ -1118,14 +1118,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
}
VirtualFile virtualFileForRevision = createVirtualFileForRevision(firstSelectedRevision);
if (virtualFileForRevision != null) {
return new OpenFileDescriptor(myProject, virtualFileForRevision);
return new OpenFileDescriptor(myVcs.getProject(), virtualFileForRevision);
}
else {
return null;
}
}
else if (PlatformDataKeys.PROJECT.is(dataId)) {
return myProject;
return myVcs.getProject();
}
else if (VcsDataKeys.VCS_FILE_REVISION.is(dataId)) {
return firstSelectedRevision;
@@ -27,7 +27,10 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -41,7 +44,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.annotate.Annotater;
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
@@ -160,7 +163,7 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
private FileHistoryPanelImpl ensureHistoryPanelCreated() {
if (myFileHistoryPanel == null) {
ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(myVcs.getProject()).getContentManager();
myFileHistoryPanel = new FileHistoryPanelImpl(myVcs.getProject(), myPath, myRepositoryPath, mySession, myVcsHistoryProvider,
myFileHistoryPanel = new FileHistoryPanelImpl(myVcs, myPath, mySession, myVcsHistoryProvider,
myAnnotationProvider, contentManager, myRefresher);
}
return myFileHistoryPanel;
@@ -436,8 +439,16 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
return exceptions;
}
public void showAnnotation(FileAnnotation annotation, VirtualFile file) {
new Annotater(annotation, myProject, file).showAnnotation();
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, file);
Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(openFileDescriptor, true);
if (editor == null) {
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.open.editor", file.getPresentableUrl()),
VcsBundle.message("message.title.cannot.open.editor"), Messages.getInformationIcon());
return;
}
AnnotateToggleAction.doAnnotate(editor, myProject, file, annotation, vcs);
}
public void showDifferences(final VcsFileRevision version1, final VcsFileRevision version2, final File file) {
@@ -130,6 +130,41 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
return 0;
}
@Nullable
@Override
public CvsChangeList getOneList(RepositoryLocation location, final VcsRevisionNumber number) throws VcsException {
CvsRepositoryLocation cvsLocation = (CvsRepositoryLocation) location;
final String module = cvsLocation.getModuleName();
final CvsEnvironment connectionSettings = cvsLocation.getEnvironment();
if (connectionSettings.isOffline()) {
return null;
}
final CvsChangeListsBuilder builder = new CvsChangeListsBuilder(module, connectionSettings, myProject, cvsLocation.getRootFile());
final CvsChangeList[] result = new CvsChangeList[1];
final CvsResult executionResult = runRLogOperation(connectionSettings, module, new Date(1000), null, new Consumer<LogInformationWrapper>() {
public void consume(LogInformationWrapper wrapper) {
if (result[0] != null) return;
final List<RevisionWrapper> wrappers = builder.revisionWrappersFromLog(wrapper);
if (wrappers != null) {
for (RevisionWrapper revisionWrapper : wrappers) {
if (Comparing.equal(revisionWrapper.getRevision().getNumber(), number.asString())) {
result[0] = builder.addRevision(revisionWrapper);
}
}
}
}
});
if (executionResult.isCanceled()) {
throw new ProcessCanceledException();
}
else if (! executionResult.hasNoErrors()) {
throw executionResult.composeError();
}
return result[0];
}
public List<CvsChangeList> getCommittedChanges(ChangeBrowserSettings settings, RepositoryLocation location, final int maxCount) throws VcsException {
CvsRepositoryLocation cvsLocation = (CvsRepositoryLocation) location;
return loadCommittedChanges(settings, cvsLocation.getModuleName(), cvsLocation.getEnvironment(), cvsLocation.getRootFile());
@@ -172,9 +172,10 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo
public void actionPerformed(AnActionEvent e) {
VcsVirtualFile vcsVirtualFile = (VcsVirtualFile)getCvsVirtualFile();
try {
final FileAnnotation annotation = CvsVcs2.getInstance(myProject)
final CvsVcs2 vcs = CvsVcs2.getInstance(myProject);
final FileAnnotation annotation = vcs
.createAnnotation(vcsVirtualFile, vcsVirtualFile.getRevision(), myCvsRootConfiguration);
AbstractVcsHelper.getInstance(myProject).showAnnotation(annotation, vcsVirtualFile);
AbstractVcsHelper.getInstance(myProject).showAnnotation(annotation, vcsVirtualFile, vcs);
}
catch (VcsException e1) {
AbstractVcsHelper.getInstance(myProject).showError(e1, CvsBundle.message("operation.name.annotate"));
@@ -171,7 +171,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
@Nullable
public VcsRevisionNumber calcCurrentRevisionNumber() {
return getCurrentRevision(myFilePath);
return myFilePath == null ? null : getCurrentRevision(myFilePath);
}
@Override
+1 -2
View File
@@ -338,8 +338,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
*/
@Override
public CommittedChangesProvider getCommittedChangesProvider() {
// TODO Temporary disabled: return myCommittedChangeListProvider;
return null;
return myCommittedChangeListProvider;
}
/**
@@ -49,7 +49,7 @@ import java.util.List;
/**
* The provider for committed change lists
*/
public class GitCommittedChangeListProvider implements CachingCommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> {
public class GitCommittedChangeListProvider implements CommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> {
/**
* the logger
*/
@@ -224,6 +224,29 @@ public class GitCommittedChangeListProvider implements CachingCommittedChangesPr
return -1;
}
@Override
public CommittedChangeList getOneList(RepositoryLocation location, final VcsRevisionNumber number) throws VcsException {
final GitRepositoryLocation l = (GitRepositoryLocation)location;
VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot());
if (root == null) {
throw new VcsException("The repository does not exists anymore: " + l.getRoot());
}
final CommittedChangeList[] result = new CommittedChangeList[1];
GitUtil.getLocalCommittedChanges(myProject, root, new Consumer<GitSimpleHandler>() {
public void consume(GitSimpleHandler h) {
h.addParameters("-n1");
h.addParameters(number.asString());
}
}, new Consumer<CommittedChangeList>() {
@Override
public void consume(CommittedChangeList committedChangeList) {
result[0] = committedChangeList;
}
}, false);
return result[0];
}
public int getFormatVersion() {
return 0;
}
@@ -268,4 +268,18 @@ public class HgCachingCommitedChangesProvider
public int getUnlimitedCountValue() {
return -1;
}
@Override
public CommittedChangeList getOneList(RepositoryLocation location, VcsRevisionNumber number) throws VcsException {
final ChangeBrowserSettings settings = createDefaultSettings();
settings.USE_CHANGE_AFTER_FILTER = true;
settings.USE_CHANGE_BEFORE_FILTER = true;
settings.CHANGE_AFTER = number.asString();
settings.CHANGE_BEFORE = number.asString();
final List<CommittedChangeList> list = getCommittedChanges(settings, location, 1);
if (list.size() == 1) {
return list.get(0);
}
return null;
}
}
@@ -39,17 +39,17 @@ import com.intellij.util.ThrowableConsumer;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnAuthenticationNotifier;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.actions.ConfigureBranchesAction;
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.DataInput;
import java.io.DataOutput;
@@ -490,6 +490,106 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
return 0;
}
@Override
public SvnChangeList getOneList(final RepositoryLocation location, VcsRevisionNumber number) throws VcsException {
final String url = ((SvnRepositoryLocation)location).getURL();
final long revision;
try {
revision = Long.parseLong(number.asString());
} catch (NumberFormatException e) {
throw new VcsException(e);
}
final SvnChangeList[] result = new SvnChangeList[1];
final SVNLogClient logger;
final SVNRevision revisionBefore;
final SVNURL repositoryUrl;
final SVNURL svnurl;
try {
logger = myVcs.createLogClient();
revisionBefore = SVNRevision.create(revision);
svnurl = SVNURL.parseURIEncoded(url);
final SVNWCClient client = myVcs.createWCClient();
SVNInfo info = client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
if (info == null) {
throw new VcsException("Can not get repository URL");
}
repositoryUrl = info.getRepositoryRootURL();
}
catch (SVNException e) {
throw new VcsException(e);
}
tryExactHit((SvnRepositoryLocation)location, result, logger, revisionBefore, repositoryUrl, svnurl);
if (result[0] == null) {
tryByRoot(result, logger, revisionBefore, repositoryUrl);
if (result[0] == null) {
tryStepByStep((SvnRepositoryLocation)location, result, logger, revisionBefore, repositoryUrl, svnurl);
}
}
return result[0];
}
private void tryByRoot(SvnChangeList[] result, SVNLogClient logger, SVNRevision revisionBefore, SVNURL repositoryUrl) throws VcsException {
final boolean authorized = SvnAuthenticationNotifier.passiveValidation(myProject, repositoryUrl);
if (! authorized) return;
tryExactHit(new SvnRepositoryLocation(repositoryUrl.toString()), result, logger, revisionBefore, repositoryUrl, repositoryUrl);
}
private void tryStepByStep(final SvnRepositoryLocation svnRepositoryLocation,
final SvnChangeList[] result,
SVNLogClient logger,
final SVNRevision revisionBefore, final SVNURL repositoryUrl, SVNURL svnurl) throws VcsException {
try {
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, revisionBefore,
false, true, true, 0, null,
new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) {
if (myProject.isDisposed()) throw new ProcessCanceledException();
if (logEntry.getDate() == null) {
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
return;
}
if (logEntry.getRevision() == revisionBefore.getNumber()) {
result[0] = new SvnChangeList(myVcs, svnRepositoryLocation, logEntry, repositoryUrl.toString());
}
}
});
}
catch (SVNException e) {
throw new VcsException(e);
}
}
private void tryExactHit(final SvnRepositoryLocation location,
final SvnChangeList[] result,
SVNLogClient logger,
SVNRevision revisionBefore,
final SVNURL repositoryUrl, SVNURL svnurl) throws VcsException {
try {
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, revisionBefore, revisionBefore,
false, true, false, 1, null,
new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) {
if (myProject.isDisposed()) throw new ProcessCanceledException();
if (logEntry.getDate() == null) {
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
return;
}
result[0] = new SvnChangeList(myVcs, (SvnRepositoryLocation) location, logEntry, repositoryUrl.toString());
}
});
}
catch (SVNException e) {
if (SVNErrorCode.FS_CATEGORY == e.getErrorMessage().getErrorCode().getCategory()) {
// pass to step by step looking for revision
return;
}
throw new VcsException(e);
}
}
public int getFormatVersion() {
return VERSION_WITH_REPLACED_PATHS;
}