/*******************************************************************************
* Copyright (C) 2015, Max Hohenegger <eclipse@hohenegger.eu>
*
* 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.gitflow.ui.internal.decorators;
import java.io.IOException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.egit.gitflow.GitFlowRepository;
import org.eclipse.egit.gitflow.ui.Activator;
import org.eclipse.egit.gitflow.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.ui.PlatformUI;
/**
* Supplies decorations for displayed repositories
*/
public class GitFlowLightweightDecorator extends LabelProvider implements
ILightweightLabelDecorator {
/**
* Property constant pointing back to the extension point id of the
* decorator
*/
public static final String DECORATOR_ID = "org.eclipse.egit.gitflow.ui.internal.decorators.GitflowLightweightDecorator"; //$NON-NLS-1$
private ILog log;
/** */
public GitFlowLightweightDecorator() {
log = Activator.getDefault().getLog();
}
/**
* This method should only be called by the decorator thread.
*
* @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object,
* org.eclipse.jface.viewers.IDecoration)
*/
@Override
public void decorate(Object element, IDecoration decoration) {
// Don't decorate if UI plugin is not running
if (Activator.getDefault() == null) {
return;
}
// Don't decorate if the workbench is not running
if (!PlatformUI.isWorkbenchRunning()) {
return;
}
final GitFlowRepository repository = getRepository(element);
try {
if (repository != null) {
decorateRepository(repository, decoration);
}
} catch (Exception e) {
handleException(repository, e);
}
}
private static @Nullable GitFlowRepository getRepository(Object element) {
GitFlowRepository repository = null;
if (element instanceof GitFlowRepository) {
repository = (GitFlowRepository) element;
}
if (element instanceof RepositoryNode) {
RepositoryNode node = (RepositoryNode) element;
Repository repo = node.getObject();
if (repo != null) {
repository = new GitFlowRepository(repo);
}
}
return repository;
}
/**
* Decorates a single repository.
*
* @param repository
* the repository to decorate
* @param decoration
* the decoration
* @throws IOException
*/
private void decorateRepository(GitFlowRepository repository,
IDecoration decoration) throws IOException {
final DecorationHelper helper = new DecorationHelper();
helper.decorate(decoration, repository);
}
/**
* Helper class for doing repository decoration
*
* Used for real-time decoration, as well as in the decorator preview
* preferences page
*/
private static class DecorationHelper {
/**
* Define a cached image descriptor which only creates the image data
* once
*/
private static class CachedImageDescriptor extends ImageDescriptor {
private ImageDescriptor descriptor;
private ImageData data;
public CachedImageDescriptor(ImageDescriptor descriptor) {
this.descriptor = descriptor;
}
@Override
public ImageData getImageData() {
if (data == null) {
data = descriptor.getImageData();
}
return data;
}
}
private final static ImageDescriptor INITIALIZED_IMAGE;
static {
INITIALIZED_IMAGE = new CachedImageDescriptor(UIIcons.OVR_GITFLOW);
}
/**
* Decorates the given <code>decoration</code> based on the state of the
* given <code>repository</code>.
*
* @param decoration
* the decoration to decorate
* @param repository
* the repository to retrieve state from
* @throws IOException
*/
public void decorate(IDecoration decoration, GitFlowRepository repository)
throws IOException {
decorateIcons(decoration, repository);
}
private void decorateIcons(IDecoration decoration,
GitFlowRepository repository) throws IOException {
ImageDescriptor overlay = null;
if (repository.getConfig().isInitialized()) {
overlay = INITIALIZED_IMAGE;
}
// TODO: change decoration depending on branch type, e.g. "F"-icon
// for feature branch
// Overlays can only be added once, so do it at the end
decoration.addOverlay(overlay);
}
}
/**
* Handle exceptions that occur in the decorator.
*
* @param repository
* The repository that triggered the exception
* @param e
* The exception that occurred
*/
private void handleException(GitFlowRepository repository, Exception e) {
if (repository != null) {
log.log(Activator.error(e.getMessage(), e));
}
}
}