diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/repo/AsyncFilesManagerListener.java b/platform/dvcs-impl/src/com/intellij/dvcs/repo/AsyncFilesManagerListener.java new file mode 100644 index 000000000000..480820128505 --- /dev/null +++ b/platform/dvcs-impl/src/com/intellij/dvcs/repo/AsyncFilesManagerListener.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2016 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.dvcs.repo; + +import java.util.EventListener; + +/** + * The listener interface for handling async vcs files holder events. + * When a files holder model starts/finishes to update itself -> updateStarted/Finished will be called for all subscribers. + * e.g. vcs updates its ignored file model after that we should trigger ui update in ChangesView; + * moreover, when long duration update starts we should also trigger some action; + */ +public interface AsyncFilesManagerListener extends EventListener { + + void updateStarted(); + + void updateFinished(); +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java index 0372744acdb2..377433326e41 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java @@ -46,6 +46,7 @@ public class IgnoredFilesCompositeHolder implements IgnoredFilesHolder { @Override public void cleanAll() { + myVcsIgnoredHolderMap.values().forEach(IgnoredFilesHolder::cleanAll); myVcsIgnoredHolderMap.clear(); myIdeIgnoredFilesHolder.cleanAll(); } @@ -97,7 +98,8 @@ public class IgnoredFilesCompositeHolder implements IgnoredFilesHolder { public Collection values() { final HashSet result = ContainerUtil.newHashSet(); result.addAll(myIdeIgnoredFilesHolder.values()); - result.addAll(myVcsIgnoredHolderMap.values().stream().map(IgnoredFilesHolder::values).flatMap(set -> set.stream()).collect(Collectors.toSet())); + result.addAll( + myVcsIgnoredHolderMap.values().stream().map(IgnoredFilesHolder::values).flatMap(set -> set.stream()).collect(Collectors.toSet())); return result; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java index acc5560dd19f..f1793a3213a1 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java @@ -15,12 +15,14 @@ */ package org.zmlx.hg4idea.provider; +import com.intellij.dvcs.repo.AsyncFilesManagerListener; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Alarm; +import com.intellij.util.EventDispatcher; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; @@ -43,7 +45,7 @@ public class HgLocalIgnoredHolder implements Disposable { @NotNull private final HgRepository myRepository; @NotNull private final Set myIgnoredSet; @NotNull private final ReentrantReadWriteLock SET_LOCK = new ReentrantReadWriteLock(); - + private final EventDispatcher myListeners = EventDispatcher.create(AsyncFilesManagerListener.class); public HgLocalIgnoredHolder(@NotNull HgRepository repository) { myRepository = repository; @@ -52,6 +54,10 @@ public class HgLocalIgnoredHolder implements Disposable { myUpdateQueue = new MergingUpdateQueue("HgIgnoreUpdate", 500, true, null, this, null, Alarm.ThreadToUse.POOLED_THREAD); } + public void addUpdateStateListener(@NotNull AsyncFilesManagerListener listener) { + myListeners.addListener(listener, this); + } + public void startRescan() { myUpdateQueue.queue(new Update("hgRescanIgnored") { @Override @@ -62,13 +68,23 @@ public class HgLocalIgnoredHolder implements Disposable { @Override public void run() { if (myInUpdateMode.compareAndSet(false, true)) { + fireUpdateStarted(); rescanAllIgnored(); myInUpdateMode.set(false); + fireUpdateFinished(); } } }); } + private void fireUpdateStarted() { + myListeners.getMulticaster().updateStarted(); + } + + private void fireUpdateFinished() { + myListeners.getMulticaster().updateFinished(); + } + private void rescanAllIgnored() { Set ignored = ContainerUtil.newHashSet(); try { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java index eb84042ccceb..424ec401a94b 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java @@ -16,6 +16,7 @@ package org.zmlx.hg4idea.repo; +import com.intellij.dvcs.repo.AsyncFilesManagerListener; import com.intellij.dvcs.repo.RepositoryImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; @@ -24,6 +25,8 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.changes.ChangesViewI; +import com.intellij.openapi.vcs.changes.ChangesViewManager; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; @@ -65,6 +68,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository { myConfig = HgConfig.getInstance(getProject(), rootDir); myLocalIgnoredHolder = new HgLocalIgnoredHolder(this); Disposer.register(this, myLocalIgnoredHolder); + myLocalIgnoredHolder.addUpdateStateListener(new MyIgnoredHolderAsyncListener(getProject())); update(); } @@ -265,4 +269,22 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository { public HgLocalIgnoredHolder getLocalIgnoredHolder() { return myLocalIgnoredHolder; } + + private static class MyIgnoredHolderAsyncListener implements AsyncFilesManagerListener { + @NotNull private final ChangesViewI myChangesViewI; + + public MyIgnoredHolderAsyncListener(@NotNull Project project) { + myChangesViewI = ChangesViewManager.getInstance(project); + } + + @Override + public void updateStarted() { + myChangesViewI.scheduleRefresh(); + } + + @Override + public void updateFinished() { + myChangesViewI.scheduleRefresh(); + } + } }