blob: c5d4d2b295ec7b70b40c315096a9eb1ef63243a8 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ltk.ui.util;
import java.util.IdentityHashMap;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.graphics.Image;
import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ltk.model.core.LtkModels;
import org.eclipse.statet.ltk.model.core.element.EmbeddingForeignElement;
import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
import org.eclipse.statet.ltk.ui.ElementLabelProvider;
@NonNullByDefault
public class ExtModelLabelProvider extends StyledCellLabelProvider
implements ILabelProvider, ElementLabelProvider, Disposable {
protected static final ElementLabelProvider NO_PROVIDER= new ElementLabelProvider() {
};
private final IdentityHashMap<String, ElementLabelProvider> providers= new IdentityHashMap<>(4);
private @Nullable String modelTypeId;
public ExtModelLabelProvider(final String modelTypeId) {
this.modelTypeId= modelTypeId;
}
public ExtModelLabelProvider() {
}
@Override
public void dispose() {
for (final var provider : this.providers.values()) {
if (provider instanceof Disposable) {
((Disposable)provider).dispose();
}
}
this.providers.clear();
super.dispose();
}
protected @Nullable ElementLabelProvider getElementLabelProvider(final @Nullable String modelId) {
if (modelId == null) {
return null;
}
var provider= this.providers.get(modelId);
if (provider == null) {
provider= LtkModels.getModelAdapter(modelId, ElementLabelProvider.class);
if (provider == null) {
provider= NO_PROVIDER;
}
this.providers.put(modelId, provider);
}
return (provider != NO_PROVIDER) ? provider : null;
}
protected void addProvider(final String modelId, final ElementLabelProvider provider) {
this.providers.put(modelId, provider);
}
@Override
public @Nullable Image getImage(final @Nullable Object element) {
if (element instanceof LtkModelElement) {
return getImage((LtkModelElement<?>)element);
}
return null;
}
@Override
public @Nullable String getText(final @Nullable Object element) {
if (element instanceof LtkModelElement) {
return getText((LtkModelElement<?>)element);
}
return null;
}
@Override
public @Nullable Image getImage(final LtkModelElement<?> element) {
final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
Image image= null;
ElementLabelProvider provider;
if (image == null && embedding && this.modelTypeId != element.getModelTypeId()
&& (provider= getElementLabelProvider(this.modelTypeId)) != null) {
image= provider.getImage(element);
}
if (image == null
&& (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
image= provider.getImage(element);
}
if (image == null && embedding) {
final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
if (embeddedElement != null
&& (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
image= provider.getImage(embeddedElement);
}
}
return image;
}
@Override
public String getText(final LtkModelElement<?> element) {
final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
String text= null;
ElementLabelProvider provider;
if (text == null && embedding && this.modelTypeId != element.getModelTypeId()
&& (provider= getElementLabelProvider(this.modelTypeId)) != null) {
text= provider.getText(element);
}
if (text == null
&& (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
text= provider.getText(element);
}
if (text == null && embedding) {
final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
if (embeddedElement != null
&& (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
text= provider.getText(embeddedElement);
}
}
if (text == null) {
text= element.getElementName().getDisplayName();
}
return text;
}
@Override
public StyledString getStyledText(final LtkModelElement<?> element) {
final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
StyledString text= null;
ElementLabelProvider provider;
if (text == null && embedding && this.modelTypeId != element.getModelTypeId()
&& (provider= getElementLabelProvider(this.modelTypeId)) != null) {
text= provider.getStyledText(element);
}
if (text == null
&& (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
text= provider.getStyledText(element);
}
if (text == null && embedding) {
final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
if (embeddedElement != null
&& (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
text= provider.getStyledText(embeddedElement);
}
}
if (text == null) {
text= new StyledString(element.getElementName().getDisplayName());
}
return text;
}
@Override
public void update(final ViewerCell cell) {
final Object cellElement= cell.getElement();
if (cellElement instanceof LtkModelElement) {
final var element= (LtkModelElement<?>)cellElement;
cell.setImage(getImage(element));
final StyledString styledText= getStyledText(element);
cell.setText(styledText.getString());
cell.setStyleRanges(styledText.getStyleRanges());
}
else {
cell.setImage(null);
cell.setText(cellElement.toString());
cell.setStyleRanges(null);
}
super.update(cell);
}
}