/** | |
* Copyright (c) 2011, 2017 Mia-Software. | |
* | |
* 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 | |
* | |
* Contributors: | |
* Gregoire Dupe (Mia-Software) - Bug 361794 - [Restructuring] New customization meta-model | |
* Gregoire Dupe (Mia-Software) - Bug 369987 - [Restructuring][Table] Switch to the new customization and facet framework | |
* Nicolas Bros (Mia-Software) - Bug 372198 - resource leak in org.eclipse.emf.facet.custom.ui.internal.CustomizedLabelProvider | |
* Vincent Lorenzo (CEA-LIST) - Bug 372644 - Create Customizable tooltips for the TreeViewer using a CustomizableLabelProvider | |
* Gregoire Dupe (Mia-Software) - Bug 373078 - API Cleaning | |
* Nicolas Bros (Mia-Software) - Bug 374941 - To be able to customize overlay icons on EClass | |
* Gregoire Dupe (Mia-Software) - Bug 374941 - To be able to customize overlay icons on EClass | |
* Gregoire Dupe (Mia-Software) - Bug 364325 - [Restructuring] The user must be able to navigate into a model using the Facet. | |
* Vincent Lorenzo (CEA-LIST) - Bug 352603 - [Table] A tooltip which displays the full label of a String cell editor | |
* Grégoire Dupé(Mia-Software) - Bug 352603 - [Table] A tooltip which displays the full label of a String cell editor | |
* David Couvrand (Soft-Maint) - Bug 402725 - Need a query to get an image from an URI | |
* Nicolas Rault (Soft-Maint) - Bug 402725 - Need a query to get an image from an URI | |
* David Couvrand (Soft-Maint) - Bug 418418 - [Customization] Overlay icons not implemented | |
* David Couvrand (Soft-Maint) - Bug 422058 - Implementation of strikethrough and underline in the CustomizedLabelProvider | |
* Grégoire Dupé (Mia-Software) - Bug 424122 - [Table] Images, fonts and colors are not shared between the instances of table | |
* Thomas Cicognani (Soft-Maint) - Bug 424414 - ImageManager doesn't cache images | |
* Thomas Cicognani (Mia-Software) - Bug 513070 - NatTable and customization: cannot change background from columns | |
*/ | |
package org.eclipse.emf.facet.custom.ui.internal; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.ecore.ETypedElement; | |
import org.eclipse.emf.ecore.resource.ResourceSet; | |
import org.eclipse.emf.facet.custom.core.ICustomizationManager; | |
import org.eclipse.emf.facet.custom.core.ICustomizationManagerFactory; | |
import org.eclipse.emf.facet.custom.core.exception.CustomizationException; | |
import org.eclipse.emf.facet.custom.core.internal.exported.CustomizationUtils; | |
import org.eclipse.emf.facet.custom.metamodel.custompt.IColor; | |
import org.eclipse.emf.facet.custom.metamodel.custompt.IImage; | |
import org.eclipse.emf.facet.custom.metamodel.v0_2_0.custompt.Alignment; | |
import org.eclipse.emf.facet.custom.metamodel.v0_2_0.custompt.Shadow; | |
import org.eclipse.emf.facet.custom.ui.ICustomOverride; | |
import org.eclipse.emf.facet.custom.ui.ICustomizedLabelProvider; | |
import org.eclipse.emf.facet.efacet.metamodel.v0_2_0.efacet.FacetOperation; | |
import org.eclipse.emf.facet.util.core.DebugUtils; | |
import org.eclipse.emf.facet.util.core.Logger; | |
import org.eclipse.emf.facet.util.swt.colorprovider.IColorProvider; | |
import org.eclipse.emf.facet.util.swt.colorprovider.IColorProviderFactory; | |
import org.eclipse.emf.facet.util.swt.fontprovider.IFontProvider; | |
import org.eclipse.emf.facet.util.swt.fontprovider.IFontProviderFactory; | |
import org.eclipse.jface.viewers.CellLabelProvider; | |
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; | |
import org.eclipse.jface.viewers.ILabelProviderListener; | |
import org.eclipse.jface.viewers.StyledString; | |
import org.eclipse.jface.viewers.ViewerCell; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.graphics.Color; | |
import org.eclipse.swt.graphics.Font; | |
import org.eclipse.swt.graphics.FontData; | |
import org.eclipse.swt.graphics.Image; | |
import org.eclipse.swt.graphics.RGB; | |
import org.eclipse.swt.widgets.Display; | |
import org.osgi.framework.Bundle; | |
import org.osgi.framework.BundleContext; | |
import org.osgi.framework.ServiceReference; | |
public class CustomizedLabelProvider extends CellLabelProvider implements | |
ICustomizedLabelProvider, IStyledLabelProvider { | |
private static final boolean DEBUG_FONT = DebugUtils.getDebugStatus(Activator.getDefault(), "font"); //$NON-NLS-1$ | |
private static final boolean DEBUG_COLOR = DebugUtils.getDebugStatus(Activator.getDefault(), "color"); //$NON-NLS-1$ | |
private static final int RGB_MAX = 255; | |
private static final RGB DEFAULT_BCKGND = new RGB( | |
CustomizedLabelProvider.RGB_MAX, CustomizedLabelProvider.RGB_MAX, | |
CustomizedLabelProvider.RGB_MAX); | |
private static final RGB DEFAULT_FOREGND = new RGB(0, 0, 0); | |
private final ICustomizationManager customManager; | |
private final PropertiesHandler propertiesHandler; | |
private final List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>(); | |
private final ImageManager imageManager; | |
private final ICustomOverride customOverride; | |
@Deprecated | |
public CustomizedLabelProvider(final ResourceSet resourceSet) { | |
this(ICustomizationManagerFactory.DEFAULT | |
.getOrCreateICustomizationManager(resourceSet)); | |
} | |
public CustomizedLabelProvider(final ICustomizationManager customManager) { | |
super(); | |
this.customManager = customManager; | |
this.propertiesHandler = new PropertiesHandler(customManager); | |
this.imageManager = new ImageManager(); | |
this.customOverride = getICustomOverride(); | |
} | |
private <T> T getPropertyValue(final Object element, | |
final FacetOperation property, final ETypedElement eTypedElement, final Class<T> classs) { | |
return CustomizationUtils.getPropertyValue(this.customManager, element, | |
property, eTypedElement, classs); | |
} | |
public String getText(final Object element) { | |
String result; | |
if (element instanceof EObject) { | |
result = getPropertyValue(element, | |
this.propertiesHandler.getLabelProperty(), null, String.class); | |
} else if (element == null) { | |
result = Messages.CustomizedLabelProvider_null; | |
} else if (element instanceof List<?>) { | |
// Here we do not add any square brackets because the square | |
// brackets are useful to emphases the sublists and here we will non | |
// meet any sublists. | |
final StringBuffer strBuffer = new StringBuffer(); | |
final List<?> list = (List<?>) element; | |
final Iterator<?> iter = list.iterator(); | |
while (iter.hasNext()) { | |
final Object current = iter.next(); | |
strBuffer.append(getText(current)); | |
if (iter.hasNext()) { | |
strBuffer.append(", "); //$NON-NLS-1$ | |
} | |
} | |
result = strBuffer.toString(); | |
} else { | |
result = element.toString(); | |
} | |
if (this.customOverride != null) { | |
try { | |
result = this.customOverride.getText(result, element, | |
this.customManager, this.propertiesHandler); | |
} catch (final CustomizationException e) { | |
result = "ERROR, cf. log"; //$NON-NLS-1$ | |
Logger.logError(e, Activator.getDefault()); | |
} | |
} | |
return result; | |
} | |
private static ICustomOverride getICustomOverride() { | |
final Bundle bundle = Activator.getDefault().getBundle(); | |
final BundleContext bundleContext = bundle.getBundleContext(); | |
final ServiceReference serviceReference = bundleContext | |
.getServiceReference(ICustomOverride.class.getName()); | |
final ICustomOverride customOverride = (ICustomOverride) bundleContext | |
.getService(serviceReference); | |
return customOverride; | |
} | |
public String getText(final Object object, final ETypedElement eTypedElement) { | |
String result; | |
if (object == null) { | |
result = Messages.CustomizedLabelProvider_null; | |
} else { | |
if (object instanceof EObject) { | |
final EObject eObject = (EObject) object; | |
try { | |
result = this.customManager.getCustomValueOf(eObject, | |
eTypedElement, | |
this.propertiesHandler.getLabelProperty(), | |
String.class); | |
} catch (CustomizationException e) { | |
Logger.logError(e, Activator.getDefault()); | |
result = "!!! Error, cf log !!!"; | |
} | |
} else { | |
result = object.toString(); | |
} | |
} | |
return result; | |
//TODO Remove before to commit | |
// if (structuralFeature.getUpperBound() == 1) { | |
// final Object object = this.customManager.getFacetManager().get(eObject, | |
// structuralFeature, Object.class); | |
// result = getText(object); | |
// } else { | |
// final StringBuffer stringBuffer = new StringBuffer(); | |
// final List<Object> objects = this.customManager.getFacetManager() | |
// .getMultiValued(eObject, structuralFeature, Object.class); | |
// final Iterator<Object> objectsIter = objects.iterator(); | |
// while (objectsIter.hasNext()) { | |
// final Object object = objectsIter.next(); | |
// stringBuffer.append(this.getText(object)); | |
// if (objectsIter.hasNext()) { | |
// stringBuffer.append(", "); | |
// } | |
// } | |
// result = stringBuffer.toString(); | |
// } | |
//TODO (end) | |
} | |
@Override | |
public void addListener(final ILabelProviderListener listener) { | |
this.listeners.add(listener); | |
} | |
@Override | |
public void dispose() { | |
this.listeners.clear(); | |
} | |
@Override | |
public boolean isLabelProperty(final Object element, final String property) { | |
return false; | |
} | |
@Override | |
public void removeListener(final ILabelProviderListener listener) { | |
this.listeners.remove(listener); | |
} | |
private static Color getColor(final RGB rgb) { | |
final Display display = Display.getDefault(); | |
final IColorProvider colorProvider = IColorProviderFactory.DEFAULT | |
.getOrCreateIColorProvider(display); | |
return colorProvider.getColor(rgb); | |
} | |
public Color getForeground(final Object element) { | |
final IColor color = getPropertyValue(element, | |
this.propertiesHandler.getForegroundProperty(), | |
null, IColor.class); | |
Color result; | |
if (color == null) { | |
result = getColor(CustomizedLabelProvider.DEFAULT_FOREGND); | |
} else { | |
result = getColor(new RGB(color.getRed(), color.getGreen(), | |
color.getBlue())); | |
} | |
return result; | |
} | |
public Color getBackground(final Object element, | |
final ETypedElement eTypedElement) { | |
final IColor color = getPropertyValue(element, | |
this.propertiesHandler.getBackgroundProperty(), eTypedElement, | |
IColor.class); | |
Color result; | |
if (color == null) { | |
result = getColor(CustomizedLabelProvider.DEFAULT_BCKGND); | |
} else { | |
result = getColor(new RGB(color.getRed(), color.getGreen(), | |
color.getBlue())); | |
} | |
return result; | |
} | |
public Color getBackground(final Object element) { | |
return getBackground(element, null); | |
} | |
private Font getFont(final FontData fontData) { | |
final IFontProvider fontProvider = IFontProviderFactory.DEFAULT | |
.getOrCreateIFontProvider(Display.getDefault()); | |
return fontProvider.getFont(fontData); | |
} | |
public Font getFont(final Object element) { | |
String fontName = getPropertyValue(element, | |
this.propertiesHandler.getFontNameProperty(), null, String.class); | |
if (fontName == null) { | |
final FontData[] fontData = Display.getDefault().getSystemFont() | |
.getFontData(); | |
fontName = fontData[0].getName(); | |
} | |
Integer fontSize = getPropertyValue(element, | |
this.propertiesHandler.getFontSizeProperty(), null, Integer.class); | |
if (fontSize == null) { | |
final FontData[] fontData = Display.getDefault().getSystemFont() | |
.getFontData(); | |
fontSize = Integer.valueOf(fontData[0].getHeight()); | |
} | |
Boolean isBold = getPropertyValue(element, | |
this.propertiesHandler.getIsBoldProperty(), null, Boolean.class); | |
if (isBold == null) { | |
isBold = Boolean.FALSE; | |
} | |
Boolean isItalic = getPropertyValue(element, | |
this.propertiesHandler.getIsItalicProperty(), null, Boolean.class); | |
if (isItalic == null) { | |
isItalic = Boolean.FALSE; | |
} | |
int fontStyle = 0; | |
if (isBold.booleanValue()) { | |
fontStyle = fontStyle | SWT.BOLD; | |
} | |
if (isItalic.booleanValue()) { | |
fontStyle = fontStyle | SWT.ITALIC; | |
} | |
FontData fontData = new FontData(fontName, fontSize.intValue(), | |
fontStyle); | |
try { | |
fontData = this.customOverride.getFont(fontData, element, | |
this.customManager, this.propertiesHandler); | |
} catch (final CustomizationException e) { | |
Logger.logError(e, Activator.getDefault()); | |
} | |
return getFont(fontData); | |
} | |
public Image getImage(final Object element) { | |
final IImage image = getPropertyValue(element, | |
this.propertiesHandler.getImageProperty(), null, IImage.class); | |
return this.imageManager.getImage(image); | |
} | |
public Image getImage(final Object element, final ETypedElement featureColumn) { | |
return getImage(element, this.propertiesHandler.getImageProperty(), featureColumn); | |
} | |
public ICustomizationManager getCustomizationManager() { | |
return this.customManager; | |
} | |
public boolean isUnderlined(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getIsUnderlinedProperty(), null, Boolean.class).booleanValue(); | |
} | |
public boolean isStruckthrough(final Object element, | |
final ETypedElement eTypedElement) { | |
final Boolean propertyValue = getPropertyValue(element, | |
this.propertiesHandler.getIsStruckthroughProperty(), | |
eTypedElement, Boolean.class); | |
boolean result = false; | |
if (propertyValue != null) { | |
result = propertyValue.booleanValue(); | |
} | |
return result; | |
} | |
private Image getImage(final Object element, final FacetOperation operation, final ETypedElement feature) { | |
final IImage iimage = getPropertyValue(element, operation, feature, | |
IImage.class); | |
return this.imageManager.getImage(iimage); | |
} | |
public Image getTopLeftOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getTopLeftOverlayProperty(), eTypedElement); | |
} | |
public Image getTopMiddleOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getTopMiddleOverlayProperty(), eTypedElement); | |
} | |
public Image getTopRightOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getTopRightOverlayProperty(), eTypedElement); | |
} | |
public Image getBottomLeftOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getBottomLeftOverlayProperty(), eTypedElement); | |
} | |
public Image getBottomMiddleOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getBottomMiddleOverlayProperty(), eTypedElement); | |
} | |
public Image getBottomRightOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getImage(element, this.propertiesHandler.getBottomRightOverlayProperty(), eTypedElement); | |
} | |
@Override | |
public String getToolTipText(final Object element) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipTextProperty(), null, String.class); | |
} | |
@Override | |
public int getToolTipStyle(final Object element) { | |
int style = 0; | |
final Shadow shadow = getPropertyValue(element, | |
this.propertiesHandler.getToolTipShadowProperty(), null, | |
Shadow.class); | |
switch (shadow) { | |
case NONE : | |
style = SWT.SHADOW_NONE; | |
break; | |
case IN : | |
style = SWT.SHADOW_IN; | |
break; | |
case OUT: | |
style = SWT.SHADOW_OUT; | |
break; | |
default: | |
throw new IllegalStateException("Un expected value"); //$NON-NLS-1$ | |
} | |
final Alignment alignment = getPropertyValue(element, | |
this.propertiesHandler.getToolTipAlignmentProperty(), null, | |
Alignment.class); | |
switch (alignment) { | |
case LEFT: | |
style |= SWT.LEFT; | |
break; | |
case CENTER: | |
style |= SWT.CENTER; | |
break; | |
case RIGHT: | |
style |= SWT.RIGHT; | |
break; | |
default: | |
throw new IllegalStateException("Un expected value"); //$NON-NLS-1$ | |
} | |
return style; | |
} | |
@Override | |
public Image getToolTipImage(final Object element) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipImageProperty(), null, Image.class); | |
} | |
@Override | |
public Color getToolTipBackgroundColor(final Object element) { | |
final IColor color = getPropertyValue(element, | |
this.propertiesHandler.getToolTipBackgroundProperty(), | |
null, IColor.class); | |
return getColor(new RGB(color.getRed(), color.getGreen(), color.getBlue())); | |
} | |
@Override | |
public Color getToolTipForegroundColor(final Object element) { | |
final IColor color = getPropertyValue(element, | |
this.propertiesHandler.getToolTipForegroundProperty(), | |
null, IColor.class); | |
return getColor(new RGB(color.getRed(), color.getGreen(), color.getBlue())); | |
} | |
public Image getToolTipTopLeftOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipTopLeftOverlayProperty(), | |
null, Image.class); | |
} | |
public Image getToolTipTopMiddleOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipTopMiddleOverlayProperty(), | |
null, Image.class); | |
} | |
public Image getToolTipTopRightOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipTopRightOverlayProperty(), | |
null, Image.class); | |
} | |
public Image getToolTipBottomLeftOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipBottomLeftOverlayProperty(), | |
null, Image.class); | |
} | |
public Image getToolTipBottomMiddleOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipBottomMiddleOverlayProperty(), | |
null, Image.class); | |
} | |
public Image getToolTipBottomRightOverlay(final Object element, | |
final ETypedElement eTypedElement) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipBottomRightOverlayProperty(), | |
null, Image.class); | |
} | |
@Override | |
public int getToolTipDisplayDelayTime(final Object element) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipDisplayDelayTimeProperty(), | |
null, Integer.class).intValue(); | |
} | |
@Override | |
public int getToolTipTimeDisplayed(final Object element) { | |
return getPropertyValue(element, | |
this.propertiesHandler.getToolTipTimeDisplayedProperty(), null, | |
Integer.class).intValue(); | |
} | |
@Override | |
public Font getToolTipFont(final Object element) { | |
final String fontName = getPropertyValue(element, | |
this.propertiesHandler.getToolTipFontNameProperty(), null, | |
String.class); | |
final Integer fontSize = getPropertyValue(element, | |
this.propertiesHandler.getToolTipFontSizeProperty(), null, | |
Integer.class); | |
final Boolean isBold = getPropertyValue(element, | |
this.propertiesHandler.getToolTipIsBoldProperty(), null, | |
Boolean.class); | |
final Boolean isItalic = getPropertyValue(element, | |
this.propertiesHandler.getToolTipIsItalicProperty(), null, | |
Boolean.class); | |
int fontStyle = 0; | |
if (isBold.booleanValue()) { | |
fontStyle = fontStyle | SWT.BOLD; | |
} | |
if (isItalic.booleanValue()) { | |
fontStyle = fontStyle | SWT.ITALIC; | |
} | |
final FontData fontData = new FontData(fontName, fontSize.intValue(), | |
fontStyle); | |
final IFontProvider fontProvider = IFontProviderFactory.DEFAULT | |
.getOrCreateIFontProvider(Display.getDefault()); | |
return fontProvider.getFont(fontData); | |
} | |
@Override | |
public void update(final ViewerCell cell) { | |
final Object element = cell.getElement(); | |
cell.setText(getText(element)); | |
cell.setBackground(getBackground(element)); | |
cell.setFont(getFont(element)); | |
cell.setForeground(getForeground(element)); | |
cell.setImage(getImage(element)); | |
} | |
public String getToolTipText(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
public Image getToolTipImage(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
public Font getToolTipFont(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
public Color getToolTipBackgroundColor(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
public Color getToolTipForegroundColor(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
public int getToolTipTimeDisplayed(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return 0; | |
} | |
public int getToolTipDisplayDelayTime(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return 0; | |
} | |
public int getToolTipStyle(final Object element, | |
final ETypedElement eTypedElement) { | |
// TODO Auto-generated method stub | |
return 0; | |
} | |
public ICustomizedLabelProvider cloneLabelProvider() { | |
return new CustomizedLabelProvider(this.customManager); | |
} | |
public StyledString getStyledText(final Object element) { | |
return new StyledString(getText(element)); | |
} | |
} |