1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 320949 - Add ability to contribute custom field-editor GUI to the Build Option Settings page

This commit is contained in:
Chris Recoskie 2011-03-09 22:28:20 +00:00
parent 35bb3c2833
commit 928076556c
9 changed files with 419 additions and 4 deletions

View file

@ -1115,6 +1115,25 @@ Overrides language id specified with the languageId attribute.
</documentation>
</annotation>
</attribute>
<attribute name="fieldEditor" type="string">
<annotation>
<documentation>
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&apos;s &lt;code&gt;valueType&lt;/code&gt; attribute.
A custom field-editor needs to be registered, under the same ID, through the &lt;code&gt;org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI&lt;/code&gt; extension-point&apos;s &lt;code&gt;&amp;lt;fieldEditor&amp;gt;&lt;/code&gt; element.
</documentation>
<appInfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI/fieldEditor/@id"/>
</appInfo>
</annotation>
</attribute>
<attribute name="fieldEditorExtraArgument" type="string">
<annotation>
<documentation>
An optional extra text string that is passed into the field-editor. Can be used to parameterize the field-editor instance.
</documentation>
</annotation>
</attribute>
</complexType>
</element>

View file

@ -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 <fieldEditor>} 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 <code>true</code> if this option was loaded from a manifest file,
* and <code>false</code> if it was loaded from a project (.cdtbuild) file.

View file

@ -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

View file

@ -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()
*/

View file

@ -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

View file

@ -2,6 +2,7 @@
<?eclipse version="3.0"?>
<plugin>
<extension-point id="buildDefinitionsUI" name="%buildDefinitionsUI.ep.name" schema="schema/buildDefinitionsUI.exsd"/>
<extension-point id="newWizardPages" name="%extension-point.name" schema="schema/newWizardPages.exsd"/>
<extension

View file

@ -0,0 +1,127 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.managedbuilder.ui" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.cdt.managedbuilder.ui" id="buildDefinitionsUI" name="Build Definitions UI Extensions"/>
</appInfo>
<documentation>
This extension point allows for the contribution of various UI extensions which can be referenced from the &lt;code&gt;org.eclipse.cdt.managedbuilder.core.buildDefinitions&lt;/code&gt; 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 &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; element of an &lt;code&gt;org.eclipse.cdt.managedbuilder.core.buildDefinitions&lt;/code&gt; extension.
</documentation>
</annotation>
<element name="extension">
<annotation>
<appInfo>
<meta.element />
</appInfo>
</annotation>
<complexType>
<sequence>
<element ref="fieldEditor" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appInfo>
<meta.attribute translatable="true"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="fieldEditor">
<annotation>
<documentation>
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 &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; element of an &lt;code&gt;org.eclipse.cdt.managedbuilder.core.buildDefinitions&lt;/code&gt; extension.
</documentation>
</annotation>
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
A unique identifier which will be used to reference this field-editor from an &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; element of an &lt;code&gt;org.eclipse.cdt.managedbuilder.core.buildDefinitions&lt;/code&gt; extension.
</documentation>
</annotation>
</attribute>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
Specifies the Java class which implements the custom field-editor. This class must extend JFace&apos;s &lt;code&gt;FieldEditor&lt;/code&gt; abstract class, and implement the &lt;code&gt;ICustomBuildOptionEditor&lt;/code&gt; interface.
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn="org.eclipse.jface.preference.FieldEditor:org.eclipse.cdt.managedbuilder.ui.properties.ICustomBuildOptionEditor"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appInfo>
<meta.section type="since"/>
</appInfo>
<documentation>
8.0
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="examples"/>
</appInfo>
<documentation>
&lt;extension point=&quot;org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI&quot;&gt;
&lt;fieldEditor
id=&quot;org.eclipse.cdt.managedbuilder.ui.tests.fieldEditors.CustomFieldEditor&quot;
class=&quot;org.eclipse.cdt.managedbuilder.ui.tests.fieldEditors.CustomFieldEditor&quot;/&gt;
&lt;/extension&gt;
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="apiInfo"/>
</appInfo>
<documentation>
None
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="implementation"/>
</appInfo>
<documentation>
None
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="copyright"/>
</appInfo>
<documentation>
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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt; Eclipse&lt;/a&gt; website.
</documentation>
</annotation>
</schema>

View file

@ -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<String, CustomFieldEditorDescriptor> customFieldEditorDescriptorIndex;
private Map<FieldEditor, Composite> fieldEditorsToParentMap =
new HashMap<FieldEditor, Composite>();
/** 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<String, CustomFieldEditorDescriptor>();
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 <code>true</code> if the settings page has been created for the
* option category specified in the argument.

View file

@ -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 <fieldEditor>
* element of the org.eclipse.cdt.managedbuilder.ui.buildDefinitionsUI extension-point,
* and then referenced, by its ID, from the <option>/fieldEditorId attribute of the
* org.eclipse.cdt.managedbuilder.core.buildDefinitions extension-point.
*
* @since 8.0
*/
public interface ICustomBuildOptionEditor
{
/**
* Initializes the custom field-editor.
*
* @param option the underlying build-option.
* @param extraArgument an optional {@link IOption#getFieldEditorExtraArgument() extra argument}
* for the field-editor. May be {@code null}.
* @param preferenceName the name of the preference this field editor binds to.
* @param parent the parent of the field editor's control.
* @return {@code true} iff the custom field-editor can be successfully displayed. Returning {@code false}
* would cause the built-in field-editor to be displayed based on the option's {@link IOption#getValueType() valueType}.
*/
boolean init(IOption option, String extraArgument, String preferenceName, Composite parent);
/**
* Returns the list of controls for which tool-tips should be displayed by the Build Settings dialog-page.
*
* @return the list of controls for which tool-tips should automatically be displayed by the Build Settings dialog-page.
* May return {@code null} to signify that tool-tips are handled by the custom field-editor itself.
*/
Control[] getToolTipSources();
}