• 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.menu;
18 
19 import com.android.ide.eclipse.adt.AdtPlugin;
20 import com.android.ide.eclipse.adt.AndroidConstants;
21 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
22 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
23 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
24 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
25 import com.android.sdklib.xml.AndroidXPathFactory;
26 
27 import org.eclipse.core.resources.IFile;
28 import org.eclipse.ui.IEditorInput;
29 import org.eclipse.ui.IEditorPart;
30 import org.eclipse.ui.PartInitException;
31 import org.eclipse.ui.part.FileEditorInput;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.Node;
34 
35 import javax.xml.xpath.XPath;
36 import javax.xml.xpath.XPathConstants;
37 import javax.xml.xpath.XPathExpressionException;
38 
39 /**
40  * Multi-page form editor for /res/menu XML files.
41  */
42 public class MenuEditor extends AndroidXmlEditor {
43 
44     public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".menu.MenuEditor"; //$NON-NLS-1$
45 
46     /** Root node of the UI element hierarchy */
47     private UiElementNode mUiRootNode;
48 
49     /**
50      * Creates the form editor for resources XML files.
51      */
MenuEditor()52     public MenuEditor() {
53         super();
54     }
55 
56     /**
57      * Returns the root node of the UI element hierarchy, which here is
58      * the "menu" node.
59      */
60     @Override
getUiRootNode()61     public UiElementNode getUiRootNode() {
62         return mUiRootNode;
63     }
64 
65     // ---- Base Class Overrides ----
66 
67     /**
68      * Returns whether the "save as" operation is supported by this editor.
69      * <p/>
70      * Save-As is a valid operation for the ManifestEditor since it acts on a
71      * single source file.
72      *
73      * @see IEditorPart
74      */
75     @Override
isSaveAsAllowed()76     public boolean isSaveAsAllowed() {
77         return true;
78     }
79 
80     /**
81      * Create the various form pages.
82      */
83     @Override
createFormPages()84     protected void createFormPages() {
85         try {
86             addPage(new MenuTreePage(this));
87         } catch (PartInitException e) {
88             AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
89         }
90 
91      }
92 
93     /* (non-java doc)
94      * Change the tab/title name to include the project name.
95      */
96     @Override
setInput(IEditorInput input)97     protected void setInput(IEditorInput input) {
98         super.setInput(input);
99         if (input instanceof FileEditorInput) {
100             FileEditorInput fileInput = (FileEditorInput) input;
101             IFile file = fileInput.getFile();
102             setPartName(String.format("%1$s", file.getName()));
103         }
104     }
105 
106     /**
107      * Processes the new XML Model, which XML root node is given.
108      *
109      * @param xml_doc The XML document, if available, or null if none exists.
110      */
111     @Override
xmlModelChanged(Document xml_doc)112     protected void xmlModelChanged(Document xml_doc) {
113         // init the ui root on demand
114         initUiRootNode(false /*force*/);
115 
116         mUiRootNode.setXmlDocument(xml_doc);
117         if (xml_doc != null) {
118             ElementDescriptor root_desc = mUiRootNode.getDescriptor();
119             try {
120                 XPath xpath = AndroidXPathFactory.newXPath();
121                 Node node = (Node) xpath.evaluate("/" + root_desc.getXmlName(),  //$NON-NLS-1$
122                         xml_doc,
123                         XPathConstants.NODE);
124                 if (node == null && root_desc.isMandatory()) {
125                     // Create the root element if it doesn't exist yet (for empty new documents)
126                     node = mUiRootNode.createXmlNode();
127                 }
128 
129                 // Refresh the manifest UI node and all its descendants
130                 mUiRootNode.loadFromXmlNode(node);
131 
132                 // TODO ? startMonitoringMarkers();
133             } catch (XPathExpressionException e) {
134                 AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
135                         root_desc.getXmlName());
136             }
137         }
138 
139         super.xmlModelChanged(xml_doc);
140     }
141 
142     /**
143      * Creates the initial UI Root Node, including the known mandatory elements.
144      * @param force if true, a new UiRootNode is recreated even if it already exists.
145      */
146     @Override
initUiRootNode(boolean force)147     protected void initUiRootNode(boolean force) {
148         // The root UI node is always created, even if there's no corresponding XML node.
149         if (mUiRootNode == null || force) {
150             Document doc = null;
151             if (mUiRootNode != null) {
152                 doc = mUiRootNode.getXmlDocument();
153             }
154 
155             // get the target data from the opened file (and its project)
156             AndroidTargetData data = getTargetData();
157 
158             ElementDescriptor desc;
159             if (data == null) {
160                 desc = new ElementDescriptor("temp", null /*children*/);
161             } else {
162                 desc = data.getMenuDescriptors().getDescriptor();
163             }
164 
165             mUiRootNode = desc.createUiNode();
166             mUiRootNode.setEditor(this);
167 
168             onDescriptorsChanged(doc);
169         }
170     }
171 
172     // ---- Local Methods ----
173 
174     /**
175      * Reloads the UI manifest node from the XML, and calls the pages to update.
176      */
onDescriptorsChanged(Document document)177     private void onDescriptorsChanged(Document document) {
178         if (document != null) {
179             mUiRootNode.loadFromXmlNode(document);
180         } else {
181             mUiRootNode.reloadFromXmlNode(mUiRootNode.getXmlNode());
182         }
183     }
184 }
185