diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java new file mode 100644 index 000000000..0fd317c1c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2007 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.uimodel; + +import com.android.SdkConstants; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; +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.ListAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; +import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.TableWrapData; + +/** + * Represents an XML attribute which has possible built-in values, and can be modified by + * an editable Combo box. + * <p/> + * See {@link UiTextAttributeNode} for more information. + */ +public class UiListAttributeNode extends UiAbstractTextAttributeNode { + + protected Combo mCombo; + + public UiListAttributeNode(ListAttributeDescriptor attributeDescriptor, + UiElementNode uiParent) { + super(attributeDescriptor, uiParent); + } + + /* (non-java doc) + * Creates a label widget and an associated text field. + * <p/> + * As most other parts of the android manifest editor, this assumes the + * parent uses a table layout with 2 columns. + */ + @Override + public final void createUiControl(final Composite parent, IManagedForm managedForm) { + FormToolkit toolkit = managedForm.getToolkit(); + TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor(); + + Label label = toolkit.createLabel(parent, desc.getUiName()); + label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE)); + SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip())); + + int style = SWT.DROP_DOWN; + mCombo = new Combo(parent, style); + TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE); + twd.maxWidth = 100; + mCombo.setLayoutData(twd); + + fillCombo(); + + setTextWidgetValue(getCurrentValue()); + + mCombo.addModifyListener(new ModifyListener() { + /** + * Sent when the text is modified, whether by the user via manual + * input or programmatic input via setText(). + */ + @Override + public void modifyText(ModifyEvent e) { + onComboChange(); + } + }); + + mCombo.addSelectionListener(new SelectionAdapter() { + /** Sent when the text is changed from a list selection. */ + @Override + public void widgetSelected(SelectionEvent e) { + onComboChange(); + } + }); + + // Remove self-reference when the widget is disposed + mCombo.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + mCombo = null; + } + }); + } + + protected void fillCombo() { + String[] values = getPossibleValues(null); + + if (values == null) { + AdtPlugin.log(IStatus.ERROR, + "FrameworkResourceManager did not provide values yet for %1$s", + getDescriptor().getXmlLocalName()); + } else { + for (String value : values) { + mCombo.add(value); + } + } + } + + /** + * Get the list values, either from the initial values set in the attribute + * or by querying the framework resource parser. + * + * {@inheritDoc} + */ + @Override + public String[] getPossibleValues(String prefix) { + AttributeDescriptor descriptor = getDescriptor(); + UiElementNode uiParent = getUiParent(); + + String attr_name = descriptor.getXmlLocalName(); + String element_name = uiParent.getDescriptor().getXmlName(); + + // FrameworkResourceManager expects a specific prefix for the attribute. + String nsPrefix = ""; + if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) { + nsPrefix = SdkConstants.ANDROID_NS_NAME + ':'; + } else if (SdkConstants.XMLNS_URI.equals(descriptor.getNamespaceUri())) { + nsPrefix = SdkConstants.XMLNS_PREFIX; + } + attr_name = nsPrefix + attr_name; + + String[] values = null; + + if (descriptor instanceof ListAttributeDescriptor && + ((ListAttributeDescriptor) descriptor).getValues() != null) { + // Get enum values from the descriptor + values = ((ListAttributeDescriptor) descriptor).getValues(); + } + + if (values == null) { + // or from the AndroidTargetData + UiElementNode uiNode = getUiParent(); + AndroidXmlEditor editor = uiNode.getEditor(); + AndroidTargetData data = editor.getTargetData(); + if (data != null) { + // get the great-grand-parent descriptor. + + // the parent should always exist. + UiElementNode grandParentNode = uiParent.getUiParent(); + + String greatGrandParentNodeName = null; + if (grandParentNode != null) { + UiElementNode greatGrandParentNode = grandParentNode.getUiParent(); + if (greatGrandParentNode != null) { + greatGrandParentNodeName = + greatGrandParentNode.getDescriptor().getXmlName(); + } + } + + values = data.getAttributeValues(element_name, attr_name, greatGrandParentNodeName); + } + } + + return values; + } + + @Override + public String getTextWidgetValue() { + if (mCombo != null) { + return mCombo.getText(); + } + + return null; + } + + @Override + public final boolean isValid() { + return mCombo != null; + } + + @Override + public void setTextWidgetValue(String value) { + if (mCombo != null) { + mCombo.setText(value); + } + } + + /** + * Handles Combo change, either from text edit or from selection change. + * <p/> + * Simply mark the attribute as dirty if it really changed. + * The container SectionPart will collect these flag and manage them. + */ + private void onComboChange() { + if (!isInInternalTextModification() && + !isDirty() && + mCombo != null && + getCurrentValue() != null && + !mCombo.getText().equals(getCurrentValue())) { + setDirty(true); + } + } +} |