OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / sdk / eclipse / plugins / com.android.ide.eclipse.adt / src / com / android / ide / eclipse / adt / internal / editors / uimodel / UiListAttributeNode.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
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
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
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.
15  */
16
17 package com.android.ide.eclipse.adt.internal.editors.uimodel;
18
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;
29
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;
44
45 /**
46  * Represents an XML attribute which has possible built-in values, and can be modified by
47  * an editable Combo box.
48  * <p/>
49  * See {@link UiTextAttributeNode} for more information.
50  */
51 public class UiListAttributeNode extends UiAbstractTextAttributeNode {
52
53     protected Combo mCombo;
54
55     public UiListAttributeNode(ListAttributeDescriptor attributeDescriptor,
56             UiElementNode uiParent) {
57         super(attributeDescriptor, uiParent);
58     }
59
60     /* (non-java doc)
61      * Creates a label widget and an associated text field.
62      * <p/>
63      * As most other parts of the android manifest editor, this assumes the
64      * parent uses a table layout with 2 columns.
65      */
66     @Override
67     public final void createUiControl(final Composite parent, IManagedForm managedForm) {
68         FormToolkit toolkit = managedForm.getToolkit();
69         TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
70
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()));
74
75         int style = SWT.DROP_DOWN;
76         mCombo = new Combo(parent, style);
77         TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE);
78         twd.maxWidth = 100;
79         mCombo.setLayoutData(twd);
80
81         fillCombo();
82
83         setTextWidgetValue(getCurrentValue());
84
85         mCombo.addModifyListener(new ModifyListener() {
86             /**
87              * Sent when the text is modified, whether by the user via manual
88              * input or programmatic input via setText().
89              */
90             public void modifyText(ModifyEvent e) {
91                 onComboChange();
92             }
93         });
94
95         mCombo.addSelectionListener(new SelectionAdapter() {
96             /** Sent when the text is changed from a list selection. */
97             @Override
98             public void widgetSelected(SelectionEvent e) {
99                 onComboChange();
100             }
101         });
102
103         // Remove self-reference when the widget is disposed
104         mCombo.addDisposeListener(new DisposeListener() {
105             public void widgetDisposed(DisposeEvent e) {
106                 mCombo = null;
107             }
108         });
109     }
110
111     protected void fillCombo() {
112         String[] values = getPossibleValues(null);
113
114         if (values == null) {
115             AdtPlugin.log(IStatus.ERROR,
116                     "FrameworkResourceManager did not provide values yet for %1$s",
117                     getDescriptor().getXmlLocalName());
118         } else {
119             for (String value : values) {
120                 mCombo.add(value);
121             }
122         }
123     }
124
125     /**
126      * Get the list values, either from the initial values set in the attribute
127      * or by querying the framework resource parser.
128      *
129      * {@inheritDoc}
130      */
131     @Override
132     public String[] getPossibleValues(String prefix) {
133         AttributeDescriptor descriptor = getDescriptor();
134         UiElementNode uiParent = getUiParent();
135
136         String attr_name = descriptor.getXmlLocalName();
137         String element_name = uiParent.getDescriptor().getXmlName();
138
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$
145         }
146         attr_name = nsPrefix + attr_name;
147
148         String[] values = null;
149
150         if (descriptor instanceof ListAttributeDescriptor &&
151                 ((ListAttributeDescriptor) descriptor).getValues() != null) {
152             // Get enum values from the descriptor
153             values = ((ListAttributeDescriptor) descriptor).getValues();
154         }
155
156         if (values == null) {
157             // or from the AndroidTargetData
158             UiElementNode uiNode = getUiParent();
159             AndroidXmlEditor editor = uiNode.getEditor();
160             AndroidTargetData data = editor.getTargetData();
161             if (data != null) {
162                 // get the great-grand-parent descriptor.
163
164                 // the parent should always exist.
165                 UiElementNode grandParentNode = uiParent.getUiParent();
166
167                 String greatGrandParentNodeName = null;
168                 if (grandParentNode != null) {
169                     UiElementNode greatGrandParentNode = grandParentNode.getUiParent();
170                     if (greatGrandParentNode != null) {
171                         greatGrandParentNodeName =
172                             greatGrandParentNode.getDescriptor().getXmlName();
173                     }
174                 }
175
176                 values = data.getAttributeValues(element_name, attr_name, greatGrandParentNodeName);
177             }
178         }
179
180         return values;
181     }
182
183     @Override
184     public String getTextWidgetValue() {
185         if (mCombo != null) {
186             return mCombo.getText();
187         }
188
189         return null;
190     }
191
192     @Override
193     public final boolean isValid() {
194         return mCombo != null;
195     }
196
197     @Override
198     public void setTextWidgetValue(String value) {
199         if (mCombo != null) {
200             mCombo.setText(value);
201         }
202     }
203
204     /**
205      * Handles Combo change, either from text edit or from selection change.
206      * <p/>
207      * Simply mark the attribute as dirty if it really changed.
208      * The container SectionPart will collect these flag and manage them.
209      */
210     private void onComboChange() {
211         if (!isInInternalTextModification() &&
212                 !isDirty() &&
213                 mCombo != null &&
214                 getCurrentValue() != null &&
215                 !mCombo.getText().equals(getCurrentValue())) {
216             setDirty(true);
217         }
218     }
219 }