[vcs-log] move runWhenLogIsReady method to the VcsLogContentUtil

GitOrigin-RevId: 5977d76cb6cf613e50e075c9b9f2394834b07011
This commit is contained in:
Julia Beliaeva
2019-07-02 06:52:16 +03:00
committed by intellij-monorepo-bot
parent 0f3655bcdc
commit e2d9e778d2
6 changed files with 65 additions and 64 deletions
@@ -1,6 +1,9 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.vcs.log.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Condition;
@@ -16,21 +19,28 @@ import com.intellij.util.Consumer;
import com.intellij.util.ContentUtilEx;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcs.log.VcsLogUi;
import com.intellij.vcs.log.ui.AbstractVcsLogUi;
import com.intellij.vcs.log.ui.VcsLogPanel;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import com.intellij.vcs.log.util.VcsLogUtil;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
/**
* Utility methods to operate VCS Log tabs as {@link Content}s of the {@link ContentManager} of the VCS toolwindow.
*/
public class VcsLogContentUtil {
private static final Logger LOG = Logger.getInstance(VcsLogContentUtil.class);
@Nullable
private static AbstractVcsLogUi getLogUi(@NotNull JComponent c) {
@@ -177,4 +187,45 @@ public class VcsLogContentUtil {
if (component == null) return;
ContentUtilEx.renameTabbedContent(manager, component, newName);
}
/**
* Executes the given action if the VcsProjectLog has been initialized. If not, then schedules the log initialization,
* waits for it in a background task, and executes the action after the log is ready.
*/
@CalledInAwt
public static void runWhenLogIsReady(@NotNull Project project, @NotNull BiConsumer<? super VcsProjectLog, ? super VcsLogManager> action) {
VcsProjectLog log = VcsProjectLog.getInstance(project);
VcsLogManager manager = log.getLogManager();
if (manager != null) {
action.accept(log, manager);
}
else { // schedule showing the log, wait its initialization, and then open the tab
CountDownLatch latch = new CountDownLatch(1);
MessageBusConnection connection = project.getMessageBus().connect(log);
connection.subscribe(VcsProjectLog.VCS_PROJECT_LOG_CHANGED, new VcsProjectLog.ProjectLogListener() {
@Override
public void logCreated(@NotNull VcsLogManager logManager) {
latch.countDown();
action.accept(log, logManager);
connection.disconnect();
}
});
new Task.Backgroundable(project, "Loading Commits") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
log.createLog(true);
try {
while (!latch.await(50, TimeUnit.MILLISECONDS)) {
indicator.checkCanceled();
}
}
catch (InterruptedException e) {
LOG.error(e);
}
}
}.queue();
}
}
}
@@ -134,7 +134,7 @@ public class VcsProjectLog implements Disposable {
}
@CalledInBackground
public void createLog(boolean forceInit) {
void createLog(boolean forceInit) {
Map<VirtualFile, VcsLogProvider> logProviders = getLogProviders();
if (!logProviders.isEmpty()) {
createLog(logProviders, forceInit);
@@ -3,9 +3,6 @@ package com.intellij.vcs.log.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
@@ -22,25 +19,22 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcs.CommittedChangeListForRevision;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.CompressedRefs;
import com.intellij.vcs.log.data.RefsModel;
import com.intellij.vcs.log.data.VcsLogData;
import com.intellij.vcs.log.impl.*;
import com.intellij.vcs.log.impl.MainVcsLogUiProperties;
import com.intellij.vcs.log.impl.VcsChangesLazilyParsedDetails;
import com.intellij.vcs.log.impl.VcsLogUiProperties;
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@@ -56,8 +50,6 @@ public class VcsLogUtil {
public static final Pattern HASH_REGEX = Pattern.compile("[a-fA-F0-9]{7,40}");
public static final String HEAD = "HEAD";
private static final Logger LOG = Logger.getInstance(VcsLogUtil.class);
@NotNull
public static Map<VirtualFile, Set<VcsRef>> groupRefsByRoot(@NotNull Collection<? extends VcsRef> refs) {
return groupByRoot(refs, VcsRef::getRoot);
@@ -328,47 +320,6 @@ public class VcsLogUtil {
return Registry.is("vcs.folder.history.in.log");
}
/**
* Executes the given action if the VcsProjectLog has been initialized. If not, then schedules the log initialization,
* waits for it in a background task, and executes the action after the log is ready.
*/
@CalledInAwt
public static void runWhenLogIsReady(@NotNull Project project, @NotNull BiConsumer<? super VcsProjectLog, ? super VcsLogManager> action) {
VcsProjectLog log = VcsProjectLog.getInstance(project);
VcsLogManager manager = log.getLogManager();
if (manager != null) {
action.accept(log, manager);
}
else { // schedule showing the log, wait its initialization, and then open the tab
CountDownLatch latch = new CountDownLatch(1);
MessageBusConnection connection = project.getMessageBus().connect(log);
connection.subscribe(VcsProjectLog.VCS_PROJECT_LOG_CHANGED, new VcsProjectLog.ProjectLogListener() {
@Override
public void logCreated(@NotNull VcsLogManager logManager) {
latch.countDown();
action.accept(log, logManager);
connection.disconnect();
}
});
new Task.Backgroundable(project, "Loading Commits") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
log.createLog(true);
try {
while (!latch.await(50, TimeUnit.MILLISECONDS)) {
indicator.checkCanceled();
}
}
catch (InterruptedException e) {
LOG.error(e);
}
}
}.queue();
}
}
public static int getMaxSize(@NotNull List<? extends VcsFullCommitDetails> detailsList) {
int maxSize = 0;
for (VcsFullCommitDetails details : detailsList) {
@@ -381,7 +332,7 @@ public class VcsLogUtil {
if (details instanceof VcsChangesLazilyParsedDetails) {
return ((VcsChangesLazilyParsedDetails)details).size();
}
int size = 0;
for (int i = 0; i < details.getParents().size(); i++) {
size += details.getChanges(i).size();
@@ -21,7 +21,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.vcs.log.VcsLogRangeFilter;
import com.intellij.vcs.log.util.VcsLogUtil;
import com.intellij.vcs.log.impl.VcsLogContentUtil;
import com.intellij.vcs.log.visible.filters.VcsLogFilterObject;
import git4idea.GitVcs;
import git4idea.commands.Git;
@@ -128,7 +128,7 @@ class GitBrancherImpl implements GitBrancher {
@Override
public void compare(@NotNull String branchName, @NotNull List<? extends GitRepository> repositories,
@NotNull GitRepository selectedRepository) {
VcsLogUtil.runWhenLogIsReady(myProject, (log, logManager) -> {
VcsLogContentUtil.runWhenLogIsReady(myProject, (log, logManager) -> {
VcsLogRangeFilter filters = VcsLogFilterObject.fromRange("HEAD", branchName);
log.getTabsManager().openAnotherLogTab(logManager, VcsLogFilterObject.collection(filters));
});
@@ -29,8 +29,8 @@ import com.intellij.util.ThreeState.UNSURE
import com.intellij.util.ui.components.BorderLayoutPanel
import com.intellij.vcs.log.VcsLogProperties
import com.intellij.vcs.log.data.DataPackChangeListener
import com.intellij.vcs.log.impl.VcsLogContentUtil
import com.intellij.vcs.log.impl.VcsProjectLog
import com.intellij.vcs.log.util.VcsLogUtil
import com.intellij.vcs.log.util.exclusiveCommits
import com.intellij.vcs.log.util.findBranch
import com.intellij.vcs.log.visible.filters.VcsLogFilterObject
@@ -59,7 +59,7 @@ class GitCleanupBranchesAction : DumbAwareAction() {
Disposer.register(content, ui)
toolWindow.activate(null, true, true)
VcsLogUtil.runWhenLogIsReady(project) { _, _ ->
VcsLogContentUtil.runWhenLogIsReady(project) { _, _ ->
ui.stopLoading()
} // schedule initialization: need the log for other actions
}
@@ -311,7 +311,7 @@ private class ShowBranchDiffAction : CleanupBranchesActionBase("Compare with Cur
val branch = e.getData(GIT_BRANCH)!!
val project = e.project!!
VcsLogUtil.runWhenLogIsReady(project) { log, logManager ->
VcsLogContentUtil.runWhenLogIsReady(project) { log, logManager ->
val filters = VcsLogFilterObject.fromRange("HEAD", branch.branchName)
log.tabsManager.openAnotherLogTab(logManager, VcsLogFilterObject.collection(filters))
}
@@ -27,7 +27,6 @@ import com.intellij.vcs.log.impl.VcsLogManager
import com.intellij.vcs.log.impl.VcsProjectLog
import com.intellij.vcs.log.ui.VcsLogPanel
import com.intellij.vcs.log.ui.VcsLogUiImpl
import com.intellij.vcs.log.util.VcsLogUtil
import com.intellij.vcs.log.util.containsAll
import com.intellij.vcs.log.visible.VcsLogFiltererImpl
import com.intellij.vcs.log.visible.VisiblePack
@@ -52,7 +51,7 @@ class GitUpdateInfoAsLog(private val project: Project,
@CalledInAwt
fun buildAndShowNotification() {
notificationShown = false
VcsLogUtil.runWhenLogIsReady(project) { log, logManager ->
VcsLogContentUtil.runWhenLogIsReady(project) { log, logManager ->
val listener = object : DataPackChangeListener {
override fun onDataPackChange(dataPack: DataPack) {
showNotificationIfRangesAreReachable(log, dataPack, logManager, this)
@@ -62,9 +61,9 @@ class GitUpdateInfoAsLog(private val project: Project,
log.dataManager?.addDataPackChangeListener(listener)
GuiUtils.invokeLaterIfNeeded({
// the log may be refreshed before we subscribe to the listener
showNotificationIfRangesAreReachable(log, logManager.dataManager.dataPack, logManager, listener)
}, ModalityState.defaultModalityState())
// the log may be refreshed before we subscribe to the listener
showNotificationIfRangesAreReachable(log, logManager.dataManager.dataPack, logManager, listener)
}, ModalityState.defaultModalityState())
}
}