mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-91843 vcs: allow to annotate non-local VirtualFiles
This commit is contained in:
@@ -65,6 +65,9 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann
|
||||
else if (AnnotateDiffViewerAction.isEnabled(e)) {
|
||||
enabled = !AnnotateDiffViewerAction.isSuspended(e);
|
||||
}
|
||||
else if (AnnotateVcsVirtualFileAction.isEnabled(e)) {
|
||||
enabled = !AnnotateVcsVirtualFileAction.isSuspended(e);
|
||||
}
|
||||
e.getPresentation().setEnabled(enabled);
|
||||
}
|
||||
|
||||
@@ -76,6 +79,9 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann
|
||||
else if (AnnotateDiffViewerAction.isEnabled(e)) {
|
||||
return AnnotateDiffViewerAction.isAnnotated(e);
|
||||
}
|
||||
else if (AnnotateVcsVirtualFileAction.isEnabled(e)) {
|
||||
return AnnotateVcsVirtualFileAction.isAnnotated(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -87,6 +93,9 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann
|
||||
else if (AnnotateDiffViewerAction.isEnabled(e)) {
|
||||
AnnotateDiffViewerAction.perform(e, selected);
|
||||
}
|
||||
else if (AnnotateVcsVirtualFileAction.isEnabled(e)) {
|
||||
AnnotateVcsVirtualFileAction.perform(e, selected);
|
||||
}
|
||||
}
|
||||
|
||||
public static void doAnnotate(@NotNull final Editor editor,
|
||||
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.vfs.ContentRevisionVirtualFile;
|
||||
import com.intellij.openapi.vcs.vfs.VcsVirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.AnnotationProviderEx;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotateVcsVirtualFileAction {
|
||||
private static final Logger LOG = Logger.getInstance(AnnotateVcsVirtualFileAction.class);
|
||||
|
||||
public static boolean isEnabled(AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
if (project == null || project.isDisposed()) return false;
|
||||
|
||||
VirtualFile[] selectedFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
|
||||
if (selectedFiles == null || selectedFiles.length != 1) return false;
|
||||
|
||||
VirtualFile file = selectedFiles[0];
|
||||
if (file.isDirectory() || file.getFileType().isBinary()) return false;
|
||||
|
||||
if (getEditors(project, file).isEmpty()) return false;
|
||||
|
||||
AnnotationData data = extractData(project, file);
|
||||
if (data == null) return false;
|
||||
|
||||
AnnotationProvider provider = data.vcs.getAnnotationProvider();
|
||||
return provider instanceof AnnotationProviderEx;
|
||||
}
|
||||
|
||||
public static boolean isSuspended(AnActionEvent e) {
|
||||
VirtualFile file = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE_ARRAY)[0];
|
||||
return AnnotateToggleAction.getBackgroundableLock(e.getRequiredData(CommonDataKeys.PROJECT), file).isLocked();
|
||||
}
|
||||
|
||||
public static boolean isAnnotated(AnActionEvent e) {
|
||||
Project project = e.getRequiredData(CommonDataKeys.PROJECT);
|
||||
VirtualFile file = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE_ARRAY)[0];
|
||||
List<Editor> editors = getEditors(project, file);
|
||||
return ContainerUtil.exists(editors, new Condition<Editor>() {
|
||||
@Override
|
||||
public boolean value(Editor editor) {
|
||||
return editor.getGutter().isAnnotationsShown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void perform(AnActionEvent e, boolean selected) {
|
||||
final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
|
||||
final VirtualFile file = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE_ARRAY)[0];
|
||||
List<Editor> editors = getEditors(project, file);
|
||||
|
||||
if (!selected) {
|
||||
for (Editor editor : editors) {
|
||||
editor.getGutter().closeAllAnnotations();
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Editor editor = editors.get(0);
|
||||
doAnnotate(project, editor, file);
|
||||
}
|
||||
}
|
||||
|
||||
private static void doAnnotate(@NotNull final Project project, @NotNull final Editor editor, @NotNull final VirtualFile file) {
|
||||
final AnnotationData data = extractData(project, file);
|
||||
assert data != null;
|
||||
|
||||
final AnnotationProviderEx provider = (AnnotationProviderEx)data.vcs.getAnnotationProvider();
|
||||
assert provider != null;
|
||||
|
||||
|
||||
final Ref<FileAnnotation> fileAnnotationRef = new Ref<FileAnnotation>();
|
||||
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
|
||||
|
||||
AnnotateToggleAction.getBackgroundableLock(project, file).lock();
|
||||
|
||||
final Task.Backgroundable annotateTask = new Task.Backgroundable(project, VcsBundle.message("retrieving.annotations"), true) {
|
||||
@Override
|
||||
public void run(final @NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
fileAnnotationRef.set(provider.annotate(data.filePath, data.revisionNumber));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
catch (ProcessCanceledException pce) {
|
||||
throw pce;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
exceptionRef.set(new VcsException(t));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
AnnotateToggleAction.getBackgroundableLock(project, file).unlock();
|
||||
|
||||
if (!exceptionRef.isNull()) {
|
||||
LOG.warn(exceptionRef.get());
|
||||
AbstractVcsHelper.getInstance(project).showErrors(Collections.singletonList(exceptionRef.get()), VcsBundle.message("message.title.annotate"));
|
||||
}
|
||||
|
||||
if (!fileAnnotationRef.isNull()) {
|
||||
AnnotateToggleAction.doAnnotate(editor, project, null, fileAnnotationRef.get(), data.vcs);
|
||||
}
|
||||
}
|
||||
};
|
||||
ProgressManager.getInstance().run(annotateTask);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Editor> getEditors(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
List<Editor> list = new ArrayList<Editor>();
|
||||
for (FileEditor fileEditor : FileEditorManager.getInstance(project).getEditors(file)) {
|
||||
if (fileEditor instanceof TextEditor) {
|
||||
list.add(((TextEditor)fileEditor).getEditor());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AnnotationData extractData(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
FilePath filePath = null;
|
||||
VcsRevisionNumber revisionNumber = null;
|
||||
if (file instanceof VcsVirtualFile) {
|
||||
filePath = VcsUtil.getFilePath(file.getPath());
|
||||
revisionNumber = ((VcsVirtualFile)file).getFileRevision().getRevisionNumber();
|
||||
}
|
||||
else if (file instanceof ContentRevisionVirtualFile) {
|
||||
ContentRevision revision = ((ContentRevisionVirtualFile)file).getContentRevision();
|
||||
filePath = revision.getFile();
|
||||
revisionNumber = revision.getRevisionNumber();
|
||||
}
|
||||
if (filePath == null || revisionNumber == null) return null;
|
||||
|
||||
AbstractVcs vcs = VcsUtil.getVcsFor(project, filePath);
|
||||
return vcs != null ? new AnnotationData(vcs, filePath, revisionNumber) : null;
|
||||
}
|
||||
|
||||
private static class AnnotationData {
|
||||
@NotNull public final AbstractVcs vcs;
|
||||
@NotNull public final FilePath filePath;
|
||||
@NotNull public final VcsRevisionNumber revisionNumber;
|
||||
|
||||
public AnnotationData(@NotNull AbstractVcs vcs,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull VcsRevisionNumber revisionNumber) {
|
||||
this.vcs = vcs;
|
||||
this.filePath = filePath;
|
||||
this.revisionNumber = revisionNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user