diff options
Diffstat (limited to 'org.eclipse.egit.ui')
20 files changed, 826 insertions, 757 deletions
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index fdad269b85..e5bfeb4e5d 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 b965a4e832..9b930e20cc 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 27ed16312c..7d042eaf7d 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 396169b9d5..72b824df42 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 0bf6e49f05..1c5d86c90a 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 2ab73d9bee..cedc7f793f 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 1444d8d52e..616dde3c73 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 0000000000..f3619767b8 --- /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 4f6b417adf..a4dcd2ff8f 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 677c18dba9..e13b607efb 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 95899f99f5..63ecd9258d 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 453c41a5a2..1c2390c394 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 11f201999e..7d907ecdd9 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 f625ff639a..7fb6ee295f 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 5520ee3ae3..0000000000 --- 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 0000000000..206a2dee3e --- /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 0000000000..442ec59388 --- /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 b4fc9f75a7..0356a4bcee 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 8652045b90..82c3f1c02d 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 2c95fb4f90..0cce452f66 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 |