diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java new file mode 100644 index 000000000..b7bab1bd3 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008 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.menu.descriptors; + +import static com.android.SdkConstants.ANDROID_NS_NAME; +import static com.android.SdkConstants.ANDROID_URI; +import static com.android.SdkConstants.TAG_MENU; + +import com.android.ide.common.resources.platform.DeclareStyleableInfo; +import com.android.ide.eclipse.adt.AdtUtils; +import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; +import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; +import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; + +import java.util.ArrayList; +import java.util.Map; + +/** + * Complete description of the menu structure. + */ +public final class MenuDescriptors implements IDescriptorProvider { + + /** The root element descriptor. */ + private ElementDescriptor mDescriptor = null; + + /** @return the root descriptor. */ + @Override + public ElementDescriptor getDescriptor() { + return mDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mDescriptor.getChildren(); + } + + /** + * Updates the document descriptor. + * <p/> + * It first computes the new children of the descriptor and then updates them + * all at once. + * + * @param styleMap The map style => attributes from the attrs.xml file + */ + public synchronized void updateDescriptors(Map<String, DeclareStyleableInfo> styleMap) { + + // There are 3 elements: menu, item and group. + // The root element MUST be a menu. + // A top menu can contain items or group: + // - top groups can contain top items + // - top items can contain sub-menus + // A sub menu can contains sub items or sub groups: + // - sub groups can contain sub items + // - sub items cannot contain anything + + if (mDescriptor == null) { + mDescriptor = createElement(styleMap, + TAG_MENU, // xmlName + "Menu", // uiName, + null, // TODO SDK URL + null, // extraAttribute + null, // childrenElements, + true /* mandatory */); + } + + // -- sub menu can have sub_items, sub_groups but not sub_menus + + ElementDescriptor sub_item = createElement(styleMap, + "item", // xmlName //$NON-NLS-1$ + "Item", // uiName, + null, // TODO SDK URL + null, // extraAttribute + null, // childrenElements, + false /* mandatory */); + + ElementDescriptor sub_group = createElement(styleMap, + "group", // xmlName //$NON-NLS-1$ + "Group", // uiName, + null, // TODO SDK URL + null, // extraAttribute + new ElementDescriptor[] { sub_item }, // childrenElements, + false /* mandatory */); + + ElementDescriptor sub_menu = createElement(styleMap, + TAG_MENU, // xmlName + "Sub-Menu", // uiName, + null, // TODO SDK URL + null, // extraAttribute + new ElementDescriptor[] { sub_item, sub_group }, // childrenElements, + true /* mandatory */); + + // -- top menu can have all top groups and top items (which can have sub menus) + + ElementDescriptor top_item = createElement(styleMap, + "item", // xmlName //$NON-NLS-1$ + "Item", // uiName, + null, // TODO SDK URL + null, // extraAttribute + new ElementDescriptor[] { sub_menu }, // childrenElements, + false /* mandatory */); + + ElementDescriptor top_group = createElement(styleMap, + "group", // xmlName //$NON-NLS-1$ + "Group", // uiName, + null, // TODO SDK URL + null, // extraAttribute + new ElementDescriptor[] { top_item }, // childrenElements, + false /* mandatory */); + + XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME, + ANDROID_URI); + + updateElement(mDescriptor, styleMap, "Menu", xmlns); //$NON-NLS-1$ + mDescriptor.setChildren(new ElementDescriptor[] { top_item, top_group }); + } + + /** + * Returns a new ElementDescriptor constructed from the information given here + * and the javadoc & attributes extracted from the style map if any. + */ + private ElementDescriptor createElement( + Map<String, DeclareStyleableInfo> styleMap, + String xmlName, String uiName, String sdkUrl, + AttributeDescriptor extraAttribute, + ElementDescriptor[] childrenElements, boolean mandatory) { + + ElementDescriptor element = new ElementDescriptor(xmlName, uiName, null, sdkUrl, + null, childrenElements, mandatory); + + return updateElement(element, styleMap, + getStyleName(xmlName), + extraAttribute); + } + + /** + * Updates an ElementDescriptor with the javadoc & attributes extracted from the style + * map if any. + */ + private ElementDescriptor updateElement(ElementDescriptor element, + Map<String, DeclareStyleableInfo> styleMap, + String styleName, + AttributeDescriptor extraAttribute) { + ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>(); + + DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null; + if (style != null) { + DescriptorsUtils.appendAttributes(descs, + null, // elementName + ANDROID_URI, + style.getAttributes(), + null, // requiredAttributes + null); // overrides + element.setTooltip(style.getJavaDoc()); + } + + if (extraAttribute != null) { + descs.add(extraAttribute); + } + + element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()])); + return element; + } + + /** + * Returns the style name (i.e. the <declare-styleable> name found in attrs.xml) + * for a given XML element name. + * <p/> + * The rule is that all elements have for style name: + * - their xml name capitalized + * - a "Menu" prefix, except for <menu> itself which is just "Menu". + */ + private String getStyleName(String xmlName) { + String styleName = AdtUtils.capitalize(xmlName); + + // This is NOT the UI Name but the expected internal style name + final String MENU_STYLE_BASE_NAME = "Menu"; //$NON-NLS-1$ + + if (!styleName.equals(MENU_STYLE_BASE_NAME)) { + styleName = MENU_STYLE_BASE_NAME + styleName; + } + return styleName; + } +} |