aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common')
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonActionContributor.java40
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonMatchingStrategy.java84
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonSourceViewerConfig.java66
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlDelegate.java249
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlEditor.java467
5 files changed, 906 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonActionContributor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonActionContributor.java
new file mode 100755
index 000000000..5857b1532
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonActionContributor.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.adt.internal.editors.common;
+
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * Action contributor for the editors.
+ * This delegates to editor-specific action contributors.
+ */
+public class CommonActionContributor extends EditorActionBarContributor {
+
+ public CommonActionContributor() {
+ super();
+ }
+
+ @Override
+ public void setActiveEditor(IEditorPart part) {
+ LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(part);
+ if (delegate != null) {
+ delegate.setActiveEditor(part, getActionBars());
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonMatchingStrategy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonMatchingStrategy.java
new file mode 100755
index 000000000..224c28fff
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonMatchingStrategy.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.common;
+
+import static com.android.SdkConstants.FD_RES_LAYOUT;
+
+import com.android.ide.common.resources.ResourceFolder;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorMatchingStrategy;
+import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
+import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
+import com.android.resources.ResourceFolderType;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Matching strategy for the editors.
+ * This finds the right MatchingStrategy and delegates to it.
+ */
+public class CommonMatchingStrategy implements IEditorMatchingStrategy {
+
+ @Override
+ public boolean matches(IEditorReference editorRef, IEditorInput input) {
+ if (input instanceof FileEditorInput) {
+ FileEditorInput fileInput = (FileEditorInput)input;
+
+ // get the IFile object and check it's in one of the layout folders.
+ IFile file = fileInput.getFile();
+ if (file.getParent().getName().startsWith(FD_RES_LAYOUT)) {
+ ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(file);
+ if (resFolder != null && resFolder.getType() == ResourceFolderType.LAYOUT) {
+ if (AdtPrefs.getPrefs().isSharedLayoutEditor()) {
+ LayoutEditorMatchingStrategy m = new LayoutEditorMatchingStrategy();
+ return m.matches(editorRef, fileInput);
+ } else {
+ // Skip files that don't match by name (see below). However, for
+ // layout files we can't just use editorRef.getName(), since
+ // the name sometimes includes the parent folder name (when the
+ // files are in layout- folders.
+ if (!(editorRef.getName().endsWith(file.getName()) &&
+ editorRef.getId().equals(CommonXmlEditor.ID))) {
+ return false;
+ }
+ }
+ }
+ } else {
+ // Per the IEditorMatchingStrategy documentation, editorRef.getEditorInput()
+ // is expensive so try exclude files that definitely don't match, such
+ // as those with the wrong extension or wrong file name
+ if (!(file.getName().equals(editorRef.getName()) &&
+ editorRef.getId().equals(CommonXmlEditor.ID))) {
+ return false;
+ }
+ }
+
+ try {
+ return input.equals(editorRef.getEditorInput());
+ } catch (PartInitException e) {
+ AdtPlugin.log(e, null);
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonSourceViewerConfig.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonSourceViewerConfig.java
new file mode 100755
index 000000000..be31040c3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonSourceViewerConfig.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.common;
+
+import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
+
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+
+
+/**
+ * Source Viewer Configuration for the Common XML editor.
+ * Everything is already generic and done in the base class.
+ * The base class will use the delegate to find out the proper content assist to use.
+ */
+public final class CommonSourceViewerConfig extends AndroidSourceViewerConfig {
+
+ private final IContentAssistProcessor mContentAssist;
+
+ public CommonSourceViewerConfig() {
+ super();
+ mContentAssist = null;
+ }
+
+ public CommonSourceViewerConfig(IContentAssistProcessor contentAssist) {
+ super();
+ mContentAssist = contentAssist;
+ }
+
+
+ /**
+ * @return The {@link IContentAssistProcessor} passed to the constructor or null.
+ */
+ @Override
+ public IContentAssistProcessor getAndroidContentAssistProcessor(
+ ISourceViewer sourceViewer,
+ String partitionType) {
+ // You may think you could use AndroidXmlEditor.fromTextViewer(sourceViewer)
+ // to find the editor associated with the sourceViewer and then access the
+ // delegate and query the content assist specific to a given delegate.
+ // Unfortunately this is invoked whilst the editor part is being created
+ // so we can't match an existing editor to the source view -- since there
+ // is no such "existing" editor. It's just being created.
+ //
+ // As a workaround, CommonXmlEditor#addPages() will unconfigure the
+ // default sourceViewerConfig and reconfigure it with one that really
+ // knows which content assist it should be using.
+
+ return mContentAssist;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlDelegate.java
new file mode 100755
index 000000000..d9ee8a5d8
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlDelegate.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.common;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
+import com.android.resources.ResourceFolderType;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.eclipse.ui.part.EditorActionBarContributor;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.MultiPageEditorPart;
+import org.w3c.dom.Document;
+
+/**
+ * Implementation of form editor for /res XML files.
+ * <p/>
+ * All delegates must have one {@link IDelegateCreator} instance
+ * registered in the {@code DELEGATES[]} array of {@link CommonXmlEditor}.
+ */
+public abstract class CommonXmlDelegate {
+
+ /** The editor that created the delegate. Never null. */
+ private final CommonXmlEditor mEditor;
+
+ /** Root node of the UI element hierarchy. Can be null. */
+ private UiElementNode mUiRootNode;
+
+ private IContentAssistProcessor mContentAssist;
+
+ /**
+ * Static creator for {@link CommonXmlDelegate}s. Delegates implement a method
+ * that will decide whether this delegate can be created for the given file input.
+ */
+ public interface IDelegateCreator {
+ /**
+ * Determines whether this delegate can handle the given file, typically
+ * based on its resource path (e.g. ResourceManager#getResourceFolder).
+ *
+ * @param delegator The non-null instance of {@link CommonXmlEditor}.
+ * @param type The {@link ResourceFolderType} of the folder containing the file,
+ * if it can be determined. Null otherwise.
+ * @return A new delegate that can handle that file or null.
+ */
+ public @Nullable <T extends CommonXmlDelegate> T createForFile(
+ @NonNull CommonXmlEditor delegator,
+ @Nullable ResourceFolderType type);
+ }
+
+ /** Implemented by delegates that need to support {@link EditorActionBarContributor} */
+ public interface IActionContributorDelegate {
+ /** Called from {@link EditorActionBarContributor#setActiveEditor(IEditorPart)}. */
+ public void setActiveEditor(IEditorPart part, IActionBars bars);
+ }
+
+ protected CommonXmlDelegate(
+ CommonXmlEditor editor,
+ IContentAssistProcessor contentAssist) {
+ mEditor = editor;
+ mContentAssist = contentAssist;
+ }
+
+ public void dispose() {
+ }
+
+ /**
+ * Returns the editor that created this delegate.
+ *
+ * @return the editor that created this delegate. Never null.
+ */
+ public @NonNull CommonXmlEditor getEditor() {
+ return mEditor;
+ }
+
+ /**
+ * @return The root node of the UI element hierarchy
+ */
+ public UiElementNode getUiRootNode() {
+ return mUiRootNode;
+ }
+
+ protected void setUiRootNode(UiElementNode uiRootNode) {
+ mUiRootNode = uiRootNode;
+ }
+
+ /** Called to compute the initial {@code UiRootNode}. */
+ public abstract void delegateInitUiRootNode(boolean force);
+
+ /**
+ * Returns true, indicating the "save as" operation is supported by this editor.
+ */
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ /**
+ * Create the various form pages.
+ */
+ public abstract void delegateCreateFormPages();
+
+ public void delegatePostCreatePages() {
+ // pass
+ }
+
+ /**
+ * Changes the tab/title name to include the project name.
+ */
+ public void delegateSetInput(IEditorInput input) {
+ if (input instanceof FileEditorInput) {
+ FileEditorInput fileInput = (FileEditorInput) input;
+ IFile file = fileInput.getFile();
+ getEditor().setPartName(file.getName());
+ } else if (input instanceof IURIEditorInput) {
+ IURIEditorInput uriInput = (IURIEditorInput) input;
+ String name = uriInput.getName();
+ getEditor().setPartName(name);
+ }
+ }
+
+ /**
+ * Processes the new XML Model, which XML root node is given.
+ *
+ * @param xml_doc The XML document, if available, or null if none exists.
+ */
+ public abstract void delegateXmlModelChanged(Document xml_doc);
+
+ public void delegatePageChange(int newPageIndex) {
+ // pass
+ }
+
+ public void delegatePostPageChange(int newPageIndex) {
+ // pass
+ }
+ /**
+ * Save the XML.
+ * <p/>
+ * The actual save operation is done in the super class by committing
+ * all data to the XML model and then having the Structured XML Editor
+ * save the XML.
+ * <p/>
+ * Here we just need to tell the graphical editor that the model has
+ * been saved.
+ */
+ public void delegateDoSave(IProgressMonitor monitor) {
+ // pass
+ }
+
+ /**
+ * Tells the editor to start a Lint check.
+ * It's up to the caller to check whether this should be done depending on preferences.
+ */
+ public Job delegateRunLint() {
+ return getEditor().startLintJob();
+ }
+
+
+ /**
+ * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it.
+ */
+ public Object delegateGetAdapter(Class<?> adapter) {
+ return null;
+ }
+
+ /**
+ * Returns the {@link IContentAssistProcessor} associated with this editor.
+ * Most implementations should lazily allocate one processor and always return the
+ * same instance.
+ * Must return null if there's no specific content assist processor for this editor.
+ */
+ public IContentAssistProcessor getAndroidContentAssistProcessor() {
+ return mContentAssist;
+ }
+
+ /**
+ * Does this editor participate in the "format GUI editor changes" option?
+ *
+ * @return false since editors do not support automatically formatting XML
+ * affected by GUI changes unless they explicitly opt in to it.
+ */
+ public boolean delegateSupportsFormatOnGuiEdit() {
+ return false;
+ }
+
+ /**
+ * Called after the editor's active page has been set.
+ *
+ * @param superReturned the return value from
+ * {@link MultiPageEditorPart#setActivePage(int)}
+ * @param pageIndex the index of the page to be activated; the index must be
+ * valid
+ * @return the page, or null
+ * @see MultiPageEditorPart#setActivePage(int)
+ */
+ public IFormPage delegatePostSetActivePage(IFormPage superReturned, String pageIndex) {
+ return superReturned;
+ }
+
+ /** Called after an editor has been activated */
+ public void delegateActivated() {
+ }
+
+ /** Called after an editor has been deactivated */
+ public void delegateDeactivated() {
+ }
+
+ /**
+ * Returns the name of the editor to be shown in the editor tab etc. Return
+ * null to keep the default.
+ *
+ * @return the part name, or null to use the default
+ */
+ public String delegateGetPartName() {
+ return null;
+ }
+
+ /**
+ * Returns the persistence category, as described in
+ * {@link AndroidXmlEditor#getPersistenceCategory}.
+ *
+ * @return the persistence category to use for this editor
+ */
+ public int delegateGetPersistenceCategory() {
+ return AndroidXmlEditor.CATEGORY_OTHER;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlEditor.java
new file mode 100755
index 000000000..be06d38e2
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/common/CommonXmlEditor.java
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.common;
+
+import com.android.ide.common.resources.ResourceFolder;
+import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AdtUtils;
+import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.animator.AnimationEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.color.ColorEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlDelegate.IDelegateCreator;
+import com.android.ide.eclipse.adt.internal.editors.drawable.DrawableEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.menu.MenuEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.otherxml.OtherXmlEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.otherxml.PlainXmlEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
+import com.android.ide.eclipse.adt.internal.editors.values.ValuesEditorDelegate;
+import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
+import com.android.resources.ResourceFolderType;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ISourceViewerExtension2;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IShowEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.eclipse.ui.ide.IDE;
+import org.w3c.dom.Document;
+
+/**
+ * Multi-page form editor for ALL /res XML files.
+ * <p/>
+ * This editor doesn't actually do anything. Instead, it defers actual implementation
+ * to {@link CommonXmlDelegate} instances.
+ */
+public class CommonXmlEditor extends AndroidXmlEditor implements IShowEditorInput {
+
+ public static final String ID = AdtConstants.EDITORS_NAMESPACE + ".CommonXmlEditor"; //$NON-NLS-1$
+
+ /**
+ * Registered {@link CommonXmlDelegate}s.
+ * All delegates must have a {@code Creator} class which is instantiated
+ * once here statically. All the creators are invoked in the order they
+ * are defined and the first one to return a non-null delegate is used.
+ */
+ private static final IDelegateCreator[] DELEGATES = {
+ new LayoutEditorDelegate.Creator(),
+ new ValuesEditorDelegate.Creator(),
+ new AnimationEditorDelegate.Creator(),
+ new ColorEditorDelegate.Creator(),
+ new DrawableEditorDelegate.Creator(),
+ new MenuEditorDelegate.Creator(),
+ new OtherXmlEditorDelegate.Creator(),
+ };
+
+ /**
+ * IDs of legacy editors replaced by the {@link CommonXmlEditor}.
+ */
+ public static final String[] LEGACY_EDITOR_IDS = {
+ LayoutEditorDelegate.LEGACY_EDITOR_ID,
+ ValuesEditorDelegate.LEGACY_EDITOR_ID,
+ AnimationEditorDelegate.LEGACY_EDITOR_ID,
+ ColorEditorDelegate.LEGACY_EDITOR_ID,
+ DrawableEditorDelegate.LEGACY_EDITOR_ID,
+ MenuEditorDelegate.LEGACY_EDITOR_ID,
+ OtherXmlEditorDelegate.LEGACY_EDITOR_ID,
+ };
+
+ private CommonXmlDelegate mDelegate = null;
+
+ /**
+ * Creates the form editor for resources XML files.
+ */
+ public CommonXmlEditor() {
+ super();
+ }
+
+ @Override
+ public void init(IEditorSite site, final IEditorInput editorInput)
+ throws PartInitException {
+ if (editorInput instanceof IFileEditorInput) {
+
+ IFileEditorInput fileInput = (IFileEditorInput) editorInput;
+ IFile file = fileInput.getFile();
+
+ // Adjust the default file editor ID
+
+ IEditorDescriptor file_desc = IDE.getDefaultEditor(file);
+ String id = file_desc == null ? null : file_desc.getId();
+ boolean mustChange = id != null &&
+ !id.equals(ID) &&
+ id.startsWith(AdtConstants.EDITORS_NAMESPACE);
+ if (!mustChange) {
+ // Maybe this was opened by a manual Open With with a legacy ID?
+ id = site.getId();
+ mustChange = id != null &&
+ !id.equals(ID) &&
+ id.startsWith(AdtConstants.EDITORS_NAMESPACE);
+ }
+
+ if (mustChange) {
+ // It starts by our editor namespace but it's not the right ID.
+ // This is an old Android XML ID. Change it to our new ID.
+ IDE.setDefaultEditor(file, ID);
+ AdtPlugin.log(IStatus.INFO,
+ "Changed legacy editor ID %s for %s", //$NON-NLS-1$
+ id,
+ file.getFullPath());
+ }
+
+ // Now find the delegate for the file.
+
+ ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(file);
+ ResourceFolderType type = resFolder == null ? null : resFolder.getType();
+
+ if (type == null) {
+ // We lack any real resource information about that file.
+ // Let's take a guess using the actual path.
+ String folderName = AdtUtils.getParentFolderName(editorInput);
+ type = ResourceFolderType.getFolderType(folderName);
+ }
+
+ if (type != null) {
+ for (IDelegateCreator creator : DELEGATES) {
+ mDelegate = creator.createForFile(this, type);
+ if (mDelegate != null) {
+ break;
+ }
+ }
+ }
+
+ if (mDelegate == null) {
+ // We didn't find any editor.
+ // We'll use the PlainXmlEditorDelegate as a catch-all editor.
+ AdtPlugin.log(IStatus.INFO,
+ "No valid Android XML Editor Delegate found for file %1$s [Res %2$s, type %3$s]",
+ file.getFullPath(),
+ resFolder,
+ type);
+ mDelegate = new PlainXmlEditorDelegate(this);
+ }
+ } else if (editorInput instanceof IURIEditorInput) {
+ String folderName = AdtUtils.getParentFolderName(editorInput);
+ ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
+ if (type == ResourceFolderType.LAYOUT) {
+ // The layout editor has a lot of hardcoded requirements for real IFiles
+ // and IProjects so for now just use a plain XML editor for project-less layout
+ // files
+ mDelegate = new OtherXmlEditorDelegate(this);
+ } else if (type != null) {
+ for (IDelegateCreator creator : DELEGATES) {
+ mDelegate = creator.createForFile(this, type);
+ if (mDelegate != null) {
+ break;
+ }
+ }
+ }
+
+ if (mDelegate == null) {
+ // We didn't find any editor.
+ // We'll use the PlainXmlEditorDelegate as a catch-all editor.
+ AdtPlugin.log(IStatus.INFO,
+ "No valid Android XML Editor Delegate found for file %1$s [Res %2$s, type %3$s]",
+ ((IURIEditorInput) editorInput).getURI().toString(),
+ folderName,
+ type);
+ mDelegate = new PlainXmlEditorDelegate(this);
+ }
+ }
+
+ if (mDelegate == null) {
+ // We can't do anything if we don't have a valid file.
+ AdtPlugin.log(IStatus.INFO,
+ "Android XML Editor cannot process non-file input %1$s", //$NON-NLS-1$
+ (editorInput == null ? "null" : editorInput.toString())); //$NON-NLS-1$
+ throw new PartInitException("Android XML Editor cannot process this input.");
+ } else {
+ // Invoke the editor's init after setting up the delegate. This will call setInput().
+ super.init(site, editorInput);
+ }
+ }
+
+ /**
+ * @return The root node of the UI element hierarchy
+ */
+ @Override
+ public UiElementNode getUiRootNode() {
+ return mDelegate == null ? null : mDelegate.getUiRootNode();
+ }
+
+ public CommonXmlDelegate getDelegate() {
+ return mDelegate;
+ }
+
+ // ---- Base Class Overrides ----
+
+ @Override
+ public void dispose() {
+ if (mDelegate != null) {
+ mDelegate.dispose();
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * Save the XML.
+ * <p/>
+ * The actual save operation is done in the super class by committing
+ * all data to the XML model and then having the Structured XML Editor
+ * save the XML.
+ * <p/>
+ * Here we just need to tell the delegate that the model has
+ * been saved.
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ super.doSave(monitor);
+ if (mDelegate != null) {
+ mDelegate.delegateDoSave(monitor);
+ }
+ }
+
+ /**
+ * Returns whether the "save as" operation is supported by this editor.
+ * <p/>
+ * Save-As is a valid operation for the ManifestEditor since it acts on a
+ * single source file.
+ *
+ * @see IEditorPart
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return mDelegate == null ? false : mDelegate.isSaveAsAllowed();
+ }
+
+ /**
+ * Create the various form pages.
+ */
+ @Override
+ protected void createFormPages() {
+ if (mDelegate != null) {
+ mDelegate.delegateCreateFormPages();
+ }
+ }
+
+ @Override
+ protected void postCreatePages() {
+ super.postCreatePages();
+
+ if (mDelegate != null) {
+ mDelegate.delegatePostCreatePages();
+ }
+ }
+
+ @Override
+ protected void addPages() {
+ // Create the editor pages.
+ // This will also create the EditorPart.
+ super.addPages();
+
+ // When the EditorPart is being created, it configures the SourceViewer
+ // and will try to use our CommonSourceViewerConfig. Our config needs to
+ // know which ContentAssist processor to use (since we have one per resource
+ // folder type) but it doesn't have the necessary info to do so.
+ // Consequently, once the part is created, we can now unconfigure the source
+ // viewer and reconfigure it with the right settings.
+ ISourceViewer ssv = getStructuredSourceViewer();
+ if (mDelegate != null && ssv instanceof ISourceViewerExtension2) {
+ ((ISourceViewerExtension2) ssv).unconfigure();
+ ssv.configure(new CommonSourceViewerConfig(
+ mDelegate.getAndroidContentAssistProcessor()));
+ }
+ }
+
+ /* (non-java doc)
+ * Change the tab/title name to include the name of the layout.
+ */
+ @Override
+ protected void setInput(IEditorInput input) {
+ super.setInput(input);
+ assert mDelegate != null;
+ if (mDelegate != null) {
+ mDelegate.delegateSetInput(input);
+ }
+ }
+
+ @Override
+ public void setInputWithNotify(IEditorInput input) {
+ super.setInputWithNotify(input);
+ if (mDelegate instanceof LayoutEditorDelegate) {
+ ((LayoutEditorDelegate) mDelegate).delegateSetInputWithNotify(input);
+ }
+ }
+
+ /**
+ * Processes the new XML Model, which XML root node is given.
+ *
+ * @param xml_doc The XML document, if available, or null if none exists.
+ */
+ @Override
+ protected void xmlModelChanged(Document xml_doc) {
+ if (mDelegate != null) {
+ mDelegate.delegateXmlModelChanged(xml_doc);
+ }
+ }
+
+ @Override
+ protected Job runLint() {
+ if (mDelegate != null && getEditorInput() instanceof IFileEditorInput) {
+ return mDelegate.delegateRunLint();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it.
+ */
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ if (mDelegate != null) {
+ Object value = mDelegate.delegateGetAdapter(adapter);
+ if (value != null) {
+ return value;
+ }
+ }
+
+ // return default
+ return super.getAdapter(adapter);
+ }
+
+ @Override
+ protected void pageChange(int newPageIndex) {
+ if (mDelegate != null) {
+ mDelegate.delegatePageChange(newPageIndex);
+ }
+
+ super.pageChange(newPageIndex);
+
+ if (mDelegate != null) {
+ mDelegate.delegatePostPageChange(newPageIndex);
+ }
+ }
+
+ @Override
+ protected int getPersistenceCategory() {
+ if (mDelegate != null) {
+ return mDelegate.delegateGetPersistenceCategory();
+ }
+ return CATEGORY_OTHER;
+ }
+
+ @Override
+ public void initUiRootNode(boolean force) {
+ if (mDelegate != null) {
+ mDelegate.delegateInitUiRootNode(force);
+ }
+ }
+
+ @Override
+ public IFormPage setActivePage(String pageId) {
+ IFormPage page = super.setActivePage(pageId);
+
+ if (mDelegate != null) {
+ return mDelegate.delegatePostSetActivePage(page, pageId);
+ }
+
+ return page;
+ }
+
+ /* Implements showEditorInput(...) in IShowEditorInput */
+ @Override
+ public void showEditorInput(IEditorInput editorInput) {
+ if (mDelegate instanceof LayoutEditorDelegate) {
+ ((LayoutEditorDelegate) mDelegate).showEditorInput(editorInput);
+ }
+ }
+
+ @Override
+ public boolean supportsFormatOnGuiEdit() {
+ if (mDelegate != null) {
+ return mDelegate.delegateSupportsFormatOnGuiEdit();
+ }
+ return super.supportsFormatOnGuiEdit();
+ }
+
+ @Override
+ public void activated() {
+ super.activated();
+ if (mDelegate != null) {
+ mDelegate.delegateActivated();
+ }
+ }
+
+ @Override
+ public void deactivated() {
+ super.deactivated();
+ if (mDelegate != null) {
+ mDelegate.delegateDeactivated();
+ }
+ }
+
+ @Override
+ public String getPartName() {
+ if (mDelegate != null) {
+ String name = mDelegate.delegateGetPartName();
+ if (name != null) {
+ return name;
+ }
+ }
+
+ return super.getPartName();
+ }
+
+ // --------------------
+ // Base methods exposed so that XmlEditorDelegate can access them
+
+ @Override
+ public void setPartName(String partName) {
+ super.setPartName(partName);
+ }
+
+ @Override
+ public void setPageText(int pageIndex, String text) {
+ super.setPageText(pageIndex, text);
+ }
+
+ @Override
+ public void firePropertyChange(int propertyId) {
+ super.firePropertyChange(propertyId);
+ }
+
+ @Override
+ public int getPageCount() {
+ return super.getPageCount();
+ }
+
+ @Override
+ public int getCurrentPage() {
+ return super.getCurrentPage();
+ }
+}