/******************************************************************************* * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org> * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com> * Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch> * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.egit.ui.internal.synchronize.mapping; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.ListenerList; import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.UIPreferences; import org.eclipse.egit.ui.internal.GitLabelProvider; import org.eclipse.egit.ui.internal.PreferenceBasedDateFormatter; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator; import org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider; import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.team.ui.mapping.SynchronizationLabelProvider; /** * Label provider for Git ChangeSet model. */ public class GitChangeSetLabelProvider extends SynchronizationLabelProvider implements IStyledLabelProvider { /** */ public static final String BINDING_CHANGESET_SHORT_MESSAGE = '{' + GitLightweightDecorator.DecorationHelper.BINDING_SHORT_MESSAGE + '}'; /** */ public static final String BINDING_CHANGESET_COMMITTER = "{committer}"; //$NON-NLS-1$ /** */ public static final String BINDING_CHANGESET_AUTHOR = "{author}"; //$NON-NLS-1$ /** */ public static final String BINDING_CHANGESET_DATE = "{date}"; //$NON-NLS-1$ private GitLabelProvider delegateLabelProvider; private final ListenerList listeners = new ListenerList( ListenerList.IDENTITY); private final IPreferenceStore store = Activator.getDefault() .getPreferenceStore(); private final IPropertyChangeListener uiPrefsListener; private PreferenceBasedDateFormatter dateFormatter; /** * Creates a new {@link GitChangeSetLabelProvider}. */ public GitChangeSetLabelProvider() { dateFormatter = PreferenceBasedDateFormatter.create(); uiPrefsListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { String property = event.getProperty(); if (UIPreferences.DATE_FORMAT.equals(property) || UIPreferences.DATE_FORMAT_CHOICE.equals(property)) { dateFormatter = PreferenceBasedDateFormatter.create(); fireLabelProviderChanged(new LabelProviderChangedEvent( GitChangeSetLabelProvider.this)); } } }; store.addPropertyChangeListener(uiPrefsListener); } @Override protected GitLabelProvider getDelegateLabelProvider() { if (delegateLabelProvider == null) delegateLabelProvider = new GitLabelProvider(); return delegateLabelProvider; } @Override public StyledString getStyledText(Object element) { // need to compare classes as everything is 'instanceof GitModelCommit' if (element.getClass().equals(GitModelCommit.class)) { String formattedName = createChangeSetLabel((GitModelCommit) element); StyledString string = new StyledString(formattedName); GitModelCommit commit = (GitModelCommit) element; String format = " [" + getAbbreviatedId(commit) + "]"; //$NON-NLS-1$//$NON-NLS-2$ string.append(format, StyledString.DECORATIONS_STYLER); return string; } if (element instanceof GitChangeSetModelProvider) return new StyledString(UIText.GitChangeSetModelProviderLabel); return getDelegateLabelProvider().getStyledText(element); } private String createChangeSetLabel(GitModelCommit commitModel) { String format = store.getString(UIPreferences.SYNC_VIEW_CHANGESET_LABEL_FORMAT); Commit commit = commitModel.getCachedCommitObj(); Map<String, String> bindings = new HashMap<>(); bindings.put(BINDING_CHANGESET_DATE, dateFormatter.formatDate(commit.getCommitDate())); bindings.put(BINDING_CHANGESET_AUTHOR, commit.getAuthorName()); bindings.put(BINDING_CHANGESET_COMMITTER, commit.getCommitterName()); bindings.put(BINDING_CHANGESET_SHORT_MESSAGE, commit.getShortMessage()); return formatName(format, bindings); } /** * @param format * @param bindings * @return formatted commit name */ public static String formatName(final String format, Map<String, String> bindings) { String result = format; for (Entry<String, String> e : bindings.entrySet()) { result = result.replace(e.getKey(), e.getValue()); } return result; } private String getAbbreviatedId(GitModelCommit commit) { AbbreviatedObjectId shortId = commit.getCachedCommitObj().getId(); return shortId.name().substring(0, 6); } // The super class adds the listeners to the delegate label provider, where // we don't have access. Therefore we keep our own listener list, and do the // notification ourselves when the date format preferences change. @Override public void addListener(ILabelProviderListener listener) { super.addListener(listener); listeners.add(listener); } @Override public void removeListener(ILabelProviderListener listener) { listeners.remove(listener); super.removeListener(listener); } private void fireLabelProviderChanged( final LabelProviderChangedEvent event) { for (Object o : listeners.getListeners()) { final ILabelProviderListener l = (ILabelProviderListener) o; SafeRunnable.run(new SafeRunnable() { @Override public void run() { l.labelProviderChanged(event); } }); } } @Override public void dispose() { store.removePropertyChangeListener(uiPrefsListener); listeners.clear(); super.dispose(); } }