1 /*
2  * Copyright (C) 2012 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.common;
18 
19 import com.android.annotations.NonNull;
20 import com.android.annotations.Nullable;
21 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
22 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
23 import com.android.resources.ResourceFolderType;
24 
25 import org.eclipse.core.resources.IFile;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.jobs.Job;
28 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
29 import org.eclipse.ui.IActionBars;
30 import org.eclipse.ui.IEditorInput;
31 import org.eclipse.ui.IEditorPart;
32 import org.eclipse.ui.IURIEditorInput;
33 import org.eclipse.ui.forms.editor.IFormPage;
34 import org.eclipse.ui.part.EditorActionBarContributor;
35 import org.eclipse.ui.part.FileEditorInput;
36 import org.eclipse.ui.part.MultiPageEditorPart;
37 import org.w3c.dom.Document;
38 
39 /**
40  * Implementation of form editor for /res XML files.
41  * <p/>
42  * All delegates must have one {@link IDelegateCreator} instance
43  * registered in the {@code DELEGATES[]} array of {@link CommonXmlEditor}.
44  */
45 public abstract class CommonXmlDelegate {
46 
47     /** The editor that created the delegate. Never null. */
48     private final CommonXmlEditor mEditor;
49 
50     /** Root node of the UI element hierarchy. Can be null. */
51     private UiElementNode mUiRootNode;
52 
53     private IContentAssistProcessor mContentAssist;
54 
55     /**
56      * Static creator for {@link CommonXmlDelegate}s. Delegates implement a method
57      * that will decide whether this delegate can be created for the given file input.
58      */
59     public interface IDelegateCreator {
60         /**
61          * Determines whether this delegate can handle the given file, typically
62          * based on its resource path (e.g. ResourceManager#getResourceFolder).
63          *
64          * @param delegator The non-null instance of {@link CommonXmlEditor}.
65          * @param type The {@link ResourceFolderType} of the folder containing the file,
66          *   if it can be determined. Null otherwise.
67          * @return A new delegate that can handle that file or null.
68          */
createForFile( @onNull CommonXmlEditor delegator, @Nullable ResourceFolderType type)69         public @Nullable <T extends CommonXmlDelegate> T createForFile(
70                             @NonNull CommonXmlEditor delegator,
71                             @Nullable ResourceFolderType type);
72     }
73 
74     /** Implemented by delegates that need to support {@link EditorActionBarContributor} */
75     public interface IActionContributorDelegate {
76         /** Called from {@link EditorActionBarContributor#setActiveEditor(IEditorPart)}. */
setActiveEditor(IEditorPart part, IActionBars bars)77         public void setActiveEditor(IEditorPart part, IActionBars bars);
78     }
79 
CommonXmlDelegate( CommonXmlEditor editor, IContentAssistProcessor contentAssist)80     protected CommonXmlDelegate(
81             CommonXmlEditor editor,
82             IContentAssistProcessor contentAssist) {
83         mEditor = editor;
84         mContentAssist = contentAssist;
85     }
86 
dispose()87     public void dispose() {
88     }
89 
90     /**
91      * Returns the editor that created this delegate.
92      *
93      * @return the editor that created this delegate. Never null.
94      */
getEditor()95     public @NonNull CommonXmlEditor getEditor() {
96         return mEditor;
97     }
98 
99     /**
100      * @return The root node of the UI element hierarchy
101      */
getUiRootNode()102     public UiElementNode getUiRootNode() {
103         return mUiRootNode;
104     }
105 
setUiRootNode(UiElementNode uiRootNode)106     protected void setUiRootNode(UiElementNode uiRootNode) {
107         mUiRootNode = uiRootNode;
108     }
109 
110     /** Called to compute the initial {@code UiRootNode}. */
delegateInitUiRootNode(boolean force)111     public abstract void delegateInitUiRootNode(boolean force);
112 
113     /**
114      * Returns true, indicating the "save as" operation is supported by this editor.
115      */
isSaveAsAllowed()116     public boolean isSaveAsAllowed() {
117         return true;
118     }
119 
120     /**
121      * Create the various form pages.
122      */
delegateCreateFormPages()123     public abstract void delegateCreateFormPages();
124 
delegatePostCreatePages()125     public void delegatePostCreatePages() {
126         // pass
127     }
128 
129     /**
130      * Changes the tab/title name to include the project name.
131      */
delegateSetInput(IEditorInput input)132     public void delegateSetInput(IEditorInput input) {
133         if (input instanceof FileEditorInput) {
134             FileEditorInput fileInput = (FileEditorInput) input;
135             IFile file = fileInput.getFile();
136             getEditor().setPartName(file.getName());
137         } else if (input instanceof IURIEditorInput) {
138             IURIEditorInput uriInput = (IURIEditorInput) input;
139             String name = uriInput.getName();
140             getEditor().setPartName(name);
141         }
142     }
143 
144     /**
145      * Processes the new XML Model, which XML root node is given.
146      *
147      * @param xml_doc The XML document, if available, or null if none exists.
148      */
delegateXmlModelChanged(Document xml_doc)149     public abstract void delegateXmlModelChanged(Document xml_doc);
150 
delegatePageChange(int newPageIndex)151     public void delegatePageChange(int newPageIndex) {
152         // pass
153     }
154 
delegatePostPageChange(int newPageIndex)155     public void delegatePostPageChange(int newPageIndex) {
156         // pass
157     }
158     /**
159      * Save the XML.
160      * <p/>
161      * The actual save operation is done in the super class by committing
162      * all data to the XML model and then having the Structured XML Editor
163      * save the XML.
164      * <p/>
165      * Here we just need to tell the graphical editor that the model has
166      * been saved.
167      */
delegateDoSave(IProgressMonitor monitor)168     public void delegateDoSave(IProgressMonitor monitor) {
169         // pass
170     }
171 
172     /**
173      * Tells the editor to start a Lint check.
174      * It's up to the caller to check whether this should be done depending on preferences.
175      */
delegateRunLint()176     public Job delegateRunLint() {
177         return getEditor().startLintJob();
178     }
179 
180 
181     /**
182      * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it.
183      */
delegateGetAdapter(Class<?> adapter)184     public Object delegateGetAdapter(Class<?> adapter) {
185         return null;
186     }
187 
188     /**
189      * Returns the {@link IContentAssistProcessor} associated with this editor.
190      * Most implementations should lazily allocate one processor and always return the
191      * same instance.
192      * Must return null if there's no specific content assist processor for this editor.
193      */
getAndroidContentAssistProcessor()194     public IContentAssistProcessor getAndroidContentAssistProcessor() {
195         return mContentAssist;
196     }
197 
198     /**
199      * Does this editor participate in the "format GUI editor changes" option?
200      *
201      * @return false since editors do not support automatically formatting XML
202      *         affected by GUI changes unless they explicitly opt in to it.
203      */
delegateSupportsFormatOnGuiEdit()204     public boolean delegateSupportsFormatOnGuiEdit() {
205         return false;
206     }
207 
208     /**
209      * Called after the editor's active page has been set.
210      *
211      * @param superReturned the return value from
212      *            {@link MultiPageEditorPart#setActivePage(int)}
213      * @param pageIndex the index of the page to be activated; the index must be
214      *            valid
215      * @return the page, or null
216      * @see MultiPageEditorPart#setActivePage(int)
217      */
delegatePostSetActivePage(IFormPage superReturned, String pageIndex)218     public IFormPage delegatePostSetActivePage(IFormPage superReturned, String pageIndex) {
219         return superReturned;
220     }
221 
222     /** Called after an editor has been activated */
delegateActivated()223     public void delegateActivated() {
224     }
225 
226     /** Called after an editor has been deactivated */
delegateDeactivated()227     public void delegateDeactivated() {
228     }
229 
230     /**
231      * Returns the name of the editor to be shown in the editor tab etc. Return
232      * null to keep the default.
233      *
234      * @return the part name, or null to use the default
235      */
delegateGetPartName()236     public String delegateGetPartName() {
237         return null;
238     }
239 
240     /**
241      * Returns the persistence category, as described in
242      * {@link AndroidXmlEditor#getPersistenceCategory}.
243      *
244      * @return the persistence category to use for this editor
245      */
delegateGetPersistenceCategory()246     public int delegateGetPersistenceCategory() {
247         return AndroidXmlEditor.CATEGORY_OTHER;
248     }
249 }
250