diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java new file mode 100644 index 000000000..a320b682d --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2012 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.layout.properties; + +import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN; +import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.ide.common.api.IAttributeInfo; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor; +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.layout.gle2.GraphicalEditorPart; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ViewHierarchy; +import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; + +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.wb.internal.core.model.property.Property; +import org.eclipse.wb.internal.core.model.property.editor.PropertyEditor; +import org.eclipse.wb.internal.core.model.property.table.PropertyTooltipProvider; +import org.eclipse.wb.internal.core.model.property.table.PropertyTooltipTextProvider; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +import java.util.Map; + +/** + * An Android XML property + */ +class XmlProperty extends Property { + private PropertyFactory mFactory; + final AttributeDescriptor mDescriptor; + private UiViewElementNode mNode; + private Property mParent; + + XmlProperty( + @NonNull PropertyEditor editor, + @NonNull PropertyFactory factory, + @NonNull UiViewElementNode node, + @NonNull AttributeDescriptor descriptor) { + super(editor); + mFactory = factory; + mNode = node; + mDescriptor = descriptor; + } + + @NonNull + public PropertyFactory getFactory() { + return mFactory; + } + + @NonNull + public UiViewElementNode getNode() { + return mNode; + } + + @NonNull + public AttributeDescriptor getDescriptor() { + return mDescriptor; + } + + @Override + @NonNull + public String getName() { + return mDescriptor.getXmlLocalName(); + } + + @Override + @NonNull + public String getTitle() { + String name = mDescriptor.getXmlLocalName(); + int nameLength = name.length(); + + if (name.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) { + if (name.startsWith(ATTR_LAYOUT_MARGIN) + && nameLength > ATTR_LAYOUT_MARGIN.length()) { + name = name.substring(ATTR_LAYOUT_MARGIN.length()); + } else { + name = name.substring(ATTR_LAYOUT_RESOURCE_PREFIX.length()); + } + } + + // Capitalize + name = DescriptorsUtils.capitalize(name); + + // If we're nested within a complex property, say "Line Spacing", don't + // include "Line Spacing " as a prefix for each property here + if (mParent != null) { + String parentTitle = mParent.getTitle(); + if (name.startsWith(parentTitle)) { + int parentTitleLength = parentTitle.length(); + if (parentTitleLength < nameLength) { + if (nameLength > parentTitleLength && + Character.isWhitespace(name.charAt(parentTitleLength))) { + parentTitleLength++; + } + name = name.substring(parentTitleLength); + } + } + } + + return name; + } + + @Override + public <T> T getAdapter(Class<T> adapter) { + // tooltip + if (adapter == PropertyTooltipProvider.class) { + return adapter.cast(new PropertyTooltipTextProvider() { + @Override + protected String getText(Property p) throws Exception { + if (mDescriptor instanceof IPropertyDescriptor) { + IPropertyDescriptor d = (IPropertyDescriptor) mDescriptor; + return d.getDescription(); + } + + return null; + } + }); + } else if (adapter == IContentProposalProvider.class) { + IAttributeInfo info = mDescriptor.getAttributeInfo(); + if (info != null) { + return adapter.cast(new PropertyValueCompleter(this)); + } + // Fallback: complete values on resource values + return adapter.cast(new ResourceValueCompleter(this)); + } else if (adapter == ILabelProvider.class) { + return adapter.cast(new LabelProvider() { + @Override + public Image getImage(Object element) { + return AdtPlugin.getAndroidLogo(); + } + + @Override + public String getText(Object element) { + return ((IContentProposal) element).getLabel(); + } + }); + } + return super.getAdapter(adapter); + } + + @Override + public boolean isModified() throws Exception { + Object s = null; + try { + Element element = (Element) mNode.getXmlNode(); + if (element == null) { + return false; + } + String name = mDescriptor.getXmlLocalName(); + String uri = mDescriptor.getNamespaceUri(); + if (uri != null) { + return element.hasAttributeNS(uri, name); + } else { + return element.hasAttribute(name); + } + } catch (Exception e) { + // pass + } + return s != null && s.toString().length() > 0; + } + + @Nullable + public String getStringValue() { + Element element = (Element) mNode.getXmlNode(); + if (element == null) { + return null; + } + String name = mDescriptor.getXmlLocalName(); + String uri = mDescriptor.getNamespaceUri(); + Attr attr; + if (uri != null) { + attr = element.getAttributeNodeNS(uri, name); + } else { + attr = element.getAttributeNode(name); + } + if (attr != null) { + return attr.getValue(); + } + + Object viewObject = getFactory().getCurrentViewObject(); + if (viewObject != null) { + GraphicalEditorPart graphicalEditor = getGraphicalEditor(); + if (graphicalEditor == null) { + return null; + } + ViewHierarchy views = graphicalEditor.getCanvasControl().getViewHierarchy(); + Map<String, String> defaultProperties = views.getDefaultProperties(viewObject); + if (defaultProperties != null) { + return defaultProperties.get(name); + } + } + + return null; + } + + @Override + @Nullable + public Object getValue() throws Exception { + return getStringValue(); + } + + @Override + public void setValue(Object value) throws Exception { + CommonXmlEditor editor = getXmlEditor(); + if (editor == null) { + return; + } + final String attribute = mDescriptor.getXmlLocalName(); + final String xmlValue = value != null && value != UNKNOWN_VALUE ? value.toString() : null; + editor.wrapUndoEditXmlModel( + String.format("Set \"%1$s\" to \"%2$s\"", attribute, xmlValue), + new Runnable() { + @Override + public void run() { + mNode.setAttributeValue(attribute, + mDescriptor.getNamespaceUri(), xmlValue, true /*override*/); + mNode.commitDirtyAttributesToXml(); + } + }); + } + + @Override + @NonNull + public Property getComposite(Property[] properties) { + return XmlPropertyComposite.create(properties); + } + + @Nullable + GraphicalEditorPart getGraphicalEditor() { + return mFactory.getGraphicalEditor(); + } + + @Nullable + CommonXmlEditor getXmlEditor() { + GraphicalEditorPart graphicalEditor = getGraphicalEditor(); + if (graphicalEditor != null) { + return graphicalEditor.getEditorDelegate().getEditor(); + } + + return null; + } + + @Nullable + public Property getParent() { + return mParent; + } + + public void setParent(@Nullable Property parent) { + mParent = parent; + } + + @Override + public String toString() { + return getName() + ":" + getPriority(); + } +} |