• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.layout.uimodel;
18 
19 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
20 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
21 import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
22 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
23 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
24 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
25 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
26 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
27 import com.android.sdklib.IAndroidTarget;
28 import com.android.sdklib.SdkConstants;
29 
30 import org.eclipse.core.resources.IProject;
31 
32 import java.util.List;
33 
34 /**
35  * Specialized version of {@link UiElementNode} for the {@link ViewElementDescriptor}s.
36  */
37 public class UiViewElementNode extends UiElementNode {
38 
39     private AttributeDescriptor[] mCachedAttributeDescriptors;
40 
UiViewElementNode(ViewElementDescriptor elementDescriptor)41     public UiViewElementNode(ViewElementDescriptor elementDescriptor) {
42         super(elementDescriptor);
43     }
44 
45     /**
46      * Returns an AttributeDescriptor array that depends on the current UiParent.
47      * <p/>
48      * The array merges both "direct" attributes with the descriptor layout attributes.
49      * The array instance is cached and cleared if the UiParent is changed.
50      */
51     @Override
getAttributeDescriptors()52     public AttributeDescriptor[] getAttributeDescriptors() {
53         if (mCachedAttributeDescriptors != null) {
54             return mCachedAttributeDescriptors;
55         }
56 
57         UiElementNode ui_parent = getUiParent();
58         AttributeDescriptor[] direct_attrs = super.getAttributeDescriptors();
59         mCachedAttributeDescriptors = direct_attrs;
60 
61         AttributeDescriptor[] layout_attrs = null;
62         boolean need_xmlns = false;
63 
64         if (ui_parent instanceof UiDocumentNode) {
65             // Limitation: right now the layout behaves as if everything was
66             // owned by a FrameLayout.
67             // TODO replace by something user-configurable.
68 
69             List<ElementDescriptor> layoutDescriptors = null;
70             IProject project = getEditor().getProject();
71             if (project != null) {
72                 Sdk currentSdk = Sdk.getCurrent();
73                 if (currentSdk != null) {
74                     IAndroidTarget target = currentSdk.getTarget(project);
75                     if (target != null) {
76                         AndroidTargetData data = currentSdk.getTargetData(target);
77                         if (data != null) {
78                             layoutDescriptors = data.getLayoutDescriptors().getLayoutDescriptors();
79                         }
80                     }
81                 }
82             }
83 
84             if (layoutDescriptors != null) {
85                 for (ElementDescriptor desc : layoutDescriptors) {
86                     if (desc instanceof ViewElementDescriptor &&
87                             desc.getXmlName().equals(SdkConstants.CLASS_NAME_FRAMELAYOUT)) {
88                         layout_attrs = ((ViewElementDescriptor) desc).getLayoutAttributes();
89                         need_xmlns = true;
90                         break;
91                     }
92                 }
93             }
94         } else if (ui_parent instanceof UiViewElementNode){
95             layout_attrs =
96                 ((ViewElementDescriptor) ui_parent.getDescriptor()).getLayoutAttributes();
97         }
98 
99         if (layout_attrs == null || layout_attrs.length == 0) {
100             return mCachedAttributeDescriptors;
101         }
102 
103         mCachedAttributeDescriptors =
104             new AttributeDescriptor[direct_attrs.length +
105                                     layout_attrs.length +
106                                     (need_xmlns ? 1 : 0)];
107         System.arraycopy(direct_attrs, 0,
108                 mCachedAttributeDescriptors, 0,
109                 direct_attrs.length);
110         System.arraycopy(layout_attrs, 0,
111                 mCachedAttributeDescriptors, direct_attrs.length,
112                 layout_attrs.length);
113         if (need_xmlns) {
114             AttributeDescriptor desc = new XmlnsAttributeDescriptor(
115                     "android",  //$NON-NLS-1$
116                     SdkConstants.NS_RESOURCES);
117             mCachedAttributeDescriptors[direct_attrs.length + layout_attrs.length] = desc;
118         }
119 
120         return mCachedAttributeDescriptors;
121     }
122 
123     /**
124      * Sets the parent of this UI node.
125      * <p/>
126      * Also removes the cached AttributeDescriptor array that depends on the current UiParent.
127      */
128     @Override
setUiParent(UiElementNode parent)129     protected void setUiParent(UiElementNode parent) {
130         super.setUiParent(parent);
131         mCachedAttributeDescriptors = null;
132     }
133 }
134