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