/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * 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: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.ui.ridgets.swt; import java.net.URL; import org.eclipse.core.databinding.beans.BeansObservables; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Control; import org.eclipse.riena.ui.core.resource.IIconManager; import org.eclipse.riena.ui.core.resource.IconManagerProvider; import org.eclipse.riena.ui.core.resource.IconSize; import org.eclipse.riena.ui.ridgets.AbstractMarkerSupport; import org.eclipse.riena.ui.ridgets.ILabelRidget; /** * Superclass of LabelRidget that does not depend on the Label SWT control. May be reused for custom Label controls. */ public abstract class AbstractLabelRidget extends AbstractValueRidget implements ILabelRidget { /** * This property is used by the databinding to sync ridget and model. It is always fired before its sibling {@link ILabelRidget#PROPERTY_TEXT} to ensure * that the model is updated before any listeners try accessing it. * <p> * This property is not API. Do not use in client code. */ private static final String PROPERTY_TEXT_INTERNAL = "textInternal"; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private String text; private String iconID; private IconSize iconSize; private URL iconLocation; private boolean textAlreadyInitialized; private boolean useRidgetIcon; public AbstractLabelRidget() { textAlreadyInitialized = false; useRidgetIcon = false; } @Override protected AbstractMarkerSupport createMarkerSupport() { return new BasicMarkerSupport(this, propertyChangeSupport); } @Override protected IObservableValue getRidgetObservable() { return BeansObservables.observeValue(this, PROPERTY_TEXT_INTERNAL); } @Override protected void bindUIControl() { initText(); updateUIText(); updateUIIcon(); } /** * If the text of the ridget has no value, initialize it with the text of the UI control. */ private void initText() { if (text == null && !textAlreadyInitialized) { final Control control = getUIControl(); if (control != null && !control.isDisposed()) { text = getUIControlText(); if (text == null) { text = EMPTY_STRING; } textAlreadyInitialized = true; } } } /** * {@inheritDoc} * <p> * The <i>full</i> name of the icon is returned, also called icon ID. The icon ID (can) contains the name, the size and the state. */ public String getIcon() { return iconID; } public URL getIconLocation() { return iconLocation; } public String getText() { return text; } /** * This method is not API. Do not use in client code. * * @noreference This method is not intended to be referenced by clients. */ public final String getTextInternal() { return getText(); } /** * Always returns true because mandatory markers do not make sense for this ridget. */ @Override public boolean isDisableMandatoryMarker() { return true; } /** * {@inheritDoc} * <p> * <i>Also sets the size {@code IconSize.NONE} for the icon.</i> * * @see #setIcon(String,IconSize) */ public void setIcon(final String icon) { setIcon(icon, IconSize.NONE); } /** * {@inheritDoc} * <p> * The name and the size of the icon will be managed by an implementation of {@code IIconManager}. * * @since 2.0 */ public void setIcon(final String icon, final IconSize size) { final boolean oldUseRidgetIcon = useRidgetIcon; useRidgetIcon = true; final String oldIcon = this.iconID; final IIconManager manager = IconManagerProvider.getInstance().getIconManager(); this.iconID = manager.getIconID(icon, size); this.iconSize = size; if (hasChanged(oldIcon, icon) || !oldUseRidgetIcon) { updateUIIcon(); } } public void setIconLocation(final URL location) { useRidgetIcon = true; final URL oldUrl = this.iconLocation; this.iconLocation = location; if (hasChanged(oldUrl, location)) { updateUIIcon(); } } public void setText(final String text) { final String oldValue = this.text; this.text = text; updateUIText(); firePropertyChange(PROPERTY_TEXT_INTERNAL, oldValue, this.text); firePropertyChange(ILabelRidget.PROPERTY_TEXT, oldValue, this.text); } /** * This method is not API. Do not use in client code. * * @noreference This method is not intended to be referenced by clients. */ public final void setTextInternal(final String text) { setText(text); } // helping methods // //////////////// /** * @return The controls text. */ protected abstract String getUIControlText(); private void updateUIText() { if (getUIControl() != null) { setUIControlText(text); } } /** * Sets the controls text. */ protected abstract void setUIControlText(String text); private void updateUIIcon() { if (getUIControl() != null) { Image image = null; if (getIcon() != null) { image = getManagedImage(getIcon(), iconSize); } else if (iconLocation != null) { final String key = iconLocation.toExternalForm(); image = getManagedImage(key); } if ((image != null) || useRidgetIcon) { setUIControlImage(image); } } } /** * Sets the controls image. */ protected abstract void setUIControlImage(Image image); private boolean hasChanged(final URL oldValue, final URL newValue) { if (oldValue == null && newValue == null) { return false; } if (oldValue == null || newValue == null) { return true; } // avoid URL.equals(...) since it opens a network connection :( final String str1 = oldValue.toExternalForm(); final String str2 = newValue.toExternalForm(); return !str1.equals(str2); } }