2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.eclipse.org/org/documents/epl-v10.php
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.ide.eclipse.adt.internal.editors.uimodel;
19 import com.android.ide.eclipse.adt.AdtPlugin;
20 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
21 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
22 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
23 import com.android.ide.eclipse.adt.internal.editors.descriptors.ListAttributeDescriptor;
24 import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
25 import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
26 import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
27 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
28 import com.android.sdklib.SdkConstants;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.events.DisposeEvent;
33 import org.eclipse.swt.events.DisposeListener;
34 import org.eclipse.swt.events.ModifyEvent;
35 import org.eclipse.swt.events.ModifyListener;
36 import org.eclipse.swt.events.SelectionAdapter;
37 import org.eclipse.swt.events.SelectionEvent;
38 import org.eclipse.swt.widgets.Combo;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Label;
41 import org.eclipse.ui.forms.IManagedForm;
42 import org.eclipse.ui.forms.widgets.FormToolkit;
43 import org.eclipse.ui.forms.widgets.TableWrapData;
46 * Represents an XML attribute which has possible built-in values, and can be modified by
47 * an editable Combo box.
49 * See {@link UiTextAttributeNode} for more information.
51 public class UiListAttributeNode extends UiAbstractTextAttributeNode {
53 protected Combo mCombo;
55 public UiListAttributeNode(ListAttributeDescriptor attributeDescriptor,
56 UiElementNode uiParent) {
57 super(attributeDescriptor, uiParent);
61 * Creates a label widget and an associated text field.
63 * As most other parts of the android manifest editor, this assumes the
64 * parent uses a table layout with 2 columns.
67 public final void createUiControl(final Composite parent, IManagedForm managedForm) {
68 FormToolkit toolkit = managedForm.getToolkit();
69 TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
71 Label label = toolkit.createLabel(parent, desc.getUiName());
72 label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
73 SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip()));
75 int style = SWT.DROP_DOWN;
76 mCombo = new Combo(parent, style);
77 TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE);
79 mCombo.setLayoutData(twd);
83 setTextWidgetValue(getCurrentValue());
85 mCombo.addModifyListener(new ModifyListener() {
87 * Sent when the text is modified, whether by the user via manual
88 * input or programmatic input via setText().
90 public void modifyText(ModifyEvent e) {
95 mCombo.addSelectionListener(new SelectionAdapter() {
96 /** Sent when the text is changed from a list selection. */
98 public void widgetSelected(SelectionEvent e) {
103 // Remove self-reference when the widget is disposed
104 mCombo.addDisposeListener(new DisposeListener() {
105 public void widgetDisposed(DisposeEvent e) {
111 protected void fillCombo() {
112 String[] values = getPossibleValues(null);
114 if (values == null) {
115 AdtPlugin.log(IStatus.ERROR,
116 "FrameworkResourceManager did not provide values yet for %1$s",
117 getDescriptor().getXmlLocalName());
119 for (String value : values) {
126 * Get the list values, either from the initial values set in the attribute
127 * or by querying the framework resource parser.
132 public String[] getPossibleValues(String prefix) {
133 AttributeDescriptor descriptor = getDescriptor();
134 UiElementNode uiParent = getUiParent();
136 String attr_name = descriptor.getXmlLocalName();
137 String element_name = uiParent.getDescriptor().getXmlName();
139 // FrameworkResourceManager expects a specific prefix for the attribute.
140 String nsPrefix = "";
141 if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
142 nsPrefix = "android:"; //$NON-NLS-1$
143 } else if (XmlnsAttributeDescriptor.XMLNS_URI.equals(descriptor.getNamespaceUri())) {
144 nsPrefix = "xmlns:"; //$NON-NLS-1$
146 attr_name = nsPrefix + attr_name;
148 String[] values = null;
150 if (descriptor instanceof ListAttributeDescriptor &&
151 ((ListAttributeDescriptor) descriptor).getValues() != null) {
152 // Get enum values from the descriptor
153 values = ((ListAttributeDescriptor) descriptor).getValues();
156 if (values == null) {
157 // or from the AndroidTargetData
158 UiElementNode uiNode = getUiParent();
159 AndroidXmlEditor editor = uiNode.getEditor();
160 AndroidTargetData data = editor.getTargetData();
162 // get the great-grand-parent descriptor.
164 // the parent should always exist.
165 UiElementNode grandParentNode = uiParent.getUiParent();
167 String greatGrandParentNodeName = null;
168 if (grandParentNode != null) {
169 UiElementNode greatGrandParentNode = grandParentNode.getUiParent();
170 if (greatGrandParentNode != null) {
171 greatGrandParentNodeName =
172 greatGrandParentNode.getDescriptor().getXmlName();
176 values = data.getAttributeValues(element_name, attr_name, greatGrandParentNodeName);
184 public String getTextWidgetValue() {
185 if (mCombo != null) {
186 return mCombo.getText();
193 public final boolean isValid() {
194 return mCombo != null;
198 public void setTextWidgetValue(String value) {
199 if (mCombo != null) {
200 mCombo.setText(value);
205 * Handles Combo change, either from text edit or from selection change.
207 * Simply mark the attribute as dirty if it really changed.
208 * The container SectionPart will collect these flag and manage them.
210 private void onComboChange() {
211 if (!isInInternalTextModification() &&
214 getCurrentValue() != null &&
215 !mCombo.getText().equals(getCurrentValue())) {