diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java index d8cc4e0233..77e565c8d0 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java @@ -9,6 +9,7 @@ * Copyright (C) 2012, François Rey * Copyright (C) 2015, IBM Corporation (Dani Megert ) * Copyright (C) 2015, Thomas Wolf + * Copyright (C) 2015, Stefan Dirix (Stefan Dirix ) * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -55,6 +56,7 @@ import org.eclipse.egit.ui.internal.repository.tree.RefNode; import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode; import org.eclipse.egit.ui.internal.repository.tree.TagNode; +import org.eclipse.egit.ui.internal.selection.SelectionUtils; import org.eclipse.egit.ui.internal.trace.GitTraceLocation; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jface.action.Action; @@ -1341,17 +1343,32 @@ public void run() { @Override public boolean setInput(Object object) { try { + Object useAsInput = object; + + // Workaround for the limitation of GenericHistoryView to only + // forward the first part of a selection and adapting it + // immediately to IResource. + ISelection selection = getSite().getPage().getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + HistoryPageInput mostFittingInput = SelectionUtils + .getMostFittingInput(structuredSelection, object); + if (mostFittingInput != null) { + useAsInput = mostFittingInput; + } + } + // hide the warning text initially setWarningText(null); trace = GitTraceLocation.HISTORYVIEW.isActive(); if (trace) GitTraceLocation.getTrace().traceEntry( - GitTraceLocation.HISTORYVIEW.getLocation(), object); + GitTraceLocation.HISTORYVIEW.getLocation(), useAsInput); - if (object == getInput()) + if (useAsInput == getInput()) return true; this.input = null; - return super.setInput(object); + return super.setInput(useAsInput); } finally { if (trace) GitTraceLocation.getTrace().traceExit( diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java index 4fbc7784c3..1d7f75b606 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -27,9 +28,11 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.egit.core.AdapterUtils; import org.eclipse.egit.core.internal.util.ResourceUtil; +import org.eclipse.egit.core.project.RepositoryMapping; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.egit.ui.internal.UIText; +import org.eclipse.egit.ui.internal.history.HistoryPageInput; import org.eclipse.egit.ui.internal.revision.FileRevisionEditorInput; import org.eclipse.egit.ui.internal.trace.GitTraceLocation; import org.eclipse.jgit.annotations.NonNull; @@ -165,12 +168,27 @@ public static IPath[] getSelectedLocations( } /** + * Returns the resources contained in the given selection. + * * @param selection * @return the resources in the selection */ @NonNull public static IResource[] getSelectedResources( @NonNull IStructuredSelection selection) { + Set result = getSelectedResourcesSet(selection); + return result.toArray(new IResource[result.size()]); + } + + /** + * Returns the resources contained in the given selection. + * + * @param selection + * @return the resources in the selection + */ + @NonNull + private static Set getSelectedResourcesSet( + @NonNull IStructuredSelection selection) { Set result = new LinkedHashSet(); for (Object o : selection.toList()) { ResourceMapping mapping = AdapterUtils.adapt(o, @@ -184,7 +202,7 @@ public static IResource[] getSelectedResources( } } - return result.toArray(new IResource[result.size()]); + return result; } private static List extractResourcesFromMapping( @@ -211,6 +229,51 @@ private static List extractResourcesFromMapping( return result; } + /** + * Determines the most fitting {@link HistoryPageInput} for the given + * {@link IStructuredSelection}. The {@code mandatoryObject} must be + * contained in the selection and in a repository. + *

+ * Most fitting means that the input will contain all selected resources + * which are contained in the same repository as the given + * {@code mandatoryObject}. + *

+ * + * @param selection + * The selection for which the most fitting HistoryPageInput is + * to be determined. + * @param mandatoryObject + * The object to which the HistoryPageInput is tailored. Must be + * contained in the given selection and in a repository. + * @return The most fitting HistoryPageInput. Will return {@code null} when + * the {@code mandatoryObject} is not contained in the given + * selection or in a repository. + */ + @Nullable + public static HistoryPageInput getMostFittingInput( + @NonNull IStructuredSelection selection, Object mandatoryObject) { + Set resources = getSelectedResourcesSet(selection); + if (!resources.contains(mandatoryObject)) { + return null; + } + + Repository repository = getRepository((IResource) mandatoryObject); + if (repository == null) { + return null; + } + + for (Iterator it = resources.iterator(); it.hasNext();) { + IResource resource = it.next(); + if (getRepository(resource) != repository) { + it.remove(); + } + } + + IResource[] resourceArray = resources.toArray(new IResource[resources + .size()]); + return new HistoryPageInput(repository, resourceArray); + } + /** * Determines a set of either {@link IResource}s or {@link IPath}s from a * selection. For selection contents that adapt to {@link IResource} or @@ -363,4 +426,17 @@ private static IEvaluationContext getEvaluationContext() { return ctx; } + @Nullable + private static Repository getRepository(IResource resource) { + IPath location = resource.getLocation(); + if (location != null) { + RepositoryMapping repositoryMapping = RepositoryMapping + .getMapping(location); + if (repositoryMapping != null) { + return repositoryMapping.getRepository(); + } + } + return null; + } + }