diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterChangeListener.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterChangeListener.java
deleted file mode 100644
index 81f20021f573..000000000000
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterChangeListener.java
+++ /dev/null
@@ -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();
-
-}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshListener.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java
similarity index 53%
rename from platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshListener.java
rename to platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java
index 4a9799264f4d..2d5dc5fbb5af 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshListener.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java
@@ -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.
+ *
+ * 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);
}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUi.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUi.java
index 995407eaef52..b477e160d558 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUi.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUi.java
@@ -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);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java
index ff6a9ac156c1..d1576fd12390 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java
@@ -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(parentDisposable, 10, new ThrowableConsumer() {
@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 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 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() {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
index 80d351204cba..8824594ccd53 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
@@ -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 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);
}
};
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
index 9cc4ac990efe..4e6b1b272006 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
@@ -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);
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
index 45f0bc535af2..96f9be8bbb37 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
@@ -46,7 +46,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
@NotNull private final VcsLogUiProperties myUiProperties;
@NotNull private final VcsLogFilterer myFilterer;
- @NotNull private final Collection myFilterChangeListeners = ContainerUtil.newArrayList();
+ @NotNull private final Collection myLogListeners = ContainerUtil.newArrayList();
@NotNull private VisiblePack myVisiblePack;
@@ -69,13 +69,16 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
TIntHashSet previouslySelected = getSelectedCommits();
+ PermanentGraph 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);
}
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java
index cb78aec9333d..3ea5c106a45a 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java
@@ -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 getRefsToDisplayOnPanel(@NotNull RefsModel refsModel) {
+ private List getRefsToDisplayOnPanel(@NotNull VcsLogRefs refsModel) {
Collection allRefs = refsModel.getBranches();
List groups = ContainerUtil.newArrayList();
diff --git a/plugins/git4idea/src/git4idea/branch/DeepComparator.java b/plugins/git4idea/src/git4idea/branch/DeepComparator.java
index b6df56e04347..d6d30dcc3c24 100644
--- a/plugins/git4idea/src/git4idea/branch/DeepComparator.java
+++ b/plugins/git4idea/src/git4idea/branch/DeepComparator.java
@@ -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 repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
- VcsLogDataProvider provider = myTask.myProvider;
+ if (refreshHappened) {
+ // collect data
+ String comparedBranch = myTask.myComparedBranch;
+ Map repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
+ VcsLogDataProvider provider = myTask.myProvider;
- stopAndUnhighlight();
+ stopAndUnhighlight();
- // highlight again
- Map repositories = getRepositories(dataPack.getLogProviders(), comparedBranch);
- if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
- highlightInBackground(comparedBranch, provider);
+ // highlight again
+ Map 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 repositories = getRepositories(myUi.getDataPack().getLogProviders(), branchToCompare);
- if (repositories.isEmpty()) {
- return;
- }
+ Map 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() {