diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryUi.java index a30cddb645bf..4bd3c41ea07c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryUi.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryUi.java @@ -15,6 +15,7 @@ */ package com.intellij.vcs.log.history; +import com.google.common.util.concurrent.SettableFuture; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; @@ -30,7 +31,9 @@ import com.intellij.openapi.vcs.vfs.VcsVirtualFolder; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ObjectUtils; +import com.intellij.util.PairFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.VcsLogFilterCollection; import com.intellij.vcs.log.VcsLogFilterUi; @@ -38,14 +41,19 @@ import com.intellij.vcs.log.data.LoadingDetails; import com.intellij.vcs.log.data.VcsLogData; import com.intellij.vcs.log.data.index.IndexDataGetter; import com.intellij.vcs.log.impl.CommonUiProperties; +import com.intellij.vcs.log.impl.VcsLogContentProvider; import com.intellij.vcs.log.impl.VcsLogUiProperties; +import com.intellij.vcs.log.impl.VcsProjectLog; import com.intellij.vcs.log.ui.AbstractVcsLogUi; import com.intellij.vcs.log.ui.VcsLogColorManager; +import com.intellij.vcs.log.ui.VcsLogUiImpl; import com.intellij.vcs.log.ui.highlighters.CurrentBranchHighlighter; import com.intellij.vcs.log.ui.highlighters.MyCommitsHighlighter; import com.intellij.vcs.log.ui.highlighters.VcsLogHighlighterFactory; +import com.intellij.vcs.log.ui.table.GraphTableModel; import com.intellij.vcs.log.ui.table.VcsLogGraphTable; import com.intellij.vcs.log.visible.VisiblePackRefresher; +import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -205,6 +213,37 @@ public class FileHistoryUi extends AbstractVcsLogUi { return CommittedChangesTreeBrowser.zipChanges(changes); } + @Override + protected void handleCommitNotFound(@NotNull T commitId, @NotNull PairFunction rowGetter) { + String mainText = "Commit " + commitId.toString() + " does not exist in history for " + myPath.getName(); + if (getFilters().getBranchFilter() != null) { + showWarningWithLink(mainText + " in current branch.", "Show all branches and search again.", () -> { + myUiProperties.set(FileHistoryUiProperties.SHOW_ALL_BRANCHES, true); + invokeOnChange(() -> jumpTo(commitId, rowGetter, SettableFuture.create())); + }); + } + else { + VcsLogUiImpl mainLogUi = VcsProjectLog.getInstance(myProject).getMainLogUi(); + if (mainLogUi != null) { + showWarningWithLink(mainText + ".", "Search in Log.", () -> { + if (VcsLogContentProvider.selectLogUi(myProject, mainLogUi)) { + if (commitId instanceof Hash) { + mainLogUi.jumpToCommit((Hash)commitId, + notNull(VcsUtil.getVcsRootFor(myProject, myPath)), + SettableFuture.create()); + } + else if (commitId instanceof String) { + mainLogUi.jumpToCommitByPartOfHash((String)commitId, SettableFuture.create()); + } + } + }); + } + else { + super.handleCommitNotFound(commitId, rowGetter); + } + } + } + @NotNull public FilePath getPath() { return myPath; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java index e054b4e89a81..e65e74b828d9 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java @@ -33,6 +33,7 @@ import com.intellij.util.ContentsUtil; import com.intellij.util.NotNullFunction; 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; @@ -113,15 +114,22 @@ public class VcsLogContentProvider implements ChangesViewContentProvider { ContentManager manager = toolWindow.getContentManager(); JComponent component = ContentUtilEx.findContentComponent(manager, c -> { + VcsLogPanel vcsLogPanel = null; if (c instanceof VcsLogPanel) { - AbstractVcsLogUi ui = ((VcsLogPanel)c).getUi(); + vcsLogPanel = (VcsLogPanel)c; + } + else if (c instanceof JPanel) { + vcsLogPanel = ContainerUtil.findInstance(c.getComponents(), VcsLogPanel.class); + } + + if (vcsLogPanel != null) { + AbstractVcsLogUi ui = vcsLogPanel.getUi(); //noinspection unchecked return clazz.isInstance(ui) && condition.value((U)ui); } return false; }); if (component == null) return false; - //noinspection unchecked if (!toolWindow.isVisible()) toolWindow.activate(null); return ContentUtilEx.selectContent(manager, component, true); @@ -149,6 +157,10 @@ public class VcsLogContentProvider implements ChangesViewContentProvider { logManager.scheduleInitialization(); } + public static boolean selectLogUi(@NotNull Project project, @NotNull VcsLogUi ui) { + return findAndSelectContent(project, AbstractVcsLogUi.class, u -> u.equals(ui)); + } + @NotNull private static String generateShortName(@NotNull ToolWindow toolWindow) { TabbedContent tabbedContent = ContentUtilEx.findTabbedContent(toolWindow.getContentManager(), TAB_NAME); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/AbstractVcsLogUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/AbstractVcsLogUi.java index 5021fba72cf4..38d74884f7e5 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/AbstractVcsLogUi.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/AbstractVcsLogUi.java @@ -22,6 +22,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.NamedRunnable; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; @@ -199,6 +200,16 @@ public abstract class AbstractVcsLogUi implements VcsLogUi, Disposable { VcsBalloonProblemNotifier.showOverChangesView(myProject, "Commit " + commitId.toString() + " not found.", MessageType.WARNING); } + protected void showWarningWithLink(@NotNull String mainText, @NotNull String linkText, @NotNull Runnable onClick) { + VcsBalloonProblemNotifier.showOverChangesView(myProject, mainText, MessageType.WARNING, + new NamedRunnable(linkText) { + @Override + public void run() { + onClick.run(); + } + }); + } + @Override public void addLogListener(@NotNull VcsLogListener listener) { ApplicationManager.getApplication().assertIsDispatchThread(); 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 97c5f2828075..d0208295d0b5 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 @@ -5,9 +5,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.MessageType; -import com.intellij.openapi.util.NamedRunnable; -import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.util.PairFunction; import com.intellij.vcs.log.VcsLogFilterCollection; import com.intellij.vcs.log.VcsLogFilterUi; @@ -100,15 +97,11 @@ public class VcsLogUiImpl extends AbstractVcsLogUi { super.handleCommitNotFound(commitId, rowGetter); } else { - String message = "Commit " + commitId.toString() + " does not exist or does not match active filters"; - VcsBalloonProblemNotifier.showOverChangesView(myProject, message, MessageType.WARNING, - new NamedRunnable("Reset filters and search again.") { - @Override - public void run() { - getFilterUi().setFilter(null); - invokeOnChange(() -> jumpTo(commitId, rowGetter, SettableFuture.create())); - } - }); + showWarningWithLink("Commit " + commitId.toString() + " does not exist or does not match active filters", + "Reset filters and search again.", () -> { + getFilterUi().setFilter(null); + invokeOnChange(() -> jumpTo(commitId, rowGetter, SettableFuture.create())); + }); } }