From 6f49708d1896bcde13ce6bea0b2a704a5de115df Mon Sep 17 00:00:00 2001 From: Raphael Date: Fri, 12 Mar 2010 15:23:51 -0800 Subject: [PATCH] ADT GLE: treat all unknown layout XML nodes as base View objects. This adds an interface that UIElementNode queries when it needs to treat an unknown XML local name. The default is to create ElementDescriptors, but layout overrides this to deal with custom view and to create base View descriptors by default. Change-Id: I639fb169a6b1b53b28715c88f9a037426d7ca88f --- .../descriptors/IUnknownDescriptorProvider.java | 38 ++++++++++ .../adt/internal/editors/layout/LayoutEditor.java | 80 +++++++++++++++++++++ .../descriptors/CustomViewDescriptorService.java | 10 +-- .../layout/descriptors/LayoutDescriptors.java | 29 +++++++- .../layout/descriptors/ViewElementDescriptor.java | 2 - .../descriptors/ResourcesDescriptors.java | 30 ++++---- .../internal/editors/uimodel/UiElementNode.java | 83 +++++++++++++++++----- 7 files changed, 231 insertions(+), 41 deletions(-) create mode 100755 eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IUnknownDescriptorProvider.java diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IUnknownDescriptorProvider.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IUnknownDescriptorProvider.java new file mode 100755 index 000000000..2a750efb7 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IUnknownDescriptorProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.editors.descriptors; + +import com.android.ide.eclipse.adt.internal.editors.resources.uimodel.UiItemElementNode; + +/** + * {@link UiItemElementNode} is the main class that creates the UI Model hierarchy based + * on an XML DOM hierarchy, matching XML names to the {@link ElementDescriptor} names. + *

+ * This interface declares a provider that can provide an {@link ElementDescriptor} + * for an unknown XML local name. + */ +public interface IUnknownDescriptorProvider { + + /** + * Returns an instance of {@link ElementDescriptor} matching the given XML Local Name. + * + * @param xmlLocalName The XML local name. + * @return A new or existing {@link ElementDescriptor} or derived instance. Must not be null. + */ + ElementDescriptor getDescriptor(String xmlLocalName); + +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java index 25337645a..c407ff9cf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java @@ -20,6 +20,10 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.AndroidEditor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.IUnknownDescriptorProvider; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.CustomViewDescriptorService; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.layout.gle1.GraphicalLayoutEditor; import com.android.ide.eclipse.adt.internal.editors.layout.gle1.UiContentOutlinePage; import com.android.ide.eclipse.adt.internal.editors.layout.gle1.UiPropertySheetPage; @@ -28,15 +32,19 @@ import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiActions; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; +import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.internal.ui.EclipseUiHelper; +import com.android.sdklib.IAndroidTarget; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.gef.ui.parts.TreeViewer; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IShowEditorInput; import org.eclipse.ui.IWorkbenchPage; @@ -48,6 +56,8 @@ import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.w3c.dom.Document; +import java.util.HashMap; + /** * Multi-page form editor for /res/layout XML files. */ @@ -67,6 +77,10 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa private UiEditorActions mUiEditorActions; + private final HashMap mUnknownDescriptorMap = + new HashMap(); + + /** * Flag indicating if the replacement file is due to a config change. * If false, it means the new file is due to an "open action" from the user. @@ -412,11 +426,77 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa mUiRootNode = (UiDocumentNode) desc.createUiNode(); mUiRootNode.setEditor(this); + mUiRootNode.setUnknownDescriptorProvider(new IUnknownDescriptorProvider() { + + public ElementDescriptor getDescriptor(String xmlLocalName) { + + ElementDescriptor desc = mUnknownDescriptorMap.get(xmlLocalName); + + if (desc == null) { + desc = createUnknownDescriptor(xmlLocalName); + mUnknownDescriptorMap.put(xmlLocalName, desc); + } + + return desc; + } + }); + onDescriptorsChanged(doc); } } + /** + * Creates a new {@link ElementDescriptor} for an unknown XML local name + * (i.e. one that was not mapped by the current descriptors). + *

+ * Since we deal with layouts, we returns either a descriptor for a custom view + * or one for the base View. + * + * @param xmlLocalName The XML local name to match. + * @return A non-null {@link ElementDescriptor}. + */ + private ElementDescriptor createUnknownDescriptor(String xmlLocalName) { + IEditorInput editorInput = getEditorInput(); + if (editorInput instanceof IFileEditorInput) { + IFileEditorInput fileInput = (IFileEditorInput)editorInput; + IProject project = fileInput.getFile().getProject(); + + // Check if we can find a custom view specific to this project. + ElementDescriptor desc = CustomViewDescriptorService.getInstance().getDescriptor( + project, xmlLocalName); + + if (desc != null) { + return desc; + } + + // If we didn't find a custom view, reuse the base View descriptor. + // This is a layout after all, so every XML node should represent + // a view. + + Sdk currentSdk = Sdk.getCurrent(); + if (currentSdk != null) { + IAndroidTarget target = currentSdk.getTarget(project); + if (target != null) { + AndroidTargetData data = currentSdk.getTargetData(target); + desc = data.getLayoutDescriptors().getBaseViewDescriptor(); + } + } + + if (desc != null) { + return desc; + } + } + + // We get here if the editor input is not of the right type or if the + // SDK hasn't finished loading. In either case, return something just + // because we should not return null. + return new ViewElementDescriptor(xmlLocalName, xmlLocalName); + } + private void onDescriptorsChanged(Document document) { + + mUnknownDescriptorMap.clear(); + if (document != null) { mUiRootNode.loadFromXmlNode(document); } else { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java index 72fee7489..3ba530310 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java @@ -198,10 +198,12 @@ public final class CustomViewDescriptorService { List builtInList = null; Sdk currentSdk = Sdk.getCurrent(); - IAndroidTarget target = currentSdk == null ? null : currentSdk.getTarget(project); - if (target != null) { - AndroidTargetData data = currentSdk.getTargetData(target); - builtInList = data.getLayoutDescriptors().getViewDescriptors(); + if (currentSdk != null) { + IAndroidTarget target = currentSdk.getTarget(project); + if (target != null) { + AndroidTargetData data = currentSdk.getTargetData(target); + builtInList = data.getLayoutDescriptors().getViewDescriptors(); + } } // give up if there's no type diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java index 19d93f8c0..04ac83366 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java @@ -60,17 +60,20 @@ public final class LayoutDescriptors implements IDescriptorProvider { /** Read-Only list of View Descriptors. */ private List mROViewDescriptors; - /** @return the document descriptor. Contains all layouts and views linked together. */ + /** The descriptor matching android.view.View. */ + private ElementDescriptor mBaseViewDescriptor; + + /** Returns the document descriptor. Contains all layouts and views linked together. */ public DocumentDescriptor getDescriptor() { return mRootDescriptor; } - /** @return The read-only list of all known ViewLayout descriptors. */ + /** Returns the read-only list of all known ViewLayout descriptors. */ public List getLayoutDescriptors() { return mROLayoutDescriptors; } - /** @return The read-only list of all known View (not ViewLayout) descriptors. */ + /** Returns the read-only list of all known View (not ViewLayout) descriptors. */ public List getViewDescriptors() { return mROViewDescriptors; } @@ -80,6 +83,25 @@ public final class LayoutDescriptors implements IDescriptorProvider { } /** + * Returns the descriptor matching android.view.View. + */ + public ElementDescriptor getBaseViewDescriptor() { + if (mBaseViewDescriptor == null) { + for (ElementDescriptor desc : mViewDescriptors) { + if (desc instanceof ViewElementDescriptor) { + ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc; + if (AndroidConstants.CLASS_VIEW.equals(viewDesc.getFullClassName())) { + mBaseViewDescriptor = viewDesc; + break; + } + } + + } + } + return mBaseViewDescriptor; + } + + /** * Updates the document descriptor. *

* It first computes the new children of the descriptor and then update them @@ -140,6 +162,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { mLayoutDescriptors = newLayouts; mRootDescriptor.setChildren(newDescriptors); + mBaseViewDescriptor = null; mROLayoutDescriptors = Collections.unmodifiableList(mLayoutDescriptors); mROViewDescriptors = Collections.unmodifiableList(mViewDescriptors); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java index c579edbf2..be81f5478 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java @@ -134,8 +134,6 @@ public final class ViewElementDescriptor extends ElementDescriptor { * @param xml_name The XML element node name. Case sensitive. * @param fullClassName The fully qualified class name the {@link ViewElementDescriptor} is * representing. - * - * @deprecated Never used. We should clean it up someday. */ public ViewElementDescriptor(String xml_name, String fullClassName) { super(xml_name); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java index 8fa8a94be..1b055b107 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java @@ -29,7 +29,7 @@ import com.android.ide.eclipse.adt.internal.resources.ResourceType; /** * Complete description of the structure for resources XML files (under res/values/) */ -public class ResourcesDescriptors implements IDescriptorProvider { +public final class ResourcesDescriptors implements IDescriptorProvider { // Public attributes names, attributes descriptors and elements descriptors @@ -46,22 +46,22 @@ public class ResourcesDescriptors implements IDescriptorProvider { public static ResourcesDescriptors getInstance() { return sThis; } - + /* * @see com.android.ide.eclipse.editors.descriptors.IDescriptorProvider#getRootElementDescriptors() */ public ElementDescriptor[] getRootElementDescriptors() { return new ElementDescriptor[] { mResourcesElement }; } - + public ElementDescriptor getDescriptor() { return mResourcesElement; } - + public ElementDescriptor getElementDescriptor() { return mResourcesElement; } - + private ResourcesDescriptors() { // Common attributes used in many placed @@ -70,7 +70,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor color_element = new ElementDescriptor( "color", //$NON-NLS-1$ - "Color", + "Color", "A @color@ value specifies an RGB value with an alpha channel, which can be used in various places such as specifying a solid color for a Drawable or the color to use for text. It always begins with a # character and then is followed by the alpha-red-green-blue information in one of the following formats: #RGB, #ARGB, #RRGGBB or #AARRGGBB.", "http://code.google.com/android/reference/available-resources.html#colorvals", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -87,7 +87,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor string_element = new ElementDescriptor( "string", //$NON-NLS-1$ - "String", + "String", "@Strings@, with optional simple formatting, can be stored and retrieved as resources. You can add formatting to your string by using three standard HTML tags: b, i, and u. If you use an apostrophe or a quote in your string, you must either escape it or enclose the whole string in the other kind of enclosing quotes.", "http://code.google.com/android/reference/available-resources.html#stringresources", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -104,7 +104,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor item_element = new ItemElementDescriptor( "item", //$NON-NLS-1$ - "Item", + "Item", null, // TODO find javadoc null, // TODO find link to javadoc new AttributeDescriptor[] { @@ -141,7 +141,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor drawable_element = new ElementDescriptor( "drawable", //$NON-NLS-1$ - "Drawable", + "Drawable", "A @drawable@ defines a rectangle of color. Android accepts color values written in various web-style formats -- a hexadecimal constant in any of the following forms: #RGB, #ARGB, #RRGGBB, #AARRGGBB. Zero in the alpha channel means transparent. The default value is opaque.", "http://code.google.com/android/reference/available-resources.html#colordrawableresources", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -158,7 +158,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor dimen_element = new ElementDescriptor( "dimen", //$NON-NLS-1$ - "Dimension", + "Dimension", "You can create common dimensions to use for various screen elements by defining @dimension@ values in XML. A dimension resource is a number followed by a unit of measurement. Supported units are px (pixels), in (inches), mm (millimeters), pt (points at 72 DPI), dp (density-independent pixels) and sp (scale-independent pixels)", "http://code.google.com/android/reference/available-resources.html#dimension", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -175,7 +175,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { ElementDescriptor style_element = new ElementDescriptor( "style", //$NON-NLS-1$ - "Style/Theme", + "Style/Theme", "Both @styles and themes@ are defined in a style block containing one or more string or numerical values (typically color values), or references to other resources (drawables and so on).", "http://code.google.com/android/reference/available-resources.html#stylesandthemes", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -191,7 +191,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { new ElementDescriptor[] { new ElementDescriptor( "item", //$NON-NLS-1$ - "Item", + "Item", "A value to use in this @theme@. It can be a standard string, a hex color value, or a reference to any other resource type.", "http://code.google.com/android/reference/available-resources.html#stylesandthemes", //$NON-NLS-1$ new AttributeDescriptor[] { @@ -222,7 +222,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { new ElementDescriptor[] { new ElementDescriptor( "item", //$NON-NLS-1$ - "Item", + "Item", "A string value to use in this string array.", null, // tooltip new AttributeDescriptor[] { @@ -249,7 +249,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { new ElementDescriptor[] { new ElementDescriptor( "item", //$NON-NLS-1$ - "Item", + "Item", "An integer value to use in this integer array.", null, // tooltip new AttributeDescriptor[] { @@ -264,7 +264,7 @@ public class ResourcesDescriptors implements IDescriptorProvider { mResourcesElement = new ElementDescriptor( ROOT_ELEMENT, - "Resources", + "Resources", null, "http://code.google.com/android/reference/available-resources.html", //$NON-NLS-1$ null, // no attributes diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java index 73f5be14b..e56ed54d8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java @@ -20,10 +20,10 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.AndroidEditor; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.IUnknownDescriptorProvider; import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.CustomViewDescriptorService; import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors; @@ -33,8 +33,6 @@ import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; import com.android.sdklib.SdkConstants; import org.eclipse.core.runtime.IStatus; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySource; import org.w3c.dom.Attr; @@ -113,6 +111,9 @@ public class UiElementNode implements IPropertySource { /** An optional list of {@link IUiUpdateListener}. Most element nodes will not have any * listeners attached, so the list is only created on demand and can be null. */ private ArrayList mUiUpdateListeners; + /** A provider that knows how to create {@link ElementDescriptor} from unmapped XML names. + * The default is to have one that creates new {@link ElementDescriptor}. */ + private IUnknownDescriptorProvider mUnknownDescProvider; /** Error Flag */ private boolean mHasError; /** Temporary data used by the editors. This data is not sync'ed with the XML */ @@ -504,6 +505,65 @@ public class UiElementNode implements IPropertySource { } /** + * Returns the provider that knows how to create {@link ElementDescriptor} from unmapped + * XML names. + *

+ * The default is to have one that creates new {@link ElementDescriptor}. + *

+ * There is only one such provider in any UI model tree, attached to the root node. + * + * @return An instance of {@link IUnknownDescriptorProvider}. Can never be null. + */ + public IUnknownDescriptorProvider getUnknownDescriptorProvider() { + if (mUiParent != null) { + return mUiParent.getUnknownDescriptorProvider(); + } + if (mUnknownUiAttributes == null) { + // Create the default one on demand. + mUnknownDescProvider = new IUnknownDescriptorProvider() { + + private final HashMap mMap = + new HashMap(); + + /** + * The default is to create a new ElementDescriptor wrapping + * the unknown XML local name and reuse previously created descriptors. + */ + public ElementDescriptor getDescriptor(String xmlLocalName) { + + ElementDescriptor desc = mMap.get(xmlLocalName); + + if (desc == null) { + desc = new ElementDescriptor(xmlLocalName); + mMap.put(xmlLocalName, desc); + } + + return desc; + } + }; + } + return mUnknownDescProvider; + } + + /** + * Sets the provider that knows how to create {@link ElementDescriptor} from unmapped + * XML names. + *

+ * The default is to have one that creates new {@link ElementDescriptor}. + *

+ * There is only one such provider in any UI model tree, attached to the root node. + * + * @param unknownDescProvider The new provider to use. Must not be null. + */ + public void setUnknownDescriptorProvider(IUnknownDescriptorProvider unknownDescProvider) { + if (mUiParent == null) { + mUnknownDescProvider = unknownDescProvider; + } else { + mUiParent.setUnknownDescriptorProvider(unknownDescProvider); + } + } + + /** * Adds a new {@link IUiUpdateListener} to the internal update listener list. */ public void addUpdateListener(IUiUpdateListener listener) { @@ -828,20 +888,9 @@ public class UiElementNode implements IPropertySource { false /* recursive */); if (desc == null) { // Unknown node. Create a temporary descriptor for it. - // most important we want to auto-add unknown attributes to it. - AndroidEditor editor = getEditor(); - IEditorInput editorInput = editor.getEditorInput(); - if (editorInput instanceof IFileEditorInput) { - IFileEditorInput fileInput = (IFileEditorInput)editorInput; - desc = CustomViewDescriptorService.getInstance().getDescriptor( - fileInput.getFile().getProject(), element_name); - if (desc == null) { - desc = new ElementDescriptor(element_name); - } - } else { - desc = new ElementDescriptor(element_name); - // TODO associate a new "?" icon to this descriptor. - } + // We'll add unknown attributes to it later. + IUnknownDescriptorProvider p = getUnknownDescriptorProvider(); + desc = p.getDescriptor(element_name); } structure_changed = true; ui_node = appendNewUiChild(desc); -- 2.11.0