Mercurial > projects > dwt-addons
view dwtx/jface/viewers/ContentViewer.d @ 43:ea8ff534f622
Fix override and super aliases
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Apr 2008 01:24:25 +0200 |
parents | da5ad8eedf5d |
children | 28f6c339768e |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2006 IBM Corporation 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: * IBM Corporation - initial API and implementation * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.jface.viewers.ContentViewer; import dwtx.jface.viewers.IBaseLabelProvider; import dwtx.jface.viewers.Viewer; import dwtx.jface.viewers.ILabelProviderListener; import dwtx.jface.viewers.IContentProvider; import dwtx.jface.viewers.LabelProviderChangedEvent; import dwtx.jface.viewers.LabelProvider; import dwt.events.DisposeEvent; import dwt.events.DisposeListener; import dwt.widgets.Control; import dwtx.core.runtime.Assert; import dwt.dwthelper.utils; import tango.util.log.Trace; /** * A content viewer is a model-based adapter on a widget which accesses its * model by means of a content provider and a label provider. * <p> * A viewer's model consists of elements, represented by objects. * A viewer defines and implements generic infrastructure for handling model * input, updates, and selections in terms of elements. * Input is obtained by querying an <code>IContentProvider</code> which returns * elements. The elements themselves are not displayed directly. They are * mapped to labels, containing text and/or an image, using the viewer's * <code>ILabelProvider</code>. * </p> * <p> * Implementing a concrete content viewer typically involves the following steps: * <ul> * <li> * create DWT controls for viewer (in constructor) (optional) * </li> * <li> * initialize DWT controls from input (inputChanged) * </li> * <li> * define viewer-specific update methods * </li> * <li> * support selections (<code>setSelection</code>, <code>getSelection</code>) * </ul> * </p> */ public abstract class ContentViewer : Viewer { /** * This viewer's content provider, or <code>null</code> if none. */ private IContentProvider contentProvider = null; /** * This viewer's input, or <code>null</code> if none. * The viewer's input provides the "model" for the viewer's content. */ private Object input = null; /** * This viewer's label provider. Initially <code>null</code>, but * lazily initialized (to a <code>SimpleLabelProvider</code>). */ private IBaseLabelProvider labelProvider = null; /** * This viewer's label provider listener. * Note: Having a viewer register a label provider listener with * a label provider avoids having to define public methods * for internal events. */ private const ILabelProviderListener labelProviderListener; /** * Creates a content viewer with no input, no content provider, and a * default label provider. */ protected this() { labelProviderListener = new class ILabelProviderListener { public void labelProviderChanged(LabelProviderChangedEvent event) { this.outer.handleLabelProviderChanged(event); } }; } /** * Returns the content provider used by this viewer, * or <code>null</code> if this view does not yet have a content * provider. * <p> * The <code>ContentViewer</code> implementation of this method returns the content * provider recorded is an internal state variable. * Overriding this method is generally not required; * however, if overriding in a subclass, * <code>super.getContentProvider</code> must be invoked. * </p> * * @return the content provider, or <code>null</code> if none */ public IContentProvider getContentProvider() { return contentProvider; } /** * The <code>ContentViewer</code> implementation of this <code>IInputProvider</code> * method returns the current input of this viewer, or <code>null</code> * if none. The viewer's input provides the "model" for the viewer's * content. */ public override Object getInput() { return input; } /** * Returns the label provider used by this viewer. * <p> * The <code>ContentViewer</code> implementation of this method returns the label * provider recorded in an internal state variable; if none has been * set (with <code>setLabelProvider</code>) a <code>SimpleLabelProvider</code> * will be created, remembered, and returned. * Overriding this method is generally not required; * however, if overriding in a subclass, * <code>super.getLabelProvider</code> must be invoked. * </p> * * @return a label provider */ public IBaseLabelProvider getLabelProvider() { Trace.formatln( "{} {}:", __FILE__, __LINE__ ); if (labelProvider is null) { Trace.formatln( "{} {}:", __FILE__, __LINE__ ); labelProvider = new LabelProvider(); } PrintStackTrace(); return labelProvider; } /** * Handles a dispose event on this viewer's control. * <p> * The <code>ContentViewer</code> implementation of this method disposes of this * viewer's label provider and content provider (if it has one). * Subclasses should override this method to perform any additional * cleanup of resources; however, overriding methods must invoke * <code>super.handleDispose</code>. * </p> * * @param event a dispose event */ protected void handleDispose(DisposeEvent event) { if (contentProvider !is null) { contentProvider.inputChanged(this, getInput(), null); contentProvider.dispose(); contentProvider = null; } if (labelProvider !is null) { labelProvider.removeListener(labelProviderListener); labelProvider.dispose(); labelProvider = null; Trace.formatln( "{} {}: labelProvider = null;", __FILE__, __LINE__ ); } input = null; } /** * Handles a label provider changed event. * <p> * The <code>ContentViewer</code> implementation of this method calls <code>labelProviderChanged()</code> * to cause a complete refresh of the viewer. * Subclasses may reimplement or extend. * </p> * @param event the change event */ protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { labelProviderChanged(); } /** * Adds event listener hooks to the given control. * <p> * All subclasses must call this method when their control is * first established. * </p> * <p> * The <code>ContentViewer</code> implementation of this method hooks * dispose events for the given control. * Subclasses may override if they need to add other control hooks; * however, <code>super.hookControl</code> must be invoked. * </p> * * @param control the control */ protected void hookControl(Control control) { control.addDisposeListener(new class DisposeListener { public void widgetDisposed(DisposeEvent event) { handleDispose(event); } }); } /** * Notifies that the label provider has changed. * <p> * The <code>ContentViewer</code> implementation of this method calls <code>refresh()</code>. * Subclasses may reimplement or extend. * </p> */ protected void labelProviderChanged() { refresh(); } /** * Sets the content provider used by this viewer. * <p> * The <code>ContentViewer</code> implementation of this method records the * content provider in an internal state variable. * Overriding this method is generally not required; * however, if overriding in a subclass, * <code>super.setContentProvider</code> must be invoked. * </p> * * @param contentProvider the content provider * @see #getContentProvider */ public void setContentProvider(IContentProvider contentProvider) { Assert.isNotNull(cast(Object)contentProvider); IContentProvider oldContentProvider = this.contentProvider; this.contentProvider = contentProvider; if (oldContentProvider !is null) { Object currentInput = getInput(); oldContentProvider.inputChanged(this, currentInput, null); oldContentProvider.dispose(); contentProvider.inputChanged(this, null, currentInput); refresh(); } } /** * The <code>ContentViewer</code> implementation of this <code>Viewer</code> * method invokes <code>inputChanged</code> on the content provider and then the * <code>inputChanged</code> hook method. This method fails if this viewer does * not have a content provider. Subclassers are advised to override * <code>inputChanged</code> rather than this method, but may extend this method * if required. */ public override void setInput(Object input) { Assert .isTrue(getContentProvider() !is null, "ContentViewer must have a content provider when input is set."); //$NON-NLS-1$ Object oldInput = getInput(); contentProvider.inputChanged(this, oldInput, input); this.input = input; // call input hook inputChanged(this.input, oldInput); } /** * Sets the label provider for this viewer. * <p> * The <code>ContentViewer</code> implementation of this method ensures that the * given label provider is connected to this viewer and the * former label provider is disconnected from this viewer. * Overriding this method is generally not required; * however, if overriding in a subclass, * <code>super.setLabelProvider</code> must be invoked. * </p> * * @param labelProvider the label provider, or <code>null</code> if none */ public void setLabelProvider(IBaseLabelProvider labelProvider) { Trace.formatln( "{} {}: setLabelProvider", __FILE__, __LINE__ ); IBaseLabelProvider oldProvider = this.labelProvider; // If it hasn't changed, do nothing. // This also ensures that the provider is not disposed // if set a second time. if (labelProvider is oldProvider) { return; } if (oldProvider !is null) { oldProvider.removeListener(this.labelProviderListener); } this.labelProvider = labelProvider; if (labelProvider !is null) { labelProvider.addListener(this.labelProviderListener); } refresh(); // Dispose old provider after refresh, so that items never refer to stale images. if (oldProvider !is null) { oldProvider.dispose(); } Trace.formatln( "{} {}: setLabelProvider", __FILE__, __LINE__ ); } }