Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml62
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java64
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd115
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java173
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java426
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java59
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java7
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java9
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java13
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java317
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java15
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java7
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java3
23 files changed, 1230 insertions, 60 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
index 67494d80a5..dfaafb86ce 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
@@ -9311,4 +9311,66 @@
name="Test Plugin GCC BOP Patterns Highlighter">
</errorparser>
</extension>
+ <!-- Tree Option -->
+ <extension
+ id="cdt.managed.build.test.tree.option"
+ name="Test Managed Build TreeOption"
+ point="org.eclipse.cdt.managedbuilder.core.buildDefinitions">
+ <managedBuildRevision fileVersion="4.0.0"/>
+ <tool
+ natureFilter="cnature"
+ name="Test Tool"
+ outputFlag="-o"
+ command="gcc"
+ id="cdt.managedbuild.tool.gnu.c.linker.test.tree.tool"
+ errorParsers="org.eclipse.cdt.core.GLDErrorParser">
+
+ <option
+ defaultValue="grandChild_1_1_1"
+ name="Dummy Tree Option"
+ command="-dummy"
+ id="cdt.managedbuild.tool.gnu.c.linker.test.tree.option"
+ valueType="tree">
+ <treeOptionRoot name="root" id="option.tree.root">
+ <treeOption name="Parent 1" id="parent_1">
+ <treeOption name="Child 1 1" id="child_1_1">
+ <treeOption name="Grand Child 1 1 1" id="grandChild_1_1_1" />
+ <treeOption name="Grand Child 1 1 2" id="grandChild_1_1_2" />
+ <treeOption name="Grand Child 1 1 3" id="grandChild_1_1_3" />
+ </treeOption>
+ <treeOption name="Child 1 2" id="child_1_2">
+ <treeOption name="Grand Child 1 2 1" id="grandChild_1_2_1" />
+ <treeOption name="Grand Child 1 2 2" id="grandChild_1_2_2" command="-dummy122" />
+ <treeOption name="Grand Child 1 2 3" id="grandChild_1_2_3" />
+ </treeOption>
+ </treeOption>
+ <treeOption name="Parent 2" id="parent_2">
+ <treeOption name="Child 2 1" id="child_2_1">
+ <treeOption name="Grand Child 2 1 1" id="grandChild_2_1_1" />
+ <treeOption name="Grand Child 2 1 2" id="grandChild_2_1_2" />
+ <treeOption name="Grand Child 2 1 3" id="grandChild_2_1_3" />
+ </treeOption>
+ <treeOption name="Child 2 2" id="child_2_2">
+ <treeOption name="Grand Child 2 2 1" id="grandChild_2_2_1" />
+ <treeOption name="Grand Child 2 2 2" id="grandChild_2_2_2" />
+ <treeOption name="Grand Child 2 2 3" id="grandChild_2_2_3" />
+ </treeOption>
+ </treeOption>
+ <treeOption name="Parent 3" id="parent_3" order="0">
+ <treeOption name="Child 3 1" id="child_3_1">
+ <treeOption name="Grand Child 3 1 1" id="grandChild_3_1_1" />
+ <treeOption name="Grand Child 3 1 2" id="grandChild_3_1_2" />
+ <treeOption name="Grand Child 3 1 3" id="grandChild_3_1_3" />
+ </treeOption>
+ <treeOption name="Child 3 2" id="child_3_2">
+ <treeOption name="Grand Child 3 2 1" id="grandChild_3_2_1" />
+ <treeOption name="Grand Child 3 2 2" id="grandChild_3_2_2" />
+ <treeOption name="Grand Child 3 2 3" id="grandChild_3_2_3" />
+ </treeOption>
+ </treeOption>
+ </treeOptionRoot>
+ </option>
+ </tool>
+ </extension>
+
</plugin>
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java
index 68e2a10bb9..e1bf503c10 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java
@@ -22,6 +22,9 @@ import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot;
+import org.eclipse.cdt.managedbuilder.core.IOptionApplicability;
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.IProjectType;
import org.eclipse.cdt.managedbuilder.core.ITargetPlatform;
@@ -30,6 +33,7 @@ import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.Builder;
import org.eclipse.core.runtime.IConfigurationElement;
+import org.junit.Assert;
public class ManagedBuildCoreTests extends TestCase {
@@ -44,6 +48,7 @@ public class ManagedBuildCoreTests extends TestCase {
public static Test suite() {
TestSuite suite = new TestSuite(ManagedBuildCoreTests.class.getName());
suite.addTest(new ManagedBuildCoreTests("testLoadManifest"));
+ suite.addTest(new ManagedBuildCoreTests("testTreeOptions"));
return suite;
}
@@ -598,5 +603,64 @@ public class ManagedBuildCoreTests extends TestCase {
} // end for
} // end routine
+
+ /**
+ * Tests Options of type tree as implemented in bug 365718
+ * @throws Exception
+ */
+ public void testTreeOptions() throws Exception {
+ IOption treeOption = ManagedBuildManager.getExtensionOption("cdt.managedbuild.tool.gnu.c.linker.test.tree.option");
+ assertNotNull(treeOption);
+
+ // standard options
+ assertEquals(IOption.TREE, treeOption.getValueType());
+ assertEquals("grandChild_1_1_1", treeOption.getValue());
+ assertEquals("grandChild_1_1_1", treeOption.getDefaultValue());
+ assertEquals("cdt.managedbuild.tool.gnu.c.linker.test.tree.option", treeOption.getId());
+ assertEquals("-dummy", treeOption.getCommand());
+ assertEquals("-dummy122", treeOption.getCommand("grandChild_1_2_2"));
+
+ String[] applicableValues = treeOption.getApplicableValues();
+ String[] expected = new String[18];
+ int index = 0;
+ for (int i = 1; i < 4; i++) {
+ for (int j = 1; j < 3; j++) {
+ for (int k = 1; k < 4; k++) {
+ expected[index++] = "Grand Child " + i + ' ' + j + ' ' + k;
+ }
+ }
+ }
+ Assert.assertArrayEquals(expected, applicableValues);
+
+ ITreeRoot treeRoot = treeOption.getTreeRoot();
+ assertNotNull(treeRoot);
+
+ // test some tree option attributes
+ ITreeOption[] children = treeRoot.getChildren();
+ assertNotNull(children);
+ assertEquals(0, children[2].getOrder());
+ assertEquals("Parent 2", children[1].getName());
+ assertTrue(children[0].isContainer());
+
+ ITreeOption findNode = treeRoot.findNode("grandChild_2_1_3");
+ assertNotNull(findNode);
+
+ int size = children.length;
+ treeRoot.addChild("newID", "New Name");
+ assertEquals(size+1, treeRoot.getChildren().length);
+ assertEquals("newID", treeRoot.getChild("New Name").getID());
+
+ // check tree only methods
+ IOption nonTreeOption = ManagedBuildManager.getExtensionOption("testgnu.c.compiler.exe.debug.option.debugging.level");
+ assertFalse(IOption.TREE == nonTreeOption.getValueType());
+ boolean exception = false;
+ try {
+ nonTreeOption.getTreeRoot();
+ } catch (Exception e) {
+ exception = true;
+ }
+ assertTrue(exception);
+
+ }
} // end class
diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
index e8a56781bf..6e8e0e3285 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
+++ b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
@@ -1178,6 +1178,7 @@ Options can also be associated with a toolchain. However in such a case the opti
<choice>
<element ref="listOptionValue" minOccurs="0" maxOccurs="unbounded"/>
<element ref="enumeratedOptionValue" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="treeOptionRoot" minOccurs="0" maxOccurs="1"/>
</choice>
<element ref="enablement" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
@@ -1289,6 +1290,8 @@ Additional special types exist to flag options of special relevance to the build
</enumeration>
<enumeration value="undefSymbolFiles">
</enumeration>
+ <enumeration value="tree">
+ </enumeration>
</restriction>
</simpleType>
</attribute>
@@ -1512,6 +1515,118 @@ A custom field-editor needs to be registered, under the same ID, through the &lt
</complexType>
</element>
+ <element name="treeOption">
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <element ref="treeOption"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id should be the value used for determining which treeOption is selected, it has to be unique within the tree.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ Display name for the option
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ Description of the option to be presented to the user
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="command" type="string">
+ <annotation>
+ <documentation>
+ The command that the tree value translates to on the command line.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="isDefault" type="boolean">
+ <annotation>
+ <documentation>
+ Flags this tree value as the default to apply to the option if the user has not changed the setting.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ An icon to be used for this node in the tree representation. Should use full path for the icon: e.g., platform:/plugin/org.eclipse.cdt/icons/wizard.png
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="order" type="string">
+ <annotation>
+ <documentation>
+ An integer representing the order of this option within its peers in the tree. The order is a relative number, were smaller numbers appear on top of larger numbers.
+If no order is defined a default order is assumed, see &quot;org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption.DEFAULT_ORDER&quot; for more details.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="treeOptionRoot">
+ <annotation>
+ <documentation>
+ Represents the root of a tree of options. Note that the root is never shown to the user and can&apos;t be selected. It is a place holder for settings affecting the options tree behavior
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="treeOption"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The tree root icon can be used in branding the UI representation of the tree. Should use full path for the icon: e.g., platform:/plugin/org.eclipse.cdt/icons/wizard.png
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="selectLeafOnly" type="boolean">
+ <annotation>
+ <documentation>
+ Determines whether this tree allows selecting categories as well as leaf nodes, or leaf nodes only.
+Default is true (leaf nodes only).
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
<element name="builder">
<annotation>
<documentation>
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 2196fd19fe..85ac319e5f 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
@@ -55,6 +55,12 @@ public interface IOption extends IBuildObject {
public static final int LIBRARY_FILES = 10;
public static final int MACRO_FILES = 11;
+ /**
+ * Tree of items to select one from.
+ * @since 8.1
+ */
+ public static final int TREE = 12;
+
public static final int UNDEF_INCLUDE_PATH = -INCLUDE_PATH;
public static final int UNDEF_PREPROCESSOR_SYMBOLS = -PREPROCESSOR_SYMBOLS;
public static final int UNDEF_INCLUDE_FILES = -INCLUDE_FILES;
@@ -84,6 +90,14 @@ public interface IOption extends IBuildObject {
/** @since 7.0 */
public static final String BROWSE_FILTER_EXTENSIONS = "browseFilterExtensions"; //$NON-NLS-1$
public static final String CATEGORY = "category"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String ICON = "icon"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String ORDER = "order"; //$NON-NLS-1$
public static final String COMMAND = "command"; //$NON-NLS-1$
public static final String COMMAND_FALSE = "commandFalse"; //$NON-NLS-1$
/** @since 8.0 */
@@ -92,6 +106,22 @@ public interface IOption extends IBuildObject {
public static final String CONTEXT_ID = "contextId"; //$NON-NLS-1$
public static final String DEFAULT_VALUE = "defaultValue"; //$NON-NLS-1$
public static final String ENUM_VALUE = "enumeratedOptionValue"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String TREE_ROOT = "treeOptionRoot"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String SELECT_LEAF_ONLY = "selectLeafOnly"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String TREE_VALUE = "treeOption"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String DESCRIPTION = "description"; //$NON-NLS-1$
public static final String IS_DEFAULT = "isDefault"; //$NON-NLS-1$
public static final String LIST_VALUE = "listOptionValue"; //$NON-NLS-1$
public static final String RESOURCE_FILTER = "resourceFilter"; //$NON-NLS-1$
@@ -114,6 +144,10 @@ public interface IOption extends IBuildObject {
public static final String TYPE_UNDEF_LIB_FILES = "undefLibFiles"; //$NON-NLS-1$
public static final String TYPE_UNDEF_INC_FILES = "undefIncludeFiles"; //$NON-NLS-1$
public static final String TYPE_UNDEF_SYMBOL_FILES = "undefSymbolFiles"; //$NON-NLS-1$
+ /**
+ * @since 8.1
+ */
+ public static final String TYPE_TREE = "tree"; //$NON-NLS-1$
public static final String VALUE = "value"; //$NON-NLS-1$
public static final String VALUE_TYPE = "valueType"; //$NON-NLS-1$
@@ -326,18 +360,59 @@ public interface IOption extends IBuildObject {
public String getEnumCommand (String id) throws BuildException;
/**
+ * Returns the command associated with the child of this option
+ * with the given id. Applies to options of types that has children
+ * for example {@link #TREE} or {@link #ENUMERATED}
+ *
+ * @param id - child id
+ * @return the command associated with the child id. For
+ * example, if the child id was <code>gnu.debug.level.default</code>
+ * for the debug level option of the Gnu compiler, and the plugin
+ * manifest defined that as -g, then the return value would be the
+ * String "-g"
+ *
+ * @throws BuildException
+ * @since 8.1
+ */
+ public String getCommand (String id) throws BuildException;
+
+ /**
* @param id - enumeration id
* @return the "name" associated with the enumeration id.
*/
public String getEnumName (String id) throws BuildException;
/**
+ * Returns the name associated with the child of this option
+ * with the given id. Applies to options of types that has children
+ * for example {@link #TREE} or {@link #ENUMERATED}
+ *
+ * @param id The id to look for
+ * @return Name of the child with the passed id or <code>null</code> if not found.
+ * @throws BuildException if any issue happened while searching.
+ * @since 8.1
+ */
+ public abstract String getName(String id) throws BuildException;
+
+ /**
* @param name - a "name" associated with enumeration id
* @return enumeration id
*/
public String getEnumeratedId(String name) throws BuildException;
/**
+ * Returns the id associated with the child of this option
+ * with the given name. Applies to options of types that has children
+ * for example {@link #TREE} or {@link #ENUMERATED}
+ *
+ * @param name the name of the child to look for.
+ * @return The id of the found child or <code>null</code> if not found.
+ * @throws BuildException if any error happened while searching
+ * @since 8.1
+ */
+ public abstract String getId(String name) throws BuildException;
+
+ /**
* @return an array of <code>String</code> containing the includes paths
* defined in the build model.
*/
@@ -514,6 +589,7 @@ public interface IOption extends IBuildObject {
* <li/>{@link IOption#BOOLEAN}
* <li/>{@link IOption#STRING}
* <li/>{@link IOption#ENUMERATED}
+ * <li/>{@link IOption#TREE}
* <li/>{@link IOption#STRING_LIST} - corresponds to
* {@link IOption#INCLUDE_PATH}, {@link IOption#PREPROCESSOR_SYMBOLS}, {@link IOption#LIBRARIES},
* {@link IOption#OBJECTS}, {@link IOption#INCLUDE_FILES}, {@link IOption#LIBRARY_PATHS},
@@ -528,4 +604,101 @@ public interface IOption extends IBuildObject {
String[] getBasicStringListValue() throws BuildException;
public OptionStringValue[] getBasicStringListValueElements() throws BuildException;
+
+ /**
+ * Returns the tree root of this option if it is of type {@link #TREE}
+ * @return tree root of this option or <code>null</code> if not found.
+ * @throws BuildException if this option is not of type {@link #TREE}
+ * @since 8.1
+ */
+ public ITreeRoot getTreeRoot() throws BuildException;
+
+ /**
+ * Represents the root of the tree of values in options of
+ * type {@link IOption#TREE}
+ * @author mhussein
+ * @since 8.1
+ *
+ */
+ public interface ITreeRoot extends ITreeOption {
+ /**
+ * Determines whether this tree allows selecting leaf nodes
+ * only or any nodes.
+ * @return <code>true</code> if only leaf nodes are allowed.
+ * <code>false</code> if all child nodes could be selected.
+ * @see ITreeOption#isContainer()
+ */
+ boolean isSelectLeafsOnly();
+
+ /**
+ * Locates the node with the given id anywhere in the tree.
+ * @param id the id to search for
+ * @return the found child or <code>null</code> if not found.
+ */
+ ITreeOption findNode(String id);
+
+ /**
+ * Adds a new node to the tree.
+ * @param id The id of the new child.
+ * @param name The name of the new child.
+ * @param category The category of the new child.category is a '.'
+ * separated string representing hierarchical path
+ * of the child from the root of the tree.
+ * can cause other nodes to be created to construct the
+ * full path to the new child.
+ * @param order The order of the newly created node among its peers.
+ * see {@link ITreeOption#getOrder()} for more information.
+ * Note: this order will apply to any parents auto-created
+ * according to the passed category.
+ * if <code>null</code> the {@link ITreeOption#DEFAULT_ORDER}
+ * will be used.
+ * @return the newly added node.
+ */
+ ITreeOption addNode(String id, String name, String category, Integer order);
+ }
+
+ /**
+ * Represents a one of the possible values for options of type
+ * {@link IOption#TREE}
+ * @author mhussein
+ * @since 8.1
+ *
+ */
+ public interface ITreeOption {
+ /**
+ * The default order for tree nodes without order specified.
+ * Tree options with Orders smaller than this should appear above
+ * tree options with no order specified and vice versa.
+ */
+ public static final int DEFAULT_ORDER = 1000;
+
+ String getName();
+ String getID();
+ String getDescription();
+ /**
+ * The order that determines UI appearance of the tree node,
+ * not necessarily its position in {@link #getChildren()}
+ * @return The order of this tree option relative to its peers.
+ * Smaller number means it should appear above peers.
+ * @see #DEFAULT_ORDER
+ */
+ int getOrder();
+ void setOrder(int order);
+
+ ITreeOption[] getChildren();
+ ITreeOption getParent();
+ boolean isContainer();
+ String getCommand();
+ ITreeOption getChild(String name);
+
+ /**
+ * Adds a new child directly under this node.
+ * @param id
+ * @param name
+ * @return
+ */
+ ITreeOption addChild(String id, String name);
+ void remove();
+ String getIcon();
+ }
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java
index cf081b242f..0304e01527 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java
@@ -120,6 +120,7 @@ public class ManagedOptionValueHandler implements
}
break;
case IOption.ENUMERATED:
+ case IOption.TREE:
if (option.getValue().toString().equals(defaultValue.toString())) {
return true;
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java
index 0142f707db..62b8143297 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java
@@ -657,7 +657,7 @@ public class BuildStep implements IBuildStep {
} else {
ManagedBuildManager.setOption(cfg, fTool, assignToOption, false);
}
- } else if (optType == IOption.ENUMERATED) {
+ } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) {
if (bRcs.length > 0) {
ManagedBuildManager.setOption(cfg, fTool, assignToOption, BuildDescriptionManager.getRelPath(cwd, bRcs[0].getLocation()).toOSString());
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java
index f65adbc4e3..f3d8fb9e16 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java
@@ -132,6 +132,7 @@ public class ConfigurationV2 extends BuildObject implements IConfigurationV2 {
new OptionReference(newRef, opt).setValue(optRef.getBooleanValue());
break;
case IOption.STRING:
+ case IOption.TREE:
new OptionReference(newRef, opt).setValue(optRef.getStringValue());
break;
case IOption.ENUMERATED:
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 711e3c60c3..07d69fe1a7 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
@@ -39,6 +39,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler;
import org.eclipse.cdt.managedbuilder.core.OptionStringValue;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption;
import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression;
import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData;
import org.eclipse.cdt.managedbuilder.macros.IOptionContextData;
@@ -71,9 +72,9 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
private String commandFalse;
private String tip;
private String contextId;
- private List<String> enumList;
- private Map<String, String> enumCommands;
- private Map<String, String> enumNames;
+ private List<String> applicableValuesList;
+ private Map<String, String> commandsMap;
+ private Map<String, String> namesMap;
private Object value;
private Object defaultValue;
private Integer valueType;
@@ -87,6 +88,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
private IConfigurationElement applicabilityCalculatorElement = null;
private IOptionApplicability applicabilityCalculator = null;
private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null;
+ private ITreeRoot treeRoot;
// Miscellaneous
private boolean isExtensionOption = false;
private boolean isDirty = false;
@@ -222,10 +224,13 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
if (option.resourceFilter != null) {
resourceFilter = new Integer(option.resourceFilter.intValue());
}
- if (option.enumList != null) {
- enumList = new ArrayList<String>(option.enumList);
- enumCommands = new HashMap<String, String>(option.enumCommands);
- enumNames = new HashMap<String, String>(option.enumNames);
+ if (option.applicableValuesList != null) {
+ applicableValuesList = new ArrayList<String>(option.applicableValuesList);
+ commandsMap = new HashMap<String, String>(option.commandsMap);
+ namesMap = new HashMap<String, String>(option.namesMap);
+ }
+ if (option.treeRoot != null) {
+ treeRoot = new TreeRoot((TreeRoot) option.treeRoot);
}
if (option.valueType != null) {
@@ -245,6 +250,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
break;
case STRING:
case ENUMERATED:
+ case TREE:
if (option.value != null) {
value = new String((String)option.value);
}
@@ -549,18 +555,18 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
ICStorageElement configElement = configNode;
String optId = SafeStringInterner.safeIntern(configElement.getAttribute(ID));
if (i == 0) {
- enumList = new ArrayList<String>();
+ applicableValuesList = new ArrayList<String>();
if (defaultValue == null) {
defaultValue = optId; // Default value to be overridden is default is specified
}
}
- enumList.add(optId);
+ applicableValuesList.add(optId);
if (configElement.getAttribute(COMMAND) != null) {
- getEnumCommandMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(COMMAND)));
+ getCommandMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(COMMAND)));
} else {
- getEnumCommandMap().put(optId, EMPTY_STRING);
+ getCommandMap().put(optId, EMPTY_STRING);
}
- getEnumNameMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(NAME)));
+ getNameMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(NAME)));
if (configElement.getAttribute(IS_DEFAULT) != null) {
Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT));
if (isDefault.booleanValue()) {
@@ -570,6 +576,14 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
}
break;
+ case TREE:
+ if (element.getAttribute(VALUE) != null) {
+ value = element.getAttribute(VALUE);
+ }
+ if (element.getAttribute(DEFAULT_VALUE) != null) {
+ defaultValue = element.getAttribute(DEFAULT_VALUE);
+ }
+ break;
case STRING_LIST:
case INCLUDE_PATH:
case PREPROCESSOR_SYMBOLS:
@@ -727,6 +741,8 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
return UNDEF_INCLUDE_FILES;
else if (valueTypeStr.equals(TYPE_UNDEF_SYMBOL_FILES))
return UNDEF_MACRO_FILES;
+ else if (valueTypeStr.equals(TYPE_TREE))
+ return TREE;
else {
// TODO: This was the CDT 2.0 default - should we keep it?
return PREPROCESSOR_SYMBOLS;
@@ -789,6 +805,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
break;
case STRING:
case ENUMERATED:
+ case TREE:
element.setAttribute(VALUE, (String)value);
break;
case STRING_LIST:
@@ -834,6 +851,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
break;
case STRING:
case ENUMERATED:
+ case TREE:
element.setAttribute(DEFAULT_VALUE, (String)defaultValue);
break;
default:
@@ -898,6 +916,9 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
case UNDEF_MACRO_FILES:
str = TYPE_UNDEF_SYMBOL_FILES;
break;
+ case TREE:
+ str = TYPE_TREE;
+ break;
default:
// TODO; is this a problem...
str = EMPTY_STRING;
@@ -1039,7 +1060,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
@Override
public String[] getApplicableValues() {
// Does this option instance have the list of values?
- if (enumList == null) {
+ if (applicableValuesList == null) {
if (superClass != null) {
return superClass.getApplicableValues();
} else {
@@ -1047,13 +1068,13 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
}
// Get all of the enumerated names from the option
- if (enumList.size() == 0) {
+ if (applicableValuesList.size() == 0) {
return EMPTY_STRING_ARRAY;
} else {
// Return the elements in the order they are specified in the manifest
- String[] enumNames = new String[enumList.size()];
- for (int index = 0; index < enumList.size(); ++ index) {
- enumNames[index] = getEnumNameMap().get(enumList.get(index));
+ String[] enumNames = new String[applicableValuesList.size()];
+ for (int index = 0; index < applicableValuesList.size(); ++ index) {
+ enumNames[index] = getNameMap().get(applicableValuesList.get(index));
}
return enumNames;
}
@@ -1311,35 +1332,35 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
/* (non-Javadoc)
- * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String)
+ * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand(java.lang.String)
*/
@Override
- public String getEnumCommand(String id) throws BuildException {
+ public String getCommand(String id) throws BuildException {
// Sanity
if (id == null) return EMPTY_STRING;
// Does this option instance have the list of values?
- if (enumList == null) {
+ if (applicableValuesList == null) {
if (superClass != null) {
- return superClass.getEnumCommand(id);
+ return superClass.getCommand(id);
} else {
return EMPTY_STRING;
}
}
- if (getValueType() != ENUMERATED) {
+ if (getValueType() != ENUMERATED && getValueType() != TREE) {
throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
// First check for the command in ID->command map
- String cmd = getEnumCommandMap().get(id);
+ String cmd = getCommandMap().get(id);
if (cmd == null) {
// This may be a 1.2 project or plugin manifest. If so, the argument is the human readable
// name of the enumeration. Search for the ID that maps to the name and use that to find the
// command.
- for (String realID : enumList) {
- String name = getEnumNameMap().get(realID);
+ for (String realID : applicableValuesList) {
+ String name = getNameMap().get(realID);
if (id.equals(name)) {
- cmd = getEnumCommandMap().get(realID);
+ cmd = getCommandMap().get(realID);
break;
}
}
@@ -1348,17 +1369,30 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
/* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String)
+ */
+ @Override
+ public String getEnumCommand(String id) throws BuildException {
+ return getCommand(id);
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String)
*/
@Override
public String getEnumName(String id) throws BuildException {
+ return getName(id);
+ }
+
+ @Override
+ public String getName(String id) throws BuildException {
// Sanity
if (id == null) return EMPTY_STRING;
// Does this option instance have the list of values?
- if (enumList == null) {
+ if (applicableValuesList == null) {
if (superClass != null) {
- return superClass.getEnumName(id);
+ return superClass.getName(id);
} else {
return EMPTY_STRING;
}
@@ -1368,7 +1402,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
// First check for the command in ID->name map
- String name = getEnumNameMap().get(id);
+ String name = getNameMap().get(id);
if (name == null) {
// This may be a 1.2 project or plugin manifest. If so, the argument is the human readable
// name of the enumeration.
@@ -1384,11 +1418,11 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
* @return a Map of enumerated option value IDs to actual commands that are passed
* to a tool on the command line.
*/
- private Map<String, String> getEnumCommandMap() {
- if (enumCommands == null) {
- enumCommands = new HashMap<String, String>();
+ private Map<String, String> getCommandMap() {
+ if (commandsMap == null) {
+ commandsMap = new HashMap<String, String>();
}
- return enumCommands;
+ return commandsMap;
}
/* (non-Javadoc)
@@ -1396,23 +1430,28 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
*/
@Override
public String getEnumeratedId(String name) throws BuildException {
+ return getId(name);
+ }
+
+ @Override
+ public String getId(String name) throws BuildException {
if (name == null) return null;
// Does this option instance have the list of values?
- if (enumList == null) {
+ if (applicableValuesList == null) {
if (superClass != null) {
- return superClass.getEnumeratedId(name);
+ return superClass.getId(name);
} else {
return EMPTY_STRING;
}
}
- if (getValueType() != ENUMERATED) {
+ if (getValueType() != ENUMERATED && getValueType() != TREE) {
throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
- Set<String> idSet = getEnumNameMap().keySet();
+ Set<String> idSet = getNameMap().keySet();
for (String id : idSet) {
- String enumName = getEnumNameMap().get(id);
+ String enumName = getNameMap().get(id);
if (name.equals(enumName)) {
return id;
}
@@ -1424,11 +1463,11 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
*
* @return a Map of enumerated option value IDs to the selection displayed to the user.
*/
- private Map<String, String> getEnumNameMap() {
- if (enumNames == null) {
- enumNames = new HashMap<String, String>();
+ private Map<String, String> getNameMap() {
+ if (namesMap == null) {
+ namesMap = new HashMap<String, String>();
}
- return enumNames;
+ return namesMap;
}
/* (non-Javadoc)
@@ -1537,7 +1576,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
*/
@Override
public String getStringValue() throws BuildException {
- if (getValueType() != STRING && getValueType() != ENUMERATED) {
+ if (getValueType() != STRING && getValueType() != ENUMERATED && getValueType() != TREE) {
throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
return getValue() == null ? EMPTY_STRING : (String)getValue();
@@ -1609,6 +1648,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
val = new Boolean(false);
break;
case STRING:
+ case TREE:
val = EMPTY_STRING;
break;
case ENUMERATED:
@@ -1669,6 +1709,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
val = new Boolean(false);
break;
case STRING:
+ case TREE:
val = EMPTY_STRING;
break;
case ENUMERATED:
@@ -1949,7 +1990,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
@Override
public void setValue(String value) throws BuildException {
// Note that we can still set the human-readable value here
- if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) {
+ if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED || getValueType() == TREE)) {
this.value = value;
} else {
throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
@@ -2281,20 +2322,44 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
for (int i = 0; i < enumElements.length; ++i) {
String optId = SafeStringInterner.safeIntern(enumElements[i].getAttribute(ID));
if (i == 0) {
- enumList = new ArrayList<String>();
+ applicableValuesList = new ArrayList<String>();
if (defaultValue == null) {
defaultValue = optId; // Default value to be overridden if default is specified
}
}
- enumList.add(optId);
- getEnumCommandMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(COMMAND)));
- getEnumNameMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(NAME)));
+ applicableValuesList.add(optId);
+ getCommandMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(COMMAND)));
+ getNameMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(NAME)));
Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT));
if (isDefault.booleanValue()) {
defaultValue = optId;
}
}
break;
+ case TREE:
+ value = element.getAttribute(VALUE);
+ defaultValue = element.getAttribute(DEFAULT_VALUE);
+
+ IManagedConfigElement[] treeRootConfigs = element.getChildren(TREE_ROOT);
+ if (treeRootConfigs != null && treeRootConfigs.length == 1) {
+ IManagedConfigElement treeRootConfig = treeRootConfigs[0];
+ treeRoot = new TreeRoot(treeRootConfig, element, getParent() instanceof IToolChain);
+ applicableValuesList = new ArrayList<String>();
+ iterateOnTree(treeRoot, new ITreeNodeIterator() {
+
+ @Override
+ public void iterateOnNode(ITreeOption node) {}
+
+ @Override
+ public void iterateOnLeaf(ITreeOption leafNode) {
+ applicableValuesList.add(leafNode.getID());
+ getCommandMap().put(leafNode.getID(), leafNode.getCommand());
+ getNameMap().put(leafNode.getID(), leafNode.getName());
+ }
+ });
+ }
+
+ break;
case STRING_LIST:
case INCLUDE_PATH:
case PREPROCESSOR_SYMBOLS:
@@ -2613,6 +2678,8 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
return IOption.STRING;
case IOption.ENUMERATED:
return IOption.ENUMERATED;
+ case IOption.TREE:
+ return IOption.TREE;
default:
return IOption.STRING_LIST;
}
@@ -2658,4 +2725,267 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest
}
return 0;
}
+
+ public static class TreeRoot extends TreeOption implements ITreeRoot {
+ private boolean selectLeafOnly = true;
+ TreeRoot(IManagedConfigElement element, IManagedConfigElement buildOption, boolean readTool) {
+ super(element, null, readTool);
+ String leaf = element.getAttribute(SELECT_LEAF_ONLY);
+ if (leaf != null) {
+ selectLeafOnly = Boolean.valueOf(leaf);
+ }
+ String toolTip = buildOption.getAttribute(TOOL_TIP);
+ if (description == null && toolTip != null) {
+ description = toolTip;
+ }
+ }
+
+ public TreeRoot() {
+ super("", "", null); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public TreeRoot(TreeRoot clone) {
+ super(clone, null);
+ selectLeafOnly = clone.selectLeafOnly;
+ }
+
+ @Override
+ public boolean isSelectLeafsOnly() {
+ return selectLeafOnly;
+ }
+
+ @Override
+ public ITreeOption findNode(String id) {
+ if(id == null) return null;
+ return find(id, children);
+ }
+
+ private ITreeOption find(String id, List<ITreeOption> children) {
+ ITreeOption found = null;
+ if (children != null) {
+ for (ITreeOption child : children) {
+ if (id.equals(child.getID())) {
+ found = child;
+ break;
+ }
+ found = find(id, ((TreeOption)child).children);
+ if (found != null) break;
+ }
+ }
+ return found;
+ }
+
+ @Override
+ public ITreeOption addNode(String id, String name, String category, Integer order) {
+ ITreeOption parent = this;
+ if (category != null && category.length() > 0) {
+ ITreeOption tempParent;
+ String tempCategory = "";
+ String[] categories = category.split("\\."); //$NON-NLS-1$
+ for (String cat : categories) {
+ tempCategory += cat;
+ tempParent = parent.getChild(cat);
+ if (tempParent == null) {
+ tempParent = parent.addChild(cat, cat);
+ if (order != null) {
+ tempParent.setOrder(order);
+ }
+ }
+ parent = tempParent;
+ tempCategory += '.';
+ }
+ }
+
+ ITreeOption child = parent.addChild(id, name);
+ if (order != null) {
+ child.setOrder(order);
+ }
+ return child;
+ }
+
+ }
+
+ private static class TreeOption implements ITreeOption {
+ private String treeNodeId;
+ private String treeNodeName;
+ protected String description;
+ protected String icon;
+ protected String command;
+ protected List<ITreeOption> children = null;
+ private int order = DEFAULT_ORDER;
+ private ITreeOption parent;
+
+ TreeOption(IManagedConfigElement element, ITreeOption parent, boolean readTool) {
+ treeNodeId = element.getAttribute(ID);
+ treeNodeName = element.getAttribute(NAME);
+ description = element.getAttribute(DESCRIPTION);
+ command = element.getAttribute(COMMAND);
+ icon = element.getAttribute(ICON);
+
+ String orderStr = element.getAttribute(ORDER);
+ if (orderStr != null && orderStr.trim().length() > 0) {
+ try {
+ order = Integer.parseInt(orderStr);
+ } catch (NumberFormatException e) {
+ // Do nothing, default value is used.
+ }
+ }
+ this.parent = parent;
+
+ IManagedConfigElement[] treeChildren = element.getChildren(TREE_VALUE);
+ if (treeChildren != null && treeChildren.length > 0) {
+ children = new ArrayList<IOption.ITreeOption>();
+ for (IManagedConfigElement configElement : treeChildren) {
+ children.add(new TreeOption(configElement, this, readTool));
+ }
+ }
+ }
+
+ TreeOption(TreeOption clone, ITreeOption parent) {
+ treeNodeId = clone.treeNodeId;
+ treeNodeName = clone.treeNodeName;
+ description = clone.description;
+ command = clone.command;
+ icon = clone.icon;
+ order = clone.order;
+ this.parent = parent;
+
+ if (clone.children != null) {
+ children = new ArrayList<IOption.ITreeOption>();
+ for (ITreeOption cloneChild : clone.children) {
+ children.add(new TreeOption((TreeOption) cloneChild, this));
+ }
+ }
+ }
+
+ private TreeOption(String id, String name, ITreeOption parent) {
+ this.treeNodeId = id;
+ this.treeNodeName = name;
+ this.parent = parent;
+ }
+
+ @Override
+ public ITreeOption addChild(String id, String name) {
+ ITreeOption option = new TreeOption(id, name, this);
+ if (children == null) {
+ children = new ArrayList<IOption.ITreeOption>();
+ }
+ children.add(0, option);
+ return option;
+ }
+
+ @Override
+ public boolean isContainer() {
+ return children != null && !children.isEmpty(); // TODO do we need explicit marking as container for empty ones
+ }
+
+ @Override
+ public String getName() {
+ return treeNodeName;
+ }
+
+ @Override
+ public String getID() {
+ return treeNodeId;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String getCommand() {
+ return command;
+ }
+
+ @Override
+ public String getIcon() {
+ return icon;
+ }
+
+ @Override
+ public ITreeOption[] getChildren() {
+ if (children == null) return null;
+ return children.toArray(new ITreeOption[children.size()]);
+ }
+
+ @Override
+ public ITreeOption getChild(String name) {
+ if (children == null || name == null) return null;
+ for (ITreeOption child : children) {
+ if (name.equals(child.getName())) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ITreeOption getParent() {
+ return parent;
+ }
+
+ @Override
+ public int getOrder() {
+ return order;
+ }
+
+ @Override
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ @Override
+ public void remove() {
+ ((TreeOption)parent).children.remove(this);
+
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+ }
+
+ /**
+ * Calls the iterator (visitor) on the passed parent as well as all nodes in its subtree.
+ * @param it
+ * @param parent
+ */
+ public static void iterateOnTree(ITreeOption parent, ITreeNodeIterator it) {
+
+ it.iterateOnNode(parent);
+ if (!parent.isContainer()) {
+ it.iterateOnLeaf(parent);
+ }
+
+ ITreeOption[] children = parent.getChildren();
+ if (children != null) {
+ for (ITreeOption option : children) {
+ iterateOnTree(option, it);
+ }
+ }
+ }
+
+ public interface ITreeNodeIterator {
+ void iterateOnNode(ITreeOption node);
+ void iterateOnLeaf(ITreeOption leafNode);
+ }
+
+ @Override
+ public ITreeRoot getTreeRoot() throws BuildException {
+ if (treeRoot == null) {
+ if (superClass != null) {
+ return superClass.getTreeRoot();
+ } else {
+ return null;
+ }
+ }
+ if (getValueType() != TREE) {
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ }
+
+ return treeRoot;
+ }
}
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 e26d2cf9e2..f6d544f18a 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
@@ -117,6 +117,7 @@ public class OptionReference implements IOption {
value = new Boolean(element.getAttribute(DEFAULT_VALUE));
break;
case STRING:
+ case TREE:
case ENUMERATED:
// Pre-2.0 the value was the string for the UI
// Post-2.0 it is the ID of the enumerated option
@@ -189,6 +190,7 @@ public class OptionReference implements IOption {
case STRING:
value = element.getAttribute(DEFAULT_VALUE);
break;
+ case TREE:
case ENUMERATED:
String temp = element.getAttribute(DEFAULT_VALUE);
if (temp != null) {
@@ -248,6 +250,7 @@ public class OptionReference implements IOption {
element.setAttribute(DEFAULT_VALUE, ((Boolean)value).toString());
break;
case STRING:
+ case TREE:
case ENUMERATED:
element.setAttribute(DEFAULT_VALUE, (String)value);
break;
@@ -384,6 +387,19 @@ public class OptionReference implements IOption {
return new String();
}
+ public String getCommand(String id) throws BuildException {
+ if (!resolved) {
+ resolveReferences();
+ }
+ if (option != null) {
+ try {
+ String command = option.getCommand(id);
+ return command;
+ } catch (BuildException e) {}
+ }
+ return new String();
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IOption#getEnumName(java.lang.String)
*/
@@ -401,6 +417,19 @@ public class OptionReference implements IOption {
return new String();
}
+ public String getName(String id) throws BuildException {
+ if (!resolved) {
+ resolveReferences();
+ }
+ if (option != null) {
+ try {
+ String name = option.getName(id);
+ return name;
+ } catch (BuildException e) {}
+ }
+ return new String();
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String)
*/
@@ -418,6 +447,19 @@ public class OptionReference implements IOption {
return new String();
}
+ public String getId(String name) throws BuildException {
+ if (!resolved) {
+ resolveReferences();
+ }
+ if (option != null) {
+ try {
+ String id = option.getId(name);
+ return id;
+ } catch (BuildException e) {}
+ }
+ return new String();
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IBuildObject#getId()
*/
@@ -730,7 +772,7 @@ public class OptionReference implements IOption {
@Override
public void setValue(String value) throws BuildException {
// Note that we can still set the human-readable value here
- if (getValueType() == STRING || getValueType() == ENUMERATED) {
+ if (getValueType() == STRING || getValueType() == ENUMERATED || getValueType() == TREE) {
this.value = value;
} else {
throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
@@ -1024,6 +1066,8 @@ public class OptionReference implements IOption {
return IOption.STRING;
case IOption.ENUMERATED:
return IOption.ENUMERATED;
+ case IOption.TREE:
+ return IOption.TREE;
default:
return IOption.STRING_LIST;
}
@@ -1039,4 +1083,17 @@ public class OptionReference implements IOption {
}
return ve;
}
+ public ITreeRoot getTreeRoot() {
+ if (!resolved) {
+ resolveReferences();
+ }
+ if (option != null) {
+ try {
+ return option.getTreeRoot();
+ } catch (BuildException e) {
+ }
+ }
+ return null;
+ }
+
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
index d1f67bc82b..d1189ad7c7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
@@ -2625,6 +2625,13 @@ public class Tool extends HoldsOptions implements ITool, IOptionCategory, IMatch
}
break;
+ case IOption.TREE :
+ String treeVal = option.getCommand(option.getStringValue());
+ if (treeVal.length() > 0) {
+ sb.append(treeVal);
+ }
+ break;
+
case IOption.STRING :{
String strCmd = option.getCommand();
String val = option.getStringValue();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
index a983b1cf11..701d6cab4e 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
@@ -201,7 +201,9 @@ public class ToolReference implements IToolReference {
clone.setValue(parent.getBooleanValue());
break;
case IOption.STRING:
+ case IOption.TREE:
clone.setValue(parent.getStringValue());
+ break;
case IOption.ENUMERATED:
clone.setValue(parent.getSelectedEnum());
break;
@@ -518,6 +520,13 @@ public class ToolReference implements IToolReference {
}
break;
+ case IOption.TREE :
+ String treeVal = option.getCommand(option.getStringValue());
+ if (treeVal.length() > 0) {
+ buf.append(treeVal + WHITE_SPACE);
+ }
+ break;
+
case IOption.STRING :
String strCmd = option.getCommand();
String val = option.getStringValue();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java
index 9a4a12c84b..5ebcf95b94 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java
@@ -112,6 +112,7 @@ public class CheckOptionExpression implements IBooleanExpression {
switch(option.getValueType()){
case IOption.STRING:
+ case IOption.TREE:
case IOption.ENUMERATED:{
String stringValue = option.getStringValue();
stringValue = provider.resolveValue(stringValue, inexVal, delimiter,
@@ -177,6 +178,7 @@ public class CheckOptionExpression implements IBooleanExpression {
switch(option.getValueType()){
case IOption.STRING:
+ case IOption.TREE:
case IOption.ENUMERATED:{
String stringValue = option.getStringValue();
stringValue = provider.resolveValue(stringValue, inexVal, delimiter,
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java
index 1974450ec9..57bb78ee8b 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java
@@ -298,6 +298,7 @@ public class OptionEnablementExpression extends AndExpression{
}
break;
case IOption.ENUMERATED:
+ case IOption.TREE:
case IOption.STRING:
if(extensionAdjustment)
setOption.setValue(value);
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java
index 6336160fc6..f61fb6e36c 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java
@@ -913,6 +913,8 @@ public class MbsMacroSupplier extends BuildCdtVariablesSupplierBase {
break;
case IOption.ENUMERATED:
break;
+ case IOption.TREE:
+ break;
case IOption.STRING_LIST:
fType = IBuildMacro.VALUE_TEXT_LIST;
fStringListValue = option.getStringListValue();
@@ -1138,6 +1140,8 @@ public class MbsMacroSupplier extends BuildCdtVariablesSupplierBase {
break;
case IOption.ENUMERATED:
break;
+ case IOption.TREE:
+ break;
case IOption.STRING_LIST:
can = true;
break;
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java
index e23dbd5d9f..22aa3e8f07 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java
@@ -3044,7 +3044,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
boolean b = false;
if (allRes.size() > 0) b = true;
ManagedBuildManager.setOption(rcInfo, tool, assignToOption, b);
- } else if (optType == IOption.ENUMERATED) {
+ } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) {
if (allRes.size() > 0) {
String s = allRes.get(0).toString();
ManagedBuildManager.setOption(rcInfo, tool, assignToOption, s);
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java
index 3ede50863a..d96ce0bebd 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java
@@ -422,7 +422,7 @@ public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo {
} else {
ManagedBuildManager.setOption(config, tool, assignToOption, false);
}
- } else if (optType == IOption.ENUMERATED) {
+ } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) {
if (itCommandInputs.size() > 0) {
ManagedBuildManager.setOption(config, tool, assignToOption, itCommandInputs.firstElement());
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java
index de7cefba7e..79c113f644 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java
@@ -397,6 +397,19 @@ class UpdateManagedProject12 {
}
configuration.setOption(tool, newOpt, idValue != null ? idValue : name);
break;
+ case IOption.TREE:
+ // This is going to be the human readable form of the tree value
+ name = optRef.getAttribute(IOption.DEFAULT_VALUE);
+ // Convert it to the ID
+ idValue = newOpt.getId(name);
+ if (idValue == null) {
+ // If the name does not match one of the enumerations values, probably because
+ // the list of enumerands has changed, set the name to be the name used for the
+ // enumeration's default value
+ name = (String)newOpt.getDefaultValue();
+ }
+ configuration.setOption(tool, newOpt, idValue != null ? idValue : name);
+ break;
case IOption.STRING_LIST:
case IOption.INCLUDE_PATH:
case IOption.PREPROCESSOR_SYMBOLS:
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java
index 69360b49dc..0b0448d5ae 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java
@@ -427,6 +427,7 @@ class UpdateManagedProject20 {
break;
}
case IOption.ENUMERATED:
+ case IOption.TREE:
case IOption.STRING:{
if(optRef.hasAttribute(IOption.DEFAULT_VALUE))
configuration.setOption(tool,option,optRef.getAttribute(IOption.DEFAULT_VALUE));
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java
index fbb5c76a58..754f4920da 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java
@@ -118,7 +118,7 @@ public class SetMBSStringOptionValue extends ProcessRunner {
for (IOption option : options) {
if (option.getBaseId().toLowerCase().matches(lowerId)) {
int optionType = option.getValueType();
- if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED)) {
+ if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED) || (optionType == IOption.TREE)) {
ManagedBuildManager.setOption(resourceConfig, optionHolder, option, value);
modified = true;
}
@@ -133,7 +133,7 @@ public class SetMBSStringOptionValue extends ProcessRunner {
for (IOption option : options) {
if (option.getBaseId().toLowerCase().matches(lowerId)) {
int optionType = option.getValueType();
- if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED)) {
+ if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED) || (optionType == IOption.TREE)) {
ManagedBuildManager.setOption(config, optionHolder, option, value);
modified = true;
}
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 b940a747ef..d082e0c696 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
@@ -14,8 +14,12 @@
package org.eclipse.cdt.managedbuilder.ui.properties;
import java.io.File;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -28,6 +32,8 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IHoldsOptions;
import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler;
import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot;
import org.eclipse.cdt.managedbuilder.core.IOptionApplicability;
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.IResourceInfo;
@@ -42,18 +48,37 @@ 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.FileLocator;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FileFieldEditor;
+import org.eclipse.jface.preference.StringButtonFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
@@ -61,10 +86,13 @@ 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.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.osgi.framework.Bundle;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
/**
* Option settings page in project properties Build Settings under Tool Settings tab.
@@ -87,6 +115,35 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
** currently set to Enter rather than Hover since the former seems more responsive **/
private final static int selectAction = SWT.MouseEnter;
+ private final class TreeBrowseFieldEditor extends StringButtonFieldEditor {
+ private final String nameStr;
+ private final IOption option;
+ private String contextId;
+
+ private TreeBrowseFieldEditor(String name, String labelText, Composite parent, String nameStr,
+ IOption option, String contextId) {
+ super(name, labelText, parent);
+ this.nameStr = nameStr;
+ this.option = option;
+ this.contextId = contextId;
+ }
+
+ @Override
+ protected String changePressed() {
+ ITreeRoot treeRoot;
+ try {
+ treeRoot = option.getTreeRoot();
+ TreeSelectionDialog dlg = new TreeSelectionDialog(getShell(), treeRoot, nameStr, contextId);
+ if (dlg.open() == Window.OK) {
+ ITreeOption selected = dlg.getSelection();
+ return selected.getName();
+ }
+ } catch (BuildException e) {
+ }
+ return null;
+ }
+ }
+
private class TipInfo {
private String name;
private String tip;
@@ -212,7 +269,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
if (applicabilityCalculator == null || applicabilityCalculator.isOptionVisible(config, holder, opt)) {
String optId = getToolSettingsPrefStore().getOptionId(opt);
- String nameStr = TextProcessor.process(opt.getName());
+ final String nameStr = TextProcessor.process(opt.getName());
String tipStr = TextProcessor.process(opt.getToolTip());
String contextId = opt.getContextId();
@@ -374,6 +431,20 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
}
} break;
+ case IOption.TREE:
+ fieldEditor = new TreeBrowseFieldEditor(optId, nameStr, fieldEditorParent, nameStr, opt, contextId);
+ ((StringButtonFieldEditor)fieldEditor).setChangeButtonText("..."); //$NON-NLS-1$
+
+ if (pageHasToolTipBox) {
+ Text text = ((StringButtonFieldEditor)fieldEditor).getTextControl(fieldEditorParent);
+ Label label = fieldEditor.getLabelControl(fieldEditorParent);
+ text.setData(new TipInfo(nameStr,tipStr));
+ text.addListener(selectAction, tipSetListener);
+ label.setData(new TipInfo(nameStr,tipStr));
+ label.addListener(selectAction, tipSetListener);
+ }
+ break;
+
case IOption.INCLUDE_PATH:
case IOption.STRING_LIST:
case IOption.PREPROCESSOR_SYMBOLS:
@@ -563,8 +634,9 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
// }
break;
case IOption.ENUMERATED :
+ case IOption.TREE :
String enumVal = clonedOption.getStringValue();
- String enumId = clonedOption.getEnumeratedId(enumVal);
+ String enumId = clonedOption.getId(enumVal);
setOption = ManagedBuildManager.setOption(realCfg, realHolder, realOption,
(enumId != null && enumId.length() > 0) ? enumId : enumVal);
// Reset the preference store since the Id may have changed
@@ -757,6 +829,15 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
}
break;
+ case IOption.TREE:
+ if(fe instanceof TreeBrowseFieldEditor){
+ String name = ((TreeBrowseFieldEditor)fe).getStringValue();
+ String treeId = changedOption.getId(name);
+ ManagedBuildManager.setOption(fInfo,changedHolder,changedOption,
+ (treeId != null && treeId.length() > 0) ? treeId : name);
+
+ }
+ break;
case IOption.INCLUDE_PATH:
case IOption.STRING_LIST:
case IOption.PREPROCESSOR_SYMBOLS:
@@ -1004,5 +1085,237 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
}
}
+ /**
+ * @since 8.1
+ */
+ public static class TreeSelectionDialog extends TitleAreaDialog {
+ private final ITreeRoot treeRoot;
+ private ITreeOption selected;
+ private final String name;
+ private String contextId;
+ private String baseMessage = ""; //$NON-NLS-1$
+
+ public TreeSelectionDialog(Shell parentShell, ITreeRoot root, String name, String contextId) {
+ super(parentShell);
+ treeRoot = root;
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ if (root.getIcon() != null) {
+ Image img = createImage(root.getIcon());
+ if (img != null) {
+ setTitleImage(img);
+ }
+ }
+ this.name = name;
+ this.contextId = contextId;
+ if (contextId != null && contextId.length() > 0) {
+ setHelpAvailable(true);
+ }
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ if (contextId != null && contextId.length() > 0) {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, contextId);
+ }
+
+ Composite control = new Composite(parent, SWT.NULL);
+ GridData gd= new GridData(GridData.FILL_BOTH);
+ GridLayout topLayout = new GridLayout();
+ topLayout.numColumns = 1;
+ control.setLayout(topLayout);
+ control.setLayoutData(gd);
+
+ PatternFilter filter = new PatternFilter();
+ filter.setIncludeLeadingWildcard(true);
+ FilteredTree tree = new FilteredTree(control,
+ SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER,
+ filter, true);
+ final TreeViewer viewer = tree.getViewer();
+ viewer.setContentProvider(new ITreeContentProvider() {
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof ITreeOption) {
+ ITreeOption[] children = ((ITreeOption)parentElement).getChildren();
+
+ // Not entirely sure whether this method is allowed to return null,
+ // but let's play safe.
+ if (children == null)
+ return null;
+
+ List<ITreeOption> childrenList = new ArrayList<ITreeOption>(Arrays.asList(children));
+
+ // Check if any of the children has empty name
+ List<ITreeOption> toRemove = null;
+ for (ITreeOption child : children) {
+ if (child.getName() == null || child.getName().trim().length() == 0) {
+ if (toRemove == null) {
+ toRemove = new ArrayList<ITreeOption>();
+ }
+ toRemove.add(child);
+ }
+ }
+ if (toRemove != null) {
+ childrenList.removeAll(toRemove);
+ }
+
+ // Sort the children.
+ Collections.sort(childrenList, new Comparator<ITreeOption>() {
+ @Override
+ public int compare(ITreeOption arg0, ITreeOption arg1) {
+ if (arg0.getOrder() == arg1.getOrder()) {
+ return arg0.getName().compareToIgnoreCase(arg1.getName());
+ } else {
+ return arg0.getOrder() - arg1.getOrder();
+ }
+ }
+ });
+
+ return childrenList.toArray(new ITreeOption[0]);
+ }
+ return null;
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ if (element instanceof ITreeOption) {
+ return ((ITreeOption)element).getParent();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ Object[] children = getChildren(element);
+ return children != null && children.length > 0;
+ }
+
+ });
+
+ viewer.setLabelProvider(new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof ITreeOption) {
+ return ((ITreeOption)element).getName();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof ITreeOption) {
+ String icon = ((ITreeOption)element).getIcon();
+ return createImage(icon);
+ }
+ return super.getImage(element);
+ }
+ });
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Object selectedObj = ((IStructuredSelection)selection).getFirstElement();
+ if (selectedObj instanceof ITreeOption) {
+ selected = (ITreeOption) selectedObj;
+
+ updateOKButton(selected);
+
+ // Adjust Message
+ String description = selected.getDescription();
+ if (description == null) {
+ ITreeOption node = selected;
+ description = ""; //$NON-NLS-1$
+ String sep = ": "; //$NON-NLS-1$
+ while (node != null && node.getParent() != null) { // ignore root
+ description = sep + node.getName() + description;
+ node = node.getParent();
+ }
+ description = description.substring(sep.length()); // remove the first separator.
+ }
+ setMessage(baseMessage + description);
+ }
+ }
+ }
+ });
+
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ ISelection selection = event.getSelection();
+ if (!selection.isEmpty() && selection instanceof IStructuredSelection && ((IStructuredSelection)selection).size() == 1) {
+ Object selectedNode = ((IStructuredSelection)selection).getFirstElement();
+ if (selectedNode instanceof ITreeOption) {
+ if (updateOKButton((ITreeOption)selectedNode)) {
+ TreeSelectionDialog.this.okPressed();
+ } else { // if doubleclick is not on selectable item, expand/collapse
+ viewer.setExpandedState(selectedNode,!viewer.getExpandedState(selectedNode));
+ }
+ }
+ }
+ }
+ });
+
+ viewer.setInput(treeRoot);
+
+ String msg = "Select " + name; //$NON-NLS-1$
+ getShell().setText(msg);
+ setTitle(msg);
+ if (treeRoot.getDescription() != null) {
+ baseMessage = treeRoot.getDescription();
+ setMessage(baseMessage);
+ baseMessage += "\nCurrent Selection: "; //$NON-NLS-1$
+ } else {
+ setMessage(msg);
+ }
+
+ return control;
+ }
+
+ public ITreeOption getSelection() {
+ return selected;
+ }
+
+ private Image createImage(String icon) {
+ if (icon != null) {
+ URL url = null;
+ try {
+ url = FileLocator.find(new URL(icon));
+ } catch (Exception e) {
+ }
+ if (url != null) {
+ ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+ return desc.createImage();
+ }
+ }
+ return null;
+ }
+ private boolean updateOKButton(ITreeOption selection) {
+ // Check if Valid selection (only allow selecting leaf nodes)
+ if (treeRoot.isSelectLeafsOnly()) {
+ boolean enableOK = !selection.isContainer();
+ getButton(IDialogConstants.OK_ID).setEnabled(enableOK);
+ return enableOK;
+ }
+ return false;
+ }
+ }
}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java
index 685cf46fee..547d4d61f8 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java
@@ -20,6 +20,7 @@ import java.util.Vector;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot;
import org.eclipse.cdt.managedbuilder.core.IResourceInfo;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.internal.core.MultiResourceInfo;
@@ -316,6 +317,20 @@ public class BuildToolSettingUI extends AbstractToolSettingUI {
if (!enumeration.equals("")) //$NON-NLS-1$
setOption(opt, enumeration);
break;
+ case IOption.TREE :
+ String selectedID = ""; //$NON-NLS-1$
+ ITreeRoot treeRoot = opt.getTreeRoot();
+ String[] treeValues = opt.getApplicableValues();
+ for (int i = 0; i < treeValues.length; i++) {
+ if (opt.getCommand(treeValues[i]).equals(
+ optionValue)) {
+ selectedID = treeValues[i];
+ optionValueExist = true;
+ }
+ }
+ if (!selectedID.equals("")) //$NON-NLS-1$
+ setOption(opt, selectedID);
+ break;
case IOption.STRING_LIST :
case IOption.INCLUDE_PATH :
case IOption.PREPROCESSOR_SYMBOLS :
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java
index f1f0ec3eae..dd5c356a01 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java
@@ -205,8 +205,8 @@ public class ToolSettingsPrefStore implements IPreferenceStore {
try {
IOption opt = (IOption)option[1];
Object val = opt.getValue();
- if(opt.getValueType() == IOption.ENUMERATED && val instanceof String)
- val = opt.getEnumName((String)val);
+ if((opt.getValueType() == IOption.ENUMERATED || opt.getValueType() == IOption.TREE) && val instanceof String)
+ val = opt.getName((String)val);
return val;
} catch (BuildException e) {
}
@@ -313,9 +313,10 @@ public class ToolSettingsPrefStore implements IPreferenceStore {
}
break;
case IOption.ENUMERATED:
+ case IOption.TREE:
if(value instanceof String){
String val = (String)value;
- String enumId = option.getEnumeratedId(val);
+ String enumId = option.getId(val);
newOption = rcInfo.setOption(holder, option,
(enumId != null && enumId.length() > 0) ? enumId : val);
}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java
index db5056087e..a6e7dabb92 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java
@@ -568,8 +568,9 @@ public class ToolSettingsTab extends AbstractCBuildPropertyTab implements IPrefe
ManagedBuildManager.setOption(res, dst, op2, boolVal);
break;
case IOption.ENUMERATED :
+ case IOption.TREE :
String enumVal = op1.getStringValue();
- String enumId = op1.getEnumeratedId(enumVal);
+ String enumId = op1.getId(enumVal);
String out = (enumId != null && enumId.length() > 0) ? enumId : enumVal;
ManagedBuildManager.setOption(res, dst, op2, out);
break;

Back to the top