Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--icons/org.eclipse.egit.ui/icons/elcl16/filter_none.svg253
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/rebase/RebaseInteractivePlan.java15
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/selection/SelectionForViewsTest.java233
-rw-r--r--org.eclipse.egit.ui/icons/elcl16/filter_none.pngbin0 -> 723 bytes
-rw-r--r--org.eclipse.egit.ui/icons/elcl16/filter_none@2x.pngbin0 -> 1314 bytes
-rw-r--r--org.eclipse.egit.ui/plugin.xml14
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java9
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java313
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java17
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java49
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseInteractiveView.java80
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogItem.java94
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java55
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java25
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java8
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/AbstractSelectionProvider.java88
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/MultiViewerSelectionProvider.java110
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/RepositorySelectionProvider.java77
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java236
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties5
23 files changed, 1510 insertions, 183 deletions
diff --git a/icons/org.eclipse.egit.ui/icons/elcl16/filter_none.svg b/icons/org.eclipse.egit.ui/icons/elcl16/filter_none.svg
new file mode 100644
index 0000000000..6deb5835d8
--- /dev/null
+++ b/icons/org.eclipse.egit.ui/icons/elcl16/filter_none.svg
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.2 r9819"
+ sodipodi:docname="filter_none.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5103">
+ <stop
+ style="stop-color:#fefdef;stop-opacity:1"
+ offset="0"
+ id="stop5105" />
+ <stop
+ style="stop-color:#fce69e;stop-opacity:1"
+ offset="1"
+ id="stop5107" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4922">
+ <stop
+ style="stop-color:#77849a;stop-opacity:1"
+ offset="0"
+ id="stop4924" />
+ <stop
+ style="stop-color:#38445d;stop-opacity:1"
+ offset="1"
+ id="stop4926" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4878">
+ <stop
+ style="stop-color:#4e8fbd;stop-opacity:1"
+ offset="0"
+ id="stop4880" />
+ <stop
+ style="stop-color:#4d5a5d;stop-opacity:1"
+ offset="1"
+ id="stop4882" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4878"
+ id="linearGradient4884"
+ x1="0"
+ y1="13.5"
+ x2="7.9998932"
+ y2="13.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4878-7">
+ <stop
+ style="stop-color:#4e8fbd;stop-opacity:1"
+ offset="0"
+ id="stop4880-4" />
+ <stop
+ style="stop-color:#4d5a5d;stop-opacity:1"
+ offset="1"
+ id="stop4882-0" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(0,1026.3622)"
+ y2="13.5"
+ x2="7.9998932"
+ y1="13.5"
+ x1="0"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4901"
+ xlink:href="#linearGradient4878-7"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4922"
+ id="linearGradient4929"
+ x1="10"
+ y1="1"
+ x2="10"
+ y2="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1036.3622)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4922-8">
+ <stop
+ style="stop-color:#77849a;stop-opacity:1"
+ offset="0"
+ id="stop4924-8" />
+ <stop
+ style="stop-color:#38445d;stop-opacity:1"
+ offset="1"
+ id="stop4926-2" />
+ </linearGradient>
+ <linearGradient
+ y2="6"
+ x2="10"
+ y1="1"
+ x1="10"
+ gradientTransform="translate(0,-1053.3622)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4946"
+ xlink:href="#linearGradient4922-8"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5103"
+ id="linearGradient5109"
+ x1="11.906143"
+ y1="1042.3622"
+ x2="11.906143"
+ y2="1047.2684"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ color-interpolation-filters="sRGB"
+ inkscape:collect="always"
+ id="filter4764">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.125"
+ id="feGaussianBlur4766" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="8.622948"
+ inkscape:cy="8.030652"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1241"
+ inkscape:window-height="814"
+ inkscape:window-x="275"
+ inkscape:window-y="275"
+ inkscape:window-maximized="0"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3999"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="fill:url(#linearGradient4884);stroke:none;fill-opacity:1;opacity:0.5"
+ d="m 0,13 0,1 5,0 0,2 L 7.9998932,13.5 5,11 5,13 z"
+ id="path4108"
+ inkscape:connector-curvature="0"
+ transform="translate(0,1036.3622)"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:url(#linearGradient4901);fill-opacity:1;stroke:none;display:inline;opacity:0.3"
+ d="m 0,1039.3622 0,1 5,0 0,2 2.9998932,-2.5 -2.9998932,-2.5 0,2 z"
+ id="path4108-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <rect
+ style="fill:url(#linearGradient4929);fill-opacity:1;stroke:none;opacity:0.5"
+ id="rect4920"
+ width="1"
+ height="5"
+ x="9"
+ y="1037.3622" />
+ <rect
+ style="fill:url(#linearGradient4946);fill-opacity:1;stroke:none;display:inline;opacity:0.5"
+ id="rect4920-4"
+ width="1"
+ height="5"
+ x="9"
+ y="-1052.3622"
+ transform="scale(1,-1)" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path4744"
+ style="font-size:7.60321283px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
+ d="m 22.25,1045.6747 0,-6 4,0 0,1 -3,0 0,1 2,0 0,1 -2,0 0,3 z" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path4744-9"
+ style="font-size:7.60321283px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;opacity:0.5;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;filter:url(#filter4764);font-family:Arial;-inkscape-font-specification:Arial"
+ d="m 22.382582,1045.8073 0,-6 4,0 0,1 -3,0 0,1 2,0 0,1 -2,0 0,3 z" />
+ <g
+ id="g3039"
+ transform="matrix(1.0000319,0,0,1,-15.438502,1.6875)">
+ <path
+ style="font-size:7.60321283px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000f6f;fill-opacity:1;stroke:#6f99c7;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Arial;-inkscape-font-specification:Arial"
+ d="m 16.9375,1035.6747 14,14"
+ id="path4792-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:7.60321283px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000f6f;fill-opacity:1;stroke:#000f6f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
+ d="m 16.25,1035.6747 14,14"
+ id="path4792"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:url(#linearGradient5109);fill-opacity:1;stroke:none;display:inline"
+ d="m 5,1044.3622 0,1 7,0 0,2 2.999893,-2.5 -2.999893,-2.5 0,2 z"
+ id="path4108-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#b57a13;fill-opacity:1;stroke:none;display:inline;opacity:1"
+ d="m 11,1041.3622 0,2 -5,0 -1,0 c -0.9918497,0.9918 -0.9863244,2.0137 0,3 l 1,0 5,0 0,2 c 0,0.6519 0.740915,0.6375 1.5,0 l 3.9375,-3.5 -3.9375,-3.5 c -0.760225,-0.7602 -1.5,-0.5203 -1.5,0 z m 1,1 3,2.5 -3,2.5 0,-2 -6.4375,0 c -0.2762136,-0.2099 -0.2774437,-0.7282 0,-1 l 6.4375,0 z"
+ id="path4108-1-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccc" />
+ </g>
+</svg>
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
index 21e7c3a4ea..b187aee1ce 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
@@ -525,10 +525,10 @@ public class RepositoryUtil {
sbAbsolute.append(File.pathSeparatorChar);
}
- prefs.put(PREFS_DIRECTORIES_REL, sbRelative.toString());
// redundantly store absolute paths to ensure compatibility with older
// EGit versions
prefs.put(PREFS_DIRECTORIES, sbAbsolute.toString());
+ prefs.put(PREFS_DIRECTORIES_REL, sbRelative.toString());
try {
prefs.flush();
} catch (BackingStoreException e) {
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/rebase/RebaseInteractivePlan.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/rebase/RebaseInteractivePlan.java
index 71be792485..d094a76572 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/rebase/RebaseInteractivePlan.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/rebase/RebaseInteractivePlan.java
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
@@ -456,7 +457,7 @@ public class RebaseInteractivePlan implements IndexDiffChangedListener,
* This class wraps a {@link RebaseTodoLine} and holds additional
* information about the underlying commit, if available.
*/
- public class PlanElement {
+ public class PlanElement implements IAdaptable {
private final RebaseTodoLine line;
/** author info, may be null */
@@ -673,6 +674,18 @@ public class RebaseInteractivePlan implements IndexDiffChangedListener,
public String toString() {
return line.toString();
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object getAdapter(Class adapter) {
+ // TODO generify once EGit baseline is Eclipse 4.5
+ if (adapter.isInstance(this)) {
+ return this;
+ } else if (Repository.class.equals(adapter)) {
+ return repositoryRef.get();
+ }
+ return null;
+ }
}
/**
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/selection/SelectionForViewsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/selection/SelectionForViewsTest.java
new file mode 100644
index 0000000000..f15537fbdd
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/selection/SelectionForViewsTest.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.selection;
+
+import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.egit.core.AdapterUtils;
+import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.op.CloneOperation;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.rebase.RebaseInteractiveView;
+import org.eclipse.egit.ui.internal.reflog.ReflogView;
+import org.eclipse.egit.ui.internal.repository.RepositoriesView;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
+import org.eclipse.egit.ui.internal.staging.StagingView;
+import org.eclipse.egit.ui.test.TestUtil;
+import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestBase;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarDropDownButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.team.internal.ui.history.GenericHistoryView;
+import org.eclipse.team.ui.history.IHistoryView;
+import org.eclipse.ui.PlatformUI;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for EGit views reacting on repository changes.
+ */
+@SuppressWarnings("restriction")
+@RunWith(SWTBotJunit4ClassRunner.class)
+public class SelectionForViewsTest extends GitRepositoriesViewTestBase {
+
+ private File localRepositoryDir; // Normal repo
+
+ private File remoteRepositoryDir; // Bare repo
+
+ private File clonedRepositoryDir; // 2nd normal repo
+
+ private SWTBotView stagingView;
+
+ private SWTBotView reflogView;
+
+ private SWTBotView rebaseInteractiveView;
+
+ private SWTBotView historyView;
+
+ private SWTBotView repoView;
+
+ @Before
+ public void before() throws Exception {
+ localRepositoryDir = createProjectAndCommitToRepository();
+ remoteRepositoryDir = createRemoteRepository(localRepositoryDir);
+ URIish uri = new URIish("file:///" + remoteRepositoryDir.getPath());
+ File workdir = new File(getTestDirectory(), "ClonedRepo");
+ CloneOperation op = new CloneOperation(uri, true, null, workdir,
+ "refs/heads/master", "origin", 0);
+ op.run(null);
+ clonedRepositoryDir = new File(workdir, Constants.DOT_GIT);
+ RepositoryUtil repoUtil = Activator.getDefault().getRepositoryUtil();
+ repoUtil.addConfiguredRepository(localRepositoryDir);
+ repoUtil.addConfiguredRepository(clonedRepositoryDir);
+ repoUtil.addConfiguredRepository(remoteRepositoryDir); // it's bare
+ stagingView = TestUtil.showView(StagingView.VIEW_ID);
+ reflogView = TestUtil.showView(ReflogView.VIEW_ID);
+ rebaseInteractiveView = TestUtil
+ .showView(RebaseInteractiveView.VIEW_ID);
+ repoView = TestUtil.showView(RepositoriesView.VIEW_ID);
+ RepositoriesView repos = (RepositoriesView) repoView.getViewReference()
+ .getView(false);
+ repos.setReactOnSelection(true);
+ historyView = TestUtil.showHistoryView();
+ IHistoryView history = (IHistoryView) historyView.getViewReference()
+ .getView(false);
+ ((GenericHistoryView) history).setLinkingEnabled(true);
+ // Ensure that the git history page is active
+ Exception[] exception = { null };
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ try {
+ history.showHistoryFor(new RepositoryNode(null,
+ lookupRepository(localRepositoryDir)), true);
+ } catch (Exception e) {
+ exception[0] = e;
+ }
+ });
+ if (exception[0] != null) {
+ throw exception[0];
+ }
+ waitForRefreshes();
+ }
+
+ @After
+ public void after() {
+ RepositoriesView repos = (RepositoriesView) repoView.getViewReference()
+ .getView(false);
+ repos.setReactOnSelection(false);
+ IHistoryView history = (IHistoryView) historyView.getViewReference()
+ .getView(false);
+ ((GenericHistoryView) history).setLinkingEnabled(false);
+ stagingView = null;
+ reflogView = null;
+ rebaseInteractiveView = null;
+ historyView = null;
+ repoView = null;
+ }
+
+ private void assertRepoSelection(SWTBotView view, File repoDir)
+ throws Exception {
+ view.show();
+ waitForRefreshes();
+ String viewId = view.getViewReference().getId();
+ ISelectionProvider selectionProvider = view.getViewReference()
+ .getView(false).getViewSite().getSelectionProvider();
+ assertNotNull("No selection provider " + viewId, selectionProvider);
+ ISelection selection = UIThreadRunnable
+ .syncExec(() -> selectionProvider.getSelection());
+ assertTrue("Expected an IStructuredSelection " + viewId,
+ selection instanceof IStructuredSelection);
+ assertFalse("Expected a non-empty selection " + viewId,
+ selection.isEmpty());
+ Object firstElement = ((IStructuredSelection) selection)
+ .getFirstElement();
+ assertNotNull("Null in selection " + viewId, firstElement);
+ Repository repo = AdapterUtils.adapt(firstElement, Repository.class);
+ assertNotNull("Expected a repository " + viewId + ", but "
+ + firstElement.getClass().getName()
+ + " doesn't adapt to Repository", repo);
+ assertEquals("Wrong directory " + viewId, repoDir, repo.getDirectory());
+ }
+
+ private void assertAllViews(File repoDir) throws Exception {
+ assertRepoSelection(repoView, repoDir);
+ assertRepoSelection(reflogView, repoDir);
+ assertRepoSelection(rebaseInteractiveView, repoDir);
+ assertRepoSelection(stagingView, repoDir);
+ assertRepoSelection(historyView, repoDir);
+ }
+
+ private void waitForRefreshes() throws Exception {
+ TestUtil.joinJobs(JobFamilies.GENERATE_HISTORY);
+ TestUtil.joinJobs(JobFamilies.STAGING_VIEW_RELOAD);
+ // Join UI update triggered by GenerateHistoryJob
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ // Nothing
+ });
+ refreshAndWait();
+ }
+
+ private String repositoryName(File repoDir) throws Exception {
+ return org.eclipse.egit.core.Activator.getDefault().getRepositoryUtil()
+ .getRepositoryName(lookupRepository(repoDir));
+ }
+
+ @Test
+ public void testViewsReactOnRepoViewSelection() throws Exception {
+ repoView.show();
+ repoView.setFocus();
+ SWTBotTree tree = repoView.bot().tree();
+ SWTBotTreeItem repoNode = myRepoViewUtil.getRootItem(tree,
+ clonedRepositoryDir);
+ repoNode.select();
+ assertAllViews(clonedRepositoryDir);
+ }
+
+ @Test
+ public void testViewsReactOnBareRepoViewSelection() throws Exception {
+ repoView.show();
+ repoView.setFocus();
+ SWTBotTree tree = repoView.bot().tree();
+ SWTBotTreeItem repoNode = myRepoViewUtil.getRootItem(tree,
+ remoteRepositoryDir);
+ repoNode.select();
+ assertAllViews(remoteRepositoryDir);
+ }
+
+ @Ignore("Doesn't work for an unknown reason. Other views do not update in test, while this works in production.")
+ @Test
+ public void testViewsReactOnRepoSwitchInStaging() throws Exception {
+ stagingView.show();
+ stagingView.setFocus();
+ waitForRefreshes();
+ SWTBotToolbarDropDownButton button = stagingView
+ .toolbarDropDownButton(UIText.RepositoryToolbarAction_tooltip);
+ button.menuItem(allOf(instanceOf(MenuItem.class),
+ withMnemonic(repositoryName(clonedRepositoryDir)))).click();
+ TestUtil.joinJobs(JobFamilies.STAGING_VIEW_RELOAD);
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ // Nothing
+ });
+ assertAllViews(clonedRepositoryDir);
+ stagingView.show();
+ stagingView.setFocus();
+ waitForRefreshes();
+ button = stagingView
+ .toolbarDropDownButton(UIText.RepositoryToolbarAction_tooltip);
+ button.menuItem(allOf(instanceOf(MenuItem.class),
+ withMnemonic(repositoryName(clonedRepositoryDir)))).click();
+ TestUtil.joinJobs(JobFamilies.STAGING_VIEW_RELOAD);
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ // Nothing
+ });
+ assertAllViews(localRepositoryDir);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.egit.ui/icons/elcl16/filter_none.png b/org.eclipse.egit.ui/icons/elcl16/filter_none.png
new file mode 100644
index 0000000000..36beea9d76
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/elcl16/filter_none.png
Binary files differ
diff --git a/org.eclipse.egit.ui/icons/elcl16/filter_none@2x.png b/org.eclipse.egit.ui/icons/elcl16/filter_none@2x.png
new file mode 100644
index 0000000000..795309f533
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/elcl16/filter_none@2x.png
Binary files differ
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 37b3f6735f..eb2464f264 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -120,6 +120,20 @@
</adapter>
</factory>
<factory
+ adaptableType="org.eclipse.egit.ui.internal.reflog.ReflogItem"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.team.ui.history.IHistoryPageSource">
+ </adapter>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.core.internal.rebase.RebaseInteractivePlan$PlanElement"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.team.ui.history.IHistoryPageSource">
+ </adapter>
+ </factory>
+ <factory
adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelRoot"
class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
<adapter
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
index 06af3f6c62..dd1a37ca44 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
@@ -216,4 +216,10 @@ public class JobFamilies {
* Stash git job
*/
public static final Object STASH = new JobFamily(UIIcons.STASH);
+
+ /**
+ * Staging view reload
+ */
+ public static final Object STAGING_VIEW_RELOAD = new JobFamily();
+
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
index 08db44c505..c4c6b6c9e6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
@@ -141,6 +141,9 @@ public class UIIcons {
/** Synchronize Wizard banner */
public final static ImageDescriptor WIZBAN_SYNCHRONIZE;
+ /** History view, show full repo history */
+ public final static ImageDescriptor FILTERNONE;
+
/** History view, select all version in same project */
public final static ImageDescriptor FILTERPROJECT;
@@ -380,6 +383,7 @@ public class UIIcons {
CHECKBOX_ENABLED_UNCHECKED = map("checkboxes/enabled_unchecked.png"); //$NON-NLS-1$
CHECKBOX_DISABLED_CHECKED = map("checkboxes/disabled_checked.png"); //$NON-NLS-1$
CHECKBOX_DISABLED_UNCHECKED = map("checkboxes/disabled_unchecked.png"); //$NON-NLS-1$
+ FILTERNONE = map("elcl16/filter_none.png"); //$NON-NLS-1$
FILTERRESOURCE = map("elcl16/filterresource.png"); //$NON-NLS-1$
FILTERPROJECT = map("elcl16/filterproject.png"); //$NON-NLS-1$
FILTERFOLDER = map("elcl16/filterfolder.png"); //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index 311295ef17..48453bcf7a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -1322,6 +1322,12 @@ public class UIText extends NLS {
public static String RepositoryAction_multiRepoSelectionTitle;
/** */
+ public static String RepositoryToolbarAction_label;
+
+ /** */
+ public static String RepositoryToolbarAction_tooltip;
+
+ /** */
public static String RepositoryCommit_AuthorDate;
/** */
@@ -5347,6 +5353,9 @@ public class UIText extends NLS {
public static String StagingView_MessageErrors;
/** */
+ public static String StagingView_LoadJob;
+
+ /** */
public static String StashApplyCommand_applyFailed;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java
new file mode 100644
index 0000000000..0ef1982142
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.components;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.egit.core.RepositoryCache;
+import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.CommonUtils;
+import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+
+/**
+ * Provides a way to populate a menu with a list of repositories.
+ */
+public final class RepositoryMenuUtil {
+
+ private RepositoryMenuUtil() {
+ // Utility class shall not be instantiated
+ }
+
+ /**
+ * Populates the given {@link IMenuManager} with a list of repositories.
+ * Each currently known configured repository is shown with its repository
+ * name and the path to the .git directory as tooltip; when a menu item is
+ * selected, the given {@code action} is invoked. Bare repositories can be
+ * excluded from the list. Menu items are sorted by repository name and .git
+ * directory paths.
+ *
+ * @param menuManager
+ * to populate with the list of repositories
+ * @param includeBare
+ * {@code true} if bare repositories should be included in the
+ * list, {@code false} otherwise
+ * @param currentRepoDir
+ * git directory of a repository that is to be marked as
+ * "current"; may be {@code null}.
+ * @param action
+ * to perform on the chosen repository
+ */
+ public static void fillRepositories(@NonNull IMenuManager menuManager,
+ boolean includeBare, @Nullable File currentRepoDir,
+ @NonNull Consumer<Repository> action) {
+ for (IAction item : getRepositoryActions(includeBare, currentRepoDir,
+ action)) {
+ menuManager.add(item);
+ }
+ }
+
+ /**
+ * Creates for each configured repository an {@link IAction} that will
+ * perform the given {@code action} when invoked.
+ *
+ * @param includeBare
+ * {@code true} if bare repositories should be included in the
+ * list, {@code false} otherwise
+ * @param currentRepoDir
+ * git directory of a repository that is to be marked as
+ * "current"; may be {@code null}.
+ * @param action
+ * to perform on the chosen repository
+ * @return the (possibly empty) list of actions
+ */
+ public static Collection<IAction> getRepositoryActions(boolean includeBare,
+ @Nullable File currentRepoDir,
+ @NonNull Consumer<Repository> action) {
+ RepositoryUtil util = org.eclipse.egit.core.Activator.getDefault()
+ .getRepositoryUtil();
+ RepositoryCache cache = org.eclipse.egit.core.Activator.getDefault()
+ .getRepositoryCache();
+ Set<String> repositories = util.getRepositories();
+ Map<String, Set<File>> repos = new HashMap<>();
+ for (String repo : repositories) {
+ File gitDir = new File(repo);
+ String name = null;
+ try {
+ Repository r = cache.lookupRepository(gitDir);
+ if (!includeBare && r.isBare()) {
+ continue;
+ }
+ name = util.getRepositoryName(r);
+ } catch (IOException e) {
+ continue;
+ }
+ Set<File> files = repos.get(name);
+ if (files == null) {
+ files = new HashSet<>();
+ files.add(gitDir);
+ repos.put(name, files);
+ } else {
+ files.add(gitDir);
+ }
+ }
+ String[] repoNames = repos.keySet().toArray(new String[repos.size()]);
+ Arrays.sort(repoNames, CommonUtils.STRING_ASCENDING_COMPARATOR);
+ List<IAction> result = new ArrayList<>();
+ for (String repoName : repoNames) {
+ Set<File> files = repos.get(repoName);
+ File[] gitDirs = files.toArray(new File[files.size()]);
+ Arrays.sort(gitDirs);
+ for (File f : gitDirs) {
+ IAction menuItem = new Action(repoName,
+ IAction.AS_RADIO_BUTTON) {
+ @Override
+ public void run() {
+ try {
+ Repository r = cache.lookupRepository(f);
+ action.accept(r);
+ } catch (IOException e) {
+ Activator.showError(e.getLocalizedMessage(), e);
+ }
+ }
+ };
+ menuItem.setToolTipText(f.getPath());
+ if (f.equals(currentRepoDir)) {
+ menuItem.setChecked(true);
+ }
+ result.add(menuItem);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Utility class facilitating creating toolbar actions that show a drop-down
+ * menu of all registered repositories, performing a given action on a
+ * selected repository.
+ */
+ public static class RepositoryToolbarAction extends Action
+ implements IWorkbenchAction, IMenuCreator {
+
+ private final RepositoryUtil util = org.eclipse.egit.core.Activator
+ .getDefault().getRepositoryUtil();
+
+ private final IEclipsePreferences preferences = util.getPreferences();
+
+ private final IPreferenceChangeListener listener;
+
+ private final @NonNull Consumer<Repository> action;
+
+ private final @NonNull Supplier<Repository> currentRepo;
+
+ private final boolean includeBare;
+
+ private Menu menu;
+
+ private boolean showMenu;
+
+ /**
+ * Creates a new {@link RepositoryToolbarAction} with the given
+ * {@code action} and default text, image, and tooltip.
+ *
+ * @param includeBare
+ * {@code true} if bare repositories shall be included,
+ * {@code false} otherwise
+ * @param currentRepo
+ * supplying the "current" repository, if any, or
+ * {@code null} otherwise
+ * @param action
+ * to run when a repository is selected from the drop-down
+ * menu
+ */
+ public RepositoryToolbarAction(boolean includeBare,
+ @NonNull Supplier<Repository> currentRepo,
+ @NonNull Consumer<Repository> action) {
+ this(UIText.RepositoryToolbarAction_label, UIIcons.REPOSITORY,
+ UIText.RepositoryToolbarAction_tooltip, includeBare,
+ currentRepo, action);
+ }
+
+ /**
+ * Creates a new {@link RepositoryToolbarAction} with the given text and
+ * the given {@code action}.
+ *
+ * @param text
+ * for the action
+ * @param image
+ * for the action
+ * @param tooltip
+ * for the action
+ * @param includeBare
+ * {@code true} if bare repositories shall be included,
+ * {@code false} otherwise
+ * @param currentRepo
+ * supplying the "current" repository, if any, or
+ * {@code null} otherwise
+ * @param action
+ * to run when a repository is selected from the drop-down
+ * menu
+ */
+ public RepositoryToolbarAction(String text,
+ @Nullable ImageDescriptor image, @Nullable String tooltip,
+ boolean includeBare, @NonNull Supplier<Repository> currentRepo,
+ @NonNull Consumer<Repository> action) {
+ super(text, IAction.AS_DROP_DOWN_MENU);
+ setImageDescriptor(image);
+ setToolTipText(tooltip == null ? text : tooltip);
+ this.includeBare = includeBare;
+ this.currentRepo = currentRepo;
+ this.action = action;
+ this.listener = event -> {
+ if (RepositoryUtil.PREFS_DIRECTORIES_REL
+ .equals(event.getKey())) {
+ setEnabled(!util.getRepositories().isEmpty());
+ }
+ };
+ setEnabled(!util.getRepositories().isEmpty());
+ preferences.addPreferenceChangeListener(listener);
+ }
+
+ @Override
+ public void run() {
+ showMenu = true;
+ }
+
+ @Override
+ public void runWithEvent(Event event) {
+ if (!isEnabled()) {
+ return;
+ }
+ // Show the menu also when the button is clicked, unless run() is
+ // overridden (and not called via super).
+ showMenu = false;
+ run();
+ Widget widget = event.widget;
+ if (showMenu && (widget instanceof ToolItem)) {
+ ToolItem item = (ToolItem) widget;
+ Rectangle bounds = item.getBounds();
+ event.detail = SWT.ARROW;
+ event.x = bounds.x;
+ event.y = bounds.y + bounds.height;
+ item.notifyListeners(SWT.Selection, event);
+ }
+ }
+
+ @Override
+ public IMenuCreator getMenuCreator() {
+ return this;
+ }
+
+ @Override
+ public Menu getMenu(Control parent) {
+ if (menu != null) {
+ menu.dispose();
+ menu = null;
+ }
+ if (isEnabled()) {
+ Repository current = currentRepo.get();
+ File gitDir = current == null ? null : current.getDirectory();
+ Collection<IAction> actions = RepositoryMenuUtil
+ .getRepositoryActions(includeBare, gitDir, action);
+ menu = new Menu(parent);
+ for (IAction a : actions) {
+ ActionContributionItem item = new ActionContributionItem(a);
+ item.fill(menu, -1);
+ }
+ }
+ return menu;
+ }
+
+ @Override
+ public Menu getMenu(Menu parent) {
+ // Not used
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ if (menu != null) {
+ menu.dispose();
+ menu = null;
+ }
+ preferences.removePreferenceChangeListener(listener);
+ }
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
index 0f4a9d4b49..8e741782dd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
@@ -377,12 +377,14 @@ class CommitGraphTable {
void setInput(final RevFlag hFlag, final SWTCommitList list,
final SWTCommit[] asArray, HistoryPageInput input, boolean keepPosition) {
int topIndex = -1;
- if (keepPosition)
+ if (keepPosition) {
topIndex = table.getTable().getTopIndex();
+ }
setHistoryPageInput(input);
final SWTCommitList oldList = allCommits;
- if (oldList != null && oldList != list)
+ if (oldList != null && oldList != list) {
oldList.dispose();
+ }
highlight = hFlag;
allCommits = list;
int newAllCommitsLength = allCommits.size();
@@ -390,13 +392,18 @@ class CommitGraphTable {
if (asArray != null && asArray.length > 0) {
if (oldList != list || allCommitsLength < newAllCommitsLength)
initCommitsMap();
- } else
+ } else {
table.getTable().deselectAll();
+ // Fire an event
+ table.setSelection(table.getSelection());
+ }
allCommitsLength = newAllCommitsLength;
- if (commitToShow != null)
+ if (commitToShow != null) {
selectCommit(commitToShow);
- if (keepPosition)
+ }
+ if (keepPosition) {
table.getTable().setTopIndex(topIndex);
+ }
}
void setHistoryPageInput(HistoryPageInput input) {
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 bdbef9fc86..bcf75950d2 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
@@ -8,7 +8,7 @@
* Copyright (C) 2012-2013 Robin Stocker <robin@nibor.org>
* Copyright (C) 2012, Fran├žois Rey <eclipse.org_@_francois_._rey_._name>
* Copyright (C) 2015, IBM Corporation (Dani Megert <daniel_megert@ch.ibm.com>)
- * Copyright (C) 2015-2016 Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2015-2017 Thomas Wolf <thomas.wolf@paranor.ch>
* Copyright (C) 2015-2017, Stefan Dirix <sdirix@eclipsesource.com>
*
* All rights reserved. This program and the accompanying materials
@@ -50,6 +50,7 @@ import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.commit.DiffDocument;
import org.eclipse.egit.ui.internal.commit.DiffRegionFormatter;
import org.eclipse.egit.ui.internal.commit.DiffViewer;
+import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.dialogs.HyperlinkSourceViewer;
import org.eclipse.egit.ui.internal.dialogs.HyperlinkTokenScanner;
import org.eclipse.egit.ui.internal.fetch.FetchHeadChangedEvent;
@@ -58,8 +59,10 @@ import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
import org.eclipse.egit.ui.internal.repository.tree.FileNode;
import org.eclipse.egit.ui.internal.repository.tree.FolderNode;
import org.eclipse.egit.ui.internal.repository.tree.RefNode;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
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.RepositorySelectionProvider;
import org.eclipse.egit.ui.internal.selection.SelectionUtils;
import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
import org.eclipse.jface.action.Action;
@@ -102,6 +105,7 @@ import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.diff.DiffConfig;
import org.eclipse.jgit.diff.DiffEntry;
@@ -321,6 +325,8 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
ShowFilterAction showAllResourceVersionsAction;
+ RepositoryToolbarAction switchRepositoryAction;
+
private GitHistoryPage historyPage;
GitHistoryPageActions(GitHistoryPage historyPage) {
@@ -335,6 +341,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
}
private void createActions() {
+ createRepositorySwitchAction();
createFindToolbarAction();
createRefreshAction();
createFilterActions();
@@ -357,6 +364,31 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
fillCommentAction.setEnabled(showCommentAction.isChecked());
}
+ private void createRepositorySwitchAction() {
+ switchRepositoryAction = new RepositoryToolbarAction(true,
+ () -> historyPage.currentRepo,
+ repo -> {
+ Repository current = historyPage.currentRepo;
+ if (current != null && repo.getDirectory()
+ .equals(current.getDirectory())) {
+ HistoryPageInput currentInput = historyPage
+ .getInputInternal();
+ if (currentInput != null
+ && currentInput.getItems() == null
+ && currentInput.getFileList() == null) {
+ // Already showing this repo unfiltered
+ return;
+ }
+ }
+ if (historyPage.selectionTracker != null) {
+ historyPage.selectionTracker.clearSelection();
+ }
+ historyPage.getHistoryView()
+ .showHistoryFor(new RepositoryNode(null, repo));
+ });
+ actionsToDispose.add(switchRepositoryAction);
+ }
+
private void createFindToolbarAction() {
findAction = new Action(UIText.GitHistoryPage_FindMenuLabel,
UIIcons.ELCL16_FIND) {
@@ -416,7 +448,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
private void createFilterActions() {
showAllRepoVersionsAction = new ShowFilterAction(
- ShowFilter.SHOWALLREPO, UIIcons.REPOSITORY,
+ ShowFilter.SHOWALLREPO, UIIcons.FILTERNONE,
UIText.GitHistoryPage_AllInRepoMenuLabel,
UIText.GitHistoryPage_AllInRepoTooltip);
@@ -1285,7 +1317,11 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
attachCommitSelectionChanged();
initActions();
- getSite().setSelectionProvider(graph.getTableView());
+ getSite().setSelectionProvider(
+ new RepositorySelectionProvider(graph.getTableView(), () -> {
+ HistoryPageInput myInput = getInputInternal();
+ return myInput != null ? myInput.getRepository() : null;
+ }));
getSite().registerContextMenu(POPUP_ID, popupMgr, graph.getTableView());
// due to the issues described in bug 322751, it makes no
// sense to set a selection provider for the site here
@@ -1451,6 +1487,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
private void setupToolBar() {
IToolBarManager mgr = getSite().getActionBars().getToolBarManager();
mgr.add(actions.findAction);
+ mgr.add(actions.switchRepositoryAction);
mgr.add(new Separator());
mgr.add(actions.showAllRepoVersionsAction);
mgr.add(actions.showAllProjectVersionsAction);
@@ -2164,9 +2201,13 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
AnyObjectId headId = resolveHead(db, true);
if (headId == null) {
- graph.getTableView().setInput(new SWTCommit[0]);
+ TableViewer viewer = graph.getTableView();
+ viewer.setInput(new SWTCommit[0]);
currentHeadId = null;
currentFetchHeadId = null;
+ currentRepo = db;
+ // Force a selection changed event
+ viewer.setSelection(viewer.getSelection());
return;
}
AnyObjectId fetchHeadId = resolveFetchHead(db);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseInteractiveView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseInteractiveView.java
index a693716abb..cb14c20966 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseInteractiveView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseInteractiveView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2016 SAP AG and others.
+ * Copyright (c) 2013, 2017 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,7 @@
* Contributors:
* Tobias Pfeifer (SAP AG) - initial implementation
* Tobias Baumann (tobbaumann@gmail.com) - Bug 473950
- * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 477248, 460595
+ * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 477248, 460595, 518607
*******************************************************************************/
package org.eclipse.egit.ui.internal.rebase;
@@ -44,8 +44,10 @@ import org.eclipse.egit.ui.internal.commands.shared.ProcessStepsRebaseCommand;
import org.eclipse.egit.ui.internal.commands.shared.SkipRebaseCommand;
import org.eclipse.egit.ui.internal.commit.CommitEditor;
import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
+import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.repository.RepositoriesView;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
+import org.eclipse.egit.ui.internal.selection.RepositorySelectionProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
@@ -114,6 +116,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.ViewPart;
@@ -175,22 +178,12 @@ public class RebaseInteractiveView extends ViewPart implements
private IPropertyChangeListener uiPrefsListener;
- private InitialSelection initialSelection;
+ private IWorkbenchAction switchRepositoriesAction;
@Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
setPartName(UIText.InteractiveRebaseView_this_partName);
- initInitialSelection(site);
- }
-
- private void initInitialSelection(IViewSite site) {
- this.initialSelection = new InitialSelection(
- site.getWorkbenchWindow().getSelectionService().getSelection());
- if (!isViewInputDerivableFromSelection(initialSelection.selection)) {
- this.initialSelection.activeEditor = site.getPage()
- .getActiveEditor();
- }
}
private static boolean isViewInputDerivableFromSelection(Object o) {
@@ -205,6 +198,10 @@ public class RebaseInteractiveView extends ViewPart implements
* @param o
*/
public void setInput(Object o) {
+ newInput(o, true);
+ }
+
+ private void newInput(Object o, boolean force) {
if (o == null)
return;
@@ -230,7 +227,9 @@ public class RebaseInteractiveView extends ViewPart implements
if (repo == null) {
repo = AdapterUtils.adapt(o, Repository.class);
}
-
+ if (repo == null && !force) {
+ return;
+ }
currentRepository = repo;
showRepository(repo);
}
@@ -246,6 +245,10 @@ public class RebaseInteractiveView extends ViewPart implements
public void dispose() {
removeListeners();
resources.dispose();
+ if (switchRepositoriesAction != null) {
+ switchRepositoriesAction.dispose();
+ switchRepositoriesAction = null;
+ }
super.dispose();
}
@@ -393,7 +396,17 @@ public class RebaseInteractiveView extends ViewPart implements
linkSelectionAction.setImageDescriptor(UIIcons.ELCL16_SYNCED);
toolbar.add(linkSelectionAction);
- reactOnInitalSelection();
+ switchRepositoriesAction = new RepositoryToolbarAction(false,
+ () -> currentRepository,
+ repo -> setInput(new StructuredSelection(repo)));
+ toolbar.add(switchRepositoriesAction);
+
+ UIUtils.notifySelectionChangedWithCurrentSelection(
+ selectionChangedListener, getSite());
+
+ getSite().setSelectionProvider(new RepositorySelectionProvider(
+ planTreeViewer, () -> currentRepository));
+
}
private void createCommandToolBar(Form theForm, FormToolkit toolkit) {
@@ -508,17 +521,21 @@ public class RebaseInteractiveView extends ViewPart implements
public void selectionChanged(IWorkbenchPart part,
ISelection selection) {
if (!listenOnRepositoryViewSelection
- || part == getSite().getPart())
+ || part == getSite().getPart()) {
return;
-
+ }
// this may happen if we switch between editors
if (part instanceof IEditorPart) {
IEditorInput input = ((IEditorPart) part).getEditorInput();
- if (input instanceof IFileEditorInput)
- setInput(new StructuredSelection(
- ((IFileEditorInput) input).getFile()));
- } else
- setInput(selection);
+ if (input instanceof IFileEditorInput) {
+ newInput(
+ new StructuredSelection(
+ ((IFileEditorInput) input).getFile()),
+ false);
+ }
+ } else {
+ newInput(selection, false);
+ }
}
};
@@ -526,22 +543,6 @@ public class RebaseInteractiveView extends ViewPart implements
srv.addPostSelectionListener(selectionChangedListener);
}
- private void reactOnInitalSelection() {
- selectionChangedListener.selectionChanged(initialSelection.activeEditor,
- initialSelection.selection);
- this.initialSelection = null;
- }
-
- private static final class InitialSelection {
- ISelection selection;
-
- IEditorPart activeEditor;
-
- InitialSelection(ISelection selection) {
- this.selection = selection;
- }
- }
-
private class RebaseCommandItemSelectionListener extends SelectionAdapter {
private final AbstractRebaseCommandHandler command;
@@ -911,7 +912,6 @@ public class RebaseInteractiveView extends ViewPart implements
} else {
currentPlan = null;
planIndexer = null;
- form.setText(UIText.RebaseInteractiveView_NoSelection);
}
refresh();
}
@@ -934,6 +934,8 @@ public class RebaseInteractiveView extends ViewPart implements
try {
planTreeViewer.setInput(currentPlan);
refreshUI();
+ // Force a selection changed event
+ planTreeViewer.setSelection(planTreeViewer.getSelection());
} finally {
t.setRedraw(true);
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogItem.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogItem.java
new file mode 100644
index 0000000000..d168aa63f1
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogItem.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.reflog;
+
+import java.util.Objects;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.egit.ui.internal.reflog.ReflogViewContentProvider.ReflogInput;
+import org.eclipse.jgit.lib.CheckoutEntry;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * A DTO for {@link ReflogEntry} to use as tree elements in the reflog view.
+ * Also adapts to the repository the item was loaded from.
+ */
+public class ReflogItem implements ReflogEntry, IAdaptable {
+
+ private final ReflogEntry entry;
+
+ private final ReflogInput input;
+
+ ReflogItem(ReflogInput input, ReflogEntry entry) {
+ this.entry = entry;
+ this.input = input;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object getAdapter(Class adapter) {
+ // TODO generify once EGit base version is Eclipse 4.5
+ if (adapter.isInstance(this)) {
+ return this;
+ } else if (Repository.class.equals(adapter)) {
+ return input.getRepository();
+ }
+ return null;
+ }
+
+ @Override
+ public ObjectId getOldId() {
+ return entry.getOldId();
+ }
+
+ @Override
+ public ObjectId getNewId() {
+ return entry.getNewId();
+ }
+
+ @Override
+ public PersonIdent getWho() {
+ return entry.getWho();
+ }
+
+ @Override
+ public String getComment() {
+ return entry.getComment();
+ }
+
+ @Override
+ public CheckoutEntry parseCheckout() {
+ return entry.parseCheckout();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof ReflogItem)) {
+ return false;
+ }
+ ReflogItem other = (ReflogItem) obj;
+ return input == other.input
+ && Objects.equals(getNewId(), other.getNewId())
+ && Objects.equals(getOldId(), other.getOldId())
+ && Objects.equals(getWho(), other.getWho())
+ && Objects.equals(getComment(), other.getComment());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(input, getNewId(), getOldId(), getWho(),
+ getComment());
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
index 4c7ad0791d..1c341a27b0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 Chris Aniszczyk <caniszczyk@gmail.com> and others.
+ * Copyright (c) 2011, 2017 Chris Aniszczyk <caniszczyk@gmail.com> and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
* EclipseSource - Filtered Viewer
* Robin Stocker <robin@nibor.org> - Show In support
* Tobias Baumann <tobbaumann@gmail.com> - Bug 475836
- * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 477248
+ * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 477248, 518607
*******************************************************************************/
package org.eclipse.egit.ui.internal.reflog;
@@ -29,8 +29,10 @@ import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.actions.ResetMenu;
import org.eclipse.egit.ui.internal.commit.CommitEditor;
import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
+import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.reflog.ReflogViewContentProvider.ReflogInput;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
+import org.eclipse.egit.ui.internal.selection.RepositorySelectionProvider;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
@@ -48,7 +50,6 @@ import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
@@ -85,6 +86,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.OpenAndLinkWithEditorHelper;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
@@ -129,6 +131,8 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
private PreferenceBasedDateFormatter dateFormatter;
+ private IWorkbenchAction switchRepositoriesAction;
+
@Override
public void createPartControl(Composite parent) {
dateFormatter = PreferenceBasedDateFormatter.create();
@@ -146,8 +150,8 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
Image repoImage = UIIcons.REPOSITORY.createImage();
UIUtils.hookDisposal(form, repoImage);
- final Image branchImage = UIIcons.CHANGESET.createImage();
- UIUtils.hookDisposal(form, branchImage);
+ Image commitImage = UIIcons.CHANGESET.createImage();
+ UIUtils.hookDisposal(form, commitImage);
form.setImage(repoImage);
form.setText(UIText.StagingView_NoSelectionTitle);
GridDataFactory.fillDefaults().grab(true, true).applyTo(form);
@@ -204,7 +208,7 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
@Override
public Image getImage(Object element) {
if (element instanceof ReflogEntry) {
- return branchImage;
+ return commitImage;
}
return null;
}
@@ -381,11 +385,22 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
UIUtils.notifySelectionChangedWithCurrentSelection(
selectionChangedListener, site);
- site.setSelectionProvider(refLogTableTreeViewer);
+ site.setSelectionProvider(new RepositorySelectionProvider(
+ refLogTableTreeViewer, () -> getRepository()));
+
+ // site.setSelectionProvider(refLogTableTreeViewer);
addRefsChangedListener = Repository.getGlobalListenerList()
.addRefsChangedListener(this);
+ // Toolbar
+ IToolBarManager toolbar = getViewSite().getActionBars()
+ .getToolBarManager();
+ switchRepositoriesAction = new RepositoryToolbarAction(false,
+ () -> getRepository(),
+ repo -> reactOnSelection(new StructuredSelection(repo)));
+ toolbar.add(switchRepositoriesAction);
+ getViewSite().getActionBars().updateActionBars();
// register context menu
MenuManager menuManager = new MenuManager();
menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
@@ -421,6 +436,10 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
}
Activator.getDefault().getPreferenceStore()
.removePropertyChangeListener(uiPrefsListener);
+ if (switchRepositoriesAction != null) {
+ switchRepositoriesAction.dispose();
+ switchRepositoriesAction = null;
+ }
}
private void reactOnSelection(ISelection selection) {
@@ -569,23 +588,13 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
@Override
public void onRefsChanged(RefsChangedEvent event) {
- PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
- @Override
- public void run() {
- Object currentInput = refLogTableTreeViewer.getInput();
- if (currentInput instanceof ReflogInput) {
- ReflogInput oldInput = (ReflogInput) currentInput;
- refLogTableTreeViewer.setInput(new ReflogInput(
- oldInput.getRepository(), oldInput.getRef()));
- }
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ Object currentInput = refLogTableTreeViewer.getInput();
+ if (currentInput instanceof ReflogInput) {
+ ReflogInput oldInput = (ReflogInput) currentInput;
+ refLogTableTreeViewer.setInput(new ReflogInput(
+ oldInput.getRepository(), oldInput.getRef()));
}
});
}
-
- /**
- * @return selection provider
- */
- public ISelectionProvider getSelectionProvider() {
- return refLogTableTreeViewer;
- }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
index 01ede86c39..fa972e92ff 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
@@ -13,19 +13,19 @@
package org.eclipse.egit.ui.internal.reflog;
import java.io.File;
-import java.util.Collection;
import java.util.Objects;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.model.WorkbenchAdapter;
@@ -77,6 +77,7 @@ public class ReflogViewContentProvider implements ITreeContentProvider {
}
};
+
/**
* Input class for this content provider.
*/
@@ -89,7 +90,7 @@ public class ReflogViewContentProvider implements ITreeContentProvider {
private final ISchedulingRule rule;
- private Collection<ReflogEntry> refLog;
+ private ReflogItem[] refLog;
/**
* Create input with non-null repository and non-null ref
@@ -126,7 +127,7 @@ public class ReflogViewContentProvider implements ITreeContentProvider {
@Override
public Object[] getChildren(Object o) {
if (refLog != null) {
- return refLog.toArray();
+ return refLog;
}
return null;
}
@@ -138,8 +139,10 @@ public class ReflogViewContentProvider implements ITreeContentProvider {
return; // Already loaded.
}
try (Git git = new Git(repository)) {
- refLog = git.reflog().setRef(ref).call();
- collector.add(refLog.toArray(), monitor);
+ refLog = git.reflog().setRef(ref).call().stream()
+ .map(entry -> new ReflogItem(ReflogInput.this, entry))
+ .toArray(ReflogItem[]::new);
+ collector.add(refLog, monitor);
} catch (Exception e) {
Activator.logError("Error running reflog command", e); //$NON-NLS-1$
collector.add(ERROR_ELEMENT, monitor);
@@ -170,6 +173,16 @@ public class ReflogViewContentProvider implements ITreeContentProvider {
currentInput = newInput;
if (viewer instanceof AbstractTreeViewer && newInput != null) {
loader = new DeferredBatchLoader((AbstractTreeViewer) viewer);
+ loader.addUpdateCompleteListener(new JobChangeAdapter() {
+
+ @Override
+ public void done(IJobChangeEvent event) {
+ if (event.getResult().isOK()) {
+ // Force a selection event
+ viewer.setSelection(viewer.getSelection());
+ }
+ }
+ });
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
index 7d1d2df205..ab88dd3356 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2016 SAP AG and others.
+ * Copyright (c) 2010, 2017 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -958,6 +958,12 @@ public class RepositoriesView extends CommonNavigator implements IShowInSource,
showPaths(Arrays.asList(path));
return;
}
+ Repository repository = AdapterUtils.adapt(ssel.getFirstElement(),
+ Repository.class);
+ if (repository != null) {
+ showRepository(repository);
+ return;
+ }
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/AbstractSelectionProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/AbstractSelectionProvider.java
new file mode 100644
index 0000000000..19de9c6a8b
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/AbstractSelectionProvider.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.selection;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+
+/**
+ * Base class for custom selection providers.
+ */
+public abstract class AbstractSelectionProvider
+ implements IPostSelectionProvider {
+
+ private final CopyOnWriteArrayList<ISelectionChangedListener> selectionListeners = new CopyOnWriteArrayList<>();
+
+ private final CopyOnWriteArrayList<ISelectionChangedListener> postSelectionListeners = new CopyOnWriteArrayList<>();
+
+ @Override
+ public void addSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ selectionListeners.addIfAbsent(listener);
+ }
+
+ @Override
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ selectionListeners.remove(listener);
+ }
+
+ @Override
+ public void addPostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ postSelectionListeners.addIfAbsent(listener);
+ }
+
+ @Override
+ public void removePostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ postSelectionListeners.remove(listener);
+ }
+
+ /**
+ * @return the list
+ */
+ protected CopyOnWriteArrayList<ISelectionChangedListener> getSelectionListeners() {
+ return selectionListeners;
+ }
+
+ /**
+ * @return the list
+ */
+ protected CopyOnWriteArrayList<ISelectionChangedListener> getPostSelectionListeners() {
+ return postSelectionListeners;
+ }
+
+ /**
+ * @param listeners
+ */
+ protected void fireSelectionChanged(
+ CopyOnWriteArrayList<ISelectionChangedListener> listeners) {
+ if (listeners.isEmpty()) {
+ return;
+ }
+ SelectionChangedEvent event = new SelectionChangedEvent(this,
+ getSelection());
+ for (ISelectionChangedListener listener : listeners) {
+ SafeRunner.run(new SafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ listener.selectionChanged(event);
+ }
+ });
+ }
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/MultiViewerSelectionProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/MultiViewerSelectionProvider.java
new file mode 100644
index 0000000000..e4efe789ab
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/MultiViewerSelectionProvider.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.selection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * A {@link IPostSelectionProvider} for views with several viewers, tracking
+ * focus changes among the viewers to supply the correct selection.
+ */
+public class MultiViewerSelectionProvider extends AbstractSelectionProvider {
+
+ private final List<Viewer> viewers = new ArrayList<>();
+
+ private final Listener focusHook = event -> {
+ if (event.type == SWT.FocusIn && event.widget instanceof Control) {
+ focusChanged((Control) event.widget);
+ }
+ };
+
+ private final ISelectionChangedListener selectionHook = event -> selectionChanged(
+ event);
+
+ private final ISelectionChangedListener postSelectionHook = event -> postSelectionChanged(
+ event);
+
+ private Viewer currentViewer;
+
+ /**
+ * Creates a new {@link MultiViewerSelectionProvider} for the given viewers.
+ * The first viewer given is assumed to be the one that's focused initially.
+ *
+ * @param providers
+ * that contribute to this selection provider
+ */
+ public MultiViewerSelectionProvider(Viewer... providers) {
+ Assert.isLegal(providers != null && providers.length > 0);
+ for (Viewer viewer : providers) {
+ Assert.isLegal(viewer != null);
+ viewers.add(viewer);
+ viewer.getControl().addListener(SWT.FocusIn, focusHook);
+ viewer.addSelectionChangedListener(selectionHook);
+ if (viewer instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) viewer)
+ .addPostSelectionChangedListener(postSelectionHook);
+ }
+ if (currentViewer == null) {
+ currentViewer = viewer;
+ }
+ }
+ }
+
+ private void focusChanged(Control control) {
+ for (Viewer viewer : viewers) {
+ if (control == viewer.getControl()) {
+ if (viewer != currentViewer) {
+ currentViewer = viewer;
+ fireSelectionChanged(getSelectionListeners());
+ fireSelectionChanged(getPostSelectionListeners());
+ }
+ return;
+ }
+ }
+ }
+
+ private void selectionChanged(SelectionChangedEvent event) {
+ if (event.getSelectionProvider() == currentViewer) {
+ fireSelectionChanged(getSelectionListeners());
+ }
+ }
+
+ private void postSelectionChanged(SelectionChangedEvent event) {
+ if (event.getSelectionProvider() == currentViewer) {
+ fireSelectionChanged(getPostSelectionListeners());
+ }
+ }
+
+ @Override
+ public ISelection getSelection() {
+ if (currentViewer != null) {
+ return currentViewer.getSelection();
+ }
+ return StructuredSelection.EMPTY;
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ if (currentViewer != null) {
+ currentViewer.setSelection(selection);
+ }
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/RepositorySelectionProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/RepositorySelectionProvider.java
new file mode 100644
index 0000000000..a61a772b05
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/RepositorySelectionProvider.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.selection;
+
+import java.util.function.Supplier;
+
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * An {@link IPostSelectionProvider} that provides a selection containing the
+ * current repository as determined by a {@link Supplier} if the base selection
+ * provider does not have a selection.
+ */
+public class RepositorySelectionProvider extends AbstractSelectionProvider {
+
+ private final ISelectionProvider baseProvider;
+
+ private final Supplier<? extends Repository> repositoryProvider;
+
+ private final ISelectionChangedListener selectionHook = event -> fireSelectionChanged(
+ getSelectionListeners());
+
+ private final ISelectionChangedListener postSelectionHook = event -> fireSelectionChanged(
+ getPostSelectionListeners());
+
+ /**
+ * Creates a new {@link RepositorySelectionProvider}. If the base provider
+ * yields an empty selection, it supplies the current repository as
+ * determined by the given {@link Supplier}.
+ *
+ * @param baseProvider
+ * to use normally for selections
+ * @param repositoryProvider
+ * to use to get the repository
+ */
+ public RepositorySelectionProvider(ISelectionProvider baseProvider,
+ Supplier<? extends Repository> repositoryProvider) {
+ this.repositoryProvider = repositoryProvider;
+ this.baseProvider = baseProvider;
+ baseProvider.addSelectionChangedListener(selectionHook);
+ if (baseProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) baseProvider)
+ .addPostSelectionChangedListener(postSelectionHook);
+ }
+ }
+
+ @Override
+ public ISelection getSelection() {
+ ISelection selection = baseProvider.getSelection();
+ if (selection.isEmpty() && selection instanceof IStructuredSelection) {
+ Repository repository = repositoryProvider.get();
+ if (repository != null) {
+ return new StructuredSelection(
+ new RepositoryNode(null, repository));
+ }
+ }
+ return selection;
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ baseProvider.setSelection(selection);
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
index c4abbe9cae..6663e14334 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2011, 2016 Bernard Leach <leachbj@bouncycastle.org> and others.
+ * Copyright (C) 2011, 2017 Bernard Leach <leachbj@bouncycastle.org> and others.
* Copyright (C) 2015 SAP SE (Christian Georgi <christian.georgi@sap.com>)
* Copyright (C) 2015 Denis Zygann <d.zygann@web.de>
* Copyright (C) 2016 IBM (Daniel Megert <daniel_megert@ch.ibm.com>)
@@ -85,6 +85,7 @@ import org.eclipse.egit.ui.internal.commit.CommitJob;
import org.eclipse.egit.ui.internal.commit.CommitMessageHistory;
import org.eclipse.egit.ui.internal.commit.CommitProposalProcessor;
import org.eclipse.egit.ui.internal.commit.DiffViewer;
+import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.components.ToggleableWarningLabel;
import org.eclipse.egit.ui.internal.decorators.IProblemDecoratable;
import org.eclipse.egit.ui.internal.decorators.ProblemLabelDecorator;
@@ -98,6 +99,8 @@ import org.eclipse.egit.ui.internal.operations.DeletePathsOperationUI;
import org.eclipse.egit.ui.internal.operations.IgnoreOperationUI;
import org.eclipse.egit.ui.internal.push.PushMode;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
+import org.eclipse.egit.ui.internal.selection.MultiViewerSelectionProvider;
+import org.eclipse.egit.ui.internal.selection.RepositorySelectionProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.jface.action.IAction;
@@ -151,8 +154,6 @@ import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.events.ListenerHandle;
-import org.eclipse.jgit.events.RefsChangedEvent;
-import org.eclipse.jgit.events.RefsChangedListener;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -211,6 +212,7 @@ import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Form;
@@ -223,6 +225,7 @@ import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.progress.WorkbenchJob;
/**
* A GitX style staging view with embedded commit dialog.
@@ -319,6 +322,12 @@ public class StagingView extends ViewPart
private IAction compareModeAction;
+ private IWorkbenchAction switchRepositoriesAction;
+
+ /** The currently set repository, even if it is bare. */
+ private Repository realRepository;
+
+ /** The currently set repository, if it's not a bare repository. */
@Nullable
private Repository currentRepository;
@@ -650,14 +659,11 @@ public class StagingView extends ViewPart
if (!RepositoryUtil.PREFS_DIRECTORIES_REL.equals(event.getKey())) {
return;
}
-
final Repository repo = currentRepository;
- if (repo == null)
+ if (repo == null || Activator.getDefault().getRepositoryUtil()
+ .contains(repo)) {
return;
-
- if (Activator.getDefault().getRepositoryUtil().contains(repo))
- return;
-
+ }
reload(null);
}
@@ -1255,7 +1261,9 @@ public class StagingView extends ViewPart
UIUtils.notifySelectionChangedWithCurrentSelection(
selectionChangedListener, site);
- site.setSelectionProvider(unstagedViewer);
+ site.setSelectionProvider(new RepositorySelectionProvider(
+ new MultiViewerSelectionProvider(unstagedViewer, stagedViewer),
+ () -> realRepository));
ViewerFilter filter = new ViewerFilter() {
@Override
@@ -1800,6 +1808,15 @@ public class StagingView extends ViewPart
toolbar.add(new Separator());
+ switchRepositoriesAction = new RepositoryToolbarAction(false,
+ () -> realRepository,
+ repo -> {
+ if (realRepository != repo) {
+ reload(repo);
+ }
+ });
+ toolbar.add(switchRepositoriesAction);
+
compareModeAction = new Action(UIText.StagingView_CompareMode,
IAction.AS_CHECK_BOX) {
@Override
@@ -3413,6 +3430,7 @@ public class StagingView extends ViewPart
*/
private void clearRepository(@Nullable Repository repository) {
saveCommitMessageComponentState();
+ realRepository = repository;
currentRepository = null;
StagingViewUpdate update = new StagingViewUpdate(null, null, null);
setStagingViewerInput(unstagedViewer, update, null, null);
@@ -3426,6 +3444,9 @@ public class StagingView extends ViewPart
form.setText(UIText.StagingView_NoSelectionTitle);
}
updateIgnoreErrorsButtonVisibility();
+ updateRebaseButtonVisibility(false);
+ // Force a selection changed event
+ unstagedViewer.setSelection(unstagedViewer.getSelection());
}
/**
@@ -3483,117 +3504,101 @@ public class StagingView extends ViewPart
return;
}
if (repository == null) {
- asyncExec(new Runnable() {
- @Override
- public void run() {
- clearRepository(null);
- }
- });
+ asyncUpdate(() -> clearRepository(null));
return;
}
if (!isValidRepo(repository)) {
- asyncExec(new Runnable() {
- @Override
- public void run() {
- clearRepository(repository);
- }
- });
+ asyncUpdate(() -> clearRepository(repository));
return;
}
final boolean repositoryChanged = currentRepository != repository;
+ realRepository = repository;
currentRepository = repository;
- asyncExec(new Runnable() {
-
- @Override
- public void run() {
- if (isDisposed()) {
- return;
- }
+ asyncUpdate(() -> {
+ if (isDisposed()) {
+ return;
+ }
- final IndexDiffData indexDiff = doReload(repository);
- boolean indexDiffAvailable = indexDiffAvailable(indexDiff);
- boolean noConflicts = noConflicts(indexDiff);
-
- if (repositoryChanged) {
- // Reset paths, they're from the old repository
- resetPathsToExpand();
- if (refsChangedListener != null)
- refsChangedListener.remove();
- refsChangedListener = repository.getListenerList()
- .addRefsChangedListener(new RefsChangedListener() {
-
- @Override
- public void onRefsChanged(RefsChangedEvent event) {
- updateRebaseButtonVisibility(repository
- .getRepositoryState().isRebasing());
- }
-
- });
- }
- final StagingViewUpdate update = new StagingViewUpdate(repository, indexDiff, null);
- Object[] unstagedExpanded = unstagedViewer.getVisibleExpandedElements();
- Object[] stagedExpanded = stagedViewer.getVisibleExpandedElements();
+ final IndexDiffData indexDiff = doReload(repository);
+ boolean indexDiffAvailable = indexDiffAvailable(indexDiff);
+ boolean noConflicts = noConflicts(indexDiff);
- int unstagedElementsCount = updateAutoExpand(unstagedViewer,
- getUnstaged(indexDiff));
- int stagedElementsCount = updateAutoExpand(stagedViewer,
- getStaged(indexDiff));
- int elementsCount = unstagedElementsCount + stagedElementsCount;
-
- if (elementsCount > getMaxLimitForListMode()) {
- listPresentationAction.setEnabled(false);
- if (presentation == Presentation.LIST) {
- compactTreePresentationAction.setChecked(true);
- switchToCompactModeInternal(true);
- } else {
- setExpandCollapseActionsVisible(false,
- unstagedElementsCount <= getMaxLimitForListMode(),
- true);
- setExpandCollapseActionsVisible(true,
- stagedElementsCount <= getMaxLimitForListMode(),
- true);
- }
+ if (repositoryChanged) {
+ // Reset paths, they're from the old repository
+ resetPathsToExpand();
+ if (refsChangedListener != null)
+ refsChangedListener.remove();
+ refsChangedListener = repository.getListenerList()
+ .addRefsChangedListener(
+ event -> updateRebaseButtonVisibility(repository
+ .getRepositoryState().isRebasing()));
+ }
+ final StagingViewUpdate update = new StagingViewUpdate(repository,
+ indexDiff, null);
+ Object[] unstagedExpanded = unstagedViewer
+ .getVisibleExpandedElements();
+ Object[] stagedExpanded = stagedViewer.getVisibleExpandedElements();
+
+ int unstagedElementsCount = updateAutoExpand(unstagedViewer,
+ getUnstaged(indexDiff));
+ int stagedElementsCount = updateAutoExpand(stagedViewer,
+ getStaged(indexDiff));
+ int elementsCount = unstagedElementsCount + stagedElementsCount;
+
+ if (elementsCount > getMaxLimitForListMode()) {
+ listPresentationAction.setEnabled(false);
+ if (presentation == Presentation.LIST) {
+ compactTreePresentationAction.setChecked(true);
+ switchToCompactModeInternal(true);
} else {
- listPresentationAction.setEnabled(true);
- boolean changed = getPreferenceStore().getBoolean(
- UIPreferences.STAGING_VIEW_PRESENTATION_CHANGED);
- if (changed) {
- listPresentationAction.setChecked(true);
- switchToListMode();
- } else if (presentation != Presentation.LIST) {
- setExpandCollapseActionsVisible(false, true, true);
- setExpandCollapseActionsVisible(true, true, true);
- }
+ setExpandCollapseActionsVisible(false,
+ unstagedElementsCount <= getMaxLimitForListMode(),
+ true);
+ setExpandCollapseActionsVisible(true,
+ stagedElementsCount <= getMaxLimitForListMode(),
+ true);
}
+ } else {
+ listPresentationAction.setEnabled(true);
+ boolean changed = getPreferenceStore().getBoolean(
+ UIPreferences.STAGING_VIEW_PRESENTATION_CHANGED);
+ if (changed) {
+ listPresentationAction.setChecked(true);
+ switchToListMode();
+ } else if (presentation != Presentation.LIST) {
+ setExpandCollapseActionsVisible(false, true, true);
+ setExpandCollapseActionsVisible(true, true, true);
+ }
+ }
- setStagingViewerInput(unstagedViewer, update, unstagedExpanded,
- pathsToExpandInUnstaged);
- setStagingViewerInput(stagedViewer, update, stagedExpanded,
- pathsToExpandInStaged);
- resetPathsToExpand();
- refreshAction.setEnabled(true);
-
- updateRebaseButtonVisibility(repository.getRepositoryState()
- .isRebasing());
+ setStagingViewerInput(unstagedViewer, update, unstagedExpanded,
+ pathsToExpandInUnstaged);
+ setStagingViewerInput(stagedViewer, update, stagedExpanded,
+ pathsToExpandInStaged);
+ resetPathsToExpand();
+ // Force a selection changed event
+ unstagedViewer.setSelection(unstagedViewer.getSelection());
+ refreshAction.setEnabled(true);
- updateIgnoreErrorsButtonVisibility();
+ updateRebaseButtonVisibility(
+ repository.getRepositoryState().isRebasing());
- boolean rebaseContinueEnabled = indexDiffAvailable
- && repository.getRepositoryState().isRebasing()
- && noConflicts;
- rebaseContinueButton.setEnabled(rebaseContinueEnabled);
+ updateIgnoreErrorsButtonVisibility();
- form.setText(GitLabels.getStyledLabelSafe(repository).toString());
- updateCommitMessageComponent(repositoryChanged, indexDiffAvailable);
- enableCommitWidgets(indexDiffAvailable && noConflicts);
+ boolean rebaseContinueEnabled = indexDiffAvailable
+ && repository.getRepositoryState().isRebasing()
+ && noConflicts;
+ rebaseContinueButton.setEnabled(rebaseContinueEnabled);
- updateCommitButtons();
- updateSectionText();
- }
+ form.setText(GitLabels.getStyledLabelSafe(repository).toString());
+ updateCommitMessageComponent(repositoryChanged, indexDiffAvailable);
+ enableCommitWidgets(indexDiffAvailable && noConflicts);
+ updateCommitButtons();
+ updateSectionText();
});
}
@@ -4072,6 +4077,11 @@ public class StagingView extends ViewPart
refsChangedListener.remove();
}
+ if (switchRepositoriesAction != null) {
+ switchRepositoriesAction.dispose();
+ switchRepositoriesAction = null;
+ }
+
getPreferenceStore().removePropertyChangeListener(uiPrefsListener);
getDialogSettings().put(STORE_SORT_STATE, sortAction.isChecked());
@@ -4093,6 +4103,30 @@ public class StagingView extends ViewPart
PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
}
+ private void asyncUpdate(Runnable runnable) {
+ Job update = new WorkbenchJob(UIText.StagingView_LoadJob) {
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ try {
+ runnable.run();
+ return Status.OK_STATUS;
+ } catch (Exception e) {
+ return Activator.createErrorStatus(e.getLocalizedMessage(),
+ e);
+ }
+ }
+
+ @Override
+ public boolean belongsTo(Object family) {
+ return family == JobFamilies.STAGING_VIEW_RELOAD
+ || super.belongsTo(family);
+ }
+ };
+ update.setSystem(true);
+ update.schedule();
+ }
+
/**
* This comparator sorts the {@link StagingEntry}s alphabetically or groups
* them by state. If grouped by state the entries in the same group are also
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index 0bca35bc55..482cce18d8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -419,6 +419,8 @@ RepositoryAction_errorFindingRepo=Could not find a repository associated with th
RepositoryAction_errorFindingRepoTitle=Cannot Find Repository
RepositoryAction_multiRepoSelection=Cannot perform action on multiple repositories simultaneously.\n\nPlease select items from only one repository.
RepositoryAction_multiRepoSelectionTitle=Multiple Repositories Selection
+RepositoryToolbarAction_label=Repository
+RepositoryToolbarAction_tooltip=Switch repository
RepositoryCommit_AuthorDate=\ ({0} on {1})
RepositoryCommit_AuthorDateCommitter=\ ({0} on {1}, committed by {2})
RepositoryLocationPage_info=Select a location of Git Repositories
@@ -1807,7 +1809,6 @@ Examples:\
OpenWorkingFileAction_text=&Open
OpenWorkingFileAction_tooltip=Open working file
OpenWorkingFileAction_openWorkingFileShellTitle=Problems Opening Working File
-
StagingView_UnstagedChanges=Unstaged Changes ({0})
StagingView_UnstagedChangesTooltip=Changes not in the git index; not in the commit
StagingView_ShowFileNamesFirst=Show File Names First
@@ -1865,7 +1866,7 @@ StagingView_AddJob=Adding files to index...
StagingView_RemoveJob=Removing files from index...
StagingView_ResetJob=Unstaging files...
StagingView_MessageErrors=Fix warnings/errors before you commit changes or explicitly ignore them
-
+StagingView_LoadJob=Staging View Loader
StagingView_IgnoreErrors=Ignore warnings and errors
StashApplyCommand_applyFailed=Applying stashed commit ''{0}'' failed due to ''{1}''
StashApplyCommand_jobTitle=Apply changes from stashed commit ''{0}''

Back to the top