Mercurial > projects > dwt-addons
view dwtx/jface/preference/PreferencePage.d @ 43:ea8ff534f622
Fix override and super aliases
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Apr 2008 01:24:25 +0200 |
parents | b3c8e32d406f |
children | 46a6e0e6ccd4 |
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 * Sebastian Davids <sdavids@gmx.de> - Fix for bug 38729 - [Preferences] * NPE PreferencePage isValid. * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.jface.preference.PreferencePage; import dwtx.jface.preference.IPreferencePage; import dwtx.jface.preference.IPreferenceStore; import dwtx.jface.preference.IPreferencePageContainer; import dwt.DWT; import dwt.events.DisposeEvent; import dwt.events.DisposeListener; import dwt.events.SelectionAdapter; import dwt.events.SelectionEvent; import dwt.graphics.Font; import dwt.graphics.Point; import dwt.layout.GridData; import dwt.layout.GridLayout; import dwt.widgets.Button; import dwt.widgets.Composite; import dwt.widgets.Control; import dwt.widgets.Event; import dwt.widgets.Label; import dwtx.jface.dialogs.Dialog; import dwtx.jface.dialogs.DialogPage; import dwtx.jface.dialogs.IDialogConstants; import dwtx.jface.resource.ImageDescriptor; import dwtx.jface.resource.JFaceResources; import dwtx.jface.util.IPropertyChangeListener; import dwtx.jface.util.PropertyChangeEvent; import dwt.dwthelper.utils; /** * Abstract base implementation for all preference page implementations. * <p> * Subclasses must implement the <code>createControl</code> framework * method to supply the page's main control. * </p> * <p> * Subclasses should extend the <code>doComputeSize</code> framework * method to compute the size of the page's control. * </p> * <p> * Subclasses may override the <code>performOk</code>, <code>performApply</code>, * <code>performDefaults</code>, <code>performCancel</code>, and <code>performHelp</code> * framework methods to react to the standard button events. * </p> * <p> * Subclasses may call the <code>noDefaultAndApplyButton</code> framework * method before the page's control has been created to suppress * the standard Apply and Defaults buttons. * </p> */ public abstract class PreferencePage : DialogPage, IPreferencePage { alias DialogPage.setMessage setMessage; /** * Preference store, or <code>null</code>. */ private IPreferenceStore preferenceStore; /** * Valid state for this page; <code>true</code> by default. * * @see #isValid */ private bool isValid_ = true; /** * Body of page. */ private Control body_; /** * Whether this page has the standard Apply and Defaults buttons; * <code>true</code> by default. * * @see #noDefaultAndApplyButton */ private bool createDefaultAndApplyButton = true; /** * Standard Defaults button, or <code>null</code> if none. * This button has id <code>DEFAULTS_ID</code>. */ private Button defaultsButton = null; /** * The container this preference page belongs to; <code>null</code> * if none. */ private IPreferencePageContainer container = null; /** * Standard Apply button, or <code>null</code> if none. * This button has id <code>APPLY_ID</code>. */ private Button applyButton = null; /** * Description label. * * @see #createDescriptionLabel(Composite) */ private Label descriptionLabel; /** * Caches size of page. */ private Point size = null; /** * Creates a new preference page with an empty title and no image. */ protected this() { this(""); //$NON-NLS-1$ } /** * Creates a new preference page with the given title and no image. * * @param title the title of this preference page */ protected this(String title) { super(title); } /** * Creates a new abstract preference page with the given title and image. * * @param title the title of this preference page * @param image the image for this preference page, * or <code>null</code> if none */ protected this(String title, ImageDescriptor image) { super(title, image); } /** * Computes the size for this page's UI control. * <p> * The default implementation of this <code>IPreferencePage</code> * method returns the size set by <code>setSize</code>; if no size * has been set, but the page has a UI control, the framework * method <code>doComputeSize</code> is called to compute the size. * </p> * * @return the size of the preference page encoded as * <code>new Point(width,height)</code>, or * <code>(0,0)</code> if the page doesn't currently have any UI component */ public Point computeSize() { if (size !is null) { return size; } Control control = getControl(); if (control !is null) { size = doComputeSize(); return size; } return new Point(0, 0); } /** * Contributes additional buttons to the given composite. * <p> * The default implementation of this framework hook method does * nothing. Subclasses should override this method to contribute buttons * to this page's button bar. For each button a subclass contributes, * it must also increase the parent's grid layout number of columns * by one; that is, * <pre> * ((GridLayout) parent.getLayout()).numColumns++); * </pre> * </p> * * @param parent the button bar */ protected void contributeButtons(Composite parent) { } /** * Creates and returns the DWT control for the customized body * of this preference page under the given parent composite. * <p> * This framework method must be implemented by concrete subclasses. Any * subclass returning a <code>Composite</code> object whose <code>Layout</code> * has default margins (for example, a <code>GridLayout</code>) are expected to * set the margins of this <code>Layout</code> to 0 pixels. * </p> * * @param parent the parent composite * @return the new control */ protected abstract Control createContents(Composite parent); /** * The <code>PreferencePage</code> implementation of this * <code>IDialogPage</code> method creates a description label * and button bar for the page. It calls <code>createContents</code> * to create the custom contents of the page. * <p> * If a subclass that overrides this method creates a <code>Composite</code> * that has a layout with default margins (for example, a <code>GridLayout</code>) * it is expected to set the margins of this <code>Layout</code> to 0 pixels. */ public void createControl(Composite parent){ GridData gd; Composite content = new Composite(parent, DWT.NONE); setControl(content); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; content.setLayout(layout); //Apply the font on creation for backward compatibility applyDialogFont(content); // initialize the dialog units initializeDialogUnits(content); descriptionLabel = createDescriptionLabel(content); if (descriptionLabel !is null) { descriptionLabel.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); } body_ = createContents(content); if (body_ !is null) { // null is not a valid return value but support graceful failure body_.setLayoutData(new GridData(GridData.FILL_BOTH)); } Composite buttonBar = new Composite(content, DWT.NONE); layout = new GridLayout(); layout.numColumns = 0; layout.marginHeight = 0; layout.marginWidth = 0; layout.makeColumnsEqualWidth = false; buttonBar.setLayout(layout); gd = new GridData(GridData.HORIZONTAL_ALIGN_END); buttonBar.setLayoutData(gd); contributeButtons(buttonBar); if (createDefaultAndApplyButton) { layout.numColumns = layout.numColumns + 2; String[] labels = JFaceResources.getStrings([ "defaults", "apply"]); //$NON-NLS-2$//$NON-NLS-1$ int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); defaultsButton = new Button(buttonBar, DWT.PUSH); defaultsButton.setText(labels[0]); Dialog.applyDialogFont(defaultsButton); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); Point minButtonSize = defaultsButton.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); data.widthHint = Math.max(widthHint, minButtonSize.x); defaultsButton.setLayoutData(data); defaultsButton.addSelectionListener(new class SelectionAdapter { public void widgetSelected(SelectionEvent e) { performDefaults(); } }); applyButton = new Button(buttonBar, DWT.PUSH); applyButton.setText(labels[1]); Dialog.applyDialogFont(applyButton); data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); minButtonSize = applyButton.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); data.widthHint = Math.max(widthHint, minButtonSize.x); applyButton.setLayoutData(data); applyButton.addSelectionListener(new class SelectionAdapter { public void widgetSelected(SelectionEvent e) { performApply(); } }); applyButton.setEnabled(isValid()); applyDialogFont(buttonBar); } else { /* Check if there are any other buttons on the button bar. * If not, throw away the button bar composite. Otherwise * there is an unusually large button bar. */ if (buttonBar.getChildren().length < 1) { buttonBar.dispose(); } } } /** * Apply the dialog font to the composite and it's children * if it is set. Subclasses may override if they wish to * set the font themselves. * @param composite */ protected void applyDialogFont(Composite composite) { Dialog.applyDialogFont(composite); } /** * Creates and returns an DWT label under the given composite. * * @param parent the parent composite * @return the new label */ protected Label createDescriptionLabel(Composite parent) { Label result = null; String description = getDescription(); if (description !is null) { result = new Label(parent, DWT.WRAP); result.setFont(parent.getFont()); result.setText(description); } return result; } /** * Computes the size needed by this page's UI control. * <p> * All pages should override this method and set the appropriate sizes * of their widgets, and then call <code>super.doComputeSize</code>. * </p> * * @return the size of the preference page encoded as * <code>new Point(width,height)</code> */ protected Point doComputeSize() { if (descriptionLabel !is null && body_ !is null) { Point bodySize = body_.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); GridData gd = cast(GridData) descriptionLabel.getLayoutData(); gd.widthHint = bodySize.x; } return getControl().computeSize(DWT.DEFAULT, DWT.DEFAULT, true); } /** * Returns the preference store of this preference page. * <p> * This is a framework hook method for subclasses to return a * page-specific preference store. The default implementation * returns <code>null</code>. * </p> * * @return the preference store, or <code>null</code> if none */ protected IPreferenceStore doGetPreferenceStore() { return null; } /** * Returns the container of this page. * * @return the preference page container, or <code>null</code> if this * page has yet to be added to a container */ public IPreferencePageContainer getContainer() { return container; } /** * Returns the preference store of this preference page. * * @return the preference store , or <code>null</code> if none */ public IPreferenceStore getPreferenceStore() { if (preferenceStore is null) { preferenceStore = doGetPreferenceStore(); } if (preferenceStore !is null) { return preferenceStore; } else if (container !is null) { return container.getPreferenceStore(); } return null; } /** * The preference page implementation of an <code>IPreferencePage</code> * method returns whether this preference page is valid. Preference * pages are considered valid by default; call <code>setValid(false)</code> * to make a page invalid. */ public bool isValid() { return isValid_; } /** * Suppresses creation of the standard Default and Apply buttons * for this page. * <p> * Subclasses wishing a preference page wihthout these buttons * should call this framework method before the page's control * has been created. * </p> */ protected void noDefaultAndApplyButton() { createDefaultAndApplyButton = false; } /** * The <code>PreferencePage</code> implementation of this * <code>IPreferencePage</code> method returns <code>true</code> * if the page is valid. */ public bool okToLeave() { return isValid(); } /** * Performs special processing when this page's Apply button has been pressed. * <p> * This is a framework hook method for sublcasses to do special things when * the Apply button has been pressed. * The default implementation of this framework method simply calls * <code>performOk</code> to simulate the pressing of the page's OK button. * </p> * * @see #performOk */ protected void performApply() { performOk(); } /** * The preference page implementation of an <code>IPreferencePage</code> * method performs special processing when this page's Cancel button has * been pressed. * <p> * This is a framework hook method for sublcasses to do special things when * the Cancel button has been pressed. The default implementation of this * framework method does nothing and returns <code>true</code>. */ public bool performCancel() { return true; } /** * Performs special processing when this page's Defaults button has been pressed. * <p> * This is a framework hook method for subclasses to do special things when * the Defaults button has been pressed. * Subclasses may override, but should call <code>super.performDefaults</code>. * </p> */ protected void performDefaults() { updateApplyButton(); } /** * Method declared on IPreferencePage. * Subclasses should override */ public bool performOk() { return true; } /** (non-Javadoc) * Method declared on IPreferencePage. */ public void setContainer(IPreferencePageContainer container) { this.container = container; } /** * Sets the preference store for this preference page. * <p> * If preferenceStore is set to null, getPreferenceStore * will invoke doGetPreferenceStore the next time it is called. * </p> * * @param store the preference store, or <code>null</code> * @see #getPreferenceStore */ public void setPreferenceStore(IPreferenceStore store) { preferenceStore = store; } /* (non-Javadoc) * Method declared on IPreferencePage. */ public void setSize(Point uiSize) { Control control = getControl(); if (control !is null) { control.setSize(uiSize); size = uiSize; } } /** * The <code>PreferencePage</code> implementation of this <code>IDialogPage</code> * method extends the <code>DialogPage</code> implementation to update * the preference page container title. Subclasses may extend. */ public override void setTitle(String title) { super.setTitle(title); if (getContainer() !is null) { getContainer().updateTitle(); } } /** * Sets whether this page is valid. * The enable state of the container buttons and the * apply button is updated when a page's valid state * changes. * <p> * * @param b the new valid state */ public void setValid(bool b) { bool oldValue = isValid_; isValid_ = b; if (oldValue !is isValid_) { // update container state if (getContainer() !is null) { getContainer().updateButtons(); } // update page state updateApplyButton(); } } /** * Returns a string suitable for debugging purpose only. */ public override String toString() { return getTitle(); } /** * Updates the enabled state of the Apply button to reflect whether * this page is valid. */ protected void updateApplyButton() { if (applyButton !is null) { applyButton.setEnabled(isValid()); } } /** * Creates a composite with a highlighted Note entry and a message text. * This is designed to take up the full width of the page. * * @param font the font to use * @param composite the parent composite * @param title the title of the note * @param message the message for the note * @return the composite for the note */ protected Composite createNoteComposite(Font font, Composite composite, String title, String message) { Composite messageComposite = new Composite(composite, DWT.NONE); GridLayout messageLayout = new GridLayout(); messageLayout.numColumns = 2; messageLayout.marginWidth = 0; messageLayout.marginHeight = 0; messageComposite.setLayout(messageLayout); messageComposite.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); messageComposite.setFont(font); final Label noteLabel = new Label(messageComposite, DWT.BOLD); noteLabel.setText(title); noteLabel.setFont(JFaceResources.getFontRegistry().getBold( JFaceResources.DEFAULT_FONT)); noteLabel .setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); final IPropertyChangeListener fontListener = new class IPropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { if (JFaceResources.BANNER_FONT.equals(event.getProperty())) { noteLabel.setFont(JFaceResources .getFont(JFaceResources.BANNER_FONT)); } } }; JFaceResources.getFontRegistry().addListener(fontListener); noteLabel.addDisposeListener(new class DisposeListener { public void widgetDisposed(DisposeEvent event) { JFaceResources.getFontRegistry().removeListener(fontListener); } }); Label messageLabel = new Label(messageComposite, DWT.WRAP); messageLabel.setText(message); messageLabel.setFont(font); return messageComposite; } /** * Returns the Apply button. * * @return the Apply button */ protected Button getApplyButton() { return applyButton; } /** * Returns the Restore Defaults button. * * @return the Restore Defaults button */ protected Button getDefaultsButton() { return defaultsButton; } /* (non-Javadoc) * @see dwtx.jface.dialogs.IDialogPage#performHelp() */ public override void performHelp() { getControl().notifyListeners(DWT.Help, new Event()); } /** * Apply the data to the receiver. By default do nothing. * @param data * @since 3.1 */ public void applyData(Object data) { } /* (non-Javadoc) * @see dwtx.jface.dialogs.DialogPage#setErrorMessage(java.lang.String) */ public override void setErrorMessage(String newMessage) { super.setErrorMessage(newMessage); if (getContainer() !is null) { getContainer().updateMessage(); } } /* (non-Javadoc) * @see dwtx.jface.dialogs.DialogPage#setMessage(java.lang.String, int) */ public override void setMessage(String newMessage, int newType) { super.setMessage(newMessage, newType); if (getContainer() !is null) { getContainer().updateMessage(); } } }