mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 11:20:44 +07:00
diff: show progress bar while loading annotations
* add DiffViewer-independent progress bar
This commit is contained in:
@@ -31,4 +31,9 @@ public abstract class DiffContextEx extends DiffContext {
|
||||
* this can be used, if some change in request or settings was made, and we need to reload DiffRequest to apply them.
|
||||
*/
|
||||
public abstract void reloadDiffRequest();
|
||||
|
||||
/*
|
||||
* Show indeterminate progress near status panel.
|
||||
*/
|
||||
public abstract void showProgressBar(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.HintHint;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.JBProgressBar;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -93,6 +94,7 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
@NotNull private final Wrapper myContentPanel;
|
||||
@NotNull private final Wrapper myToolbarPanel; // TODO: allow to call 'updateToolbar' from Viewer ?
|
||||
@NotNull private final Wrapper myToolbarStatusPanel;
|
||||
@NotNull private final MyProgressBar myProgressBar;
|
||||
|
||||
@NotNull private DiffRequest myActiveRequest;
|
||||
|
||||
@@ -119,19 +121,17 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
|
||||
// UI
|
||||
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myMainPanel = new MyPanel();
|
||||
myContentPanel = new Wrapper();
|
||||
myToolbarPanel = new Wrapper();
|
||||
myToolbarPanel.setFocusable(true);
|
||||
myToolbarStatusPanel = new Wrapper();
|
||||
myProgressBar = new MyProgressBar();
|
||||
|
||||
myPanel.add(myMainPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
topPanel.add(myToolbarPanel, BorderLayout.CENTER);
|
||||
topPanel.add(myToolbarStatusPanel, BorderLayout.EAST);
|
||||
myPanel = JBUI.Panels.simplePanel(myMainPanel);
|
||||
|
||||
JPanel statusPanel = JBUI.Panels.simplePanel(myToolbarStatusPanel).addToLeft(myProgressBar);
|
||||
JPanel topPanel = JBUI.Panels.simplePanel(myToolbarPanel).addToRight(statusPanel);
|
||||
|
||||
myMainPanel.add(topPanel, BorderLayout.NORTH);
|
||||
myMainPanel.add(myContentPanel, BorderLayout.CENTER);
|
||||
@@ -894,6 +894,26 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyProgressBar extends JBProgressBar {
|
||||
private int myProgressCount = 0;
|
||||
|
||||
public MyProgressBar() {
|
||||
setIndeterminate(true);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public void startProgress() {
|
||||
myProgressCount++;
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void stopProgress() {
|
||||
myProgressCount--;
|
||||
LOG.assertTrue(myProgressCount >= 0);
|
||||
if (myProgressCount == 0) setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyFocusTraversalPolicy extends IdeFocusTraversalPolicy {
|
||||
@Override
|
||||
public final Component getDefaultComponentImpl(final Container focusCycleRoot) {
|
||||
@@ -920,6 +940,16 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
reloadRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showProgressBar(boolean enabled) {
|
||||
if (enabled) {
|
||||
myProgressBar.startProgress();
|
||||
}
|
||||
else {
|
||||
myProgressBar.stopProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Project getProject() {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.diff.util;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -22,8 +23,10 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -162,4 +165,46 @@ public class BackgroundTaskUtil {
|
||||
|
||||
return resultRef.get();
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
@NotNull
|
||||
public static ProgressIndicator executeOnPooledThread(@NotNull final Consumer<ProgressIndicator> task, @NotNull Disposable parent) {
|
||||
final ModalityState modalityState = ModalityState.current();
|
||||
final ProgressIndicator indicator = new EmptyProgressIndicator() {
|
||||
@NotNull
|
||||
@Override
|
||||
public ModalityState getModalityState() {
|
||||
return modalityState;
|
||||
}
|
||||
};
|
||||
indicator.start();
|
||||
|
||||
final Disposable disposable = new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (indicator.isRunning()) indicator.cancel();
|
||||
}
|
||||
};
|
||||
Disposer.register(parent, disposable);
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
task.consume(indicator);
|
||||
}
|
||||
finally {
|
||||
indicator.stop();
|
||||
Disposer.dispose(disposable);
|
||||
}
|
||||
}
|
||||
}, indicator);
|
||||
}
|
||||
});
|
||||
|
||||
return indicator;
|
||||
}
|
||||
}
|
||||
|
||||
+35
-33
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.vcs.actions;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.DiffContextEx;
|
||||
import com.intellij.diff.DiffExtension;
|
||||
import com.intellij.diff.FrameDiffTool.DiffViewer;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
@@ -28,19 +29,16 @@ import com.intellij.diff.tools.util.base.DiffViewerBase;
|
||||
import com.intellij.diff.tools.util.base.DiffViewerListener;
|
||||
import com.intellij.diff.tools.util.side.OnesideTextDiffViewer;
|
||||
import com.intellij.diff.tools.util.side.TwosideTextDiffViewer;
|
||||
import com.intellij.diff.util.BackgroundTaskUtil;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.localVcs.UpToDateLineNumberProvider;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
|
||||
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
@@ -48,7 +46,10 @@ import com.intellij.openapi.util.Pair;
|
||||
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.*;
|
||||
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.vcs.changes.CurrentContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevisionEx;
|
||||
@@ -59,6 +60,7 @@ 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.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.vcs.AnnotationProviderEx;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
@@ -145,41 +147,41 @@ public class AnnotateDiffViewerAction extends DumbAwareAction {
|
||||
final FileAnnotationLoader loader = createAnnotationsLoader(project, viewer.getRequest(), side);
|
||||
assert loader != null;
|
||||
|
||||
final DiffContextEx diffContext = ObjectUtils.tryCast(viewer.getContext(), DiffContextEx.class);
|
||||
|
||||
markRunningProgress(viewer, side, true);
|
||||
if (diffContext != null) diffContext.showProgressBar(true);
|
||||
|
||||
// TODO: show progress in diff viewer
|
||||
// TODO: we can abort loading on DiffViewer.dispose(). But vcs can't stop gracefully anyway.
|
||||
Task.Backgroundable task = new Task.Backgroundable(project, VcsBundle.message("retrieving.annotations"), true,
|
||||
BackgroundFromStartOption.getInstance()) {
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
loader.run();
|
||||
}
|
||||
|
||||
BackgroundTaskUtil.executeOnPooledThread(new Consumer<ProgressIndicator>() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
markRunningProgress(viewer, side, false);
|
||||
|
||||
if (loader.getException() != null) {
|
||||
AbstractVcsHelper.getInstance(myProject).showError(loader.getException(), VcsBundle.message("operation.name.annotate"));
|
||||
public void consume(ProgressIndicator indicator) {
|
||||
try {
|
||||
loader.run();
|
||||
}
|
||||
if (loader.getResult() == null) return;
|
||||
if (viewer.isDisposed()) return;
|
||||
finally {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (diffContext != null) diffContext.showProgressBar(false);
|
||||
markRunningProgress(viewer, side, false);
|
||||
|
||||
annotator.showAnnotation(viewer, side, loader.getResult());
|
||||
if (loader.getException() != null) {
|
||||
AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(viewer.getProject());
|
||||
vcsHelper.showError(loader.getException(), VcsBundle.message("operation.name.annotate"));
|
||||
}
|
||||
if (loader.getResult() == null) return;
|
||||
if (viewer.isDisposed()) return;
|
||||
|
||||
if (loader.shouldCache()) {
|
||||
putDataToCache(viewer, side, loader.getResult());
|
||||
annotator.showAnnotation(viewer, side, loader.getResult());
|
||||
|
||||
if (loader.shouldCache()) {
|
||||
putDataToCache(viewer, side, loader.getResult());
|
||||
}
|
||||
}
|
||||
}, indicator.getModalityState());
|
||||
}
|
||||
}
|
||||
};
|
||||
ProgressIndicator indicator = new BackgroundableProcessIndicator(task);
|
||||
ProgressManagerImpl progressManager = (ProgressManagerImpl)ProgressManager.getInstance();
|
||||
progressManager.runProcessWithProgressAsynchronously(task, indicator, null, ModalityState.current());
|
||||
}, viewer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user