From 928076556c8a4b0f331df02b59db9f63d2c13bd5 Mon Sep 17 00:00:00 2001 From: Chris Recoskie Date: Wed, 9 Mar 2011 22:28:20 +0000 Subject: [PATCH] Bug 320949 - Add ability to contribute custom field-editor GUI to the Build Option Settings page --- .../schema/buildDefinitions.exsd | 19 +++ .../cdt/managedbuilder/core/IOption.java | 26 ++++ .../managedbuilder/internal/core/Option.java | 55 ++++++++ .../internal/core/OptionReference.java | 20 +++ .../plugin.properties | 1 + .../plugin.xml | 1 + .../schema/buildDefinitionsUI.exsd | 127 ++++++++++++++++++ .../ui/properties/BuildOptionSettingsUI.java | 120 ++++++++++++++++- .../properties/ICustomBuildOptionEditor.java | 54 ++++++++ 9 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 build/org.eclipse.cdt.managedbuilder.ui/schema/buildDefinitionsUI.exsd create mode 100644 build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ICustomBuildOptionEditor.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd index d007f51e9bd..f10e4a4279e 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd +++ b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd @@ -1115,6 +1115,25 @@ Overrides language id specified with the languageId attribute. + + + + Optional ID of the custom field-editor to represent this build-option in the project Properties dialog UI. If no custom field-editor ID is specified then the option will be represented by one of the built-in field-editors based on the option's <code>valueType</code> attribute. + +A custom field-editor needs to be registered, under the same ID, through the <code>org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI</code> extension-point's <code>&lt;fieldEditor&gt;</code> element. + + + + + + + + + + An optional extra text string that is passed into the field-editor. Can be used to parameterize the field-editor instance. + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java index 49e60826091..2196fd19fe8 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java @@ -119,6 +119,11 @@ public interface IOption extends IBuildObject { public static final String VALUE_TYPE = "valueType"; //$NON-NLS-1$ public static final String VALUE_HANDLER = "valueHandler"; //$NON-NLS-1$ public static final String VALUE_HANDLER_EXTRA_ARGUMENT = "valueHandlerExtraArgument"; //$NON-NLS-1$ + + /** @since 8.0 */ + public static final String FIELD_EDITOR_ID = "fieldEditor"; //$NON-NLS-1$ + /** @since 8.0 */ + public static final String FIELD_EDITOR_EXTRA_ARGUMENT = "fieldEditorExtraArgument"; //$NON-NLS-1$ // Schema attribute names for listOptionValue elements public static final String LIST_ITEM_VALUE = "value"; //$NON-NLS-1$ @@ -463,6 +468,27 @@ public interface IOption extends IBuildObject { */ public void setValueHandlerExtraArgument(String extraArgument); + /** + * @return the custom field-editor ID for this build-option. This ID should match a custom-field editor + * contributed through the {@code } element of the + * {@code org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI} extension-point. + * @since 8.0 + */ + public String getFieldEditorId(); + + /** + * @return an optional extra argument for the {@link #getFieldEditorId() field-editor}. + * @since 8.0 + */ + public String getFieldEditorExtraArgument(); + + /** + * Sets the optional extra argument for the field-editor. + * @param extraArgument free-form extra argument to be interpreted by the {@link #getFieldEditorId() field-editor} + * @since 8.0 + */ + public void setFieldEditorExtraArgument(String extraArgument); + /** * @return true if this option was loaded from a manifest file, * and false if it was loaded from a project (.cdtbuild) file. diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java index 58581915a80..cf81b2b055c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java @@ -81,6 +81,8 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest private IConfigurationElement valueHandlerElement = null; private IManagedOptionValueHandler valueHandler = null; private String valueHandlerExtraArgument; + private String fieldEditorId; + private String fieldEditorExtraArgument; private IConfigurationElement applicabilityCalculatorElement = null; private IOptionApplicability applicabilityCalculator = null; private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; @@ -298,6 +300,13 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest valueHandlerExtraArgument = new String(option.valueHandlerExtraArgument); } + if (option.fieldEditorId != null) { + fieldEditorId = option.fieldEditorId; + } + if (option.fieldEditorExtraArgument != null) { + fieldEditorExtraArgument = new String(option.fieldEditorExtraArgument); + } + if(copyIds){ isDirty = option.isDirty; rebuildState = option.rebuildState; @@ -430,6 +439,10 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } // valueHandlerExtraArgument valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); + + // fieldEditor and optional argument + fieldEditorId = element.getAttribute(FIELD_EDITOR_ID); + fieldEditorExtraArgument = element.getAttribute(FIELD_EDITOR_EXTRA_ARGUMENT); } /* (non-Javadoc) @@ -2076,6 +2089,48 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getFieldEditorId() + */ + public String getFieldEditorId() { + if (fieldEditorId == null) { + if (superClass != null) { + return ((Option)superClass).getFieldEditorId(); + } + } + return fieldEditorId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getFieldEditorExtraArgument() + */ + public String getFieldEditorExtraArgument() { + if (fieldEditorExtraArgument == null) { + if (superClass != null) { + return superClass.getFieldEditorExtraArgument(); + } else { + return null; + } + } + return fieldEditorExtraArgument; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setFieldEditorExtraArgument(java.lang.String) + */ + public void setFieldEditorExtraArgument(String extraArgument) { + if (extraArgument == null && fieldEditorExtraArgument == null) return; + if (extraArgument == null || + fieldEditorExtraArgument == null || + !extraArgument.equals(fieldEditorExtraArgument)) { + fieldEditorExtraArgument = extraArgument; + if(!isExtensionElement()){ + isDirty = true; + rebuildState = true; + } + } + } + /* * O B J E C T S T A T E M A I N T E N A N C E diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java index b53ab702426..5644597483a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java @@ -910,6 +910,26 @@ public class OptionReference implements IOption { public void setValueHandlerExtraArgument(String extraArgument) { } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getFieldEditorId() + */ + public String getFieldEditorId() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getFieldEditorExtraArgument() + */ + public String getFieldEditorExtraArgument() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setFieldEditorExtraArgument(java.lang.String) + */ + public void setFieldEditorExtraArgument(String extraArgument) { + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.IOption#isValid() */ diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties index 8f36122bf02..f511362e8b3 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties @@ -102,4 +102,5 @@ multicfg=Multiple Configurations Edit # menu labels Configurations.menu=Build Configurations +buildDefinitionsUI.ep.name = Build Definitions UI extension-point.name = Custom MBS New Wizard Pages \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml index d586182b82e..91b7a5ce094 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml @@ -2,6 +2,7 @@ + + + + + + + + + This extension point allows for the contribution of various UI extensions which can be referenced from the <code>org.eclipse.cdt.managedbuilder.core.buildDefinitions</code> extensions. Via this extension point, for example, the developer may contribute a custom JFace field-editor, which can then be referenced by its ID from an <code>&lt;option&gt;</code> element of an <code>org.eclipse.cdt.managedbuilder.core.buildDefinitions</code> extension. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This element can be used to contribute a custom JFace field-editor to represent a build-option in the project Properties dialog UI. Contributing a custom field-editor through this element is not enough - the custom field-editor must also be referenced by its ID from an <code>&lt;option&gt;</code> element of an <code>org.eclipse.cdt.managedbuilder.core.buildDefinitions</code> extension. + + + + + + + A unique identifier which will be used to reference this field-editor from an <code>&lt;option&gt;</code> element of an <code>org.eclipse.cdt.managedbuilder.core.buildDefinitions</code> extension. + + + + + + + Specifies the Java class which implements the custom field-editor. This class must extend JFace's <code>FieldEditor</code> abstract class, and implement the <code>ICustomBuildOptionEditor</code> interface. + + + + + + + + + + + + + + + 8.0 + + + + + + + + + <extension point="org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI"> + <fieldEditor + id="org.eclipse.cdt.managedbuilder.ui.tests.fieldEditors.CustomFieldEditor" + class="org.eclipse.cdt.managedbuilder.ui.tests.fieldEditors.CustomFieldEditor"/> +</extension> + + + + + + + + + None + + + + + + + + + None + + + + + + + + + Copyright (c) 2011 Texas Instruments Incorporated 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 on the <a href="http://www.eclipse.org/legal/epl-v10.html"> Eclipse</a> website. + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java index 7e6c9955cc9..215d396cf62 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2010 IBM Corporation and others. + * Copyright (c) 2003, 2011 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 @@ -9,6 +9,7 @@ * IBM Rational Software - Initial API and implementation * ARM Ltd. - basic tooltip support * Miwako Tokugawa (Intel Corporation) - Fixed-location tooltip support + * Baltasar Belyavsky (Texas Instruments) - custom field-editor support *******************************************************************************/ package org.eclipse.cdt.managedbuilder.ui.properties; @@ -38,6 +39,10 @@ import org.eclipse.cdt.managedbuilder.internal.ui.Messages; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.ui.newui.AbstractPage; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.DirectoryFieldEditor; import org.eclipse.jface.preference.FieldEditor; @@ -52,11 +57,14 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; +import org.osgi.framework.Bundle; + /** * Option settings page in project properties Build Settings under Tool Settings tab. @@ -70,6 +78,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { private IHoldsOptions[] ohs; /** The index of the current IHoldsOptions in ohs */ private int curr = -1; + private Map customFieldEditorDescriptorIndex; private Map fieldEditorsToParentMap = new HashMap(); /** True if the user selected "Display tool option tips at a fixed location" in Preferences */ @@ -215,9 +224,35 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { // Figure out which type the option is and add a proper field // editor for it Composite fieldEditorParent = getFieldEditorParent(); - FieldEditor fieldEditor; + FieldEditor fieldEditor = null; - switch (opt.getValueType()) { + String customFieldEditorId = opt.getFieldEditorId(); + if(customFieldEditorId != null) { + fieldEditor = createCustomFieldEditor(customFieldEditorId); + if(fieldEditor != null) { + ICustomBuildOptionEditor customFieldEditor = (ICustomBuildOptionEditor)fieldEditor; + if(customFieldEditor.init(opt, opt.getFieldEditorExtraArgument(), optId, fieldEditorParent)) { + Control[] toolTipSources = customFieldEditor.getToolTipSources(); + if(toolTipSources != null) { + for(Control control : toolTipSources) { + if(pageHasToolTipBox) { + control.setData(new TipInfo(nameStr,tipStr)); + control.addListener(selectAction, tipSetListener); + } + else { + control.setToolTipText(tipStr); + } + } + } + } + else { + fieldEditor = null; + } + } + } + + if(fieldEditor == null) { + switch (opt.getValueType()) { case IOption.STRING: { StringFieldEditor stringField; @@ -378,8 +413,9 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { default: throw new BuildException(null); + } } - + setFieldEditorEnablement(holder, opt, applicabilityCalculator, fieldEditor, fieldEditorParent); addField(fieldEditor); @@ -392,6 +428,82 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { } } + /** + * Instantiates the custom-field editor registered under the given id. + */ + private FieldEditor createCustomFieldEditor(String customFieldEditorId) { + if(this.customFieldEditorDescriptorIndex == null) { + loadCustomFieldEditorDescriptors(); + } + + CustomFieldEditorDescriptor editorDescriptor = this.customFieldEditorDescriptorIndex.get(customFieldEditorId); + if(editorDescriptor != null) { + return editorDescriptor.createEditor(); + } + + return null; + } + + /** + * Holds all the information necessary to instantiate a custom field-editor. + * Also acts as a factory - instantiates and returns a non-initialized field-editor. + */ + private class CustomFieldEditorDescriptor + { + private final String editorClassName; + private final String bundleName; + + CustomFieldEditorDescriptor(String editorClassName, String bundleName) { + this.editorClassName = editorClassName; + this.bundleName = bundleName; + } + + FieldEditor createEditor() { + try { + Bundle bundle = Platform.getBundle(this.bundleName); + if(bundle != null) { + Class editorClass = bundle.loadClass(this.editorClassName); + if(editorClass != null) { + Object editor = editorClass.newInstance(); + if(editor instanceof FieldEditor && editor instanceof ICustomBuildOptionEditor) { + return (FieldEditor)editor; + } + } + } + } + catch(Exception x) { + ManagedBuilderUIPlugin.log(x); + } + + return null; + } + } + + /** + * Loads all the registered custom field-editor descriptors. + * Synchronization is not necessary as this would always be invoked on the UI thread. + */ + private void loadCustomFieldEditorDescriptors() { + if(this.customFieldEditorDescriptorIndex != null) + return; + + this.customFieldEditorDescriptorIndex = new HashMap(); + + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint( + ManagedBuilderUIPlugin.getUniqueIdentifier() + ".buildDefinitionsUI"); //$NON-NLS-1$ + + for(IExtension e : ep.getExtensions()) { + for(IConfigurationElement providerElement : e.getConfigurationElements()) { + String editorId = providerElement.getAttribute("id"); //$NON-NLS-1$ + String editorClassName = providerElement.getAttribute("class"); //$NON-NLS-1$ + + String bundleName = providerElement.getContributor().getName(); + + this.customFieldEditorDescriptorIndex.put(editorId, new CustomFieldEditorDescriptor(editorClassName, bundleName)); + } + } + } + /** * Answers true if the settings page has been created for the * option category specified in the argument. diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ICustomBuildOptionEditor.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ICustomBuildOptionEditor.java new file mode 100644 index 00000000000..af2ce51c5f8 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ICustomBuildOptionEditor.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Texas Instruments, 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: + * Texas Instruments - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.ui.properties; + +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +/** + * This interface can be implemented by clients to contribute custom build-option + * editors to the CDT Build Settings page in the project Properties dialog. + * + * In addition to implementing this interface, the custom build-option editor class + * must also extend the {@link org.eclipse.jface.preference.FieldEditor} class. The + * custom build-option editor class should be contributed through the + * element of the org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI extension-point, + * and then referenced, by its ID, from the