aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2018-07-24 17:19:12 -0400
committerThomas Wolf2018-08-06 15:53:27 -0400
commit6ee58057c2dc1ab8498651e1ab91955289f7e981 (patch)
treea96324ec43af9989bd54840e7ddebe3d63e9f421
parentf83e6aeca768531f345f9092afd384bf763ff7ae (diff)
downloadegit-6ee58057c2dc1ab8498651e1ab91955289f7e981.tar.gz
egit-6ee58057c2dc1ab8498651e1ab91955289f7e981.tar.xz
egit-6ee58057c2dc1ab8498651e1ab91955289f7e981.zip
Use an asynchronous lightweight decorator in the repositories view
In the previous implementation, the label provider produced styled labels that included the decorations. But label providers run in the UI thread, and expensive decorations like a branch state (N commits ahead, M behind) could thus lead to UI blocks. Newly, leverage Eclipse's built-in support. Use a lightweight decorator for RepositoryTreeNode and register it in plugin.xml. Separate out getting labels into a WorkbenchAdapter and adapt the GitAdapterFactory accordingly. (We already created a WorkbenchAdapter there, but first we always created a new one, and second, it always created a RepositoriesViewLabelProvider just to get the label text. That's terribly inefficient and the logic is completely backwards.) Also use ImageDescriptors instead of Images where possible. Factor out the handling of LabelProviderChangedEvent from GitLightweightDecorator into GitDecorator and re-use it in the new decorator for RepositoryTreeNodes. Make the RepositoriesViewLabelProvider a decorating label provider based on a WorkbenchLabelProvider, which uses the singleton RepositoryTreeNodeWorkbenchAdapter to get labels and images. Change the other uses of RepositoriesViewLabelProvider in dialogs to work with the new setup. Adapt git repositories view tests. These often use the label provider to determine expected node labels, and then try to find a node with a matching label. Decorations are now asynchronous, and thus the label returned from the label provider may or may not contain the decoration. Even with waiting for decoration jobs we may end up with the label being determined in the test and the one in the UI being different. The latter may or may not contain the decoration, which makes finding expected nodes a bit difficult. For now, use the TestUtil navigation methods, which just check for containment. This works well, but because some decorations include the repo directory path which in turn includes the test method name, some test methods and even some test repo names had to be changed to avoid false "duplicate nodes" failures. User-visible UI changes from all that: next to none. Three differences I noticed in the default theme on OS X: 1. Decorations all use the default decoration style (light brown), with the exception of the directory paths shown on repository nodes and on working tree nodes. Those are handled specially and use the qualifier style. 2. Decorations in the "File->Import...->Projects from Git->Existing git repositories" page now actually work. 3. Image decorations briefly flicker on a refresh because of the way asynchronous lightweight decorators work. The flickering is due to the repository view being wholly refreshed frequently. On such a refresh, the viewer tries to get a new decorated label, but the decoration isn't available yet. Once it is available, an event is fired, and the viewer updates the label again. For text labels, the new RepositoriesViewLabelProvider contains a work-around, but for images, that method won't work. The only image decorations (so far) are the check markers for the currently checked-out ref. Otherwise, I notice much faster Eclipse startup with the repositories view open and containing some repositories. Bug: 536814 Change-Id: Ifa8279dd6755c57696b8b64e96bc41a1f948aa59 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java23
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java15
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java11
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java13
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java2
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java7
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java10
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java19
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java11
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java18
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java25
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java69
-rw-r--r--org.eclipse.egit.ui/plugin.properties8
-rw-r--r--org.eclipse.egit.ui/plugin.xml15
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java21
-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/clone/GitSelectRepositoryPage.java2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java5
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDecorator.java138
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java96
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java20
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushTagsPage.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java32
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java604
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewStyledCellLabelProvider.java45
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeDecorator.java375
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeWorkbenchAdapter.java139
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/RepositoryTreeNodeType.java55
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties3
32 files changed, 943 insertions, 863 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
index 425c29d4d..63ef60e07 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
@@ -238,6 +238,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
TestUtil.processUIEvents();
// close all editors/dialogs
new Eclipse().reset();
+ clearAllConfiguredRepositories();
closeGitViews();
TestUtil.processUIEvents();
// cleanup
@@ -284,11 +285,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
testUtils.deleteTempDirs();
}
- protected static void shutDownRepositories() throws Exception {
- RepositoryCache cache = Activator.getDefault().getRepositoryCache();
- for(Repository repository:cache.getAllRepositories())
- repository.close();
- cache.clear();
+ protected void clearAllConfiguredRepositories() throws Exception {
IEclipsePreferences prefs = Activator.getDefault().getRepositoryUtil()
.getPreferences();
synchronized (prefs) {
@@ -298,6 +295,14 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
}
}
+ protected static void shutDownRepositories() throws Exception {
+ RepositoryCache cache = Activator.getDefault().getRepositoryCache();
+ for (Repository repository : cache.getAllRepositories()) {
+ repository.close();
+ }
+ cache.clear();
+ }
+
protected static void deleteAllProjects() throws Exception {
for (IProject prj : ResourcesPlugin.getWorkspace().getRoot()
.getProjects()) {
@@ -381,7 +386,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
} else {
commitables = new IFile[] { dotProject, textFile, textFile2 };
}
- ArrayList<IFile> untracked = new ArrayList<IFile>();
+ ArrayList<IFile> untracked = new ArrayList<>();
untracked.addAll(Arrays.asList(commitables));
// commit to stable
CommitOperation op = new CommitOperation(commitables,
@@ -662,7 +667,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
IFile file = touch(newContent);
IFile[] commitables = new IFile[] { file };
- ArrayList<IFile> untracked = new ArrayList<IFile>();
+ ArrayList<IFile> untracked = new ArrayList<>();
untracked.addAll(Arrays.asList(commitables));
String message = commitMessage;
if (message == null)
@@ -716,7 +721,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
}
protected static void stage(IFile file) throws Exception {
- ArrayList<IFile> unstaged = new ArrayList<IFile>();
+ ArrayList<IFile> unstaged = new ArrayList<>();
unstaged.addAll(Arrays.asList(new IFile[] { file }));
AddToIndexOperation op = new AddToIndexOperation(unstaged);
op.execute(null);
@@ -728,7 +733,7 @@ public abstract class LocalRepositoryTestCase extends EGitTestCase {
if (!prj.isAccessible())
throw new IllegalStateException("No project to touch");
IFile[] commitables = new IFile[] { file };
- ArrayList<IFile> untracked = new ArrayList<IFile>();
+ ArrayList<IFile> untracked = new ArrayList<>();
untracked.addAll(Arrays.asList(commitables));
CommitOperation op = new CommitOperation(commitables,
untracked, TestUtil.TESTAUTHOR, TestUtil.TESTCOMMITTER,
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
index 12063befa..13315742c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
@@ -40,13 +40,8 @@ import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.internal.UIText;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
-import org.eclipse.egit.ui.internal.repository.tree.LocalNode;
-import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
-import org.eclipse.egit.ui.internal.repository.tree.TagsNode;
import org.eclipse.egit.ui.test.ContextMenuHelper;
import org.eclipse.egit.ui.test.TestUtil;
-import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestUtils;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.lib.Constants;
@@ -100,12 +95,8 @@ public class BranchAndResetActionTest extends LocalRepositoryTestCase {
top.execute(null);
touchAndSubmit(null);
- RepositoriesViewLabelProvider provider = GitRepositoriesViewTestUtils
- .createLabelProvider();
- LOCAL_BRANCHES = provider.getText(new LocalNode(new RepositoryNode(
- null, repo), repo));
- TAGS = provider.getText(new TagsNode(new RepositoryNode(null, repo),
- repo));
+ LOCAL_BRANCHES = UIText.RepositoriesViewLabelProvider_LocalNodetext;
+ TAGS = UIText.RepositoriesViewLabelProvider_TagsNodeText;
}
@Test
@@ -171,7 +162,7 @@ public class BranchAndResetActionTest extends LocalRepositoryTestCase {
.getProject(PROJ1).getFolder(FOLDER).getFile("ToBeDeleted");
toBeDeleted.create(new ByteArrayInputStream(new byte[0]), false, null);
- ArrayList<IFile> untracked = new ArrayList<IFile>();
+ ArrayList<IFile> untracked = new ArrayList<>();
untracked.add(toBeDeleted);
// commit to stable
CommitOperation op = new CommitOperation(new IFile[] { toBeDeleted },
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
index bf7514156..4724595ed 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
@@ -35,13 +35,9 @@ import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
-import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
-import org.eclipse.egit.ui.internal.repository.tree.TagsNode;
import org.eclipse.egit.ui.test.ContextMenuHelper;
import org.eclipse.egit.ui.test.JobJoiner;
import org.eclipse.egit.ui.test.TestUtil;
-import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestUtils;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand.ResetType;
@@ -96,12 +92,7 @@ public class CompareActionsTest extends LocalRepositoryTestCase {
top.execute(null);
touchAndSubmit(null);
- RepositoriesViewLabelProvider provider = GitRepositoriesViewTestUtils
- .createLabelProvider();
- // LOCAL_BRANCHES = provider.getText(new LocalNode(new RepositoryNode(
- // null, repo), repo));
- TAGS = provider.getText(new TagsNode(new RepositoryNode(null, repo),
- repo));
+ TAGS = UIText.RepositoriesViewLabelProvider_TagsNodeText;
}
private static void setEnabledModelProvider(String modelProviderId) {
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
index 7f2464bb1..b74ebb365 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
@@ -22,14 +22,9 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.internal.UIText;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
-import org.eclipse.egit.ui.internal.repository.tree.LocalNode;
-import org.eclipse.egit.ui.internal.repository.tree.RemoteTrackingNode;
-import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
import org.eclipse.egit.ui.test.ContextMenuHelper;
import org.eclipse.egit.ui.test.JobJoiner;
import org.eclipse.egit.ui.test.TestUtil;
-import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestUtils;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -65,13 +60,9 @@ public class FetchAndMergeActionTest extends LocalRepositoryTestCase {
public void setup() throws Exception {
repositoryFile = createProjectAndCommitToRepository();
childRepositoryFile = createChildRepository(repositoryFile);
- RepositoriesViewLabelProvider provider = GitRepositoriesViewTestUtils
- .createLabelProvider();
Repository repo = lookupRepository(childRepositoryFile);
- REMOTE_BRANCHES = provider.getText(new RemoteTrackingNode(
- new RepositoryNode(null, repo), repo));
- LOCAL_BRANCHES = provider.getText(new LocalNode(new RepositoryNode(
- null, repo), repo));
+ REMOTE_BRANCHES = UIText.RepositoriesViewLabelProvider_RemoteTrackingNodetext;
+ LOCAL_BRANCHES = UIText.RepositoriesViewLabelProvider_LocalNodetext;
ObjectId id = repo.resolve(repo.getFullBranch());
initialCommitId = id.name();
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
index 9e86473d8..7b7df801c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
@@ -219,7 +219,7 @@ public class GitRepositoriesViewBranchHandlingTest extends
}
@Test
- public void testClonedRepository() throws Exception {
+ public void testBranchCreateInClone() throws Exception {
SWTBotTree tree = getOrOpenView().bot().tree();
SWTBotTreeItem item = TestUtil.expandAndWait(myRepoViewUtil
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
index fd8da96b1..cada79cb4 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
@@ -74,7 +74,7 @@ public class GitRepositoriesViewFetchAndPushTest extends
// now let's clone the remote repository
uri = new URIish(remoteRepositoryFile.getPath());
- workdir = new File(getTestDirectory(), "ClonedRepo2");
+ workdir = new File(getTestDirectory(), "RepoClone2");
op = new CloneOperation(uri, true, null, workdir, "refs/heads/master",
"origin", 0);
@@ -118,6 +118,7 @@ public class GitRepositoriesViewFetchAndPushTest extends
}
Job.getJobManager().join(JobFamilies.REPO_VIEW_REFRESH, null);
+ TestUtil.waitForDecorations();
SWTBotTree tree = repoView.bot().tree();
tree.select(0);
@@ -295,8 +296,8 @@ public class GitRepositoriesViewFetchAndPushTest extends
throws Exception {
SWTBotTreeItem remotesNode = myRepoViewUtil.getRemotesItem(tree,
clonedRepositoryFile);
- SWTBotTreeItem originNode = TestUtil.expandAndWait(remotesNode)
- .getNode("origin");
+ SWTBotTreeItem originNode = TestUtil
+ .getChildNode(TestUtil.expandAndWait(remotesNode), "origin");
if (useRemote) {
originNode.select();
} else {
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
index 8a3a3f08b..befc5bbcb 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
@@ -69,7 +69,7 @@ public class GitRepositoriesViewRemoteHandlingTest extends
* @throws Exception
*/
@Test
- public void testExpandRemotes() throws Exception {
+ public void testExpandRemoteNodes() throws Exception {
removeRemotesConfig(repositoryFile);
refreshAndWait();
SWTBotTree tree = getOrOpenView().bot().tree();
@@ -80,8 +80,8 @@ public class GitRepositoriesViewRemoteHandlingTest extends
StoredConfig cfg = lookupRepository(repositoryFile).getConfig();
String remoteUri = "file:///" + remoteRepositoryFile.getPath();
- cfg.setString("remote", "test", "url", remoteUri);
- cfg.setString("remote", "test", "fetch", "somejunk");
+ cfg.setString("remote", "test1", "url", remoteUri);
+ cfg.setString("remote", "test1", "fetch", "somejunk");
cfg.setString("remote", "test2", "url", remoteUri);
cfg.setString("remote", "test2", "fetch", "somejunk");
cfg.setString("remote", "test2", "pushurl", remoteUri);
@@ -97,7 +97,7 @@ public class GitRepositoriesViewRemoteHandlingTest extends
.size());
List<String> testnodes = TestUtil
- .expandAndWait(remotesItem.getNode("test")).getNodes();
+ .expandAndWait(remotesItem.getNode("test1")).getNodes();
assertEquals(2, testnodes.size());
List<String> test2nodes = TestUtil
.expandAndWait(remotesItem.getNode("test2")).getNodes();
@@ -107,7 +107,7 @@ public class GitRepositoriesViewRemoteHandlingTest extends
.getNodes().size());
// test the properties view on remote
- remotesItem.getNode("test").select();
+ remotesItem.getNode("test1").select();
ContextMenuHelper.clickContextMenuSync(tree,
myUtil.getPluginLocalizedValue("ShowIn"),
"Properties");
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
index eff6504f9..6776ee900 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
@@ -243,10 +243,13 @@ public class GitRepositoriesViewRepoDeletionTest extends
Thread.currentThread().interrupt();
return Status.CANCEL_STATUS;
}
+ // Make sure the label provider is disposed. We don't need it
+ // anymore.
+ myRepoViewUtil.dispose();
// Finally... Java does not give any guarantees about when
// exactly an only weakly reachable object is finalized and
// garbage collected.
- waitForFinalization(5000);
+ waitForFinalization(10000);
// Experience shows that an explicit garbage collection run very
// often does reclaim only weakly reachable objects and set the
// weak references' referents to null, but not even that can be
@@ -340,15 +343,23 @@ public class GitRepositoriesViewRepoDeletionTest extends
private void waitForFinalization(int maxMillis) {
long stop = System.currentTimeMillis() + maxMillis;
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
- do {
+ for (;;) {
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
+ System.out.println("Garbage collection interrupted");
break;
}
- } while (System.currentTimeMillis() < stop
- && memoryBean.getObjectPendingFinalizationCount() > 0);
+ if (memoryBean.getObjectPendingFinalizationCount() == 0) {
+ break;
+ }
+ if (System.currentTimeMillis() > stop) {
+ System.out.println(
+ "Garbage collection timed out; not all objects collected.");
+ break;
+ }
+ }
}
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
index f0b74cf41..8c6696f54 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
@@ -20,7 +20,6 @@ import java.io.File;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.JobFamilies;
@@ -67,7 +66,7 @@ public class GitRepositoriesViewTagHandlingTest extends
}
@Test
- public void testCreateTags() throws Exception {
+ public void testCreateTagMultiple() throws Exception {
SWTBotTree tree = getOrOpenView().bot().tree();
int initialCount = myRepoViewUtil.getTagsItem(tree, repositoryFile)
.expand().rowCount();
@@ -90,7 +89,7 @@ public class GitRepositoriesViewTagHandlingTest extends
}
@Test
- public void testDeleteTag() throws Exception {
+ public void testTagDeletionSingle() throws Exception {
SWTBotTree tree = getOrOpenView().bot().tree();
int initialCount = myRepoViewUtil.getTagsItem(tree, repositoryFile)
.expand().rowCount();
@@ -114,11 +113,7 @@ public class GitRepositoriesViewTagHandlingTest extends
}
@Test
- public void testDeleteTags() throws Exception {
- //TODO Remove once bug355200 has been fixed
- if (Platform.OS_MACOSX.equals(Platform.getOS()))
- return;
-
+ public void testTagDeletionMultiple() throws Exception {
SWTBotTree tree = getOrOpenView().bot().tree();
int initialCount = myRepoViewUtil.getTagsItem(tree, repositoryFile)
.expand().rowCount();
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
index 47fd89781..bee72f3e0 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
@@ -270,11 +270,13 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
SWTBotShell shell = bot.shell(wizardTitle);
bot.radio(UIText.GitSelectWizardPage_ImportExistingButton).click();
TableCollection selected = shell.bot().tree().selection();
- String wizardNode = selected.get(0, 0);
+ String wizardNodeText = selected.get(0, 0);
// wizard directory should be working dir
- assertEquals(
- myRepoViewUtil.getWorkdirItem(tree, repositoryFile).getText(),
- wizardNode);
+ String expected = myRepoViewUtil.getWorkdirItem(tree, repositoryFile)
+ .getText();
+ // One or the other or both or none might contain decorations
+ assertTrue(expected.contains(wizardNodeText)
+ || wizardNodeText.contains(expected));
shell.close();
tree = getOrOpenView().bot().tree();
// start wizard from .git
@@ -285,9 +287,9 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
myUtil.getPluginLocalizedValue("ImportProjectsCommand"));
shell = bot.shell(wizardTitle);
selected = shell.bot().tree().selection();
- wizardNode = selected.get(0, 0);
+ wizardNodeText = selected.get(0, 0);
// wizard directory should be .git
- assertEquals(Constants.DOT_GIT, wizardNode);
+ assertEquals(Constants.DOT_GIT, wizardNodeText);
shell.bot().button(IDialogConstants.NEXT_LABEL).click();
shell.bot().label("Import Projects"); // wait for import projects page
assertEquals(0, shell.bot().tree().getAllItems().length);
@@ -330,7 +332,7 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
private static IWizardDescriptor[] getAllWizards(
IWizardCategory[] categories) {
- List<IWizardDescriptor> results = new ArrayList<IWizardDescriptor>();
+ List<IWizardDescriptor> results = new ArrayList<>();
for (IWizardCategory wizardCategory : categories) {
results.addAll(Arrays.asList(wizardCategory.getWizards()));
results.addAll(Arrays
@@ -658,7 +660,7 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
}
@Test
- public void testDeleteMultipleBranches() throws Exception {
+ public void testDeleteBranchMultiple() throws Exception {
// expand first level
SWTBotTree tree = getOrOpenView().bot().tree();
refreshAndWait();
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
index dfe19ee6c..a11abfb6b 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
@@ -45,6 +45,8 @@ import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
+import org.junit.After;
+import org.junit.Before;
/**
* Collection of utility methods for Git Repositories View tests
@@ -59,7 +61,21 @@ public abstract class GitRepositoriesViewTestBase extends
protected final static String viewName = myUtil
.getPluginLocalizedValue("GitRepositoriesView_name");
- protected static final GitRepositoriesViewTestUtils myRepoViewUtil = new GitRepositoriesViewTestUtils();
+ protected static GitRepositoriesViewTestUtils myRepoViewUtil;
+
+ @Before
+ public void setup() {
+ setTestUtils();
+ }
+
+ private static void setTestUtils() {
+ myRepoViewUtil = new GitRepositoriesViewTestUtils();
+ }
+
+ @After
+ public void teardown() {
+ myRepoViewUtil.dispose();
+ }
/**
* remove all configured repositories from the view
@@ -130,6 +146,13 @@ public abstract class GitRepositoriesViewTestBase extends
fail("Refresh took longer 60 seconds");
}
TestUtil.processUIEvents();
+ TestUtil.waitForDecorations();
+ }
+
+ @Override
+ protected void clearAllConfiguredRepositories() throws Exception {
+ super.clearAllConfiguredRepositories();
+ refreshAndWait();
}
@Override
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
index 62a901d94..fb19b945c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2012 SAP AG and others.
+ * Copyright (c) 2010, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -38,7 +38,7 @@ public class GitRepositoriesViewTestUtils {
* @return label provider
*/
public static RepositoriesViewLabelProvider createLabelProvider() {
- final AtomicReference<RepositoriesViewLabelProvider> providerRef = new AtomicReference<RepositoriesViewLabelProvider>();
+ final AtomicReference<RepositoriesViewLabelProvider> providerRef = new AtomicReference<>();
Display.getDefault().syncExec(new Runnable() {
@Override
@@ -61,6 +61,10 @@ public class GitRepositoriesViewTestUtils {
labelProvider = createLabelProvider();
}
+ public void dispose() {
+ Display.getDefault().syncExec(() -> labelProvider.dispose());
+ }
+
public SWTBotTreeItem getLocalBranchesItem(SWTBotTree tree, File repo)
throws Exception {
Repository repository = lookupRepository(repo);
@@ -69,12 +73,11 @@ public class GitRepositoriesViewTestUtils {
LocalNode localBranches = new LocalNode(branches,
repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
- SWTBotTreeItem branchesItem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(branches).getString());
- SWTBotTreeItem localItem = TestUtil.expandAndWait(branchesItem).getNode(
- labelProvider.getStyledText(localBranches).getString());
+ String rootText = labelProvider.getText(root);
+ String branchesText = labelProvider.getText(branches);
+ String localText = labelProvider.getText(localBranches);
+ SWTBotTreeItem localItem = TestUtil.navigateTo(tree, rootText,
+ branchesText, localText);
return localItem;
}
@@ -84,10 +87,9 @@ public class GitRepositoriesViewTestUtils {
RepositoryNode root = new RepositoryNode(null, repository);
TagsNode tags = new TagsNode(root, repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
- SWTBotTreeItem tagsItem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(tags).getString());
+ String rootText = labelProvider.getText(root);
+ String tagsText = labelProvider.getText(tags);
+ SWTBotTreeItem tagsItem = TestUtil.navigateTo(tree, rootText, tagsText);
return tagsItem;
}
@@ -99,13 +101,11 @@ public class GitRepositoriesViewTestUtils {
RemoteTrackingNode remoteBranches = new RemoteTrackingNode(branches,
repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
- SWTBotTreeItem branchesItem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(branches).getString());
- SWTBotTreeItem remoteItem = TestUtil.expandAndWait(branchesItem)
- .getNode(labelProvider.getStyledText(remoteBranches)
- .getString());
+ String rootText = labelProvider.getText(root);
+ String branchesText = labelProvider.getText(branches);
+ String remoteText = labelProvider.getText(remoteBranches);
+ SWTBotTreeItem remoteItem = TestUtil.navigateTo(tree, rootText,
+ branchesText, remoteText);
return remoteItem;
}
@@ -113,13 +113,12 @@ public class GitRepositoriesViewTestUtils {
throws Exception {
Repository repository = lookupRepository(repositoryFile);
RepositoryNode root = new RepositoryNode(null, repository);
-
WorkingDirNode workdir = new WorkingDirNode(root, repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
- SWTBotTreeItem workdirItem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(workdir).getString());
+ String rootText = labelProvider.getText(root);
+ String workDirText = labelProvider.getText(workdir);
+ SWTBotTreeItem workdirItem = TestUtil.navigateTo(tree, rootText,
+ workDirText);
return workdirItem;
}
@@ -127,8 +126,9 @@ public class GitRepositoriesViewTestUtils {
throws Exception {
Repository repository = lookupRepository(repositoryFile);
RepositoryNode root = new RepositoryNode(null, repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
+
+ String rootText = labelProvider.getText(root);
+ SWTBotTreeItem rootItem = TestUtil.navigateTo(tree, rootText);
return rootItem;
}
@@ -137,10 +137,11 @@ public class GitRepositoriesViewTestUtils {
Repository repository = lookupRepository(repositoryFile);
RepositoryNode root = new RepositoryNode(null, repository);
AdditionalRefsNode symrefsnode = new AdditionalRefsNode(root, repository);
- SWTBotTreeItem rootItem = tree
- .getTreeItem(labelProvider.getStyledText(root).getString());
- SWTBotTreeItem symrefsitem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(symrefsnode).getString());
+
+ String rootText = labelProvider.getText(root);
+ String symrefsText = labelProvider.getText(symrefsnode);
+ SWTBotTreeItem symrefsitem = TestUtil.navigateTo(tree, rootText,
+ symrefsText);
return symrefsitem;
}
@@ -150,10 +151,10 @@ public class GitRepositoriesViewTestUtils {
RepositoryNode root = new RepositoryNode(null, repository);
RemotesNode remotes = new RemotesNode(root, repository);
- String rootText = labelProvider.getStyledText(root).getString();
- SWTBotTreeItem rootItem = tree.getTreeItem(rootText);
- SWTBotTreeItem remotesItem = TestUtil.expandAndWait(rootItem)
- .getNode(labelProvider.getStyledText(remotes).getString());
+ String rootText = labelProvider.getText(root);
+ String remotesText = labelProvider.getText(remotes);
+ SWTBotTreeItem remotesItem = TestUtil.navigateTo(tree, rootText,
+ remotesText);
return remotesItem;
}
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index fdad269b8..e5bfeb4e5 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2005, 2014 Shawn Pearce and others.
+# Copyright (c) 2005, 2018 Shawn Pearce and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
# which accompanies this distribution, and is available at
@@ -31,8 +31,10 @@ DisconnectAction_label=&Disconnect
AssumeUnchangedAction_label=A&ssume Unchanged
NoAssumeUnchangedAction_label=&No Assume Unchanged
UntrackAction_label=&Untrack
-Decorator_name=Git
-Decorator_description=Shows Git specific information on resources in projects under version control.
+Decorator_name=Git Resources
+Decorator_description=Shows git-specific information on resources in projects under version control.
+Repo_decorator_name=Git Repository Objects
+Repo_decorator_description=Shows additional information on git objects (repositories, branches, tags, and so on).
AddToIndexAction_label=&Add to Index
AddToIndexAction_tooltip=Add to Index
RemoveFromIndexAction_label=Remove from I&ndex
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index b965a4e83..9b930e20c 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -647,6 +647,21 @@
%Decorator_description
</description>
</decorator>
+ <decorator
+ lightweight="true"
+ adaptable="false"
+ label="%Repo_decorator_name"
+ class="org.eclipse.egit.ui.internal.repository.RepositoryTreeNodeDecorator"
+ state="true"
+ location="BOTTOM_RIGHT"
+ id="org.eclipse.egit.ui.internal.repository.RepositoryTreeNodeDecorator">
+ <enablement>
+ <objectClass name="org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode"/>
+ </enablement>
+ <description>
+ %Repo_decorator_description
+ </description>
+ </decorator>
</extension>
<extension point="org.eclipse.ui.themes">
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
index 27ed16312..7d042eaf7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 Benjamin Muskalla and others.
+ * Copyright (c) 2011, 2018 Benjamin Muskalla and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -57,7 +57,8 @@ public class GitLabelProvider extends LabelProvider implements
@Override
public Image getImage(Object element) {
if (element instanceof Repository) {
- return RepositoryTreeNodeType.REPO.getIcon();
+ return UIIcons.getImage(getImageCache(),
+ RepositoryTreeNodeType.REPO.getIcon());
}
if (element instanceof RefNode) {
@@ -106,12 +107,16 @@ public class GitLabelProvider extends LabelProvider implements
private Image getRefIcon(Ref ref) {
String name = ref.getName();
if (name.startsWith(Constants.R_HEADS)
- || name.startsWith(Constants.R_REMOTES))
- return RepositoryTreeNodeType.REF.getIcon();
- else if (name.startsWith(Constants.R_TAGS))
- return RepositoryTreeNodeType.TAG.getIcon();
- else
- return RepositoryTreeNodeType.ADDITIONALREF.getIcon();
+ || name.startsWith(Constants.R_REMOTES)) {
+ return UIIcons.getImage(getImageCache(),
+ RepositoryTreeNodeType.REF.getIcon());
+ } else if (name.startsWith(Constants.R_TAGS)) {
+ return UIIcons.getImage(getImageCache(),
+ RepositoryTreeNodeType.TAG.getIcon());
+ } else {
+ return UIIcons.getImage(getImageCache(),
+ RepositoryTreeNodeType.ADDITIONALREF.getIcon());
+ }
}
private LabelProvider getWorkbenchLabelProvider() {
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 396169b9d..72b824df4 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
@@ -403,6 +403,9 @@ public class UIText extends NLS {
public static String GitCloneWizard_errorCannotCreate;
/** */
+ public static String GitDecorator_jobTitle;
+
+ /** */
public static String GitDecoratorPreferencePage_bindingRepositoryNameFlag;
/** */
@@ -649,6 +652,9 @@ public class UIText extends NLS {
public static String GitHistoryPage_toggleEmailAddresses;
/** */
+ public static String GitLightweightDecorator_name;
+
+ /** */
public static String GitPreferenceRoot_automaticallyEnableChangesetModel;
/** */
@@ -1369,6 +1375,9 @@ public class UIText extends NLS {
public static String RepositoryToolbarAction_tooltip;
/** */
+ public static String RepositoryTreeNodeDecorator_name;
+
+ /** */
public static String RepositoryCommit_AuthorDate;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
index 0bf6e49f0..1c5d86c90 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2011, 2012 SAP AG and others.
+ * Copyright (C) 2011, 2018 SAP AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
index 2ab73d9be..cedc7f793 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2017 SAP AG and others.
+ * Copyright (c) 2010, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
index 1444d8d52..616dde3c7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
@@ -29,6 +29,7 @@ import org.eclipse.egit.core.op.ListRemoteOperation;
import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.components.CachedCheckboxTreeViewer;
import org.eclipse.egit.ui.internal.components.FilteredCheckboxTree;
@@ -196,7 +197,9 @@ class SourceBranchPage extends WizardPage {
@Override
public Image getImage(Object element) {
- return RepositoryTreeNodeType.REF.getIcon();
+ return UIIcons.getImage(
+ Activator.getDefault().getResourceManager(),
+ RepositoryTreeNodeType.REF.getIcon());
}
});
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDecorator.java
new file mode 100644
index 000000000..f3619767b
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDecorator.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (C) 2018, 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.decorators;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Abstract base class for git decorators. It automatically listens to index
+ * changes and fires {@link LabelProviderChangedEvent}s when the index diff
+ * changes.
+ */
+public abstract class GitDecorator extends LabelProvider
+ implements ILightweightLabelDecorator, IndexDiffChangedListener {
+
+ private Object lock = new Object();
+
+ /** Protected by lock's monitor. */
+ private EventJob eventJob;
+
+ /**
+ * Creates a new {@link GitDecorator}, registering to receive notifications
+ * about index changes.
+ */
+ public GitDecorator() {
+ org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache()
+ .addIndexDiffChangedListener(this);
+ }
+
+ @Override
+ public void dispose() {
+ org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache()
+ .removeIndexDiffChangedListener(this);
+ Job job;
+ synchronized (lock) {
+ job = eventJob;
+ eventJob = null;
+ }
+ if (job != null) {
+ job.cancel();
+ }
+ }
+
+ /**
+ * Posts an asynchronous {@link LabelProviderChangedEvent} invalidating all
+ * labels.
+ */
+ protected void postLabelEvent() {
+ getEventJob().post(this);
+ }
+
+ /**
+ * Posts a {@link LabelProviderChangedEvent} invalidating all labels.
+ */
+ protected void fireLabelEvent() {
+ LabelProviderChangedEvent event = new LabelProviderChangedEvent(this);
+ // Re-trigger decoration process (in UI thread)
+ PlatformUI.getWorkbench().getDisplay()
+ .asyncExec(() -> fireLabelProviderChanged(event));
+ }
+
+ @Override
+ public void indexDiffChanged(Repository repository,
+ IndexDiffData indexDiffData) {
+ postLabelEvent();
+ }
+
+ private EventJob getEventJob() {
+ synchronized (lock) {
+ if (eventJob == null) {
+ eventJob = new EventJob(getName());
+ eventJob.setSystem(true);
+ eventJob.setUser(false);
+ }
+ return eventJob;
+ }
+ }
+
+ /**
+ * @return a human-readable name for this decorator
+ */
+ protected abstract String getName();
+
+ /**
+ * Job reducing label events to prevent unnecessary (i.e. redundant) event
+ * processing. Each instance of a {@link GitDecorator} gets its own job.
+ */
+ private static class EventJob extends Job {
+
+ /**
+ * Constant defining the waiting time (in milliseconds) until an event
+ * is fired
+ */
+ private static final long DELAY = 100L;
+
+ private GitDecorator decorator;
+
+ public EventJob(String name) {
+ super(MessageFormat.format(UIText.GitDecorator_jobTitle, name));
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ if (decorator != null) {
+ decorator.fireLabelEvent();
+ }
+ return Status.OK_STATUS;
+ }
+
+ public void post(GitDecorator source) {
+ this.decorator = source;
+ if (getState() == SLEEPING || getState() == WAITING) {
+ cancel();
+ }
+ schedule(DELAY);
+ }
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
index 4f6b417ad..a4dcd2ff8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
@@ -8,7 +8,7 @@
* Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
* Copyright (C) 2011, Christian Halstrick <christian.halstrick@sap.com>
* Copyright (C) 2015, IBM Corporation (Dani Megert <daniel_megert@ch.ibm.com>)
- * Copyright (C) 2016, Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2016, 2018 Thomas Wolf <thomas.wolf@paranor.ch>
* Copyright (C) 2016, Stefan Dirix <sdirix@eclipsesource.com>
*
* All rights reserved. This program and the accompanying materials
@@ -35,12 +35,8 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
import org.eclipse.egit.core.internal.util.ExceptionCollector;
import org.eclipse.egit.core.project.GitProjectData;
@@ -57,9 +53,6 @@ import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IDecoration;
-import org.eclipse.jface.viewers.ILightweightLabelDecorator;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;
@@ -86,9 +79,8 @@ import org.eclipse.ui.themes.ITheme;
* when compared to <code>HEAD</code>, as well as the index in the relevant
* repository.
*/
-public class GitLightweightDecorator extends LabelProvider implements
- ILightweightLabelDecorator, IPropertyChangeListener,
- IndexDiffChangedListener {
+public class GitLightweightDecorator extends GitDecorator
+ implements IPropertyChangeListener {
/**
* Property constant pointing back to the extension point id of the
@@ -139,7 +131,6 @@ public class GitLightweightDecorator extends LabelProvider implements
PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
.addPropertyChangeListener(this);
- org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache().addIndexDiffChangedListener(this);
GitProjectData.addRepositoryChangeListener(mappingChangeListener);
}
@@ -178,7 +169,6 @@ public class GitLightweightDecorator extends LabelProvider implements
.removePropertyChangeListener(this);
TeamUI.removePropertyChangeListener(this);
Activator.removePropertyChangeListener(this);
- org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache().removeIndexDiffChangedListener(this);
GitProjectData.removeRepositoryChangeListener(mappingChangeListener);
mappingChangeListener = null;
}
@@ -704,7 +694,7 @@ public class GitLightweightDecorator extends LabelProvider implements
IndexDiffData indexDiffData) {
// clear calculated repo data
DecoratableResourceHelper.clearState(repository);
- postLabelEvent();
+ super.indexDiffChanged(repository, indexDiffData);
}
// -------- Helper methods --------
@@ -732,30 +722,6 @@ public class GitLightweightDecorator extends LabelProvider implements
}
/**
- * Post a label event to the LabelEventJob
- *
- * Posts a generic label event. No specific elements are provided; all
- * decorations shall be invalidated. Same as
- * <code>postLabelEvent(null, true)</code>.
- */
- private void postLabelEvent() {
- // Post label event to LabelEventJob
- LabelEventJob.getInstance().postLabelEvent(this);
- }
-
- void fireLabelEvent() {
- final LabelProviderChangedEvent event = new LabelProviderChangedEvent(
- this);
- // Re-trigger decoration process (in UI thread)
- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- fireLabelProviderChanged(event);
- }
- });
- }
-
- /**
* Handle exceptions that occur in the decorator. Exceptions are only logged
* for resources that are accessible (i.e. exist in an open project).
*
@@ -768,57 +734,9 @@ public class GitLightweightDecorator extends LabelProvider implements
if (resource == null || resource.isAccessible())
EXCEPTION_COLLECTOR.handleException(e);
}
-}
-
-/**
- * Job reducing label events to prevent unnecessary (i.e. redundant) event
- * processing
- */
-class LabelEventJob extends Job {
-
- /**
- * Constant defining the waiting time (in milliseconds) until an event is
- * fired
- */
- private static final long DELAY = 100L;
-
- private static LabelEventJob instance = new LabelEventJob("LabelEventJob"); //$NON-NLS-1$
-
- /**
- * Get the LabelEventJob singleton
- *
- * @return the LabelEventJob singleton
- */
- static LabelEventJob getInstance() {
- return instance;
- }
-
- private LabelEventJob(final String name) {
- super(name);
- setSystem(true);
- }
-
- private GitLightweightDecorator glwDecorator;
-
- /**
- * Post a label event
- *
- * @param decorator
- * The GitLightweightDecorator that is used to fire a
- * LabelProviderChangedEvent
- */
- void postLabelEvent(final GitLightweightDecorator decorator) {
- if (glwDecorator == null)
- glwDecorator = decorator;
- if (getState() == SLEEPING || getState() == WAITING)
- cancel();
- schedule(DELAY);
- }
@Override
- protected IStatus run(IProgressMonitor monitor) {
- if (glwDecorator != null)
- glwDecorator.fireLabelEvent();
- return Status.OK_STATUS;
+ protected String getName() {
+ return UIText.GitLightweightDecorator_name;
}
-}
+} \ No newline at end of file
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
index 677c18dba..e13b607ef 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
@@ -27,7 +27,7 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewStyledCellLabelProvider;
+import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefsNode;
import org.eclipse.egit.ui.internal.repository.tree.BranchHierarchyNode;
@@ -279,7 +279,7 @@ public abstract class AbstractBranchSelectionDialog extends TitleAreaDialog {
branchTree = tree.getViewer();
branchTree.setUseHashlookup(true);
branchTree
- .setLabelProvider(new RepositoriesViewStyledCellLabelProvider());
+ .setLabelProvider(new RepositoriesViewLabelProvider());
branchTree.setContentProvider(new RepositoriesViewContentProvider());
ColumnViewerToolTipSupport.enableFor(branchTree);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
index 95899f99f..63ecd9258 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
@@ -5,6 +5,7 @@
* Copyright (C) 2011, IBM Corporation
* Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
* Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2018, 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 2.0
@@ -38,7 +39,7 @@ import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.internal.history.GitHistoryPage;
import org.eclipse.egit.ui.internal.history.GitHistoryPageSource;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
+import org.eclipse.egit.ui.internal.repository.RepositoryTreeNodeWorkbenchAdapter;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
import org.eclipse.egit.ui.internal.selection.SelectionUtils;
import org.eclipse.egit.ui.internal.synchronize.mapping.GitModelWorkbenchAdapter;
@@ -46,7 +47,6 @@ import org.eclipse.egit.ui.internal.synchronize.mapping.GitObjectMapping;
import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
-import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Repository;
@@ -56,7 +56,6 @@ import org.eclipse.team.ui.history.IHistoryView;
import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.model.IWorkbenchAdapter;
-import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.part.IShowInSource;
/**
@@ -78,10 +77,8 @@ public class GitAdapterFactory implements IAdapterFactory {
}
if (IWorkbenchAdapter.class == adapterType) {
- // property page names for git repository tree nodes
if (adaptableObject instanceof RepositoryTreeNode) {
- return getRepositoryTreeNodeWorkbenchAdapter(
- (RepositoryTreeNode) adaptableObject);
+ return RepositoryTreeNodeWorkbenchAdapter.INSTANCE;
}
if (gitModelWorkbenchAdapter == null) {
@@ -217,15 +214,4 @@ public class GitAdapterFactory implements IAdapterFactory {
IResource.class, IWorkbenchAdapter.class, IShowInSource.class,
Repository.class, File.class, IHistoryPageSource.class};
}
-
- private static IWorkbenchAdapter getRepositoryTreeNodeWorkbenchAdapter(
- final RepositoryTreeNode node) {
- return new WorkbenchAdapter() {
- @Override
- public String getLabel(Object object) {
- ILabelProvider labelProvider= new RepositoriesViewLabelProvider();
- return labelProvider.getText(node);
- }
- };
- }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushTagsPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushTagsPage.java
index 453c41a5a..1c2390c39 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushTagsPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushTagsPage.java
@@ -24,7 +24,7 @@ import org.eclipse.egit.ui.internal.components.FilteredCheckboxTree;
import org.eclipse.egit.ui.internal.components.RemoteSelectionCombo;
import org.eclipse.egit.ui.internal.components.RemoteSelectionCombo.SelectionType;
import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
-import org.eclipse.egit.ui.internal.repository.RepositoriesViewStyledCellLabelProvider;
+import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
import org.eclipse.egit.ui.internal.repository.tree.TagNode;
import org.eclipse.egit.ui.internal.repository.tree.TagsNode;
import org.eclipse.jface.layout.GridDataFactory;
@@ -135,7 +135,7 @@ public class PushTagsPage extends WizardPage {
ContentProvider contentProvider = new ContentProvider(tagsNode);
treeViewer.setContentProvider(contentProvider);
treeViewer
- .setLabelProvider(new RepositoriesViewStyledCellLabelProvider());
+ .setLabelProvider(new RepositoriesViewLabelProvider());
treeViewer.setComparator(new ViewerComparator(
CommonUtils.STRING_ASCENDING_COMPARATOR));
treeViewer.setInput(tagsNode);
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 11f201999..7d907ecdd 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
@@ -80,7 +80,9 @@ import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
@@ -392,6 +394,12 @@ public class RepositoriesView extends CommonNavigator implements IShowInSource,
}
@Override
+ protected CommonViewer createCommonViewerObject(Composite aParent) {
+ return new RepositoriesCommonViewer(getViewSite().getId(), aParent,
+ SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ }
+
+ @Override
public Object getAdapter(Class adapter) {
// integrate with Properties view
if (adapter == IPropertySheetPage.class) {
@@ -1015,4 +1023,28 @@ public class RepositoriesView extends CommonNavigator implements IShowInSource,
return currentNode;
}
+
+ /**
+ * Customized {@link CommonViewer} that doesn't create a decorating label
+ * provider -- our label provider already does so, and we don't want double
+ * decorations.
+ */
+ private static class RepositoriesCommonViewer extends CommonViewer {
+
+ public RepositoriesCommonViewer(String viewId, Composite parent,
+ int style) {
+ super(viewId, parent, style);
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ IBaseLabelProvider labelProvider = getLabelProvider();
+ // Our label provider already decorates. Avoid double decorating.
+ if (labelProvider instanceof DecoratingStyledCellLabelProvider) {
+ ((DecoratingStyledCellLabelProvider) labelProvider)
+ .setLabelDecorator(null);
+ }
+ }
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
index f625ff639..7fb6ee295 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2013 SAP AG and others.
+ * Copyright (c) 2010, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -10,509 +10,90 @@
* Contributors:
* Mathias Kinzler (SAP AG) - initial implementation
* Chris Aniszczyk <caniszczyk@gmail.com> - added styled label support
+ * Thomas Wolf <thomas.wolf@paranor.ch> - bug 536814: completely refactored
*******************************************************************************/
package org.eclipse.egit.ui.internal.repository;
-import java.io.File;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.WeakHashMap;
-import org.eclipse.core.commands.IStateListener;
-import org.eclipse.core.commands.State;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.GitLabels;
-import org.eclipse.egit.ui.internal.ResourcePropertyTester;
-import org.eclipse.egit.ui.internal.UIIcons;
-import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
-import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
-import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
-import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
-import org.eclipse.egit.ui.internal.repository.tree.SubmodulesNode;
-import org.eclipse.egit.ui.internal.repository.tree.TagNode;
-import org.eclipse.egit.ui.internal.repository.tree.command.ToggleBranchCommitCommand;
-import org.eclipse.jface.resource.CompositeImageDescriptor;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.resource.LocalResourceManager;
-import org.eclipse.jface.resource.ResourceManager;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
+import org.eclipse.egit.ui.internal.repository.tree.WorkingDirNode;
+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledString;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.submodule.SubmoduleWalk;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
/**
- * Label Provider for the Git Repositories View
+ * A decorating label provider for repository tree nodes.
*/
-public class RepositoriesViewLabelProvider extends ColumnLabelProvider
- implements IStateListener, IStyledLabelProvider {
+public class RepositoriesViewLabelProvider
+ extends DecoratingStyledCellLabelProvider
+ implements ILabelProvider, IStyledLabelProvider {
- /**
- * A map of regular images to their decorated counterpart.
- */
- private Map<Image, Image> decoratedImages = new HashMap<>();
-
- private ResourceManager resourceManager = new LocalResourceManager(
- JFaceResources.getResources());
-
- private Image annotatedTagImage = resourceManager
- .createImage(UIIcons.TAG_ANNOTATED);
-
- private Image gerritRepoImage = resourceManager
- .createImage(UIIcons.REPOSITORY_GERRIT);
-
- private final State verboseBranchModeState;
+ private final WorkbenchLabelProvider labelProvider;
- private boolean verboseBranchMode = false;
+ private final WeakHashMap<Object, StyledString> previousDecoratedLabels = new WeakHashMap<>();
/**
- * Constructs a repositories view label provider
+ * Creates a new {@link RepositoriesViewLabelProvider}.
*/
public RepositoriesViewLabelProvider() {
- ICommandService srv = CommonUtils.getService(PlatformUI.getWorkbench(), ICommandService.class);
- verboseBranchModeState = srv.getCommand(ToggleBranchCommitCommand.ID)
- .getState(ToggleBranchCommitCommand.TOGGLE_STATE);
- verboseBranchModeState.addListener(this);
- try {
- this.verboseBranchMode = ((Boolean) verboseBranchModeState
- .getValue()).booleanValue();
- } catch (Exception e) {
- Activator.logError(e.getMessage(), e);
- }
- }
-
- @Override
- public Image getImage(Object element) {
- RepositoryTreeNode node = (RepositoryTreeNode) element;
- RepositoryTreeNodeType type = node.getType();
- if (type == RepositoryTreeNodeType.TAG) {
- TagNode tagNode = (TagNode) node;
- if (tagNode.isAnnotated())
- return decorateImage(annotatedTagImage, element);
- } else if (type == RepositoryTreeNodeType.FILE) {
- Object object = node.getObject();
- if (object instanceof File) {
- ImageDescriptor descriptor = PlatformUI.getWorkbench()
- .getEditorRegistry()
- .getImageDescriptor(((File) object).getName());
- return decorateImage((Image) resourceManager.get(descriptor),
- element);
- }
- } else if (type == RepositoryTreeNodeType.REPO) {
- Object object = node.getObject();
- if (object instanceof Repository) {
- Repository r = (Repository) object;
- if (ResourcePropertyTester.hasGerritConfiguration(r))
- return gerritRepoImage;
- }
- }
- return decorateImage(node.getType().getIcon(), element);
+ this(new WorkbenchLabelProvider());
}
- @Override
- public String getText(Object element) {
- if (!(element instanceof RepositoryTreeNode))
- return null;
-
- RepositoryTreeNode node = (RepositoryTreeNode) element;
-
- return getSimpleText(node);
+ private RepositoriesViewLabelProvider(
+ WorkbenchLabelProvider labelProvider) {
+ super(labelProvider, PlatformUI.getWorkbench()
+ .getDecoratorManager().getLabelDecorator(), null);
+ this.labelProvider = labelProvider;
}
@Override
public void dispose() {
- verboseBranchModeState.removeListener(this);
- // dispose of our decorated images
- for (Image image : decoratedImages.values()) {
- image.dispose();
- }
- resourceManager.dispose();
- decoratedImages.clear();
super.dispose();
- }
-
- private Image decorateImage(final Image image, Object element) {
-
- RepositoryTreeNode node = (RepositoryTreeNode) element;
- switch (node.getType()) {
-
- case TAG:
- // fall through
- case ADDITIONALREF:
- // fall through
- case REF:
- // if the branch or tag is checked out,
- // we want to decorate the corresponding
- // node with a little check indicator
- String refName = ((Ref) node.getObject()).getName();
- Ref leaf = ((Ref) node.getObject()).getLeaf();
-
- String branchName;
- String compareString;
-
- try {
- branchName = node.getRepository().getFullBranch();
- if (branchName == null)
- return image;
- if (refName.startsWith(Constants.R_HEADS)) {
- // local branch: HEAD would be on the branch
- compareString = refName;
- } else if (refName.startsWith(Constants.R_TAGS)) {
- // tag: HEAD would be on the commit id to which the tag is
- // pointing
- TagNode tagNode = (TagNode) node;
- compareString = tagNode.getCommitId();
- } else if (refName.startsWith(Constants.R_REMOTES)) {
- // remote branch: HEAD would be on the commit id to which
- // the branch is pointing
- ObjectId id = node.getRepository().resolve(refName);
- if (id == null)
- return image;
- try (RevWalk rw = new RevWalk(node.getRepository())) {
- RevCommit commit = rw.parseCommit(id);
- compareString = commit.getId().name();
- }
- } else if (refName.equals(Constants.HEAD)) {
- return getDecoratedImage(image);
- } else {
- String leafname = leaf.getName();
- if (leafname.startsWith(Constants.R_REFS)
- && leafname.equals(node.getRepository()
- .getFullBranch())) {
- return getDecoratedImage(image);
- }
- ObjectId objectId = leaf.getObjectId();
- if (objectId != null && objectId.equals(
- node.getRepository().resolve(Constants.HEAD))) {
- return getDecoratedImage(image);
- }
- // some other symbolic reference
- return image;
- }
- } catch (IOException e1) {
- return image;
- }
-
- if (compareString != null && compareString.equals(branchName)) {
- return getDecoratedImage(image);
- }
-
- return image;
-
- default:
- return image;
- }
- }
-
- private Image getDecoratedImage(final Image image) {
- // check if we have a decorated image yet or not
- Image decoratedImage = decoratedImages.get(image);
- if (decoratedImage == null) {
- // create one
- CompositeImageDescriptor cd = new CompositeImageDescriptor() {
-
- @Override
- protected Point getSize() {
- Rectangle bounds = image.getBounds();
- return new Point(bounds.width, bounds.height);
- }
-
- @Override
- protected void drawCompositeImage(int width, int height) {
- drawImage(image.getImageData(), 0, 0);
- drawImage(UIIcons.OVR_CHECKEDOUT.getImageData(), 0, 0);
-
- }
- };
- decoratedImage = cd.createImage();
- // store it
- decoratedImages.put(image, decoratedImage);
- }
- return decoratedImage;
- }
-
- private RevCommit getLatestCommit(RepositoryTreeNode node) {
- Ref ref = (Ref) node.getObject();
- ObjectId id;
- if (ref.isSymbolic())
- id = ref.getLeaf().getObjectId();
- else
- id = ref.getObjectId();
- if (id == null)
- return null;
- try (RevWalk walk = new RevWalk(node.getRepository())) {
- walk.setRetainBody(true);
- return walk.parseCommit(id);
- } catch (IOException ignored) {
- return null;
- }
- }
-
- private String abbreviate(final ObjectId id) {
- if (id != null)
- return id.abbreviate(7).name();
- else
- return ObjectId.zeroId().abbreviate(7).name();
- }
-
- /**
- * Get styled text for submodule repository node
- *
- * @param node
- * @return styled string
- */
- protected StyledString getStyledTextForSubmodule(RepositoryTreeNode node) {
- Repository repository = (Repository) node.getObject();
- if (repository == null) {
- return new StyledString();
- }
- StyledString string = GitLabels.getChangedPrefix(repository);
-
- String path = Repository.stripWorkDir(node.getParent().getRepository()
- .getWorkTree(), repository.getWorkTree());
- string.append(path);
-
- Ref head;
- try {
- head = repository.exactRef(Constants.HEAD);
- } catch (IOException e) {
- return string;
- }
- if (head != null) {
- string.append(' ');
- string.append('[', StyledString.DECORATIONS_STYLER);
- if (head.isSymbolic())
- string.append(
- Repository.shortenRefName(head.getLeaf().getName()),
- StyledString.DECORATIONS_STYLER);
- else if (head.getObjectId() != null)
- string.append(abbreviate(head.getObjectId()),
- StyledString.DECORATIONS_STYLER);
- string.append(']', StyledString.DECORATIONS_STYLER);
- if (verboseBranchMode && head.getObjectId() != null) {
- RevCommit commit;
- try (RevWalk walk = new RevWalk(repository)) {
- commit = walk.parseCommit(head.getObjectId());
- string.append(' ');
- string.append(commit.getShortMessage(),
- StyledString.QUALIFIER_STYLER);
- } catch (IOException ignored) {
- // Ignored
- }
- }
- }
- return string;
- }
-
- /**
- * Get styled text for commit node
- *
- * @param node
- * @return styled string
- */
- protected StyledString getStyledTextForCommit(StashedCommitNode node) {
- StyledString string = new StyledString();
- RevCommit commit = node.getObject();
- string.append(MessageFormat.format("{0}@'{'{1}'}'", //$NON-NLS-1$
- Constants.STASH, Integer.valueOf(node.getIndex())));
- string.append(' ');
- string.append('[', StyledString.DECORATIONS_STYLER);
- string.append(abbreviate(commit), StyledString.DECORATIONS_STYLER);
- string.append(']', StyledString.DECORATIONS_STYLER);
- string.append(' ');
- string.append(commit.getShortMessage(), StyledString.QUALIFIER_STYLER);
- return string;
- }
-
- /**
- * Gets the {@link StyledString} for a {@link SubmodulesNode}.
- *
- * @param node
- * to get the text for
- * @return the {@link StyledString}
- */
- protected StyledString getStyledTextForSubmodules(SubmodulesNode node) {
- String label = getSimpleText(node);
- if (label == null) {
- return new StyledString();
- }
- StyledString styled = new StyledString(label);
- Repository repository = node.getRepository();
- if (repository != null) {
- boolean hasChanges = false;
- try (SubmoduleWalk walk = SubmoduleWalk.forIndex(repository)) {
- while (!hasChanges && walk.next()) {
- Repository submodule = walk.getRepository();
- if (submodule != null) {
- Repository cached = org.eclipse.egit.core.Activator
- .getDefault().getRepositoryCache()
- .lookupRepository(submodule.getDirectory()
- .getAbsoluteFile());
- hasChanges = cached != null
- && RepositoryUtil.hasChanges(cached);
- submodule.close();
- }
- }
- } catch (IOException e) {
- hasChanges = false;
- }
- if (hasChanges) {
- StyledString prefixed = new StyledString();
- prefixed.append('>', StyledString.DECORATIONS_STYLER);
- prefixed.append(' ').append(styled);
- return prefixed;
- }
- }
- return styled;
+ previousDecoratedLabels.clear();
}
@Override
public StyledString getStyledText(Object element) {
- if (!(element instanceof RepositoryTreeNode))
- return null;
-
- RepositoryTreeNode node = (RepositoryTreeNode) element;
-
- switch (node.getType()) {
- case REPO:
- if (node.getParent() != null
- && node.getParent().getType() == RepositoryTreeNodeType.SUBMODULES)
- return getStyledTextForSubmodule(node);
- return GitLabels.getStyledLabelExtendedSafe(node.getObject());
- case ADDITIONALREF:
- Ref ref = (Ref) node.getObject();
- // shorten the name
- StyledString refName = new StyledString(
- Repository.shortenRefName(ref.getName()));
-
- if (ref.isSymbolic()) {
- refName.append(' ');
- refName.append('[', StyledString.DECORATIONS_STYLER);
- refName.append(ref.getLeaf().getName(),
- StyledString.DECORATIONS_STYLER);
- refName.append(']', StyledString.DECORATIONS_STYLER);
+ StyledString decoratedLabel = super.getStyledText(element);
+ if (decoratedLabel.getString().equals(labelProvider.getText(element))) {
+ // Decoration not available yet... but may be shortly. Try to
+ // prevent flickering by returning the previous decorated label, if
+ // any.
+ StyledString previousLabel = previousDecoratedLabels.get(element);
+ if (previousLabel != null) {
+ return previousLabel;
}
- ObjectId refId = ref.getObjectId();
- refName.append(' ');
- RevCommit commit = getLatestCommit(node);
- if (commit != null) {
- refName.append(abbreviate(commit),
- StyledString.QUALIFIER_STYLER)
- .append(' ')
- .append(commit.getShortMessage(),
+ }
+ if (element instanceof RepositoryNode) {
+ Repository repository = ((RepositoryNode) element).getRepository();
+ if (repository != null) {
+ decoratedLabel.append(" - ", StyledString.QUALIFIER_STYLER) //$NON-NLS-1$
+ .append(repository.getDirectory().getAbsolutePath(),
StyledString.QUALIFIER_STYLER);
- } else if (!ref.isSymbolic() || refId != null) {
- refName.append(abbreviate(refId),
- StyledString.QUALIFIER_STYLER);
- } else {
- refName.append(
- UIText.RepositoriesViewLabelProvider_UnbornBranchText,
- StyledString.QUALIFIER_STYLER);
}
- return refName;
- case WORKINGDIR:
- StyledString dirString = new StyledString(
- UIText.RepositoriesView_WorkingDir_treenode);
- dirString.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
- dirString.append(node.getRepository().getWorkTree()
- .getAbsolutePath(), StyledString.QUALIFIER_STYLER);
- return dirString;
-
- case REF:
- StyledString styled = null;
- String nodeText = getSimpleText(node);
- if (nodeText != null) {
- styled = new StyledString(nodeText);
- if (verboseBranchMode) {
- RevCommit latest = getLatestCommit(node);
- if (latest != null)
- styled.append(' ')
- .append(abbreviate(latest),
- StyledString.QUALIFIER_STYLER)
- .append(' ')
- .append(latest.getShortMessage(),
- StyledString.QUALIFIER_STYLER);
- }
+ } else if (element instanceof WorkingDirNode) {
+ Repository repository = ((WorkingDirNode) element).getRepository();
+ if (repository != null) {
+ decoratedLabel.append(" - ", StyledString.QUALIFIER_STYLER) //$NON-NLS-1$
+ .append(repository.getWorkTree().getAbsolutePath(),
+ StyledString.QUALIFIER_STYLER);
}
- return styled;
- case TAG:
- return getStyledTextForTag((TagNode) node);
- case STASHED_COMMIT:
- return getStyledTextForCommit((StashedCommitNode) node);
- case SUBMODULES:
- return getStyledTextForSubmodules((SubmodulesNode) node);
- case PUSH:
- // fall through
- case FETCH:
- // fall through
- case FILE:
- // fall through
- case FOLDER:
- // fall through
- case BRANCHES:
- // fall through
- case LOCAL:
- // fall through
- case REMOTETRACKING:
- // fall through
- case BRANCHHIERARCHY:
- // fall through
- case TAGS:
- // fall through;
- case ADDITIONALREFS:
- // fall through
- case REMOTES:
- // fall through
- case REMOTE:
- // fall through
- case STASH:
- // fall through
- case ERROR: {
- String label = getSimpleText(node);
- if (label != null)
- return new StyledString(label);
- }
-
}
-
- return null;
-
+ previousDecoratedLabels.put(element, decoratedLabel);
+ return decoratedLabel;
}
- private StyledString getStyledTextForTag(TagNode node) {
- String tagText = getSimpleText(node);
- if (tagText != null) {
- StyledString styled = new StyledString(tagText);
- if (verboseBranchMode) {
- if (node.getCommitId() != null
- && node.getCommitId().length() > 0)
- styled.append(' ')
- .append(node.getCommitId().substring(0, 7),
- StyledString.QUALIFIER_STYLER)
- .append(' ')
- .append(node.getCommitShortMessage(),
- StyledString.QUALIFIER_STYLER);
- }
- return styled;
- } else {
- return null;
- }
+ @Override
+ public String getText(Object element) {
+ return labelProvider.getText(element);
}
@Override
@@ -524,95 +105,4 @@ public class RepositoriesViewLabelProvider extends ColumnLabelProvider
}
return null;
}
-
- private String getSimpleText(RepositoryTreeNode node) {
- switch (node.getType()) {
- case REPO:
- Repository repository = (Repository) node.getObject();
- return GitLabels.getPlainShortLabel(repository);
- case FILE:
- // fall through
- case FOLDER:
- return ((File) node.getObject()).getName();
- case BRANCHES:
- return UIText.RepositoriesView_Branches_Nodetext;
- case LOCAL:
- return UIText.RepositoriesViewLabelProvider_LocalNodetext;
- case REMOTETRACKING:
- return UIText.RepositoriesViewLabelProvider_RemoteTrackingNodetext;
- case BRANCHHIERARCHY:
- IPath fullPath = (IPath) node.getObject();
- return fullPath.lastSegment();
- case TAGS:
- return UIText.RepositoriesViewLabelProvider_TagsNodeText;
- case ADDITIONALREFS:
- return UIText.RepositoriesViewLabelProvider_SymbolicRefNodeText;
- case REMOTES:
- return UIText.RepositoriesView_RemotesNodeText;
- case SUBMODULES:
- return UIText.RepositoriesViewLabelProvider_SubmodulesNodeText;
- case STASH:
- return UIText.RepositoriesViewLabelProvider_StashNodeText;
- case STASHED_COMMIT:
- return MessageFormat.format(
- "{0}@'{'{1}'}'", //$NON-NLS-1$
- Constants.STASH,
- Integer.valueOf(((StashedCommitNode) node).getIndex()));
- case REF:
- // fall through
- case TAG: {
- Ref ref = (Ref) node.getObject();
- // shorten the name
- String refName = Repository.shortenRefName(ref.getName());
- if (node.getParent().getType() == RepositoryTreeNodeType.BRANCHHIERARCHY) {
- int index = refName.lastIndexOf('/');
- refName = refName.substring(index + 1);
- }
- return refName;
- }
- case ADDITIONALREF: {
- Ref ref = (Ref) node.getObject();
- // shorten the name
- String refName = Repository.shortenRefName(ref.getName());
- if (ref.isSymbolic()) {
- refName = refName
- + " - " //$NON-NLS-1$
- + ref.getLeaf().getName()
- + " - " + ObjectId.toString(ref.getLeaf().getObjectId()); //$NON-NLS-1$
- } else {
- refName = refName + " - " //$NON-NLS-1$
- + ObjectId.toString(ref.getObjectId());
- }
- return refName;
- }
- case WORKINGDIR:
- return UIText.RepositoriesView_WorkingDir_treenode + " - " //$NON-NLS-1$
- + node.getRepository().getWorkTree().getAbsolutePath();
- case REMOTE:
- // fall through
- case PUSH:
- // fall through
- case FETCH:
- // fall through
- case ERROR:
- return (String) node.getObject();
-
- }
- return null;
- }
-
- /**
- * @see org.eclipse.core.commands.IStateListener#handleStateChange(org.eclipse.core.commands.State,
- * java.lang.Object)
- */
- @Override
- public void handleStateChange(State state, Object oldValue) {
- try {
- this.verboseBranchMode = ((Boolean) state.getValue())
- .booleanValue();
- } catch (Exception e) {
- Activator.logError(e.getMessage(), e);
- }
- }
-
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewStyledCellLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewStyledCellLabelProvider.java
deleted file mode 100644
index 5520ee3ae..000000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewStyledCellLabelProvider.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2013 Robin Stocker <robin@nibor.org> and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *******************************************************************************/
-package org.eclipse.egit.ui.internal.repository;
-
-import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-
-/**
- * Wraps {@link RepositoriesViewLabelProvider} in a
- * {@link DelegatingStyledCellLabelProvider} to provide styled text support for
- * use in tree or table viewers.
- * <p>
- * Also provides support for tool tips (see bug 236006 in platform which would
- * make this unnecessary).
- * <p>
- * Also implements ILabelProvider for use with PatternFilter (see bug 258029 in
- * platform which would make this unnecessary).
- */
-public class RepositoriesViewStyledCellLabelProvider extends
- DelegatingStyledCellLabelProvider implements ILabelProvider {
-
- /** */
- public RepositoriesViewStyledCellLabelProvider() {
- super(new RepositoriesViewLabelProvider());
- }
-
- @Override
- public String getText(Object element) {
- return getStyledStringProvider().getStyledText(element).getString();
- }
-
- @Override
- public String getToolTipText(Object element) {
- return ((RepositoriesViewLabelProvider) getStyledStringProvider())
- .getToolTipText(element);
- }
-
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeDecorator.java
new file mode 100644
index 000000000..206a2dee3
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeDecorator.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.repository;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import org.eclipse.core.commands.IStateListener;
+import org.eclipse.core.commands.State;
+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.GitLabels;
+import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.decorators.GitDecorator;
+import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
+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.RepositoryTreeNodeType;
+import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
+import org.eclipse.egit.ui.internal.repository.tree.TagNode;
+import org.eclipse.egit.ui.internal.repository.tree.command.ToggleBranchCommitCommand;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.lib.BranchTrackingStatus;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryState;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+
+/**
+ * Lightweight decorator for {@link RepositoryTreeNode}s. Note that this
+ * decorator does <em>not</em> listen on "references changed" events to fire
+ * {@link org.eclipse.jface.viewers.LabelProviderChangedEvent
+ * LabelProviderChangedEvent}s -- the RepositoriesView does so and refreshes
+ * itself completely.
+ */
+public class RepositoryTreeNodeDecorator extends GitDecorator
+ implements IStateListener {
+
+ private final State verboseBranchModeState;
+
+ private boolean verboseBranchMode = false;
+
+ /**
+ * Constructs a repositories view label provider
+ */
+ public RepositoryTreeNodeDecorator() {
+ ICommandService srv = CommonUtils.getService(PlatformUI.getWorkbench(), ICommandService.class);
+ verboseBranchModeState = srv.getCommand(ToggleBranchCommitCommand.ID)
+ .getState(ToggleBranchCommitCommand.TOGGLE_STATE);
+ verboseBranchModeState.addListener(this);
+ try {
+ this.verboseBranchMode = ((Boolean) verboseBranchModeState
+ .getValue()).booleanValue();
+ } catch (Exception e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ }
+
+ @Override
+ public void dispose() {
+ verboseBranchModeState.removeListener(this);
+ super.dispose();
+ }
+
+ @Override
+ public void handleStateChange(State state, Object oldValue) {
+ try {
+ boolean newValue = ((Boolean) state.getValue())
+ .booleanValue();
+ if (newValue != verboseBranchMode) {
+ verboseBranchMode = newValue;
+ postLabelEvent();
+ }
+ } catch (Exception e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void decorate(Object element, IDecoration decoration) {
+ RepositoryTreeNode<?> node = (RepositoryTreeNode) element;
+ Repository repository = node.getRepository();
+ if (repository != null) {
+ try {
+ decorateText(node, repository, decoration);
+ decorateImage(node, repository, decoration);
+ } catch (IOException e) {
+ Activator.logError(MessageFormat.format(
+ UIText.GitLabelProvider_UnableToRetrieveLabel,
+ element.toString()), e);
+ }
+ }
+ }
+
+ private void decorateText(RepositoryTreeNode<?> node,
+ @NonNull Repository repository, IDecoration decoration)
+ throws IOException {
+ switch (node.getType()) {
+ case REPO:
+ decorateRepository(node, repository, decoration);
+ break;
+ case ADDITIONALREF:
+ decorateAdditionalRef((AdditionalRefNode) node, decoration);
+ break;
+ case REF:
+ decorateRef((RefNode) node, decoration);
+ break;
+ case TAG:
+ decorateTag((TagNode) node, decoration);
+ break;
+ case STASHED_COMMIT:
+ decorateStash((StashedCommitNode) node, decoration);
+ break;
+ case SUBMODULES:
+ decorateSubmodules(repository, decoration);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void decorateAdditionalRef(AdditionalRefNode node,
+ IDecoration decoration) {
+ Ref ref = node.getObject();
+ StringBuilder suffix = new StringBuilder();
+ if (ref.isSymbolic()) {
+ suffix.append(" [").append(ref.getLeaf().getName()).append(']'); //$NON-NLS-1$
+ }
+ ObjectId refId = ref.getObjectId();
+ suffix.append(' ');
+ RevCommit commit = getLatestCommit(node);
+ if (commit != null) {
+ suffix.append(abbreviate(commit)).append(' ')
+ .append(commit.getShortMessage());
+ } else if (!ref.isSymbolic() || refId != null) {
+ suffix.append(abbreviate(refId));
+ } else {
+ suffix.append(
+ UIText.RepositoriesViewLabelProvider_UnbornBranchText);
+ }
+ decoration.addSuffix(suffix.toString());
+ }
+
+ private void decorateRef(RefNode node, IDecoration decoration) {
+ if (verboseBranchMode) {
+ RevCommit latest = getLatestCommit(node);
+ if (latest != null) {
+ decoration.addSuffix(" " + abbreviate(latest) + ' ' //$NON-NLS-1$
+ + latest.getShortMessage());
+ }
+ }
+ }
+
+ private void decorateRepository(RepositoryTreeNode<?> node,
+ @NonNull Repository repository, IDecoration decoration)
+ throws IOException {
+ boolean isSubModule = node.getParent() != null && node.getParent()
+ .getType() == RepositoryTreeNodeType.SUBMODULES;
+ if (RepositoryUtil.hasChanges(repository)) {
+ decoration.addPrefix("> "); //$NON-NLS-1$
+ }
+ StringBuilder suffix = new StringBuilder();
+ if (isSubModule) {
+ Ref head = repository.exactRef(Constants.HEAD);
+ if (head == null) {
+ return;
+ }
+ suffix.append(" ["); //$NON-NLS-1$
+ if (head.isSymbolic()) {
+ suffix.append(
+ Repository.shortenRefName(head.getLeaf().getName()));
+ } else if (head.getObjectId() != null) {
+ suffix.append(abbreviate(head.getObjectId()));
+ }
+ suffix.append(']');
+ if (verboseBranchMode && head.getObjectId() != null) {
+ try (RevWalk walk = new RevWalk(repository)) {
+ RevCommit commit = walk.parseCommit(head.getObjectId());
+ suffix.append(' ').append(commit.getShortMessage());
+ } catch (IOException ignored) {
+ // Ignored
+ }
+ }
+ } else {
+ // Not a submodule
+ String branch = Activator.getDefault().getRepositoryUtil()
+ .getShortBranch(repository);
+ if (branch == null) {
+ return;
+ }
+ suffix.append(" ["); //$NON-NLS-1$
+ suffix.append(branch);
+
+ BranchTrackingStatus trackingStatus = BranchTrackingStatus
+ .of(repository, branch);
+ if (trackingStatus != null && (trackingStatus.getAheadCount() != 0
+ || trackingStatus.getBehindCount() != 0)) {
+ String formattedTrackingStatus = GitLabels
+ .formatBranchTrackingStatus(trackingStatus);
+ suffix.append(' ').append(formattedTrackingStatus);
+ }
+
+ RepositoryState repositoryState = repository.getRepositoryState();
+ if (repositoryState != RepositoryState.SAFE) {
+ suffix.append(" - ") //$NON-NLS-1$
+ .append(repositoryState.getDescription());
+ }
+ suffix.append(']');
+ }
+ decoration.addSuffix(suffix.toString());
+ }
+
+ private void decorateStash(StashedCommitNode node, IDecoration decoration) {
+ RevCommit commit = node.getObject();
+ decoration.addSuffix(
+ " [" + abbreviate(commit) + "] " + commit.getShortMessage()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void decorateSubmodules(@NonNull Repository repository,
+ IDecoration decoration) throws IOException {
+ if (haveSubmoduleChanges(repository)) {
+ decoration.addPrefix("> "); //$NON-NLS-1$
+ }
+ }
+
+ private void decorateTag(TagNode node, IDecoration decoration) {
+ if (verboseBranchMode && node.getCommitId() != null
+ && node.getCommitId().length() > 0) {
+ decoration.addSuffix(" " + node.getCommitId().substring(0, 7) + ' ' //$NON-NLS-1$
+ + node.getCommitShortMessage());
+ }
+ }
+
+ private void decorateImage(RepositoryTreeNode<?> node,
+ @NonNull Repository repository, IDecoration decoration)
+ throws IOException {
+
+ switch (node.getType()) {
+ case TAG:
+ case ADDITIONALREF:
+ case REF:
+ // if the branch or tag is checked out,
+ // we want to decorate the corresponding
+ // node with a little check indicator
+ String refName = ((Ref) node.getObject()).getName();
+ Ref leaf = ((Ref) node.getObject()).getLeaf();
+
+ String compareString = null;
+
+ String branchName = repository.getFullBranch();
+ if (branchName == null) {
+ return;
+ }
+ if (refName.startsWith(Constants.R_HEADS)) {
+ // local branch: HEAD would be on the branch
+ compareString = refName;
+ } else if (refName.startsWith(Constants.R_TAGS)) {
+ // tag: HEAD would be on the commit id to which the tag is
+ // pointing
+ TagNode tagNode = (TagNode) node;
+ compareString = tagNode.getCommitId();
+ } else if (refName.startsWith(Constants.R_REMOTES)) {
+ // remote branch: HEAD would be on the commit id to which
+ // the branch is pointing
+ ObjectId id = repository.resolve(refName);
+ if (id == null) {
+ return;
+ }
+ try (RevWalk rw = new RevWalk(repository)) {
+ RevCommit commit = rw.parseCommit(id);
+ compareString = commit.getId().name();
+ }
+ } else if (refName.equals(Constants.HEAD)) {
+ decoration.addOverlay(UIIcons.OVR_CHECKEDOUT,
+ IDecoration.TOP_LEFT);
+ return;
+ } else {
+ String leafname = leaf.getName();
+ if (leafname.startsWith(Constants.R_REFS)
+ && leafname.equals(branchName)) {
+ decoration.addOverlay(UIIcons.OVR_CHECKEDOUT,
+ IDecoration.TOP_LEFT);
+ return;
+ }
+ ObjectId objectId = leaf.getObjectId();
+ if (objectId != null && objectId
+ .equals(repository.resolve(Constants.HEAD))) {
+ decoration.addOverlay(UIIcons.OVR_CHECKEDOUT,
+ IDecoration.TOP_LEFT);
+ return;
+ }
+ // some other symbolic reference
+ return;
+ }
+
+ if (compareString != null && compareString.equals(branchName)) {
+ decoration.addOverlay(UIIcons.OVR_CHECKEDOUT,
+ IDecoration.TOP_LEFT);
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ private RevCommit getLatestCommit(RepositoryTreeNode node) {
+ Ref ref = (Ref) node.getObject();
+ ObjectId id;
+ if (ref.isSymbolic()) {
+ id = ref.getLeaf().getObjectId();
+ } else {
+ id = ref.getObjectId();
+ }
+ if (id == null) {
+ return null;
+ }
+ try (RevWalk walk = new RevWalk(node.getRepository())) {
+ walk.setRetainBody(true);
+ return walk.parseCommit(id);
+ } catch (IOException ignored) {
+ return null;
+ }
+ }
+
+ private String abbreviate(final ObjectId id) {
+ if (id != null) {
+ return id.abbreviate(7).name();
+ } else {
+ return ObjectId.zeroId().abbreviate(7).name();
+ }
+ }
+
+ private boolean haveSubmoduleChanges(@NonNull Repository repository)
+ throws IOException {
+ boolean hasChanges = false;
+ try (SubmoduleWalk walk = SubmoduleWalk.forIndex(repository)) {
+ while (!hasChanges && walk.next()) {
+ Repository submodule = walk.getRepository();
+ if (submodule != null) {
+ Repository cached = org.eclipse.egit.core.Activator
+ .getDefault().getRepositoryCache().lookupRepository(
+ submodule.getDirectory().getAbsoluteFile());
+ hasChanges = cached != null
+ && RepositoryUtil.hasChanges(cached);
+ submodule.close();
+ }
+ }
+ }
+ return hasChanges;
+ }
+
+ @Override
+ protected String getName() {
+ return UIText.RepositoryTreeNodeDecorator_name;
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeWorkbenchAdapter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeWorkbenchAdapter.java
new file mode 100644
index 000000000..442ec5938
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNodeWorkbenchAdapter.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.repository;
+
+import java.io.File;
+import java.text.MessageFormat;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.ui.internal.GitLabels;
+import org.eclipse.egit.ui.internal.ResourcePropertyTester;
+import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
+import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
+import org.eclipse.egit.ui.internal.repository.tree.TagNode;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.model.WorkbenchAdapter;
+
+/**
+ * A {@link WorkbenchAdapter} for {@link RepositoryTreeNode}s, providing images
+ * and labels. The adapter does <em>not</em> deliver children. That
+ * functionality is left to the content provider since it may depend on global
+ * state.
+ */
+public class RepositoryTreeNodeWorkbenchAdapter extends WorkbenchAdapter {
+
+ /**
+ * The singleton instance of the {@link RepositoryTreeNodeWorkbenchAdapter}.
+ */
+ public static final RepositoryTreeNodeWorkbenchAdapter INSTANCE = new RepositoryTreeNodeWorkbenchAdapter();
+
+ private RepositoryTreeNodeWorkbenchAdapter() {
+ // Prevent creations outside of this class
+ }
+
+ @Override
+ public Object getParent(Object object) {
+ return ((RepositoryTreeNode) object).getParent();
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor(Object object) {
+ RepositoryTreeNode<?> node = (RepositoryTreeNode) object;
+ switch (node.getType()) {
+ case FILE: {
+ Object item = node.getObject();
+ if (item instanceof File) {
+ return PlatformUI.getWorkbench().getEditorRegistry()
+ .getImageDescriptor(((File) item).getName());
+ }
+ break;
+ }
+ case REPO: {
+ Object item = node.getObject();
+ if (item instanceof Repository && ResourcePropertyTester
+ .hasGerritConfiguration((Repository) item)) {
+ return UIIcons.REPOSITORY_GERRIT;
+ }
+ break;
+ }
+ case TAG:
+ if (((TagNode) node).isAnnotated()) {
+ return UIIcons.TAG_ANNOTATED;
+ }
+ break;
+ default:
+ break;
+ }
+ return node.getType().getIcon();
+ }
+
+ @Override
+ public String getLabel(Object object) {
+ RepositoryTreeNode<?> node = (RepositoryTreeNode) object;
+ switch (node.getType()) {
+ case REPO:
+ Repository repository = (Repository) node.getObject();
+ return GitLabels.getPlainShortLabel(repository);
+ case FILE:
+ case FOLDER:
+ return ((File) node.getObject()).getName();
+ case BRANCHES:
+ return UIText.RepositoriesView_Branches_Nodetext;
+ case LOCAL:
+ return UIText.RepositoriesViewLabelProvider_LocalNodetext;
+ case REMOTETRACKING:
+ return UIText.RepositoriesViewLabelProvider_RemoteTrackingNodetext;
+ case BRANCHHIERARCHY:
+ IPath fullPath = (IPath) node.getObject();
+ return fullPath.lastSegment();
+ case TAGS:
+ return UIText.RepositoriesViewLabelProvider_TagsNodeText;
+ case ADDITIONALREFS:
+ return UIText.RepositoriesViewLabelProvider_SymbolicRefNodeText;
+ case REMOTES:
+ return UIText.RepositoriesView_RemotesNodeText;
+ case SUBMODULES:
+ return UIText.RepositoriesViewLabelProvider_SubmodulesNodeText;
+ case STASH:
+ return UIText.RepositoriesViewLabelProvider_StashNodeText;
+ case STASHED_COMMIT:
+ return MessageFormat.format("{0}@'{'{1}'}'", //$NON-NLS-1$
+ Constants.STASH,
+ Integer.valueOf(((StashedCommitNode) node).getIndex()));
+ case REF:
+ case TAG: {
+ Ref ref = (Ref) node.getObject();
+ // shorten the name
+ String refName = Repository.shortenRefName(ref.getName());
+ if (node.getParent()
+ .getType() == RepositoryTreeNodeType.BRANCHHIERARCHY) {
+ refName = refName.substring(refName.lastIndexOf('/') + 1);
+ }
+ return refName;
+ }
+ case ADDITIONALREF: {
+ Ref ref = (Ref) node.getObject();
+ return Repository.shortenRefName(ref.getName());
+ }
+ case WORKINGDIR:
+ return UIText.RepositoriesView_WorkingDir_treenode;
+ default:
+ return (String) node.getObject();
+ }
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/RepositoryTreeNodeType.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/RepositoryTreeNodeType.java
index b4fc9f75a..0356a4bce 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/RepositoryTreeNodeType.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/RepositoryTreeNodeType.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
+ * Copyright (c) 2010, 2018 SAP AG and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,11 +9,12 @@
*
* Contributors:
* Mathias Kinzler (SAP AG) - initial implementation
+ * Thomas Wolf <thomas.wolf@paranor.ch> - change from Image to ImageDescriptor
*******************************************************************************/
package org.eclipse.egit.ui.internal.repository.tree;
import org.eclipse.egit.ui.internal.UIIcons;
-import org.eclipse.swt.graphics.Image;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
@@ -22,68 +23,68 @@ import org.eclipse.ui.PlatformUI;
*/
public enum RepositoryTreeNodeType {
/** */
- REPO(UIIcons.REPOSITORY.createImage()), //
+ REPO(UIIcons.REPOSITORY), //
/** */
- BRANCHES(UIIcons.BRANCHES.createImage()), //
+ BRANCHES(UIIcons.BRANCHES), //
/** */
- REF(UIIcons.BRANCH.createImage()), //
+ REF(UIIcons.BRANCH), //
/** */
- LOCAL(PlatformUI.getWorkbench().getSharedImages().getImage(
+ LOCAL(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- BRANCHHIERARCHY(PlatformUI.getWorkbench().getSharedImages().getImage(
+ BRANCHHIERARCHY(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- REMOTETRACKING(PlatformUI.getWorkbench().getSharedImages().getImage(
+ REMOTETRACKING(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- TAGS(UIIcons.TAGS.createImage()), //
+ TAGS(UIIcons.TAGS), //
/** */
- ADDITIONALREFS(PlatformUI.getWorkbench().getSharedImages().getImage(
+ ADDITIONALREFS(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- ADDITIONALREF(PlatformUI.getWorkbench().getSharedImages().getImage(
+ ADDITIONALREF(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FILE)), // TODO icon
/** */
- TAG(UIIcons.TAG.createImage()), //
+ TAG(UIIcons.TAG), //
/** */
- FOLDER(PlatformUI.getWorkbench().getSharedImages().getImage(
+ FOLDER(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- FILE(PlatformUI.getWorkbench().getSharedImages().getImage(
+ FILE(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FILE)), //
/** */
- REMOTES(UIIcons.REMOTE_REPOSITORY.createImage()), //
+ REMOTES(UIIcons.REMOTE_REPOSITORY), //
/** */
- REMOTE(UIIcons.REMOTE_SPEC.createImage()), //
+ REMOTE(UIIcons.REMOTE_SPEC), //
/** */
- FETCH(UIIcons.FETCH.createImage()), //
+ FETCH(UIIcons.FETCH), //
/** */
- PUSH(UIIcons.PUSH.createImage()), //
+ PUSH(UIIcons.PUSH), //
/** */
- SUBMODULES(UIIcons.SUBMODULES.createImage()),
+ SUBMODULES(UIIcons.SUBMODULES),
/** */
- STASH(UIIcons.STASH.createImage()),
+ STASH(UIIcons.STASH),
/** */
- STASHED_COMMIT(UIIcons.CHANGESET.createImage()),
+ STASHED_COMMIT(UIIcons.CHANGESET),
/** */
- WORKINGDIR(PlatformUI.getWorkbench().getSharedImages().getImage(
+ WORKINGDIR(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_OBJ_FOLDER)), //
/** */
- ERROR(PlatformUI.getWorkbench().getSharedImages().getImage(
+ ERROR(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
ISharedImages.IMG_ELCL_STOP)); // TODO icon?
- private final Image myImage;
+ private final ImageDescriptor myImage;
- private RepositoryTreeNodeType(Image icon) {
+ private RepositoryTreeNodeType(ImageDescriptor icon) {
myImage = icon;
}
/**
- * @return the icon for this type
+ * @return the {@link ImageDescriptor} for the icon for this type
*/
- public Image getIcon() {
+ public ImageDescriptor getIcon() {
return myImage;
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
index 8652045b9..82c3f1c02 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 GitHub Inc.
+ * Copyright (c) 2011, 2018 GitHub Inc. and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -42,7 +42,6 @@ import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.search.ui.ISearchPage;
@@ -313,8 +312,7 @@ public class CommitSearchPage extends DialogPage implements ISearchPage {
repositoryGroup, SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL
| SWT.BORDER);
this.repositoryViewer
- .setLabelProvider(new DelegatingStyledCellLabelProvider(
- new RepositoriesViewLabelProvider()));
+ .setLabelProvider(new RepositoriesViewLabelProvider());
this.repositoryViewer
.setContentProvider(new RepositoriesViewContentProvider());
this.repositoryViewer
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 2c95fb4f9..0cce452f6 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
@@ -153,6 +153,7 @@ GitCloneWizard_jobImportProjects=Importing projects from ''{0}''
GitCloneWizard_jobName=Cloning from {0}
GitCloneWizard_failed=Git repository clone failed.
GitCloneWizard_errorCannotCreate=Cannot create directory {0}.
+GitDecorator_jobTitle=Git decorator updates ({0}).
GitDecoratorPreferencePage_bindingRepositoryNameFlag=Name and state of the repository (the default state will not be shown)
GitDecoratorPreferencePage_iconsShowDirty=Dirty resources
GitDocument_errorLoadCommit=Could not load commit {0} for {1} corresponding to {2} in {3}
@@ -235,6 +236,7 @@ GitHistoryPage_pushCommit=&Push Commit...
GitHistoryPage_ShowSubMenuLabel=&Show
GitHistoryPage_ColumnsSubMenuLabel=&Columns
GitHistoryPage_toggleEmailAddresses=&E-mail Addresses
+GitLightweightDecorator_name=Git resource decorations
GitPreferenceRoot_automaticallyEnableChangesetModel=Automatically enable commit &grouping in Git synchronizations
GitPreferenceRoot_BlameGroupHeader=Revision Information
GitPreferenceRoot_BlameIgnoreWhitespaceLabel=Ignore whitespace changes
@@ -435,6 +437,7 @@ RepositoryAction_multiRepoSelection=Cannot perform action on multiple repositori
RepositoryAction_multiRepoSelectionTitle=Multiple Repositories Selection
RepositoryToolbarAction_label=Repository
RepositoryToolbarAction_tooltip=Switch repository
+RepositoryTreeNodeDecorator_name=Git object decorations
RepositoryCommit_AuthorDate=\ ({0} on {1})
RepositoryCommit_AuthorDateCommitter=\ ({0} on {1}, committed by {2})
RepositoryLocationPage_info=Select a location of Git Repositories