mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[log] Send refresh events only to the proper instance of the log
Instead of two event mechanism, introduce a single one: post evens when the VisiblePack is updated. Some clients need to know, whether the VisiblePack update was triggered by refresh or not, so supply a flag for them.
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.vcs.log;
|
||||
|
||||
public interface VcsLogFilterChangeListener {
|
||||
|
||||
void filtersPossiblyChanged();
|
||||
|
||||
}
|
||||
+12
-4
@@ -13,15 +13,23 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.vcs.log.data;
|
||||
package com.intellij.vcs.log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* This listener is notified about VCS log refresh procedure.
|
||||
* Listens to changes in the log, both in Permanent and Visible parts.
|
||||
*/
|
||||
public interface VcsLogRefreshListener {
|
||||
public interface VcsLogListener {
|
||||
|
||||
void refresh(@NotNull DataPack dataPack);
|
||||
/**
|
||||
* This method is called whether a refresh happened, or filter changed, or the VisibleGraph was rebuilt.
|
||||
* <p/>
|
||||
* It is called on the EDT thread.
|
||||
*
|
||||
* @param dataPack new VcsLogDataPack which was just applied to the UI.
|
||||
* @param refreshHappened true if a refresh initiated this log change, i.e. PermanentGraph changed.
|
||||
*/
|
||||
void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened);
|
||||
|
||||
}
|
||||
@@ -28,8 +28,8 @@ public interface VcsLogUi {
|
||||
void addHighlighter(@NotNull VcsLogHighlighter highlighter);
|
||||
void removeHighlighter(@NotNull VcsLogHighlighter highlighter);
|
||||
|
||||
void addFilterChangeListener(@NotNull VcsLogFilterChangeListener listener);
|
||||
void removeFilterChangeListener(@NotNull VcsLogFilterChangeListener listener);
|
||||
void addLogListener(@NotNull VcsLogListener listener);
|
||||
void removeLogListener(@NotNull VcsLogListener listener);
|
||||
|
||||
void setBranchesPanelVisible(boolean visible);
|
||||
|
||||
|
||||
@@ -18,12 +18,13 @@ package com.intellij.vcs.log.data;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.containers.SLRUMap;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.VcsLogDataPack;
|
||||
import com.intellij.vcs.log.VcsLogListener;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -38,7 +39,7 @@ import java.util.List;
|
||||
/**
|
||||
* Provides capabilities to asynchronously calculate "contained in branches" information.
|
||||
*/
|
||||
public class ContainingBranchesGetter {
|
||||
public class ContainingBranchesGetter implements VcsLogListener {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(ContainingBranchesGetter.class);
|
||||
|
||||
@@ -48,7 +49,7 @@ public class ContainingBranchesGetter {
|
||||
@Nullable private Runnable myLoadingFinishedListener; // access only from EDT
|
||||
private int myCurrentBranchesChecksum;
|
||||
|
||||
ContainingBranchesGetter(@NotNull Project project, @NotNull VcsLogDataHolder dataHolder, @NotNull Disposable parentDisposable) {
|
||||
ContainingBranchesGetter(@NotNull VcsLogDataHolder dataHolder, @NotNull Disposable parentDisposable) {
|
||||
myDataHolder = dataHolder;
|
||||
myTaskExecutor = new SequentialLimitedLifoExecutor<Task>(parentDisposable, 10, new ThrowableConsumer<Task, Throwable>() {
|
||||
@Override
|
||||
@@ -65,17 +66,18 @@ public class ContainingBranchesGetter {
|
||||
});
|
||||
}
|
||||
});
|
||||
project.getMessageBus().connect(parentDisposable).subscribe(VcsLogDataHolder.REFRESH_COMPLETED, new VcsLogRefreshListener() {
|
||||
@Override
|
||||
public void refresh(@NotNull DataPack dataPack) {
|
||||
Collection<VcsRef> currentBranches = dataPack.getRefs().getBranches();
|
||||
int checksum = currentBranches.hashCode();
|
||||
if (myCurrentBranchesChecksum != 0 && myCurrentBranchesChecksum != checksum) { // clear cache if branches set changed after refresh
|
||||
clearCache();
|
||||
}
|
||||
myCurrentBranchesChecksum = checksum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
|
||||
if (refreshHappened) {
|
||||
Collection<VcsRef> currentBranches = dataPack.getRefs().getBranches();
|
||||
int checksum = currentBranches.hashCode();
|
||||
if (myCurrentBranchesChecksum != 0 && myCurrentBranchesChecksum != checksum) { // clear cache if branches set changed after refresh
|
||||
clearCache();
|
||||
}
|
||||
});
|
||||
myCurrentBranchesChecksum = checksum;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.graph.PermanentGraph;
|
||||
import com.intellij.vcs.log.util.StopWatch;
|
||||
@@ -42,8 +41,6 @@ import java.util.Set;
|
||||
|
||||
public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
|
||||
|
||||
public static final Topic<VcsLogRefreshListener> REFRESH_COMPLETED = Topic.create("Vcs.Log.Completed", VcsLogRefreshListener.class);
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(VcsLogDataHolder.class);
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@@ -97,7 +94,7 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e); // TODO: show a message to the user & fallback to using in-memory Hashes
|
||||
}
|
||||
myContainingBranchesGetter = new ContainingBranchesGetter(project, this, this);
|
||||
myContainingBranchesGetter = new ContainingBranchesGetter(this, this);
|
||||
|
||||
myFilterer = new VcsLogFiltererImpl(myProject, myLogProviders, myHashMap, myTopCommitsDetailsCache, myDetailsGetter,
|
||||
uiProperties.isBek() ? PermanentGraph.SortType.Bek : PermanentGraph.SortType.Normal,
|
||||
@@ -107,7 +104,6 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
|
||||
@Override
|
||||
public void consume(DataPack dataPack) {
|
||||
myFilterer.onRefresh(dataPack);
|
||||
myProject.getMessageBus().syncPublisher(REFRESH_COMPLETED).refresh(dataPack);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ public class VcsLogManager implements Disposable {
|
||||
final VcsLogDataHolder logDataHolder = new VcsLogDataHolder(myProject, this, logProviders, mySettings, myUiProperties, visiblePackConsumer);
|
||||
myUi = new VcsLogUiImpl(logDataHolder, myProject, mySettings,
|
||||
new VcsLogColorManagerImpl(logProviders.keySet()), myUiProperties, logDataHolder.getFilterer());
|
||||
myUi.addLogListener(logDataHolder.getContainingBranchesGetter()); // TODO: remove this after VcsLogDataHolder vs VcsLoUi dependency cycle is solved
|
||||
if (contentTabName != null) {
|
||||
myLogRefresher = new PostponeableLogRefresher(myProject, logDataHolder, contentTabName);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
|
||||
@NotNull private final VcsLogUiProperties myUiProperties;
|
||||
@NotNull private final VcsLogFilterer myFilterer;
|
||||
|
||||
@NotNull private final Collection<VcsLogFilterChangeListener> myFilterChangeListeners = ContainerUtil.newArrayList();
|
||||
@NotNull private final Collection<VcsLogListener> myLogListeners = ContainerUtil.newArrayList();
|
||||
|
||||
@NotNull private VisiblePack myVisiblePack;
|
||||
|
||||
@@ -69,13 +69,16 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
|
||||
|
||||
TIntHashSet previouslySelected = getSelectedCommits();
|
||||
|
||||
PermanentGraph<Integer> previousPermGraph = myVisiblePack.getPermanentGraph();
|
||||
myVisiblePack = pack;
|
||||
|
||||
boolean permGraphChanged = previousPermGraph != myVisiblePack.getPermanentGraph();
|
||||
|
||||
GraphTableModel newModel = new GraphTableModel(myVisiblePack, myLogDataHolder, this);
|
||||
setModel(newModel, myVisiblePack.getVisibleGraph(), previouslySelected);
|
||||
myMainFrame.updateDataPack(myVisiblePack);
|
||||
setLongEdgeVisibility(myUiProperties.areLongEdgesVisible());
|
||||
fireFilterChangeEvent();
|
||||
fireFilterChangeEvent(myVisiblePack, permGraphChanged);
|
||||
repaintUI();
|
||||
}
|
||||
|
||||
@@ -376,18 +379,18 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFilterChangeListener(@NotNull VcsLogFilterChangeListener listener) {
|
||||
myFilterChangeListeners.add(listener);
|
||||
public void addLogListener(@NotNull VcsLogListener listener) {
|
||||
myLogListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFilterChangeListener(@NotNull VcsLogFilterChangeListener listener) {
|
||||
myFilterChangeListeners.remove(listener);
|
||||
public void removeLogListener(@NotNull VcsLogListener listener) {
|
||||
myLogListeners.remove(listener);
|
||||
}
|
||||
|
||||
private void fireFilterChangeEvent() {
|
||||
for (VcsLogFilterChangeListener listener : myFilterChangeListeners) {
|
||||
listener.filtersPossiblyChanged();
|
||||
private void fireFilterChangeEvent(@NotNull VisiblePack visiblePack, boolean refresh) {
|
||||
for (VcsLogListener listener : myLogListeners) {
|
||||
listener.onChange(visiblePack, refresh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.intellij.vcs.log.ui.frame;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -12,14 +11,9 @@ import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
import com.intellij.vcs.log.VcsLogProvider;
|
||||
import com.intellij.vcs.log.VcsLogRefManager;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.data.DataPack;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.data.RefsModel;
|
||||
import com.intellij.vcs.log.data.VcsLogDataHolder;
|
||||
import com.intellij.vcs.log.data.VcsLogRefreshListener;
|
||||
import com.intellij.vcs.log.impl.SingletonRefGroup;
|
||||
import com.intellij.vcs.log.impl.VcsLogUtil;
|
||||
import com.intellij.vcs.log.ui.VcsLogUiImpl;
|
||||
@@ -84,11 +78,12 @@ public class BranchesPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
Project project = dataHolder.getProject();
|
||||
project.getMessageBus().connect(project).subscribe(VcsLogDataHolder.REFRESH_COMPLETED, new VcsLogRefreshListener() {
|
||||
myUI.addLogListener(new VcsLogListener() {
|
||||
@Override
|
||||
public void refresh(@NotNull DataPack dataPack) {
|
||||
rebuild(dataPack.getRefsModel());
|
||||
public void onChange(@NotNull VcsLogDataPack dataPack, boolean refresh) {
|
||||
if (refresh) {
|
||||
rebuild(dataPack.getRefs());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -119,13 +114,13 @@ public class BranchesPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild(@NotNull RefsModel refsModel) {
|
||||
public void rebuild(@NotNull VcsLogRefs refsModel) {
|
||||
myRefGroups = getRefsToDisplayOnPanel(refsModel);
|
||||
getParent().repaint();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<RefGroup> getRefsToDisplayOnPanel(@NotNull RefsModel refsModel) {
|
||||
private List<RefGroup> getRefsToDisplayOnPanel(@NotNull VcsLogRefs refsModel) {
|
||||
Collection<VcsRef> allRefs = refsModel.getBranches();
|
||||
|
||||
List<RefGroup> groups = ContainerUtil.newArrayList();
|
||||
|
||||
@@ -28,11 +28,7 @@ import com.intellij.openapi.vcs.VcsNotifier;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.data.DataPack;
|
||||
import com.intellij.vcs.log.data.VcsLogDataHolder;
|
||||
import com.intellij.vcs.log.data.VcsLogRefreshListener;
|
||||
import com.intellij.vcs.log.impl.HashImpl;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.commands.GitCommand;
|
||||
@@ -54,7 +50,7 @@ public class DeepComparator implements Disposable {
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final GitRepositoryManager myRepositoryManager;
|
||||
@NotNull private final VcsLogUi myUi;
|
||||
@NotNull private final VcsLogFilterChangeListener myFilterChangeListener;
|
||||
@NotNull private final VcsLogListener myLogListener;
|
||||
|
||||
@Nullable private VcsLogHighlighter myHighlighter;
|
||||
@Nullable private MyTask myTask;
|
||||
@@ -71,64 +67,53 @@ public class DeepComparator implements Disposable {
|
||||
myUi = ui;
|
||||
Disposer.register(parent, this);
|
||||
|
||||
myFilterChangeListener = new VcsLogFilterChangeListener() {
|
||||
myLogListener = new VcsLogListener() {
|
||||
@Override
|
||||
public void filtersPossiblyChanged() {
|
||||
if (myTask == null) { // no task in progress => not interested in filter changes
|
||||
return;
|
||||
}
|
||||
|
||||
VcsLogBranchFilter branchFilter = myUi.getFilterUi().getFilters().getBranchFilter();
|
||||
if (branchFilter == null ||
|
||||
branchFilter.getBranchNames().size() != 1 ||
|
||||
!branchFilter.getBranchNames().iterator().next().equals(myTask.myComparedBranch)) {
|
||||
stopAndUnhighlight();
|
||||
}
|
||||
}
|
||||
};
|
||||
myUi.addFilterChangeListener(myFilterChangeListener);
|
||||
|
||||
project.getMessageBus().connect(project).subscribe(VcsLogDataHolder.REFRESH_COMPLETED, new VcsLogRefreshListener() {
|
||||
@Override
|
||||
public void refresh(@NotNull DataPack dataPack) {
|
||||
public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
|
||||
if (myTask == null) { // no task in progress => not interested in refresh events
|
||||
return;
|
||||
}
|
||||
|
||||
// collect data
|
||||
String comparedBranch = myTask.myComparedBranch;
|
||||
Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
|
||||
VcsLogDataProvider provider = myTask.myProvider;
|
||||
if (refreshHappened) {
|
||||
// collect data
|
||||
String comparedBranch = myTask.myComparedBranch;
|
||||
Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
|
||||
VcsLogDataProvider provider = myTask.myProvider;
|
||||
|
||||
stopAndUnhighlight();
|
||||
stopAndUnhighlight();
|
||||
|
||||
// highlight again
|
||||
Map<GitRepository, GitBranch> repositories = getRepositories(dataPack.getLogProviders(), comparedBranch);
|
||||
if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
|
||||
highlightInBackground(comparedBranch, provider);
|
||||
// highlight again
|
||||
Map<GitRepository, GitBranch> repositories = getRepositories(myUi.getDataPack().getLogProviders(), comparedBranch);
|
||||
if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
|
||||
highlightInBackground(comparedBranch, provider);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VcsLogBranchFilter branchFilter = myUi.getFilterUi().getFilters().getBranchFilter();
|
||||
if (branchFilter == null ||
|
||||
branchFilter.getBranchNames().size() != 1 ||
|
||||
!branchFilter.getBranchNames().iterator().next().equals(myTask.myComparedBranch)) {
|
||||
stopAndUnhighlight();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
myUi.addLogListener(myLogListener);
|
||||
}
|
||||
|
||||
public void highlightInBackground(@NotNull final String branchToCompare, @NotNull final VcsLogDataProvider dataProvider) {
|
||||
public void highlightInBackground(@NotNull String branchToCompare, @NotNull VcsLogDataProvider dataProvider) {
|
||||
if (myTask != null) {
|
||||
LOG.error("Shouldn't be possible");
|
||||
return;
|
||||
}
|
||||
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Map<GitRepository, GitBranch> repositories = getRepositories(myUi.getDataPack().getLogProviders(), branchToCompare);
|
||||
if (repositories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<GitRepository, GitBranch> repositories = getRepositories(myUi.getDataPack().getLogProviders(), branchToCompare);
|
||||
if (repositories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
myTask = new MyTask(myProject, myUi, repositories, dataProvider, branchToCompare);
|
||||
myTask.queue();
|
||||
}
|
||||
});
|
||||
myTask = new MyTask(myProject, myUi, repositories, dataProvider, branchToCompare);
|
||||
myTask.queue();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -159,7 +144,7 @@ public class DeepComparator implements Disposable {
|
||||
@Override
|
||||
public void dispose() {
|
||||
stopAndUnhighlight();
|
||||
myUi.removeFilterChangeListener(myFilterChangeListener);
|
||||
myUi.removeLogListener(myLogListener);
|
||||
}
|
||||
|
||||
public boolean hasHighlightingOrInProgress() {
|
||||
|
||||
Reference in New Issue
Block a user