mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs] IDEA-137338 reuse existing file history tab
Don't create a refresher (and thus a FileHistorySessionPartner, and the FileHistoryPanelImpl) each time "Show History" is called. Instead try to find an existing one, and reuse it.
This commit is contained in:
@@ -95,6 +95,16 @@ public class TabbedContentImpl extends ContentImpl implements TabbedContent {
|
||||
setComponent(tab.second);
|
||||
}
|
||||
|
||||
public boolean findAndSelectContent(@NotNull JComponent contentComponent) {
|
||||
String tabName = findTabNameByComponent(contentComponent);
|
||||
if (tabName != null) {
|
||||
setDisplayName(tabName);
|
||||
setComponent(contentComponent);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTabName() {
|
||||
String selected = findTabNameByComponent(getComponent());
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.util;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.ui.content.Content;
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -87,6 +89,51 @@ public class ContentUtilEx extends ContentsUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all {@link Content simple} and {@link TabbedContent tabbed} contents of the given ContentManager,
|
||||
* and selects the one which holds the specified {@code contentComponent}.
|
||||
*
|
||||
* @return true if the necessary content was found (and thus selected) among content components of the given ContentManager.
|
||||
*/
|
||||
public static boolean selectContent(@NotNull ContentManager manager, @NotNull final JComponent contentComponent, boolean requestFocus) {
|
||||
for (Content content : manager.getContents()) {
|
||||
if (content instanceof TabbedContentImpl) {
|
||||
boolean found = ((TabbedContentImpl)content).findAndSelectContent(contentComponent);
|
||||
if (found) {
|
||||
manager.setSelectedContent(content, requestFocus);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (Comparing.equal(content.getComponent(), contentComponent)) {
|
||||
manager.setSelectedContent(content, requestFocus);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all {@link Content simple} and {@link TabbedContent tabbed} contents of the given ContentManager,
|
||||
* trying to find the first one which matches the given condition.
|
||||
*/
|
||||
@Nullable
|
||||
public static JComponent findContentComponent(@NotNull ContentManager manager, @NotNull Condition<JComponent> condition) {
|
||||
for (Content content : manager.getContents()) {
|
||||
if (content instanceof TabbedContentImpl) {
|
||||
List<Pair<String, JComponent>> tabs = ((TabbedContentImpl)content).getTabs();
|
||||
for (Pair<String, JComponent> tab : tabs) {
|
||||
if (condition.value(tab.second)) {
|
||||
return tab.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (condition.value(content.getComponent())) {
|
||||
return content.getComponent();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getSelectedTab(@NotNull TabbedContent content) {
|
||||
final JComponent current = content.getComponent();
|
||||
int index = 0;
|
||||
|
||||
@@ -108,8 +108,8 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
|
||||
private final VcsHistoryProvider myProvider;
|
||||
private final AnnotationProvider myAnnotationProvider;
|
||||
private VcsHistorySession myHistorySession;
|
||||
private final FilePath myFilePath;
|
||||
private final FileHistoryRefresherI myRefresherI;
|
||||
@NotNull private final FilePath myFilePath;
|
||||
@NotNull private final FileHistoryRefresherI myRefresherI;
|
||||
private VcsFileRevision myBottomRevisionForShowDiff;
|
||||
private final DualView myDualView;
|
||||
|
||||
@@ -346,9 +346,12 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
|
||||
}
|
||||
|
||||
public FileHistoryPanelImpl(AbstractVcs vcs,
|
||||
FilePath filePath, VcsHistorySession session,
|
||||
@NotNull FilePath filePath,
|
||||
VcsHistorySession session,
|
||||
VcsHistoryProvider provider,
|
||||
ContentManager contentManager, final FileHistoryRefresherI refresherI, final boolean isStaticEmbedded) {
|
||||
ContentManager contentManager,
|
||||
@NotNull FileHistoryRefresherI refresherI,
|
||||
final boolean isStaticEmbedded) {
|
||||
super(contentManager, provider.getHelpId() != null ? provider.getHelpId() : "reference.versionControl.toolwindow.history", ! isStaticEmbedded);
|
||||
myProject = vcs.getProject();
|
||||
myIsStaticAndEmbedded = false;
|
||||
@@ -1500,6 +1503,16 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FileHistoryRefresherI getRefresher() {
|
||||
return myRefresherI;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FilePath getFilePath() {
|
||||
return myFilePath;
|
||||
}
|
||||
|
||||
public VirtualFile getVirtualFile() {
|
||||
return myFilePath.getVirtualFile();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.history;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Refreshes file history.
|
||||
@@ -35,26 +36,34 @@ public class FileHistoryRefresher implements FileHistoryRefresherI {
|
||||
public FileHistoryRefresher(final VcsHistoryProvider vcsHistoryProvider,
|
||||
final AnnotationProvider annotationProvider,
|
||||
final FilePath path,
|
||||
final String repositoryPath,
|
||||
final AbstractVcs vcs) {
|
||||
myVcsHistoryProvider = vcsHistoryProvider;
|
||||
myPath = path;
|
||||
myVcs = vcs;
|
||||
mySessionPartner = new FileHistorySessionPartner(vcsHistoryProvider, annotationProvider, path, repositoryPath, vcs, this);
|
||||
mySessionPartner = new FileHistorySessionPartner(vcsHistoryProvider, annotationProvider, path, vcs, this);
|
||||
myCanUseCache = true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FileHistoryRefresherI findOrCreate(@NotNull VcsHistoryProvider vcsHistoryProvider,
|
||||
@NotNull AnnotationProvider annotationProvider,
|
||||
@NotNull FilePath path,
|
||||
@NotNull AbstractVcs vcs) {
|
||||
FileHistoryRefresherI refresher = FileHistorySessionPartner.findExistingHistoryRefresher(vcs.getProject(), path);
|
||||
return refresher == null ? new FileHistoryRefresher(vcsHistoryProvider, annotationProvider, path, vcs) : refresher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canUseLastRevision
|
||||
*/
|
||||
@Override
|
||||
public void run(boolean isRefresh, boolean canUseLastRevision) {
|
||||
myIsRefresh = isRefresh;
|
||||
mySessionPartner.beforeRefresh();
|
||||
final VcsHistoryProviderBackgroundableProxy proxy = new VcsHistoryProviderBackgroundableProxy(
|
||||
myVcs, myVcsHistoryProvider, myVcs.getDiffProvider());
|
||||
proxy.executeAppendableSession(myVcs.getKeyInstanceMethod(), myPath, mySessionPartner, null, myCanUseCache, canUseLastRevision);
|
||||
myCanUseCache = false;
|
||||
myIsRefresh = isRefresh;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+46
-23
@@ -16,7 +16,9 @@
|
||||
package com.intellij.openapi.vcs.history;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
@@ -32,7 +34,9 @@ import com.intellij.util.BufferedListConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ContentUtilEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -44,7 +48,6 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
private final VcsHistoryProvider myVcsHistoryProvider;
|
||||
private final AnnotationProvider myAnnotationProvider;
|
||||
@NotNull private final FilePath myPath;
|
||||
private final String myRepositoryPath;
|
||||
private final AbstractVcs myVcs;
|
||||
private final FileHistoryRefresherI myRefresherI;
|
||||
private volatile VcsAbstractHistorySession mySession;
|
||||
@@ -52,14 +55,12 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
|
||||
public FileHistorySessionPartner(final VcsHistoryProvider vcsHistoryProvider, final AnnotationProvider annotationProvider,
|
||||
@NotNull final FilePath path,
|
||||
final String repositoryPath,
|
||||
final AbstractVcs vcs,
|
||||
final FileHistoryRefresherI refresherI) {
|
||||
myVcsHistoryProvider = vcsHistoryProvider;
|
||||
myAnnotationProvider = annotationProvider;
|
||||
myPath = path;
|
||||
myLimitHistoryCheck = new LimitHistoryCheck(vcs.getProject(), path.getPath());
|
||||
myRepositoryPath = repositoryPath;
|
||||
myVcs = vcs;
|
||||
myRefresherI = refresherI;
|
||||
Consumer<List<VcsFileRevision>> sessionRefresher = new Consumer<List<VcsFileRevision>>() {
|
||||
@@ -86,6 +87,17 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static FileHistoryRefresherI findExistingHistoryRefresher(@NotNull Project project, @NotNull final FilePath path) {
|
||||
JComponent component = ContentUtilEx.findContentComponent(getToolWindow(project).getContentManager(), new Condition<JComponent>() {
|
||||
@Override
|
||||
public boolean value(JComponent component) {
|
||||
return component instanceof FileHistoryPanelImpl && ((FileHistoryPanelImpl)component).getFilePath().equals(path);
|
||||
}
|
||||
});
|
||||
return component == null ? null : ((FileHistoryPanelImpl)component).getRefresher();
|
||||
}
|
||||
|
||||
public void acceptRevision(VcsFileRevision revision) {
|
||||
myLimitHistoryCheck.checkNumber();
|
||||
myBuffer.consumeOne(revision);
|
||||
@@ -98,17 +110,6 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
return myFileHistoryPanel;
|
||||
}
|
||||
|
||||
private FileHistoryPanelImpl resetHistoryPanel() {
|
||||
final VcsHistorySession copy = mySession.copyWithCachedRevision();
|
||||
if (myFileHistoryPanel == null) {
|
||||
myFileHistoryPanel = createFileHistoryPanel(copy);
|
||||
}
|
||||
else {
|
||||
myFileHistoryPanel.getHistoryPanelRefresh().consume(copy);
|
||||
}
|
||||
return myFileHistoryPanel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FileHistoryPanelImpl createFileHistoryPanel(@NotNull VcsHistorySession copy) {
|
||||
ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(myVcs.getProject()).getContentManager();
|
||||
@@ -121,22 +122,29 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
if (mySession != null) {
|
||||
mySession.shouldBeRefreshed(); // to init current revision!
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myFileHistoryPanel = resetHistoryPanel();
|
||||
ToolWindow toolWindow = ToolWindowManager.getInstance(myVcs.getProject()).getToolWindow(ToolWindowId.VCS);
|
||||
assert toolWindow != null : "Version Control ToolWindow should be available at this point.";
|
||||
|
||||
ContentUtilEx.addTabbedContent(toolWindow.getContentManager(), myFileHistoryPanel, "History", myPath.getName(),
|
||||
myRefresherI.isFirstTime());
|
||||
|
||||
if (myRefresherI.isFirstTime()) {
|
||||
toolWindow.activate(null);
|
||||
final VcsHistorySession copy = mySession.copyWithCachedRevision();
|
||||
if (myFileHistoryPanel == null) {
|
||||
myFileHistoryPanel = createFileHistoryPanel(copy);
|
||||
createOrSelectContentIfNeeded();
|
||||
}
|
||||
else {
|
||||
myFileHistoryPanel.getHistoryPanelRefresh().consume(copy);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ToolWindow getToolWindow(@NotNull Project project) {
|
||||
ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS);
|
||||
assert toolWindow != null : "Version Control ToolWindow should be available at this point.";
|
||||
return toolWindow;
|
||||
}
|
||||
|
||||
public void reportException(VcsException exception) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myVcs.getProject(),
|
||||
VcsBundle.message("message.title.could.not.load.file.history") + ": " +
|
||||
@@ -146,6 +154,21 @@ public class FileHistorySessionPartner implements VcsAppendableHistorySessionPar
|
||||
@Override
|
||||
public void beforeRefresh() {
|
||||
myLimitHistoryCheck.reset();
|
||||
if (myFileHistoryPanel != null) {
|
||||
createOrSelectContentIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
private void createOrSelectContentIfNeeded() {
|
||||
ToolWindow toolWindow = getToolWindow(myVcs.getProject());
|
||||
if (myRefresherI.isFirstTime()) {
|
||||
ContentManager manager = toolWindow.getContentManager();
|
||||
boolean selectedExistingContent = ContentUtilEx.selectContent(manager, myFileHistoryPanel, true);
|
||||
if (!selectedExistingContent) {
|
||||
ContentUtilEx.addTabbedContent(manager, myFileHistoryPanel, "History", myPath.getName(), true);
|
||||
}
|
||||
toolWindow.activate(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void finished() {
|
||||
|
||||
@@ -129,8 +129,8 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
|
||||
|
||||
public void showFileHistory(final VcsHistoryProvider vcsHistoryProvider, final AnnotationProvider annotationProvider, final FilePath path,
|
||||
final String repositoryPath, final AbstractVcs vcs) {
|
||||
final FileHistoryRefresherI refresherI = new FileHistoryRefresher(vcsHistoryProvider, annotationProvider, path, repositoryPath, vcs);
|
||||
refresherI.run(false, true);
|
||||
FileHistoryRefresherI refresher = FileHistoryRefresher.findOrCreate(vcsHistoryProvider, annotationProvider, path, vcs);
|
||||
refresher.run(false, true);
|
||||
}
|
||||
|
||||
public void showRollbackChangesDialog(List<Change> changes) {
|
||||
|
||||
Reference in New Issue
Block a user