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 */ 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)}. */ 77 public void setActiveEditor(IEditorPart part, IActionBars bars); 78 } 79 80 protected CommonXmlDelegate( 81 CommonXmlEditor editor, 82 IContentAssistProcessor contentAssist) { 83 mEditor = editor; 84 mContentAssist = contentAssist; 85 } 86 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 */ 95 public @NonNull CommonXmlEditor getEditor() { 96 return mEditor; 97 } 98 99 /** 100 * @return The root node of the UI element hierarchy 101 */ 102 public UiElementNode getUiRootNode() { 103 return mUiRootNode; 104 } 105 106 protected void setUiRootNode(UiElementNode uiRootNode) { 107 mUiRootNode = uiRootNode; 108 } 109 110 /** Called to compute the initial {@code UiRootNode}. */ 111 public abstract void delegateInitUiRootNode(boolean force); 112 113 /** 114 * Returns true, indicating the "save as" operation is supported by this editor. 115 */ 116 public boolean isSaveAsAllowed() { 117 return true; 118 } 119 120 /** 121 * Create the various form pages. 122 */ 123 public abstract void delegateCreateFormPages(); 124 125 public void delegatePostCreatePages() { 126 // pass 127 } 128 129 /** 130 * Changes the tab/title name to include the project name. 131 */ 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 */ 149 public abstract void delegateXmlModelChanged(Document xml_doc); 150 151 public void delegatePageChange(int newPageIndex) { 152 // pass 153 } 154 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 */ 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 */ 176 public Job delegateRunLint() { 177 return getEditor().startLintJob(); 178 } 179 180 181 /** 182 * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it. 183 */ 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 */ 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 */ 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 */ 218 public IFormPage delegatePostSetActivePage(IFormPage superReturned, String pageIndex) { 219 return superReturned; 220 } 221 222 /** Called after an editor has been activated */ 223 public void delegateActivated() { 224 } 225 226 /** Called after an editor has been deactivated */ 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 */ 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 */ 246 public int delegateGetPersistenceCategory() { 247 return AndroidXmlEditor.CATEGORY_OTHER; 248 } 249 } 250